diff options
Diffstat (limited to 'src/mesa/main')
270 files changed, 21506 insertions, 32514 deletions
diff --git a/src/mesa/main/accum.c b/src/mesa/main/accum.c index c8db08aa42c..0a449d6ab6e 100644 --- a/src/mesa/main/accum.c +++ b/src/mesa/main/accum.c @@ -22,18 +22,18 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "glheader.h" +#include "util/glheader.h" #include "accum.h" #include "condrender.h" #include "context.h" #include "format_unpack.h" #include "format_pack.h" #include "framebuffer.h" - +#include "renderbuffer.h" #include "macros.h" #include "state.h" #include "mtypes.h" - +#include "api_exec_decl.h" void GLAPIENTRY _mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ) @@ -82,9 +82,9 @@ _mesa_clear_accum_buffer(struct gl_context *ctx) width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin; height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin; - ctx->Driver.MapRenderbuffer(ctx, accRb, x, y, width, height, - GL_MAP_WRITE_BIT, &accMap, &accRowStride, - ctx->DrawBuffer->FlipY); + _mesa_map_renderbuffer(ctx, accRb, x, y, width, height, + GL_MAP_WRITE_BIT, &accMap, &accRowStride, + ctx->DrawBuffer->FlipY); if (!accMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); @@ -115,7 +115,7 @@ _mesa_clear_accum_buffer(struct gl_context *ctx) _mesa_warning(ctx, "unexpected accum buffer type"); } - ctx->Driver.UnmapRenderbuffer(ctx, accRb); + _mesa_unmap_renderbuffer(ctx, accRb); } @@ -137,10 +137,10 @@ accum_scale_or_bias(struct gl_context *ctx, GLfloat value, assert(accRb); - ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, - GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, - &accMap, &accRowStride, - ctx->DrawBuffer->FlipY); + _mesa_map_renderbuffer(ctx, accRb, xpos, ypos, width, height, + GL_MAP_READ_BIT | GL_MAP_WRITE_BIT, + &accMap, &accRowStride, + ctx->DrawBuffer->FlipY); if (!accMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); @@ -174,7 +174,7 @@ accum_scale_or_bias(struct gl_context *ctx, GLfloat value, /* other types someday? */ } - ctx->Driver.UnmapRenderbuffer(ctx, accRb); + _mesa_unmap_renderbuffer(ctx, accRb); } @@ -208,21 +208,21 @@ accum_or_load(struct gl_context *ctx, GLfloat value, mappingFlags |= GL_MAP_READ_BIT; /* Map accum buffer */ - ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, - mappingFlags, &accMap, &accRowStride, - ctx->DrawBuffer->FlipY); + _mesa_map_renderbuffer(ctx, accRb, xpos, ypos, width, height, + mappingFlags, &accMap, &accRowStride, + ctx->DrawBuffer->FlipY); if (!accMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); return; } /* Map color buffer */ - ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height, - GL_MAP_READ_BIT, - &colorMap, &colorRowStride, - ctx->DrawBuffer->FlipY); + _mesa_map_renderbuffer(ctx, colorRb, xpos, ypos, width, height, + GL_MAP_READ_BIT, + &colorMap, &colorRowStride, + ctx->DrawBuffer->FlipY); if (!colorMap) { - ctx->Driver.UnmapRenderbuffer(ctx, accRb); + _mesa_unmap_renderbuffer(ctx, accRb); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glAccum"); return; } @@ -272,8 +272,8 @@ accum_or_load(struct gl_context *ctx, GLfloat value, /* other types someday? */ } - ctx->Driver.UnmapRenderbuffer(ctx, accRb); - ctx->Driver.UnmapRenderbuffer(ctx, colorRb); + _mesa_unmap_renderbuffer(ctx, accRb); + _mesa_unmap_renderbuffer(ctx, colorRb); } @@ -291,7 +291,7 @@ accum_return(struct gl_context *ctx, GLfloat value, GLuint buffer; /* Map accum buffer */ - ctx->Driver.MapRenderbuffer(ctx, accRb, xpos, ypos, width, height, + _mesa_map_renderbuffer(ctx, accRb, xpos, ypos, width, height, GL_MAP_READ_BIT, &accMap, &accRowStride, fb->FlipY); if (!accMap) { @@ -312,7 +312,7 @@ accum_return(struct gl_context *ctx, GLfloat value, mappingFlags |= GL_MAP_READ_BIT; /* Map color buffer */ - ctx->Driver.MapRenderbuffer(ctx, colorRb, xpos, ypos, width, height, + _mesa_map_renderbuffer(ctx, colorRb, xpos, ypos, width, height, mappingFlags, &colorMap, &colorRowStride, fb->FlipY); if (!colorMap) { @@ -380,10 +380,10 @@ accum_return(struct gl_context *ctx, GLfloat value, /* other types someday? */ } - ctx->Driver.UnmapRenderbuffer(ctx, colorRb); + _mesa_unmap_renderbuffer(ctx, colorRb); } - ctx->Driver.UnmapRenderbuffer(ctx, accRb); + _mesa_unmap_renderbuffer(ctx, accRb); } diff --git a/src/mesa/main/accum.h b/src/mesa/main/accum.h index fe253a20db6..0a8bcfc2c5d 100644 --- a/src/mesa/main/accum.h +++ b/src/mesa/main/accum.h @@ -37,15 +37,10 @@ #ifndef ACCUM_H #define ACCUM_H -#include "main/glheader.h" +#include "util/glheader.h" struct gl_context; -extern void GLAPIENTRY -_mesa_ClearAccum( GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha ); -void GLAPIENTRY -_mesa_Accum( GLenum op, GLfloat value ); - extern void _mesa_clear_accum_buffer(struct gl_context *ctx); diff --git a/src/mesa/main/api_arrayelt.c b/src/mesa/main/api_arrayelt.c index 7e0bb54c410..805e13d0ecb 100644 --- a/src/mesa/main/api_arrayelt.c +++ b/src/mesa/main/api_arrayelt.c @@ -34,7 +34,7 @@ * Keith Whitwell <keithw@vmware.com> */ -#include "glheader.h" +#include "util/glheader.h" #include "arrayobj.h" #include "api_arrayelt.h" #include "bufferobj.h" @@ -44,6 +44,7 @@ #include "mtypes.h" #include "main/dispatch.h" #include "varray.h" +#include "api_exec_decl.h" typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data ); @@ -65,11 +66,11 @@ TYPE_IDX(GLenum t) static inline int vertex_format_to_index(const struct gl_vertex_format *vformat) { - if (vformat->Doubles) + if (vformat->User.Doubles) return 3; - else if (vformat->Integer) + else if (vformat->User.Integer) return 2; - else if (vformat->Normalized) + else if (vformat->User.Normalized) return 1; else return 0; @@ -82,7 +83,7 @@ static struct _glapi_table * get_dispatch(void) { GET_CURRENT_CONTEXT(ctx); - return ctx->CurrentServerDispatch; + return ctx->Dispatch.Current; } @@ -1394,8 +1395,8 @@ static const attrib_func AttribFuncsARB[4][4][NUM_TYPES] = { static inline attrib_func func_nv(const struct gl_vertex_format *vformat) { - return AttribFuncsNV[vformat->Normalized][vformat->Size-1] - [TYPE_IDX(vformat->Type)]; + return AttribFuncsNV[vformat->User.Normalized][vformat->User.Size-1] + [TYPE_IDX(vformat->User.Type)]; } @@ -1405,8 +1406,8 @@ func_nv(const struct gl_vertex_format *vformat) static inline attrib_func func_arb(const struct gl_vertex_format *vformat) { - return AttribFuncsARB[vertex_format_to_index(vformat)][vformat->Size-1] - [TYPE_IDX(vformat->Type)]; + return AttribFuncsARB[vertex_format_to_index(vformat)][vformat->User.Size-1] + [TYPE_IDX(vformat->User.Type)]; } @@ -1477,7 +1478,7 @@ _mesa_array_element(struct gl_context *ctx, GLint elt) * Note: this may be called during display list construction. */ void GLAPIENTRY -_ae_ArrayElement(GLint elt) +_mesa_ArrayElement(GLint elt) { GET_CURRENT_CONTEXT(ctx); struct gl_vertex_array_object *vao; @@ -1486,7 +1487,7 @@ _ae_ArrayElement(GLint elt) * then we call PrimitiveRestartNV and return. */ if (ctx->Array.PrimitiveRestart && (elt == ctx->Array.RestartIndex)) { - CALL_PrimitiveRestartNV(ctx->CurrentServerDispatch, ()); + CALL_PrimitiveRestartNV(ctx->Dispatch.Current, ()); return; } @@ -1497,11 +1498,3 @@ _ae_ArrayElement(GLint elt) _mesa_vao_unmap_arrays(ctx, vao); } - - -void -_mesa_install_arrayelt_vtxfmt(struct _glapi_table *disp, - const GLvertexformat *vfmt) -{ - SET_ArrayElement(disp, vfmt->ArrayElement); -} diff --git a/src/mesa/main/api_arrayelt.h b/src/mesa/main/api_arrayelt.h index 6c2ece81134..41f72a2f97a 100644 --- a/src/mesa/main/api_arrayelt.h +++ b/src/mesa/main/api_arrayelt.h @@ -33,11 +33,5 @@ struct _glapi_table; extern void _mesa_array_element(struct gl_context *ctx, GLint elt); -extern void GLAPIENTRY _ae_ArrayElement( GLint elt ); - -extern void -_mesa_install_arrayelt_vtxfmt(struct _glapi_table *disp, - const GLvertexformat *vfmt); - #endif /* API_ARRAYELT_H */ diff --git a/src/mesa/main/api_exec.h b/src/mesa/main/api_exec.h deleted file mode 100644 index f55f56bda4a..00000000000 --- a/src/mesa/main/api_exec.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef API_EXEC_H -#define API_EXEC_H - -#ifdef __cplusplus -extern "C" { -#endif - -struct _glapi_table; -struct gl_context; - -extern struct _glapi_table * -_mesa_alloc_dispatch_table(void); - -extern void -_mesa_initialize_exec_table(struct gl_context *ctx); - -extern void -_mesa_initialize_dispatch_tables(struct gl_context *ctx); - -extern struct _glapi_table * -_mesa_new_nop_table(unsigned numEntries); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif diff --git a/src/mesa/main/arbprogram.c b/src/mesa/main/arbprogram.c index 9635bfca1fb..f83fe1ac3d4 100644 --- a/src/mesa/main/arbprogram.c +++ b/src/mesa/main/arbprogram.c @@ -29,19 +29,21 @@ */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/draw_validate.h" #include "main/hash.h" #include "main/macros.h" #include "main/mtypes.h" -#include "main/arbprogram.h" #include "main/shaderapi.h" #include "main/state.h" #include "program/arbprogparse.h" #include "program/program.h" #include "program/prog_print.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_program.h" static void flush_vertices_for_program_constants(struct gl_context *ctx, GLenum target) @@ -77,7 +79,6 @@ lookup_or_create_program(GLuint id, GLenum target, const char* caller) /* Bind a user program */ newProg = _mesa_lookup_program(ctx, id); if (!newProg || newProg == &_mesa_DummyProgram) { - bool isGenName = newProg != NULL; /* allocate a new program now */ newProg = ctx->Driver.NewProgram(ctx, _mesa_program_enum_to_shader_stage(target), id, true); @@ -85,7 +86,7 @@ lookup_or_create_program(GLuint id, GLenum target, const char* caller) _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); return NULL; } - _mesa_HashInsert(ctx->Shared->Programs, id, newProg, isGenName); + _mesa_HashInsert(&ctx->Shared->Programs, id, newProg); } else if (newProg->Target != target) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -179,7 +180,7 @@ _mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids) if (ids[i] != 0) { struct gl_program *prog = _mesa_lookup_program(ctx, ids[i]); if (prog == &_mesa_DummyProgram) { - _mesa_HashRemove(ctx->Shared->Programs, ids[i]); + _mesa_HashRemove(&ctx->Shared->Programs, ids[i]); } else if (prog) { /* Unbind program if necessary */ @@ -203,7 +204,7 @@ _mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids) return; } /* The ID is immediately available for re-use now */ - _mesa_HashRemove(ctx->Shared->Programs, ids[i]); + _mesa_HashRemove(&ctx->Shared->Programs, ids[i]); _mesa_reference_program(ctx, &prog, NULL); } } @@ -230,17 +231,17 @@ _mesa_GenProgramsARB(GLsizei n, GLuint *ids) if (!ids) return; - _mesa_HashLockMutex(ctx->Shared->Programs); + _mesa_HashLockMutex(&ctx->Shared->Programs); - _mesa_HashFindFreeKeys(ctx->Shared->Programs, ids, n); + _mesa_HashFindFreeKeys(&ctx->Shared->Programs, ids, n); /* Insert pointer to dummy program as placeholder */ for (i = 0; i < (GLuint) n; i++) { - _mesa_HashInsertLocked(ctx->Shared->Programs, ids[i], - &_mesa_DummyProgram, true); + _mesa_HashInsertLocked(&ctx->Shared->Programs, ids[i], + &_mesa_DummyProgram); } - _mesa_HashUnlockMutex(ctx->Shared->Programs); + _mesa_HashUnlockMutex(&ctx->Shared->Programs); } @@ -379,12 +380,15 @@ set_program_string(struct gl_program *prog, GLenum target, GLenum format, GLsize gl_shader_stage stage = _mesa_program_enum_to_shader_stage(target); + uint8_t sha1[SHA1_DIGEST_LENGTH]; + _mesa_sha1_compute(string, len, sha1); + /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace * if corresponding entry found from MESA_SHADER_READ_PATH. */ - _mesa_dump_shader_source(stage, string); + _mesa_dump_shader_source(stage, string, sha1); - replacement = _mesa_read_shader_source(stage, string); + replacement = _mesa_read_shader_source(stage, string, sha1); if (replacement) string = replacement; #endif /* ENABLE_SHADER_CACHE */ @@ -405,7 +409,7 @@ set_program_string(struct gl_program *prog, GLenum target, GLenum format, GLsize if (!failed) { /* finally, give the program to the driver for translation/checking */ - if (!ctx->Driver.ProgramStringNotify(ctx, target, prog)) { + if (!st_program_string_notify(ctx, target, prog)) { failed = true; _mesa_error(ctx, GL_INVALID_OPERATION, "glProgramStringARB(rejected by driver"); @@ -961,10 +965,6 @@ get_program_iv(struct gl_program *prog, GLenum target, GLenum pname, /* default/null program */ *params = GL_FALSE; } - else if (ctx->Driver.IsProgramNative) { - /* ask the driver */ - *params = ctx->Driver.IsProgramNative( ctx, target, prog ); - } else { /* probably running in software */ *params = GL_TRUE; diff --git a/src/mesa/main/arbprogram.h b/src/mesa/main/arbprogram.h deleted file mode 100644 index d7fa15ba570..00000000000 --- a/src/mesa/main/arbprogram.h +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef ARBPROGRAM_H -#define ARBPROGRAM_H - - -#include "glheader.h" - - -extern void GLAPIENTRY -_mesa_BindProgramARB(GLenum target, GLuint id); - -extern void GLAPIENTRY -_mesa_DeleteProgramsARB(GLsizei n, const GLuint *ids); - -extern void GLAPIENTRY -_mesa_GenProgramsARB(GLsizei n, GLuint *ids); - - -extern GLboolean GLAPIENTRY -_mesa_IsProgramARB(GLuint id); - - -extern void GLAPIENTRY -_mesa_ProgramStringARB(GLenum target, GLenum format, GLsizei len, - const GLvoid *string); - -extern void GLAPIENTRY -_mesa_NamedProgramStringEXT(GLuint program, GLenum target, GLenum format, - GLsizei len, const GLvoid *string); - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4dARB(GLenum target, GLuint index, - GLdouble x, GLdouble y, GLdouble z, GLdouble w); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4dvARB(GLenum target, GLuint index, - const GLdouble *params); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4fARB(GLenum target, GLuint index, - GLfloat x, GLfloat y, GLfloat z, GLfloat w); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params); - - -extern void GLAPIENTRY -_mesa_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, - const GLfloat *params); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4dARB(GLenum target, GLuint index, - GLdouble x, GLdouble y, - GLdouble z, GLdouble w); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4dvARB(GLenum target, GLuint index, - const GLdouble *params); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4fARB(GLenum target, GLuint index, - GLfloat x, GLfloat y, GLfloat z, GLfloat w); - - -extern void GLAPIENTRY -_mesa_NamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, - GLuint index, const GLfloat *params); - -extern void GLAPIENTRY -_mesa_NamedProgramLocalParameter4dEXT(GLuint program, GLenum target, - GLuint index, GLdouble x, GLdouble y, - GLdouble z, GLdouble w); - -extern void GLAPIENTRY -_mesa_NamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, - GLuint index, const GLdouble *params); - - -extern void GLAPIENTRY -_mesa_NamedProgramLocalParameter4fEXT(GLuint program, GLenum target, - GLuint index, GLfloat x, GLfloat y, - GLfloat z, GLfloat w); - - -extern void GLAPIENTRY -_mesa_ProgramLocalParameter4fvARB(GLenum target, GLuint index, - const GLfloat *params); - -extern void GLAPIENTRY -_mesa_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, - const GLfloat *params); - -extern void GLAPIENTRY -_mesa_NamedProgramLocalParameters4fvEXT(GLuint program, GLenum target, GLuint index, - GLsizei count, const GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetProgramEnvParameterdvARB(GLenum target, GLuint index, - GLdouble *params); - - -extern void GLAPIENTRY -_mesa_GetProgramEnvParameterfvARB(GLenum target, GLuint index, - GLfloat *params); - - -extern void GLAPIENTRY -_mesa_GetProgramLocalParameterdvARB(GLenum target, GLuint index, - GLdouble *params); - -extern void GLAPIENTRY -_mesa_GetNamedProgramLocalParameterdvEXT(GLuint program, GLenum target, - GLuint index, GLdouble *params); - -extern void GLAPIENTRY -_mesa_GetProgramLocalParameterfvARB(GLenum target, GLuint index, - GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetNamedProgramLocalParameterfvEXT(GLuint program, GLenum target, - GLuint index, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetProgramivARB(GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetNamedProgramivEXT(GLuint program, GLenum target, GLenum pname, - GLint *params); - -extern void GLAPIENTRY -_mesa_GetProgramStringARB(GLenum target, GLenum pname, GLvoid *string); - -extern void GLAPIENTRY -_mesa_GetNamedProgramStringEXT(GLuint program, GLenum target, - GLenum pname, GLvoid *string); - -#endif diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c index b668fb762df..e96aaabc91e 100644 --- a/src/mesa/main/arrayobj.c +++ b/src/mesa/main/arrayobj.c @@ -40,7 +40,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "hash.h" #include "image.h" @@ -56,7 +56,7 @@ #include "util/u_atomic.h" #include "util/u_math.h" #include "util/u_memory.h" - +#include "api_exec_decl.h" const GLubyte _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = @@ -75,7 +75,6 @@ _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = VERT_ATTRIB_COLOR1, /* VERT_ATTRIB_COLOR1 */ VERT_ATTRIB_FOG, /* VERT_ATTRIB_FOG */ VERT_ATTRIB_COLOR_INDEX, /* VERT_ATTRIB_COLOR_INDEX */ - VERT_ATTRIB_EDGEFLAG, /* VERT_ATTRIB_EDGEFLAG */ VERT_ATTRIB_TEX0, /* VERT_ATTRIB_TEX0 */ VERT_ATTRIB_TEX1, /* VERT_ATTRIB_TEX1 */ VERT_ATTRIB_TEX2, /* VERT_ATTRIB_TEX2 */ @@ -100,7 +99,8 @@ _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = VERT_ATTRIB_GENERIC12, /* VERT_ATTRIB_GENERIC12 */ VERT_ATTRIB_GENERIC13, /* VERT_ATTRIB_GENERIC13 */ VERT_ATTRIB_GENERIC14, /* VERT_ATTRIB_GENERIC14 */ - VERT_ATTRIB_GENERIC15 /* VERT_ATTRIB_GENERIC15 */ + VERT_ATTRIB_GENERIC15, /* VERT_ATTRIB_GENERIC15 */ + VERT_ATTRIB_EDGEFLAG, /* VERT_ATTRIB_EDGEFLAG */ }, /* ATTRIBUTE_MAP_MODE_POSITION @@ -116,7 +116,6 @@ _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = VERT_ATTRIB_COLOR1, /* VERT_ATTRIB_COLOR1 */ VERT_ATTRIB_FOG, /* VERT_ATTRIB_FOG */ VERT_ATTRIB_COLOR_INDEX, /* VERT_ATTRIB_COLOR_INDEX */ - VERT_ATTRIB_EDGEFLAG, /* VERT_ATTRIB_EDGEFLAG */ VERT_ATTRIB_TEX0, /* VERT_ATTRIB_TEX0 */ VERT_ATTRIB_TEX1, /* VERT_ATTRIB_TEX1 */ VERT_ATTRIB_TEX2, /* VERT_ATTRIB_TEX2 */ @@ -141,7 +140,8 @@ _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = VERT_ATTRIB_GENERIC12, /* VERT_ATTRIB_GENERIC12 */ VERT_ATTRIB_GENERIC13, /* VERT_ATTRIB_GENERIC13 */ VERT_ATTRIB_GENERIC14, /* VERT_ATTRIB_GENERIC14 */ - VERT_ATTRIB_GENERIC15 /* VERT_ATTRIB_GENERIC15 */ + VERT_ATTRIB_GENERIC15, /* VERT_ATTRIB_GENERIC15 */ + VERT_ATTRIB_EDGEFLAG, /* VERT_ATTRIB_EDGEFLAG */ }, /* ATTRIBUTE_MAP_MODE_GENERIC0 @@ -157,7 +157,6 @@ _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = VERT_ATTRIB_COLOR1, /* VERT_ATTRIB_COLOR1 */ VERT_ATTRIB_FOG, /* VERT_ATTRIB_FOG */ VERT_ATTRIB_COLOR_INDEX, /* VERT_ATTRIB_COLOR_INDEX */ - VERT_ATTRIB_EDGEFLAG, /* VERT_ATTRIB_EDGEFLAG */ VERT_ATTRIB_TEX0, /* VERT_ATTRIB_TEX0 */ VERT_ATTRIB_TEX1, /* VERT_ATTRIB_TEX1 */ VERT_ATTRIB_TEX2, /* VERT_ATTRIB_TEX2 */ @@ -182,7 +181,8 @@ _mesa_vao_attribute_map[ATTRIBUTE_MAP_MODE_MAX][VERT_ATTRIB_MAX] = VERT_ATTRIB_GENERIC12, /* VERT_ATTRIB_GENERIC12 */ VERT_ATTRIB_GENERIC13, /* VERT_ATTRIB_GENERIC13 */ VERT_ATTRIB_GENERIC14, /* VERT_ATTRIB_GENERIC14 */ - VERT_ATTRIB_GENERIC15 /* VERT_ATTRIB_GENERIC15 */ + VERT_ATTRIB_GENERIC15, /* VERT_ATTRIB_GENERIC15 */ + VERT_ATTRIB_EDGEFLAG, /* VERT_ATTRIB_EDGEFLAG */ } }; @@ -206,7 +206,7 @@ _mesa_lookup_vao(struct gl_context *ctx, GLuint id) * the name of the vertex array object." */ if (id == 0) { - if (ctx->API == API_OPENGL_COMPAT) + if (_mesa_is_desktop_gl_compat(ctx)) return ctx->Array.DefaultVAO; return NULL; @@ -218,7 +218,7 @@ _mesa_lookup_vao(struct gl_context *ctx, GLuint id) vao = ctx->Array.LastLookedUpVAO; } else { vao = (struct gl_vertex_array_object *) - _mesa_HashLookupLocked(ctx->Array.Objects, id); + _mesa_HashLookupLocked(&ctx->Array.Objects, id); _mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, vao); } @@ -250,7 +250,7 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, * the name of the vertex array object." */ if (id == 0) { - if (is_ext_dsa || ctx->API == API_OPENGL_CORE) { + if (is_ext_dsa || _mesa_is_desktop_gl_core(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(zero is not valid vaobj name%s)", caller, @@ -267,7 +267,7 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, vao = ctx->Array.LastLookedUpVAO; } else { vao = (struct gl_vertex_array_object *) - _mesa_HashLookupLocked(ctx->Array.Objects, id); + _mesa_HashLookupLocked(&ctx->Array.Objects, id); /* The ARB_direct_state_access specification says: * @@ -515,10 +515,12 @@ compute_vbo_offset_range(const struct gl_vertex_array_object *vao, */ void _mesa_update_vao_derived_arrays(struct gl_context *ctx, - struct gl_vertex_array_object *vao) + struct gl_vertex_array_object *vao, + bool display_list) { + assert(display_list || !ctx->Const.UseVAOFastPath); /* Make sure we do not run into problems with shared objects */ - assert(!vao->SharedAndImmutable || vao->NewArrays == 0); + assert(!vao->SharedAndImmutable); /* Limit used for common binding scanning below. */ const GLsizeiptr MaxRelativeOffset = @@ -541,22 +543,6 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx, const GLbitfield enabled = vao->Enabled; /* VBO array bits. */ const GLbitfield vbos = vao->VertexAttribBufferMask; - const GLbitfield divisor_is_nonzero = vao->NonZeroDivisorMask; - - /* Compute and store effectively enabled and mapped vbo arrays */ - vao->_EffEnabledVBO = _mesa_vao_enable_to_vp_inputs(mode, enabled & vbos); - vao->_EffEnabledNonZeroDivisor = - _mesa_vao_enable_to_vp_inputs(mode, enabled & divisor_is_nonzero); - - /* Fast path when the VAO is updated too often. */ - if (vao->IsDynamic) - return; - - /* More than 4 updates turn the VAO to dynamic. */ - if (ctx->Const.AllowDynamicVAOFastPath && ++vao->NumUpdates > 4) { - vao->IsDynamic = true; - return; - } /* Walk those enabled arrays that have a real vbo attached */ GLbitfield mask = enabled; @@ -805,76 +791,6 @@ _mesa_update_vao_derived_arrays(struct gl_context *ctx, } -void -_mesa_set_vao_immutable(struct gl_context *ctx, - struct gl_vertex_array_object *vao) -{ - _mesa_update_vao_derived_arrays(ctx, vao); - vao->NewArrays = 0; - vao->SharedAndImmutable = true; -} - - -bool -_mesa_all_varyings_in_vbos(const struct gl_vertex_array_object *vao) -{ - /* Walk those enabled arrays that have the default vbo attached */ - GLbitfield mask = vao->Enabled & ~vao->VertexAttribBufferMask; - - while (mask) { - /* Do not use u_bit_scan64 as we can walk multiple - * attrib arrays at once - */ - const int i = ffs(mask) - 1; - const struct gl_array_attributes *attrib_array = - &vao->VertexAttrib[i]; - const struct gl_vertex_buffer_binding *buffer_binding = - &vao->BufferBinding[attrib_array->BufferBindingIndex]; - - /* We have already masked out vao->VertexAttribBufferMask */ - assert(!buffer_binding->BufferObj); - - /* Bail out once we find the first non vbo with a non zero stride */ - if (buffer_binding->Stride != 0) - return false; - - /* Note that we cannot use the xor variant since the _BoundArray mask - * may contain array attributes that are bound but not enabled. - */ - mask &= ~buffer_binding->_BoundArrays; - } - - return true; -} - -bool -_mesa_all_buffers_are_unmapped(const struct gl_vertex_array_object *vao) -{ - /* Walk the enabled arrays that have a vbo attached */ - GLbitfield mask = vao->Enabled & vao->VertexAttribBufferMask; - - while (mask) { - const int i = ffs(mask) - 1; - const struct gl_array_attributes *attrib_array = - &vao->VertexAttrib[i]; - const struct gl_vertex_buffer_binding *buffer_binding = - &vao->BufferBinding[attrib_array->BufferBindingIndex]; - - /* We have already masked with vao->VertexAttribBufferMask */ - assert(buffer_binding->BufferObj); - - /* Bail out once we find the first disallowed mapping */ - if (_mesa_check_disallowed_mapping(buffer_binding->BufferObj)) - return false; - - /* We have handled everything that is bound to this buffer_binding. */ - mask &= ~buffer_binding->_BoundArrays; - } - - return true; -} - - /** * Map buffer objects used in attribute arrays. */ @@ -895,7 +811,7 @@ _mesa_vao_map_arrays(struct gl_context *ctx, struct gl_vertex_array_object *vao, if (_mesa_bufferobj_mapped(bo, MAP_INTERNAL)) continue; - ctx->Driver.MapBufferRange(ctx, 0, bo->Size, access, bo, MAP_INTERNAL); + _mesa_bufferobj_map_range(ctx, 0, bo->Size, access, bo, MAP_INTERNAL); } } @@ -911,7 +827,7 @@ _mesa_vao_map(struct gl_context *ctx, struct gl_vertex_array_object *vao, /* map the index buffer, if there is one, and not already mapped */ if (bo && !_mesa_bufferobj_mapped(bo, MAP_INTERNAL)) - ctx->Driver.MapBufferRange(ctx, 0, bo->Size, access, bo, MAP_INTERNAL); + _mesa_bufferobj_map_range(ctx, 0, bo->Size, access, bo, MAP_INTERNAL); _mesa_vao_map_arrays(ctx, vao, access); } @@ -937,7 +853,7 @@ _mesa_vao_unmap_arrays(struct gl_context *ctx, if (!_mesa_bufferobj_mapped(bo, MAP_INTERNAL)) continue; - ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL); } } @@ -952,7 +868,7 @@ _mesa_vao_unmap(struct gl_context *ctx, struct gl_vertex_array_object *vao) /* unmap the index buffer, if there is one, and still mapped */ if (bo && _mesa_bufferobj_mapped(bo, MAP_INTERNAL)) - ctx->Driver.UnmapBuffer(ctx, bo, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL); _mesa_vao_unmap_arrays(ctx, vao); } @@ -998,24 +914,13 @@ bind_vertex_array(struct gl_context *ctx, GLuint id, bool no_error) newObj->EverBound = GL_TRUE; } - /* The _DrawArrays pointer is pointing at the VAO being unbound and - * that VAO may be in the process of being deleted. If it's not going - * to be deleted, this will have no effect, because the pointer needs - * to be updated by the VBO module anyway. - * - * Before the VBO module can update the pointer, we have to set it - * to NULL for drivers not to set up arrays which are not bound, - * or to prevent a crash if the VAO being unbound is going to be - * deleted. - */ - _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0); - _mesa_reference_vao(ctx, &ctx->Array.VAO, newObj); + _mesa_set_draw_vao(ctx, newObj); /* Update the valid-to-render state if binding on unbinding default VAO * if drawing with the default VAO is invalid. */ - if (ctx->API == API_OPENGL_CORE && + if (_mesa_is_desktop_gl_core(ctx) && (oldObj == ctx->Array.DefaultVAO) != (newObj == ctx->Array.DefaultVAO)) _mesa_update_valid_to_render_state(ctx); } @@ -1066,12 +971,10 @@ delete_vertex_arrays(struct gl_context *ctx, GLsizei n, const GLuint *ids) _mesa_BindVertexArray_no_error(0); /* The ID is immediately freed for re-use */ - _mesa_HashRemoveLocked(ctx->Array.Objects, obj->Name); + _mesa_HashRemoveLocked(&ctx->Array.Objects, obj->Name); if (ctx->Array.LastLookedUpVAO == obj) _mesa_reference_vao(ctx, &ctx->Array.LastLookedUpVAO, NULL); - if (ctx->Array._DrawVAO == obj) - _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0); /* Unreference the array object. * If refcount hits zero, the object will be deleted. @@ -1123,7 +1026,7 @@ gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, if (!arrays) return; - _mesa_HashFindFreeKeys(ctx->Array.Objects, arrays, n); + _mesa_HashFindFreeKeys(&ctx->Array.Objects, arrays, n); /* For the sake of simplicity we create the array objects in both * the Gen* and Create* cases. The only difference is the value of @@ -1138,7 +1041,7 @@ gen_vertex_arrays(struct gl_context *ctx, GLsizei n, GLuint *arrays, return; } obj->EverBound = create; - _mesa_HashInsertLocked(ctx->Array.Objects, obj->Name, obj, true); + _mesa_HashInsertLocked(&ctx->Array.Objects, obj->Name, obj); } } @@ -1260,8 +1163,6 @@ vertex_array_element_buffer(struct gl_context *ctx, GLuint vaobj, GLuint buffer, if (!bufObj) return; - - bufObj->UsageHistory |= USAGE_ELEMENT_ARRAY_BUFFER; } else { bufObj = NULL; } diff --git a/src/mesa/main/arrayobj.h b/src/mesa/main/arrayobj.h index 59e2e0c2666..279d7ec2a9a 100644 --- a/src/mesa/main/arrayobj.h +++ b/src/mesa/main/arrayobj.h @@ -27,11 +27,15 @@ #ifndef ARRAYOBJ_H #define ARRAYOBJ_H -#include "glheader.h" +#include "util/glheader.h" #include "mtypes.h" #include "glformats.h" #include "vbo/vbo.h" +#ifdef __cplusplus +extern "C" { +#endif + struct gl_context; /** @@ -85,25 +89,8 @@ _mesa_initialize_vao(struct gl_context *ctx, extern void _mesa_update_vao_derived_arrays(struct gl_context *ctx, - struct gl_vertex_array_object *vao); - - -/** - * Mark the vao as shared and immutable, do remaining updates. - */ -extern void -_mesa_set_vao_immutable(struct gl_context *ctx, - struct gl_vertex_array_object *vao); - - -/* Returns true if all varying arrays reside in vbos */ -extern bool -_mesa_all_varyings_in_vbos(const struct gl_vertex_array_object *vao); - -/* Returns true if all vbos are unmapped */ -extern bool -_mesa_all_buffers_are_unmapped(const struct gl_vertex_array_object *vao); - + struct gl_vertex_array_object *vao, + bool display_list); extern void _mesa_vao_map_arrays(struct gl_context *ctx, struct gl_vertex_array_object *vao, @@ -157,73 +144,61 @@ _mesa_vao_enable_to_vp_inputs(gl_attribute_map_mode mode, GLbitfield enabled) } } - -/** - * Helper functions for consuming backends to walk the - * ctx->Array._DrawVAO for driver side array setup. - * Note that mesa provides preprocessed minimal binding information - * in the VAO. See _mesa_update_vao_derived_arrays for documentation. - */ - -/** - * Return enabled vertex attribute bits for draw. - */ -static inline GLbitfield -_mesa_draw_array_bits(const struct gl_context *ctx) -{ - return ctx->Array._DrawVAOEnabledAttribs; -} - - /** - * Return enabled buffer object vertex attribute bits for draw. - * - * Needs the a fully updated VAO ready for draw. + * Return enabled vertex arrays. The bitmask is trimmed based on POS/GENERIC0 + * remapping, and generic varyings are masked out for fixed-func shaders. */ static inline GLbitfield -_mesa_draw_vbo_array_bits(const struct gl_context *ctx) +_mesa_get_enabled_vertex_arrays(const struct gl_context *ctx) { - const struct gl_vertex_array_object *const vao = ctx->Array._DrawVAO; - assert(vao->NewArrays == 0); - return vao->_EffEnabledVBO & ctx->Array._DrawVAOEnabledAttribs; + return ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode; } /** - * Return enabled user space vertex attribute bits for draw. + * Return the enabled user (= non-VBO) attrib mask and the non-zero divisor + * attrib mask for the draw. * - * Needs the a fully updated VAO ready for draw. + * Needs a fully updated VAO ready for draw. */ -static inline GLbitfield -_mesa_draw_user_array_bits(const struct gl_context *ctx) +static inline void +_mesa_get_derived_vao_masks(const struct gl_context *ctx, + const GLbitfield enabled_attribs, + GLbitfield *enabled_user_attribs, + GLbitfield *nonzero_divisor_attribs) { const struct gl_vertex_array_object *const vao = ctx->Array._DrawVAO; - assert(vao->NewArrays == 0); - return ~vao->_EffEnabledVBO & ctx->Array._DrawVAOEnabledAttribs; -} + const GLbitfield enabled = vao->Enabled; + const GLbitfield enabled_nonuser = enabled & vao->VertexAttribBufferMask; + const GLbitfield enabled_nonzero_divisor = enabled & vao->NonZeroDivisorMask; + *enabled_user_attribs = ~enabled_nonuser & enabled_attribs; + *nonzero_divisor_attribs = enabled_nonzero_divisor & enabled_attribs; -/** - * Return which enabled vertex attributes have a non-zero instance divisor. - * - * Needs the a fully updated VAO ready for draw. - */ -static inline GLbitfield -_mesa_draw_nonzero_divisor_bits(const struct gl_context *ctx) -{ - const struct gl_vertex_array_object *const vao = ctx->Array._DrawVAO; - assert(vao->NewArrays == 0); - return vao->_EffEnabledNonZeroDivisor & ctx->Array._DrawVAOEnabledAttribs; -} - + switch (vao->_AttributeMapMode) { + case ATTRIBUTE_MAP_MODE_POSITION: + /* Copy VERT_ATTRIB_POS enable bit into GENERIC0 position */ + *enabled_user_attribs = + (*enabled_user_attribs & ~VERT_BIT_GENERIC0) | + ((*enabled_user_attribs & VERT_BIT_POS) << VERT_ATTRIB_GENERIC0); + *nonzero_divisor_attribs = + (*nonzero_divisor_attribs & ~VERT_BIT_GENERIC0) | + ((*nonzero_divisor_attribs & VERT_BIT_POS) << VERT_ATTRIB_GENERIC0); + break; -/** - * Return enabled current values attribute bits for draw. - */ -static inline GLbitfield -_mesa_draw_current_bits(const struct gl_context *ctx) -{ - return ~ctx->Array._DrawVAOEnabledAttribs & VERT_BIT_ALL; + case ATTRIBUTE_MAP_MODE_GENERIC0: + /* Copy VERT_ATTRIB_GENERIC0 enable bit into POS position */ + *enabled_user_attribs = + (*enabled_user_attribs & ~VERT_BIT_POS) | + ((*enabled_user_attribs & VERT_BIT_GENERIC0) >> VERT_ATTRIB_GENERIC0); + *nonzero_divisor_attribs = + (*nonzero_divisor_attribs & ~VERT_BIT_POS) | + ((*nonzero_divisor_attribs & VERT_BIT_GENERIC0) >> VERT_ATTRIB_GENERIC0); + break; + default: + break; + } } @@ -236,7 +211,6 @@ static inline const struct gl_vertex_buffer_binding* _mesa_draw_buffer_binding_from_attrib(const struct gl_vertex_array_object *vao, const struct gl_array_attributes *attrib) { - assert(vao->NewArrays == 0); return &vao->BufferBinding[attrib->_EffBufferBindingIndex]; } @@ -248,24 +222,12 @@ static inline const struct gl_array_attributes* _mesa_draw_array_attrib(const struct gl_vertex_array_object *vao, gl_vert_attrib attr) { - assert(vao->NewArrays == 0); const gl_attribute_map_mode map_mode = vao->_AttributeMapMode; return &vao->VertexAttrib[_mesa_vao_attribute_map[map_mode][attr]]; } /** - * Return a vertex array vertex format provided the attribute number. - */ -static inline const struct gl_vertex_format * -_mesa_draw_array_format(const struct gl_vertex_array_object *vao, - gl_vert_attrib attr) -{ - return &_mesa_draw_array_attrib(vao, attr)->Format; -} - - -/** * Return vertex buffer binding provided an attribute number. */ static inline const struct gl_vertex_buffer_binding* @@ -324,58 +286,8 @@ _mesa_draw_current_attrib(const struct gl_context *ctx, gl_vert_attrib attr) } -/** - * Return a current value vertex format provided the attribute number. - */ -static inline const struct gl_vertex_format * -_mesa_draw_current_format(const struct gl_context *ctx, gl_vert_attrib attr) -{ - return &_vbo_current_attrib(ctx, attr)->Format; -} - - -/** - * Return true if we have the VERT_ATTRIB_EDGEFLAG array enabled. - */ -static inline bool -_mesa_draw_edge_flag_array_enabled(const struct gl_context *ctx) -{ - return ctx->Array._DrawVAOEnabledAttribs & VERT_BIT_EDGEFLAG; +#ifdef __cplusplus } - - -/* - * API functions - */ - - -void GLAPIENTRY -_mesa_BindVertexArray_no_error(GLuint id); - -void GLAPIENTRY _mesa_BindVertexArray( GLuint id ); - -void GLAPIENTRY -_mesa_DeleteVertexArrays_no_error(GLsizei n, const GLuint *ids); - -void GLAPIENTRY _mesa_DeleteVertexArrays(GLsizei n, const GLuint *ids); - -void GLAPIENTRY -_mesa_GenVertexArrays_no_error(GLsizei n, GLuint *arrays); - -void GLAPIENTRY _mesa_GenVertexArrays(GLsizei n, GLuint *arrays); - -void GLAPIENTRY -_mesa_CreateVertexArrays_no_error(GLsizei n, GLuint *arrays); - -void GLAPIENTRY _mesa_CreateVertexArrays(GLsizei n, GLuint *arrays); - -GLboolean GLAPIENTRY _mesa_IsVertexArray( GLuint id ); - -void GLAPIENTRY -_mesa_VertexArrayElementBuffer_no_error(GLuint vaobj, GLuint buffer); - -void GLAPIENTRY _mesa_VertexArrayElementBuffer(GLuint vaobj, GLuint buffer); - -void GLAPIENTRY _mesa_GetVertexArrayiv(GLuint vaobj, GLenum pname, GLint *param); +#endif #endif /* ARRAYOBJ_H */ diff --git a/src/mesa/main/atifragshader.c b/src/mesa/main/atifragshader.c index a08a1b613a1..e6229647413 100644 --- a/src/mesa/main/atifragshader.c +++ b/src/mesa/main/atifragshader.c @@ -21,7 +21,7 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/hash.h" @@ -32,6 +32,9 @@ #include "program/program.h" #include "program/prog_instruction.h" #include "util/u_memory.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_program.h" #define MESA_DEBUG_ATI_FS 0 @@ -53,6 +56,17 @@ _mesa_new_ati_fragment_shader(struct gl_context *ctx, GLuint id) return s; } +static struct gl_program * +new_ati_fs(struct gl_context *ctx, struct ati_fragment_shader *curProg) +{ + struct gl_program *prog = rzalloc(NULL, struct gl_program); + if (!prog) + return NULL; + + _mesa_init_gl_program(prog, MESA_SHADER_FRAGMENT, curProg->Id, true); + prog->ati_fs = curProg; + return prog; +} /** * Delete the given ati fragment shader @@ -70,7 +84,7 @@ _mesa_delete_ati_fragment_shader(struct gl_context *ctx, struct ati_fragment_sha free(s->SetupInst[i]); } _mesa_reference_program(ctx, &s->Program, NULL); - free(s); + FREE(s); } @@ -202,14 +216,14 @@ _mesa_GenFragmentShadersATI(GLuint range) return 0; } - _mesa_HashLockMutex(ctx->Shared->ATIShaders); + _mesa_HashLockMutex(&ctx->Shared->ATIShaders); - first = _mesa_HashFindFreeKeyBlock(ctx->Shared->ATIShaders, range); + first = _mesa_HashFindFreeKeyBlock(&ctx->Shared->ATIShaders, range); for (i = 0; i < range; i++) { - _mesa_HashInsertLocked(ctx->Shared->ATIShaders, first + i, &DummyShader, true); + _mesa_HashInsertLocked(&ctx->Shared->ATIShaders, first + i, &DummyShader); } - _mesa_HashUnlockMutex(ctx->Shared->ATIShaders); + _mesa_HashUnlockMutex(&ctx->Shared->ATIShaders); return first; } @@ -236,7 +250,7 @@ _mesa_BindFragmentShaderATI(GLuint id) if (curProg->Id != 0) { curProg->RefCount--; if (curProg->RefCount <= 0) { - _mesa_HashRemove(ctx->Shared->ATIShaders, id); + _mesa_HashRemove(&ctx->Shared->ATIShaders, id); } } @@ -245,10 +259,8 @@ _mesa_BindFragmentShaderATI(GLuint id) newProg = ctx->Shared->DefaultFragmentShader; } else { - bool isGenName; newProg = (struct ati_fragment_shader *) - _mesa_HashLookup(ctx->Shared->ATIShaders, id); - isGenName = newProg != NULL; + _mesa_HashLookup(&ctx->Shared->ATIShaders, id); if (!newProg || newProg == &DummyShader) { /* allocate a new program now */ newProg = _mesa_new_ati_fragment_shader(ctx, id); @@ -256,7 +268,7 @@ _mesa_BindFragmentShaderATI(GLuint id) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFragmentShaderATI"); return; } - _mesa_HashInsert(ctx->Shared->ATIShaders, id, newProg, isGenName); + _mesa_HashInsert(&ctx->Shared->ATIShaders, id, newProg); } } @@ -281,9 +293,9 @@ _mesa_DeleteFragmentShaderATI(GLuint id) if (id != 0) { struct ati_fragment_shader *prog = (struct ati_fragment_shader *) - _mesa_HashLookup(ctx->Shared->ATIShaders, id); + _mesa_HashLookup(&ctx->Shared->ATIShaders, id); if (prog == &DummyShader) { - _mesa_HashRemove(ctx->Shared->ATIShaders, id); + _mesa_HashRemove(&ctx->Shared->ATIShaders, id); } else if (prog) { if (ctx->ATIFragmentShader.Current && @@ -294,7 +306,7 @@ _mesa_DeleteFragmentShaderATI(GLuint id) } /* The ID is immediately available for re-use now */ - _mesa_HashRemove(ctx->Shared->ATIShaders, id); + _mesa_HashRemove(&ctx->Shared->ATIShaders, id); if (prog) { prog->RefCount--; if (prog->RefCount <= 0) { @@ -412,17 +424,38 @@ _mesa_EndFragmentShaderATI(void) } #endif - if (ctx->Driver.NewATIfs) { - struct gl_program *prog = ctx->Driver.NewATIfs(ctx, - ctx->ATIFragmentShader.Current); - _mesa_reference_program(ctx, &ctx->ATIFragmentShader.Current->Program, - NULL); - /* Don't use _mesa_reference_program(), just take ownership */ - ctx->ATIFragmentShader.Current->Program = prog; + struct gl_program *prog = new_ati_fs(ctx, + ctx->ATIFragmentShader.Current); + _mesa_reference_program(ctx, &ctx->ATIFragmentShader.Current->Program, + NULL); + /* Don't use _mesa_reference_program(), just take ownership */ + ctx->ATIFragmentShader.Current->Program = prog; + + prog->SamplersUsed = 0; + prog->Parameters = _mesa_new_parameter_list(); + + /* fill in SamplersUsed, TexturesUsed */ + for (unsigned pass = 0; pass < curProg->NumPasses; pass++) { + for (unsigned r = 0; r < MAX_NUM_FRAGMENT_REGISTERS_ATI; r++) { + struct atifs_setupinst *texinst = &curProg->SetupInst[pass][r]; + + if (texinst->Opcode == ATI_FRAGMENT_SHADER_SAMPLE_OP) { + /* by default there is 1:1 mapping between samplers and textures */ + prog->SamplersUsed |= (1 << r); + /* the target is unknown here, it will be fixed in the draw call */ + prog->TexturesUsed[r] = TEXTURE_2D_BIT; + } + } + } + + /* we always have the ATI_fs constants */ + for (unsigned i = 0; i < MAX_NUM_FRAGMENT_CONSTANTS_ATI; i++) { + _mesa_add_parameter(prog->Parameters, PROGRAM_UNIFORM, + NULL, 4, GL_FLOAT, NULL, NULL, true); } - if (!ctx->Driver.ProgramStringNotify(ctx, GL_FRAGMENT_SHADER_ATI, - curProg->Program)) { + if (!st_program_string_notify(ctx, GL_FRAGMENT_SHADER_ATI, + curProg->Program)) { ctx->ATIFragmentShader.Current->isValid = GL_FALSE; /* XXX is this the right error? */ _mesa_error(ctx, GL_INVALID_OPERATION, @@ -815,7 +848,8 @@ _mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value) curProg->LocalConstDef |= 1 << dstindex; } else { - FLUSH_VERTICES(ctx, _NEW_PROGRAM, 0); + FLUSH_VERTICES(ctx, 0, 0); + ctx->NewDriverState |= ST_NEW_FS_CONSTANTS; COPY_4V(ctx->ATIFragmentShader.GlobalConstants[dstindex], value); } } diff --git a/src/mesa/main/atifragshader.h b/src/mesa/main/atifragshader.h index 0e32795da3b..edf3f5d164e 100644 --- a/src/mesa/main/atifragshader.h +++ b/src/mesa/main/atifragshader.h @@ -8,7 +8,7 @@ #ifndef ATIFRAGSHADER_H #define ATIFRAGSHADER_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; @@ -69,58 +69,4 @@ extern void _mesa_delete_ati_fragment_shader(struct gl_context *ctx, struct ati_fragment_shader *s); - -extern GLuint GLAPIENTRY _mesa_GenFragmentShadersATI(GLuint range); - -extern void GLAPIENTRY _mesa_BindFragmentShaderATI(GLuint id); - -extern void GLAPIENTRY _mesa_DeleteFragmentShaderATI(GLuint id); - -extern void GLAPIENTRY _mesa_BeginFragmentShaderATI(void); - -extern void GLAPIENTRY _mesa_EndFragmentShaderATI(void); - -extern void GLAPIENTRY -_mesa_PassTexCoordATI(GLuint dst, GLuint coord, GLenum swizzle); - -extern void GLAPIENTRY -_mesa_SampleMapATI(GLuint dst, GLuint interp, GLenum swizzle); - -extern void GLAPIENTRY -_mesa_ColorFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod); - -extern void GLAPIENTRY -_mesa_ColorFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, - GLuint arg2Mod); - -extern void GLAPIENTRY -_mesa_ColorFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMask, - GLuint dstMod, GLuint arg1, GLuint arg1Rep, - GLuint arg1Mod, GLuint arg2, GLuint arg2Rep, - GLuint arg2Mod, GLuint arg3, GLuint arg3Rep, - GLuint arg3Mod); - -extern void GLAPIENTRY -_mesa_AlphaFragmentOp1ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod); - -extern void GLAPIENTRY -_mesa_AlphaFragmentOp2ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod); - -extern void GLAPIENTRY -_mesa_AlphaFragmentOp3ATI(GLenum op, GLuint dst, GLuint dstMod, GLuint arg1, - GLuint arg1Rep, GLuint arg1Mod, GLuint arg2, - GLuint arg2Rep, GLuint arg2Mod, GLuint arg3, - GLuint arg3Rep, GLuint arg3Mod); - -extern void GLAPIENTRY -_mesa_SetFragmentShaderConstantATI(GLuint dst, const GLfloat * value); - - #endif /* ATIFRAGSHADER_H */ diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 98c4b8afdc7..1c3057957f5 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -23,7 +23,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "glheader.h" +#include "util/glheader.h" #include "accum.h" #include "arrayobj.h" @@ -31,7 +31,6 @@ #include "blend.h" #include "buffers.h" #include "bufferobj.h" -#include "clear.h" #include "context.h" #include "depth.h" #include "enable.h" @@ -49,8 +48,6 @@ #include "shared.h" #include "scissor.h" #include "stencil.h" -#include "texenv.h" -#include "texgen.h" #include "texobj.h" #include "texparam.h" #include "texstate.h" @@ -61,7 +58,11 @@ #include "hash.h" #include <stdbool.h> #include "util/u_memory.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_manager.h" +#include "state_tracker/st_sampler_view.h" static inline bool copy_texture_attribs(struct gl_texture_object *dst, @@ -277,6 +278,7 @@ _mesa_PushAttrib(GLbitfield mask) unsigned num_tex_used = ctx->Texture.NumCurrentTexUsed; for (u = 0; u < num_tex_used; u++) { head->Texture.LodBias[u] = ctx->Texture.Unit[u].LodBias; + head->Texture.LodBiasQuantized[u] = ctx->Texture.Unit[u].LodBiasQuantized; for (tex = 0; tex < NUM_TEXTURE_TARGETS; tex++) { struct gl_texture_object *dst = &head->Texture.SavedObj[u][tex]; @@ -421,10 +423,8 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib_node *ena GL_RASTER_POSITION_UNCLIPPED_IBM); TEST_AND_UPDATE(ctx->Point.SmoothFlag, enable->PointSmooth, GL_POINT_SMOOTH); - if (ctx->Extensions.ARB_point_sprite) { - TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite, - GL_POINT_SPRITE); - } + TEST_AND_UPDATE(ctx->Point.PointSprite, enable->PointSprite, + GL_POINT_SPRITE); TEST_AND_UPDATE(ctx->Polygon.OffsetPoint, enable->PolygonOffsetPoint, GL_POLYGON_OFFSET_POINT); TEST_AND_UPDATE(ctx->Polygon.OffsetLine, enable->PolygonOffsetLine, @@ -509,10 +509,8 @@ pop_enable_group(struct gl_context *ctx, const struct gl_enable_attrib_node *ena TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_RECT_INDEX, GL_TEXTURE_RECTANGLE); } - if (ctx->Extensions.ARB_texture_cube_map) { - TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_CUBE_INDEX, - GL_TEXTURE_CUBE_MAP); - } + TEST_AND_UPDATE_BIT(old_enabled, enabled, TEXTURE_CUBE_INDEX, + GL_TEXTURE_CUBE_MAP); } if (old_gen_enabled != gen_enabled) { @@ -546,79 +544,11 @@ pop_texture_group(struct gl_context *ctx, struct gl_texture_attrib_node *texstat ctx->Texture.CurrentUnit = u; - if (ctx->Driver.TexEnv || ctx->Driver.TexGen) { - /* Slow path for legacy classic drivers. */ - _mesa_set_enable(ctx, GL_TEXTURE_1D, !!(unit->Enabled & TEXTURE_1D_BIT)); - _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, - !!(unit->Enabled & TEXTURE_CUBE_BIT)); - } - if (ctx->Extensions.NV_texture_rectangle) { - _mesa_set_enable(ctx, GL_TEXTURE_RECTANGLE_NV, - !!(unit->Enabled & TEXTURE_RECT_BIT)); - } - - _mesa_TexGeni(GL_S, GL_TEXTURE_GEN_MODE, unit->GenS.Mode); - _mesa_TexGeni(GL_T, GL_TEXTURE_GEN_MODE, unit->GenT.Mode); - _mesa_TexGeni(GL_R, GL_TEXTURE_GEN_MODE, unit->GenR.Mode); - _mesa_TexGeni(GL_Q, GL_TEXTURE_GEN_MODE, unit->GenQ.Mode); - _mesa_TexGenfv(GL_S, GL_OBJECT_PLANE, unit->ObjectPlane[GEN_S]); - _mesa_TexGenfv(GL_T, GL_OBJECT_PLANE, unit->ObjectPlane[GEN_T]); - _mesa_TexGenfv(GL_R, GL_OBJECT_PLANE, unit->ObjectPlane[GEN_R]); - _mesa_TexGenfv(GL_Q, GL_OBJECT_PLANE, unit->ObjectPlane[GEN_Q]); - /* Eye plane done differently to avoid re-transformation */ - { - - COPY_4FV(destUnit->EyePlane[GEN_S], unit->EyePlane[GEN_S]); - COPY_4FV(destUnit->EyePlane[GEN_T], unit->EyePlane[GEN_T]); - COPY_4FV(destUnit->EyePlane[GEN_R], unit->EyePlane[GEN_R]); - COPY_4FV(destUnit->EyePlane[GEN_Q], unit->EyePlane[GEN_Q]); - if (ctx->Driver.TexGen) { - ctx->Driver.TexGen(ctx, GL_S, GL_EYE_PLANE, unit->EyePlane[GEN_S]); - ctx->Driver.TexGen(ctx, GL_T, GL_EYE_PLANE, unit->EyePlane[GEN_T]); - ctx->Driver.TexGen(ctx, GL_R, GL_EYE_PLANE, unit->EyePlane[GEN_R]); - ctx->Driver.TexGen(ctx, GL_Q, GL_EYE_PLANE, unit->EyePlane[GEN_Q]); - } - } - _mesa_set_enable(ctx, GL_TEXTURE_GEN_S, !!(unit->TexGenEnabled & S_BIT)); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_T, !!(unit->TexGenEnabled & T_BIT)); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_R, !!(unit->TexGenEnabled & R_BIT)); - _mesa_set_enable(ctx, GL_TEXTURE_GEN_Q, !!(unit->TexGenEnabled & Q_BIT)); - - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, unit->EnvMode); - _mesa_TexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, unit->EnvColor); - _mesa_TexEnvf(GL_TEXTURE_FILTER_CONTROL, GL_TEXTURE_LOD_BIAS, - texstate->LodBias[u]); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, - unit->Combine.ModeRGB); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, - unit->Combine.ModeA); - { - const GLuint n = ctx->Extensions.NV_texture_env_combine4 ? 4 : 3; - GLuint i; - for (i = 0; i < n; i++) { - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB + i, - unit->Combine.SourceRGB[i]); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA + i, - unit->Combine.SourceA[i]); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_RGB + i, - unit->Combine.OperandRGB[i]); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_OPERAND0_ALPHA + i, - unit->Combine.OperandA[i]); - } - } - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE, - 1 << unit->Combine.ScaleShiftRGB); - _mesa_TexEnvi(GL_TEXTURE_ENV, GL_ALPHA_SCALE, - 1 << unit->Combine.ScaleShiftA); - } else { - /* Fast path for other drivers. */ - memcpy(destUnit, unit, sizeof(*unit)); - destUnit->_CurrentCombine = NULL; - ctx->Texture.Unit[u].LodBias = texstate->LodBias[u]; - } + /* Fast path for other drivers. */ + memcpy(destUnit, unit, sizeof(*unit)); + destUnit->_CurrentCombine = NULL; + ctx->Texture.Unit[u].LodBias = texstate->LodBias[u]; + ctx->Texture.Unit[u].LodBiasQuantized = texstate->LodBiasQuantized[u]; } /* Restore saved textures. */ @@ -663,9 +593,7 @@ pop_texture_group(struct gl_context *ctx, struct gl_texture_attrib_node *texstat if (!copy_texture_attribs(texObj, savedObj, tgt)) continue; - /* GL_ALL_ATTRIB_BITS means all pnames. (internal) */ - if (ctx->Driver.TexParameter) - ctx->Driver.TexParameter(ctx, texObj, GL_ALL_ATTRIB_BITS); + st_texture_release_all_sampler_views(st_context(ctx), texObj); } } @@ -953,69 +881,20 @@ _mesa_PopAttrib(void) if (_math_matrix_is_dirty(ctx->ModelviewMatrixStack.Top)) _math_matrix_analyse(ctx->ModelviewMatrixStack.Top); - if (ctx->Driver.Lightfv) { - /* Legacy slow path for some classic drivers. */ - for (i = 0; i < ctx->Const.MaxLights; i++) { - const struct gl_light_uniforms *lu = &attr->Light.LightSource[i]; - const struct gl_light *l = &attr->Light.Light[i]; - TEST_AND_UPDATE(ctx->Light.Light[i].Enabled, l->Enabled, - GL_LIGHT0 + i); - _mesa_light(ctx, i, GL_AMBIENT, lu->Ambient); - _mesa_light(ctx, i, GL_DIFFUSE, lu->Diffuse); - _mesa_light(ctx, i, GL_SPECULAR, lu->Specular); - _mesa_light(ctx, i, GL_POSITION, lu->EyePosition); - _mesa_light(ctx, i, GL_SPOT_DIRECTION, lu->SpotDirection); - { - GLfloat p[4] = { 0 }; - p[0] = lu->SpotExponent; - _mesa_light(ctx, i, GL_SPOT_EXPONENT, p); - } - { - GLfloat p[4] = { 0 }; - p[0] = lu->SpotCutoff; - _mesa_light(ctx, i, GL_SPOT_CUTOFF, p); - } - { - GLfloat p[4] = { 0 }; - p[0] = lu->ConstantAttenuation; - _mesa_light(ctx, i, GL_CONSTANT_ATTENUATION, p); - } - { - GLfloat p[4] = { 0 }; - p[0] = lu->LinearAttenuation; - _mesa_light(ctx, i, GL_LINEAR_ATTENUATION, p); - } - { - GLfloat p[4] = { 0 }; - p[0] = lu->QuadraticAttenuation; - _mesa_light(ctx, i, GL_QUADRATIC_ATTENUATION, p); - } - } - /* light model */ - _mesa_LightModelfv(GL_LIGHT_MODEL_AMBIENT, - attr->Light.Model.Ambient); - _mesa_LightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, - (GLfloat) attr->Light.Model.LocalViewer); - _mesa_LightModelf(GL_LIGHT_MODEL_TWO_SIDE, - (GLfloat) attr->Light.Model.TwoSide); - _mesa_LightModelf(GL_LIGHT_MODEL_COLOR_CONTROL, - (GLfloat) attr->Light.Model.ColorControl); - } else { - /* Fast path for other drivers. */ - ctx->NewState |= _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM; - - memcpy(ctx->Light.LightSource, attr->Light.LightSource, - sizeof(attr->Light.LightSource)); - memcpy(&ctx->Light.Model, &attr->Light.Model, - sizeof(attr->Light.Model)); - - for (i = 0; i < ctx->Const.MaxLights; i++) { - TEST_AND_UPDATE(ctx->Light.Light[i].Enabled, - attr->Light.Light[i].Enabled, - GL_LIGHT0 + i); - memcpy(&ctx->Light.Light[i], &attr->Light.Light[i], - sizeof(struct gl_light)); - } + /* Fast path for other drivers. */ + ctx->NewState |= _NEW_LIGHT_CONSTANTS | _NEW_FF_VERT_PROGRAM; + + memcpy(ctx->Light.LightSource, attr->Light.LightSource, + sizeof(attr->Light.LightSource)); + memcpy(&ctx->Light.Model, &attr->Light.Model, + sizeof(attr->Light.Model)); + + for (i = 0; i < ctx->Const.MaxLights; i++) { + TEST_AND_UPDATE(ctx->Light.Light[i].Enabled, + attr->Light.Light[i].Enabled, + GL_LIGHT0 + i); + memcpy(&ctx->Light.Light[i], &attr->Light.Light[i], + sizeof(struct gl_light)); } /* shade model */ TEST_AND_CALL1(Light.ShadeModel, ShadeModel); @@ -1053,37 +932,21 @@ _mesa_PopAttrib(void) if (mask & GL_POINT_BIT) { TEST_AND_CALL1(Point.Size, PointSize); TEST_AND_UPDATE(ctx->Point.SmoothFlag, attr->Point.SmoothFlag, GL_POINT_SMOOTH); - if (ctx->Extensions.EXT_point_parameters) { - _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT, - attr->Point.Params); - TEST_AND_CALL1_SEL(Point.MinSize, PointParameterf, GL_POINT_SIZE_MIN_EXT); - TEST_AND_CALL1_SEL(Point.MaxSize, PointParameterf, GL_POINT_SIZE_MAX_EXT); - TEST_AND_CALL1_SEL(Point.Threshold, PointParameterf, GL_POINT_FADE_THRESHOLD_SIZE_EXT); + _mesa_PointParameterfv(GL_DISTANCE_ATTENUATION_EXT, attr->Point.Params); + TEST_AND_CALL1_SEL(Point.MinSize, PointParameterf, GL_POINT_SIZE_MIN_EXT); + TEST_AND_CALL1_SEL(Point.MaxSize, PointParameterf, GL_POINT_SIZE_MAX_EXT); + TEST_AND_CALL1_SEL(Point.Threshold, PointParameterf, GL_POINT_FADE_THRESHOLD_SIZE_EXT); + + if (ctx->Point.CoordReplace != attr->Point.CoordReplace) { + ctx->NewState |= _NEW_POINT | _NEW_FF_VERT_PROGRAM; + ctx->Point.CoordReplace = attr->Point.CoordReplace; } - if (ctx->Extensions.ARB_point_sprite) { - if (ctx->Point.CoordReplace != attr->Point.CoordReplace) { - ctx->NewState |= _NEW_POINT | _NEW_FF_VERT_PROGRAM; - ctx->Point.CoordReplace = attr->Point.CoordReplace; - - if (ctx->Driver.TexEnv) { - unsigned active_texture = ctx->Texture.CurrentUnit; - - for (unsigned i = 0; i < ctx->Const.MaxTextureUnits; i++) { - float param = !!(ctx->Point.CoordReplace & (1 << i)); - ctx->Texture.CurrentUnit = i; - ctx->Driver.TexEnv(ctx, GL_POINT_SPRITE, GL_COORD_REPLACE, - ¶m); - } - ctx->Texture.CurrentUnit = active_texture; - } - } - TEST_AND_UPDATE(ctx->Point.PointSprite, attr->Point.PointSprite, - GL_POINT_SPRITE); + TEST_AND_UPDATE(ctx->Point.PointSprite, attr->Point.PointSprite, + GL_POINT_SPRITE); - if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20) - || ctx->API == API_OPENGL_CORE) - TEST_AND_CALL1_SEL(Point.SpriteOrigin, PointParameterf, GL_POINT_SPRITE_COORD_ORIGIN); - } + if ((_mesa_is_desktop_gl_compat(ctx) && ctx->Version >= 20) + || _mesa_is_desktop_gl_core(ctx)) + TEST_AND_CALL1_SEL(Point.SpriteOrigin, PointParameterf, GL_POINT_SPRITE_COORD_ORIGIN); } if (mask & GL_POLYGON_BIT) { @@ -1109,13 +972,7 @@ _mesa_PopAttrib(void) if (mask & GL_POLYGON_STIPPLE_BIT) { memcpy(ctx->PolygonStipple, attr->PolygonStipple, 32*sizeof(GLuint)); - if (ctx->DriverFlags.NewPolygonStipple) - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonStipple; - else - ctx->NewState |= _NEW_POLYGONSTIPPLE; - - if (ctx->Driver.PolygonStipple) - ctx->Driver.PolygonStipple(ctx, (const GLubyte *) attr->PolygonStipple); + ctx->NewDriverState |= ST_NEW_POLY_STIPPLE; } if (mask & GL_SCISSOR_BIT) { @@ -1176,7 +1033,7 @@ _mesa_PopAttrib(void) _math_matrix_analyse(ctx->ProjectionMatrixStack.Top); ctx->NewState |= _NEW_TRANSFORM; - ctx->NewDriverState |= ctx->DriverFlags.NewClipPlane; + ctx->NewDriverState |= ST_NEW_CLIP_STATE; /* restore clip planes */ for (i = 0; i < ctx->Const.MaxClipPlanes; i++) { @@ -1185,8 +1042,6 @@ _mesa_PopAttrib(void) TEST_AND_UPDATE_BIT(ctx->Transform.ClipPlanesEnabled, attr->Transform.ClipPlanesEnabled, i, GL_CLIP_PLANE0 + i); - if (ctx->Driver.ClipPlane) - ctx->Driver.ClipPlane(ctx, GL_CLIP_PLANE0 + i, eyePlane); } /* normalize/rescale */ @@ -1229,14 +1084,12 @@ _mesa_PopAttrib(void) if (memcmp(&ctx->ViewportArray[i].X, &vp->X, sizeof(float) * 6)) { ctx->NewState |= _NEW_VIEWPORT; - ctx->NewDriverState |= ctx->DriverFlags.NewViewport; + ctx->NewDriverState |= ST_NEW_VIEWPORT; memcpy(&ctx->ViewportArray[i].X, &vp->X, sizeof(float) * 6); - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); - if (ctx->Driver.DepthRange) - ctx->Driver.DepthRange(ctx); + if (ctx->invalidate_on_gl_viewport) + st_manager_invalidate_drawables(ctx); } } @@ -1352,13 +1205,11 @@ copy_array_object(struct gl_context *ctx, /* Enabled must be the same than on push */ dest->Enabled = src->Enabled; dest->_EnabledWithMapMode = src->_EnabledWithMapMode; - dest->_EffEnabledVBO = src->_EffEnabledVBO; - dest->_EffEnabledNonZeroDivisor = src->_EffEnabledNonZeroDivisor; /* The bitmask of bound VBOs needs to match the VertexBinding array */ dest->VertexAttribBufferMask = src->VertexAttribBufferMask; dest->NonZeroDivisorMask = src->NonZeroDivisorMask; + dest->NonIdentityBufferAttribMapping = src->NonIdentityBufferAttribMapping; dest->_AttributeMapMode = src->_AttributeMapMode; - dest->NewArrays = src->NewArrays; /* skip NumUpdates and IsDynamic because they can only increase, not decrease */ } @@ -1455,15 +1306,16 @@ restore_array_attrib(struct gl_context *ctx, copy_array_attrib(ctx, dest, src, true, 0); } - /* Invalidate array state. It will be updated during the next draw. */ - _mesa_set_draw_vao(ctx, ctx->Array._EmptyVAO, 0); - if (is_vao_name_zero || !src->VAO->IndexBufferObj || _mesa_IsBuffer(src->VAO->IndexBufferObj->Name)) { _mesa_BindBuffer(GL_ELEMENT_ARRAY_BUFFER_ARB, src->VAO->IndexBufferObj ? src->VAO->IndexBufferObj->Name : 0); } + + _mesa_update_edgeflag_state_vao(ctx); + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array.VAO->_EnabledWithMapMode); } @@ -1630,7 +1482,7 @@ void _mesa_free_attrib_data(struct gl_context *ctx) { for (unsigned i = 0; i < ARRAY_SIZE(ctx->AttribStack); i++) - free(ctx->AttribStack[i]); + FREE(ctx->AttribStack[i]); } diff --git a/src/mesa/main/attrib.h b/src/mesa/main/attrib.h index 90951306fd5..577e2a0e80f 100644 --- a/src/mesa/main/attrib.h +++ b/src/mesa/main/attrib.h @@ -26,29 +26,11 @@ #define ATTRIB_H -#include "glheader.h" +#include "util/glheader.h" struct _glapi_table; struct gl_context; -extern void GLAPIENTRY -_mesa_PushAttrib( GLbitfield mask ); - -extern void GLAPIENTRY -_mesa_PopAttrib( void ); - -extern void GLAPIENTRY -_mesa_PushClientAttrib( GLbitfield mask ); - -extern void GLAPIENTRY -_mesa_PopClientAttrib( void ); - -extern void GLAPIENTRY -_mesa_ClientAttribDefaultEXT( GLbitfield mask ); - -extern void GLAPIENTRY -_mesa_PushClientAttribDefaultEXT( GLbitfield mask ); - extern void _mesa_init_attrib( struct gl_context *ctx ); diff --git a/src/mesa/main/barrier.c b/src/mesa/main/barrier.c index 2be30220e49..4647e28e033 100644 --- a/src/mesa/main/barrier.c +++ b/src/mesa/main/barrier.c @@ -29,19 +29,71 @@ */ #include "context.h" -#include "barrier.h" +#include "api_exec_decl.h" +#include "pipe/p_context.h" -static void -_mesa_texture_barrier(struct gl_context *ctx) -{ - /* no-op */ -} -void -_mesa_init_barrier_functions(struct dd_function_table *driver) +static void +memory_barrier(struct gl_context *ctx, GLbitfield barriers) { - driver->TextureBarrier = _mesa_texture_barrier; + struct pipe_context *pipe = ctx->pipe; + unsigned flags = 0; + + if (barriers & GL_VERTEX_ATTRIB_ARRAY_BARRIER_BIT) + flags |= PIPE_BARRIER_VERTEX_BUFFER; + if (barriers & GL_ELEMENT_ARRAY_BARRIER_BIT) + flags |= PIPE_BARRIER_INDEX_BUFFER; + if (barriers & GL_UNIFORM_BARRIER_BIT) + flags |= PIPE_BARRIER_CONSTANT_BUFFER; + if (barriers & GL_TEXTURE_FETCH_BARRIER_BIT) + flags |= PIPE_BARRIER_TEXTURE; + if (barriers & GL_SHADER_IMAGE_ACCESS_BARRIER_BIT) + flags |= PIPE_BARRIER_IMAGE; + if (barriers & GL_COMMAND_BARRIER_BIT) + flags |= PIPE_BARRIER_INDIRECT_BUFFER; + if (barriers & GL_PIXEL_BUFFER_BARRIER_BIT) { + /* The PBO may be + * (1) bound as a texture for PBO uploads, or + * (2) accessed by the CPU via transfer ops. + * For case (2), we assume automatic flushing by the driver. + */ + flags |= PIPE_BARRIER_TEXTURE; + } + if (barriers & GL_TEXTURE_UPDATE_BARRIER_BIT) { + /* GL_TEXTURE_UPDATE_BARRIER_BIT: + * Texture updates translate to: + * (1) texture transfers to/from the CPU, + * (2) texture as blit destination, or + * (3) texture as framebuffer. + * Some drivers may handle these automatically, and can ignore the bit. + */ + flags |= PIPE_BARRIER_UPDATE_TEXTURE; + } + if (barriers & GL_BUFFER_UPDATE_BARRIER_BIT) { + /* GL_BUFFER_UPDATE_BARRIER_BIT: + * Buffer updates translate to + * (1) buffer transfers to/from the CPU, + * (2) resource copies and clears. + * Some drivers may handle these automatically, and can ignore the bit. + */ + flags |= PIPE_BARRIER_UPDATE_BUFFER; + } + if (barriers & GL_CLIENT_MAPPED_BUFFER_BARRIER_BIT) + flags |= PIPE_BARRIER_MAPPED_BUFFER; + if (barriers & GL_QUERY_BUFFER_BARRIER_BIT) + flags |= PIPE_BARRIER_QUERY_BUFFER; + if (barriers & GL_FRAMEBUFFER_BARRIER_BIT) + flags |= PIPE_BARRIER_FRAMEBUFFER; + if (barriers & GL_TRANSFORM_FEEDBACK_BARRIER_BIT) + flags |= PIPE_BARRIER_STREAMOUT_BUFFER; + if (barriers & GL_ATOMIC_COUNTER_BARRIER_BIT) + flags |= PIPE_BARRIER_SHADER_BUFFER; + if (barriers & GL_SHADER_STORAGE_BARRIER_BIT) + flags |= PIPE_BARRIER_SHADER_BUFFER; + + if (flags && pipe->memory_barrier) + pipe->memory_barrier(pipe, flags); } void GLAPIENTRY @@ -55,7 +107,7 @@ _mesa_TextureBarrierNV(void) return; } - ctx->Driver.TextureBarrier(ctx); + ctx->pipe->texture_barrier(ctx->pipe, PIPE_TEXTURE_BARRIER_SAMPLER); } void GLAPIENTRY @@ -63,8 +115,7 @@ _mesa_MemoryBarrier(GLbitfield barriers) { GET_CURRENT_CONTEXT(ctx); - if (ctx->Driver.MemoryBarrier) - ctx->Driver.MemoryBarrier(ctx, barriers); + memory_barrier(ctx, barriers); } static ALWAYS_INLINE void @@ -78,34 +129,32 @@ memory_barrier_by_region(struct gl_context *ctx, GLbitfield barriers, GL_TEXTURE_FETCH_BARRIER_BIT | GL_UNIFORM_BARRIER_BIT; - if (ctx->Driver.MemoryBarrier) { - /* From section 7.11.2 of the OpenGL ES 3.1 specification: - * - * "When barriers is ALL_BARRIER_BITS, shader memory accesses will be - * synchronized relative to all these barrier bits, but not to other - * barrier bits specific to MemoryBarrier." - * - * That is, if barriers is the special value GL_ALL_BARRIER_BITS, then all - * barriers allowed by glMemoryBarrierByRegion should be activated." - */ - if (barriers == GL_ALL_BARRIER_BITS) { - ctx->Driver.MemoryBarrier(ctx, all_allowed_bits); - return; - } - - /* From section 7.11.2 of the OpenGL ES 3.1 specification: - * - * "An INVALID_VALUE error is generated if barriers is not the special - * value ALL_BARRIER_BITS, and has any bits set other than those - * described above." - */ - if (!no_error && (barriers & ~all_allowed_bits) != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glMemoryBarrierByRegion(unsupported barrier bit"); - } + /* From section 7.11.2 of the OpenGL ES 3.1 specification: + * + * "When barriers is ALL_BARRIER_BITS, shader memory accesses will be + * synchronized relative to all these barrier bits, but not to other + * barrier bits specific to MemoryBarrier." + * + * That is, if barriers is the special value GL_ALL_BARRIER_BITS, then all + * barriers allowed by glMemoryBarrierByRegion should be activated." + */ + if (barriers == GL_ALL_BARRIER_BITS) { + memory_barrier(ctx, all_allowed_bits); + return; + } - ctx->Driver.MemoryBarrier(ctx, barriers); + /* From section 7.11.2 of the OpenGL ES 3.1 specification: + * + * "An INVALID_VALUE error is generated if barriers is not the special + * value ALL_BARRIER_BITS, and has any bits set other than those + * described above." + */ + if (!no_error && (barriers & ~all_allowed_bits) != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glMemoryBarrierByRegion(unsupported barrier bit"); } + + memory_barrier(ctx, barriers); } void GLAPIENTRY @@ -133,7 +182,7 @@ _mesa_BlendBarrier(void) return; } - ctx->Driver.FramebufferFetchBarrier(ctx); + ctx->pipe->texture_barrier(ctx->pipe, PIPE_TEXTURE_BARRIER_FRAMEBUFFER); } void GLAPIENTRY @@ -147,5 +196,5 @@ _mesa_FramebufferFetchBarrierEXT(void) return; } - ctx->Driver.FramebufferFetchBarrier(ctx); + ctx->pipe->texture_barrier(ctx->pipe, PIPE_TEXTURE_BARRIER_FRAMEBUFFER); } diff --git a/src/mesa/main/barrier.h b/src/mesa/main/barrier.h deleted file mode 100644 index acc15c67794..00000000000 --- a/src/mesa/main/barrier.h +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright © 2011 Marek Olšák <maraeo@gmail.com> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \file barrier.h - * GL_NV_texture_barrier and friends. - * - * \author Marek Olšák <maraeo@gmail.com> - */ - -#ifndef BARRIER_H -#define BARRIER_H - -#include "glheader.h" - -struct dd_function_table; - -extern void -_mesa_init_barrier_functions(struct dd_function_table *driver); - -extern void GLAPIENTRY -_mesa_TextureBarrierNV(void); - -void GLAPIENTRY -_mesa_MemoryBarrier(GLbitfield barriers); - -void GLAPIENTRY -_mesa_MemoryBarrierByRegion_no_error(GLbitfield barriers); - -void GLAPIENTRY -_mesa_MemoryBarrierByRegion(GLbitfield barriers); - -void GLAPIENTRY -_mesa_BlendBarrier(void); - -void GLAPIENTRY -_mesa_FramebufferFetchBarrierEXT(void); - -#endif /* BARRIER_H */ diff --git a/src/mesa/main/bbox.c b/src/mesa/main/bbox.c index 21843308bf6..72fce30592d 100644 --- a/src/mesa/main/bbox.c +++ b/src/mesa/main/bbox.c @@ -30,6 +30,7 @@ #include "bbox.h" #include "context.h" +#include "api_exec_decl.h" void GLAPIENTRY _mesa_PrimitiveBoundingBox( diff --git a/src/mesa/main/bbox.h b/src/mesa/main/bbox.h index d00f87ea93f..97e356a3306 100644 --- a/src/mesa/main/bbox.h +++ b/src/mesa/main/bbox.h @@ -27,15 +27,10 @@ #ifndef BBOX_H #define BBOX_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -extern void GLAPIENTRY -_mesa_PrimitiveBoundingBox( - GLfloat minX, GLfloat minY, GLfloat minZ, GLfloat minW, - GLfloat maxX, GLfloat maxY, GLfloat maxZ, GLfloat maxW); - extern void _mesa_init_bbox(struct gl_context *ctx); diff --git a/src/mesa/main/blend.c b/src/mesa/main/blend.c index fa01fa49097..e8c211ede61 100644 --- a/src/mesa/main/blend.c +++ b/src/mesa/main/blend.c @@ -29,7 +29,7 @@ -#include "glheader.h" +#include "util/glheader.h" #include "blend.h" #include "context.h" #include "draw_validate.h" @@ -37,6 +37,7 @@ #include "macros.h" #include "mtypes.h" #include "state.h" +#include "api_exec_decl.h" @@ -64,7 +65,7 @@ legal_src_factor(const struct gl_context *ctx, GLenum factor) case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: - return _mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES2; + return _mesa_is_desktop_gl(ctx) || _mesa_is_gles2(ctx); case GL_SRC1_COLOR: case GL_SRC1_ALPHA: case GL_ONE_MINUS_SRC1_COLOR: @@ -100,7 +101,7 @@ legal_dst_factor(const struct gl_context *ctx, GLenum factor) case GL_ONE_MINUS_CONSTANT_COLOR: case GL_CONSTANT_ALPHA: case GL_ONE_MINUS_CONSTANT_ALPHA: - return _mesa_is_desktop_gl(ctx) || ctx->API == API_OPENGLES2; + return _mesa_is_desktop_gl(ctx) || _mesa_is_gles2(ctx); case GL_SRC_ALPHA_SATURATE: return (ctx->API != API_OPENGLES && ctx->Extensions.ARB_blend_func_extended) @@ -239,9 +240,8 @@ blend_func_separate(struct gl_context *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; const unsigned numBuffers = num_buffers(ctx); for (unsigned buf = 0; buf < numBuffers; buf++) { @@ -263,11 +263,6 @@ blend_func_separate(struct gl_context *ctx, _mesa_update_valid_to_render_state(ctx); ctx->Color._BlendFuncPerBuffer = GL_FALSE; - - if (ctx->Driver.BlendFuncSeparate) { - ctx->Driver.BlendFuncSeparate(ctx, sfactorRGB, dfactorRGB, - sfactorA, dfactorA); - } } @@ -406,9 +401,8 @@ blend_func_separatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, return; } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.Blend[buf].SrcRGB = sfactorRGB; ctx->Color.Blend[buf].DstRGB = dfactorRGB; @@ -453,10 +447,9 @@ legal_simple_blend_equation(const struct gl_context *ctx, GLenum mode) case GL_FUNC_ADD: case GL_FUNC_SUBTRACT: case GL_FUNC_REVERSE_SUBTRACT: - return GL_TRUE; case GL_MIN: case GL_MAX: - return ctx->Extensions.EXT_blend_minmax; + return GL_TRUE; default: return GL_FALSE; } @@ -574,9 +567,6 @@ _mesa_BlendEquation( GLenum mode ) } ctx->Color._BlendEquationPerBuffer = GL_FALSE; set_advanced_blend_mode(ctx, advanced_mode); - - if (ctx->Driver.BlendEquationSeparate) - ctx->Driver.BlendEquationSeparate(ctx, mode, mode); } @@ -698,9 +688,6 @@ blend_equation_separate(struct gl_context *ctx, GLenum modeRGB, GLenum modeA, } ctx->Color._BlendEquationPerBuffer = GL_FALSE; set_advanced_blend_mode(ctx, BLEND_NONE); - - if (ctx->Driver.BlendEquationSeparate) - ctx->Driver.BlendEquationSeparate(ctx, modeRGB, modeA); } @@ -820,18 +807,14 @@ _mesa_BlendColor( GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha ) if (TEST_EQ_4V(tmp, ctx->Color.BlendColorUnclamped)) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlendColor ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlendColor; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND_COLOR; COPY_4FV( ctx->Color.BlendColorUnclamped, tmp ); ctx->Color.BlendColor[0] = CLAMP(tmp[0], 0.0F, 1.0F); ctx->Color.BlendColor[1] = CLAMP(tmp[1], 0.0F, 1.0F); ctx->Color.BlendColor[2] = CLAMP(tmp[2], 0.0F, 1.0F); ctx->Color.BlendColor[3] = CLAMP(tmp[3], 0.0F, 1.0F); - - if (ctx->Driver.BlendColor) - ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); } @@ -866,15 +849,11 @@ _mesa_AlphaFunc( GLenum func, GLclampf ref ) case GL_NOTEQUAL: case GL_GEQUAL: case GL_ALWAYS: - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewAlphaTest ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); ctx->NewDriverState |= ctx->DriverFlags.NewAlphaTest; ctx->Color.AlphaFunc = func; ctx->Color.AlphaRefUnclamped = ref; ctx->Color.AlphaRef = CLAMP(ref, 0.0F, 1.0F); - - if (ctx->Driver.AlphaFunc) - ctx->Driver.AlphaFunc(ctx, func, ctx->Color.AlphaRef); return; default: @@ -933,15 +912,11 @@ logic_op(struct gl_context *ctx, GLenum opcode, bool no_error) } } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLogicOp ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.LogicOp = opcode; ctx->Color._LogicOp = color_logicop_mapping[opcode & 0x0f]; _mesa_update_allow_draw_out_of_order(ctx); - - if (ctx->Driver.LogicOpcode) - ctx->Driver.LogicOpcode(ctx, ctx->Color._LogicOp); } @@ -983,9 +958,8 @@ _mesa_IndexMask( GLuint mask ) if (ctx->Color.IndexMask == mask) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewColorMask ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewColorMask; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.IndexMask = mask; } @@ -1023,14 +997,10 @@ _mesa_ColorMask( GLboolean red, GLboolean green, if (ctx->Color.ColorMask == mask) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewColorMask ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewColorMask; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.ColorMask = mask; _mesa_update_allow_draw_out_of_order(ctx); - - if (ctx->Driver.ColorMask) - ctx->Driver.ColorMask( ctx, red, green, blue, alpha ); } @@ -1060,9 +1030,8 @@ _mesa_ColorMaski(GLuint buf, GLboolean red, GLboolean green, if (GET_COLORMASK(ctx->Color.ColorMask, buf) == mask) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewColorMask ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewColorMask; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.ColorMask &= ~(0xf << (4 * buf)); ctx->Color.ColorMask |= mask << (4 * buf); _mesa_update_allow_draw_out_of_order(ctx); @@ -1089,14 +1058,14 @@ _mesa_ClampColor(GLenum target, GLenum clamp) switch (target) { case GL_CLAMP_VERTEX_COLOR_ARB: - if (ctx->API == API_OPENGL_CORE) + if (_mesa_is_desktop_gl_core(ctx)) goto invalid_enum; FLUSH_VERTICES(ctx, _NEW_LIGHT_STATE, GL_LIGHTING_BIT | GL_ENABLE_BIT); ctx->Light.ClampVertexColor = clamp; _mesa_update_clamp_vertex_color(ctx, ctx->DrawBuffer); break; case GL_CLAMP_FRAGMENT_COLOR_ARB: - if (ctx->API == API_OPENGL_CORE) + if (_mesa_is_desktop_gl_core(ctx)) goto invalid_enum; if (ctx->Color.ClampFragmentColor != clamp) { FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); @@ -1191,24 +1160,6 @@ _mesa_update_clamp_vertex_color(struct gl_context *ctx, _mesa_get_clamp_vertex_color(ctx, drawFb); } -/** - * Returns an appropriate mesa_format for color rendering based on the - * GL_FRAMEBUFFER_SRGB state. - * - * Some drivers implement GL_FRAMEBUFFER_SRGB using a flag on the blend state - * (which GL_FRAMEBUFFER_SRGB maps to reasonably), but some have to do so by - * overriding the format of the surface. This is a helper for doing the - * surface format override variant. - */ -mesa_format -_mesa_get_render_format(const struct gl_context *ctx, mesa_format format) -{ - if (ctx->Color.sRGBEnabled) - return format; - else - return _mesa_get_srgb_format_linear(format); -} - /**********************************************************************/ /** \name Initialization */ /*@{*/ @@ -1259,7 +1210,7 @@ void _mesa_init_color( struct gl_context * ctx ) ctx->Color.DrawBuffer[0] = GL_FRONT; } - ctx->Color.ClampFragmentColor = ctx->API == API_OPENGL_COMPAT ? + ctx->Color.ClampFragmentColor = _mesa_is_desktop_gl_compat(ctx) ? GL_FIXED_ONLY_ARB : GL_FALSE; ctx->Color._ClampFragmentColor = GL_FALSE; ctx->Color.ClampReadColor = GL_FIXED_ONLY_ARB; diff --git a/src/mesa/main/blend.h b/src/mesa/main/blend.h index 8830ca50ea3..93d37575629 100644 --- a/src/mesa/main/blend.h +++ b/src/mesa/main/blend.h @@ -33,100 +33,16 @@ #define BLEND_H -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "formats.h" #include "extensions.h" +#include "state_tracker/st_context.h" + struct gl_context; struct gl_framebuffer; - -extern void GLAPIENTRY -_mesa_BlendFunc( GLenum sfactor, GLenum dfactor ); - -extern void GLAPIENTRY -_mesa_BlendFunc_no_error(GLenum sfactor, GLenum dfactor); - -extern void GLAPIENTRY -_mesa_BlendFuncSeparate( GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorA, GLenum dfactorA ); - -extern void GLAPIENTRY -_mesa_BlendFuncSeparate_no_error(GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorA, GLenum dfactorA); - -extern void GLAPIENTRY -_mesa_BlendFunciARB_no_error(GLuint buf, GLenum sfactor, GLenum dfactor); -extern void GLAPIENTRY -_mesa_BlendFunciARB(GLuint buf, GLenum sfactor, GLenum dfactor); - - -extern void GLAPIENTRY -_mesa_BlendFuncSeparateiARB_no_error(GLuint buf, GLenum sfactorRGB, - GLenum dfactorRGB, GLenum sfactorA, - GLenum dfactorA); -extern void GLAPIENTRY -_mesa_BlendFuncSeparateiARB(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorA, GLenum dfactorA); - - -extern void GLAPIENTRY -_mesa_BlendEquation( GLenum mode ); - - -void GLAPIENTRY -_mesa_BlendEquationiARB_no_error(GLuint buf, GLenum mode); - -extern void GLAPIENTRY -_mesa_BlendEquationiARB(GLuint buf, GLenum mode); - - -void GLAPIENTRY -_mesa_BlendEquationSeparate_no_error(GLenum modeRGB, GLenum modeA); - -extern void GLAPIENTRY -_mesa_BlendEquationSeparate( GLenum modeRGB, GLenum modeA ); - - -extern void GLAPIENTRY -_mesa_BlendEquationSeparateiARB_no_error(GLuint buf, GLenum modeRGB, - GLenum modeA); -extern void GLAPIENTRY -_mesa_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA); - - -extern void GLAPIENTRY -_mesa_BlendColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha); - - -extern void GLAPIENTRY -_mesa_AlphaFunc( GLenum func, GLclampf ref ); - - -extern void GLAPIENTRY -_mesa_LogicOp( GLenum opcode ); - - -extern void GLAPIENTRY -_mesa_LogicOp_no_error(GLenum opcode); - - -extern void GLAPIENTRY -_mesa_IndexMask( GLuint mask ); - -extern void GLAPIENTRY -_mesa_ColorMask( GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha ); - -extern void GLAPIENTRY -_mesa_ColorMaski( GLuint buf, GLboolean red, GLboolean green, - GLboolean blue, GLboolean alpha ); - - -extern void GLAPIENTRY -_mesa_ClampColor(GLenum target, GLenum clamp); - extern GLboolean _mesa_get_clamp_fragment_color(const struct gl_context *ctx, const struct gl_framebuffer *drawFb); @@ -147,9 +63,6 @@ extern void _mesa_update_clamp_vertex_color(struct gl_context *ctx, const struct gl_framebuffer *drawFb); -extern mesa_format -_mesa_get_render_format(const struct gl_context *ctx, mesa_format format); - extern void _mesa_init_color( struct gl_context * ctx ); @@ -174,12 +87,8 @@ _mesa_advanded_blend_sh_constant_changed(struct gl_context *ctx, static inline void _mesa_flush_vertices_for_blend_state(struct gl_context *ctx) { - if (!ctx->DriverFlags.NewBlend) { - FLUSH_VERTICES(ctx, _NEW_COLOR, GL_COLOR_BUFFER_BIT); - } else { - FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; - } + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; } static inline void @@ -192,7 +101,7 @@ _mesa_flush_vertices_for_blend_adv(struct gl_context *ctx, _mesa_advanded_blend_sh_constant_changed(ctx, new_blend_enabled, new_mode)) { FLUSH_VERTICES(ctx, _NEW_COLOR, GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; + ctx->NewDriverState |= ST_NEW_BLEND; return; } _mesa_flush_vertices_for_blend_state(ctx); diff --git a/src/mesa/main/blit.c b/src/mesa/main/blit.c index 116c012b212..c71aa14170a 100644 --- a/src/mesa/main/blit.c +++ b/src/mesa/main/blit.c @@ -36,10 +36,21 @@ #include "fbobject.h" #include "framebuffer.h" #include "glformats.h" +#include "image.h" #include "mtypes.h" #include "macros.h" +#include "readpix.h" +#include "renderbuffer.h" #include "state.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_manager.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_scissor.h" +#include "state_tracker/st_texture.h" +#include "state_tracker/st_util.h" /** Set this to 1 to debug/log glBlitFramebuffer() calls */ #define DEBUG_BLIT 0 @@ -340,6 +351,280 @@ validate_depth_buffer(struct gl_context *ctx, struct gl_framebuffer *readFb, } +static void +do_blit_framebuffer(struct gl_context *ctx, + struct gl_framebuffer *readFB, + struct gl_framebuffer *drawFB, + GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, + GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, + GLbitfield mask, GLenum filter) +{ + struct st_context *st = st_context(ctx); + const GLbitfield depthStencil = (GL_DEPTH_BUFFER_BIT | + GL_STENCIL_BUFFER_BIT); + const uint pFilter = ((filter == GL_NEAREST) + ? PIPE_TEX_FILTER_NEAREST + : PIPE_TEX_FILTER_LINEAR); + struct { + GLint srcX0, srcY0, srcX1, srcY1; + GLint dstX0, dstY0, dstX1, dstY1; + } clip; + struct pipe_blit_info blit; + + st_manager_validate_framebuffers(st); + + /* Make sure bitmap rendering has landed in the framebuffers */ + st_flush_bitmap_cache(st); + st_invalidate_readpix_cache(st); + + clip.srcX0 = srcX0; + clip.srcY0 = srcY0; + clip.srcX1 = srcX1; + clip.srcY1 = srcY1; + clip.dstX0 = dstX0; + clip.dstY0 = dstY0; + clip.dstX1 = dstX1; + clip.dstY1 = dstY1; + + /* NOTE: If the src and dst dimensions don't match, we cannot simply adjust + * the integer coordinates to account for clipping (or scissors) because that + * would make us cut off fractional parts, affecting the result of the blit. + * + * XXX: This should depend on mask ! + */ + if (!_mesa_clip_blit(ctx, readFB, drawFB, + &clip.srcX0, &clip.srcY0, &clip.srcX1, &clip.srcY1, + &clip.dstX0, &clip.dstY0, &clip.dstX1, &clip.dstY1)) { + return; /* nothing to draw/blit */ + } + memset(&blit, 0, sizeof(struct pipe_blit_info)); + blit.scissor_enable = + (dstX0 != clip.dstX0) || + (dstY0 != clip.dstY0) || + (dstX1 != clip.dstX1) || + (dstY1 != clip.dstY1); + + if (_mesa_fb_orientation(drawFB) == Y_0_TOP) { + /* invert Y for dest */ + dstY0 = drawFB->Height - dstY0; + dstY1 = drawFB->Height - dstY1; + /* invert Y for clip */ + clip.dstY0 = drawFB->Height - clip.dstY0; + clip.dstY1 = drawFB->Height - clip.dstY1; + } + if (blit.scissor_enable) { + blit.scissor.minx = MIN2(clip.dstX0, clip.dstX1); + blit.scissor.miny = MIN2(clip.dstY0, clip.dstY1); + blit.scissor.maxx = MAX2(clip.dstX0, clip.dstX1); + blit.scissor.maxy = MAX2(clip.dstY0, clip.dstY1); +#if 0 + debug_printf("scissor = (%i,%i)-(%i,%i)\n", + blit.scissor.minx,blit.scissor.miny, + blit.scissor.maxx,blit.scissor.maxy); +#endif + } + + if (_mesa_fb_orientation(readFB) == Y_0_TOP) { + /* invert Y for src */ + srcY0 = readFB->Height - srcY0; + srcY1 = readFB->Height - srcY1; + } + + if (srcY0 > srcY1 && dstY0 > dstY1) { + /* Both src and dst are upside down. Swap Y to make it + * right-side up to increase odds of using a fast path. + * Recall that all Gallium raster coords have Y=0=top. + */ + GLint tmp; + tmp = srcY0; + srcY0 = srcY1; + srcY1 = tmp; + tmp = dstY0; + dstY0 = dstY1; + dstY1 = tmp; + } + + blit.src.box.depth = 1; + blit.dst.box.depth = 1; + + /* Destination dimensions have to be positive: */ + if (dstX0 < dstX1) { + blit.dst.box.x = dstX0; + blit.src.box.x = srcX0; + blit.dst.box.width = dstX1 - dstX0; + blit.src.box.width = srcX1 - srcX0; + } else { + blit.dst.box.x = dstX1; + blit.src.box.x = srcX1; + blit.dst.box.width = dstX0 - dstX1; + blit.src.box.width = srcX0 - srcX1; + } + if (dstY0 < dstY1) { + blit.dst.box.y = dstY0; + blit.src.box.y = srcY0; + blit.dst.box.height = dstY1 - dstY0; + blit.src.box.height = srcY1 - srcY0; + } else { + blit.dst.box.y = dstY1; + blit.src.box.y = srcY1; + blit.dst.box.height = dstY0 - dstY1; + blit.src.box.height = srcY0 - srcY1; + } + + if (drawFB != ctx->WinSysDrawBuffer) + st_window_rectangles_to_blit(ctx, &blit); + + blit.filter = pFilter; + blit.render_condition_enable = st->has_conditional_render; + blit.alpha_blend = false; + + if (mask & GL_COLOR_BUFFER_BIT) { + struct gl_renderbuffer_attachment *srcAtt = + &readFB->Attachment[readFB->_ColorReadBufferIndex]; + GLuint i; + + blit.mask = PIPE_MASK_RGBA; + + if (srcAtt->Type == GL_TEXTURE) { + /* Make sure that the st_texture_object->pt is the current storage for + * our miplevel. The finalize would happen at some point anyway, might + * as well be now. + */ + st_finalize_texture(ctx, ctx->pipe, srcAtt->Texture, srcAtt->CubeMapFace); + + struct gl_texture_object *srcObj = srcAtt->Texture; + + if (!srcObj || !srcObj->pt) { + return; + } + + blit.src.resource = srcObj->pt; + blit.src.level = srcAtt->TextureLevel; + blit.src.box.z = srcAtt->Zoffset + srcAtt->CubeMapFace; + blit.src.format = srcObj->surface_based ? srcObj->surface_format : srcObj->pt->format; + + if (!ctx->Color.sRGBEnabled) + blit.src.format = util_format_linear(blit.src.format); + } + else { + struct gl_renderbuffer *srcRb = readFB->_ColorReadBuffer; + struct pipe_surface *srcSurf; + + if (!srcRb) + return; + + _mesa_update_renderbuffer_surface(ctx, srcRb); + + if (!srcRb->surface) + return; + + srcSurf = srcRb->surface; + + blit.src.resource = srcSurf->texture; + blit.src.level = srcSurf->u.tex.level; + blit.src.box.z = srcSurf->u.tex.first_layer; + blit.src.format = srcSurf->format; + } + + for (i = 0; i < drawFB->_NumColorDrawBuffers; i++) { + struct gl_renderbuffer *dstRb = drawFB->_ColorDrawBuffers[i]; + + if (dstRb) { + struct pipe_surface *dstSurf; + + _mesa_update_renderbuffer_surface(ctx, dstRb); + + dstSurf = dstRb->surface; + + if (dstSurf) { + blit.dst.resource = dstSurf->texture; + blit.dst.level = dstSurf->u.tex.level; + blit.dst.box.z = dstSurf->u.tex.first_layer; + blit.dst.format = dstSurf->format; + + ctx->pipe->blit(ctx->pipe, &blit); + dstRb->defined = true; /* front buffer tracking */ + } + } + } + } + + if (mask & depthStencil) { + /* depth and/or stencil blit */ + + /* get src/dst depth surfaces */ + struct gl_renderbuffer *srcDepthRb = + readFB->Attachment[BUFFER_DEPTH].Renderbuffer; + struct gl_renderbuffer *dstDepthRb = + drawFB->Attachment[BUFFER_DEPTH].Renderbuffer; + struct pipe_surface *dstDepthSurf = + dstDepthRb ? dstDepthRb->surface : NULL; + + struct gl_renderbuffer *srcStencilRb = + readFB->Attachment[BUFFER_STENCIL].Renderbuffer; + struct gl_renderbuffer *dstStencilRb = + drawFB->Attachment[BUFFER_STENCIL].Renderbuffer; + struct pipe_surface *dstStencilSurf = + dstStencilRb ? dstStencilRb->surface : NULL; + + if (_mesa_has_depthstencil_combined(readFB) && + _mesa_has_depthstencil_combined(drawFB)) { + blit.mask = 0; + if (mask & GL_DEPTH_BUFFER_BIT) + blit.mask |= PIPE_MASK_Z; + if (mask & GL_STENCIL_BUFFER_BIT) + blit.mask |= PIPE_MASK_S; + + blit.dst.resource = dstDepthSurf->texture; + blit.dst.level = dstDepthSurf->u.tex.level; + blit.dst.box.z = dstDepthSurf->u.tex.first_layer; + blit.dst.format = dstDepthSurf->format; + + blit.src.resource = srcDepthRb->texture; + blit.src.level = srcDepthRb->surface->u.tex.level; + blit.src.box.z = srcDepthRb->surface->u.tex.first_layer; + blit.src.format = srcDepthRb->surface->format; + + ctx->pipe->blit(ctx->pipe, &blit); + } + else { + /* blitting depth and stencil separately */ + + if (mask & GL_DEPTH_BUFFER_BIT) { + blit.mask = PIPE_MASK_Z; + + blit.dst.resource = dstDepthSurf->texture; + blit.dst.level = dstDepthSurf->u.tex.level; + blit.dst.box.z = dstDepthSurf->u.tex.first_layer; + blit.dst.format = dstDepthSurf->format; + + blit.src.resource = srcDepthRb->texture; + blit.src.level = srcDepthRb->surface->u.tex.level; + blit.src.box.z = srcDepthRb->surface->u.tex.first_layer; + blit.src.format = srcDepthRb->surface->format; + + ctx->pipe->blit(ctx->pipe, &blit); + } + + if (mask & GL_STENCIL_BUFFER_BIT) { + blit.mask = PIPE_MASK_S; + + blit.dst.resource = dstStencilSurf->texture; + blit.dst.level = dstStencilSurf->u.tex.level; + blit.dst.box.z = dstStencilSurf->u.tex.first_layer; + blit.dst.format = dstStencilSurf->format; + + blit.src.resource = srcStencilRb->texture; + blit.src.level = srcStencilRb->surface->u.tex.level; + blit.src.box.z = srcStencilRb->surface->u.tex.first_layer; + blit.src.format = srcStencilRb->surface->format; + + ctx->pipe->blit(ctx->pipe, &blit); + } + } + } +} + static ALWAYS_INLINE void blit_framebuffer(struct gl_context *ctx, struct gl_framebuffer *readFb, struct gl_framebuffer *drawFb, @@ -572,11 +857,10 @@ blit_framebuffer(struct gl_context *ctx, return; } - assert(ctx->Driver.BlitFramebuffer); - ctx->Driver.BlitFramebuffer(ctx, readFb, drawFb, - srcX0, srcY0, srcX1, srcY1, - dstX0, dstY0, dstX1, dstY1, - mask, filter); + do_blit_framebuffer(ctx, readFb, drawFb, + srcX0, srcY0, srcX1, srcY1, + dstX0, dstY0, dstX1, dstY1, + mask, filter); } diff --git a/src/mesa/main/blit.h b/src/mesa/main/blit.h index 39021e7be68..24f46c58a57 100644 --- a/src/mesa/main/blit.h +++ b/src/mesa/main/blit.h @@ -26,7 +26,7 @@ #ifndef BLIT_H #define BLIT_H -#include "glheader.h" +#include "util/glheader.h" extern bool _mesa_regions_overlap(int srcX0, int srcY0, @@ -34,31 +34,4 @@ _mesa_regions_overlap(int srcX0, int srcY0, int dstX0, int dstY0, int dstX1, int dstY1); -void GLAPIENTRY -_mesa_BlitFramebuffer_no_error(GLint srcX0, GLint srcY0, GLint srcX1, - GLint srcY1, GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - -extern void GLAPIENTRY -_mesa_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - -void GLAPIENTRY -_mesa_BlitNamedFramebuffer_no_error(GLuint readFramebuffer, - GLuint drawFramebuffer, - GLint srcX0, GLint srcY0, - GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, - GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - -extern void GLAPIENTRY -_mesa_BlitNamedFramebuffer(GLuint readFramebuffer, GLuint drawFramebuffer, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - - #endif /* BLIT_H */ diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c index 18fa67d2d74..6ef81bcbd14 100644 --- a/src/mesa/main/bufferobj.c +++ b/src/mesa/main/bufferobj.c @@ -32,8 +32,8 @@ #include <stdbool.h> #include <inttypes.h> /* for PRId64 macro */ -#include "util/debug.h" -#include "glheader.h" +#include "util/u_debug.h" +#include "util/glheader.h" #include "enums.h" #include "hash.h" #include "context.h" @@ -47,9 +47,14 @@ #include "varray.h" #include "util/u_atomic.h" #include "util/u_memory.h" +#include "api_exec_decl.h" #include "util/set.h" +#include "state_tracker/st_debug.h" +#include "state_tracker/st_atom.h" +#include "frontend/api.h" +#include "util/u_inlines.h" /* Debug flags */ /*#define VBO_DEBUG*/ /*#define BOUNDS_CHECK*/ @@ -64,6 +69,557 @@ /** + * Replace data in a subrange of buffer object. If the data range + * specified by size + offset extends beyond the end of the buffer or + * if data is NULL, no copy is performed. + * Called via glBufferSubDataARB(). + */ +void +_mesa_bufferobj_subdata(struct gl_context *ctx, + GLintptrARB offset, + GLsizeiptrARB size, + const void *data, struct gl_buffer_object *obj) +{ + /* we may be called from VBO code, so double-check params here */ + assert(offset >= 0); + assert(size >= 0); + assert(offset + size <= obj->Size); + + if (!size) + return; + + /* + * According to ARB_vertex_buffer_object specification, if data is null, + * then the contents of the buffer object's data store is undefined. We just + * ignore, and leave it unchanged. + */ + if (!data) + return; + + if (!obj->buffer) { + /* we probably ran out of memory during buffer allocation */ + return; + } + + /* Now that transfers are per-context, we don't have to figure out + * flushing here. Usually drivers won't need to flush in this case + * even if the buffer is currently referenced by hardware - they + * just queue the upload as dma rather than mapping the underlying + * buffer directly. + * + * If the buffer is mapped, suppress implicit buffer range invalidation + * by using PIPE_MAP_DIRECTLY. + */ + struct pipe_context *pipe = ctx->pipe; + + pipe->buffer_subdata(pipe, obj->buffer, + _mesa_bufferobj_mapped(obj, MAP_USER) ? + PIPE_MAP_DIRECTLY : 0, + offset, size, data); +} + + +/** + * Called via glGetBufferSubDataARB(). + */ +static void +bufferobj_get_subdata(struct gl_context *ctx, + GLintptrARB offset, + GLsizeiptrARB size, + void *data, struct gl_buffer_object *obj) +{ + /* we may be called from VBO code, so double-check params here */ + assert(offset >= 0); + assert(size >= 0); + assert(offset + size <= obj->Size); + + if (!size) + return; + + if (!obj->buffer) { + /* we probably ran out of memory during buffer allocation */ + return; + } + + pipe_buffer_read(ctx->pipe, obj->buffer, + offset, size, data); +} + +void +_mesa_bufferobj_get_subdata(struct gl_context *ctx, + GLintptrARB offset, + GLsizeiptrARB size, + void *data, struct gl_buffer_object *obj) +{ + bufferobj_get_subdata(ctx, offset, size, data, obj); +} + +/** + * Return bitmask of PIPE_BIND_x flags corresponding a GL buffer target. + */ +static unsigned +buffer_target_to_bind_flags(GLenum target) +{ + switch (target) { + case GL_PIXEL_PACK_BUFFER_ARB: + case GL_PIXEL_UNPACK_BUFFER_ARB: + return PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW; + case GL_ARRAY_BUFFER_ARB: + return PIPE_BIND_VERTEX_BUFFER; + case GL_ELEMENT_ARRAY_BUFFER_ARB: + return PIPE_BIND_INDEX_BUFFER; + case GL_TEXTURE_BUFFER: + return PIPE_BIND_SAMPLER_VIEW; + case GL_TRANSFORM_FEEDBACK_BUFFER: + return PIPE_BIND_STREAM_OUTPUT; + case GL_UNIFORM_BUFFER: + return PIPE_BIND_CONSTANT_BUFFER; + case GL_DRAW_INDIRECT_BUFFER: + case GL_PARAMETER_BUFFER_ARB: + return PIPE_BIND_COMMAND_ARGS_BUFFER; + case GL_ATOMIC_COUNTER_BUFFER: + case GL_SHADER_STORAGE_BUFFER: + return PIPE_BIND_SHADER_BUFFER; + case GL_QUERY_BUFFER: + return PIPE_BIND_QUERY_BUFFER; + default: + return 0; + } +} + + +/** + * Return bitmask of PIPE_RESOURCE_x flags corresponding to GL_MAP_x flags. + */ +static unsigned +storage_flags_to_buffer_flags(GLbitfield storageFlags) +{ + unsigned flags = 0; + if (storageFlags & GL_MAP_PERSISTENT_BIT) + flags |= PIPE_RESOURCE_FLAG_MAP_PERSISTENT; + if (storageFlags & GL_MAP_COHERENT_BIT) + flags |= PIPE_RESOURCE_FLAG_MAP_COHERENT; + if (storageFlags & GL_SPARSE_STORAGE_BIT_ARB) + flags |= PIPE_RESOURCE_FLAG_SPARSE; + return flags; +} + + +/** + * From a buffer object's target, immutability flag, storage flags and + * usage hint, return a pipe_resource_usage value (PIPE_USAGE_DYNAMIC, + * STREAM, etc). + */ +static enum pipe_resource_usage +buffer_usage(GLenum target, GLboolean immutable, + GLbitfield storageFlags, GLenum usage) +{ + /* "immutable" means that "storageFlags" was set by the user and "usage" + * was guessed by Mesa. Otherwise, "usage" was set by the user and + * storageFlags was guessed by Mesa. + * + * Therefore, use storageFlags with immutable, else use "usage". + */ + if (immutable) { + /* BufferStorage */ + if (storageFlags & GL_MAP_READ_BIT) + return PIPE_USAGE_STAGING; + else if (storageFlags & GL_CLIENT_STORAGE_BIT) + return PIPE_USAGE_STREAM; + else + return PIPE_USAGE_DEFAULT; + } + else { + /* These are often read by the CPU, so enable CPU caches. */ + if (target == GL_PIXEL_PACK_BUFFER || + target == GL_PIXEL_UNPACK_BUFFER) + return PIPE_USAGE_STAGING; + + /* BufferData */ + switch (usage) { + case GL_DYNAMIC_DRAW: + case GL_DYNAMIC_COPY: + return PIPE_USAGE_DYNAMIC; + case GL_STREAM_DRAW: + case GL_STREAM_COPY: + return PIPE_USAGE_STREAM; + case GL_STATIC_READ: + case GL_DYNAMIC_READ: + case GL_STREAM_READ: + return PIPE_USAGE_STAGING; + case GL_STATIC_DRAW: + case GL_STATIC_COPY: + default: + return PIPE_USAGE_DEFAULT; + } + } +} + + +static ALWAYS_INLINE GLboolean +bufferobj_data(struct gl_context *ctx, + GLenum target, + GLsizeiptrARB size, + const void *data, + struct gl_memory_object *memObj, + GLuint64 offset, + GLenum usage, + GLbitfield storageFlags, + struct gl_buffer_object *obj) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + bool is_mapped = _mesa_bufferobj_mapped(obj, MAP_USER); + + if (size > UINT32_MAX || offset > UINT32_MAX) { + /* pipe_resource.width0 is 32 bits only and increasing it + * to 64 bits doesn't make much sense since hw support + * for > 4GB resources is limited. + */ + obj->Size = 0; + return GL_FALSE; + } + + if (target != GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD && + size && obj->buffer && + obj->Size == size && + obj->Usage == usage && + obj->StorageFlags == storageFlags) { + if (data) { + /* Just discard the old contents and write new data. + * This should be the same as creating a new buffer, but we avoid + * a lot of validation in Mesa. + * + * If the buffer is mapped, we can't discard it. + * + * PIPE_MAP_DIRECTLY supresses implicit buffer range + * invalidation. + */ + pipe->buffer_subdata(pipe, obj->buffer, + is_mapped ? PIPE_MAP_DIRECTLY : + PIPE_MAP_DISCARD_WHOLE_RESOURCE, + 0, size, data); + return GL_TRUE; + } else if (is_mapped) { + return GL_TRUE; /* can't reallocate, nothing to do */ + } else if (screen->get_param(screen, PIPE_CAP_INVALIDATE_BUFFER)) { + pipe->invalidate_resource(pipe, obj->buffer); + return GL_TRUE; + } + } + + obj->Size = size; + obj->Usage = usage; + obj->StorageFlags = storageFlags; + + _mesa_bufferobj_release_buffer(obj); + + unsigned bindings = buffer_target_to_bind_flags(target); + + if (storageFlags & MESA_GALLIUM_VERTEX_STATE_STORAGE) + bindings |= PIPE_BIND_VERTEX_STATE; + + if (ST_DEBUG & DEBUG_BUFFER) { + debug_printf("Create buffer size %" PRId64 " bind 0x%x\n", + (int64_t) size, bindings); + } + + if (size != 0) { + struct pipe_resource buffer; + + memset(&buffer, 0, sizeof buffer); + buffer.target = PIPE_BUFFER; + buffer.format = PIPE_FORMAT_R8_UNORM; /* want TYPELESS or similar */ + buffer.bind = bindings; + buffer.usage = + buffer_usage(target, obj->Immutable, storageFlags, usage); + buffer.flags = storage_flags_to_buffer_flags(storageFlags); + buffer.width0 = size; + buffer.height0 = 1; + buffer.depth0 = 1; + buffer.array_size = 1; + + if (memObj) { + obj->buffer = screen->resource_from_memobj(screen, &buffer, + memObj->memory, + offset); + } + else if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { + obj->buffer = + screen->resource_from_user_memory(screen, &buffer, (void*)data); + } + else { + obj->buffer = screen->resource_create(screen, &buffer); + + if (obj->buffer && data) + pipe_buffer_write(pipe, obj->buffer, 0, size, data); + } + + if (!obj->buffer) { + /* out of memory */ + obj->Size = 0; + return GL_FALSE; + } + + obj->private_refcount_ctx = ctx; + } + + /* The current buffer may be bound, so we have to revalidate all atoms that + * might be using it. + */ + if (obj->UsageHistory & USAGE_ARRAY_BUFFER) + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + if (obj->UsageHistory & USAGE_UNIFORM_BUFFER) + ctx->NewDriverState |= ST_NEW_UNIFORM_BUFFER; + if (obj->UsageHistory & USAGE_SHADER_STORAGE_BUFFER) + ctx->NewDriverState |= ST_NEW_STORAGE_BUFFER; + if (obj->UsageHistory & USAGE_TEXTURE_BUFFER) + ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS | ST_NEW_IMAGE_UNITS; + if (obj->UsageHistory & USAGE_ATOMIC_COUNTER_BUFFER) + ctx->NewDriverState |= ctx->DriverFlags.NewAtomicBuffer; + + return GL_TRUE; +} + +/** + * Allocate space for and store data in a buffer object. Any data that was + * previously stored in the buffer object is lost. If data is NULL, + * memory will be allocated, but no copy will occur. + * Called via ctx->Driver.BufferData(). + * \return GL_TRUE for success, GL_FALSE if out of memory + */ +GLboolean +_mesa_bufferobj_data(struct gl_context *ctx, + GLenum target, + GLsizeiptrARB size, + const void *data, + GLenum usage, + GLbitfield storageFlags, + struct gl_buffer_object *obj) +{ + return bufferobj_data(ctx, target, size, data, NULL, 0, usage, storageFlags, obj); +} + +static GLboolean +bufferobj_data_mem(struct gl_context *ctx, + GLenum target, + GLsizeiptrARB size, + struct gl_memory_object *memObj, + GLuint64 offset, + GLenum usage, + struct gl_buffer_object *bufObj) +{ + return bufferobj_data(ctx, target, size, NULL, memObj, offset, usage, GL_DYNAMIC_STORAGE_BIT, bufObj); +} + +/** + * Convert GLbitfield of GL_MAP_x flags to gallium pipe_map_flags flags. + * \param wholeBuffer is the whole buffer being mapped? + */ +enum pipe_map_flags +_mesa_access_flags_to_transfer_flags(GLbitfield access, bool wholeBuffer) +{ + enum pipe_map_flags flags = 0; + + if (access & GL_MAP_WRITE_BIT) + flags |= PIPE_MAP_WRITE; + + if (access & GL_MAP_READ_BIT) + flags |= PIPE_MAP_READ; + + if (access & GL_MAP_FLUSH_EXPLICIT_BIT) + flags |= PIPE_MAP_FLUSH_EXPLICIT; + + if (access & GL_MAP_INVALIDATE_BUFFER_BIT) { + flags |= PIPE_MAP_DISCARD_WHOLE_RESOURCE; + } + else if (access & GL_MAP_INVALIDATE_RANGE_BIT) { + if (wholeBuffer) + flags |= PIPE_MAP_DISCARD_WHOLE_RESOURCE; + else + flags |= PIPE_MAP_DISCARD_RANGE; + } + + if (access & GL_MAP_UNSYNCHRONIZED_BIT) + flags |= PIPE_MAP_UNSYNCHRONIZED; + + if (access & GL_MAP_PERSISTENT_BIT) + flags |= PIPE_MAP_PERSISTENT; + + if (access & GL_MAP_COHERENT_BIT) + flags |= PIPE_MAP_COHERENT; + + /* ... other flags ... + */ + + if (access & MESA_MAP_NOWAIT_BIT) + flags |= PIPE_MAP_DONTBLOCK; + if (access & MESA_MAP_THREAD_SAFE_BIT) + flags |= PIPE_MAP_THREAD_SAFE; + if (access & MESA_MAP_ONCE) + flags |= PIPE_MAP_ONCE; + + return flags; +} + + +/** + * Called via glMapBufferRange(). + */ +void * +_mesa_bufferobj_map_range(struct gl_context *ctx, + GLintptr offset, GLsizeiptr length, GLbitfield access, + struct gl_buffer_object *obj, + gl_map_buffer_index index) +{ + struct pipe_context *pipe = ctx->pipe; + + assert(offset >= 0); + assert(length >= 0); + assert(offset < obj->Size); + assert(offset + length <= obj->Size); + + enum pipe_map_flags transfer_flags = + _mesa_access_flags_to_transfer_flags(access, + offset == 0 && length == obj->Size); + + /* Sometimes games do silly things like MapBufferRange(UNSYNC|DISCARD_RANGE) + * In this case, the the UNSYNC is a bit redundant, but the games rely + * on the driver rebinding/replacing the backing storage rather than + * going down the UNSYNC path (ie. honoring DISCARD_x first before UNSYNC). + */ + if (unlikely(ctx->st_opts->ignore_map_unsynchronized)) { + if (transfer_flags & (PIPE_MAP_DISCARD_RANGE | PIPE_MAP_DISCARD_WHOLE_RESOURCE)) + transfer_flags &= ~PIPE_MAP_UNSYNCHRONIZED; + } + + if (ctx->Const.ForceMapBufferSynchronized) + transfer_flags &= ~PIPE_MAP_UNSYNCHRONIZED; + + obj->Mappings[index].Pointer = pipe_buffer_map_range(pipe, + obj->buffer, + offset, length, + transfer_flags, + &obj->transfer[index]); + if (obj->Mappings[index].Pointer) { + obj->Mappings[index].Offset = offset; + obj->Mappings[index].Length = length; + obj->Mappings[index].AccessFlags = access; + } + else { + obj->transfer[index] = NULL; + } + + return obj->Mappings[index].Pointer; +} + + +void +_mesa_bufferobj_flush_mapped_range(struct gl_context *ctx, + GLintptr offset, GLsizeiptr length, + struct gl_buffer_object *obj, + gl_map_buffer_index index) +{ + struct pipe_context *pipe = ctx->pipe; + + /* Subrange is relative to mapped range */ + assert(offset >= 0); + assert(length >= 0); + assert(offset + length <= obj->Mappings[index].Length); + assert(obj->Mappings[index].Pointer); + + if (!length) + return; + + pipe_buffer_flush_mapped_range(pipe, obj->transfer[index], + obj->Mappings[index].Offset + offset, + length); +} + + +/** + * Called via glUnmapBufferARB(). + */ +GLboolean +_mesa_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj, + gl_map_buffer_index index) +{ + struct pipe_context *pipe = ctx->pipe; + + if (obj->Mappings[index].Length) + pipe_buffer_unmap(pipe, obj->transfer[index]); + + obj->transfer[index] = NULL; + obj->Mappings[index].Pointer = NULL; + obj->Mappings[index].Offset = 0; + obj->Mappings[index].Length = 0; + return GL_TRUE; +} + + +/** + * Called via glCopyBufferSubData(). + */ +static void +bufferobj_copy_subdata(struct gl_context *ctx, + struct gl_buffer_object *src, + struct gl_buffer_object *dst, + GLintptr readOffset, GLintptr writeOffset, + GLsizeiptr size) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_box box; + + dst->MinMaxCacheDirty = true; + if (!size) + return; + + /* buffer should not already be mapped */ + assert(!_mesa_check_disallowed_mapping(src)); + /* dst can be mapped, just not the same range as the target range */ + + u_box_1d(readOffset, size, &box); + + pipe->resource_copy_region(pipe, dst->buffer, 0, writeOffset, 0, 0, + src->buffer, 0, &box); +} + +static void +clear_buffer_subdata_sw(struct gl_context *ctx, + GLintptr offset, GLsizeiptr size, + const GLvoid *clearValue, + GLsizeiptr clearValueSize, + struct gl_buffer_object *bufObj) +{ + GLsizeiptr i; + GLubyte *dest; + + dest = _mesa_bufferobj_map_range(ctx, offset, size, + GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_RANGE_BIT, + bufObj, MAP_INTERNAL); + + if (!dest) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data"); + return; + } + + if (clearValue == NULL) { + /* Clear with zeros, per the spec */ + memset(dest, 0, size); + _mesa_bufferobj_unmap(ctx, bufObj, MAP_INTERNAL); + return; + } + + for (i = 0; i < size/clearValueSize; ++i) { + memcpy(dest, clearValue, clearValueSize); + dest += clearValueSize; + } + + _mesa_bufferobj_unmap(ctx, bufObj, MAP_INTERNAL); +} + +/** * Helper to warn of possible performance issues, such as frequently * updating a buffer created with GL_STATIC_DRAW. Called via the macro * below. @@ -94,7 +650,7 @@ buffer_usage_warning(struct gl_context *ctx, GLuint *id, const char *fmt, ...) * glBindBuffer() so that glIsBuffer() can work correctly. */ static struct gl_buffer_object DummyBufferObject = { - .MinMaxCacheMutex = _SIMPLE_MTX_INITIALIZER_NP, + .MinMaxCacheMutex = SIMPLE_MTX_INITIALIZER, .RefCount = 1000*1000*1000, /* never delete */ }; @@ -106,19 +662,16 @@ static struct gl_buffer_object DummyBufferObject = { * \return pointer to pointer to the buffer object bound to \c target in the * specified context or \c NULL if \c target is invalid. */ -static inline struct gl_buffer_object ** -get_buffer_target(struct gl_context *ctx, GLenum target) +static ALWAYS_INLINE struct gl_buffer_object ** +get_buffer_target(struct gl_context *ctx, GLenum target, bool no_error) { /* Other targets are only supported in desktop OpenGL and OpenGL ES 3.0. */ - if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) { + if (!no_error && !_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) { switch (target) { case GL_ARRAY_BUFFER: case GL_ELEMENT_ARRAY_BUFFER: - break; case GL_PIXEL_PACK_BUFFER: case GL_PIXEL_UNPACK_BUFFER: - if (!ctx->Extensions.EXT_pixel_buffer_object) - return NULL; break; default: return NULL; @@ -127,13 +680,8 @@ get_buffer_target(struct gl_context *ctx, GLenum target) switch (target) { case GL_ARRAY_BUFFER_ARB: - if (ctx->Array.ArrayBufferObj) - ctx->Array.ArrayBufferObj->UsageHistory |= USAGE_ARRAY_BUFFER; return &ctx->Array.ArrayBufferObj; case GL_ELEMENT_ARRAY_BUFFER_ARB: - if (ctx->Array.VAO->IndexBufferObj) - ctx->Array.VAO->IndexBufferObj->UsageHistory - |= USAGE_ELEMENT_ARRAY_BUFFER; return &ctx->Array.VAO->IndexBufferObj; case GL_PIXEL_PACK_BUFFER_EXT: return &ctx->Pack.BufferObj; @@ -144,58 +692,61 @@ get_buffer_target(struct gl_context *ctx, GLenum target) case GL_COPY_WRITE_BUFFER: return &ctx->CopyWriteBuffer; case GL_QUERY_BUFFER: - if (_mesa_has_ARB_query_buffer_object(ctx)) + if (no_error || _mesa_has_ARB_query_buffer_object(ctx)) return &ctx->QueryBuffer; break; case GL_DRAW_INDIRECT_BUFFER: - if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_draw_indirect) || + if (no_error || + (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_draw_indirect) || _mesa_is_gles31(ctx)) { return &ctx->DrawIndirectBuffer; } break; case GL_PARAMETER_BUFFER_ARB: - if (_mesa_has_ARB_indirect_parameters(ctx)) { + if (no_error || _mesa_has_ARB_indirect_parameters(ctx)) { return &ctx->ParameterBuffer; } break; case GL_DISPATCH_INDIRECT_BUFFER: - if (_mesa_has_compute_shaders(ctx)) { + if (no_error || _mesa_has_compute_shaders(ctx)) { return &ctx->DispatchIndirectBuffer; } break; case GL_TRANSFORM_FEEDBACK_BUFFER: - if (ctx->Extensions.EXT_transform_feedback) { + if (no_error || ctx->Extensions.EXT_transform_feedback) { return &ctx->TransformFeedback.CurrentBuffer; } break; case GL_TEXTURE_BUFFER: - if (_mesa_has_ARB_texture_buffer_object(ctx) || + if (no_error || + _mesa_has_ARB_texture_buffer_object(ctx) || _mesa_has_OES_texture_buffer(ctx)) { return &ctx->Texture.BufferObject; } break; case GL_UNIFORM_BUFFER: - if (ctx->Extensions.ARB_uniform_buffer_object) { + if (no_error || ctx->Extensions.ARB_uniform_buffer_object) { return &ctx->UniformBuffer; } break; case GL_SHADER_STORAGE_BUFFER: - if (ctx->Extensions.ARB_shader_storage_buffer_object || _mesa_is_gles31(ctx)) { + if (no_error || + ctx->Extensions.ARB_shader_storage_buffer_object || + _mesa_is_gles31(ctx)) { return &ctx->ShaderStorageBuffer; } break; case GL_ATOMIC_COUNTER_BUFFER: - if (ctx->Extensions.ARB_shader_atomic_counters || _mesa_is_gles31(ctx)) { + if (no_error || + ctx->Extensions.ARB_shader_atomic_counters || _mesa_is_gles31(ctx)) { return &ctx->AtomicBuffer; } break; case GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD: - if (ctx->Extensions.AMD_pinned_memory) { + if (no_error || ctx->Extensions.AMD_pinned_memory) { return &ctx->ExternalVirtualMemoryBuffer; } break; - default: - return NULL; } return NULL; } @@ -213,7 +764,7 @@ static inline struct gl_buffer_object * get_buffer(struct gl_context *ctx, const char *func, GLenum target, GLenum error) { - struct gl_buffer_object **bufObj = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, false); if (!bufObj) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(target)", func); @@ -456,23 +1007,25 @@ convert_clear_buffer_data(struct gl_context *ctx, } } - -/** - * Allocate and initialize a new buffer object. - * - * Default callback for the \c dd_function_table::NewBufferObject() hook. - */ -static struct gl_buffer_object * -_mesa_new_buffer_object(struct gl_context *ctx, GLuint name) +void +_mesa_bufferobj_release_buffer(struct gl_buffer_object *obj) { - struct gl_buffer_object *obj = MALLOC_STRUCT(gl_buffer_object); - if (!obj) - return NULL; + if (!obj->buffer) + return; - _mesa_initialize_buffer_object(ctx, obj, name); - return obj; -} + /* Subtract the remaining private references before unreferencing + * the buffer. See the header file for explanation. + */ + if (obj->private_refcount) { + assert(obj->private_refcount > 0); + p_atomic_add(&obj->buffer->reference.count, + -obj->private_refcount); + obj->private_refcount = 0; + } + obj->private_refcount_ctx = NULL; + pipe_resource_reference(&obj->buffer, NULL); +} /** * Delete a buffer object. @@ -483,10 +1036,11 @@ void _mesa_delete_buffer_object(struct gl_context *ctx, struct gl_buffer_object *bufObj) { - (void) ctx; + assert(bufObj->RefCount == 0); + _mesa_buffer_unmap_all_mappings(ctx, bufObj); + _mesa_bufferobj_release_buffer(bufObj); vbo_delete_minmax_cache(bufObj); - align_free(bufObj->Data); /* assign strange values here to help w/ debugging */ bufObj->RefCount = -1000; @@ -498,55 +1052,6 @@ _mesa_delete_buffer_object(struct gl_context *ctx, } - -/** - * Set ptr to bufObj w/ reference counting. - * This is normally only called from the _mesa_reference_buffer_object() macro - * when there's a real pointer change. - */ -void -_mesa_reference_buffer_object_(struct gl_context *ctx, - struct gl_buffer_object **ptr, - struct gl_buffer_object *bufObj, - bool shared_binding) -{ - if (*ptr) { - /* Unreference the old buffer */ - struct gl_buffer_object *oldObj = *ptr; - - assert(oldObj->RefCount >= 1); - - /* Count references only if the context doesn't own the buffer or if - * ptr is a binding point shared by multiple contexts (such as a texture - * buffer object being a buffer bound within a texture object). - */ - if (shared_binding || ctx != oldObj->Ctx) { - if (p_atomic_dec_zero(&oldObj->RefCount)) { - assert(ctx->Driver.DeleteBuffer); - ctx->Driver.DeleteBuffer(ctx, oldObj); - } - } else if (ctx == oldObj->Ctx) { - /* Update the private ref count. */ - assert(oldObj->CtxRefCount >= 1); - oldObj->CtxRefCount--; - } - - *ptr = NULL; - } - assert(!*ptr); - - if (bufObj) { - /* reference new buffer */ - if (shared_binding || ctx != bufObj->Ctx) - p_atomic_inc(&bufObj->RefCount); - else if (ctx == bufObj->Ctx) - bufObj->CtxRefCount++; - - *ptr = bufObj; - } -} - - /** * Get the value of MESA_NO_MINMAX_CACHE. */ @@ -557,34 +1062,13 @@ get_no_minmax_cache() static bool disable = false; if (!read) { - disable = env_var_as_boolean("MESA_NO_MINMAX_CACHE", false); + disable = debug_get_bool_option("MESA_NO_MINMAX_CACHE", false); read = true; } return disable; } - -/** - * Initialize a buffer object to default values. - */ -void -_mesa_initialize_buffer_object(struct gl_context *ctx, - struct gl_buffer_object *obj, - GLuint name) -{ - memset(obj, 0, sizeof(struct gl_buffer_object)); - obj->RefCount = 1; - obj->Name = name; - obj->Usage = GL_STATIC_DRAW_ARB; - - simple_mtx_init(&obj->MinMaxCacheMutex, mtx_plain); - if (get_no_minmax_cache()) - obj->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; -} - - - /** * Callback called from _mesa_HashWalk() */ @@ -600,295 +1084,6 @@ count_buffer_size(void *data, void *userData) /** - * Compute total size (in bytes) of all buffer objects for the given context. - * For debugging purposes. - */ -GLuint -_mesa_total_buffer_object_memory(struct gl_context *ctx) -{ - GLuint total = 0; - - _mesa_HashWalkMaybeLocked(ctx->Shared->BufferObjects, count_buffer_size, - &total, ctx->BufferObjectsLocked); - - return total; -} - - -/** - * Allocate space for and store data in a buffer object. Any data that was - * previously stored in the buffer object is lost. If \c data is \c NULL, - * memory will be allocated, but no copy will occur. - * - * This is the default callback for \c dd_function_table::BufferData() - * Note that all GL error checking will have been done already. - * - * \param ctx GL context. - * \param target Buffer object target on which to operate. - * \param size Size, in bytes, of the new data store. - * \param data Pointer to the data to store in the buffer object. This - * pointer may be \c NULL. - * \param usage Hints about how the data will be used. - * \param bufObj Object to be used. - * - * \return GL_TRUE for success, GL_FALSE for failure - * \sa glBufferDataARB, dd_function_table::BufferData. - */ -static GLboolean -buffer_data_fallback(struct gl_context *ctx, GLenum target, GLsizeiptrARB size, - const GLvoid *data, GLenum usage, GLenum storageFlags, - struct gl_buffer_object *bufObj) -{ - void * new_data; - - (void) target; - - align_free( bufObj->Data ); - - new_data = align_malloc( size, ctx->Const.MinMapBufferAlignment ); - if (new_data) { - bufObj->Data = (GLubyte *) new_data; - bufObj->Size = size; - bufObj->Usage = usage; - bufObj->StorageFlags = storageFlags; - - if (data) { - memcpy( bufObj->Data, data, size ); - } - - return GL_TRUE; - } - else { - return GL_FALSE; - } -} - - -/** - * Replace data in a subrange of buffer object. If the data range - * specified by \c size + \c offset extends beyond the end of the buffer or - * if \c data is \c NULL, no copy is performed. - * - * This is the default callback for \c dd_function_table::BufferSubData() - * Note that all GL error checking will have been done already. - * - * \param ctx GL context. - * \param offset Offset of the first byte to be modified. - * \param size Size, in bytes, of the data range. - * \param data Pointer to the data to store in the buffer object. - * \param bufObj Object to be used. - * - * \sa glBufferSubDataARB, dd_function_table::BufferSubData. - */ -static void -buffer_sub_data_fallback(struct gl_context *ctx, GLintptrARB offset, - GLsizeiptrARB size, const GLvoid *data, - struct gl_buffer_object *bufObj) -{ - (void) ctx; - - /* this should have been caught in _mesa_BufferSubData() */ - assert(size + offset <= bufObj->Size); - - if (bufObj->Data) { - memcpy( (GLubyte *) bufObj->Data + offset, data, size ); - } -} - - -/** - * Retrieve data from a subrange of buffer object. If the data range - * specified by \c size + \c offset extends beyond the end of the buffer or - * if \c data is \c NULL, no copy is performed. - * - * This is the default callback for \c dd_function_table::GetBufferSubData() - * Note that all GL error checking will have been done already. - * - * \param ctx GL context. - * \param target Buffer object target on which to operate. - * \param offset Offset of the first byte to be fetched. - * \param size Size, in bytes, of the data range. - * \param data Destination for data - * \param bufObj Object to be used. - * - * \sa glBufferGetSubDataARB, dd_function_table::GetBufferSubData. - */ -static void -buffer_get_subdata(struct gl_context *ctx, GLintptrARB offset, - GLsizeiptrARB size, GLvoid *data, - struct gl_buffer_object *bufObj ) -{ - (void) ctx; - - if (bufObj->Data && ((GLsizeiptrARB) (size + offset) <= bufObj->Size)) { - memcpy( data, (GLubyte *) bufObj->Data + offset, size ); - } -} - - -/** - * Clear a subrange of the buffer object with copies of the supplied data. - * If data is NULL the buffer is filled with zeros. - * - * This is the default callback for \c dd_function_table::ClearBufferSubData() - * Note that all GL error checking will have been done already. - * - * \param ctx GL context. - * \param offset Offset of the first byte to be cleared. - * \param size Size, in bytes, of the to be cleared range. - * \param clearValue Source of the data. - * \param clearValueSize Size, in bytes, of the supplied data. - * \param bufObj Object to be cleared. - * - * \sa glClearBufferSubData, glClearBufferData and - * dd_function_table::ClearBufferSubData. - */ -void -_mesa_ClearBufferSubData_sw(struct gl_context *ctx, - GLintptr offset, GLsizeiptr size, - const GLvoid *clearValue, - GLsizeiptr clearValueSize, - struct gl_buffer_object *bufObj) -{ - GLsizeiptr i; - GLubyte *dest; - - assert(ctx->Driver.MapBufferRange); - dest = ctx->Driver.MapBufferRange(ctx, offset, size, - GL_MAP_WRITE_BIT | - GL_MAP_INVALIDATE_RANGE_BIT, - bufObj, MAP_INTERNAL); - - if (!dest) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearBuffer[Sub]Data"); - return; - } - - if (clearValue == NULL) { - /* Clear with zeros, per the spec */ - memset(dest, 0, size); - ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL); - return; - } - - for (i = 0; i < size/clearValueSize; ++i) { - memcpy(dest, clearValue, clearValueSize); - dest += clearValueSize; - } - - ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_INTERNAL); -} - - -/** - * Default fallback for \c dd_function_table::MapBufferRange(). - * Called via glMapBufferRange(). - */ -static void * -map_buffer_range_fallback(struct gl_context *ctx, GLintptr offset, - GLsizeiptr length, GLbitfield access, - struct gl_buffer_object *bufObj, - gl_map_buffer_index index) -{ - (void) ctx; - assert(!_mesa_bufferobj_mapped(bufObj, index)); - /* Just return a direct pointer to the data */ - bufObj->Mappings[index].Pointer = bufObj->Data + offset; - bufObj->Mappings[index].Length = length; - bufObj->Mappings[index].Offset = offset; - bufObj->Mappings[index].AccessFlags = access; - return bufObj->Mappings[index].Pointer; -} - - -/** - * Default fallback for \c dd_function_table::FlushMappedBufferRange(). - * Called via glFlushMappedBufferRange(). - */ -static void -flush_mapped_buffer_range_fallback(struct gl_context *ctx, - GLintptr offset, GLsizeiptr length, - struct gl_buffer_object *obj, - gl_map_buffer_index index) -{ - (void) ctx; - (void) offset; - (void) length; - (void) obj; - (void) index; - /* no-op */ -} - - -/** - * Default callback for \c dd_function_table::UnmapBuffer(). - * - * The input parameters will have been already tested for errors. - * - * \sa glUnmapBufferARB, dd_function_table::UnmapBuffer - */ -static GLboolean -unmap_buffer_fallback(struct gl_context *ctx, struct gl_buffer_object *bufObj, - gl_map_buffer_index index) -{ - (void) ctx; - /* XXX we might assert here that bufObj->Pointer is non-null */ - bufObj->Mappings[index].Pointer = NULL; - bufObj->Mappings[index].Length = 0; - bufObj->Mappings[index].Offset = 0; - bufObj->Mappings[index].AccessFlags = 0x0; - return GL_TRUE; -} - - -/** - * Default fallback for \c dd_function_table::CopyBufferSubData(). - * Called via glCopyBufferSubData(). - */ -static void -copy_buffer_sub_data_fallback(struct gl_context *ctx, - struct gl_buffer_object *src, - struct gl_buffer_object *dst, - GLintptr readOffset, GLintptr writeOffset, - GLsizeiptr size) -{ - GLubyte *srcPtr, *dstPtr; - - if (src == dst) { - srcPtr = dstPtr = ctx->Driver.MapBufferRange(ctx, 0, src->Size, - GL_MAP_READ_BIT | - GL_MAP_WRITE_BIT, src, - MAP_INTERNAL); - - if (!srcPtr) - return; - - srcPtr += readOffset; - dstPtr += writeOffset; - } else { - srcPtr = ctx->Driver.MapBufferRange(ctx, readOffset, size, - GL_MAP_READ_BIT, src, - MAP_INTERNAL); - dstPtr = ctx->Driver.MapBufferRange(ctx, writeOffset, size, - (GL_MAP_WRITE_BIT | - GL_MAP_INVALIDATE_RANGE_BIT), dst, - MAP_INTERNAL); - } - - /* Note: the src and dst regions will never overlap. Trying to do so - * would generate GL_INVALID_VALUE earlier. - */ - if (srcPtr && dstPtr) - memcpy(dstPtr, srcPtr, size); - - ctx->Driver.UnmapBuffer(ctx, src, MAP_INTERNAL); - if (dst != src) - ctx->Driver.UnmapBuffer(ctx, dst, MAP_INTERNAL); -} - - - -/** * Initialize the state associated with buffer objects */ void @@ -1038,13 +1233,29 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) NULL); } - _mesa_HashLockMutex(ctx->Shared->BufferObjects); + _mesa_HashLockMutex(&ctx->Shared->BufferObjects); unreference_zombie_buffers_for_ctx(ctx); - _mesa_HashWalkLocked(ctx->Shared->BufferObjects, + _mesa_HashWalkLocked(&ctx->Shared->BufferObjects, detach_unrefcounted_buffer_from_ctx, ctx); - _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); + _mesa_HashUnlockMutex(&ctx->Shared->BufferObjects); } +struct gl_buffer_object * +_mesa_bufferobj_alloc(struct gl_context *ctx, GLuint id) +{ + struct gl_buffer_object *buf = CALLOC_STRUCT(gl_buffer_object); + if (!buf) + return NULL; + + buf->RefCount = 1; + buf->Name = id; + buf->Usage = GL_STATIC_DRAW_ARB; + + simple_mtx_init(&buf->MinMaxCacheMutex, mtx_plain); + if (get_no_minmax_cache()) + buf->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE; + return buf; +} /** * Create a buffer object that will be backed by an OpenGL buffer ID * where the creating context will hold one global buffer reference instead @@ -1055,78 +1266,99 @@ _mesa_free_buffer_objects( struct gl_context *ctx ) static struct gl_buffer_object * new_gl_buffer_object(struct gl_context *ctx, GLuint id) { - struct gl_buffer_object *buf = ctx->Driver.NewBufferObject(ctx, id); + struct gl_buffer_object *buf = _mesa_bufferobj_alloc(ctx, id); buf->Ctx = ctx; buf->RefCount++; /* global buffer reference held by the context */ return buf; } -bool -_mesa_handle_bind_buffer_gen(struct gl_context *ctx, - GLuint buffer, - struct gl_buffer_object **buf_handle, - const char *caller) +static ALWAYS_INLINE bool +handle_bind_buffer_gen(struct gl_context *ctx, + GLuint buffer, + struct gl_buffer_object **buf_handle, + const char *caller, bool no_error) { struct gl_buffer_object *buf = *buf_handle; - if (!buf && (ctx->API == API_OPENGL_CORE)) { + if (unlikely(!no_error && !buf && _mesa_is_desktop_gl_core(ctx))) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller); return false; } - if (!buf || buf == &DummyBufferObject) { + if (unlikely(!buf || buf == &DummyBufferObject)) { /* If this is a new buffer object id, or one which was generated but * never used before, allocate a buffer object now. */ *buf_handle = new_gl_buffer_object(ctx, buffer); - if (!*buf_handle) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); - return false; + if (!no_error && !*buf_handle) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); + return false; } - _mesa_HashInsertMaybeLocked(ctx->Shared->BufferObjects, buffer, - *buf_handle, buf != NULL, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, + ctx->BufferObjectsLocked); + _mesa_HashInsertLocked(&ctx->Shared->BufferObjects, buffer, + *buf_handle); + /* If one context only creates buffers and another context only deletes + * buffers, buffers don't get released because it only produces zombie + * buffers. Only the context that has created the buffers can release + * them. Thus, when we create buffers, we prune the list of zombie + * buffers. + */ + unreference_zombie_buffers_for_ctx(ctx); + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } return true; } +bool +_mesa_handle_bind_buffer_gen(struct gl_context *ctx, + GLuint buffer, + struct gl_buffer_object **buf_handle, + const char *caller, bool no_error) +{ + return handle_bind_buffer_gen(ctx, buffer, buf_handle, caller, no_error); +} + /** * Bind the specified target to buffer for the specified context. * Called by glBindBuffer() and other functions. */ static void bind_buffer_object(struct gl_context *ctx, - struct gl_buffer_object **bindTarget, GLuint buffer) + struct gl_buffer_object **bindTarget, GLuint buffer, + bool no_error) { struct gl_buffer_object *oldBufObj; - struct gl_buffer_object *newBufObj = NULL; + struct gl_buffer_object *newBufObj; assert(bindTarget); + /* Fast path that unbinds. It's better when NULL is a literal, so that + * the compiler can simplify this code after inlining. + */ + if (buffer == 0) { + _mesa_reference_buffer_object(ctx, bindTarget, NULL); + return; + } + /* Get pointer to old buffer object (to be unbound) */ oldBufObj = *bindTarget; - if ((oldBufObj && oldBufObj->Name == buffer && !oldBufObj->DeletePending) || - (!oldBufObj && buffer == 0)) + GLuint old_name = oldBufObj && !oldBufObj->DeletePending ? oldBufObj->Name : 0; + if (unlikely(old_name == buffer)) return; /* rebinding the same buffer object- no change */ - /* - * Get pointer to new buffer object (newBufObj) - */ - if (buffer != 0) { - /* non-default buffer object */ - newBufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &newBufObj, "glBindBuffer")) - return; - - /* record usage history */ - if (bindTarget == &ctx->Pack.BufferObj) - newBufObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; - } + newBufObj = _mesa_lookup_bufferobj(ctx, buffer); + /* Get a new buffer object if it hasn't been created. */ + if (unlikely(!handle_bind_buffer_gen(ctx, buffer, &newBufObj, "glBindBuffer", + no_error))) + return; - /* bind new buffer */ + /* At this point, the compiler should deduce that newBufObj is non-NULL if + * everything has been inlined, so the compiler should simplify this. + */ _mesa_reference_buffer_object(ctx, bindTarget, newBufObj); } @@ -1140,10 +1372,10 @@ void _mesa_update_default_objects_buffer_objects(struct gl_context *ctx) { /* Bind 0 to remove references to those in the shared context hash table. */ - bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0); - bind_buffer_object(ctx, &ctx->Array.VAO->IndexBufferObj, 0); - bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0); - bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0); + bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0, false); + bind_buffer_object(ctx, &ctx->Array.VAO->IndexBufferObj, 0, false); + bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0, false); + bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0, false); } @@ -1159,7 +1391,7 @@ _mesa_lookup_bufferobj(struct gl_context *ctx, GLuint buffer) return NULL; else return (struct gl_buffer_object *) - _mesa_HashLookupMaybeLocked(ctx->Shared->BufferObjects, buffer, + _mesa_HashLookupMaybeLocked(&ctx->Shared->BufferObjects, buffer, ctx->BufferObjectsLocked); } @@ -1171,7 +1403,7 @@ _mesa_lookup_bufferobj_locked(struct gl_context *ctx, GLuint buffer) return NULL; else return (struct gl_buffer_object *) - _mesa_HashLookupLocked(ctx->Shared->BufferObjects, buffer); + _mesa_HashLookupLocked(&ctx->Shared->BufferObjects, buffer); } /** @@ -1210,7 +1442,7 @@ _mesa_lookup_bufferobj_err(struct gl_context *ctx, GLuint buffer, * * This function assumes that the caller has already locked the * hash table mutex by calling - * _mesa_HashLockMutex(ctx->Shared->BufferObjects). + * _mesa_HashLockMutex(&ctx->Shared->BufferObjects). */ struct gl_buffer_object * _mesa_multi_bind_lookup_bufferobj(struct gl_context *ctx, @@ -1267,41 +1499,13 @@ unbind(struct gl_context *ctx, } } - -/** - * Plug default/fallback buffer object functions into the device - * driver hooks. - */ -void -_mesa_init_buffer_object_functions(struct dd_function_table *driver) -{ - /* GL_ARB_vertex/pixel_buffer_object */ - driver->NewBufferObject = _mesa_new_buffer_object; - driver->DeleteBuffer = _mesa_delete_buffer_object; - driver->BufferData = buffer_data_fallback; - driver->BufferSubData = buffer_sub_data_fallback; - driver->GetBufferSubData = buffer_get_subdata; - driver->UnmapBuffer = unmap_buffer_fallback; - - /* GL_ARB_clear_buffer_object */ - driver->ClearBufferSubData = _mesa_ClearBufferSubData_sw; - - /* GL_ARB_map_buffer_range */ - driver->MapBufferRange = map_buffer_range_fallback; - driver->FlushMappedBufferRange = flush_mapped_buffer_range_fallback; - - /* GL_ARB_copy_buffer */ - driver->CopyBufferSubData = copy_buffer_sub_data_fallback; -} - - void _mesa_buffer_unmap_all_mappings(struct gl_context *ctx, struct gl_buffer_object *bufObj) { for (int i = 0; i < MAP_COUNT; i++) { if (_mesa_bufferobj_mapped(bufObj, i)) { - ctx->Driver.UnmapBuffer(ctx, bufObj, i); + _mesa_bufferobj_unmap(ctx, bufObj, i); assert(bufObj->Mappings[i].Pointer == NULL); bufObj->Mappings[i].AccessFlags = 0; } @@ -1318,8 +1522,8 @@ _mesa_BindBuffer_no_error(GLenum target, GLuint buffer) { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target); - bind_buffer_object(ctx, bindTarget, buffer); + struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target, true); + bind_buffer_object(ctx, bindTarget, buffer, true); } @@ -1333,27 +1537,14 @@ _mesa_BindBuffer(GLenum target, GLuint buffer) _mesa_enum_to_string(target), buffer); } - struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target); + struct gl_buffer_object **bindTarget = get_buffer_target(ctx, target, false); if (!bindTarget) { _mesa_error(ctx, GL_INVALID_ENUM, "glBindBufferARB(target %s)", _mesa_enum_to_string(target)); return; } - bind_buffer_object(ctx, bindTarget, buffer); -} - -void -_mesa_InternalBindElementBuffer(struct gl_context *ctx, - struct gl_buffer_object *buf) -{ - struct gl_buffer_object **bindTarget = - get_buffer_target(ctx, GL_ELEMENT_ARRAY_BUFFER); - - /* Move the buffer reference from the parameter to the bind point. */ - _mesa_reference_buffer_object(ctx, bindTarget, NULL); - if (buf) - *bindTarget = buf; + bind_buffer_object(ctx, bindTarget, buffer, false); } /** @@ -1452,7 +1643,7 @@ bind_uniform_buffer(struct gl_context *ctx, { bind_buffer(ctx, &ctx->UniformBufferBindings[index], bufObj, offset, size, autoSize, - ctx->DriverFlags.NewUniformBuffer, + ST_NEW_UNIFORM_BUFFER, USAGE_UNIFORM_BUFFER); } @@ -1473,7 +1664,7 @@ bind_shader_storage_buffer(struct gl_context *ctx, { bind_buffer(ctx, &ctx->ShaderStorageBufferBindings[index], bufObj, offset, size, autoSize, - ctx->DriverFlags.NewShaderStorageBuffer, + ST_NEW_STORAGE_BUFFER, USAGE_SHADER_STORAGE_BUFFER); } @@ -1572,7 +1763,7 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) { FLUSH_VERTICES(ctx, 0, 0); - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); unreference_zombie_buffers_for_ctx(ctx); @@ -1593,38 +1784,38 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) } if (ctx->Array.ArrayBufferObj == bufObj) { - bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0); + bind_buffer_object(ctx, &ctx->Array.ArrayBufferObj, 0, false); } if (vao->IndexBufferObj == bufObj) { - bind_buffer_object(ctx, &vao->IndexBufferObj, 0); + bind_buffer_object(ctx, &vao->IndexBufferObj, 0, false); } /* unbind ARB_draw_indirect binding point */ if (ctx->DrawIndirectBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->DrawIndirectBuffer, 0); + bind_buffer_object(ctx, &ctx->DrawIndirectBuffer, 0, false); } /* unbind ARB_indirect_parameters binding point */ if (ctx->ParameterBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->ParameterBuffer, 0); + bind_buffer_object(ctx, &ctx->ParameterBuffer, 0, false); } /* unbind ARB_compute_shader binding point */ if (ctx->DispatchIndirectBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->DispatchIndirectBuffer, 0); + bind_buffer_object(ctx, &ctx->DispatchIndirectBuffer, 0, false); } /* unbind ARB_copy_buffer binding points */ if (ctx->CopyReadBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->CopyReadBuffer, 0); + bind_buffer_object(ctx, &ctx->CopyReadBuffer, 0, false); } if (ctx->CopyWriteBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->CopyWriteBuffer, 0); + bind_buffer_object(ctx, &ctx->CopyWriteBuffer, 0, false); } /* unbind transform feedback binding points */ if (ctx->TransformFeedback.CurrentBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->TransformFeedback.CurrentBuffer, 0); + bind_buffer_object(ctx, &ctx->TransformFeedback.CurrentBuffer, 0, false); } for (j = 0; j < MAX_FEEDBACK_BUFFERS; j++) { if (ctx->TransformFeedback.CurrentObject->Buffers[j] == bufObj) { @@ -1642,7 +1833,7 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) } if (ctx->UniformBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->UniformBuffer, 0); + bind_buffer_object(ctx, &ctx->UniformBuffer, 0, false); } /* unbind SSBO binding points */ @@ -1653,7 +1844,7 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) } if (ctx->ShaderStorageBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->ShaderStorageBuffer, 0); + bind_buffer_object(ctx, &ctx->ShaderStorageBuffer, 0, false); } /* unbind Atomci Buffer binding points */ @@ -1664,32 +1855,32 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) } if (ctx->AtomicBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->AtomicBuffer, 0); + bind_buffer_object(ctx, &ctx->AtomicBuffer, 0, false); } /* unbind any pixel pack/unpack pointers bound to this buffer */ if (ctx->Pack.BufferObj == bufObj) { - bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0); + bind_buffer_object(ctx, &ctx->Pack.BufferObj, 0, false); } if (ctx->Unpack.BufferObj == bufObj) { - bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0); + bind_buffer_object(ctx, &ctx->Unpack.BufferObj, 0, false); } if (ctx->Texture.BufferObject == bufObj) { - bind_buffer_object(ctx, &ctx->Texture.BufferObject, 0); + bind_buffer_object(ctx, &ctx->Texture.BufferObject, 0, false); } if (ctx->ExternalVirtualMemoryBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->ExternalVirtualMemoryBuffer, 0); + bind_buffer_object(ctx, &ctx->ExternalVirtualMemoryBuffer, 0, false); } /* unbind query buffer binding point */ if (ctx->QueryBuffer == bufObj) { - bind_buffer_object(ctx, &ctx->QueryBuffer, 0); + bind_buffer_object(ctx, &ctx->QueryBuffer, 0, false); } /* The ID is immediately freed for re-use */ - _mesa_HashRemoveLocked(ctx->Shared->BufferObjects, ids[i]); + _mesa_HashRemoveLocked(&ctx->Shared->BufferObjects, ids[i]); /* Make sure we do not run into the classic ABA problem on bind. * We don't want to allow re-binding a buffer object that's been * "deleted" by glDeleteBuffers(). @@ -1718,7 +1909,7 @@ delete_buffers(struct gl_context *ctx, GLsizei n, const GLuint *ids) } } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -1761,10 +1952,17 @@ create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa) /* * This must be atomic (generation and allocation of buffer object IDs) */ - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); + /* If one context only creates buffers and another context only deletes + * buffers, buffers don't get released because it only produces zombie + * buffers. Only the context that has created the buffers can release + * them. Thus, when we create buffers, we prune the list of zombie + * buffers. + */ + unreference_zombie_buffers_for_ctx(ctx); - _mesa_HashFindFreeKeys(ctx->Shared->BufferObjects, buffers, n); + _mesa_HashFindFreeKeys(&ctx->Shared->BufferObjects, buffers, n); /* Insert the ID and pointer into the hash table. If non-DSA, insert a * DummyBufferObject. Otherwise, create a new buffer object and insert @@ -1772,11 +1970,10 @@ create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa) */ for (int i = 0; i < n; i++) { if (dsa) { - assert(ctx->Driver.NewBufferObject); buf = new_gl_buffer_object(ctx, buffers[i]); if (!buf) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCreateBuffers"); - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); return; } @@ -1784,10 +1981,10 @@ create_buffers(struct gl_context *ctx, GLsizei n, GLuint *buffers, bool dsa) else buf = &DummyBufferObject; - _mesa_HashInsertLocked(ctx->Shared->BufferObjects, buffers[i], buf, true); + _mesa_HashInsertLocked(&ctx->Shared->BufferObjects, buffers[i], buf); } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -1943,19 +2140,16 @@ buffer_storage(struct gl_context *ctx, struct gl_buffer_object *bufObj, FLUSH_VERTICES(ctx, 0, 0); - bufObj->Written = GL_TRUE; bufObj->Immutable = GL_TRUE; bufObj->MinMaxCacheDirty = true; if (memObj) { - assert(ctx->Driver.BufferDataMem); - res = ctx->Driver.BufferDataMem(ctx, target, size, memObj, offset, - GL_DYNAMIC_DRAW, bufObj); + res = bufferobj_data_mem(ctx, target, size, memObj, offset, + GL_DYNAMIC_DRAW, bufObj); } else { - assert(ctx->Driver.BufferData); - res = ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW, - flags, bufObj); + res = _mesa_bufferobj_data(ctx, target, size, data, GL_DYNAMIC_DRAW, + flags, bufObj); } if (!res) { @@ -2026,7 +2220,8 @@ inlined_buffer_storage(GLenum target, GLuint buffer, GLsizeiptr size, } } else { if (no_error) { - struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObjPtr = + get_buffer_target(ctx, target, true); bufObj = *bufObjPtr; } else { bufObj = get_buffer(ctx, func, target, GL_INVALID_OPERATION); @@ -2064,8 +2259,8 @@ _mesa_NamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glNamedBufferStorageEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glNamedBufferStorageEXT", false)) return; inlined_buffer_storage(GL_NONE, buffer, size, data, flags, GL_NONE, 0, @@ -2118,7 +2313,7 @@ void GLAPIENTRY _mesa_NamedBufferStorageMemEXT(GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset) { - inlined_buffer_storage(GL_NONE, buffer, size, GL_NONE, 0, memory, offset, + inlined_buffer_storage(GL_NONE, buffer, size, NULL, 0, memory, offset, true, true, false, "glNamedBufferStorageMemEXT"); } @@ -2127,7 +2322,7 @@ void GLAPIENTRY _mesa_NamedBufferStorageMemEXT_no_error(GLuint buffer, GLsizeiptr size, GLuint memory, GLuint64 offset) { - inlined_buffer_storage(GL_NONE, buffer, size, GL_NONE, 0, memory, offset, + inlined_buffer_storage(GL_NONE, buffer, size, NULL, 0, memory, offset, true, true, true, "glNamedBufferStorageMemEXT"); } @@ -2191,7 +2386,6 @@ buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj, FLUSH_VERTICES(ctx, 0, 0); - bufObj->Written = GL_TRUE; bufObj->MinMaxCacheDirty = true; #ifdef VBO_DEBUG @@ -2203,12 +2397,11 @@ buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj, size += 100; #endif - assert(ctx->Driver.BufferData); - if (!ctx->Driver.BufferData(ctx, target, size, data, usage, - GL_MAP_READ_BIT | - GL_MAP_WRITE_BIT | - GL_DYNAMIC_STORAGE_BIT, - bufObj)) { + if (!_mesa_bufferobj_data(ctx, target, size, data, usage, + GL_MAP_READ_BIT | + GL_MAP_WRITE_BIT | + GL_DYNAMIC_STORAGE_BIT, + bufObj)) { if (target == GL_EXTERNAL_VIRTUAL_MEMORY_BUFFER_AMD) { if (!no_error) { /* From GL_AMD_pinned_memory: @@ -2255,7 +2448,7 @@ _mesa_BufferData_no_error(GLenum target, GLsizeiptr size, const GLvoid *data, { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bufObj = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, true); buffer_data_no_error(ctx, *bufObj, target, size, data, usage, "glBufferData"); } @@ -2318,8 +2511,8 @@ _mesa_NamedBufferDataEXT(GLuint buffer, GLsizeiptr size, const GLvoid *data, } bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glNamedBufferDataEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glNamedBufferDataEXT", false)) return; _mesa_buffer_data(ctx, bufObj, GL_NONE, size, data, usage, @@ -2380,11 +2573,9 @@ _mesa_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj, return; bufObj->NumSubDataCalls++; - bufObj->Written = GL_TRUE; bufObj->MinMaxCacheDirty = true; - assert(ctx->Driver.BufferSubData); - ctx->Driver.BufferSubData(ctx, offset, size, data, bufObj); + _mesa_bufferobj_subdata(ctx, offset, size, data, bufObj); } @@ -2406,7 +2597,7 @@ buffer_sub_data(GLenum target, GLuint buffer, GLintptr offset, } } else { if (no_error) { - struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true); bufObj = *bufObjPtr; } else { bufObj = get_buffer(ctx, func, target, GL_INVALID_OPERATION); @@ -2467,8 +2658,8 @@ _mesa_NamedBufferSubDataEXT(GLuint buffer, GLintptr offset, } bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glNamedBufferSubDataEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glNamedBufferSubDataEXT", false)) return; if (validate_buffer_sub_data(ctx, bufObj, offset, size, @@ -2495,8 +2686,7 @@ _mesa_GetBufferSubData(GLenum target, GLintptr offset, return; } - assert(ctx->Driver.GetBufferSubData); - ctx->Driver.GetBufferSubData(ctx, offset, size, data, bufObj); + bufferobj_get_subdata(ctx, offset, size, data, bufObj); } void GLAPIENTRY @@ -2516,8 +2706,7 @@ _mesa_GetNamedBufferSubData(GLuint buffer, GLintptr offset, return; } - assert(ctx->Driver.GetBufferSubData); - ctx->Driver.GetBufferSubData(ctx, offset, size, data, bufObj); + bufferobj_get_subdata(ctx, offset, size, data, bufObj); } @@ -2535,8 +2724,8 @@ _mesa_GetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, } bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glGetNamedBufferSubDataEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glGetNamedBufferSubDataEXT", false)) return; if (!buffer_object_subdata_range_good(ctx, bufObj, offset, size, false, @@ -2544,8 +2733,7 @@ _mesa_GetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, return; } - assert(ctx->Driver.GetBufferSubData); - ctx->Driver.GetBufferSubData(ctx, offset, size, data, bufObj); + bufferobj_get_subdata(ctx, offset, size, data, bufObj); } /** @@ -2592,20 +2780,21 @@ clear_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj, bufObj->MinMaxCacheDirty = true; - if (data == NULL) { - /* clear to zeros, per the spec */ - ctx->Driver.ClearBufferSubData(ctx, offset, size, - NULL, clearValueSize, bufObj); + if (!ctx->pipe->clear_buffer) { + clear_buffer_subdata_sw(ctx, offset, size, + data, clearValueSize, bufObj); return; } - if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue, - format, type, data, func)) { + if (!data) + memset(clearValue, 0, MAX_PIXEL_BYTES); + else if (!convert_clear_buffer_data(ctx, mesaFormat, clearValue, + format, type, data, func)) { return; } - ctx->Driver.ClearBufferSubData(ctx, offset, size, - clearValue, clearValueSize, bufObj); + ctx->pipe->clear_buffer(ctx->pipe, bufObj->buffer, offset, size, + clearValue, clearValueSize); } static void @@ -2639,7 +2828,7 @@ _mesa_ClearBufferData_no_error(GLenum target, GLenum internalformat, { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bufObj = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, true); clear_buffer_sub_data_no_error(ctx, *bufObj, internalformat, 0, (*bufObj)->Size, format, type, data, "glClearBufferData", false); @@ -2699,8 +2888,8 @@ _mesa_ClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glClearNamedBufferDataEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glClearNamedBufferDataEXT", false)) return; clear_buffer_sub_data_error(ctx, bufObj, internalformat, 0, bufObj->Size, @@ -2717,7 +2906,7 @@ _mesa_ClearBufferSubData_no_error(GLenum target, GLenum internalformat, { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bufObj = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObj = get_buffer_target(ctx, target, true); clear_buffer_sub_data_no_error(ctx, *bufObj, internalformat, offset, size, format, type, data, "glClearBufferSubData", true); @@ -2785,8 +2974,8 @@ _mesa_ClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, { GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glClearNamedBufferSubDataEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glClearNamedBufferSubDataEXT", false)) return; clear_buffer_sub_data_error(ctx, bufObj, internalformat, offset, size, @@ -2797,7 +2986,7 @@ _mesa_ClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, static GLboolean unmap_buffer(struct gl_context *ctx, struct gl_buffer_object *bufObj) { - GLboolean status = ctx->Driver.UnmapBuffer(ctx, bufObj, MAP_USER); + GLboolean status = _mesa_bufferobj_unmap(ctx, bufObj, MAP_USER); bufObj->Mappings[MAP_USER].AccessFlags = 0; assert(bufObj->Mappings[MAP_USER].Pointer == NULL); assert(bufObj->Mappings[MAP_USER].Offset == 0); @@ -2862,7 +3051,7 @@ GLboolean GLAPIENTRY _mesa_UnmapBuffer_no_error(GLenum target) { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true); struct gl_buffer_object *bufObj = *bufObjPtr; return unmap_buffer(ctx, bufObj); @@ -3037,8 +3226,8 @@ _mesa_GetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params) } bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glGetNamedBufferParameterivEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glGetNamedBufferParameterivEXT", false)) return; if (!get_buffer_parameter(ctx, bufObj, pname, ¶meter, @@ -3127,8 +3316,8 @@ _mesa_GetNamedBufferPointervEXT(GLuint buffer, GLenum pname, GLvoid **params) } bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glGetNamedBufferPointervEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glGetNamedBufferPointervEXT", false)) return; *params = bufObj->Mappings[MAP_USER].Pointer; @@ -3169,14 +3358,14 @@ copy_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *src, return; } - if (readOffset + size > src->Size) { + if (size > src->Size || readOffset > src->Size - size) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(readOffset %d + size %d > src_buffer_size %d)", func, (int) readOffset, (int) size, (int) src->Size); return; } - if (writeOffset + size > dst->Size) { + if (size > dst->Size || writeOffset > dst->Size - size) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(writeOffset %d + size %d > dst_buffer_size %d)", func, (int) writeOffset, (int) size, (int) dst->Size); @@ -3198,9 +3387,7 @@ copy_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *src, } } - dst->MinMaxCacheDirty = true; - - ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset, size); + bufferobj_copy_subdata(ctx, src, dst, readOffset, writeOffset, size); } void GLAPIENTRY @@ -3210,15 +3397,14 @@ _mesa_CopyBufferSubData_no_error(GLenum readTarget, GLenum writeTarget, { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **src_ptr = get_buffer_target(ctx, readTarget); + struct gl_buffer_object **src_ptr = get_buffer_target(ctx, readTarget, true); struct gl_buffer_object *src = *src_ptr; - struct gl_buffer_object **dst_ptr = get_buffer_target(ctx, writeTarget); + struct gl_buffer_object **dst_ptr = get_buffer_target(ctx, writeTarget, true); struct gl_buffer_object *dst = *dst_ptr; - dst->MinMaxCacheDirty = true; - ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset, - size); + bufferobj_copy_subdata(ctx, src, dst, readOffset, writeOffset, + size); } void GLAPIENTRY @@ -3252,15 +3438,14 @@ _mesa_NamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, struct gl_buffer_object *src, *dst; src = _mesa_lookup_bufferobj(ctx, readBuffer); - if (!_mesa_handle_bind_buffer_gen(ctx, readBuffer, - &src, - "glNamedCopyBufferSubDataEXT")) + if (!handle_bind_buffer_gen(ctx, readBuffer, + &src, + "glNamedCopyBufferSubDataEXT", false)) return; dst = _mesa_lookup_bufferobj(ctx, writeBuffer); - if (!_mesa_handle_bind_buffer_gen(ctx, writeBuffer, - &dst, - "glNamedCopyBufferSubDataEXT")) + if (!handle_bind_buffer_gen(ctx, writeBuffer, + &dst, "glNamedCopyBufferSubDataEXT", false)) return; copy_buffer_sub_data(ctx, src, dst, readOffset, writeOffset, size, @@ -3277,9 +3462,8 @@ _mesa_CopyNamedBufferSubData_no_error(GLuint readBuffer, GLuint writeBuffer, struct gl_buffer_object *src = _mesa_lookup_bufferobj(ctx, readBuffer); struct gl_buffer_object *dst = _mesa_lookup_bufferobj(ctx, writeBuffer); - dst->MinMaxCacheDirty = true; - ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset, - size); + bufferobj_copy_subdata(ctx, src, dst, readOffset, writeOffset, + size); } void GLAPIENTRY @@ -3319,7 +3503,7 @@ _mesa_InternalBufferSubDataCopyMESA(GLintptr srcBuffer, GLuint srcOffset, if (named && ext_dsa) { func = "glNamedBufferSubDataEXT"; dst = _mesa_lookup_bufferobj(ctx, dstTargetOrName); - if (!_mesa_handle_bind_buffer_gen(ctx, dstTargetOrName, &dst, func)) + if (!handle_bind_buffer_gen(ctx, dstTargetOrName, &dst, func, false)) goto done; } else if (named) { func = "glNamedBufferSubData"; @@ -3337,8 +3521,7 @@ _mesa_InternalBufferSubDataCopyMESA(GLintptr srcBuffer, GLuint srcOffset, if (!validate_buffer_sub_data(ctx, dst, dstOffset, size, func)) goto done; /* the error is already set */ - dst->MinMaxCacheDirty = true; - ctx->Driver.CopyBufferSubData(ctx, src, dst, srcOffset, dstOffset, size); + bufferobj_copy_subdata(ctx, src, dst, srcOffset, dstOffset, size); done: /* The caller passes the reference to this function, so unreference it. */ @@ -3492,9 +3675,8 @@ map_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj, return NULL; } - assert(ctx->Driver.MapBufferRange); - void *map = ctx->Driver.MapBufferRange(ctx, offset, length, access, bufObj, - MAP_USER); + void *map = _mesa_bufferobj_map_range(ctx, offset, length, access, bufObj, + MAP_USER); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s(map failed)", func); } @@ -3510,7 +3692,6 @@ map_buffer_range(struct gl_context *ctx, struct gl_buffer_object *bufObj, } if (access & GL_MAP_WRITE_BIT) { - bufObj->Written = GL_TRUE; bufObj->MinMaxCacheDirty = true; } @@ -3548,7 +3729,7 @@ _mesa_MapBufferRange_no_error(GLenum target, GLintptr offset, { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true); struct gl_buffer_object *bufObj = *bufObjPtr; return map_buffer_range(ctx, bufObj, offset, length, access, @@ -3606,7 +3787,7 @@ map_named_buffer_range(GLuint buffer, GLintptr offset, GLsizeiptr length, if (dsa_ext) { bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &bufObj, func)) + if (!handle_bind_buffer_gen(ctx, buffer, &bufObj, func, false)) return NULL; } else { bufObj = _mesa_lookup_bufferobj_err(ctx, buffer, func); @@ -3676,7 +3857,7 @@ _mesa_MapBuffer_no_error(GLenum target, GLenum access) GLbitfield accessFlags; get_map_buffer_access_flags(ctx, access, &accessFlags); - struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true); struct gl_buffer_object *bufObj = *bufObjPtr; return map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, @@ -3762,8 +3943,8 @@ _mesa_MapNamedBufferEXT(GLuint buffer, GLenum access) } struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glMapNamedBufferEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glMapNamedBufferEXT", false)) return NULL; if (!validate_map_buffer_range(ctx, bufObj, 0, bufObj->Size, accessFlags, @@ -3822,9 +4003,8 @@ flush_mapped_buffer_range(struct gl_context *ctx, assert(bufObj->Mappings[MAP_USER].AccessFlags & GL_MAP_WRITE_BIT); - if (ctx->Driver.FlushMappedBufferRange) - ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj, - MAP_USER); + _mesa_bufferobj_flush_mapped_range(ctx, offset, length, bufObj, + MAP_USER); } void GLAPIENTRY @@ -3832,12 +4012,11 @@ _mesa_FlushMappedBufferRange_no_error(GLenum target, GLintptr offset, GLsizeiptr length) { GET_CURRENT_CONTEXT(ctx); - struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target); + struct gl_buffer_object **bufObjPtr = get_buffer_target(ctx, target, true); struct gl_buffer_object *bufObj = *bufObjPtr; - if (ctx->Driver.FlushMappedBufferRange) - ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj, - MAP_USER); + _mesa_bufferobj_flush_mapped_range(ctx, offset, length, bufObj, + MAP_USER); } void GLAPIENTRY @@ -3863,9 +4042,8 @@ _mesa_FlushMappedNamedBufferRange_no_error(GLuint buffer, GLintptr offset, GET_CURRENT_CONTEXT(ctx); struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (ctx->Driver.FlushMappedBufferRange) - ctx->Driver.FlushMappedBufferRange(ctx, offset, length, bufObj, - MAP_USER); + _mesa_bufferobj_flush_mapped_range(ctx, offset, length, bufObj, + MAP_USER); } void GLAPIENTRY @@ -3898,8 +4076,8 @@ _mesa_FlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, } bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glFlushMappedNamedBufferRangeEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glFlushMappedNamedBufferRangeEXT", false)) return; flush_mapped_buffer_range(ctx, bufObj, offset, length, @@ -4161,7 +4339,7 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count, /* Assume that at least one binding will be changed */ FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer; + ctx->NewDriverState |= ST_NEW_UNIFORM_BUFFER; if (!buffers) { /* The ARB_multi_bind spec says: @@ -4195,7 +4373,7 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count, * parameters are valid and no other error occurs." */ - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); for (int i = 0; i < count; i++) { @@ -4247,7 +4425,7 @@ bind_uniform_buffers(struct gl_context *ctx, GLuint first, GLsizei count, USAGE_UNIFORM_BUFFER); } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -4264,7 +4442,7 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first, /* Assume that at least one binding will be changed */ FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer; + ctx->NewDriverState |= ST_NEW_STORAGE_BUFFER; if (!buffers) { /* The ARB_multi_bind spec says: @@ -4298,7 +4476,7 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first, * parameters are valid and no other error occurs." */ - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); for (int i = 0; i < count; i++) { @@ -4350,7 +4528,7 @@ bind_shader_storage_buffers(struct gl_context *ctx, GLuint first, USAGE_SHADER_STORAGE_BUFFER); } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -4432,7 +4610,6 @@ bind_xfb_buffers(struct gl_context *ctx, /* Assume that at least one binding will be changed */ FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback; if (!buffers) { /* The ARB_multi_bind spec says: @@ -4466,7 +4643,7 @@ bind_xfb_buffers(struct gl_context *ctx, * parameters are valid and no other error occurs." */ - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); for (int i = 0; i < count; i++) { @@ -4534,7 +4711,7 @@ bind_xfb_buffers(struct gl_context *ctx, offset, size); } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -4627,7 +4804,7 @@ bind_atomic_buffers(struct gl_context *ctx, * parameters are valid and no other error occurs." */ - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); for (int i = 0; i < count; i++) { @@ -4676,7 +4853,7 @@ bind_atomic_buffers(struct gl_context *ctx, USAGE_ATOMIC_COUNTER_BUFFER); } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -4697,15 +4874,9 @@ bind_buffer_range(GLenum target, GLuint index, GLuint buffer, GLintptr offset, bufObj = NULL; } else { bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glBindBufferRange")) + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glBindBufferRange", no_error)) return; - - if (!no_error && !bufObj) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindBufferRange(invalid buffer=%u)", buffer); - return; - } } if (no_error) { @@ -4795,15 +4966,9 @@ _mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer) bufObj = NULL; } else { bufObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, - &bufObj, "glBindBufferBase")) - return; - - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glBindBufferBase(invalid buffer=%u)", buffer); + if (!handle_bind_buffer_gen(ctx, buffer, + &bufObj, "glBindBufferBase", false)) return; - } } /* Note that there's some oddness in the GL 3.1-GL 3.3 specifications with @@ -4925,13 +5090,35 @@ _mesa_BindBuffersBase(GLenum target, GLuint first, GLsizei count, } } +/** + * Called via glInvalidateBuffer(Sub)Data. + */ +static void +bufferobj_invalidate(struct gl_context *ctx, + struct gl_buffer_object *obj, + GLintptr offset, + GLsizeiptr size) +{ + struct pipe_context *pipe = ctx->pipe; + + /* We ignore partial invalidates. */ + if (offset != 0 || size != obj->Size) + return; + + /* If the buffer is mapped, we can't invalidate it. */ + if (!obj->buffer || _mesa_bufferobj_mapped(obj, MAP_USER)) + return; + + pipe->invalidate_resource(pipe, obj->buffer); +} + static ALWAYS_INLINE void invalidate_buffer_subdata(struct gl_context *ctx, struct gl_buffer_object *bufObj, GLintptr offset, GLsizeiptr length) { - if (ctx->Driver.InvalidateBufferSubData) - ctx->Driver.InvalidateBufferSubData(ctx, bufObj, offset, length); + if (ctx->has_invalidate_buffer) + bufferobj_invalidate(ctx, bufObj, offset, length); } void GLAPIENTRY @@ -5081,7 +5268,14 @@ buffer_page_commitment(struct gl_context *ctx, return; } - ctx->Driver.BufferPageCommitment(ctx, bufferObj, offset, size, commit); + struct pipe_context *pipe = ctx->pipe; + struct pipe_box box; + + u_box_1d(offset, size, &box); + + if (!pipe->resource_commit(pipe, bufferObj->buffer, 0, &box, commit)) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBufferPageCommitmentARB(out of memory)"); + } } void GLAPIENTRY @@ -5130,8 +5324,8 @@ _mesa_NamedBufferPageCommitmentEXT(GLuint buffer, GLintptr offset, /* Use NamedBuffer* functions logic from EXT_direct_state_access */ if (buffer != 0) { bufferObj = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &bufferObj, - "glNamedBufferPageCommitmentEXT")) + if (!handle_bind_buffer_gen(ctx, buffer, &bufferObj, + "glNamedBufferPageCommitmentEXT", false)) return; } else { /* GL_EXT_direct_state_access says about NamedBuffer* functions: diff --git a/src/mesa/main/bufferobj.h b/src/mesa/main/bufferobj.h index 198bf74a02b..0b4c8f80a85 100644 --- a/src/mesa/main/bufferobj.h +++ b/src/mesa/main/bufferobj.h @@ -36,6 +36,79 @@ * Internal functions */ +static ALWAYS_INLINE struct pipe_resource * +_mesa_get_bufferobj_reference(struct gl_context *ctx, struct gl_buffer_object *obj) +{ + assert(obj); + struct pipe_resource *buffer = obj->buffer; + + /* Only one context is using the fast path. All other contexts must use + * the slow path. + */ + if (unlikely(obj->private_refcount_ctx != ctx || + obj->private_refcount <= 0)) { + if (buffer) { + if (obj->private_refcount_ctx != ctx) { + p_atomic_inc(&buffer->reference.count); + } else { + /* This is the number of atomic increments we will skip. */ + const unsigned count = 100000000; + p_atomic_add(&buffer->reference.count, count); + + /* Remove the reference that we return. */ + assert(obj->private_refcount == 0); + obj->private_refcount = count - 1; + } + } + return buffer; + } + + /* Return a buffer reference while decrementing the private refcount. + * The buffer must be non-NULL, which is implied by private_refcount_ctx + * being non-NULL. + */ + assert(buffer); + obj->private_refcount--; + return buffer; +} + +void _mesa_bufferobj_subdata(struct gl_context *ctx, + GLintptrARB offset, + GLsizeiptrARB size, + const void * data, struct gl_buffer_object *obj); +GLboolean _mesa_bufferobj_data(struct gl_context *ctx, + GLenum target, + GLsizeiptrARB size, + const void *data, + GLenum usage, + GLbitfield storageFlags, + struct gl_buffer_object *obj); +void +_mesa_bufferobj_get_subdata(struct gl_context *ctx, + GLintptrARB offset, + GLsizeiptrARB size, + void *data, struct gl_buffer_object *obj); + +void *_mesa_bufferobj_map_range(struct gl_context *ctx, + GLintptr offset, GLsizeiptr length, + GLbitfield access, + struct gl_buffer_object *obj, + gl_map_buffer_index index); + +void _mesa_bufferobj_flush_mapped_range(struct gl_context *ctx, + GLintptr offset, GLsizeiptr length, + struct gl_buffer_object *obj, + gl_map_buffer_index index); +GLboolean _mesa_bufferobj_unmap(struct gl_context *ctx, struct gl_buffer_object *obj, + gl_map_buffer_index index); + +struct gl_buffer_object * +_mesa_bufferobj_alloc(struct gl_context *ctx, GLuint id); +void +_mesa_bufferobj_release_buffer(struct gl_buffer_object *obj); + +enum pipe_map_flags +_mesa_access_flags_to_transfer_flags(GLbitfield access, bool wholeBuffer); /** Is the given buffer object currently mapped by the GL user? */ static inline GLboolean @@ -71,7 +144,7 @@ extern bool _mesa_handle_bind_buffer_gen(struct gl_context *ctx, GLuint buffer, struct gl_buffer_object **buf_handle, - const char *caller); + const char *caller, bool no_error); extern void _mesa_update_default_objects_buffer_objects(struct gl_context *ctx); @@ -94,19 +167,51 @@ _mesa_multi_bind_lookup_bufferobj(struct gl_context *ctx, bool *error); extern void -_mesa_initialize_buffer_object(struct gl_context *ctx, - struct gl_buffer_object *obj, - GLuint name); - -extern void _mesa_delete_buffer_object(struct gl_context *ctx, struct gl_buffer_object *bufObj); -extern void +/** + * Set ptr to bufObj w/ reference counting. + * This is normally only called from the _mesa_reference_buffer_object() macro + * when there's a real pointer change. + */ +static inline void _mesa_reference_buffer_object_(struct gl_context *ctx, struct gl_buffer_object **ptr, struct gl_buffer_object *bufObj, - bool shared_binding); + bool shared_binding) +{ + if (*ptr) { + /* Unreference the old buffer */ + struct gl_buffer_object *oldObj = *ptr; + + assert(oldObj->RefCount >= 1); + + /* Count references only if the context doesn't own the buffer or if + * ptr is a binding point shared by multiple contexts (such as a texture + * buffer object being a buffer bound within a texture object). + */ + if (shared_binding || ctx != oldObj->Ctx) { + if (p_atomic_dec_zero(&oldObj->RefCount)) { + _mesa_delete_buffer_object(ctx, oldObj); + } + } else { + /* Update the private ref count. */ + assert(oldObj->CtxRefCount >= 1); + oldObj->CtxRefCount--; + } + } + + if (bufObj) { + /* reference new buffer */ + if (shared_binding || ctx != bufObj->Ctx) + p_atomic_inc(&bufObj->RefCount); + else + bufObj->CtxRefCount++; + } + + *ptr = bufObj; +} /** * Assign a buffer into a pointer with reference counting. The destination @@ -134,12 +239,6 @@ _mesa_reference_buffer_object_shared(struct gl_context *ctx, _mesa_reference_buffer_object_(ctx, ptr, bufObj, true); } -extern GLuint -_mesa_total_buffer_object_memory(struct gl_context *ctx); - -extern void -_mesa_init_buffer_object_functions(struct dd_function_table *driver); - extern void _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj, GLenum target, GLsizeiptr size, const GLvoid *data, @@ -160,322 +259,4 @@ _mesa_ClearBufferSubData_sw(struct gl_context *ctx, GLsizeiptr clearValueSize, struct gl_buffer_object *bufObj); -/* - * API functions - */ -void GLAPIENTRY -_mesa_BindBuffer_no_error(GLenum target, GLuint buffer); - -void GLAPIENTRY -_mesa_BindBuffer(GLenum target, GLuint buffer); - -void -_mesa_InternalBindElementBuffer(struct gl_context *ctx, - struct gl_buffer_object *buf); - -void GLAPIENTRY -_mesa_DeleteBuffers_no_error(GLsizei n, const GLuint * buffer); - -void GLAPIENTRY -_mesa_DeleteBuffers(GLsizei n, const GLuint * buffer); - -void GLAPIENTRY -_mesa_GenBuffers_no_error(GLsizei n, GLuint *buffers); - -void GLAPIENTRY -_mesa_GenBuffers(GLsizei n, GLuint *buffers); - -void GLAPIENTRY -_mesa_CreateBuffers_no_error(GLsizei n, GLuint *buffers); - -void GLAPIENTRY -_mesa_CreateBuffers(GLsizei n, GLuint *buffers); - -GLboolean GLAPIENTRY -_mesa_IsBuffer(GLuint buffer); - -void GLAPIENTRY -_mesa_BufferStorage_no_error(GLenum target, GLsizeiptr size, - const GLvoid *data, GLbitfield flags); -void GLAPIENTRY -_mesa_BufferStorage(GLenum target, GLsizeiptr size, const GLvoid *data, - GLbitfield flags); -void GLAPIENTRY -_mesa_NamedBufferStorageEXT(GLuint buffer, GLsizeiptr size, - const GLvoid *data, GLbitfield flags); -void GLAPIENTRY -_mesa_BufferStorageMemEXT(GLenum target, GLsizeiptr size, - GLuint memory, GLuint64 offset); -void GLAPIENTRY -_mesa_BufferStorageMemEXT_no_error(GLenum target, GLsizeiptr size, - GLuint memory, GLuint64 offset); -void GLAPIENTRY -_mesa_NamedBufferStorage_no_error(GLuint buffer, GLsizeiptr size, - const GLvoid *data, GLbitfield flags); -void GLAPIENTRY -_mesa_NamedBufferStorage(GLuint buffer, GLsizeiptr size, const GLvoid *data, - GLbitfield flags); -void GLAPIENTRY -_mesa_NamedBufferStorageMemEXT(GLuint buffer, GLsizeiptr size, - GLuint memory, GLuint64 offset); -void GLAPIENTRY -_mesa_NamedBufferStorageMemEXT_no_error(GLuint buffer, GLsizeiptr size, - GLuint memory, GLuint64 offset); - -void GLAPIENTRY -_mesa_BufferData_no_error(GLenum target, GLsizeiptr size, - const GLvoid *data, GLenum usage); - -void GLAPIENTRY -_mesa_BufferData(GLenum target, GLsizeiptr size, - const GLvoid *data, GLenum usage); - -void GLAPIENTRY -_mesa_NamedBufferData_no_error(GLuint buffer, GLsizeiptr size, - const GLvoid *data, GLenum usage); - -void GLAPIENTRY -_mesa_NamedBufferData(GLuint buffer, GLsizeiptr size, - const GLvoid *data, GLenum usage); -void GLAPIENTRY -_mesa_NamedBufferDataEXT(GLuint buffer, GLsizeiptr size, - const GLvoid *data, GLenum usage); - -void GLAPIENTRY -_mesa_BufferSubData_no_error(GLenum target, GLintptr offset, - GLsizeiptr size, const GLvoid *data); -void GLAPIENTRY -_mesa_BufferSubData(GLenum target, GLintptr offset, - GLsizeiptr size, const GLvoid *data); - -void GLAPIENTRY -_mesa_NamedBufferSubData_no_error(GLuint buffer, GLintptr offset, - GLsizeiptr size, const GLvoid *data); -void GLAPIENTRY -_mesa_NamedBufferSubData(GLuint buffer, GLintptr offset, - GLsizeiptr size, const GLvoid *data); -void GLAPIENTRY -_mesa_NamedBufferSubDataEXT(GLuint buffer, GLintptr offset, - GLsizeiptr size, const GLvoid *data); - -void GLAPIENTRY -_mesa_GetBufferSubData(GLenum target, GLintptr offset, - GLsizeiptr size, GLvoid *data); - -void GLAPIENTRY -_mesa_GetNamedBufferSubData(GLuint buffer, GLintptr offset, - GLsizeiptr size, GLvoid *data); - -void GLAPIENTRY -_mesa_GetNamedBufferSubDataEXT(GLuint buffer, GLintptr offset, - GLsizeiptr size, GLvoid *data); - -void GLAPIENTRY -_mesa_ClearBufferData_no_error(GLenum target, GLenum internalformat, - GLenum format, GLenum type, const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearBufferData(GLenum target, GLenum internalformat, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearNamedBufferData_no_error(GLuint buffer, GLenum internalformat, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearNamedBufferData(GLuint buffer, GLenum internalformat, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearNamedBufferDataEXT(GLuint buffer, GLenum internalformat, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearBufferSubData_no_error(GLenum target, GLenum internalformat, - GLintptr offset, GLsizeiptr size, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearBufferSubData(GLenum target, GLenum internalformat, - GLintptr offset, GLsizeiptr size, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearNamedBufferSubData_no_error(GLuint buffer, GLenum internalformat, - GLintptr offset, GLsizeiptr size, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearNamedBufferSubData(GLuint buffer, GLenum internalformat, - GLintptr offset, GLsizeiptr size, - GLenum format, GLenum type, - const GLvoid *data); - -void GLAPIENTRY -_mesa_ClearNamedBufferSubDataEXT(GLuint buffer, GLenum internalformat, - GLintptr offset, GLsizeiptr size, - GLenum format, GLenum type, - const GLvoid *data); - -GLboolean GLAPIENTRY -_mesa_UnmapBuffer_no_error(GLenum target); -GLboolean GLAPIENTRY -_mesa_UnmapBuffer(GLenum target); - -GLboolean GLAPIENTRY -_mesa_UnmapNamedBufferEXT_no_error(GLuint buffer); -GLboolean GLAPIENTRY -_mesa_UnmapNamedBufferEXT(GLuint buffer); - -void GLAPIENTRY -_mesa_GetBufferParameteriv(GLenum target, GLenum pname, GLint *params); - -void GLAPIENTRY -_mesa_GetBufferParameteri64v(GLenum target, GLenum pname, GLint64 *params); - -void GLAPIENTRY -_mesa_GetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params); - -void GLAPIENTRY -_mesa_GetNamedBufferParameterivEXT(GLuint buffer, GLenum pname, GLint *params); - -void GLAPIENTRY -_mesa_GetNamedBufferParameteri64v(GLuint buffer, GLenum pname, - GLint64 *params); - -void GLAPIENTRY -_mesa_GetBufferPointerv(GLenum target, GLenum pname, GLvoid **params); - -void GLAPIENTRY -_mesa_GetNamedBufferPointerv(GLuint buffer, GLenum pname, GLvoid **params); - -void GLAPIENTRY -_mesa_GetNamedBufferPointervEXT(GLuint buffer, GLenum pname, GLvoid **params); - -void GLAPIENTRY -_mesa_CopyBufferSubData_no_error(GLenum readTarget, GLenum writeTarget, - GLintptr readOffset, GLintptr writeOffset, - GLsizeiptr size); -void GLAPIENTRY -_mesa_CopyBufferSubData(GLenum readTarget, GLenum writeTarget, - GLintptr readOffset, GLintptr writeOffset, - GLsizeiptr size); - -void GLAPIENTRY -_mesa_NamedCopyBufferSubDataEXT(GLuint readBuffer, GLuint writeBuffer, - GLintptr readOffset, GLintptr writeOffset, - GLsizeiptr size); - -void GLAPIENTRY -_mesa_CopyNamedBufferSubData_no_error(GLuint readBuffer, GLuint writeBuffer, - GLintptr readOffset, - GLintptr writeOffset, GLsizeiptr size); -void GLAPIENTRY -_mesa_CopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, - GLintptr readOffset, GLintptr writeOffset, - GLsizeiptr size); -void GLAPIENTRY -_mesa_InternalBufferSubDataCopyMESA(GLintptr srcBuffer, GLuint srcOffset, - GLuint dstTargetOrName, GLintptr dstOffset, - GLsizeiptr size, GLboolean named, - GLboolean ext_dsa); - -void * GLAPIENTRY -_mesa_MapBufferRange_no_error(GLenum target, GLintptr offset, - GLsizeiptr length, GLbitfield access); -void * GLAPIENTRY -_mesa_MapBufferRange(GLenum target, GLintptr offset, GLsizeiptr length, - GLbitfield access); - -void * GLAPIENTRY -_mesa_MapNamedBufferRange_no_error(GLuint buffer, GLintptr offset, - GLsizeiptr length, GLbitfield access); -void * GLAPIENTRY -_mesa_MapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, - GLbitfield access); -void * GLAPIENTRY -_mesa_MapNamedBufferRangeEXT(GLuint buffer, GLintptr offset, - GLsizeiptr length, GLbitfield access); - -void * GLAPIENTRY -_mesa_MapBuffer_no_error(GLenum target, GLenum access); -void * GLAPIENTRY -_mesa_MapBuffer(GLenum target, GLenum access); - -void * GLAPIENTRY -_mesa_MapNamedBuffer_no_error(GLuint buffer, GLenum access); -void * GLAPIENTRY -_mesa_MapNamedBuffer(GLuint buffer, GLenum access); -void * GLAPIENTRY -_mesa_MapNamedBufferEXT(GLuint buffer, GLenum access); - -void GLAPIENTRY -_mesa_FlushMappedBufferRange_no_error(GLenum target, GLintptr offset, - GLsizeiptr length); -void GLAPIENTRY -_mesa_FlushMappedBufferRange(GLenum target, - GLintptr offset, GLsizeiptr length); - -void GLAPIENTRY -_mesa_FlushMappedNamedBufferRange_no_error(GLuint buffer, GLintptr offset, - GLsizeiptr length); -void GLAPIENTRY -_mesa_FlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, - GLsizeiptr length); - -void GLAPIENTRY -_mesa_FlushMappedNamedBufferRangeEXT(GLuint buffer, GLintptr offset, - GLsizeiptr length); - -void GLAPIENTRY -_mesa_BindBufferRange_no_error(GLenum target, GLuint index, GLuint buffer, - GLintptr offset, GLsizeiptr size); -void GLAPIENTRY -_mesa_BindBufferRange(GLenum target, GLuint index, - GLuint buffer, GLintptr offset, GLsizeiptr size); - -void GLAPIENTRY -_mesa_BindBufferBase(GLenum target, GLuint index, GLuint buffer); - -void GLAPIENTRY -_mesa_BindBuffersRange(GLenum target, GLuint first, GLsizei count, - const GLuint *buffers, - const GLintptr *offsets, const GLsizeiptr *sizes); -void GLAPIENTRY -_mesa_BindBuffersBase(GLenum target, GLuint first, GLsizei count, - const GLuint *buffers); - -void GLAPIENTRY -_mesa_InvalidateBufferSubData_no_error(GLuint buffer, GLintptr offset, - GLsizeiptr length); - -void GLAPIENTRY -_mesa_InvalidateBufferSubData(GLuint buffer, GLintptr offset, - GLsizeiptr length); - -void GLAPIENTRY -_mesa_InvalidateBufferData_no_error(GLuint buffer); - -void GLAPIENTRY -_mesa_InvalidateBufferData(GLuint buffer); - -void GLAPIENTRY -_mesa_BufferPageCommitmentARB(GLenum target, GLintptr offset, GLsizeiptr size, - GLboolean commit); - -void GLAPIENTRY -_mesa_NamedBufferPageCommitmentARB(GLuint buffer, GLintptr offset, - GLsizeiptr size, GLboolean commit); - -void GLAPIENTRY -_mesa_NamedBufferPageCommitmentEXT(GLuint buffer, GLintptr offset, - GLsizeiptr size, GLboolean commit); - #endif diff --git a/src/mesa/main/buffers.c b/src/mesa/main/buffers.c index 5930ec49e4e..c4c67ade324 100644 --- a/src/mesa/main/buffers.c +++ b/src/mesa/main/buffers.c @@ -30,16 +30,23 @@ -#include "glheader.h" +#include "util/glheader.h" #include "buffers.h" #include "context.h" #include "enums.h" #include "fbobject.h" +#include "framebuffer.h" #include "hash.h" #include "mtypes.h" +#include "state.h" #include "util/bitscan.h" #include "util/u_math.h" +#include "api_exec_decl.h" +#include "state_tracker/st_manager.h" +#include "state_tracker/st_atom.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_util.h" #define BAD_MASK ~0u @@ -315,10 +322,8 @@ draw_buffer(struct gl_context *ctx, struct gl_framebuffer *fb, /* Call device driver function only if fb is the bound draw buffer */ if (fb == ctx->DrawBuffer) { - if (ctx->Driver.DrawBuffer) - ctx->Driver.DrawBuffer(ctx); - if (ctx->Driver.DrawBufferAllocate) - ctx->Driver.DrawBufferAllocate(ctx); + if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) + _mesa_draw_buffer_allocate(ctx); } } @@ -454,7 +459,7 @@ draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n, * and the constant must be BACK or NONE." * (same restriction applies with GL_EXT_draw_buffers specification) */ - if (ctx->API == API_OPENGLES2 && _mesa_is_winsys_fbo(fb) && + if (_mesa_is_gles2(ctx) && _mesa_is_winsys_fbo(fb) && (n != 1 || (buffers[0] != GL_NONE && buffers[0] != GL_BACK))) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(invalid buffers)", caller); return; @@ -583,7 +588,7 @@ draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n, * INVALID_OPERATION." (same restriction applies with * GL_EXT_draw_buffers specification) */ - if (ctx->API == API_OPENGLES2 && _mesa_is_user_fbo(fb) && + if (_mesa_is_gles2(ctx) && _mesa_is_user_fbo(fb) && buffers[output] != GL_NONE && buffers[output] != GL_COLOR_ATTACHMENT0 + output) { _mesa_error(ctx, GL_INVALID_OPERATION, @@ -624,10 +629,8 @@ draw_buffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei n, * may not be valid. */ if (fb == ctx->DrawBuffer) { - if (ctx->Driver.DrawBuffer) - ctx->Driver.DrawBuffer(ctx); - if (ctx->Driver.DrawBufferAllocate) - ctx->Driver.DrawBufferAllocate(ctx); + if (_mesa_is_winsys_fbo(ctx->DrawBuffer)) + _mesa_draw_buffer_allocate(ctx); } } @@ -728,7 +731,7 @@ updated_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb) { FLUSH_VERTICES(ctx, _NEW_BUFFERS, GL_COLOR_BUFFER_BIT); - if (ctx->API == API_OPENGL_COMPAT && !ctx->Extensions.ARB_ES2_compatibility) { + if (_mesa_is_desktop_gl_compat(ctx) && !ctx->Extensions.ARB_ES2_compatibility) { /* Flag the FBO as requiring validation. */ if (_mesa_is_user_fbo(fb)) { fb->_Status = 0; @@ -936,8 +939,19 @@ read_buffer(struct gl_context *ctx, struct gl_framebuffer *fb, /* Call the device driver function only if fb is the bound read buffer */ if (fb == ctx->ReadBuffer) { - if (ctx->Driver.ReadBuffer) - ctx->Driver.ReadBuffer(ctx, buffer); + /* Check if we need to allocate a front color buffer. + * Front buffers are often allocated on demand (other color buffers are + * always allocated in advance). + */ + if ((fb->_ColorReadBufferIndex == BUFFER_FRONT_LEFT || + fb->_ColorReadBufferIndex == BUFFER_FRONT_RIGHT) && + fb->Attachment[fb->_ColorReadBufferIndex].Type == GL_NONE) { + assert(_mesa_is_winsys_fbo(fb)); + /* add the buffer */ + st_manager_add_color_renderbuffer(ctx, fb, fb->_ColorReadBufferIndex); + _mesa_update_state(ctx); + st_validate_state(st_context(ctx), ST_PIPELINE_UPDATE_FB_STATE_MASK); + } } } diff --git a/src/mesa/main/buffers.h b/src/mesa/main/buffers.h index 28e26b57558..004ba17689c 100644 --- a/src/mesa/main/buffers.h +++ b/src/mesa/main/buffers.h @@ -33,39 +33,13 @@ #define BUFFERS_H -#include "glheader.h" +#include "util/glheader.h" #include "menums.h" struct gl_context; struct gl_framebuffer; -void GLAPIENTRY -_mesa_DrawBuffer_no_error(GLenum mode); - -extern void GLAPIENTRY -_mesa_DrawBuffer( GLenum mode ); - -void GLAPIENTRY -_mesa_NamedFramebufferDrawBuffer_no_error(GLuint framebuffer, GLenum buf); - -extern void GLAPIENTRY -_mesa_NamedFramebufferDrawBuffer(GLuint framebuffer, GLenum buf); - -void GLAPIENTRY -_mesa_DrawBuffers_no_error(GLsizei n, const GLenum *buffers); - -extern void GLAPIENTRY -_mesa_DrawBuffers(GLsizei n, const GLenum *buffers); - -void GLAPIENTRY -_mesa_NamedFramebufferDrawBuffers_no_error(GLuint framebuffer, GLsizei n, - const GLenum *bufs); - -extern void GLAPIENTRY -_mesa_NamedFramebufferDrawBuffers(GLuint framebuffer, GLsizei n, - const GLenum *bufs); - extern void _mesa_drawbuffers(struct gl_context *ctx, struct gl_framebuffer *fb, GLuint n, const GLenum16 *buffers, @@ -82,25 +56,4 @@ extern GLenum _mesa_back_to_front_if_single_buffered(const struct gl_framebuffer *fb, GLenum buffer); -void GLAPIENTRY -_mesa_ReadBuffer_no_error(GLenum mode); - -extern void GLAPIENTRY -_mesa_ReadBuffer( GLenum mode ); - -void GLAPIENTRY -_mesa_NamedFramebufferReadBuffer_no_error(GLuint framebuffer, GLenum src); - -extern void GLAPIENTRY -_mesa_NamedFramebufferReadBuffer(GLuint framebuffer, GLenum src); - -extern void GLAPIENTRY -_mesa_FramebufferDrawBufferEXT(GLuint framebuffer, GLenum buf); - -extern void GLAPIENTRY -_mesa_FramebufferReadBufferEXT(GLuint framebuffer, GLenum buf); - -extern void GLAPIENTRY -_mesa_FramebufferDrawBuffersEXT(GLuint framebuffer, GLsizei n, - const GLenum *bufs); #endif diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c index 2e22c83e030..bb604224c9d 100644 --- a/src/mesa/main/clear.c +++ b/src/mesa/main/clear.c @@ -31,8 +31,7 @@ #include "glformats.h" -#include "glheader.h" -#include "clear.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" #include "fbobject.h" @@ -40,8 +39,9 @@ #include "macros.h" #include "mtypes.h" #include "state.h" +#include "api_exec_decl.h" - +#include "state_tracker/st_cb_clear.h" void GLAPIENTRY _mesa_ClearIndex( GLfloat c ) @@ -140,7 +140,7 @@ color_buffer_writes_enabled(const struct gl_context *ctx, unsigned idx) * \param mask bit-mask indicating the buffers to be cleared. * * Flushes the vertices and verifies the parameter. - * If __struct gl_contextRec::NewState is set then calls _mesa_update_state() + * If __struct gl_contextRec::NewState is set then calls _mesa_update_clear_state() * to update gl_frame_buffer::_Xmin, etc. If the rasterization mode is set to * GL_RENDER then requests the driver to clear the buffers, via the * dd_function_table::Clear callback. @@ -163,14 +163,14 @@ clear(struct gl_context *ctx, GLbitfield mask, bool no_error) * existed in OpenGL ES. */ if ((mask & GL_ACCUM_BUFFER_BIT) != 0 - && (ctx->API == API_OPENGL_CORE || _mesa_is_gles(ctx))) { + && (_mesa_is_desktop_gl_core(ctx) || _mesa_is_gles(ctx))) { _mesa_error( ctx, GL_INVALID_VALUE, "glClear(GL_ACCUM_BUFFER_BIT)"); return; } } if (ctx->NewState) { - _mesa_update_state( ctx ); /* update _Xmin, etc */ + _mesa_update_clear_state( ctx ); /* update _Xmin, etc */ } if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { @@ -221,8 +221,7 @@ clear(struct gl_context *ctx, GLbitfield mask, bool no_error) bufferMask |= BUFFER_BIT_ACCUM; } - assert(ctx->Driver.Clear); - ctx->Driver.Clear(ctx, bufferMask); + st_Clear(ctx, bufferMask); } } @@ -350,7 +349,7 @@ clear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, FLUSH_VERTICES(ctx, 0, 0); if (ctx->NewState) { - _mesa_update_state( ctx ); + _mesa_update_clear_state( ctx ); } if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { @@ -377,12 +376,12 @@ clear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, && !ctx->RasterDiscard) { /* Save current stencil clear value, set to 'value', do the * stencil clear and restore the clear value. - * XXX in the future we may have a new ctx->Driver.ClearBuffer() + * XXX in the future we may have a new st_ClearBuffer() * hook instead. */ const GLuint clearSave = ctx->Stencil.Clear; ctx->Stencil.Clear = *value; - ctx->Driver.Clear(ctx, BUFFER_BIT_STENCIL); + st_Clear(ctx, BUFFER_BIT_STENCIL); ctx->Stencil.Clear = clearSave; } break; @@ -402,7 +401,7 @@ clear_bufferiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, /* set color */ COPY_4V(ctx->Color.ClearColor.i, value); /* clear buffer(s) */ - ctx->Driver.Clear(ctx, mask); + st_Clear(ctx, mask); /* restore color */ ctx->Color.ClearColor = clearSave; } @@ -469,7 +468,7 @@ clear_bufferuiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, FLUSH_VERTICES(ctx, 0, 0); if (ctx->NewState) { - _mesa_update_state( ctx ); + _mesa_update_clear_state( ctx ); } if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) { @@ -495,7 +494,7 @@ clear_bufferuiv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, /* set color */ COPY_4V(ctx->Color.ClearColor.ui, value); /* clear buffer(s) */ - ctx->Driver.Clear(ctx, mask); + st_Clear(ctx, mask); /* restore color */ ctx->Color.ClearColor = clearSave; } @@ -563,7 +562,7 @@ clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, FLUSH_VERTICES(ctx, 0, 0); if (ctx->NewState) { - _mesa_update_state( ctx ); + _mesa_update_clear_state( ctx ); } if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE) { @@ -590,7 +589,7 @@ clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, && !ctx->RasterDiscard) { /* Save current depth clear value, set to 'value', do the * depth clear and restore the clear value. - * XXX in the future we may have a new ctx->Driver.ClearBuffer() + * XXX in the future we may have a new st_ClearBuffer() * hook instead. */ const GLclampd clearSave = ctx->Depth.Clear; @@ -608,7 +607,7 @@ clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, _mesa_has_depth_float_channel(rb->InternalFormat); ctx->Depth.Clear = is_float_depth ? *value : SATURATE(*value); - ctx->Driver.Clear(ctx, BUFFER_BIT_DEPTH); + st_Clear(ctx, BUFFER_BIT_DEPTH); ctx->Depth.Clear = clearSave; } /* clear depth buffer to value */ @@ -629,7 +628,7 @@ clear_bufferfv(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, /* set color */ COPY_4V(ctx->Color.ClearColor.f, value); /* clear buffer(s) */ - ctx->Driver.Clear(ctx, mask); + st_Clear(ctx, mask); /* restore color */ ctx->Color.ClearColor = clearSave; } @@ -723,7 +722,7 @@ clear_bufferfi(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, return; if (ctx->NewState) { - _mesa_update_state( ctx ); + _mesa_update_clear_state( ctx ); } if (!no_error && ctx->DrawBuffer->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { @@ -759,7 +758,7 @@ clear_bufferfi(struct gl_context *ctx, GLenum buffer, GLint drawbuffer, ctx->Stencil.Clear = stencil; /* clear buffers */ - ctx->Driver.Clear(ctx, mask); + st_Clear(ctx, mask); /* restore */ ctx->Depth.Clear = clearDepthSave; diff --git a/src/mesa/main/clear.h b/src/mesa/main/clear.h deleted file mode 100644 index 151905c0ef8..00000000000 --- a/src/mesa/main/clear.h +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef CLEAR_H -#define CLEAR_H - - -#include "glheader.h" - - -extern void GLAPIENTRY -_mesa_ClearIndex( GLfloat c ); - -extern void GLAPIENTRY -_mesa_ClearColor( GLclampf red, GLclampf green, - GLclampf blue, GLclampf alpha ); - -extern void GLAPIENTRY -_mesa_ClearColorIiEXT(GLint r, GLint g, GLint b, GLint a); - -extern void GLAPIENTRY -_mesa_ClearColorIuiEXT(GLuint r, GLuint g, GLuint b, GLuint a); - -void GLAPIENTRY -_mesa_Clear_no_error(GLbitfield mask); - -extern void GLAPIENTRY -_mesa_Clear( GLbitfield mask ); - -void GLAPIENTRY -_mesa_ClearBufferiv_no_error(GLenum buffer, GLint drawbuffer, - const GLint *value); - -extern void GLAPIENTRY -_mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value); - -extern void GLAPIENTRY -_mesa_ClearNamedFramebufferiv(GLuint framebuffer, GLenum buffer, - GLint drawbuffer, const GLint *value); - -void GLAPIENTRY -_mesa_ClearBufferuiv_no_error(GLenum buffer, GLint drawbuffer, - const GLuint *value); - -extern void GLAPIENTRY -_mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value); - -extern void GLAPIENTRY -_mesa_ClearNamedFramebufferuiv(GLuint framebuffer, GLenum buffer, - GLint drawbuffer, const GLuint *value); - -void GLAPIENTRY -_mesa_ClearBufferfv_no_error(GLenum buffer, GLint drawbuffer, - const GLfloat *value); - -extern void GLAPIENTRY -_mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value); - -extern void GLAPIENTRY -_mesa_ClearNamedFramebufferfv(GLuint framebuffer, GLenum buffer, - GLint drawbuffer, const GLfloat *value); - -void GLAPIENTRY -_mesa_ClearBufferfi_no_error(GLenum buffer, GLint drawbuffer, - GLfloat depth, GLint stencil); - -extern void GLAPIENTRY -_mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, - GLfloat depth, GLint stencil); - -extern void GLAPIENTRY -_mesa_ClearNamedFramebufferfi(GLuint framebuffer, GLenum buffer, - GLint drawbuffer, GLfloat depth, GLint stencil); - -#endif diff --git a/src/mesa/main/clip.c b/src/mesa/main/clip.c index 6a1e00fc4cb..b69ae5a956b 100644 --- a/src/mesa/main/clip.c +++ b/src/mesa/main/clip.c @@ -23,14 +23,16 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "clip.h" #include "context.h" #include "macros.h" #include "mtypes.h" #include "math/m_matrix.h" +#include "api_exec_decl.h" +#include "state_tracker/st_context.h" /** * Update derived clip plane state. @@ -86,15 +88,12 @@ _mesa_ClipPlane( GLenum plane, const GLdouble *eq ) /* EyeUserPlane is used by program state constants. */ FLUSH_VERTICES(ctx, _NEW_TRANSFORM, GL_TRANSFORM_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewClipPlane; + ctx->NewDriverState |= ST_NEW_CLIP_STATE; COPY_4FV(ctx->Transform.EyeUserPlane[p], equation); if (ctx->Transform.ClipPlanesEnabled & (1 << p)) { _mesa_update_clip_plane(ctx, p); } - - if (ctx->Driver.ClipPlane) - ctx->Driver.ClipPlane( ctx, plane, equation ); } diff --git a/src/mesa/main/clip.h b/src/mesa/main/clip.h index 7c46a6a0e06..dc0db979499 100644 --- a/src/mesa/main/clip.h +++ b/src/mesa/main/clip.h @@ -31,17 +31,11 @@ #ifndef CLIP_H #define CLIP_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; extern void _mesa_update_clip_plane(struct gl_context *ctx, GLuint plane); -extern void GLAPIENTRY -_mesa_ClipPlane( GLenum plane, const GLdouble *equation ); - -extern void GLAPIENTRY -_mesa_GetClipPlane( GLenum plane, GLdouble *equation ); - #endif diff --git a/src/mesa/main/colortab.c b/src/mesa/main/colortab.c deleted file mode 100644 index e8df73a0b83..00000000000 --- a/src/mesa/main/colortab.c +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#include "glheader.h" -#include "bufferobj.h" -#include "colortab.h" -#include "context.h" -#include "image.h" -#include "macros.h" -#include "mtypes.h" -#include "pack.h" -#include "pbo.h" -#include "state.h" -#include "teximage.h" -#include "texstate.h" - - -void GLAPIENTRY -_mesa_ColorTable( GLenum target, GLenum internalFormat, - GLsizei width, GLenum format, GLenum type, - const GLvoid *data ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTable"); -} - - - -void GLAPIENTRY -_mesa_ColorSubTable( GLenum target, GLsizei start, - GLsizei count, GLenum format, GLenum type, - const GLvoid *data ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glColorSubTable"); -} - - - -void GLAPIENTRY -_mesa_CopyColorTable(GLenum target, GLenum internalformat, - GLint x, GLint y, GLsizei width) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyColorTable"); -} - - - -void GLAPIENTRY -_mesa_CopyColorSubTable(GLenum target, GLsizei start, - GLint x, GLint y, GLsizei width) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyColorSubTable"); -} - - - -void GLAPIENTRY -_mesa_GetnColorTableARB( GLenum target, GLenum format, GLenum type, - GLsizei bufSize, GLvoid *data ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetnColorTableARB"); -} - - -void GLAPIENTRY -_mesa_GetColorTable( GLenum target, GLenum format, - GLenum type, GLvoid *data ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTable"); -} - - -void GLAPIENTRY -_mesa_ColorTableParameterfv(GLenum target, GLenum pname, const GLfloat *params) -{ - /* no extensions use this function */ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTableParameterfv"); -} - - - -void GLAPIENTRY -_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params) -{ - /* no extensions use this function */ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glColorTableParameteriv"); -} - - - -void GLAPIENTRY -_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTableParameterfv"); -} - - - -void GLAPIENTRY -_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ) -{ - GET_CURRENT_CONTEXT(ctx); - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetColorTableParameteriv"); -} diff --git a/src/mesa/main/colortab.h b/src/mesa/main/colortab.h deleted file mode 100644 index e1165d70214..00000000000 --- a/src/mesa/main/colortab.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef COLORTAB_H -#define COLORTAB_H - -#include "glheader.h" - -struct _glapi_table; - -void GLAPIENTRY -_mesa_ColorTable( GLenum target, GLenum internalformat, - GLsizei width, GLenum format, GLenum type, - const GLvoid *table ); -void GLAPIENTRY -_mesa_ColorSubTable( GLenum target, GLsizei start, - GLsizei count, GLenum format, GLenum type, - const GLvoid *table ); -void GLAPIENTRY -_mesa_CopyColorTable(GLenum target, GLenum internalformat, - GLint x, GLint y, GLsizei width); -void GLAPIENTRY -_mesa_CopyColorSubTable(GLenum target, GLsizei start, - GLint x, GLint y, GLsizei width); -void GLAPIENTRY -_mesa_GetnColorTableARB( GLenum target, GLenum format, GLenum type, - GLsizei bufSize, GLvoid *data ); -void GLAPIENTRY -_mesa_GetColorTable( GLenum target, GLenum format, - GLenum type, GLvoid *data ); -void GLAPIENTRY -_mesa_ColorTableParameterfv(GLenum target, GLenum pname, - const GLfloat *params); -void GLAPIENTRY -_mesa_ColorTableParameteriv(GLenum target, GLenum pname, const GLint *params); -void GLAPIENTRY -_mesa_GetColorTableParameterfv( GLenum target, GLenum pname, GLfloat *params ); -void GLAPIENTRY -_mesa_GetColorTableParameteriv( GLenum target, GLenum pname, GLint *params ); - - -#endif /* COLORTAB_H */ diff --git a/src/mesa/main/compute.c b/src/mesa/main/compute.c index dc05cb37002..e601f19d533 100644 --- a/src/mesa/main/compute.c +++ b/src/mesa/main/compute.c @@ -21,10 +21,17 @@ * DEALINGS IN THE SOFTWARE. */ -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" -#include "compute.h" #include "context.h" +#include "state.h" +#include "api_exec_decl.h" + +#include "pipe/p_state.h" + +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_util.h" static bool check_valid_to_compute(struct gl_context *ctx, const char *function) @@ -52,7 +59,7 @@ check_valid_to_compute(struct gl_context *ctx, const char *function) } static bool -validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups) +validate_DispatchCompute(struct gl_context *ctx, struct pipe_grid_info *info) { if (!check_valid_to_compute(ctx, "glDispatchCompute")) return GL_FALSE; @@ -76,7 +83,7 @@ validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups) * Additionally, the OpenGLES 3.1 specification does not contain "or * equal to" as an error condition. */ - if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) { + if (info->grid[i] > ctx->Const.MaxComputeWorkGroupCount[i]) { _mesa_error(ctx, GL_INVALID_VALUE, "glDispatchCompute(num_groups_%c)", 'x' + i); return GL_FALSE; @@ -100,8 +107,7 @@ validate_DispatchCompute(struct gl_context *ctx, const GLuint *num_groups) static bool validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, - const GLuint *num_groups, - const GLuint *group_size) + struct pipe_grid_info *info) { if (!check_valid_to_compute(ctx, "glDispatchComputeGroupSizeARB")) return GL_FALSE; @@ -127,7 +133,7 @@ validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, * num_groups_y and num_groups_z are greater than or equal to the * maximum work group count for the corresponding dimension." */ - if (num_groups[i] > ctx->Const.MaxComputeWorkGroupCount[i]) { + if (info->grid[i] > ctx->Const.MaxComputeWorkGroupCount[i]) { _mesa_error(ctx, GL_INVALID_VALUE, "glDispatchComputeGroupSizeARB(num_groups_%c)", 'x' + i); return GL_FALSE; @@ -145,8 +151,8 @@ validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, * However, the "less than" is a spec bug because they are declared as * unsigned integers. */ - if (group_size[i] == 0 || - group_size[i] > ctx->Const.MaxComputeVariableGroupSize[i]) { + if (info->block[i] == 0 || + info->block[i] > ctx->Const.MaxComputeVariableGroupSize[i]) { _mesa_error(ctx, GL_INVALID_VALUE, "glDispatchComputeGroupSizeARB(group_size_%c)", 'x' + i); return GL_FALSE; @@ -161,19 +167,19 @@ validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, * for compute shaders with variable group size * (MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB)." */ - uint64_t total_invocations = group_size[0] * group_size[1]; + uint64_t total_invocations = info->block[0] * info->block[1]; if (total_invocations <= UINT32_MAX) { /* Only bother multiplying the third value if total still fits in * 32-bit, since MaxComputeVariableGroupInvocations is also 32-bit. */ - total_invocations *= group_size[2]; + total_invocations *= info->block[2]; } if (total_invocations > ctx->Const.MaxComputeVariableGroupInvocations) { _mesa_error(ctx, GL_INVALID_VALUE, "glDispatchComputeGroupSizeARB(product of local_sizes " "exceeds MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB " "(%u * %u * %u > %u))", - group_size[0], group_size[1], group_size[2], + info->block[0], info->block[1], info->block[2], ctx->Const.MaxComputeVariableGroupInvocations); return GL_FALSE; } @@ -192,11 +198,11 @@ validate_DispatchComputeGroupSizeARB(struct gl_context *ctx, * of four." */ if (prog->info.cs.derivative_group == DERIVATIVE_GROUP_QUADS && - ((group_size[0] & 1) || (group_size[1] & 1))) { + ((info->block[0] & 1) || (info->block[1] & 1))) { _mesa_error(ctx, GL_INVALID_VALUE, "glDispatchComputeGroupSizeARB(derivative_group_quadsNV " "requires group_size_x (%d) and group_size_y (%d) to be " - "divisble by 2)", group_size[0], group_size[1]); + "divisble by 2)", info->block[0], info->block[1]); return GL_FALSE; } @@ -278,12 +284,26 @@ valid_dispatch_indirect(struct gl_context *ctx, GLintptr indirect) return GL_TRUE; } +static void +prepare_compute(struct gl_context *ctx) +{ + struct st_context *st = st_context(ctx); + + st_flush_bitmap_cache(st); + st_invalidate_readpix_cache(st); + + if (ctx->NewState) + _mesa_update_state(ctx); + + st_validate_state(st, ST_PIPELINE_COMPUTE_STATE_MASK); +} + static ALWAYS_INLINE void dispatch_compute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z, bool no_error) { GET_CURRENT_CONTEXT(ctx); - const GLuint num_groups[3] = { num_groups_x, num_groups_y, num_groups_z }; + struct pipe_grid_info info = { 0 }; FLUSH_VERTICES(ctx, 0, 0); @@ -291,13 +311,24 @@ dispatch_compute(GLuint num_groups_x, GLuint num_groups_y, _mesa_debug(ctx, "glDispatchCompute(%d, %d, %d)\n", num_groups_x, num_groups_y, num_groups_z); - if (!no_error && !validate_DispatchCompute(ctx, num_groups)) + info.grid[0] = num_groups_x; + info.grid[1] = num_groups_y; + info.grid[2] = num_groups_z; + + if (!no_error && !validate_DispatchCompute(ctx, &info)) return; if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u) return; - ctx->Driver.DispatchCompute(ctx, num_groups); + struct gl_program *prog = + ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + info.block[0] = prog->info.workgroup_size[0]; + info.block[1] = prog->info.workgroup_size[1]; + info.block[2] = prog->info.workgroup_size[2]; + + prepare_compute(ctx); + ctx->pipe->launch_grid(ctx->pipe, &info); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); @@ -331,7 +362,18 @@ dispatch_compute_indirect(GLintptr indirect, bool no_error) if (!no_error && !valid_dispatch_indirect(ctx, indirect)) return; - ctx->Driver.DispatchComputeIndirect(ctx, indirect); + struct pipe_grid_info info = { 0 }; + info.indirect_offset = indirect; + info.indirect = ctx->DispatchIndirectBuffer->buffer; + + struct gl_program *prog = + ctx->_Shader->CurrentProgram[MESA_SHADER_COMPUTE]; + info.block[0] = prog->info.workgroup_size[0]; + info.block[1] = prog->info.workgroup_size[1]; + info.block[2] = prog->info.workgroup_size[2]; + + prepare_compute(ctx); + ctx->pipe->launch_grid(ctx->pipe, &info); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); @@ -356,9 +398,6 @@ dispatch_compute_group_size(GLuint num_groups_x, GLuint num_groups_y, bool no_error) { GET_CURRENT_CONTEXT(ctx); - const GLuint num_groups[3] = { num_groups_x, num_groups_y, num_groups_z }; - const GLuint group_size[3] = { group_size_x, group_size_y, group_size_z }; - FLUSH_VERTICES(ctx, 0, 0); if (MESA_VERBOSE & VERBOSE_API) @@ -367,14 +406,24 @@ dispatch_compute_group_size(GLuint num_groups_x, GLuint num_groups_y, num_groups_x, num_groups_y, num_groups_z, group_size_x, group_size_y, group_size_z); + struct pipe_grid_info info = { 0 }; + info.grid[0] = num_groups_x; + info.grid[1] = num_groups_y; + info.grid[2] = num_groups_z; + + info.block[0] = group_size_x; + info.block[1] = group_size_y; + info.block[2] = group_size_z; + if (!no_error && - !validate_DispatchComputeGroupSizeARB(ctx, num_groups, group_size)) + !validate_DispatchComputeGroupSizeARB(ctx, &info)) return; if (num_groups_x == 0u || num_groups_y == 0u || num_groups_z == 0u) return; - ctx->Driver.DispatchComputeGroupSize(ctx, num_groups, group_size); + prepare_compute(ctx); + ctx->pipe->launch_grid(ctx->pipe, &info); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); diff --git a/src/mesa/main/compute.h b/src/mesa/main/compute.h deleted file mode 100644 index bfb3223d077..00000000000 --- a/src/mesa/main/compute.h +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright © 2014 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef COMPUTE_H -#define COMPUTE_H - - -#include "glheader.h" - -extern void GLAPIENTRY -_mesa_DispatchCompute_no_error(GLuint num_groups_x, GLuint num_groups_y, - GLuint num_groups_z); -extern void GLAPIENTRY -_mesa_DispatchCompute(GLuint num_groups_x, - GLuint num_groups_y, - GLuint num_groups_z); - -extern void GLAPIENTRY -_mesa_DispatchComputeIndirect_no_error(GLintptr indirect); -extern void GLAPIENTRY -_mesa_DispatchComputeIndirect(GLintptr indirect); - -extern void GLAPIENTRY -_mesa_DispatchComputeGroupSizeARB_no_error(GLuint num_groups_x, - GLuint num_groups_y, - GLuint num_groups_z, - GLuint group_size_x, - GLuint group_size_y, - GLuint group_size_z); -extern void GLAPIENTRY -_mesa_DispatchComputeGroupSizeARB(GLuint num_groups_x, GLuint num_groups_y, - GLuint num_groups_z, GLuint group_size_x, - GLuint group_size_y, GLuint group_size_z); - -#endif diff --git a/src/mesa/main/condrender.c b/src/mesa/main/condrender.c index 1ceb1f60569..17ebc0b8e9b 100644 --- a/src/mesa/main/condrender.c +++ b/src/mesa/main/condrender.c @@ -30,12 +30,74 @@ * \author Brian Paul */ -#include "glheader.h" +#include "util/glheader.h" #include "condrender.h" #include "enums.h" #include "mtypes.h" #include "queryobj.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_context.h" + +static void +BeginConditionalRender(struct gl_context *ctx, struct gl_query_object *q, + GLenum mode) +{ + struct st_context *st = st_context(ctx); + uint m; + /* Don't invert the condition for rendering by default */ + bool inverted = false; + + st_flush_bitmap_cache(st); + + switch (mode) { + case GL_QUERY_WAIT: + m = PIPE_RENDER_COND_WAIT; + break; + case GL_QUERY_NO_WAIT: + m = PIPE_RENDER_COND_NO_WAIT; + break; + case GL_QUERY_BY_REGION_WAIT: + m = PIPE_RENDER_COND_BY_REGION_WAIT; + break; + case GL_QUERY_BY_REGION_NO_WAIT: + m = PIPE_RENDER_COND_BY_REGION_NO_WAIT; + break; + case GL_QUERY_WAIT_INVERTED: + m = PIPE_RENDER_COND_WAIT; + inverted = true; + break; + case GL_QUERY_NO_WAIT_INVERTED: + m = PIPE_RENDER_COND_NO_WAIT; + inverted = true; + break; + case GL_QUERY_BY_REGION_WAIT_INVERTED: + m = PIPE_RENDER_COND_BY_REGION_WAIT; + inverted = true; + break; + case GL_QUERY_BY_REGION_NO_WAIT_INVERTED: + m = PIPE_RENDER_COND_BY_REGION_NO_WAIT; + inverted = true; + break; + default: + assert(0 && "bad mode in st_BeginConditionalRender"); + m = PIPE_RENDER_COND_WAIT; + } + + cso_set_render_condition(st->cso_context, q->pq, inverted, m); +} + +static void +EndConditionalRender(struct gl_context *ctx, struct gl_query_object *q) +{ + struct st_context *st = st_context(ctx); + (void) q; + + st_flush_bitmap_cache(st); + + cso_set_render_condition(st->cso_context, NULL, false, 0); +} static ALWAYS_INLINE void begin_conditional_render(struct gl_context *ctx, GLuint queryId, GLenum mode, @@ -99,8 +161,7 @@ begin_conditional_render(struct gl_context *ctx, GLuint queryId, GLenum mode, ctx->Query.CondRenderQuery = q; ctx->Query.CondRenderMode = mode; - if (ctx->Driver.BeginConditionalRender) - ctx->Driver.BeginConditionalRender(ctx, q, mode); + BeginConditionalRender(ctx, q, mode); } @@ -138,15 +199,14 @@ end_conditional_render(struct gl_context *ctx) { FLUSH_VERTICES(ctx, 0, 0); - if (ctx->Driver.EndConditionalRender) - ctx->Driver.EndConditionalRender(ctx, ctx->Query.CondRenderQuery); + EndConditionalRender(ctx, ctx->Query.CondRenderQuery); ctx->Query.CondRenderQuery = NULL; ctx->Query.CondRenderMode = GL_NONE; } -void APIENTRY +void GLAPIENTRY _mesa_EndConditionalRender_no_error(void) { GET_CURRENT_CONTEXT(ctx); @@ -154,7 +214,7 @@ _mesa_EndConditionalRender_no_error(void) } -void APIENTRY +void GLAPIENTRY _mesa_EndConditionalRender(void) { GET_CURRENT_CONTEXT(ctx); @@ -195,27 +255,27 @@ _mesa_check_conditional_render(struct gl_context *ctx) FALLTHROUGH; case GL_QUERY_WAIT: if (!q->Ready) { - ctx->Driver.WaitQuery(ctx, q); + _mesa_wait_query(ctx, q); } return q->Result > 0; case GL_QUERY_BY_REGION_WAIT_INVERTED: FALLTHROUGH; case GL_QUERY_WAIT_INVERTED: if (!q->Ready) { - ctx->Driver.WaitQuery(ctx, q); + _mesa_wait_query(ctx, q); } return q->Result == 0; case GL_QUERY_BY_REGION_NO_WAIT: FALLTHROUGH; case GL_QUERY_NO_WAIT: if (!q->Ready) - ctx->Driver.CheckQuery(ctx, q); + _mesa_check_query(ctx, q); return q->Ready ? (q->Result > 0) : GL_TRUE; case GL_QUERY_BY_REGION_NO_WAIT_INVERTED: FALLTHROUGH; case GL_QUERY_NO_WAIT_INVERTED: if (!q->Ready) - ctx->Driver.CheckQuery(ctx, q); + _mesa_check_query(ctx, q); return q->Ready ? (q->Result == 0) : GL_TRUE; default: _mesa_problem(ctx, "Bad cond render mode %s in " diff --git a/src/mesa/main/condrender.h b/src/mesa/main/condrender.h index e7672512f7e..03984b6b59d 100644 --- a/src/mesa/main/condrender.h +++ b/src/mesa/main/condrender.h @@ -27,24 +27,10 @@ #define CONDRENDER_H -#include "glheader.h" +#include "util/glheader.h" #include "context.h" - -void GLAPIENTRY -_mesa_BeginConditionalRender_no_error(GLuint queryId, GLenum mode); - -extern void GLAPIENTRY -_mesa_BeginConditionalRender(GLuint queryId, GLenum mode); - -void APIENTRY -_mesa_EndConditionalRender_no_error(void); - -extern void APIENTRY -_mesa_EndConditionalRender(void); - extern GLboolean _mesa_check_conditional_render(struct gl_context *ctx); - #endif /* CONDRENDER_H */ diff --git a/src/mesa/main/config.h b/src/mesa/main/config.h index 3571a338d58..753d847efb1 100644 --- a/src/mesa/main/config.h +++ b/src/mesa/main/config.h @@ -76,6 +76,10 @@ /** Maximum Name stack depth */ #define MAX_NAME_STACK_DEPTH 64 +/** Name stack buffer size */ +#define NAME_STACK_BUFFER_SIZE 2048 +/** Maximum name stack result number */ +#define MAX_NAME_STACK_RESULT_NUM 256 /** Minimum point size */ #define MIN_POINT_SIZE 1.0 diff --git a/src/mesa/main/conservativeraster.c b/src/mesa/main/conservativeraster.c index b912b5517fd..793a6c9e2bd 100644 --- a/src/mesa/main/conservativeraster.c +++ b/src/mesa/main/conservativeraster.c @@ -31,6 +31,9 @@ #include "conservativeraster.h" #include "context.h" #include "enums.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_context.h" static ALWAYS_INLINE void conservative_raster_parameter(GLenum pname, GLfloat param, @@ -61,8 +64,7 @@ conservative_raster_parameter(GLenum pname, GLfloat param, } FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= - ctx->DriverFlags.NewNvConservativeRasterizationParams; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->ConservativeRasterDilate = CLAMP(param, @@ -81,9 +83,7 @@ conservative_raster_parameter(GLenum pname, GLfloat param, } FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= - ctx->DriverFlags.NewNvConservativeRasterizationParams; - + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->ConservativeRasterMode = param; break; default: diff --git a/src/mesa/main/conservativeraster.h b/src/mesa/main/conservativeraster.h index 1865cfc2a4d..c8899d564c4 100644 --- a/src/mesa/main/conservativeraster.h +++ b/src/mesa/main/conservativeraster.h @@ -26,22 +26,10 @@ #ifndef CONSERVATIVERASTER_H #define CONSERVATIVERASTER_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -extern void GLAPIENTRY -_mesa_ConservativeRasterParameteriNV_no_error(GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_ConservativeRasterParameteriNV(GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_ConservativeRasterParameterfNV_no_error(GLenum pname, GLfloat param); - -extern void GLAPIENTRY -_mesa_ConservativeRasterParameterfNV(GLenum pname, GLfloat param); - extern void _mesa_init_conservative_raster(struct gl_context *ctx); diff --git a/src/mesa/main/consts_exts.h b/src/mesa/main/consts_exts.h new file mode 100644 index 00000000000..e9f8ea82a0d --- /dev/null +++ b/src/mesa/main/consts_exts.h @@ -0,0 +1,1026 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file consts_exts.h + * Mesa Constants and GL Extensions data structures. + */ + +#ifndef __CONSTS_EXTS_H__ +#define __CONSTS_EXTS_H__ + +#include "util/glheader.h" +#include "compiler/shader_enums.h" +#include "compiler/shader_info.h" + +struct nir_shader_compiler_options; + +/** + * Enable flag for each OpenGL extension. Different device drivers will + * enable different extensions at runtime. + */ +struct gl_extensions +{ + GLboolean dummy; /* don't remove this! */ + GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */ + GLboolean ANGLE_texture_compression_dxt; + GLboolean ARB_ES2_compatibility; + GLboolean ARB_ES3_compatibility; + GLboolean ARB_ES3_1_compatibility; + GLboolean ARB_ES3_2_compatibility; + GLboolean ARB_arrays_of_arrays; + GLboolean ARB_base_instance; + GLboolean ARB_bindless_texture; + GLboolean ARB_blend_func_extended; + GLboolean ARB_buffer_storage; + GLboolean ARB_clip_control; + GLboolean ARB_color_buffer_float; + GLboolean ARB_compatibility; + GLboolean ARB_compute_shader; + GLboolean ARB_compute_variable_group_size; + GLboolean ARB_conditional_render_inverted; + GLboolean ARB_conservative_depth; + GLboolean ARB_copy_image; + GLboolean ARB_cull_distance; + GLboolean ARB_depth_buffer_float; + GLboolean ARB_depth_clamp; + GLboolean ARB_derivative_control; + GLboolean ARB_draw_buffers_blend; + GLboolean ARB_draw_elements_base_vertex; + GLboolean ARB_draw_indirect; + GLboolean ARB_draw_instanced; + GLboolean ARB_fragment_coord_conventions; + GLboolean ARB_fragment_layer_viewport; + GLboolean ARB_fragment_program; + GLboolean ARB_fragment_program_shadow; + GLboolean ARB_fragment_shader; + GLboolean ARB_framebuffer_no_attachments; + GLboolean ARB_framebuffer_object; + GLboolean ARB_fragment_shader_interlock; + GLboolean ARB_enhanced_layouts; + GLboolean ARB_explicit_attrib_location; + GLboolean ARB_explicit_uniform_location; + GLboolean ARB_gl_spirv; + GLboolean ARB_gpu_shader5; + GLboolean ARB_gpu_shader_fp64; + GLboolean ARB_gpu_shader_int64; + GLboolean ARB_half_float_vertex; + GLboolean ARB_indirect_parameters; + GLboolean ARB_instanced_arrays; + GLboolean ARB_internalformat_query; + GLboolean ARB_internalformat_query2; + GLboolean ARB_map_buffer_range; + GLboolean ARB_occlusion_query; + GLboolean ARB_occlusion_query2; + GLboolean ARB_pipeline_statistics_query; + GLboolean ARB_polygon_offset_clamp; + GLboolean ARB_post_depth_coverage; + GLboolean ARB_query_buffer_object; + GLboolean ARB_robust_buffer_access_behavior; + GLboolean ARB_sample_locations; + GLboolean ARB_sample_shading; + GLboolean ARB_seamless_cube_map; + GLboolean ARB_shader_atomic_counter_ops; + GLboolean ARB_shader_atomic_counters; + GLboolean ARB_shader_ballot; + GLboolean ARB_shader_bit_encoding; + GLboolean ARB_shader_clock; + GLboolean ARB_shader_draw_parameters; + GLboolean ARB_shader_group_vote; + GLboolean ARB_shader_image_load_store; + GLboolean ARB_shader_image_size; + GLboolean ARB_shader_precision; + GLboolean ARB_shader_stencil_export; + GLboolean ARB_shader_storage_buffer_object; + GLboolean ARB_shader_texture_image_samples; + GLboolean ARB_shader_texture_lod; + GLboolean ARB_shader_viewport_layer_array; + GLboolean ARB_shading_language_packing; + GLboolean ARB_shading_language_420pack; + GLboolean ARB_shadow; + GLboolean ARB_sparse_buffer; + GLboolean ARB_sparse_texture; + GLboolean ARB_sparse_texture2; + GLboolean ARB_sparse_texture_clamp; + GLboolean ARB_stencil_texturing; + GLboolean ARB_spirv_extensions; + GLboolean ARB_sync; + GLboolean ARB_tessellation_shader; + GLboolean ARB_texture_buffer_object; + GLboolean ARB_texture_buffer_object_rgb32; + GLboolean ARB_texture_buffer_range; + GLboolean ARB_texture_compression_bptc; + GLboolean ARB_texture_compression_rgtc; + GLboolean ARB_texture_cube_map_array; + GLboolean ARB_texture_filter_anisotropic; + GLboolean ARB_texture_filter_minmax; + GLboolean ARB_texture_float; + GLboolean ARB_texture_gather; + GLboolean ARB_texture_mirror_clamp_to_edge; + GLboolean ARB_texture_multisample; + GLboolean ARB_texture_non_power_of_two; + GLboolean ARB_texture_stencil8; + GLboolean ARB_texture_query_levels; + GLboolean ARB_texture_query_lod; + GLboolean ARB_texture_rg; + GLboolean ARB_texture_rgb10_a2ui; + GLboolean ARB_texture_view; + GLboolean ARB_timer_query; + GLboolean ARB_transform_feedback2; + GLboolean ARB_transform_feedback3; + GLboolean ARB_transform_feedback_instanced; + GLboolean ARB_transform_feedback_overflow_query; + GLboolean ARB_uniform_buffer_object; + GLboolean ARB_vertex_attrib_64bit; + GLboolean ARB_vertex_program; + GLboolean ARB_vertex_shader; + GLboolean ARB_vertex_type_10f_11f_11f_rev; + GLboolean ARB_vertex_type_2_10_10_10_rev; + GLboolean ARB_viewport_array; + GLboolean EXT_blend_equation_separate; + GLboolean EXT_color_buffer_float; + GLboolean EXT_color_buffer_half_float; + GLboolean EXT_demote_to_helper_invocation; + GLboolean EXT_depth_bounds_test; + GLboolean EXT_disjoint_timer_query; + GLboolean EXT_draw_buffers2; + GLboolean EXT_EGL_image_storage; + GLboolean EXT_float_blend; + GLboolean EXT_framebuffer_multisample; + GLboolean EXT_framebuffer_multisample_blit_scaled; + GLboolean EXT_framebuffer_sRGB; + GLboolean EXT_gpu_program_parameters; + GLboolean EXT_gpu_shader4; + GLboolean EXT_memory_object; + GLboolean EXT_memory_object_fd; + GLboolean EXT_memory_object_win32; + GLboolean EXT_multisampled_render_to_texture; + GLboolean EXT_packed_float; + GLboolean EXT_provoking_vertex; + GLboolean EXT_render_snorm; + GLboolean EXT_semaphore; + GLboolean EXT_semaphore_fd; + GLboolean EXT_semaphore_win32; + GLboolean EXT_shader_image_load_formatted; + GLboolean EXT_shader_image_load_store; + GLboolean EXT_shader_integer_mix; + GLboolean EXT_shader_samples_identical; + GLboolean EXT_sRGB; + GLboolean EXT_stencil_two_side; + GLboolean EXT_texture_array; + GLboolean EXT_texture_buffer_object; + GLboolean EXT_texture_compression_latc; + GLboolean EXT_texture_compression_s3tc; + GLboolean EXT_texture_compression_s3tc_srgb; + GLboolean EXT_texture_env_dot3; + GLboolean EXT_texture_filter_anisotropic; + GLboolean EXT_texture_filter_minmax; + GLboolean EXT_texture_integer; + GLboolean EXT_texture_mirror_clamp; + GLboolean EXT_texture_norm16; + GLboolean EXT_texture_shadow_lod; + GLboolean EXT_texture_shared_exponent; + GLboolean EXT_texture_snorm; + GLboolean EXT_texture_sRGB; + GLboolean EXT_texture_sRGB_R8; + GLboolean EXT_texture_sRGB_RG8; + GLboolean EXT_texture_sRGB_decode; + GLboolean EXT_texture_swizzle; + GLboolean EXT_texture_type_2_10_10_10_REV; + GLboolean EXT_transform_feedback; + GLboolean EXT_timer_query; + GLboolean EXT_vertex_array_bgra; + GLboolean EXT_window_rectangles; + GLboolean OES_copy_image; + GLboolean OES_primitive_bounding_box; + GLboolean OES_sample_variables; + GLboolean OES_standard_derivatives; + GLboolean OES_texture_buffer; + GLboolean OES_texture_cube_map_array; + GLboolean OES_texture_view; + GLboolean OES_viewport_array; + /* vendor extensions */ + GLboolean AMD_compressed_ATC_texture; + GLboolean AMD_framebuffer_multisample_advanced; + GLboolean AMD_depth_clamp_separate; + GLboolean AMD_gpu_shader_half_float; + GLboolean AMD_performance_monitor; + GLboolean AMD_pinned_memory; + GLboolean AMD_seamless_cubemap_per_texture; + GLboolean AMD_vertex_shader_layer; + GLboolean AMD_vertex_shader_viewport_index; + GLboolean ANDROID_extension_pack_es31a; + GLboolean ARM_shader_framebuffer_fetch_depth_stencil; + GLboolean ATI_meminfo; + GLboolean ATI_texture_compression_3dc; + GLboolean ATI_texture_mirror_once; + GLboolean ATI_texture_env_combine3; + GLboolean ATI_fragment_shader; + GLboolean GREMEDY_string_marker; + GLboolean INTEL_blackhole_render; + GLboolean INTEL_conservative_rasterization; + GLboolean INTEL_performance_query; + GLboolean INTEL_shader_atomic_float_minmax; + GLboolean INTEL_shader_integer_functions2; + GLboolean KHR_blend_equation_advanced; + GLboolean KHR_blend_equation_advanced_coherent; + GLboolean KHR_robustness; + GLboolean KHR_texture_compression_astc_hdr; + GLboolean KHR_texture_compression_astc_ldr; + GLboolean KHR_texture_compression_astc_sliced_3d; + GLboolean MESA_framebuffer_flip_y; + GLboolean MESA_texture_const_bandwidth; + GLboolean MESA_pack_invert; + GLboolean MESA_tile_raster_order; + GLboolean EXT_shader_framebuffer_fetch; + GLboolean EXT_shader_framebuffer_fetch_non_coherent; + GLboolean MESA_shader_integer_functions; + GLboolean MESA_window_pos; + GLboolean MESA_ycbcr_texture; + GLboolean NV_alpha_to_coverage_dither_control; + GLboolean NV_compute_shader_derivatives; + GLboolean NV_conditional_render; + GLboolean NV_copy_depth_to_color; + GLboolean NV_copy_image; + GLboolean NV_fill_rectangle; + GLboolean NV_fog_distance; + GLboolean NV_primitive_restart; + GLboolean NV_shader_atomic_float; + GLboolean NV_shader_atomic_int64; + GLboolean NV_texture_barrier; + GLboolean NV_texture_env_combine4; + GLboolean NV_texture_rectangle; + GLboolean NV_vdpau_interop; + GLboolean NV_conservative_raster; + GLboolean NV_conservative_raster_dilate; + GLboolean NV_conservative_raster_pre_snap_triangles; + GLboolean NV_conservative_raster_pre_snap; + GLboolean NV_viewport_array2; + GLboolean NV_viewport_swizzle; + GLboolean NVX_gpu_memory_info; + GLboolean TDFX_texture_compression_FXT1; + GLboolean OES_EGL_image; + GLboolean OES_draw_texture; + GLboolean OES_depth_texture_cube_map; + GLboolean OES_EGL_image_external; + GLboolean OES_texture_3D; + GLboolean OES_texture_float; + GLboolean OES_texture_float_linear; + GLboolean OES_texture_half_float; + GLboolean OES_texture_half_float_linear; + GLboolean OES_compressed_ETC1_RGB8_texture; + GLboolean OES_geometry_shader; + GLboolean OES_texture_compression_astc; + GLboolean extension_sentinel; + /** The extension string */ + const GLubyte *String; + /** Number of supported extensions */ + GLuint Count; + /** + * The context version which extension helper functions compare against. + * By default, the value is equal to ctx->Version. This changes to ~0 + * while meta is in progress. + */ + GLubyte Version; +}; + +/** + * Compiler options for a single GLSL shaders type + */ +struct gl_shader_compiler_options +{ + /** Driver-selectable options: */ + GLboolean EmitNoCont; /**< Emit CONT opcode? */ + GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ + GLbitfield LowerBuiltinVariablesXfb; /**< Which builtin variables should + * be lowered for transform feedback + **/ + + /** + * If we can lower the precision of variables based on precision + * qualifiers + */ + GLboolean LowerPrecisionFloat16; + GLboolean LowerPrecisionInt16; + GLboolean LowerPrecisionDerivatives; + GLboolean LowerPrecisionFloat16Uniforms; + + /** + * This enables lowering of 16b constants. Some drivers may not + * to lower constants to 16b (ie. if the hw can do automatic + * narrowing on constant load) + */ + GLboolean LowerPrecisionConstants; + + /** + * \name Forms of indirect addressing the driver cannot do. + */ + /*@{*/ + GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */ + GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */ + GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */ + GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */ + /*@}*/ + + GLuint MaxIfDepth; /**< Maximum nested IF blocks */ + + /** + * Optimize code for array of structures backends. + * + * This is a proxy for: + * - preferring DP4 instructions (rather than MUL/MAD) for + * matrix * vector operations, such as position transformation. + */ + GLboolean OptimizeForAOS; + + /** Clamp UBO and SSBO block indices so they don't go out-of-bounds. */ + GLboolean ClampBlockIndicesToArrayBounds; + + /** (driconf) Force gl_Position to be considered invariant */ + GLboolean PositionAlwaysInvariant; + + /** (driconf) Force gl_Position to be considered precise */ + GLboolean PositionAlwaysPrecise; + + const struct nir_shader_compiler_options *NirOptions; +}; + +/** + * Precision info for shader datatypes. See glGetShaderPrecisionFormat(). + */ +struct gl_precision +{ + GLushort RangeMin; /**< min value exponent */ + GLushort RangeMax; /**< max value exponent */ + GLushort Precision; /**< number of mantissa bits */ +}; + +/** + * Limits for vertex, geometry and fragment programs/shaders. + */ +struct gl_program_constants +{ + /* logical limits */ + GLuint MaxInstructions; + GLuint MaxAluInstructions; + GLuint MaxTexInstructions; + GLuint MaxTexIndirections; + GLuint MaxAttribs; + GLuint MaxTemps; + GLuint MaxAddressRegs; + GLuint MaxAddressOffset; /**< [-MaxAddressOffset, MaxAddressOffset-1] */ + GLuint MaxParameters; + GLuint MaxLocalParams; + GLuint MaxEnvParams; + /* native/hardware limits */ + GLuint MaxNativeInstructions; + GLuint MaxNativeAluInstructions; + GLuint MaxNativeTexInstructions; + GLuint MaxNativeTexIndirections; + GLuint MaxNativeAttribs; + GLuint MaxNativeTemps; + GLuint MaxNativeAddressRegs; + GLuint MaxNativeParameters; + /* For shaders */ + GLuint MaxUniformComponents; /**< Usually == MaxParameters * 4 */ + + /** + * \name Per-stage input / output limits + * + * Previous to OpenGL 3.2, the intrastage data limits were advertised with + * a single value: GL_MAX_VARYING_COMPONENTS (GL_MAX_VARYING_VECTORS in + * ES). This is stored as \c gl_constants::MaxVarying. + * + * Starting with OpenGL 3.2, the limits are advertised with per-stage + * variables. Each stage as a certain number of outputs that it can feed + * to the next stage and a certain number inputs that it can consume from + * the previous stage. + * + * Vertex shader inputs do not participate this in this accounting. + * These are tracked exclusively by \c gl_program_constants::MaxAttribs. + * + * Fragment shader outputs do not participate this in this accounting. + * These are tracked exclusively by \c gl_constants::MaxDrawBuffers. + */ + /*@{*/ + GLuint MaxInputComponents; + GLuint MaxOutputComponents; + /*@}*/ + + /* ES 2.0 and GL_ARB_ES2_compatibility */ + struct gl_precision LowFloat, MediumFloat, HighFloat; + struct gl_precision LowInt, MediumInt, HighInt; + /* GL_ARB_uniform_buffer_object */ + GLuint MaxUniformBlocks; + uint64_t MaxCombinedUniformComponents; + GLuint MaxTextureImageUnits; + + /* GL_ARB_shader_atomic_counters */ + GLuint MaxAtomicBuffers; + GLuint MaxAtomicCounters; + + /* GL_ARB_shader_image_load_store */ + GLuint MaxImageUniforms; + + /* GL_ARB_shader_storage_buffer_object */ + GLuint MaxShaderStorageBlocks; +}; + +/** + * Constants which may be overridden by device driver during context creation + * but are never changed after that. + */ +struct gl_constants +{ + /** + * Bitmask of valid primitive types supported by the driver, + */ + GLbitfield DriverSupportedPrimMask; + + GLuint MaxTextureMbytes; /**< Max memory per image, in MB */ + GLuint MaxTextureSize; /**< Max 1D/2D texture size, in pixels*/ + GLuint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */ + GLuint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */ + GLuint MaxArrayTextureLayers; /**< Max layers in array textures */ + GLuint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */ + GLuint MaxTextureCoordUnits; + GLuint MaxCombinedTextureImageUnits; + GLuint MaxTextureUnits; /**< = MIN(CoordUnits, FragmentProgram.ImageUnits) */ + GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ + GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ + GLuint MaxTextureBufferSize; /**< GL_ARB_texture_buffer_object */ + + GLuint TextureBufferOffsetAlignment; /**< GL_ARB_texture_buffer_range */ + + GLuint MaxArrayLockSize; + + GLint SubPixelBits; + + GLfloat MinPointSize, MaxPointSize; /**< aliased */ + GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */ + GLfloat PointSizeGranularity; + GLfloat MinLineWidth, MaxLineWidth; /**< aliased */ + GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */ + GLfloat LineWidthGranularity; + + GLuint MaxClipPlanes; + GLuint MaxLights; + GLfloat MaxShininess; /**< GL_NV_light_max_exponent */ + GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */ + + GLuint MaxViewportWidth, MaxViewportHeight; + GLuint MaxViewports; /**< GL_ARB_viewport_array */ + GLuint ViewportSubpixelBits; /**< GL_ARB_viewport_array */ + struct { + GLfloat Min; + GLfloat Max; + } ViewportBounds; /**< GL_ARB_viewport_array */ + GLuint MaxWindowRectangles; /**< GL_EXT_window_rectangles */ + + struct gl_program_constants Program[MESA_SHADER_STAGES]; + GLuint MaxProgramMatrices; + GLuint MaxProgramMatrixStackDepth; + + struct { + GLuint SamplesPassed; + GLuint TimeElapsed; + GLuint Timestamp; + GLuint PrimitivesGenerated; + GLuint PrimitivesWritten; + GLuint VerticesSubmitted; + GLuint PrimitivesSubmitted; + GLuint VsInvocations; + GLuint TessPatches; + GLuint TessInvocations; + GLuint GsInvocations; + GLuint GsPrimitives; + GLuint FsInvocations; + GLuint ComputeInvocations; + GLuint ClInPrimitives; + GLuint ClOutPrimitives; + } QueryCounterBits; + + GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ + + GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */ + GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */ + GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ + + /** + * GL_ARB_framebuffer_no_attachments + */ + GLuint MaxFramebufferWidth; + GLuint MaxFramebufferHeight; + GLuint MaxFramebufferLayers; + GLuint MaxFramebufferSamples; + + /** Number of varying vectors between any two shader stages. */ + GLuint MaxVarying; + + /** @{ + * GL_ARB_uniform_buffer_object + */ + GLuint MaxCombinedUniformBlocks; + GLuint MaxUniformBufferBindings; + GLuint MaxUniformBlockSize; + GLuint UniformBufferOffsetAlignment; + /** @} */ + + /** @{ + * GL_ARB_shader_storage_buffer_object + */ + GLuint MaxCombinedShaderStorageBlocks; + GLuint MaxShaderStorageBufferBindings; + GLuint MaxShaderStorageBlockSize; + GLuint ShaderStorageBufferOffsetAlignment; + /** @} */ + + /** + * GL_ARB_explicit_uniform_location + */ + GLuint MaxUserAssignableUniformLocations; + + /** geometry shader */ + GLuint MaxGeometryOutputVertices; + GLuint MaxGeometryTotalOutputComponents; + GLuint MaxGeometryShaderInvocations; + + GLuint GLSLVersion; /**< Desktop GLSL version supported (ex: 120 = 1.20) */ + GLuint GLSLVersionCompat; /**< Desktop compat GLSL version supported */ + + /** + * Changes default GLSL extension behavior from "error" to "warn". It's out + * of spec, but it can make some apps work that otherwise wouldn't. + */ + GLboolean ForceGLSLExtensionsWarn; + + /** + * Force all shaders to behave as if they were declared with the + * compatibility token. + */ + GLboolean ForceCompatShaders; + + /** + * If non-zero, forces GLSL shaders to behave as if they began + * with "#version ForceGLSLVersion". + */ + GLuint ForceGLSLVersion; + + /** + * Allow GLSL #extension directives in the middle of shaders. + */ + GLboolean AllowGLSLExtensionDirectiveMidShader; + + /** + * Allow a subset of GLSL 1.20 in GLSL 1.10 as needed by SPECviewperf13. + */ + GLboolean AllowGLSL120SubsetIn110; + + /** + * Allow builtins as part of constant expressions. This was not allowed + * until GLSL 1.20 this allows it everywhere. + */ + GLboolean AllowGLSLBuiltinConstantExpression; + + /** + * Allow some relaxation of GLSL ES shader restrictions. This encompasses + * a number of relaxations to the ES shader rules. + */ + GLboolean AllowGLSLRelaxedES; + + /** + * Allow GLSL built-in variables to be redeclared verbatim + */ + GLboolean AllowGLSLBuiltinVariableRedeclaration; + + /** + * Allow GLSL interpolation qualifier mismatch across shader stages. + */ + GLboolean AllowGLSLCrossStageInterpolationMismatch; + + /** + * Allow creating a higher compat profile (version 3.1+) for apps that + * request it. Be careful when adding that driconf option because some + * features are unimplemented and might not work correctly. + */ + GLboolean AllowHigherCompatVersion; + + /** + * Allow GLSL shaders with the compatibility version directive + * in non-compatibility profiles. (for shader-db) + */ + GLboolean AllowGLSLCompatShaders; + + /** + * Allow extra tokens at end of preprocessor directives. The CTS now tests + * to make sure these are not allowed. However, previously drivers would + * allow them to exist and just issue a warning so some old applications + * depend on this. + */ + GLboolean AllowExtraPPTokens; + + /** + * The spec forbids a shader to "statically write both gl_ClipVertex + * and gl_ClipDistance". + * This option adds a tolerance for shader that statically writes to + * both but at least one of the write can be removed by a dead code + * elimination pass. + */ + GLboolean DoDCEBeforeClipCullAnalysis; + + /** + * Force computing the absolute value for sqrt() and inversesqrt() to follow + * D3D9 when apps rely on this behaviour. + */ + GLboolean ForceGLSLAbsSqrt; + + /** + * Forces the GLSL compiler to ignore writes to readonly vars rather than + * throwing an error. + */ + GLboolean GLSLIgnoreWriteToReadonlyVar; + + /** + * Types of variable to default initialized to zero. Supported values are: + * - 0: no zero initialization + * - 1: all shader variables and gl_FragColor are initialiazed to 0 + * - 2: same as 1, but shader out variables are *not* initialized, while + * function out variables are now initialized. + */ + GLchar GLSLZeroInit; + + /** + * Force GL names reuse. Needed by SPECviewperf13. + */ + GLboolean ForceGLNamesReuse; + + /** + * Treat integer textures using GL_LINEAR filters as GL_NEAREST. + */ + GLboolean ForceIntegerTexNearest; + + /** + * Treat 32-bit floating-point textures using GL_LINEAR filters as + * GL_NEAREST. + */ + GLboolean ForceFloat32TexNearest; + + /** + * Does the driver support real 32-bit integers? (Otherwise, integers are + * simulated via floats.) + */ + GLboolean NativeIntegers; + + /** + * If the driver supports real 32-bit integers, what integer value should be + * used for boolean true in uniform uploads? (Usually 1 or ~0.) + */ + GLuint UniformBooleanTrue; + + /** + * Maximum amount of time, measured in nanseconds, that the server can wait. + */ + GLuint64 MaxServerWaitTimeout; + + /** GL_EXT_provoking_vertex */ + GLboolean QuadsFollowProvokingVertexConvention; + + /** GL_ARB_viewport_array */ + GLenum16 LayerAndVPIndexProvokingVertex; + + /** OpenGL version 3.0 */ + GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */ + + /** OpenGL version 3.2 */ + GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */ + + /** OpenGL version 4.4 */ + GLuint MaxVertexAttribStride; + + /** GL_EXT_transform_feedback */ + GLuint MaxTransformFeedbackBuffers; + GLuint MaxTransformFeedbackSeparateComponents; + GLuint MaxTransformFeedbackInterleavedComponents; + GLuint MaxVertexStreams; + + /** GL_EXT_gpu_shader4 */ + GLint MinProgramTexelOffset, MaxProgramTexelOffset; + + /** GL_ARB_texture_gather */ + GLuint MinProgramTextureGatherOffset; + GLuint MaxProgramTextureGatherOffset; + GLuint MaxProgramTextureGatherComponents; + + /* GL_ARB_robustness */ + GLenum16 ResetStrategy; + + /* GL_KHR_robustness */ + GLboolean RobustAccess; + + /* GL_ARB_blend_func_extended */ + GLuint MaxDualSourceDrawBuffers; + + /** + * For drivers which can do a better job at eliminating unused uniforms + * than the GLSL compiler. + * + * XXX Remove these as soon as a better solution is available. + */ + GLboolean GLSLSkipStrictMaxUniformLimitCheck; + + GLboolean GLSLHasHalfFloatPacking; + + /** + * Whether gl_FragCoord, gl_PointCoord and gl_FrontFacing + * are system values. + **/ + bool GLSLFragCoordIsSysVal; + bool GLSLPointCoordIsSysVal; + bool GLSLFrontFacingIsSysVal; + + /** + * Whether to call lower_const_arrays_to_uniforms() during linking. + */ + bool GLSLLowerConstArrays; + + /** + * True if gl_TessLevelInner/Outer[] in the TES should be inputs + * (otherwise, they're system values). + */ + bool GLSLTessLevelsAsInputs; + + /** GL_ARB_map_buffer_alignment */ + GLuint MinMapBufferAlignment; + + /** + * Disable varying packing. This is out of spec, but potentially useful + * for older platforms that supports a limited number of texture + * indirections--on these platforms, unpacking the varyings in the fragment + * shader increases the number of texture indirections by 1, which might + * make some shaders not executable at all. + * + * Drivers that support transform feedback must set this value to GL_FALSE. + */ + GLboolean DisableVaryingPacking; + + /** + * Disable varying packing if used for transform feedback. This is needed + * for some drivers (e.g. Panfrost) where transform feedback requires + * unpacked varyings. + * + * This variable is mutually exlusive with DisableVaryingPacking. + */ + GLboolean DisableTransformFeedbackPacking; + + /** + * Disable the glsl optimisation that resizes uniform arrays. + */ + bool DisableUniformArrayResize; + + /** + * Alias extension e.g. GL_ATI_shader_texture_lod to GL_ARB_shader_texture_lod. + */ + char *AliasShaderExtension; + + /** + * Allow fs-only bias argument in vertex shaders. + */ + GLboolean AllowVertexTextureBias; + + /** + * Align varyings to POT in a slot + * + * Drivers that prefer varyings to be aligned to POT must set this value to GL_TRUE + */ + GLboolean PreferPOTAlignedVaryings; + + + /** + * UBOs and SSBOs can be packed tightly by the OpenGL implementation when + * layout is set as shared (the default) or packed. However most Mesa drivers + * just use STD140 for these layouts. This flag allows drivers to use STD430 + * for packed and shared layouts which allows arrays to be packed more + * tightly. + */ + bool UseSTD430AsDefaultPacking; + + /** + * Should meaningful names be generated for compiler temporary variables? + * + * Generally, it is not useful to have the compiler generate "meaningful" + * names for temporary variables that it creates. This can, however, be a + * useful debugging aid. In Mesa debug builds or release builds when + * MESA_GLSL is set at run-time, meaningful names will be generated. + * Drivers can also force names to be generated by setting this field. + * For example, the i965 driver may set it when INTEL_DEBUG=vs (to dump + * vertex shader assembly) is set at run-time. + */ + bool GenerateTemporaryNames; + + /* + * Maximum value supported for an index in DrawElements and friends. + * + * This must be at least (1ull<<24)-1. The default value is + * (1ull<<32)-1. + * + * \since ES 3.0 or GL_ARB_ES3_compatibility + * \sa _mesa_init_constants + */ + GLuint64 MaxElementIndex; + + /** + * Disable interpretation of line continuations (lines ending with a + * backslash character ('\') in GLSL source. + */ + GLboolean DisableGLSLLineContinuations; + + /** GL_ARB_texture_multisample */ + GLint MaxColorTextureSamples; + GLint MaxDepthTextureSamples; + GLint MaxIntegerSamples; + + /** GL_AMD_framebuffer_multisample_advanced */ + GLint MaxColorFramebufferSamples; + GLint MaxColorFramebufferStorageSamples; + GLint MaxDepthStencilFramebufferSamples; + + /* An array of supported MSAA modes allowing different sample + * counts per attachment type. + */ + struct { + GLint NumColorSamples; + GLint NumColorStorageSamples; + GLint NumDepthStencilSamples; + } SupportedMultisampleModes[40]; + GLint NumSupportedMultisampleModes; + + /** GL_ARB_shader_atomic_counters */ + GLuint MaxAtomicBufferBindings; + GLuint MaxAtomicBufferSize; + GLuint MaxCombinedAtomicBuffers; + GLuint MaxCombinedAtomicCounters; + + /** GL_ARB_vertex_attrib_binding */ + GLint MaxVertexAttribRelativeOffset; + GLint MaxVertexAttribBindings; + + /* GL_ARB_shader_image_load_store */ + GLuint MaxImageUnits; + GLuint MaxCombinedShaderOutputResources; + GLuint MaxImageSamples; + GLuint MaxCombinedImageUniforms; + + /** GL_ARB_compute_shader */ + GLuint MaxComputeWorkGroupCount[3]; /* Array of x, y, z dimensions */ + GLuint MaxComputeWorkGroupSize[3]; /* Array of x, y, z dimensions */ + GLuint MaxComputeWorkGroupInvocations; + GLuint MaxComputeSharedMemorySize; + + /** GL_ARB_compute_variable_group_size */ + GLuint MaxComputeVariableGroupSize[3]; /* Array of x, y, z dimensions */ + GLuint MaxComputeVariableGroupInvocations; + + /** GL_ARB_gpu_shader5 */ + GLfloat MinFragmentInterpolationOffset; + GLfloat MaxFragmentInterpolationOffset; + + GLboolean FakeSWMSAA; + + /** GL_KHR_context_flush_control */ + GLenum16 ContextReleaseBehavior; + + struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES]; + + /** GL_ARB_tessellation_shader */ + GLuint MaxPatchVertices; + GLuint MaxTessGenLevel; + GLuint MaxTessPatchComponents; + GLuint MaxTessControlTotalOutputComponents; + bool PrimitiveRestartForPatches; + + /** GL_OES_primitive_bounding_box */ + bool NoPrimitiveBoundingBoxOutput; + + /** GL_ARB_sparse_buffer */ + GLuint SparseBufferPageSize; + + /** Used as an input for sha1 generation in the on-disk shader cache */ + unsigned char *dri_config_options_sha1; + + /** When drivers are OK with mapped buffers during draw and other calls. */ + bool AllowMappedBuffersDuringExecution; + + /** Override GL_MAP_UNSYNCHRONIZED_BIT */ + bool ForceMapBufferSynchronized; + + /** GL_ARB_get_program_binary */ + GLuint NumProgramBinaryFormats; + + /** GL_ARB_gl_spirv */ + GLuint NumShaderBinaryFormats; + + /** GL_NV_conservative_raster */ + GLuint MaxSubpixelPrecisionBiasBits; + + /** GL_NV_conservative_raster_dilate */ + GLfloat ConservativeRasterDilateRange[2]; + GLfloat ConservativeRasterDilateGranularity; + + /** Is the drivers uniform storage packed or padded to 16 bytes. */ + bool PackedDriverUniformStorage; + + bool HasFBFetch; + + /** Whether the backend supports reading from outputs */ + bool SupportsReadingOutputs; + + bool CombinedClipCullDistanceArrays; + + bool PointSizeFixed; + + /** Wether or not glBitmap uses red textures rather than alpha */ + bool BitmapUsesRed; + + /** Whether the vertex buffer offset is a signed 32-bit integer. */ + bool VertexBufferOffsetIsInt32; + + /** Whether out-of-order draw (Begin/End) optimizations are allowed. */ + bool AllowDrawOutOfOrder; + + /** Whether to force the fast path for binding VAOs. It has much lower + * overhead due to not spending CPU cycles on trying to find interleaved + * vertex attribs and binding them. + */ + bool UseVAOFastPath; + + /** Whether the driver can support primitive restart with a fixed index. + * This is essentially a subset of NV_primitive_restart with enough support + * to be able to enable GLES 3.1. Some hardware can support this but not the + * full NV extension with arbitrary restart indices. + */ + bool PrimitiveRestartFixedIndex; + + /** GL_ARB_gl_spirv */ + struct spirv_supported_capabilities SpirVCapabilities; + + /** GL_ARB_spirv_extensions */ + struct spirv_supported_extensions *SpirVExtensions; + + char *VendorOverride; + char *RendererOverride; + + /** Buffer size used to upload vertices from glBegin/glEnd. */ + unsigned glBeginEndBufferSize; + + /** Whether the driver doesn't want x/y/width/height clipped based on src size + * when doing a copy texture operation (eg: may want out-of-bounds reads that + * produce 0 instead of leaving the texture content undefined). + */ + bool NoClippingOnCopyTex; + + /** + * Force glthread to always return GL_FRAMEBUFFER_COMPLETE to prevent + * synchronization. Used for apps that call it every frame or multiple times + * a frame, but always getting framebuffer completeness. + */ + bool GLThreadNopCheckFramebufferStatus; + + /** GL_ARB_sparse_texture */ + GLuint MaxSparseTextureSize; + GLuint MaxSparse3DTextureSize; + GLuint MaxSparseArrayTextureLayers; + bool SparseTextureFullArrayCubeMipmaps; + + /** Use hardware accelerated GL_SELECT */ + bool HardwareAcceleratedSelect; + + /** Allow GLThread to convert glBuffer */ + bool AllowGLThreadBufferSubDataOpt; + + /** Whether pipe_context::draw_vertex_state is supported. */ + bool HasDrawVertexState; +}; + +#endif diff --git a/src/mesa/main/context.c b/src/mesa/main/context.c index aedb50eafe9..cbe8b4c0914 100644 --- a/src/mesa/main/context.c +++ b/src/mesa/main/context.c @@ -76,10 +76,9 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "accum.h" -#include "api_exec.h" #include "arrayobj.h" #include "attrib.h" #include "bbox.h" @@ -88,7 +87,6 @@ #include "bufferobj.h" #include "conservativeraster.h" #include "context.h" -#include "cpuinfo.h" #include "debug.h" #include "debug_output.h" #include "depth.h" @@ -125,9 +123,10 @@ #include "shaderobj.h" #include "shaderimage.h" #include "state.h" -#include "util/debug.h" +#include "util/u_debug.h" #include "util/disk_cache.h" #include "util/strtod.h" +#include "util/u_call_once.h" #include "stencil.h" #include "shaderimage.h" #include "texcompress_s3tc.h" @@ -144,16 +143,15 @@ #include "macros.h" #include "git_sha1.h" -#ifdef USE_SPARC_ASM -#include "sparc/sparc.h" -#endif - #include "compiler/glsl_types.h" #include "compiler/glsl/builtin_functions.h" #include "compiler/glsl/glsl_parser_extras.h" #include <stdbool.h> #include "util/u_memory.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_cb_flush.h" #ifndef MESA_VERBOSE int MESA_VERBOSE = 0; @@ -168,101 +166,6 @@ int MESA_DEBUG_FLAGS = 0; GLfloat _mesa_ubyte_to_float_color_tab[256]; - -/** - * Swap buffers notification callback. - * - * \param ctx GL context. - * - * Called by window system just before swapping buffers. - * We have to finish any pending rendering. - */ -void -_mesa_notifySwapBuffers(struct gl_context *ctx) -{ - if (MESA_VERBOSE & VERBOSE_SWAPBUFFERS) - _mesa_debug(ctx, "SwapBuffers\n"); - FLUSH_VERTICES(ctx, 0, 0); - if (ctx->Driver.Flush) { - ctx->Driver.Flush(ctx); - } -} - - -/**********************************************************************/ -/** \name GL Visual initialization */ -/**********************************************************************/ -/*@{*/ - - -/** - * Makes some sanity checks and fills in the fields of the struct - * gl_config object with the given parameters. If the caller needs to - * set additional fields, he should just probably init the whole - * gl_config object himself. - * - * \param dbFlag double buffering - * \param stereoFlag stereo buffer - * \param depthBits requested bits per depth buffer value. Any value in [0, 32] - * is acceptable but the actual depth type will be GLushort or GLuint as - * needed. - * \param stencilBits requested minimum bits per stencil buffer value - * \param accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits number - * of bits per color component in accum buffer. - * \param redBits number of bits per color component in frame buffer for RGB(A) - * mode. We always use 8 in core Mesa though. - * \param greenBits same as above. - * \param blueBits same as above. - * \param alphaBits same as above. - * \param numSamples number of samples per pixel. - * - * \return pointer to new struct gl_config or NULL if requested parameters - * can't be met. - * - * \return GL_TRUE on success, or GL_FALSE on failure. - */ -void -_mesa_initialize_visual( struct gl_config *vis, - GLboolean dbFlag, - GLboolean stereoFlag, - GLint redBits, - GLint greenBits, - GLint blueBits, - GLint alphaBits, - GLint depthBits, - GLint stencilBits, - GLint accumRedBits, - GLint accumGreenBits, - GLint accumBlueBits, - GLint accumAlphaBits, - GLuint numSamples ) -{ - assert(vis); - - vis->doubleBufferMode = dbFlag; - vis->stereoMode = stereoFlag; - - vis->redBits = redBits; - vis->greenBits = greenBits; - vis->blueBits = blueBits; - vis->alphaBits = alphaBits; - vis->rgbBits = redBits + greenBits + blueBits + alphaBits; - - vis->depthBits = depthBits; - vis->stencilBits = stencilBits; - - vis->accumRedBits = accumRedBits; - vis->accumGreenBits = accumGreenBits; - vis->accumBlueBits = accumBlueBits; - vis->accumAlphaBits = accumAlphaBits; - - vis->samples = numSamples; -} - - -/*@}*/ - - /**********************************************************************/ /** \name Context allocation, initialization, destroying * @@ -281,7 +184,6 @@ static void one_time_fini(void) { glsl_type_singleton_decref(); - _mesa_locale_fini(); } /** @@ -289,7 +191,7 @@ one_time_fini(void) */ static void -one_time_init(void) +one_time_init(const char *extensions_override) { GLuint i; @@ -300,11 +202,17 @@ one_time_init(void) STATIC_ASSERT(sizeof(GLint) == 4); STATIC_ASSERT(sizeof(GLuint) == 4); - _mesa_locale_init(); + const char *env_const = os_get_option("MESA_EXTENSION_OVERRIDE"); + if (env_const) { + if (extensions_override && + strcmp(extensions_override, env_const)) { + printf("Warning: MESA_EXTENSION_OVERRIDE used instead of driconf setting\n"); + } + extensions_override = env_const; + } - _mesa_one_time_init_extension_overrides(); + _mesa_one_time_init_extension_overrides(extensions_override); - _mesa_get_cpu_features(); for (i = 0; i < 256; i++) { _mesa_ubyte_to_float_color_tab[i] = (float) i / 255.0F; @@ -312,7 +220,7 @@ one_time_init(void) atexit(one_time_fini); -#if defined(DEBUG) +#if MESA_DEBUG if (MESA_VERBOSE != 0) { _mesa_debug(NULL, "Mesa " PACKAGE_VERSION " DEBUG build" MESA_GIT_SHA1 "\n"); } @@ -327,26 +235,18 @@ one_time_init(void) } /** - * One-time initialization flag - * - * \sa Used by _mesa_initialize(). - */ -static once_flag init_once = ONCE_FLAG_INIT; - - -/** * Calls all the various one-time-init functions in Mesa. * * While holding a global mutex lock, calls several initialization functions, * and sets the glapi callbacks if the \c MESA_DEBUG environment variable is * defined. - * - * \sa _math_init(). */ void -_mesa_initialize(void) +_mesa_initialize(const char *extensions_override) { - call_once(&init_once, one_time_init); + static util_once_flag once = UTIL_ONCE_FLAG_INIT; + util_call_once_data(&once, + (util_call_once_data_func)one_time_init, extensions_override); } @@ -558,12 +458,6 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->GLSLLowerConstArrays = true; - /* Assume that if GLSL 1.30+ (or GLSL ES 3.00+) is supported that - * gl_VertexID is implemented using a native hardware register with OpenGL - * semantics. - */ - consts->VertexID_is_zero_based = false; - /* GL_ARB_draw_buffers */ consts->MaxDrawBuffers = MAX_DRAW_BUFFERS; @@ -578,7 +472,7 @@ _mesa_init_constants(struct gl_constants *consts, gl_api api) consts->MaxGeometryTotalOutputComponents = MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS; consts->MaxGeometryShaderInvocations = MAX_GEOMETRY_SHADER_INVOCATIONS; -#ifdef DEBUG +#if MESA_DEBUG consts->GenerateTemporaryNames = true; #else consts->GenerateTemporaryNames = false; @@ -791,6 +685,7 @@ init_attrib_groups(struct gl_context *ctx) _mesa_init_pixelstore( ctx ); _mesa_init_point( ctx ); _mesa_init_polygon( ctx ); + _mesa_init_varray( ctx ); /* should be before _mesa_init_program */ _mesa_init_program( ctx ); _mesa_init_queryobj( ctx ); _mesa_init_sync( ctx ); @@ -800,7 +695,6 @@ init_attrib_groups(struct gl_context *ctx) _mesa_init_stencil( ctx ); _mesa_init_transform( ctx ); _mesa_init_transform_feedback( ctx ); - _mesa_init_varray( ctx ); _mesa_init_viewport( ctx ); _mesa_init_resident_handles( ctx ); @@ -811,11 +705,10 @@ init_attrib_groups(struct gl_context *ctx) ctx->TileRasterOrderIncreasingX = GL_TRUE; ctx->TileRasterOrderIncreasingY = GL_TRUE; ctx->NewState = _NEW_ALL; - ctx->NewDriverState = ~0; + ctx->NewDriverState = ST_ALL_STATES_MASK; ctx->ErrorValue = GL_NO_ERROR; ctx->ShareGroupReset = false; - ctx->VertexProgram._VaryingInputs = VERT_BIT_ALL; - ctx->IntelBlackholeRender = env_var_as_boolean("INTEL_BLACKHOLE_DEFAULT", false); + ctx->IntelBlackholeRender = debug_get_bool_option("INTEL_BLACKHOLE_DEFAULT", false); return GL_TRUE; } @@ -916,6 +809,17 @@ generic_nop(void) #endif +static int +glthread_nop(void) +{ + /* This writes the error into the glthread command buffer if glthread is + * enabled. + */ + CALL_InternalSetError(GET_DISPATCH(), (GL_INVALID_OPERATION)); + return 0; +} + + /** * Create a new API dispatch table in which all entries point to the * generic_nop() function. This will not work on Windows because of @@ -923,7 +827,7 @@ generic_nop(void) * call stack. That's impossible with one generic no-op function. */ struct _glapi_table * -_mesa_new_nop_table(unsigned numEntries) +_mesa_new_nop_table(unsigned numEntries, bool glthread) { struct _glapi_table *table; @@ -939,6 +843,13 @@ _mesa_new_nop_table(unsigned numEntries) #else table = _glapi_new_nop_table(numEntries); #endif + + if (glthread) { + _glapi_proc *entry = (_glapi_proc *) table; + for (unsigned i = 0; i < numEntries; i++) + entry[i] = (_glapi_proc)glthread_nop; + } + return table; } @@ -949,7 +860,7 @@ _mesa_new_nop_table(unsigned numEntries) * functions will call nop_handler() above. */ struct _glapi_table * -_mesa_alloc_dispatch_table(void) +_mesa_alloc_dispatch_table(bool glthread) { /* Find the larger of Mesa's dispatch table and libGL's dispatch table. * In practice, this'll be the same for stand-alone Mesa. But for DRI @@ -958,7 +869,7 @@ _mesa_alloc_dispatch_table(void) */ int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); - struct _glapi_table *table = _mesa_new_nop_table(numEntries); + struct _glapi_table *table = _mesa_new_nop_table(numEntries, glthread); #if defined(_WIN32) if (table) { @@ -990,86 +901,59 @@ _mesa_alloc_dispatch_table(void) } /** - * Creates a minimal dispatch table for use within glBegin()/glEnd(). + * Allocate dispatch tables and set all functions to nop. + * It also makes the OutsideBeginEnd dispatch table current within gl_dispatch. * - * This ensures that we generate GL_INVALID_OPERATION errors from most - * functions, since the set of functions that are valid within Begin/End is - * very small. - * - * From the GL 1.0 specification section 2.6.3, "GL Commands within - * Begin/End" - * - * "The only GL commands that are allowed within any Begin/End pairs are - * the commands for specifying vertex coordinates, vertex color, normal - * coordinates, and texture coordinates (Vertex, Color, Index, Normal, - * TexCoord), EvalCoord and EvalPoint commands (see section 5.1), - * commands for specifying lighting material parameters (Material - * commands see section 2.12.2), display list invocation commands - * (CallList and CallLists see section 5.4), and the EdgeFlag - * command. Executing Begin after Begin has already been executed but - * before an End is issued generates the INVALID OPERATION error, as does - * executing End without a previous corresponding Begin. Executing any - * other GL command within Begin/End results in the error INVALID - * OPERATION." - * - * The table entries for specifying vertex attributes are set up by - * install_vtxfmt(), and End() and dlists - * are set by install_vtxfmt() as well. + * \param glthread Whether to set nop dispatch for glthread or regular dispatch */ -static struct _glapi_table * -create_beginend_table(const struct gl_context *ctx) +bool +_mesa_alloc_dispatch_tables(gl_api api, struct gl_dispatch *d, bool glthread) { - struct _glapi_table *table; - - table = _mesa_alloc_dispatch_table(); - if (!table) - return NULL; + d->OutsideBeginEnd = _mesa_alloc_dispatch_table(glthread); + if (!d->OutsideBeginEnd) + return false; + + if (api == API_OPENGL_COMPAT) { + d->BeginEnd = _mesa_alloc_dispatch_table(glthread); + d->Save = _mesa_alloc_dispatch_table(glthread); + if (!d->BeginEnd || !d->Save) + return false; + } - /* Fill in functions which return a value, since they should return some - * specific value even if they emit a GL_INVALID_OPERATION error from them - * being called within glBegin()/glEnd(). - */ -#define COPY_DISPATCH(func) SET_##func(table, GET_##func(ctx->Exec)) - - COPY_DISPATCH(GenLists); - COPY_DISPATCH(IsProgram); - COPY_DISPATCH(IsVertexArray); - COPY_DISPATCH(IsBuffer); - COPY_DISPATCH(IsEnabled); - COPY_DISPATCH(IsEnabledi); - COPY_DISPATCH(IsRenderbuffer); - COPY_DISPATCH(IsFramebuffer); - COPY_DISPATCH(CheckFramebufferStatus); - COPY_DISPATCH(RenderMode); - COPY_DISPATCH(GetString); - COPY_DISPATCH(GetStringi); - COPY_DISPATCH(GetPointerv); - COPY_DISPATCH(IsQuery); - COPY_DISPATCH(IsSampler); - COPY_DISPATCH(IsSync); - COPY_DISPATCH(IsTexture); - COPY_DISPATCH(IsTransformFeedback); - COPY_DISPATCH(DeleteQueries); - COPY_DISPATCH(AreTexturesResident); - COPY_DISPATCH(FenceSync); - COPY_DISPATCH(ClientWaitSync); - COPY_DISPATCH(MapBuffer); - COPY_DISPATCH(UnmapBuffer); - COPY_DISPATCH(MapBufferRange); - COPY_DISPATCH(ObjectPurgeableAPPLE); - COPY_DISPATCH(ObjectUnpurgeableAPPLE); + d->Current = d->Exec = d->OutsideBeginEnd; + return true; +} - return table; +static void +_mesa_free_dispatch_tables(struct gl_dispatch *d) +{ + free(d->OutsideBeginEnd); + free(d->BeginEnd); + free(d->HWSelectModeBeginEnd); + free(d->Save); + free(d->ContextLost); } -void +bool _mesa_initialize_dispatch_tables(struct gl_context *ctx) { - /* Do the code-generated setup of the exec table in api_exec.c. */ - _mesa_initialize_exec_table(ctx); + if (!_mesa_alloc_dispatch_tables(ctx->API, &ctx->Dispatch, false)) + return false; + + /* Do the code-generated initialization of dispatch tables. */ + _mesa_init_dispatch(ctx); + vbo_init_dispatch_begin_end(ctx); + + if (_mesa_is_desktop_gl_compat(ctx)) { + _mesa_init_dispatch_save(ctx); + _mesa_init_dispatch_save_begin_end(ctx); + } - if (ctx->Save) - _mesa_initialize_save_table(ctx); + /* This binds the dispatch table to the context, but MakeCurrent will + * bind it for the user. If glthread is enabled, it will override it. + */ + ctx->GLApi = ctx->Dispatch.Current; + return true; } /** @@ -1078,7 +962,7 @@ _mesa_initialize_dispatch_tables(struct gl_context *ctx) * This includes allocating all the other structs and arrays which hang off of * the context by pointers. * Note that the driver needs to pass in its dd_function_table here since - * we need to at least call driverFunctions->NewTextureObject to create the + * we need to at least call st_NewTextureObject to create the * default texture objects. * * Called by _mesa_create_context(). @@ -1102,6 +986,7 @@ _mesa_initialize_dispatch_tables(struct gl_context *ctx) GLboolean _mesa_initialize_context(struct gl_context *ctx, gl_api api, + bool no_error, const struct gl_config *visual, struct gl_context *share_list, const struct dd_function_table *driverFunctions) @@ -1109,8 +994,23 @@ _mesa_initialize_context(struct gl_context *ctx, struct gl_shared_state *shared; int i; - assert(driverFunctions->NewTextureObject); - assert(driverFunctions->FreeTextureImageBuffer); + switch (api) { + case API_OPENGL_COMPAT: + case API_OPENGL_CORE: + if (!HAVE_OPENGL) + return GL_FALSE; + break; + case API_OPENGLES2: + if (!HAVE_OPENGL_ES_2) + return GL_FALSE; + break; + case API_OPENGLES: + if (!HAVE_OPENGL_ES_1) + return GL_FALSE; + break; + default: + return GL_FALSE; + } ctx->API = api; ctx->DrawBuffer = NULL; @@ -1130,7 +1030,7 @@ _mesa_initialize_context(struct gl_context *ctx, _mesa_override_gl_version(ctx); /* misc one-time initializations */ - _mesa_initialize(); + _mesa_initialize(NULL); /* Plug in driver functions and context pointer here. * This is important because when we call alloc_shared_state() below @@ -1150,56 +1050,30 @@ _mesa_initialize_context(struct gl_context *ctx, return GL_FALSE; } + /* all supported by default */ + ctx->Const.DriverSupportedPrimMask = 0xffffffff; + _mesa_reference_shared_state(ctx, &ctx->Shared, shared); if (!init_attrib_groups( ctx )) goto fail; - /* KHR_no_error is likely to crash, overflow memory, etc if an application - * has errors so don't enable it for setuid processes. - */ - if (env_var_as_boolean("MESA_NO_ERROR", false)) { -#if !defined(_WIN32) - if (geteuid() == getuid()) -#endif - ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; - } + if (no_error) + ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_NO_ERROR_BIT_KHR; - /* setup the API dispatch tables with all nop functions */ - ctx->OutsideBeginEnd = _mesa_alloc_dispatch_table(); - if (!ctx->OutsideBeginEnd) - goto fail; - ctx->Exec = ctx->OutsideBeginEnd; - ctx->CurrentClientDispatch = ctx->CurrentServerDispatch = ctx->OutsideBeginEnd; - - ctx->FragmentProgram._MaintainTexEnvProgram - = (getenv("MESA_TEX_PROG") != NULL); - - ctx->VertexProgram._MaintainTnlProgram - = (getenv("MESA_TNL_PROG") != NULL); - if (ctx->VertexProgram._MaintainTnlProgram) { - /* this is required... */ - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - _mesa_reset_vertex_processing_mode(ctx); - } + _mesa_reset_vertex_processing_mode(ctx); /* Mesa core handles all the formats that mesa core knows about. * Drivers will want to override this list with just the formats - * they can handle, and confirm that appropriate fallbacks exist in - * _mesa_choose_tex_format(). + * they can handle. */ memset(&ctx->TextureFormatSupported, GL_TRUE, sizeof(ctx->TextureFormatSupported)); switch (ctx->API) { case API_OPENGL_COMPAT: - ctx->BeginEnd = create_beginend_table(ctx); - ctx->Save = _mesa_alloc_dispatch_table(); - if (!ctx->BeginEnd || !ctx->Save) - goto fail; - - FALLTHROUGH; case API_OPENGL_CORE: + case API_OPENGLES2: break; case API_OPENGLES: /** @@ -1218,23 +1092,16 @@ _mesa_initialize_context(struct gl_context *ctx, texUnit->GenR._ModeBit = TEXGEN_REFLECTION_MAP_NV; } break; - case API_OPENGLES2: - ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE; - ctx->VertexProgram._MaintainTnlProgram = GL_TRUE; - _mesa_reset_vertex_processing_mode(ctx); - break; } + ctx->VertexProgram.PointSizeEnabled = _mesa_is_gles2(ctx); + ctx->PointSizeIsSet = GL_TRUE; ctx->FirstTimeCurrent = GL_TRUE; - ctx->_PrimitiveIDIsUnused = true; return GL_TRUE; fail: _mesa_reference_shared_state(ctx, &ctx->Shared, NULL); - free(ctx->BeginEnd); - free(ctx->OutsideBeginEnd); - free(ctx->Save); return GL_FALSE; } @@ -1278,11 +1145,11 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output) _mesa_reference_vao(ctx, &ctx->Array.VAO, NULL); _mesa_reference_vao(ctx, &ctx->Array.DefaultVAO, NULL); - _mesa_reference_vao(ctx, &ctx->Array._EmptyVAO, NULL); _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL); _mesa_free_attrib_data(ctx); _mesa_free_eval_data( ctx ); + _mesa_free_feedback(ctx); _mesa_free_texture_data( ctx ); _mesa_free_image_textures(ctx); _mesa_free_matrix_data( ctx ); @@ -1295,6 +1162,7 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output) _mesa_free_transform_feedback(ctx); _mesa_free_performance_monitors(ctx); _mesa_free_performance_queries(ctx); + _mesa_free_perfomance_monitor_groups(ctx); _mesa_free_resident_handles(ctx); _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); @@ -1308,10 +1176,7 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output) _mesa_free_buffer_objects(ctx); /* free dispatch tables */ - free(ctx->BeginEnd); - free(ctx->OutsideBeginEnd); - free(ctx->Save); - free(ctx->ContextLost); + _mesa_free_dispatch_tables(&ctx->Dispatch); free(ctx->MarshalExec); /* Shared context state (display lists, textures, etc) */ @@ -1338,6 +1203,7 @@ _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output) } free(ctx->Const.SpirVExtensions); + free(ctx->tmp_draws); } @@ -1448,7 +1314,7 @@ _mesa_copy_context( const struct gl_context *src, struct gl_context *dst, /* XXX FIXME: Call callbacks? */ dst->NewState = _NEW_ALL; - dst->NewDriverState = ~0; + dst->NewDriverState = ST_ALL_STATES_MASK; } @@ -1572,8 +1438,8 @@ handle_first_current(struct gl_context *ctx) * that will erroneously allow this usage in a 3.0 forward-compatible * context too. */ - ctx->_AttribZeroAliasesVertex = (ctx->API == API_OPENGLES - || (ctx->API == API_OPENGL_COMPAT + ctx->_AttribZeroAliasesVertex = (_mesa_is_gles1(ctx) + || (_mesa_is_desktop_gl_compat(ctx) && !is_forward_compatible_context)); } @@ -1629,19 +1495,16 @@ _mesa_make_current( struct gl_context *newCtx, } if (curCtx && - (curCtx->WinSysDrawBuffer || curCtx->WinSysReadBuffer) && /* make sure this context is valid for flushing */ curCtx != newCtx && curCtx->Const.ContextReleaseBehavior == GL_CONTEXT_RELEASE_BEHAVIOR_FLUSH) { - _mesa_flush(curCtx); + FLUSH_VERTICES(curCtx, 0, 0); + if (curCtx->st){ + st_glFlush(curCtx, 0); + } } - /* Call this periodically to detect when the user has begun using - * GL rendering from multiple threads. - */ - _glapi_check_multithread(); - if (!newCtx) { _glapi_set_dispatch(NULL); /* none current */ /* We need old ctx to correctly release Draw/ReadBuffer @@ -1658,7 +1521,7 @@ _mesa_make_current( struct gl_context *newCtx, else { _glapi_set_context((void *) newCtx); assert(_mesa_get_current_context() == newCtx); - _glapi_set_dispatch(newCtx->CurrentClientDispatch); + _glapi_set_dispatch(newCtx->GLApi); if (drawBuffer && readBuffer) { assert(_mesa_is_winsys_fbo(drawBuffer)); @@ -1757,25 +1620,6 @@ _mesa_get_current_context( void ) return (struct gl_context *) _glapi_get_context(); } - -/** - * Get context's current API dispatch table. - * - * It'll either be the immediate-mode execute dispatcher, the display list - * compile dispatcher, or the thread marshalling dispatcher. - * - * \param ctx GL context. - * - * \return pointer to dispatch_table. - * - * Simply returns __struct gl_contextRec::CurrentClientDispatch. - */ -struct _glapi_table * -_mesa_get_dispatch(struct gl_context *ctx) -{ - return ctx->CurrentClientDispatch; -} - /*@}*/ @@ -1789,10 +1633,10 @@ _mesa_get_dispatch(struct gl_context *ctx) void _mesa_flush(struct gl_context *ctx) { + bool async = !ctx->Shared->HasExternallySharedImages; FLUSH_VERTICES(ctx, 0, 0); - if (ctx->Driver.Flush) { - ctx->Driver.Flush(ctx); - } + + st_glFlush(ctx, async ? PIPE_FLUSH_ASYNC : 0); } @@ -1811,9 +1655,7 @@ _mesa_Finish(void) FLUSH_VERTICES(ctx, 0, 0); - if (ctx->Driver.Finish) { - ctx->Driver.Finish(ctx); - } + st_glFinish(ctx); } diff --git a/src/mesa/main/context.h b/src/mesa/main/context.h index 9113ecd6ad9..eabb0ffa6f6 100644 --- a/src/mesa/main/context.h +++ b/src/mesa/main/context.h @@ -64,41 +64,35 @@ extern "C" { struct _glapi_table; -/** \name Visual-related functions */ -/*@{*/ - -extern void -_mesa_initialize_visual( struct gl_config *v, - GLboolean dbFlag, - GLboolean stereoFlag, - GLint redBits, - GLint greenBits, - GLint blueBits, - GLint alphaBits, - GLint depthBits, - GLint stencilBits, - GLint accumRedBits, - GLint accumGreenBits, - GLint accumBlueBits, - GLint accumAlphaBits, - GLuint numSamples ); - -/*@}*/ - - /** \name Context-related functions */ /*@{*/ extern void -_mesa_initialize(void); +_mesa_initialize(const char *extensions_override); extern GLboolean _mesa_initialize_context( struct gl_context *ctx, gl_api api, + bool no_error, const struct gl_config *visual, struct gl_context *share_list, const struct dd_function_table *driverFunctions); +extern struct _glapi_table * +_mesa_alloc_dispatch_table(bool glthread); + +extern void +_mesa_init_dispatch(struct gl_context *ctx); + +extern bool +_mesa_alloc_dispatch_tables(gl_api api, struct gl_dispatch *d, bool glthread); + +extern bool +_mesa_initialize_dispatch_tables(struct gl_context *ctx); + +extern struct _glapi_table * +_mesa_new_nop_table(unsigned numEntries, bool glthread); + extern void _mesa_free_context_data(struct gl_context *ctx, bool destroy_debug_output); @@ -121,13 +115,6 @@ extern void _mesa_init_constants(struct gl_constants *consts, gl_api api); extern void -_mesa_notifySwapBuffers(struct gl_context *gc); - - -extern struct _glapi_table * -_mesa_get_dispatch(struct gl_context *ctx); - -extern void _mesa_set_context_lost_dispatch(struct gl_context *ctx); @@ -138,12 +125,6 @@ _mesa_set_context_lost_dispatch(struct gl_context *ctx); extern void _mesa_flush(struct gl_context *ctx); -extern void GLAPIENTRY -_mesa_Finish( void ); - -extern void GLAPIENTRY -_mesa_Flush( void ); - /*@}*/ @@ -269,14 +250,61 @@ do { \ /** + * Checks if the context is for Desktop GL Compatibility + */ +static inline bool +_mesa_is_desktop_gl_compat(const struct gl_context *ctx) +{ +#if HAVE_OPENGL + return ctx->API == API_OPENGL_COMPAT; +#else + return false; +#endif +} + +/** + * Checks if the context is for Desktop GL Core + */ +static inline bool +_mesa_is_desktop_gl_core(const struct gl_context *ctx) +{ +#if HAVE_OPENGL + return ctx->API == API_OPENGL_CORE; +#else + return false; +#endif +} + +/** * Checks if the context is for Desktop GL (Compatibility or Core) */ static inline bool _mesa_is_desktop_gl(const struct gl_context *ctx) { - return ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGL_CORE; + return _mesa_is_desktop_gl_compat(ctx) || _mesa_is_desktop_gl_core(ctx); +} + +/** + * Checks if the context is for GLES 1.0 + */ +static inline bool +_mesa_is_gles1(const struct gl_context *ctx) +{ +#if HAVE_OPENGL_ES_1 + return ctx->API == API_OPENGLES; +#else + return false; +#endif } +/** + * Checks if the context is for GLES 2.0 or later + */ +static inline bool +_mesa_is_gles2(const struct gl_context *ctx) +{ + return _mesa_is_api_gles2(ctx->API); +} /** * Checks if the context is for any GLES version @@ -284,17 +312,16 @@ _mesa_is_desktop_gl(const struct gl_context *ctx) static inline bool _mesa_is_gles(const struct gl_context *ctx) { - return ctx->API == API_OPENGLES || ctx->API == API_OPENGLES2; + return _mesa_is_gles1(ctx) || _mesa_is_gles2(ctx); } - /** * Checks if the context is for GLES 3.0 or later */ static inline bool _mesa_is_gles3(const struct gl_context *ctx) { - return ctx->API == API_OPENGLES2 && ctx->Version >= 30; + return _mesa_is_gles2(ctx) && ctx->Version >= 30; } @@ -304,7 +331,7 @@ _mesa_is_gles3(const struct gl_context *ctx) static inline bool _mesa_is_gles31(const struct gl_context *ctx) { - return ctx->API == API_OPENGLES2 && ctx->Version >= 31; + return _mesa_is_gles2(ctx) && ctx->Version >= 31; } @@ -314,7 +341,7 @@ _mesa_is_gles31(const struct gl_context *ctx) static inline bool _mesa_is_gles32(const struct gl_context *ctx) { - return ctx->API == API_OPENGLES2 && ctx->Version >= 32; + return _mesa_is_gles2(ctx) && ctx->Version >= 32; } @@ -401,7 +428,7 @@ static inline bool _mesa_has_compute_shaders(const struct gl_context *ctx) { return _mesa_has_ARB_compute_shader(ctx) || - (ctx->API == API_OPENGLES2 && ctx->Version >= 31); + _mesa_is_gles31(ctx); } /** @@ -431,6 +458,36 @@ _mesa_has_texture_view(const struct gl_context *ctx) _mesa_has_OES_texture_view(ctx); } +static inline bool +_mesa_hw_select_enabled(const struct gl_context *ctx) +{ + return ctx->RenderMode == GL_SELECT && + ctx->Const.HardwareAcceleratedSelect; +} + +static inline bool +_mesa_has_occlusion_query(const struct gl_context *ctx) +{ + return _mesa_has_ARB_occlusion_query(ctx) || + _mesa_has_ARB_occlusion_query2(ctx) || + (_mesa_is_desktop_gl(ctx) && ctx->Version >= 15); +} + +static inline bool +_mesa_has_occlusion_query_boolean(const struct gl_context *ctx) +{ + return _mesa_has_ARB_occlusion_query2(ctx) || + _mesa_has_EXT_occlusion_query_boolean(ctx) || + (_mesa_is_desktop_gl(ctx) && ctx->Version >= 33); +} + +static inline bool +_mesa_has_pipeline_statistics(const struct gl_context *ctx) +{ + return _mesa_has_ARB_pipeline_statistics_query(ctx) || + (_mesa_is_desktop_gl(ctx) && ctx->Version >= 46); +} + #ifdef __cplusplus } #endif diff --git a/src/mesa/main/convolve.c b/src/mesa/main/convolve.c deleted file mode 100644 index e2c355c4f41..00000000000 --- a/src/mesa/main/convolve.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/* - * Image convolution functions. - * - * Notes: filter kernel elements are indexed by <n> and <m> as in - * the GL spec. - */ - - -#include "glheader.h" -#include "context.h" -#include "convolve.h" - - -void GLAPIENTRY -_mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, GLenum format, GLenum type, const GLvoid *image) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter1D"); -} - -void GLAPIENTRY -_mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *image) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionFilter2D"); -} - - -void GLAPIENTRY -_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterf"); -} - - -void GLAPIENTRY -_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, const GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameterfv"); -} - - -void GLAPIENTRY -_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteri"); -} - - -void GLAPIENTRY -_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glConvolutionParameteriv"); -} - - -void GLAPIENTRY -_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter1D"); -} - - -void GLAPIENTRY -_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyConvolutionFilter2D"); -} - - -void GLAPIENTRY -_mesa_GetnConvolutionFilterARB(GLenum target, GLenum format, GLenum type, - GLsizei bufSize, GLvoid *image) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionFilter"); -} - - -void GLAPIENTRY -_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, - GLvoid *image) -{ - _mesa_GetnConvolutionFilterARB(target, format, type, INT_MAX, image); -} - - -void GLAPIENTRY -_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameterfv"); -} - - -void GLAPIENTRY -_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetConvolutionParameteriv"); -} - - -void GLAPIENTRY -_mesa_GetnSeparableFilterARB(GLenum target, GLenum format, GLenum type, - GLsizei rowBufSize, GLvoid *row, - GLsizei columnBufSize, GLvoid *column, - GLvoid *span) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetSeparableFilter"); -} - - -void GLAPIENTRY -_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, - GLvoid *row, GLvoid *column, GLvoid *span) -{ - _mesa_GetnSeparableFilterARB(target, format, type, INT_MAX, row, - INT_MAX, column, span); -} - - -void GLAPIENTRY -_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *row, const GLvoid *column) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glSeparableFilter2D"); -} diff --git a/src/mesa/main/convolve.h b/src/mesa/main/convolve.h deleted file mode 100644 index e696ce497e0..00000000000 --- a/src/mesa/main/convolve.h +++ /dev/null @@ -1,80 +0,0 @@ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2001 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef CONVOLVE_H -#define CONVOLVE_H - - -#include "glheader.h" - -struct _glapi_table; - -void GLAPIENTRY -_mesa_ConvolutionFilter1D(GLenum target, GLenum internalFormat, GLsizei width, - GLenum format, GLenum type, const GLvoid *image); -void GLAPIENTRY -_mesa_ConvolutionFilter2D(GLenum target, GLenum internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, - const GLvoid *image); -void GLAPIENTRY -_mesa_ConvolutionParameterf(GLenum target, GLenum pname, GLfloat param); -void GLAPIENTRY -_mesa_ConvolutionParameterfv(GLenum target, GLenum pname, - const GLfloat *params); -void GLAPIENTRY -_mesa_ConvolutionParameteri(GLenum target, GLenum pname, GLint param); -void GLAPIENTRY -_mesa_ConvolutionParameteriv(GLenum target, GLenum pname, const GLint *params); -void GLAPIENTRY -_mesa_CopyConvolutionFilter1D(GLenum target, GLenum internalFormat, GLint x, - GLint y, GLsizei width); -void GLAPIENTRY -_mesa_CopyConvolutionFilter2D(GLenum target, GLenum internalFormat, GLint x, - GLint y, GLsizei width, GLsizei height); -void GLAPIENTRY -_mesa_GetnConvolutionFilterARB(GLenum target, GLenum format, GLenum type, - GLsizei bufSize, GLvoid *image); -void GLAPIENTRY -_mesa_GetConvolutionFilter(GLenum target, GLenum format, GLenum type, - GLvoid *image); -void GLAPIENTRY -_mesa_GetConvolutionParameterfv(GLenum target, GLenum pname, GLfloat *params); -void GLAPIENTRY -_mesa_GetConvolutionParameteriv(GLenum target, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetnSeparableFilterARB(GLenum target, GLenum format, GLenum type, - GLsizei rowBufSize, GLvoid *row, - GLsizei columnBufSize, GLvoid *column, - GLvoid *span); -void GLAPIENTRY -_mesa_GetSeparableFilter(GLenum target, GLenum format, GLenum type, - GLvoid *row, GLvoid *column, GLvoid *span); -void GLAPIENTRY -_mesa_SeparableFilter2D(GLenum target, GLenum internalFormat, GLsizei width, - GLsizei height, GLenum format, GLenum type, - const GLvoid *row, const GLvoid *column); - -#endif /* CONVOLVE_H */ diff --git a/src/mesa/main/copyimage.c b/src/mesa/main/copyimage.c index 3373c6e8cbb..3fcfd3dda15 100644 --- a/src/mesa/main/copyimage.c +++ b/src/mesa/main/copyimage.c @@ -20,21 +20,20 @@ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jason Ekstrand <jason.ekstrand@intel.com> */ #include "context.h" -#include "glheader.h" +#include "util/glheader.h" #include "errors.h" #include "enums.h" -#include "copyimage.h" #include "teximage.h" #include "texobj.h" #include "fbobject.h" #include "textureview.h" #include "glformats.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_copyimage.h" enum mesa_block_class { BLOCK_CLASS_128_BITS, @@ -101,6 +100,9 @@ prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target, break; case GL_TEXTURE_EXTERNAL_OES: /* Only exists in ES */ + if (_mesa_is_gles(ctx)) + break; + FALLTHROUGH; case GL_TEXTURE_BUFFER: default: _mesa_error(ctx, GL_INVALID_ENUM, @@ -237,7 +239,11 @@ prepare_target_err(struct gl_context *ctx, GLuint name, GLenum target, if (target == GL_TEXTURE_CUBE_MAP) { int i; - assert(z < MAX_FACES); /* should have been caught earlier */ + if (z < 0 || z >= MAX_FACES) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glCopyImageSubData(cube face (%sZ = %d)", dbg_prefix, z); + return false; + } /* make sure all the cube faces are present */ for (i = 0; i < depth; i++) { @@ -567,12 +573,12 @@ copy_image_subdata(struct gl_context *ctx, newDstZ = 0; } - ctx->Driver.CopyImageSubData(ctx, - srcTexImage, srcRenderbuffer, - srcX, srcY, newSrcZ, - dstTexImage, dstRenderbuffer, - dstX, dstY, newDstZ, - srcWidth, srcHeight); + st_CopyImageSubData(ctx, + srcTexImage, srcRenderbuffer, + srcX, srcY, newSrcZ, + dstTexImage, dstRenderbuffer, + dstX, dstY, newDstZ, + srcWidth, srcHeight); } } diff --git a/src/mesa/main/copyimage.h b/src/mesa/main/copyimage.h deleted file mode 100644 index 09f6dca3bdf..00000000000 --- a/src/mesa/main/copyimage.h +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2014 Intel Corporation. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Jason Ekstrand <jason.ekstrand@intel.com> - */ - - -#ifndef COPYIMAGE_H -#define COPYIMAGE_H - -#include "glheader.h" - -#ifdef __cplusplus -extern "C" { -#endif - -void GLAPIENTRY -_mesa_CopyImageSubData_no_error(GLuint srcName, GLenum srcTarget, GLint srcLevel, - GLint srcX, GLint srcY, GLint srcZ, - GLuint destName, GLenum destTarget, GLint destLevel, - GLint destX, GLint destY, GLint destZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -extern void GLAPIENTRY -_mesa_CopyImageSubData(GLuint srcName, GLenum srcTarget, GLint srcLevel, - GLint srcX, GLint srcY, GLint srcZ, - GLuint destName, GLenum destTarget, GLint destLevel, - GLint destX, GLint destY, GLint destZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -void GLAPIENTRY -_mesa_CopyImageSubDataNV_no_error(GLuint srcName, GLenum srcTarget, GLint srcLevel, - GLint srcX, GLint srcY, GLint srcZ, - GLuint destName, GLenum destTarget, GLint destLevel, - GLint destX, GLint destY, GLint destZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -extern void GLAPIENTRY -_mesa_CopyImageSubDataNV(GLuint srcName, GLenum srcTarget, GLint srcLevel, - GLint srcX, GLint srcY, GLint srcZ, - GLuint destName, GLenum destTarget, GLint destLevel, - GLint destX, GLint destY, GLint destZ, - GLsizei srcWidth, GLsizei srcHeight, GLsizei srcDepth); - -#ifdef __cplusplus -} -#endif - -#endif /* COPYIMAGE_H */ diff --git a/src/mesa/main/cpuinfo.c b/src/mesa/main/cpuinfo.c deleted file mode 100644 index 1623a20892e..00000000000 --- a/src/mesa/main/cpuinfo.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#include <stdlib.h> -#include <string.h> -#include <assert.h> - -#include "main/cpuinfo.h" - - -/** - * This function should be called before the various "cpu_has_foo" macros - * are used. - */ -void -_mesa_get_cpu_features(void) -{ -#if defined USE_X86_ASM || defined USE_X86_64_ASM - _mesa_get_x86_features(); -#endif -} - - -/** - * Return a string describing the CPU architexture and extensions that - * Mesa is using (such as SSE or Altivec). - * \return information string, free it with free() - */ -char * -_mesa_get_cpu_string(void) -{ -#define MAX_STRING 50 - char *buffer; - - buffer = malloc(MAX_STRING); - if (!buffer) - return NULL; - - buffer[0] = 0; - -#ifdef USE_X86_ASM - - if (_mesa_x86_cpu_features) { - strcat(buffer, "x86"); - } - -# ifdef USE_MMX_ASM - if (cpu_has_mmx) { - strcat(buffer, (cpu_has_mmxext) ? "/MMX+" : "/MMX"); - } -# endif -# ifdef USE_3DNOW_ASM - if (cpu_has_3dnow) { - strcat(buffer, (cpu_has_3dnowext) ? "/3DNow!+" : "/3DNow!"); - } -# endif -# ifdef USE_SSE_ASM - if (cpu_has_xmm) { - strcat(buffer, (cpu_has_xmm2) ? "/SSE2" : "/SSE"); - } -# endif - -#elif defined(USE_SPARC_ASM) - - strcat(buffer, "SPARC"); - -#endif - - assert(strlen(buffer) < MAX_STRING); - - return buffer; -} diff --git a/src/mesa/main/cpuinfo.h b/src/mesa/main/cpuinfo.h deleted file mode 100644 index 57925e82bf2..00000000000 --- a/src/mesa/main/cpuinfo.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef CPUINFO_H -#define CPUINFO_H - - -#if defined USE_X86_ASM || defined USE_X86_64_ASM -#include "x86/common_x86_asm.h" -#endif - - -extern void -_mesa_get_cpu_features(void); - - -extern char * -_mesa_get_cpu_string(void); - - -#endif /* CPUINFO_H */ diff --git a/src/mesa/main/dd.h b/src/mesa/main/dd.h index 8db6848be95..8904ab92137 100644 --- a/src/mesa/main/dd.h +++ b/src/mesa/main/dd.h @@ -31,20 +31,15 @@ #ifndef DD_INCLUDED #define DD_INCLUDED -#include "glheader.h" +#include "util/glheader.h" #include "formats.h" #include "menums.h" #include "compiler/shader_enums.h" -/* Windows winnt.h defines MemoryBarrier as a macro on some platforms, - * including as a function-like macro in some cases. That either causes - * the table entry below to have a weird name, or fail to compile. - */ -#ifdef MemoryBarrier -#undef MemoryBarrier +#if defined(_WIN32) && defined(_WINDOWS_) +#error "Should not include <windows.h> here" #endif -struct gl_bitmap_atlas; struct gl_buffer_object; struct gl_context; struct gl_display_list; @@ -59,13 +54,20 @@ struct gl_shader_program; struct gl_texture_image; struct gl_texture_object; struct gl_memory_info; +struct gl_memory_object; +struct gl_query_object; +struct gl_sampler_object; struct gl_transform_feedback_object; +struct gl_vertex_array_object; struct ati_fragment_shader; struct util_queue_monitoring; -struct _mesa_prim; -struct _mesa_index_buffer; struct pipe_draw_info; +struct pipe_draw_indirect_info; struct pipe_draw_start_count_bias; +struct pipe_vertex_state; +struct pipe_draw_vertex_state_info; +struct pipe_vertex_buffer; +struct pipe_vertex_element; /* GL_ARB_vertex_buffer_object */ /* Modifies GL_MAP_UNSYNCHRONIZED_BIT to allow driver to fail (return @@ -75,7 +77,7 @@ struct pipe_draw_start_count_bias; * would require more book-keeping in the driver than seems necessary * at this point. * - * Does GL_MAP_INVALDIATE_BUFFER_BIT do this? Not really -- we don't + * Does GL_MAP_INVALIDATE_BUFFER_BIT do this? Not really -- we don't * want to provoke the driver to throw away the old storage, we will * respect the contents of already referenced data. */ @@ -87,6 +89,12 @@ struct pipe_draw_start_count_bias; /* This buffer will only be mapped/unmapped once */ #define MESA_MAP_ONCE 0x10000 +/* This BufferStorage flag indicates that the buffer will be used + * by pipe_vertex_state, which doesn't track buffer busyness and doesn't + * support invalidations. + */ +#define MESA_GALLIUM_VERTEX_STATE_STORAGE 0x20000 + /** * Device driver function table. @@ -103,422 +111,12 @@ struct pipe_draw_start_count_bias; */ struct dd_function_table { /** - * Return a string as needed by glGetString(). - * Only the GL_RENDERER query must be implemented. Otherwise, NULL can be - * returned. - */ - const GLubyte * (*GetString)( struct gl_context *ctx, GLenum name ); - - /** - * Notify the driver after Mesa has made some internal state changes. - * - * This is in addition to any state change callbacks Mesa may already have - * made. - */ - void (*UpdateState)(struct gl_context *ctx); - - /** - * This is called whenever glFinish() is called. - */ - void (*Finish)( struct gl_context *ctx ); - - /** - * This is called whenever glFlush() is called. - */ - void (*Flush)( struct gl_context *ctx ); - - /** - * Clear the color/depth/stencil/accum buffer(s). - * \param buffers a bitmask of BUFFER_BIT_* flags indicating which - * renderbuffers need to be cleared. - */ - void (*Clear)( struct gl_context *ctx, GLbitfield buffers ); - - /** - * Execute glRasterPos, updating the ctx->Current.Raster fields - */ - void (*RasterPos)( struct gl_context *ctx, const GLfloat v[4] ); - - /** - * \name Image-related functions - */ - /*@{*/ - - /** - * Called by glDrawPixels(). - * \p unpack describes how to unpack the source image data. - */ - void (*DrawPixels)( struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - const GLvoid *pixels ); - - /** - * Called by glReadPixels(). - */ - void (*ReadPixels)( struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const struct gl_pixelstore_attrib *unpack, - GLvoid *dest ); - - /** - * Called by glCopyPixels(). - */ - void (*CopyPixels)( struct gl_context *ctx, GLint srcx, GLint srcy, - GLsizei width, GLsizei height, - GLint dstx, GLint dsty, GLenum type ); - - /** - * Called by glBitmap(). - */ - void (*Bitmap)( struct gl_context *ctx, - GLint x, GLint y, GLsizei width, GLsizei height, - const struct gl_pixelstore_attrib *unpack, - const GLubyte *bitmap ); - - /** - * Called by display list code for optimized glCallLists/glBitmap rendering - * The driver must support texture rectangles of width 1024 or more. - */ - void (*DrawAtlasBitmaps)(struct gl_context *ctx, - const struct gl_bitmap_atlas *atlas, - GLuint count, const GLubyte *ids); - /*@}*/ - - - /** - * \name Texture image functions - */ - /*@{*/ - - /** - * Choose actual hardware texture format given the texture target, the - * user-provided source image format and type and the desired internal - * format. In some cases, srcFormat and srcType can be GL_NONE. - * Note: target may be GL_TEXTURE_CUBE_MAP, but never - * GL_TEXTURE_CUBE_MAP_[POSITIVE/NEGATIVE]_[XYZ]. - * Called by glTexImage(), etc. - */ - mesa_format (*ChooseTextureFormat)(struct gl_context *ctx, - GLenum target, GLint internalFormat, - GLenum srcFormat, GLenum srcType ); - - /** - * Queries different driver parameters for a particular target and format. - * Since ARB_internalformat_query2 introduced several new query parameters - * over ARB_internalformat_query, having one driver hook for each parameter - * is no longer feasible. So this is the generic entry-point for calls - * to glGetInternalFormativ and glGetInternalFormati64v, after Mesa has - * checked errors and default values. - * - * \param ctx GL context - * \param target GL target enum - * \param internalFormat GL format enum - * \param pname GL enum that specifies the info to query. - * \param params Buffer to hold the result of the query. - */ - void (*QueryInternalFormat)(struct gl_context *ctx, - GLenum target, - GLenum internalFormat, - GLenum pname, - GLint *params); - - /** - * Called by glTexImage[123]D() and glCopyTexImage[12]D() - * Allocate texture memory and copy the user's image to the buffer. - * The gl_texture_image fields, etc. will be fully initialized. - * The parameters are the same as glTexImage3D(), plus: - * \param dims 1, 2, or 3 indicating glTexImage1/2/3D() - * \param packing describes how to unpack the source data. - * \param texImage is the destination texture image. - */ - void (*TexImage)(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing); - - /** - * Called by glTexSubImage[123]D(). - * Replace a subset of the target texture with new texel data. - */ - void (*TexSubImage)(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLint depth, - GLenum format, GLenum type, - const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing); - - - /** - * Called by glGetTexImage(), glGetTextureSubImage(). - */ - void (*GetTexSubImage)(struct gl_context *ctx, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, GLvoid *pixels, - struct gl_texture_image *texImage); - - /** - * Called by glClearTex[Sub]Image - * - * Clears a rectangular region of the image to a given value. The - * clearValue argument is either NULL or points to a single texel to use as - * the clear value in the same internal format as the texture image. If it - * is NULL then the texture should be cleared to zeroes. - */ - void (*ClearTexSubImage)(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - const GLvoid *clearValue); - - /** - * Called by glCopyTex[Sub]Image[123]D(). - * - * This function should copy a rectangular region in the rb to a single - * destination slice, specified by @slice. In the case of 1D array - * textures (where one GL call can potentially affect multiple destination - * slices), core mesa takes care of calling this function multiple times, - * once for each scanline to be copied. - */ - void (*CopyTexSubImage)(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint slice, - struct gl_renderbuffer *rb, - GLint x, GLint y, - GLsizei width, GLsizei height); - /** - * Called by glCopyImageSubData(). - * - * This function should copy one 2-D slice from src_teximage or - * src_renderbuffer to dst_teximage or dst_renderbuffer. Either the - * teximage or renderbuffer pointer will be non-null to indicate which - * is the real src/dst. - * - * If one of the textures is 3-D or is a 1-D or 2-D array - * texture, this function will be called multiple times: once for each - * slice. If one of the textures is a cube map, this function will be - * called once for each face to be copied. - */ - void (*CopyImageSubData)(struct gl_context *ctx, - struct gl_texture_image *src_teximage, - struct gl_renderbuffer *src_renderbuffer, - int src_x, int src_y, int src_z, - struct gl_texture_image *dst_teximage, - struct gl_renderbuffer *dst_renderbuffer, - int dst_x, int dst_y, int dst_z, - int src_width, int src_height); - - /** - * Called by glGenerateMipmap() or when GL_GENERATE_MIPMAP_SGIS is enabled. - * Note that if the texture is a cube map, the <target> parameter will - * indicate which cube face to generate (GL_POSITIVE/NEGATIVE_X/Y/Z). - * texObj->BaseLevel is the level from which to generate the remaining - * mipmap levels. - */ - void (*GenerateMipmap)(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj); - - /** - * Called by glTexImage, glCompressedTexImage, glCopyTexImage - * and glTexStorage to check if the dimensions of the texture image - * are too large. - * \param target any GL_PROXY_TEXTURE_x target - * \return GL_TRUE if the image is OK, GL_FALSE if too large - */ - GLboolean (*TestProxyTexImage)(struct gl_context *ctx, GLenum target, - GLuint numLevels, GLint level, - mesa_format format, GLuint numSamples, - GLint width, GLint height, - GLint depth); - /*@}*/ - - - /** - * \name Compressed texture functions - */ - /*@{*/ - - /** - * Called by glCompressedTexImage[123]D(). - */ - void (*CompressedTexImage)(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLsizei imageSize, const GLvoid *data); - - /** - * Called by glCompressedTexSubImage[123]D(). - */ - void (*CompressedTexSubImage)(struct gl_context *ctx, GLuint dims, - struct gl_texture_image *texImage, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, - GLsizei imageSize, const GLvoid *data); - /*@}*/ - - /** - * \name Texture object / image functions - */ - /*@{*/ - - /** - * Called by glBindTexture() and glBindTextures(). - */ - void (*BindTexture)( struct gl_context *ctx, GLuint texUnit, - GLenum target, struct gl_texture_object *tObj ); - - /** - * Called to allocate a new texture object. Drivers will usually - * allocate/return a subclass of gl_texture_object. - */ - struct gl_texture_object * (*NewTextureObject)(struct gl_context *ctx, - GLuint name, GLenum target); - /** - * Called to delete/free a texture object. Drivers should free the - * object and any image data it contains. - */ - void (*DeleteTexture)(struct gl_context *ctx, - struct gl_texture_object *texObj); - - /** - * Called to notify that texture is removed from ctx->Shared->TexObjects - */ - void (*TextureRemovedFromShared)(struct gl_context *ctx, - struct gl_texture_object *texObj); - - /** Called to allocate a new texture image object. */ - struct gl_texture_image * (*NewTextureImage)(struct gl_context *ctx); - - /** Called to free a texture image object returned by NewTextureImage() */ - void (*DeleteTextureImage)(struct gl_context *ctx, - struct gl_texture_image *); - - /** Called to allocate memory for a single texture image */ - GLboolean (*AllocTextureImageBuffer)(struct gl_context *ctx, - struct gl_texture_image *texImage); - - /** Free the memory for a single texture image */ - void (*FreeTextureImageBuffer)(struct gl_context *ctx, - struct gl_texture_image *texImage); - - /** Map a slice of a texture image into user space. - * Note: for GL_TEXTURE_1D_ARRAY, height must be 1, y must be 0 and slice - * indicates the 1D array index. - * \param texImage the texture image - * \param slice the 3D image slice or array texture slice - * \param x, y, w, h region of interest - * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT and - * GL_MAP_INVALIDATE_RANGE_BIT (if writing) - * \param mapOut returns start of mapping of region of interest - * \param rowStrideOut returns row stride (in bytes). In the case of a - * compressed texture, this is the byte stride between one row of blocks - * and another. - */ - void (*MapTextureImage)(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **mapOut, GLint *rowStrideOut); - - void (*UnmapTextureImage)(struct gl_context *ctx, - struct gl_texture_image *texImage, - GLuint slice); - - /** For GL_ARB_texture_storage. Allocate memory for whole mipmap stack. - * All the gl_texture_images in the texture object will have their - * dimensions, format, etc. initialized already. - */ - GLboolean (*AllocTextureStorage)(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth); - - /** Called as part of glTextureView to add views to origTexObj */ - GLboolean (*TextureView)(struct gl_context *ctx, - struct gl_texture_object *texObj, - struct gl_texture_object *origTexObj); - - /** - * Map a renderbuffer into user space. - * \param mode bitmask of GL_MAP_READ_BIT, GL_MAP_WRITE_BIT and - * GL_MAP_INVALIDATE_RANGE_BIT (if writing) - */ - void (*MapRenderbuffer)(struct gl_context *ctx, - struct gl_renderbuffer *rb, - GLuint x, GLuint y, GLuint w, GLuint h, - GLbitfield mode, - GLubyte **mapOut, GLint *rowStrideOut, - bool flip_y); - - void (*UnmapRenderbuffer)(struct gl_context *ctx, - struct gl_renderbuffer *rb); - - /** - * Optional driver entrypoint that binds a non-texture renderbuffer's - * contents to a texture image. - */ - GLboolean (*BindRenderbufferTexImage)(struct gl_context *ctx, - struct gl_renderbuffer *rb, - struct gl_texture_image *texImage); - /*@}*/ - - - /** * \name Vertex/fragment program functions */ - /*@{*/ /** Allocate a new program */ struct gl_program * (*NewProgram)(struct gl_context *ctx, gl_shader_stage stage, GLuint id, bool is_arb_asm); - /** Delete a program */ - void (*DeleteProgram)(struct gl_context *ctx, struct gl_program *prog); - /** - * Allocate a program to associate with the new ATI fragment shader (optional) - */ - struct gl_program * (*NewATIfs)(struct gl_context *ctx, - struct ati_fragment_shader *curProg); - /** - * Notify driver that a program string (and GPU code) has been specified - * or modified. Return GL_TRUE or GL_FALSE to indicate if the program is - * supported by the driver. - */ - GLboolean (*ProgramStringNotify)(struct gl_context *ctx, GLenum target, - struct gl_program *prog); - - /** - * Notify driver that the sampler uniforms for the current program have - * changed. On some drivers, this may require shader recompiles. - */ - void (*SamplerUniformChange)(struct gl_context *ctx, GLenum target, - struct gl_program *prog); - - /** Query if program can be loaded onto hardware */ - GLboolean (*IsProgramNative)(struct gl_context *ctx, GLenum target, - struct gl_program *prog); - - /*@}*/ - - /** - * \name GLSL shader/program functions. - */ - /*@{*/ - /** - * Called when a shader program is linked. - * - * This gives drivers an opportunity to clone the IR and make their - * own transformations on it for the purposes of code generation. - */ - GLboolean (*LinkShader)(struct gl_context *ctx, - struct gl_shader_program *shader); - /*@}*/ - - /** * \name Draw functions. */ @@ -545,424 +143,32 @@ struct dd_function_table { */ /** - * Draw a number of primitives. - * \param prims array [nr_prims] describing what to draw (prim type, - * vertex count, first index, instance count, etc). - * \param ib index buffer for indexed drawing, NULL for array drawing - * \param index_bounds_valid are min_index and max_index valid? - * \param min_index lowest vertex index used - * \param max_index highest vertex index used - * \param num_instances instance count from ARB_draw_instanced - * \param base_instance base instance from ARB_base_instance - */ - void (*Draw)(struct gl_context *ctx, - const struct _mesa_prim *prims, unsigned nr_prims, - const struct _mesa_index_buffer *ib, - bool index_bounds_valid, - bool primitive_restart, - unsigned restart_index, - unsigned min_index, unsigned max_index, - unsigned num_instances, unsigned base_instance); - - /** - * Optimal Gallium version of Draw() that doesn't require translation - * of draw info in the state tracker. + * The basic draw function used to implement glDrawArrays, glDrawElements, + * multidraws, and instancing. * - * The interface is identical to pipe_context::draw_vbo - * with indirect == NULL. - * - * "info" is not const and the following fields can be changed by - * the callee, so callers should be aware: - * - info->index_bounds_valid (if false) - * - info->min_index (if index_bounds_valid is false) - * - info->max_index (if index_bounds_valid is false) - * - info->drawid (if increment_draw_id is true) - * - info->index.gl_bo (if index_size && !has_user_indices) + * The interface is identical to pipe_context::draw_vbo. */ void (*DrawGallium)(struct gl_context *ctx, - struct pipe_draw_info *info, + const struct pipe_draw_info *info, unsigned drawid_offset, + const struct pipe_draw_indirect_info *indirect, const struct pipe_draw_start_count_bias *draws, unsigned num_draws); /** * Same as DrawGallium, but mode can also change between draws. * - * If mode != NULL, mode changes for each draw. - * At least one of them must be non-NULL. - * * "info" is not const and the following fields can be changed by * the callee in addition to the fields listed by DrawGallium: - * - info->mode (if mode != NULL) + * - info->mode * * This function exists to decrease complexity of DrawGallium. */ void (*DrawGalliumMultiMode)(struct gl_context *ctx, - struct pipe_draw_info *info, - unsigned drawid_offset, - const struct pipe_draw_start_count_bias *draws, - const unsigned char *mode, - unsigned num_draws); - - /** - * Draw a primitive, getting the vertex count, instance count, start - * vertex, etc. from a buffer object. - * \param mode GL_POINTS, GL_LINES, GL_TRIANGLE_STRIP, etc. - * \param indirect_data buffer to get "DrawArrays/ElementsIndirectCommand" - * data - * \param indirect_offset offset of first primitive in indrect_data buffer - * \param draw_count number of primitives to draw - * \param stride stride, in bytes, between - * "DrawArrays/ElementsIndirectCommand" objects - * \param indirect_draw_count_buffer if non-NULL specifies a buffer to get - * the real draw_count value. Used for - * GL_ARB_indirect_parameters. - * \param indirect_draw_count_offset offset to the draw_count value in - * indirect_draw_count_buffer - * \param ib index buffer for indexed drawing, NULL otherwise. - */ - void (*DrawIndirect)(struct gl_context *ctx, GLuint mode, - struct gl_buffer_object *indirect_data, - GLsizeiptr indirect_offset, unsigned draw_count, - unsigned stride, - struct gl_buffer_object *indirect_draw_count_buffer, - GLsizeiptr indirect_draw_count_offset, - const struct _mesa_index_buffer *ib, - bool primitive_restart, - unsigned restart_index); - - /** - * Driver implementation of glDrawTransformFeedback. - * - * \param mode Primitive type - * \param num_instances instance count from ARB_draw_instanced - * \param stream If called via DrawTransformFeedbackStream, specifies - * the vertex stream buffer from which to get the vertex - * count. - * \param tfb_vertcount if non-null, indicates which transform feedback - * object has the vertex count. - */ - void (*DrawTransformFeedback)(struct gl_context *ctx, GLenum mode, - unsigned num_instances, unsigned stream, - struct gl_transform_feedback_object *tfb_vertcount); - /*@}*/ - - - /** - * \name State-changing functions. - * - * \note drawing functions are above. - * - * These functions are called by their corresponding OpenGL API functions. - * They are \e also called by the gl_PopAttrib() function!!! - * May add more functions like these to the device driver in the future. - */ - /*@{*/ - /** Specify the alpha test function */ - void (*AlphaFunc)(struct gl_context *ctx, GLenum func, GLfloat ref); - /** Set the blend color */ - void (*BlendColor)(struct gl_context *ctx, const GLfloat color[4]); - /** Set the blend equation */ - void (*BlendEquationSeparate)(struct gl_context *ctx, - GLenum modeRGB, GLenum modeA); - /** Specify pixel arithmetic */ - void (*BlendFuncSeparate)(struct gl_context *ctx, - GLenum sfactorRGB, GLenum dfactorRGB, - GLenum sfactorA, GLenum dfactorA); - /** Specify a plane against which all geometry is clipped */ - void (*ClipPlane)(struct gl_context *ctx, GLenum plane, const GLfloat *eq); - /** Enable and disable writing of frame buffer color components */ - void (*ColorMask)(struct gl_context *ctx, GLboolean rmask, GLboolean gmask, - GLboolean bmask, GLboolean amask ); - /** Cause a material color to track the current color */ - void (*ColorMaterial)(struct gl_context *ctx, GLenum face, GLenum mode); - /** Specify whether front- or back-facing facets can be culled */ - void (*CullFace)(struct gl_context *ctx, GLenum mode); - /** Define front- and back-facing polygons */ - void (*FrontFace)(struct gl_context *ctx, GLenum mode); - /** Specify the value used for depth buffer comparisons */ - void (*DepthFunc)(struct gl_context *ctx, GLenum func); - /** Enable or disable writing into the depth buffer */ - void (*DepthMask)(struct gl_context *ctx, GLboolean flag); - /** Specify mapping of depth values from NDC to window coordinates */ - void (*DepthRange)(struct gl_context *ctx); - /** Specify the current buffer for writing */ - void (*DrawBuffer)(struct gl_context *ctx); - /** Used to allocated any buffers with on-demand creation */ - void (*DrawBufferAllocate)(struct gl_context *ctx); - /** Enable or disable server-side gl capabilities */ - void (*Enable)(struct gl_context *ctx, GLenum cap, GLboolean state); - /** Specify fog parameters */ - void (*Fogfv)(struct gl_context *ctx, GLenum pname, const GLfloat *params); - /** Set light source parameters. - * Note: for GL_POSITION and GL_SPOT_DIRECTION, params will have already - * been transformed to eye-space. - */ - void (*Lightfv)(struct gl_context *ctx, GLenum light, - GLenum pname, const GLfloat *params ); - /** Set the lighting model parameters */ - void (*LightModelfv)(struct gl_context *ctx, GLenum pname, - const GLfloat *params); - /** Specify the line stipple pattern */ - void (*LineStipple)(struct gl_context *ctx, GLint factor, GLushort pattern ); - /** Specify the width of rasterized lines */ - void (*LineWidth)(struct gl_context *ctx, GLfloat width); - /** Specify a logical pixel operation for color index rendering */ - void (*LogicOpcode)(struct gl_context *ctx, enum gl_logicop_mode opcode); - void (*PointParameterfv)(struct gl_context *ctx, GLenum pname, - const GLfloat *params); - /** Specify the diameter of rasterized points */ - void (*PointSize)(struct gl_context *ctx, GLfloat size); - /** Select a polygon rasterization mode */ - void (*PolygonMode)(struct gl_context *ctx, GLenum face, GLenum mode); - /** Set the scale and units used to calculate depth values */ - void (*PolygonOffset)(struct gl_context *ctx, GLfloat factor, GLfloat units, GLfloat clamp); - /** Set the polygon stippling pattern */ - void (*PolygonStipple)(struct gl_context *ctx, const GLubyte *mask ); - /* Specifies the current buffer for reading */ - void (*ReadBuffer)( struct gl_context *ctx, GLenum buffer ); - /** Set rasterization mode */ - void (*RenderMode)(struct gl_context *ctx, GLenum mode ); - /** Define the scissor box */ - void (*Scissor)(struct gl_context *ctx); - /** Select flat or smooth shading */ - void (*ShadeModel)(struct gl_context *ctx, GLenum mode); - /** OpenGL 2.0 two-sided StencilFunc */ - void (*StencilFuncSeparate)(struct gl_context *ctx, GLenum face, GLenum func, - GLint ref, GLuint mask); - /** OpenGL 2.0 two-sided StencilMask */ - void (*StencilMaskSeparate)(struct gl_context *ctx, GLenum face, GLuint mask); - /** OpenGL 2.0 two-sided StencilOp */ - void (*StencilOpSeparate)(struct gl_context *ctx, GLenum face, GLenum fail, - GLenum zfail, GLenum zpass); - /** Control the generation of texture coordinates */ - void (*TexGen)(struct gl_context *ctx, GLenum coord, GLenum pname, - const GLfloat *params); - /** Set texture environment parameters */ - void (*TexEnv)(struct gl_context *ctx, GLenum target, GLenum pname, - const GLfloat *param); - /** Set texture parameter (callee gets param value from the texObj) */ - void (*TexParameter)(struct gl_context *ctx, - struct gl_texture_object *texObj, GLenum pname); - /** Set the viewport */ - void (*Viewport)(struct gl_context *ctx); - /*@}*/ - - - /** - * \name Vertex/pixel buffer object functions - */ - /*@{*/ - struct gl_buffer_object * (*NewBufferObject)(struct gl_context *ctx, - GLuint buffer); - - void (*DeleteBuffer)( struct gl_context *ctx, struct gl_buffer_object *obj ); - - GLboolean (*BufferData)(struct gl_context *ctx, GLenum target, - GLsizeiptrARB size, const GLvoid *data, GLenum usage, - GLenum storageFlags, struct gl_buffer_object *obj); - - void (*BufferSubData)( struct gl_context *ctx, GLintptrARB offset, - GLsizeiptrARB size, const GLvoid *data, - struct gl_buffer_object *obj ); - - void (*GetBufferSubData)( struct gl_context *ctx, - GLintptrARB offset, GLsizeiptrARB size, - GLvoid *data, struct gl_buffer_object *obj ); - - void (*ClearBufferSubData)( struct gl_context *ctx, - GLintptr offset, GLsizeiptr size, - const GLvoid *clearValue, - GLsizeiptr clearValueSize, - struct gl_buffer_object *obj ); - - void (*CopyBufferSubData)( struct gl_context *ctx, - struct gl_buffer_object *src, - struct gl_buffer_object *dst, - GLintptr readOffset, GLintptr writeOffset, - GLsizeiptr size ); - - void (*InvalidateBufferSubData)( struct gl_context *ctx, - struct gl_buffer_object *obj, - GLintptr offset, - GLsizeiptr length ); - - /* Returns pointer to the start of the mapped range. - * May return NULL if MESA_MAP_NOWAIT_BIT is set in access: - */ - void * (*MapBufferRange)( struct gl_context *ctx, GLintptr offset, - GLsizeiptr length, GLbitfield access, - struct gl_buffer_object *obj, - gl_map_buffer_index index); - - void (*FlushMappedBufferRange)(struct gl_context *ctx, - GLintptr offset, GLsizeiptr length, - struct gl_buffer_object *obj, - gl_map_buffer_index index); - - GLboolean (*UnmapBuffer)( struct gl_context *ctx, - struct gl_buffer_object *obj, - gl_map_buffer_index index); - /*@}*/ - - /** - * \name Functions for GL_APPLE_object_purgeable - */ - /*@{*/ - /* variations on ObjectPurgeable */ - GLenum (*BufferObjectPurgeable)(struct gl_context *ctx, - struct gl_buffer_object *obj, GLenum option); - GLenum (*RenderObjectPurgeable)(struct gl_context *ctx, - struct gl_renderbuffer *obj, GLenum option); - GLenum (*TextureObjectPurgeable)(struct gl_context *ctx, - struct gl_texture_object *obj, - GLenum option); - - /* variations on ObjectUnpurgeable */ - GLenum (*BufferObjectUnpurgeable)(struct gl_context *ctx, - struct gl_buffer_object *obj, - GLenum option); - GLenum (*RenderObjectUnpurgeable)(struct gl_context *ctx, - struct gl_renderbuffer *obj, - GLenum option); - GLenum (*TextureObjectUnpurgeable)(struct gl_context *ctx, - struct gl_texture_object *obj, - GLenum option); - /*@}*/ - - /** - * \name Functions for GL_EXT_framebuffer_{object,blit,discard}. - */ - /*@{*/ - struct gl_framebuffer * (*NewFramebuffer)(struct gl_context *ctx, - GLuint name); - struct gl_renderbuffer * (*NewRenderbuffer)(struct gl_context *ctx, - GLuint name); - void (*BindFramebuffer)(struct gl_context *ctx, GLenum target, - struct gl_framebuffer *drawFb, - struct gl_framebuffer *readFb); - void (*FramebufferRenderbuffer)(struct gl_context *ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_renderbuffer *rb); - void (*RenderTexture)(struct gl_context *ctx, - struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att); - void (*FinishRenderTexture)(struct gl_context *ctx, - struct gl_renderbuffer *rb); - void (*ValidateFramebuffer)(struct gl_context *ctx, - struct gl_framebuffer *fb); - /*@}*/ - void (*BlitFramebuffer)(struct gl_context *ctx, - struct gl_framebuffer *readFb, - struct gl_framebuffer *drawFb, - GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, - GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, - GLbitfield mask, GLenum filter); - void (*DiscardFramebuffer)(struct gl_context *ctx, struct gl_framebuffer *fb, - struct gl_renderbuffer_attachment *att); - - /** - * \name Functions for GL_ARB_sample_locations - */ - void (*GetProgrammableSampleCaps)(struct gl_context *ctx, - const struct gl_framebuffer *fb, - GLuint *bits, GLuint *width, GLuint *height); - void (*EvaluateDepthValues)(struct gl_context *ctx); - - /** - * \name Query objects - */ - /*@{*/ - struct gl_query_object * (*NewQueryObject)(struct gl_context *ctx, GLuint id); - void (*DeleteQuery)(struct gl_context *ctx, struct gl_query_object *q); - void (*BeginQuery)(struct gl_context *ctx, struct gl_query_object *q); - void (*QueryCounter)(struct gl_context *ctx, struct gl_query_object *q); - void (*EndQuery)(struct gl_context *ctx, struct gl_query_object *q); - void (*CheckQuery)(struct gl_context *ctx, struct gl_query_object *q); - void (*WaitQuery)(struct gl_context *ctx, struct gl_query_object *q); - /* - * \pname the value requested to be written (GL_QUERY_RESULT, etc) - * \ptype the type of the value requested to be written: - * GL_UNSIGNED_INT, GL_UNSIGNED_INT64_ARB, - * GL_INT, GL_INT64_ARB - */ - void (*StoreQueryResult)(struct gl_context *ctx, struct gl_query_object *q, - struct gl_buffer_object *buf, intptr_t offset, - GLenum pname, GLenum ptype); - /*@}*/ - - /** - * \name Performance monitors - */ - /*@{*/ - void (*InitPerfMonitorGroups)(struct gl_context *ctx); - struct gl_perf_monitor_object * (*NewPerfMonitor)(struct gl_context *ctx); - void (*DeletePerfMonitor)(struct gl_context *ctx, - struct gl_perf_monitor_object *m); - GLboolean (*BeginPerfMonitor)(struct gl_context *ctx, - struct gl_perf_monitor_object *m); - - /** Stop an active performance monitor, discarding results. */ - void (*ResetPerfMonitor)(struct gl_context *ctx, - struct gl_perf_monitor_object *m); - void (*EndPerfMonitor)(struct gl_context *ctx, - struct gl_perf_monitor_object *m); - GLboolean (*IsPerfMonitorResultAvailable)(struct gl_context *ctx, - struct gl_perf_monitor_object *m); - void (*GetPerfMonitorResult)(struct gl_context *ctx, - struct gl_perf_monitor_object *m, - GLsizei dataSize, - GLuint *data, - GLint *bytesWritten); - /*@}*/ - - /** - * \name Performance Query objects - */ - /*@{*/ - unsigned (*InitPerfQueryInfo)(struct gl_context *ctx); - void (*GetPerfQueryInfo)(struct gl_context *ctx, - unsigned queryIndex, - const char **name, - GLuint *dataSize, - GLuint *numCounters, - GLuint *numActive); - void (*GetPerfCounterInfo)(struct gl_context *ctx, - unsigned queryIndex, - unsigned counterIndex, - const char **name, - const char **desc, - GLuint *offset, - GLuint *data_size, - GLuint *type_enum, - GLuint *data_type_enum, - GLuint64 *raw_max); - struct gl_perf_query_object * (*NewPerfQueryObject)(struct gl_context *ctx, - unsigned queryIndex); - void (*DeletePerfQuery)(struct gl_context *ctx, - struct gl_perf_query_object *obj); - bool (*BeginPerfQuery)(struct gl_context *ctx, - struct gl_perf_query_object *obj); - void (*EndPerfQuery)(struct gl_context *ctx, - struct gl_perf_query_object *obj); - void (*WaitPerfQuery)(struct gl_context *ctx, - struct gl_perf_query_object *obj); - bool (*IsPerfQueryReady)(struct gl_context *ctx, - struct gl_perf_query_object *obj); - bool (*GetPerfQueryData)(struct gl_context *ctx, - struct gl_perf_query_object *obj, - GLsizei dataSize, - GLuint *data, - GLuint *bytesWritten); - /*@}*/ - - - /** - * \name GREMEDY debug/marker functions - */ - /*@{*/ - void (*EmitStringMarker)(struct gl_context *ctx, const GLchar *string, GLsizei len); + struct pipe_draw_info *info, + const struct pipe_draw_start_count_bias *draws, + const unsigned char *mode, + unsigned num_draws); /*@}*/ /** @@ -1000,126 +206,9 @@ struct dd_function_table { /** Need to call vbo_save_SaveFlushVertices() upon state change? */ GLboolean SaveNeedFlush; - /** - * Notify driver that the special derived value _NeedEyeCoords has - * changed. - */ - void (*LightingSpaceChange)( struct gl_context *ctx ); - /**@}*/ /** - * \name GL_ARB_sync interfaces - */ - /*@{*/ - struct gl_sync_object * (*NewSyncObject)(struct gl_context *); - void (*FenceSync)(struct gl_context *, struct gl_sync_object *, - GLenum, GLbitfield); - void (*DeleteSyncObject)(struct gl_context *, struct gl_sync_object *); - void (*CheckSync)(struct gl_context *, struct gl_sync_object *); - void (*ClientWaitSync)(struct gl_context *, struct gl_sync_object *, - GLbitfield, GLuint64); - void (*ServerWaitSync)(struct gl_context *, struct gl_sync_object *, - GLbitfield, GLuint64); - /*@}*/ - - /** GL_NV_conditional_render */ - void (*BeginConditionalRender)(struct gl_context *ctx, - struct gl_query_object *q, - GLenum mode); - void (*EndConditionalRender)(struct gl_context *ctx, - struct gl_query_object *q); - - /** - * \name GL_OES_draw_texture interface - */ - /*@{*/ - void (*DrawTex)(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, - GLfloat width, GLfloat height); - /*@}*/ - - /** - * \name GL_OES_EGL_image interface - */ - void (*EGLImageTargetTexture2D)(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - GLeglImageOES image_handle); - void (*EGLImageTargetRenderbufferStorage)(struct gl_context *ctx, - struct gl_renderbuffer *rb, - void *image_handle); - - /** - * \name GL_EXT_EGL_image_storage interface - */ - void (*EGLImageTargetTexStorage)(struct gl_context *ctx, GLenum target, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - GLeglImageOES image_handle); - /** - * \name GL_EXT_transform_feedback interface - */ - struct gl_transform_feedback_object * - (*NewTransformFeedback)(struct gl_context *ctx, GLuint name); - void (*DeleteTransformFeedback)(struct gl_context *ctx, - struct gl_transform_feedback_object *obj); - void (*BeginTransformFeedback)(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj); - void (*EndTransformFeedback)(struct gl_context *ctx, - struct gl_transform_feedback_object *obj); - void (*PauseTransformFeedback)(struct gl_context *ctx, - struct gl_transform_feedback_object *obj); - void (*ResumeTransformFeedback)(struct gl_context *ctx, - struct gl_transform_feedback_object *obj); - - /** - * Return the number of vertices written to a stream during the last - * Begin/EndTransformFeedback block. - */ - GLsizei (*GetTransformFeedbackVertexCount)(struct gl_context *ctx, - struct gl_transform_feedback_object *obj, - GLuint stream); - - /** - * \name GL_NV_texture_barrier interface - */ - void (*TextureBarrier)(struct gl_context *ctx); - - /** - * \name GL_ARB_sampler_objects - */ - struct gl_sampler_object * (*NewSamplerObject)(struct gl_context *ctx, - GLuint name); - - /** - * \name Return a timestamp in nanoseconds as defined by GL_ARB_timer_query. - * This should be equivalent to glGetInteger64v(GL_TIMESTAMP); - */ - uint64_t (*GetTimestamp)(struct gl_context *ctx); - - /** - * \name GL_ARB_texture_multisample - */ - void (*GetSamplePosition)(struct gl_context *ctx, - struct gl_framebuffer *fb, - GLuint index, - GLfloat *outValue); - - /** - * \name NV_vdpau_interop interface - */ - void (*VDPAUMapSurface)(struct gl_context *ctx, GLenum target, - GLenum access, GLboolean output, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - const GLvoid *vdpSurface, GLuint index); - void (*VDPAUUnmapSurface)(struct gl_context *ctx, GLenum target, - GLenum access, GLboolean output, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage, - const GLvoid *vdpSurface, GLuint index); - - /** * Query reset status for GL_ARB_robustness * * Per \c glGetGraphicsResetStatusARB, this function should return a @@ -1129,176 +218,12 @@ struct dd_function_table { GLenum (*GetGraphicsResetStatus)(struct gl_context *ctx); /** - * \name GL_ARB_shader_image_load_store interface. - */ - /** @{ */ - void (*MemoryBarrier)(struct gl_context *ctx, GLbitfield barriers); - /** @} */ - - /** - * GL_EXT_shader_framebuffer_fetch_non_coherent rendering barrier. - * - * On return from this function any framebuffer contents written by - * previous draw commands are guaranteed to be visible from subsequent - * fragment shader invocations using the - * EXT_shader_framebuffer_fetch_non_coherent interface. - */ - /** @{ */ - void (*FramebufferFetchBarrier)(struct gl_context *ctx); - /** @} */ - - /** - * \name GL_ARB_compute_shader interface - */ - /*@{*/ - void (*DispatchCompute)(struct gl_context *ctx, const GLuint *num_groups); - void (*DispatchComputeIndirect)(struct gl_context *ctx, GLintptr indirect); - /*@}*/ - - /** - * \name GL_ARB_compute_variable_group_size interface - */ - /*@{*/ - void (*DispatchComputeGroupSize)(struct gl_context *ctx, - const GLuint *num_groups, - const GLuint *group_size); - /*@}*/ - - /** - * Query information about memory. Device memory is e.g. VRAM. Staging - * memory is e.g. GART. All sizes are in kilobytes. - */ - void (*QueryMemoryInfo)(struct gl_context *ctx, - struct gl_memory_info *info); - - /** - * Indicate that this thread is being used by Mesa as a background drawing - * thread for the given GL context. - * - * If this function is called more than once from any given thread, each - * subsequent call overrides the context that was passed in the previous - * call. Mesa takes advantage of this to re-use a background thread to - * perform drawing on behalf of multiple contexts. - * - * Mesa may sometimes call this function from a non-background thread - * (i.e. a thread that has already been bound to a context using - * __DriverAPIRec::MakeCurrent()); when this happens, ctx will be equal to - * the context that is bound to this thread. - * - * Mesa will only call this function if GL multithreading is enabled. - */ - void (*SetBackgroundContext)(struct gl_context *ctx, - struct util_queue_monitoring *queue_info); - - /** - * \name GL_ARB_sparse_buffer interface - */ - /*@{*/ - void (*BufferPageCommitment)(struct gl_context *ctx, - struct gl_buffer_object *bufferObj, - GLintptr offset, GLsizeiptr size, - GLboolean commit); - /*@}*/ - - /** - * \name GL_ARB_bindless_texture interface - */ - /*@{*/ - GLuint64 (*NewTextureHandle)(struct gl_context *ctx, - struct gl_texture_object *texObj, - struct gl_sampler_object *sampObj); - void (*DeleteTextureHandle)(struct gl_context *ctx, GLuint64 handle); - void (*MakeTextureHandleResident)(struct gl_context *ctx, GLuint64 handle, - bool resident); - GLuint64 (*NewImageHandle)(struct gl_context *ctx, - struct gl_image_unit *imgObj); - void (*DeleteImageHandle)(struct gl_context *ctx, GLuint64 handle); - void (*MakeImageHandleResident)(struct gl_context *ctx, GLuint64 handle, - GLenum access, bool resident); - /*@}*/ - - - /** - * \name GL_EXT_external_objects interface - */ - /*@{*/ - /** - * Called to allocate a new memory object. Drivers will usually - * allocate/return a subclass of gl_memory_object. - */ - struct gl_memory_object * (*NewMemoryObject)(struct gl_context *ctx, - GLuint name); - /** - * Called to delete/free a memory object. Drivers should free the - * object and any image data it contains. - */ - void (*DeleteMemoryObject)(struct gl_context *ctx, - struct gl_memory_object *memObj); - - /** - * Set the given memory object as the texture's storage. - */ - GLboolean (*SetTextureStorageForMemoryObject)(struct gl_context *ctx, - struct gl_texture_object *tex_obj, - struct gl_memory_object *mem_obj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth, - GLuint64 offset); - - /** - * Use a memory object as the backing data for a buffer object - */ - GLboolean (*BufferDataMem)(struct gl_context *ctx, - GLenum target, - GLsizeiptrARB size, - struct gl_memory_object *memObj, - GLuint64 offset, - GLenum usage, - struct gl_buffer_object *bufObj); - - /** - * Fill uuid with an unique identifier for this driver - * - * uuid must point to GL_UUID_SIZE_EXT bytes of available memory - */ - void (*GetDriverUuid)(struct gl_context *ctx, char *uuid); - - /** - * Fill uuid with an unique identifier for the device associated - * to this driver - * - * uuid must point to GL_UUID_SIZE_EXT bytes of available memory - */ - void (*GetDeviceUuid)(struct gl_context *ctx, char *uuid); - - /*@}*/ - - /** - * \name GL_EXT_external_objects_fd interface - */ - /*@{*/ - /** - * Called to import a memory object. The caller relinquishes ownership - * of fd after the call returns. - * - * Accessing fd after ImportMemoryObjectFd returns results in undefined - * behaviour. This is consistent with EXT_external_object_fd. - */ - void (*ImportMemoryObjectFd)(struct gl_context *ctx, - struct gl_memory_object *memObj, - GLuint64 size, - int fd); - /*@}*/ - - /** * \name GL_ARB_get_program_binary */ /*@{*/ /** * Calls to retrieve/store a binary serialized copy of the current program. */ - void (*GetProgramBinaryDriverSHA1)(struct gl_context *ctx, uint8_t *sha1); - void (*ProgramBinarySerializeDriverBlob)(struct gl_context *ctx, struct gl_shader_program *shProg, struct gl_program *prog); @@ -1309,64 +234,6 @@ struct dd_function_table { /*@}*/ /** - * \name GL_EXT_semaphore interface - */ - /*@{*/ - /** - * Called to allocate a new semaphore object. Drivers will usually - * allocate/return a subclass of gl_semaphore_object. - */ - struct gl_semaphore_object * (*NewSemaphoreObject)(struct gl_context *ctx, - GLuint name); - /** - * Called to delete/free a semaphore object. Drivers should free the - * object and any associated resources. - */ - void (*DeleteSemaphoreObject)(struct gl_context *ctx, - struct gl_semaphore_object *semObj); - - /** - * Introduce an operation to wait for the semaphore object in the GL - * server's command stream - */ - void (*ServerWaitSemaphoreObject)(struct gl_context *ctx, - struct gl_semaphore_object *semObj, - GLuint numBufferBarriers, - struct gl_buffer_object **bufObjs, - GLuint numTextureBarriers, - struct gl_texture_object **texObjs, - const GLenum *srcLayouts); - - /** - * Introduce an operation to signal the semaphore object in the GL - * server's command stream - */ - void (*ServerSignalSemaphoreObject)(struct gl_context *ctx, - struct gl_semaphore_object *semObj, - GLuint numBufferBarriers, - struct gl_buffer_object **bufObjs, - GLuint numTextureBarriers, - struct gl_texture_object **texObjs, - const GLenum *dstLayouts); - /*@}*/ - - /** - * \name GL_EXT_semaphore_fd interface - */ - /*@{*/ - /** - * Called to import a semaphore object. The caller relinquishes ownership - * of fd after the call returns. - * - * Accessing fd after ImportSemaphoreFd returns results in undefined - * behaviour. This is consistent with EXT_semaphore_fd. - */ - void (*ImportSemaphoreFd)(struct gl_context *ctx, - struct gl_semaphore_object *semObj, - int fd); - /*@}*/ - - /** * \name Disk shader cache functions */ /*@{*/ @@ -1381,449 +248,7 @@ struct dd_function_table { struct gl_program *prog); /*@}*/ - /** - * \name Set the number of compiler threads for ARB_parallel_shader_compile - */ - void (*SetMaxShaderCompilerThreads)(struct gl_context *ctx, unsigned count); - bool (*GetShaderProgramCompletionStatus)(struct gl_context *ctx, - struct gl_shader_program *shprog); - - void (*PinDriverToL3Cache)(struct gl_context *ctx, unsigned L3_cache); + GLboolean (*ValidateEGLImage)(struct gl_context *ctx, GLeglImageOES image_handle); }; - -/** - * Per-vertex functions. - * - * These are the functions which can appear between glBegin and glEnd. - * Depending on whether we're inside or outside a glBegin/End pair - * and whether we're in immediate mode or building a display list, these - * functions behave differently. This structure allows us to switch - * between those modes more easily. - * - * Generally, these pointers point to functions in the VBO module. - */ -typedef struct { - void (GLAPIENTRYP ArrayElement)( GLint ); - void (GLAPIENTRYP Color3f)( GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP Color3fv)( const GLfloat * ); - void (GLAPIENTRYP Color4f)( GLfloat, GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP Color4fv)( const GLfloat * ); - void (GLAPIENTRYP EdgeFlag)( GLboolean ); - void (GLAPIENTRYP EvalCoord1f)( GLfloat ); - void (GLAPIENTRYP EvalCoord1fv)( const GLfloat * ); - void (GLAPIENTRYP EvalCoord2f)( GLfloat, GLfloat ); - void (GLAPIENTRYP EvalCoord2fv)( const GLfloat * ); - void (GLAPIENTRYP EvalPoint1)( GLint ); - void (GLAPIENTRYP EvalPoint2)( GLint, GLint ); - void (GLAPIENTRYP FogCoordfEXT)( GLfloat ); - void (GLAPIENTRYP FogCoordfvEXT)( const GLfloat * ); - void (GLAPIENTRYP Indexf)( GLfloat ); - void (GLAPIENTRYP Indexfv)( const GLfloat * ); - void (GLAPIENTRYP Materialfv)( GLenum face, GLenum pname, const GLfloat * ); - void (GLAPIENTRYP MultiTexCoord1fARB)( GLenum, GLfloat ); - void (GLAPIENTRYP MultiTexCoord1fvARB)( GLenum, const GLfloat * ); - void (GLAPIENTRYP MultiTexCoord2fARB)( GLenum, GLfloat, GLfloat ); - void (GLAPIENTRYP MultiTexCoord2fvARB)( GLenum, const GLfloat * ); - void (GLAPIENTRYP MultiTexCoord3fARB)( GLenum, GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP MultiTexCoord3fvARB)( GLenum, const GLfloat * ); - void (GLAPIENTRYP MultiTexCoord4fARB)( GLenum, GLfloat, GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP MultiTexCoord4fvARB)( GLenum, const GLfloat * ); - void (GLAPIENTRYP Normal3f)( GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP Normal3fv)( const GLfloat * ); - void (GLAPIENTRYP SecondaryColor3fEXT)( GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP SecondaryColor3fvEXT)( const GLfloat * ); - void (GLAPIENTRYP TexCoord1f)( GLfloat ); - void (GLAPIENTRYP TexCoord1fv)( const GLfloat * ); - void (GLAPIENTRYP TexCoord2f)( GLfloat, GLfloat ); - void (GLAPIENTRYP TexCoord2fv)( const GLfloat * ); - void (GLAPIENTRYP TexCoord3f)( GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP TexCoord3fv)( const GLfloat * ); - void (GLAPIENTRYP TexCoord4f)( GLfloat, GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP TexCoord4fv)( const GLfloat * ); - void (GLAPIENTRYP Vertex2f)( GLfloat, GLfloat ); - void (GLAPIENTRYP Vertex2fv)( const GLfloat * ); - void (GLAPIENTRYP Vertex3f)( GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP Vertex3fv)( const GLfloat * ); - void (GLAPIENTRYP Vertex4f)( GLfloat, GLfloat, GLfloat, GLfloat ); - void (GLAPIENTRYP Vertex4fv)( const GLfloat * ); - void (GLAPIENTRYP CallList)( GLuint ); - void (GLAPIENTRYP CallLists)( GLsizei, GLenum, const GLvoid * ); - void (GLAPIENTRYP Begin)( GLenum ); - void (GLAPIENTRYP End)( void ); - void (GLAPIENTRYP PrimitiveRestartNV)( void ); - /* Originally for GL_NV_vertex_program, now used only dlist.c and friends */ - void (GLAPIENTRYP VertexAttrib1fNV)( GLuint index, GLfloat x ); - void (GLAPIENTRYP VertexAttrib1fvNV)( GLuint index, const GLfloat *v ); - void (GLAPIENTRYP VertexAttrib2fNV)( GLuint index, GLfloat x, GLfloat y ); - void (GLAPIENTRYP VertexAttrib2fvNV)( GLuint index, const GLfloat *v ); - void (GLAPIENTRYP VertexAttrib3fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z ); - void (GLAPIENTRYP VertexAttrib3fvNV)( GLuint index, const GLfloat *v ); - void (GLAPIENTRYP VertexAttrib4fNV)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void (GLAPIENTRYP VertexAttrib4fvNV)( GLuint index, const GLfloat *v ); - /* GL_ARB_vertex_program */ - void (GLAPIENTRYP VertexAttrib1fARB)( GLuint index, GLfloat x ); - void (GLAPIENTRYP VertexAttrib1fvARB)( GLuint index, const GLfloat *v ); - void (GLAPIENTRYP VertexAttrib2fARB)( GLuint index, GLfloat x, GLfloat y ); - void (GLAPIENTRYP VertexAttrib2fvARB)( GLuint index, const GLfloat *v ); - void (GLAPIENTRYP VertexAttrib3fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z ); - void (GLAPIENTRYP VertexAttrib3fvARB)( GLuint index, const GLfloat *v ); - void (GLAPIENTRYP VertexAttrib4fARB)( GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w ); - void (GLAPIENTRYP VertexAttrib4fvARB)( GLuint index, const GLfloat *v ); - - /* GL_EXT_gpu_shader4 / GL 3.0 */ - void (GLAPIENTRYP VertexAttribI1i)( GLuint index, GLint x); - void (GLAPIENTRYP VertexAttribI2i)( GLuint index, GLint x, GLint y); - void (GLAPIENTRYP VertexAttribI3i)( GLuint index, GLint x, GLint y, GLint z); - void (GLAPIENTRYP VertexAttribI4i)( GLuint index, GLint x, GLint y, GLint z, GLint w); - void (GLAPIENTRYP VertexAttribI2iv)( GLuint index, const GLint *v); - void (GLAPIENTRYP VertexAttribI3iv)( GLuint index, const GLint *v); - void (GLAPIENTRYP VertexAttribI4iv)( GLuint index, const GLint *v); - - void (GLAPIENTRYP VertexAttribI1ui)( GLuint index, GLuint x); - void (GLAPIENTRYP VertexAttribI2ui)( GLuint index, GLuint x, GLuint y); - void (GLAPIENTRYP VertexAttribI3ui)( GLuint index, GLuint x, GLuint y, GLuint z); - void (GLAPIENTRYP VertexAttribI4ui)( GLuint index, GLuint x, GLuint y, GLuint z, GLuint w); - void (GLAPIENTRYP VertexAttribI2uiv)( GLuint index, const GLuint *v); - void (GLAPIENTRYP VertexAttribI3uiv)( GLuint index, const GLuint *v); - void (GLAPIENTRYP VertexAttribI4uiv)( GLuint index, const GLuint *v); - - /* GL_ARB_vertex_type_10_10_10_2_rev / GL3.3 */ - void (GLAPIENTRYP VertexP2ui)( GLenum type, GLuint value ); - void (GLAPIENTRYP VertexP2uiv)( GLenum type, const GLuint *value); - - void (GLAPIENTRYP VertexP3ui)( GLenum type, GLuint value ); - void (GLAPIENTRYP VertexP3uiv)( GLenum type, const GLuint *value); - - void (GLAPIENTRYP VertexP4ui)( GLenum type, GLuint value ); - void (GLAPIENTRYP VertexP4uiv)( GLenum type, const GLuint *value); - - void (GLAPIENTRYP TexCoordP1ui)( GLenum type, GLuint coords ); - void (GLAPIENTRYP TexCoordP1uiv)( GLenum type, const GLuint *coords ); - - void (GLAPIENTRYP TexCoordP2ui)( GLenum type, GLuint coords ); - void (GLAPIENTRYP TexCoordP2uiv)( GLenum type, const GLuint *coords ); - - void (GLAPIENTRYP TexCoordP3ui)( GLenum type, GLuint coords ); - void (GLAPIENTRYP TexCoordP3uiv)( GLenum type, const GLuint *coords ); - - void (GLAPIENTRYP TexCoordP4ui)( GLenum type, GLuint coords ); - void (GLAPIENTRYP TexCoordP4uiv)( GLenum type, const GLuint *coords ); - - void (GLAPIENTRYP MultiTexCoordP1ui)( GLenum texture, GLenum type, GLuint coords ); - void (GLAPIENTRYP MultiTexCoordP1uiv)( GLenum texture, GLenum type, const GLuint *coords ); - void (GLAPIENTRYP MultiTexCoordP2ui)( GLenum texture, GLenum type, GLuint coords ); - void (GLAPIENTRYP MultiTexCoordP2uiv)( GLenum texture, GLenum type, const GLuint *coords ); - void (GLAPIENTRYP MultiTexCoordP3ui)( GLenum texture, GLenum type, GLuint coords ); - void (GLAPIENTRYP MultiTexCoordP3uiv)( GLenum texture, GLenum type, const GLuint *coords ); - void (GLAPIENTRYP MultiTexCoordP4ui)( GLenum texture, GLenum type, GLuint coords ); - void (GLAPIENTRYP MultiTexCoordP4uiv)( GLenum texture, GLenum type, const GLuint *coords ); - - void (GLAPIENTRYP NormalP3ui)( GLenum type, GLuint coords ); - void (GLAPIENTRYP NormalP3uiv)( GLenum type, const GLuint *coords ); - - void (GLAPIENTRYP ColorP3ui)( GLenum type, GLuint color ); - void (GLAPIENTRYP ColorP3uiv)( GLenum type, const GLuint *color ); - - void (GLAPIENTRYP ColorP4ui)( GLenum type, GLuint color ); - void (GLAPIENTRYP ColorP4uiv)( GLenum type, const GLuint *color ); - - void (GLAPIENTRYP SecondaryColorP3ui)( GLenum type, GLuint color ); - void (GLAPIENTRYP SecondaryColorP3uiv)( GLenum type, const GLuint *color ); - - void (GLAPIENTRYP VertexAttribP1ui)( GLuint index, GLenum type, - GLboolean normalized, GLuint value); - void (GLAPIENTRYP VertexAttribP2ui)( GLuint index, GLenum type, - GLboolean normalized, GLuint value); - void (GLAPIENTRYP VertexAttribP3ui)( GLuint index, GLenum type, - GLboolean normalized, GLuint value); - void (GLAPIENTRYP VertexAttribP4ui)( GLuint index, GLenum type, - GLboolean normalized, GLuint value); - void (GLAPIENTRYP VertexAttribP1uiv)( GLuint index, GLenum type, - GLboolean normalized, - const GLuint *value); - void (GLAPIENTRYP VertexAttribP2uiv)( GLuint index, GLenum type, - GLboolean normalized, - const GLuint *value); - void (GLAPIENTRYP VertexAttribP3uiv)( GLuint index, GLenum type, - GLboolean normalized, - const GLuint *value); - void (GLAPIENTRYP VertexAttribP4uiv)( GLuint index, GLenum type, - GLboolean normalized, - const GLuint *value); - - /* GL_ARB_vertex_attrib_64bit / GL 4.1 */ - void (GLAPIENTRYP VertexAttribL1d)( GLuint index, GLdouble x); - void (GLAPIENTRYP VertexAttribL2d)( GLuint index, GLdouble x, GLdouble y); - void (GLAPIENTRYP VertexAttribL3d)( GLuint index, GLdouble x, GLdouble y, GLdouble z); - void (GLAPIENTRYP VertexAttribL4d)( GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w); - - - void (GLAPIENTRYP VertexAttribL1dv)( GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttribL2dv)( GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttribL3dv)( GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttribL4dv)( GLuint index, const GLdouble *v); - - void (GLAPIENTRYP VertexAttribL1ui64ARB)( GLuint index, GLuint64EXT x); - void (GLAPIENTRYP VertexAttribL1ui64vARB)( GLuint index, const GLuint64EXT *v); - - /* GL_NV_half_float */ - void (GLAPIENTRYP Vertex2hNV)( GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP Vertex2hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP Vertex3hNV)( GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP Vertex3hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP Vertex4hNV)( GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP Vertex4hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP Normal3hNV)( GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP Normal3hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP Color3hNV)( GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP Color3hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP Color4hNV)( GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP Color4hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP TexCoord1hNV)( GLhalfNV ); - void (GLAPIENTRYP TexCoord1hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP TexCoord2hNV)( GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP TexCoord2hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP TexCoord3hNV)( GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP TexCoord3hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP TexCoord4hNV)( GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP TexCoord4hvNV)( const GLhalfNV * ); - void (GLAPIENTRYP MultiTexCoord1hNV)( GLenum, GLhalfNV ); - void (GLAPIENTRYP MultiTexCoord1hvNV)( GLenum, const GLhalfNV * ); - void (GLAPIENTRYP MultiTexCoord2hNV)( GLenum, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP MultiTexCoord2hvNV)( GLenum, const GLhalfNV * ); - void (GLAPIENTRYP MultiTexCoord3hNV)( GLenum, GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP MultiTexCoord3hvNV)( GLenum, const GLhalfNV * ); - void (GLAPIENTRYP MultiTexCoord4hNV)( GLenum, GLhalfNV, GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP MultiTexCoord4hvNV)( GLenum, const GLhalfNV * ); - void (GLAPIENTRYP VertexAttrib1hNV)( GLuint index, GLhalfNV x ); - void (GLAPIENTRYP VertexAttrib1hvNV)( GLuint index, const GLhalfNV *v ); - void (GLAPIENTRYP VertexAttrib2hNV)( GLuint index, GLhalfNV x, GLhalfNV y ); - void (GLAPIENTRYP VertexAttrib2hvNV)( GLuint index, const GLhalfNV *v ); - void (GLAPIENTRYP VertexAttrib3hNV)( GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z ); - void (GLAPIENTRYP VertexAttrib3hvNV)( GLuint index, const GLhalfNV *v ); - void (GLAPIENTRYP VertexAttrib4hNV)( GLuint index, GLhalfNV x, GLhalfNV y, GLhalfNV z, GLhalfNV w ); - void (GLAPIENTRYP VertexAttrib4hvNV)( GLuint index, const GLhalfNV *v ); - void (GLAPIENTRYP VertexAttribs1hvNV)(GLuint index, GLsizei n, const GLhalfNV *v); - void (GLAPIENTRYP VertexAttribs2hvNV)(GLuint index, GLsizei n, const GLhalfNV *v); - void (GLAPIENTRYP VertexAttribs3hvNV)(GLuint index, GLsizei n, const GLhalfNV *v); - void (GLAPIENTRYP VertexAttribs4hvNV)(GLuint index, GLsizei n, const GLhalfNV *v); - void (GLAPIENTRYP FogCoordhNV)( GLhalfNV ); - void (GLAPIENTRYP FogCoordhvNV)( const GLhalfNV * ); - void (GLAPIENTRYP SecondaryColor3hNV)( GLhalfNV, GLhalfNV, GLhalfNV ); - void (GLAPIENTRYP SecondaryColor3hvNV)( const GLhalfNV * ); - - void (GLAPIENTRYP Color3b)( GLbyte red, GLbyte green, GLbyte blue ); - void (GLAPIENTRYP Color3d)( GLdouble red, GLdouble green, GLdouble blue ); - void (GLAPIENTRYP Color3i)( GLint red, GLint green, GLint blue ); - void (GLAPIENTRYP Color3s)( GLshort red, GLshort green, GLshort blue ); - void (GLAPIENTRYP Color3ui)( GLuint red, GLuint green, GLuint blue ); - void (GLAPIENTRYP Color3us)( GLushort red, GLushort green, GLushort blue ); - void (GLAPIENTRYP Color3ub)( GLubyte red, GLubyte green, GLubyte blue ); - void (GLAPIENTRYP Color3bv)( const GLbyte *v ); - void (GLAPIENTRYP Color3dv)( const GLdouble *v ); - void (GLAPIENTRYP Color3iv)( const GLint *v ); - void (GLAPIENTRYP Color3sv)( const GLshort *v ); - void (GLAPIENTRYP Color3uiv)( const GLuint *v ); - void (GLAPIENTRYP Color3usv)( const GLushort *v ); - void (GLAPIENTRYP Color3ubv)( const GLubyte *v ); - void (GLAPIENTRYP Color4b)( GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha ); - void (GLAPIENTRYP Color4d)( GLdouble red, GLdouble green, GLdouble blue, - GLdouble alpha ); - void (GLAPIENTRYP Color4i)( GLint red, GLint green, GLint blue, GLint alpha ); - void (GLAPIENTRYP Color4s)( GLshort red, GLshort green, GLshort blue, - GLshort alpha ); - void (GLAPIENTRYP Color4ui)( GLuint red, GLuint green, GLuint blue, GLuint alpha ); - void (GLAPIENTRYP Color4us)( GLushort red, GLushort green, GLushort blue, - GLushort alpha ); - void (GLAPIENTRYP Color4ub)( GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha ); - void (GLAPIENTRYP Color4iv)( const GLint *v ); - void (GLAPIENTRYP Color4bv)( const GLbyte *v ); - void (GLAPIENTRYP Color4dv)( const GLdouble *v ); - void (GLAPIENTRYP Color4sv)( const GLshort *v); - void (GLAPIENTRYP Color4uiv)( const GLuint *v); - void (GLAPIENTRYP Color4usv)( const GLushort *v); - void (GLAPIENTRYP Color4ubv)( const GLubyte *v); - void (GLAPIENTRYP FogCoordd)( GLdouble d ); - void (GLAPIENTRYP FogCoorddv)( const GLdouble *v ); - void (GLAPIENTRYP Indexd)( GLdouble c ); - void (GLAPIENTRYP Indexi)( GLint c ); - void (GLAPIENTRYP Indexs)( GLshort c ); - void (GLAPIENTRYP Indexub)( GLubyte c ); - void (GLAPIENTRYP Indexdv)( const GLdouble *c ); - void (GLAPIENTRYP Indexiv)( const GLint *c ); - void (GLAPIENTRYP Indexsv)( const GLshort *c ); - void (GLAPIENTRYP Indexubv)( const GLubyte *c ); - void (GLAPIENTRYP EdgeFlagv)(const GLboolean *flag); - void (GLAPIENTRYP Normal3b)( GLbyte nx, GLbyte ny, GLbyte nz ); - void (GLAPIENTRYP Normal3d)( GLdouble nx, GLdouble ny, GLdouble nz ); - void (GLAPIENTRYP Normal3i)( GLint nx, GLint ny, GLint nz ); - void (GLAPIENTRYP Normal3s)( GLshort nx, GLshort ny, GLshort nz ); - void (GLAPIENTRYP Normal3bv)( const GLbyte *v ); - void (GLAPIENTRYP Normal3dv)( const GLdouble *v ); - void (GLAPIENTRYP Normal3iv)( const GLint *v ); - void (GLAPIENTRYP Normal3sv)( const GLshort *v ); - void (GLAPIENTRYP TexCoord1d)( GLdouble s ); - void (GLAPIENTRYP TexCoord1i)( GLint s ); - void (GLAPIENTRYP TexCoord1s)( GLshort s ); - void (GLAPIENTRYP TexCoord2d)( GLdouble s, GLdouble t ); - void (GLAPIENTRYP TexCoord2s)( GLshort s, GLshort t ); - void (GLAPIENTRYP TexCoord2i)( GLint s, GLint t ); - void (GLAPIENTRYP TexCoord3d)( GLdouble s, GLdouble t, GLdouble r ); - void (GLAPIENTRYP TexCoord3i)( GLint s, GLint t, GLint r ); - void (GLAPIENTRYP TexCoord3s)( GLshort s, GLshort t, GLshort r ); - void (GLAPIENTRYP TexCoord4d)( GLdouble s, GLdouble t, GLdouble r, GLdouble q ); - void (GLAPIENTRYP TexCoord4i)( GLint s, GLint t, GLint r, GLint q ); - void (GLAPIENTRYP TexCoord4s)( GLshort s, GLshort t, GLshort r, GLshort q ); - void (GLAPIENTRYP TexCoord1dv)( const GLdouble *v ); - void (GLAPIENTRYP TexCoord1iv)( const GLint *v ); - void (GLAPIENTRYP TexCoord1sv)( const GLshort *v ); - void (GLAPIENTRYP TexCoord2dv)( const GLdouble *v ); - void (GLAPIENTRYP TexCoord2iv)( const GLint *v ); - void (GLAPIENTRYP TexCoord2sv)( const GLshort *v ); - void (GLAPIENTRYP TexCoord3dv)( const GLdouble *v ); - void (GLAPIENTRYP TexCoord3iv)( const GLint *v ); - void (GLAPIENTRYP TexCoord3sv)( const GLshort *v ); - void (GLAPIENTRYP TexCoord4dv)( const GLdouble *v ); - void (GLAPIENTRYP TexCoord4iv)( const GLint *v ); - void (GLAPIENTRYP TexCoord4sv)( const GLshort *v ); - void (GLAPIENTRYP Vertex2d)( GLdouble x, GLdouble y ); - void (GLAPIENTRYP Vertex2i)( GLint x, GLint y ); - void (GLAPIENTRYP Vertex2s)( GLshort x, GLshort y ); - void (GLAPIENTRYP Vertex3d)( GLdouble x, GLdouble y, GLdouble z ); - void (GLAPIENTRYP Vertex3i)( GLint x, GLint y, GLint z ); - void (GLAPIENTRYP Vertex3s)( GLshort x, GLshort y, GLshort z ); - void (GLAPIENTRYP Vertex4d)( GLdouble x, GLdouble y, GLdouble z, GLdouble w ); - void (GLAPIENTRYP Vertex4i)( GLint x, GLint y, GLint z, GLint w ); - void (GLAPIENTRYP Vertex4s)( GLshort x, GLshort y, GLshort z, GLshort w ); - void (GLAPIENTRYP Vertex2dv)( const GLdouble *v ); - void (GLAPIENTRYP Vertex2iv)( const GLint *v ); - void (GLAPIENTRYP Vertex2sv)( const GLshort *v ); - void (GLAPIENTRYP Vertex3dv)( const GLdouble *v ); - void (GLAPIENTRYP Vertex3iv)( const GLint *v ); - void (GLAPIENTRYP Vertex3sv)( const GLshort *v ); - void (GLAPIENTRYP Vertex4dv)( const GLdouble *v ); - void (GLAPIENTRYP Vertex4iv)( const GLint *v ); - void (GLAPIENTRYP Vertex4sv)( const GLshort *v ); - void (GLAPIENTRYP MultiTexCoord1d)(GLenum target, GLdouble s); - void (GLAPIENTRYP MultiTexCoord1dv)(GLenum target, const GLdouble *v); - void (GLAPIENTRYP MultiTexCoord1i)(GLenum target, GLint s); - void (GLAPIENTRYP MultiTexCoord1iv)(GLenum target, const GLint *v); - void (GLAPIENTRYP MultiTexCoord1s)(GLenum target, GLshort s); - void (GLAPIENTRYP MultiTexCoord1sv)(GLenum target, const GLshort *v); - void (GLAPIENTRYP MultiTexCoord2d)(GLenum target, GLdouble s, GLdouble t); - void (GLAPIENTRYP MultiTexCoord2dv)(GLenum target, const GLdouble *v); - void (GLAPIENTRYP MultiTexCoord2i)(GLenum target, GLint s, GLint t); - void (GLAPIENTRYP MultiTexCoord2iv)(GLenum target, const GLint *v); - void (GLAPIENTRYP MultiTexCoord2s)(GLenum target, GLshort s, GLshort t); - void (GLAPIENTRYP MultiTexCoord2sv)(GLenum target, const GLshort *v); - void (GLAPIENTRYP MultiTexCoord3d)(GLenum target, GLdouble s, GLdouble t, GLdouble r); - void (GLAPIENTRYP MultiTexCoord3dv)(GLenum target, const GLdouble *v); - void (GLAPIENTRYP MultiTexCoord3i)(GLenum target, GLint s, GLint t, GLint r); - void (GLAPIENTRYP MultiTexCoord3iv)(GLenum target, const GLint *v); - void (GLAPIENTRYP MultiTexCoord3s)(GLenum target, GLshort s, GLshort t, GLshort r); - void (GLAPIENTRYP MultiTexCoord3sv)(GLenum target, const GLshort *v); - void (GLAPIENTRYP MultiTexCoord4d)(GLenum target, GLdouble s, GLdouble t, GLdouble r, - GLdouble q); - void (GLAPIENTRYP MultiTexCoord4dv)(GLenum target, const GLdouble *v); - void (GLAPIENTRYP MultiTexCoord4i)(GLenum target, GLint s, GLint t, GLint r, GLint q); - void (GLAPIENTRYP MultiTexCoord4iv)(GLenum target, const GLint *v); - void (GLAPIENTRYP MultiTexCoord4s)(GLenum target, GLshort s, GLshort t, GLshort r, - GLshort q); - void (GLAPIENTRYP MultiTexCoord4sv)(GLenum target, const GLshort *v); - void (GLAPIENTRYP EvalCoord2dv)( const GLdouble *u ); - void (GLAPIENTRYP EvalCoord2d)( GLdouble u, GLdouble v ); - void (GLAPIENTRYP EvalCoord1dv)( const GLdouble *u ); - void (GLAPIENTRYP EvalCoord1d)( GLdouble u ); - void (GLAPIENTRYP Materialf)( GLenum face, GLenum pname, GLfloat param ); - void (GLAPIENTRYP Materiali)(GLenum face, GLenum pname, GLint param ); - void (GLAPIENTRYP Materialiv)(GLenum face, GLenum pname, const GLint *params ); - void (GLAPIENTRYP SecondaryColor3b)( GLbyte red, GLbyte green, GLbyte blue ); - void (GLAPIENTRYP SecondaryColor3d)( GLdouble red, GLdouble green, GLdouble blue ); - void (GLAPIENTRYP SecondaryColor3i)( GLint red, GLint green, GLint blue ); - void (GLAPIENTRYP SecondaryColor3s)( GLshort red, GLshort green, GLshort blue ); - void (GLAPIENTRYP SecondaryColor3ui)( GLuint red, GLuint green, GLuint blue ); - void (GLAPIENTRYP SecondaryColor3us)( GLushort red, GLushort green, GLushort blue ); - void (GLAPIENTRYP SecondaryColor3ub)( GLubyte red, GLubyte green, GLubyte blue ); - void (GLAPIENTRYP SecondaryColor3bv)( const GLbyte *v ); - void (GLAPIENTRYP SecondaryColor3dv)( const GLdouble *v ); - void (GLAPIENTRYP SecondaryColor3iv)( const GLint *v ); - void (GLAPIENTRYP SecondaryColor3sv)( const GLshort *v ); - void (GLAPIENTRYP SecondaryColor3uiv)( const GLuint *v ); - void (GLAPIENTRYP SecondaryColor3usv)( const GLushort *v ); - void (GLAPIENTRYP SecondaryColor3ubv)( const GLubyte *v ); - void (GLAPIENTRYP VertexAttrib1sNV)(GLuint index, GLshort x); - void (GLAPIENTRYP VertexAttrib1dNV)(GLuint index, GLdouble x); - void (GLAPIENTRYP VertexAttrib2sNV)(GLuint index, GLshort x, GLshort y); - void (GLAPIENTRYP VertexAttrib2dNV)(GLuint index, GLdouble x, GLdouble y); - void (GLAPIENTRYP VertexAttrib3sNV)(GLuint index, GLshort x, GLshort y, GLshort z); - void (GLAPIENTRYP VertexAttrib3dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z); - void (GLAPIENTRYP VertexAttrib4sNV)(GLuint index, GLshort x, GLshort y, GLshort z, - GLshort w); - void (GLAPIENTRYP VertexAttrib4dNV)(GLuint index, GLdouble x, GLdouble y, GLdouble z, - GLdouble w); - void (GLAPIENTRYP VertexAttrib4ubNV)(GLuint index, GLubyte x, GLubyte y, GLubyte z, - GLubyte w); - void (GLAPIENTRYP VertexAttrib1svNV)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib1dvNV)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib2svNV)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib2dvNV)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib3svNV)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib3dvNV)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib4svNV)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib4dvNV)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib4ubvNV)(GLuint index, const GLubyte *v); - void (GLAPIENTRYP VertexAttribs1svNV)(GLuint index, GLsizei n, const GLshort *v); - void (GLAPIENTRYP VertexAttribs1fvNV)(GLuint index, GLsizei n, const GLfloat *v); - void (GLAPIENTRYP VertexAttribs1dvNV)(GLuint index, GLsizei n, const GLdouble *v); - void (GLAPIENTRYP VertexAttribs2svNV)(GLuint index, GLsizei n, const GLshort *v); - void (GLAPIENTRYP VertexAttribs2fvNV)(GLuint index, GLsizei n, const GLfloat *v); - void (GLAPIENTRYP VertexAttribs2dvNV)(GLuint index, GLsizei n, const GLdouble *v); - void (GLAPIENTRYP VertexAttribs3svNV)(GLuint index, GLsizei n, const GLshort *v); - void (GLAPIENTRYP VertexAttribs3fvNV)(GLuint index, GLsizei n, const GLfloat *v); - void (GLAPIENTRYP VertexAttribs3dvNV)(GLuint index, GLsizei n, const GLdouble *v); - void (GLAPIENTRYP VertexAttribs4svNV)(GLuint index, GLsizei n, const GLshort *v); - void (GLAPIENTRYP VertexAttribs4fvNV)(GLuint index, GLsizei n, const GLfloat *v); - void (GLAPIENTRYP VertexAttribs4dvNV)(GLuint index, GLsizei n, const GLdouble *v); - void (GLAPIENTRYP VertexAttribs4ubvNV)(GLuint index, GLsizei n, const GLubyte *v); - void (GLAPIENTRYP VertexAttrib1s)(GLuint index, GLshort x); - void (GLAPIENTRYP VertexAttrib1d)(GLuint index, GLdouble x); - void (GLAPIENTRYP VertexAttrib2s)(GLuint index, GLshort x, GLshort y); - void (GLAPIENTRYP VertexAttrib2d)(GLuint index, GLdouble x, GLdouble y); - void (GLAPIENTRYP VertexAttrib3s)(GLuint index, GLshort x, GLshort y, GLshort z); - void (GLAPIENTRYP VertexAttrib3d)(GLuint index, GLdouble x, GLdouble y, GLdouble z); - void (GLAPIENTRYP VertexAttrib4s)(GLuint index, GLshort x, GLshort y, GLshort z, - GLshort w); - void (GLAPIENTRYP VertexAttrib4d)(GLuint index, GLdouble x, GLdouble y, GLdouble z, - GLdouble w); - void (GLAPIENTRYP VertexAttrib1sv)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib1dv)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib2sv)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib2dv)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib3sv)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib3dv)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib4sv)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttrib4dv)(GLuint index, const GLdouble *v); - void (GLAPIENTRYP VertexAttrib4bv)(GLuint index, const GLbyte * v); - void (GLAPIENTRYP VertexAttrib4iv)(GLuint index, const GLint * v); - void (GLAPIENTRYP VertexAttrib4ubv)(GLuint index, const GLubyte * v); - void (GLAPIENTRYP VertexAttrib4usv)(GLuint index, const GLushort * v); - void (GLAPIENTRYP VertexAttrib4uiv)(GLuint index, const GLuint * v); - void (GLAPIENTRYP VertexAttrib4Nbv)(GLuint index, const GLbyte * v); - void (GLAPIENTRYP VertexAttrib4Nsv)(GLuint index, const GLshort * v); - void (GLAPIENTRYP VertexAttrib4Niv)(GLuint index, const GLint * v); - void (GLAPIENTRYP VertexAttrib4Nub)(GLuint index, GLubyte x, GLubyte y, GLubyte z, - GLubyte w); - void (GLAPIENTRYP VertexAttrib4Nubv)(GLuint index, const GLubyte * v); - void (GLAPIENTRYP VertexAttrib4Nusv)(GLuint index, const GLushort * v); - void (GLAPIENTRYP VertexAttrib4Nuiv)(GLuint index, const GLuint * v); - void (GLAPIENTRYP VertexAttribI1iv)(GLuint index, const GLint *v); - void (GLAPIENTRYP VertexAttribI1uiv)(GLuint index, const GLuint *v); - void (GLAPIENTRYP VertexAttribI4bv)(GLuint index, const GLbyte *v); - void (GLAPIENTRYP VertexAttribI4sv)(GLuint index, const GLshort *v); - void (GLAPIENTRYP VertexAttribI4ubv)(GLuint index, const GLubyte *v); - void (GLAPIENTRYP VertexAttribI4usv)(GLuint index, const GLushort *v); -} GLvertexformat; - - #endif /* DD_INCLUDED */ diff --git a/src/mesa/main/debug.c b/src/mesa/main/debug.c index 28b81fb9447..e81bcd7b6a9 100644 --- a/src/mesa/main/debug.c +++ b/src/mesa/main/debug.c @@ -37,7 +37,10 @@ #include "pixelstore.h" #include "readpix.h" #include "texobj.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_cb_readpixels.h" static const char * tex_target_name(GLenum tgt) @@ -278,9 +281,9 @@ write_texture_image(struct gl_texture_object *texObj, store = ctx->Pack; /* save */ ctx->Pack = ctx->DefaultPacking; - ctx->Driver.GetTexSubImage(ctx, - 0, 0, 0, img->Width, img->Height, img->Depth, - GL_RGBA, GL_UNSIGNED_BYTE, buffer, img); + st_GetTexSubImage(ctx, + 0, 0, 0, img->Width, img->Height, img->Depth, + GL_RGBA, GL_UNSIGNED_BYTE, buffer, img); /* make filename */ snprintf(s, sizeof(s), "/tmp/tex%u.l%u.f%u.ppm", texObj->Name, level, face); @@ -325,8 +328,8 @@ _mesa_write_renderbuffer_image(const struct gl_renderbuffer *rb) buffer = malloc(rb->Width * rb->Height * 4); - ctx->Driver.ReadPixels(ctx, 0, 0, rb->Width, rb->Height, - format, type, &ctx->DefaultPacking, buffer); + st_ReadPixels(ctx, 0, 0, rb->Width, rb->Height, + format, type, &ctx->DefaultPacking, buffer); /* make filename */ snprintf(s, sizeof(s), "/tmp/renderbuffer%u.ppm", rb->Name); @@ -409,7 +412,7 @@ _mesa_dump_textures(GLuint writeImages) { GET_CURRENT_CONTEXT(ctx); WriteImages = writeImages; - _mesa_HashWalk(ctx->Shared->TexObjects, dump_texture_cb, ctx); + _mesa_HashWalk(&ctx->Shared->TexObjects, dump_texture_cb, ctx); } @@ -442,7 +445,7 @@ _mesa_dump_renderbuffers(GLboolean writeImages) { GET_CURRENT_CONTEXT(ctx); WriteImages = writeImages; - _mesa_HashWalk(ctx->Shared->RenderBuffers, dump_renderbuffer_cb, ctx); + _mesa_HashWalk(&ctx->Shared->RenderBuffers, dump_renderbuffer_cb, ctx); } @@ -607,9 +610,9 @@ _mesa_print_texture(struct gl_context *ctx, struct gl_texture_image *img) GLuint i, j, c; GLubyte *data; - ctx->Driver.MapTextureImage(ctx, img, slice, - 0, 0, img->Width, img->Height, GL_MAP_READ_BIT, - &data, &srcRowStride); + st_MapTextureImage(ctx, img, slice, + 0, 0, img->Width, img->Height, GL_MAP_READ_BIT, + &data, &srcRowStride); if (!data) { printf("No texture data\n"); @@ -656,5 +659,5 @@ _mesa_print_texture(struct gl_context *ctx, struct gl_texture_image *img) } } - ctx->Driver.UnmapTextureImage(ctx, img, slice); + st_UnmapTextureImage(ctx, img, slice); } diff --git a/src/mesa/main/debug.h b/src/mesa/main/debug.h index 902f59538bd..64aaf176086 100644 --- a/src/mesa/main/debug.h +++ b/src/mesa/main/debug.h @@ -36,7 +36,7 @@ #ifndef _DEBUG_H #define _DEBUG_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_texture_image; diff --git a/src/mesa/main/debug_output.c b/src/mesa/main/debug_output.c index 6527aea5771..bee71950dea 100644 --- a/src/mesa/main/debug_output.c +++ b/src/mesa/main/debug_output.c @@ -35,7 +35,9 @@ #include "util/hash_table.h" #include "util/list.h" #include "util/u_memory.h" +#include "api_exec_decl.h" +#include "pipe/p_context.h" static GLuint PrevDynamicID = 0; @@ -193,7 +195,8 @@ void _mesa_debug_get_id(GLuint *id) { if (!(*id)) { - *id = p_atomic_inc_return(&PrevDynamicID); + /* Don't update *id if we raced with some other thread. */ + p_atomic_cmpxchg(id, 0, p_atomic_inc_return(&PrevDynamicID)); } } @@ -679,6 +682,83 @@ debug_pop_group(struct gl_debug_state *debug) /** + * Installed as util_debug_callback when GL_DEBUG_OUTPUT is enabled. + */ +static void +_debug_message(void *data, + unsigned *id, + enum util_debug_type ptype, + const char *fmt, + va_list args) +{ + struct gl_context *ctx = data; + enum mesa_debug_source source; + enum mesa_debug_type type; + enum mesa_debug_severity severity; + + switch (ptype) { + case UTIL_DEBUG_TYPE_OUT_OF_MEMORY: + source = MESA_DEBUG_SOURCE_API; + type = MESA_DEBUG_TYPE_ERROR; + severity = MESA_DEBUG_SEVERITY_MEDIUM; + break; + case UTIL_DEBUG_TYPE_ERROR: + source = MESA_DEBUG_SOURCE_API; + type = MESA_DEBUG_TYPE_ERROR; + severity = MESA_DEBUG_SEVERITY_MEDIUM; + break; + case UTIL_DEBUG_TYPE_SHADER_INFO: + source = MESA_DEBUG_SOURCE_SHADER_COMPILER; + type = MESA_DEBUG_TYPE_OTHER; + severity = MESA_DEBUG_SEVERITY_NOTIFICATION; + break; + case UTIL_DEBUG_TYPE_PERF_INFO: + source = MESA_DEBUG_SOURCE_API; + type = MESA_DEBUG_TYPE_PERFORMANCE; + severity = MESA_DEBUG_SEVERITY_NOTIFICATION; + break; + case UTIL_DEBUG_TYPE_INFO: + source = MESA_DEBUG_SOURCE_API; + type = MESA_DEBUG_TYPE_OTHER; + severity = MESA_DEBUG_SEVERITY_NOTIFICATION; + break; + case UTIL_DEBUG_TYPE_FALLBACK: + source = MESA_DEBUG_SOURCE_API; + type = MESA_DEBUG_TYPE_PERFORMANCE; + severity = MESA_DEBUG_SEVERITY_NOTIFICATION; + break; + case UTIL_DEBUG_TYPE_CONFORMANCE: + source = MESA_DEBUG_SOURCE_API; + type = MESA_DEBUG_TYPE_OTHER; + severity = MESA_DEBUG_SEVERITY_NOTIFICATION; + break; + default: + unreachable("invalid debug type"); + } + _mesa_gl_vdebugf(ctx, id, source, type, severity, fmt, args); +} + +void +_mesa_update_debug_callback(struct gl_context *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + + if (!pipe->set_debug_callback) + return; + + if (_mesa_get_debug_state_int(ctx, GL_DEBUG_OUTPUT)) { + struct util_debug_callback cb; + memset(&cb, 0, sizeof(cb)); + cb.async = !_mesa_get_debug_state_int(ctx, GL_DEBUG_OUTPUT_SYNCHRONOUS); + cb.debug_message = _debug_message; + cb.data = ctx; + pipe->set_debug_callback(pipe, &cb); + } else { + pipe->set_debug_callback(pipe, NULL); + } +} + +/** * Lock and return debug state for the context. The debug state will be * allocated and initialized upon the first call. When NULL is returned, the * debug state is not locked. @@ -1009,8 +1089,8 @@ _mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id, gl_enum_to_debug_severity(severity), length, buf); - if (type == GL_DEBUG_TYPE_MARKER && ctx->Driver.EmitStringMarker) { - ctx->Driver.EmitStringMarker(ctx, buf, length); + if (type == GL_DEBUG_TYPE_MARKER && ctx->has_string_marker) { + ctx->pipe->emit_string_marker(ctx->pipe, buf, length); } } @@ -1296,7 +1376,7 @@ _mesa_StringMarkerGREMEDY(GLsizei len, const GLvoid *string) /* if length not specified, string will be null terminated: */ if (len <= 0) len = strlen(string); - ctx->Driver.EmitStringMarker(ctx, string, len); + ctx->pipe->emit_string_marker(ctx->pipe, string, len); } else { _mesa_error(ctx, GL_INVALID_OPERATION, "StringMarkerGREMEDY"); } diff --git a/src/mesa/main/debug_output.h b/src/mesa/main/debug_output.h index e467b087b5e..3ac009ab5a1 100644 --- a/src/mesa/main/debug_output.h +++ b/src/mesa/main/debug_output.h @@ -29,7 +29,7 @@ #include <stdio.h> #include <stdarg.h> -#include "glheader.h" +#include "util/glheader.h" #include "menums.h" @@ -69,35 +69,8 @@ _mesa_debug_is_message_enabled(const struct gl_debug_state *debug, GLuint id, enum mesa_debug_severity severity); -void GLAPIENTRY -_mesa_DebugMessageInsert(GLenum source, GLenum type, GLuint id, - GLenum severity, GLint length, - const GLchar* buf); - -GLuint GLAPIENTRY -_mesa_GetDebugMessageLog(GLuint count, GLsizei logSize, GLenum* sources, - GLenum* types, GLenum* ids, GLenum* severities, - GLsizei* lengths, GLchar* messageLog); - -void GLAPIENTRY -_mesa_DebugMessageControl(GLenum source, GLenum type, GLenum severity, - GLsizei count, const GLuint *ids, - GLboolean enabled); - -void GLAPIENTRY -_mesa_DebugMessageCallback(GLDEBUGPROC callback, - const void *userParam); - -void GLAPIENTRY -_mesa_PushDebugGroup(GLenum source, GLuint id, GLsizei length, - const GLchar *message); - -void GLAPIENTRY -_mesa_PopDebugGroup(void); - -void GLAPIENTRY -_mesa_StringMarkerGREMEDY(GLsizei len, const GLvoid *string); - +void +_mesa_update_debug_callback(struct gl_context *ctx); #ifdef __cplusplus } diff --git a/src/mesa/main/depth.c b/src/mesa/main/depth.c index d69e8e71d00..a0041cff573 100644 --- a/src/mesa/main/depth.c +++ b/src/mesa/main/depth.c @@ -23,7 +23,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "depth.h" @@ -31,7 +31,9 @@ #include "macros.h" #include "mtypes.h" #include "state.h" +#include "api_exec_decl.h" +#include "state_tracker/st_context.h" /**********************************************************************/ /***** API Functions *****/ @@ -82,14 +84,10 @@ depth_func(struct gl_context *ctx, GLenum func, bool no_error) } } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH, - GL_DEPTH_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepth; + FLUSH_VERTICES(ctx, 0, GL_DEPTH_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Depth.Func = func; _mesa_update_allow_draw_out_of_order(ctx); - - if (ctx->Driver.DepthFunc) - ctx->Driver.DepthFunc(ctx, func); } @@ -129,14 +127,10 @@ _mesa_DepthMask( GLboolean flag ) if (ctx->Depth.Mask == flag) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH, - GL_DEPTH_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepth; + FLUSH_VERTICES(ctx, 0, GL_DEPTH_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Depth.Mask = flag; _mesa_update_allow_draw_out_of_order(ctx); - - if (ctx->Driver.DepthMask) - ctx->Driver.DepthMask( ctx, flag ); } @@ -163,9 +157,8 @@ _mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ) if (ctx->Depth.BoundsMin == zmin && ctx->Depth.BoundsMax == zmax) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH, - GL_DEPTH_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepth; + FLUSH_VERTICES(ctx, 0, GL_DEPTH_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Depth.BoundsMin = zmin; ctx->Depth.BoundsMax = zmax; } diff --git a/src/mesa/main/depth.h b/src/mesa/main/depth.h index 478249f157c..512474a5179 100644 --- a/src/mesa/main/depth.h +++ b/src/mesa/main/depth.h @@ -32,29 +32,10 @@ #define DEPTH_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; - -extern void GLAPIENTRY -_mesa_ClearDepth( GLclampd depth ); - -extern void GLAPIENTRY -_mesa_ClearDepthf( GLclampf depth ); - -void GLAPIENTRY -_mesa_DepthFunc_no_error(GLenum func); - -extern void GLAPIENTRY -_mesa_DepthFunc(GLenum func); - -extern void GLAPIENTRY -_mesa_DepthMask( GLboolean flag ); - -extern void GLAPIENTRY -_mesa_DepthBoundsEXT( GLclampd zmin, GLclampd zmax ); - extern void _mesa_init_depth( struct gl_context * ctx ); diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index 5012996da44..1ca48a9c6a2 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -29,54 +29,37 @@ * Display lists management functions. */ -#include "c99_math.h" -#include "glheader.h" - +#include "api_save.h" #include "api_arrayelt.h" -#include "api_exec.h" #include "draw_validate.h" -#include "atifragshader.h" -#include "config.h" -#include "bufferobj.h" #include "arrayobj.h" -#include "context.h" -#include "dlist.h" #include "enums.h" #include "eval.h" -#include "fbobject.h" -#include "framebuffer.h" -#include "glapi/glapi.h" -#include "glformats.h" #include "hash.h" #include "image.h" #include "light.h" -#include "macros.h" #include "pack.h" #include "pbo.h" -#include "queryobj.h" -#include "samplerobj.h" -#include "shaderapi.h" -#include "syncobj.h" #include "teximage.h" -#include "texstorage.h" -#include "mtypes.h" +#include "texobj.h" #include "varray.h" -#include "arbprogram.h" -#include "transformfeedback.h" #include "glthread_marshal.h" -#include "math/m_matrix.h" - #include "main/dispatch.h" -#include "vbo/vbo.h" -#include "vbo/vbo_util.h" #include "vbo/vbo_save.h" -#include "util/format_r11g11b10f.h" - +#include "util/u_inlines.h" #include "util/u_memory.h" +#include "api_exec_decl.h" -#define USE_BITMAP_ATLAS 1 +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_sampler_view.h" + +static bool +_mesa_glthread_should_execute_list(struct gl_context *ctx, + struct gl_display_list *dlist); /** * Flush vertices. @@ -150,9 +133,6 @@ /** * Display list opcodes. - * - * The fact that these identifiers are assigned consecutive - * integer values starting at 0 is very important, see InstSize array usage) */ typedef enum { @@ -515,7 +495,7 @@ typedef enum OPCODE_TEXPARAMETER_I, OPCODE_TEXPARAMETER_UI, - /* GL_ARB_instanced_arrays */ + /* GL_EXT/ARB_instanced_arrays */ OPCODE_VERTEX_ATTRIB_DIVISOR, /* GL_NV_texture_barrier */ @@ -629,49 +609,20 @@ typedef enum OPCODE_NAMED_PROGRAM_STRING, OPCODE_NAMED_PROGRAM_LOCAL_PARAMETER, + /* GL_ARB_ES3_2_compatibility */ + OPCODE_PRIMITIVE_BOUNDING_BOX, + OPCODE_VERTEX_LIST, + OPCODE_VERTEX_LIST_LOOPBACK, + OPCODE_VERTEX_LIST_COPY_CURRENT, /* The following three are meta instructions */ OPCODE_ERROR, /* raise compiled-in error */ OPCODE_CONTINUE, - OPCODE_NOP, /* No-op (used for 8-byte alignment */ - OPCODE_END_OF_LIST, - OPCODE_EXT_0 + OPCODE_END_OF_LIST } OpCode; - -/** - * Display list node. - * - * Display list instructions are stored as sequences of "nodes". Nodes - * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks - * are linked together with a pointer. - * - * Each instruction in the display list is stored as a sequence of - * contiguous nodes in memory. - * Each node is the union of a variety of data types. - * - * Note, all of these members should be 4 bytes in size or less for the - * sake of compact display lists. We store 8-byte pointers in a pair of - * these nodes using the save/get_pointer() functions below. - */ -union gl_dlist_node -{ - OpCode opcode; - GLboolean b; - GLbitfield bf; - GLubyte ub; - GLshort s; - GLushort us; - GLint i; - GLuint ui; - GLenum e; - GLfloat f; - GLsizei si; -}; - - typedef union gl_dlist_node Node; @@ -779,14 +730,6 @@ union int64_pair #define BLOCK_SIZE 256 - -/** - * Number of nodes of storage needed for each instruction. - * Sizes for dynamically allocated opcodes are stored in the context struct. - */ -static GLuint InstSize[OPCODE_END_OF_LIST + 1]; - - void mesa_print_display_list(GLuint list); @@ -796,37 +739,54 @@ void mesa_print_display_list(GLuint list); static void vbo_destroy_vertex_list(struct gl_context *ctx, struct vbo_save_vertex_list *node) { - for (gl_vertex_processing_mode vpm = VP_MODE_FF; vpm < VP_MODE_MAX; ++vpm) - _mesa_reference_vao(ctx, &node->VAO[vpm], NULL); + struct gl_buffer_object *bo = node->cold->VAO[0]->BufferBinding[0].BufferObj; + + if (_mesa_bufferobj_mapped(bo, MAP_INTERNAL)) + _mesa_bufferobj_unmap(ctx, bo, MAP_INTERNAL); + + for (gl_vertex_processing_mode mode = VP_MODE_FF; mode < VP_MODE_MAX; ++mode) { + _mesa_reference_vao(ctx, &node->cold->VAO[mode], NULL); + if (node->private_refcount[mode]) { + assert(node->private_refcount[mode] > 0); + p_atomic_add(&node->state[mode]->reference.count, + -node->private_refcount[mode]); + } + pipe_vertex_state_reference(&node->state[mode], NULL); + } - if (--node->prim_store->refcount == 0) { - free(node->prim_store->prims); - free(node->prim_store); + if (node->modes) { + free(node->modes); + free(node->start_counts); } - free(node->merged.mode); - free(node->merged.start_count); + _mesa_reference_buffer_object(ctx, &node->cold->ib.obj, NULL); + free(node->cold->current_data); + node->cold->current_data = NULL; - _mesa_reference_buffer_object(ctx, &node->merged.ib.obj, NULL); - free(node->current_data); - node->current_data = NULL; + free(node->cold->prims); + free(node->cold); } static void -vbo_print_vertex_list(struct gl_context *ctx, struct vbo_save_vertex_list *node, FILE *f) +vbo_print_vertex_list(struct gl_context *ctx, struct vbo_save_vertex_list *node, OpCode op, FILE *f) { GLuint i; - struct gl_buffer_object *buffer = node->VAO[0]->BufferBinding[0].BufferObj; + struct gl_buffer_object *buffer = node->cold->VAO[0]->BufferBinding[0].BufferObj; const GLuint vertex_size = _vbo_save_get_stride(node)/sizeof(GLfloat); (void) ctx; - fprintf(f, "VBO-VERTEX-LIST, %u vertices, %d primitives, %d vertsize, " + const char *label[] = { + "VBO-VERTEX-LIST", "VBO-VERTEX-LIST-LOOPBACK", "VBO-VERTEX-LIST-COPY-CURRENT" + }; + + fprintf(f, "%s, %u vertices, %d primitives, %d vertsize, " "buffer %p\n", - node->vertex_count, node->prim_count, vertex_size, + label[op - OPCODE_VERTEX_LIST], + node->cold->vertex_count, node->cold->prim_count, vertex_size, buffer); - for (i = 0; i < node->prim_count; i++) { - struct _mesa_prim *prim = &node->prims[i]; + for (i = 0; i < node->cold->prim_count; i++) { + struct _mesa_prim *prim = &node->cold->prims[i]; fprintf(f, " prim %d: %s %d..%d %s %s\n", i, _mesa_lookup_prim_by_nr(prim->mode), @@ -838,265 +798,12 @@ vbo_print_vertex_list(struct gl_context *ctx, struct vbo_save_vertex_list *node, } -/** - * Does the given display list only contain a single glBitmap call? - */ -static bool -is_bitmap_list(const struct gl_display_list *dlist) -{ - const Node *n = dlist->Head; - if (n[0].opcode == OPCODE_BITMAP) { - n += InstSize[OPCODE_BITMAP]; - if (n[0].opcode == OPCODE_END_OF_LIST) - return true; - } - return false; -} - - -/** - * Is the given display list an empty list? - */ -static bool -is_empty_list(const struct gl_display_list *dlist) -{ - const Node *n = dlist->Head; - return n[0].opcode == OPCODE_END_OF_LIST; -} - - -/** - * Delete/free a gl_bitmap_atlas. Called during context tear-down. - */ -void -_mesa_delete_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas) -{ - if (atlas->texObj) { - ctx->Driver.DeleteTexture(ctx, atlas->texObj); - } - free(atlas->glyphs); - free(atlas); -} - - -/** - * Lookup a gl_bitmap_atlas by listBase ID. - */ -static struct gl_bitmap_atlas * -lookup_bitmap_atlas(struct gl_context *ctx, GLuint listBase) -{ - struct gl_bitmap_atlas *atlas; - - assert(listBase > 0); - atlas = _mesa_HashLookup(ctx->Shared->BitmapAtlas, listBase); - return atlas; -} - - -/** - * Create new bitmap atlas and insert into hash table. - */ -static struct gl_bitmap_atlas * -alloc_bitmap_atlas(struct gl_context *ctx, GLuint listBase, bool isGenName) +static inline +Node *get_list_head(struct gl_context *ctx, struct gl_display_list *dlist) { - struct gl_bitmap_atlas *atlas; - - assert(listBase > 0); - assert(_mesa_HashLookup(ctx->Shared->BitmapAtlas, listBase) == NULL); - - atlas = calloc(1, sizeof(*atlas)); - if (atlas) { - _mesa_HashInsert(ctx->Shared->BitmapAtlas, listBase, atlas, isGenName); - atlas->Id = listBase; - } - - return atlas; -} - - -/** - * Try to build a bitmap atlas. This involves examining a sequence of - * display lists which contain glBitmap commands and putting the bitmap - * images into a texture map (the atlas). - * If we succeed, gl_bitmap_atlas::complete will be set to true. - * If we fail, gl_bitmap_atlas::incomplete will be set to true. - */ -static void -build_bitmap_atlas(struct gl_context *ctx, struct gl_bitmap_atlas *atlas, - GLuint listBase) -{ - unsigned i, row_height = 0, xpos = 0, ypos = 0; - GLubyte *map; - GLint map_stride; - - assert(atlas); - assert(!atlas->complete); - assert(atlas->numBitmaps > 0); - - /* We use a rectangle texture (non-normalized coords) for the atlas */ - assert(ctx->Extensions.NV_texture_rectangle); - assert(ctx->Const.MaxTextureRectSize >= 1024); - - atlas->texWidth = 1024; - atlas->texHeight = 0; /* determined below */ - - atlas->glyphs = malloc(atlas->numBitmaps * sizeof(atlas->glyphs[0])); - if (!atlas->glyphs) { - /* give up */ - atlas->incomplete = true; - return; - } - - /* Loop over the display lists. They should all contain a single glBitmap - * call. If not, bail out. Also, compute the position and sizes of each - * bitmap in the atlas to determine the texture atlas size. - */ - for (i = 0; i < atlas->numBitmaps; i++) { - const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i); - const Node *n; - struct gl_bitmap_glyph *g = &atlas->glyphs[i]; - unsigned bitmap_width, bitmap_height; - float bitmap_xmove, bitmap_ymove, bitmap_xorig, bitmap_yorig; - - if (!list || is_empty_list(list)) { - /* stop here */ - atlas->numBitmaps = i; - break; - } - - if (!is_bitmap_list(list)) { - /* This list does not contain exactly one glBitmap command. Give up. */ - atlas->incomplete = true; - return; - } - - /* get bitmap info from the display list command */ - n = list->Head; - assert(n[0].opcode == OPCODE_BITMAP); - bitmap_width = n[1].i; - bitmap_height = n[2].i; - bitmap_xorig = n[3].f; - bitmap_yorig = n[4].f; - bitmap_xmove = n[5].f; - bitmap_ymove = n[6].f; - - if (xpos + bitmap_width > atlas->texWidth) { - /* advance to the next row of the texture */ - xpos = 0; - ypos += row_height; - row_height = 0; - } - - /* save the bitmap's position in the atlas */ - g->x = xpos; - g->y = ypos; - g->w = bitmap_width; - g->h = bitmap_height; - g->xorig = bitmap_xorig; - g->yorig = bitmap_yorig; - g->xmove = bitmap_xmove; - g->ymove = bitmap_ymove; - - xpos += bitmap_width; - - /* keep track of tallest bitmap in the row */ - row_height = MAX2(row_height, bitmap_height); - } - - /* Now we know the texture height */ - atlas->texHeight = ypos + row_height; - - if (atlas->texHeight == 0) { - /* no glyphs found, give up */ - goto fail; - } - else if (atlas->texHeight > ctx->Const.MaxTextureRectSize) { - /* too large, give up */ - goto fail; - } - - /* Create atlas texture (texture ID is irrelevant) */ - atlas->texObj = ctx->Driver.NewTextureObject(ctx, 999, GL_TEXTURE_RECTANGLE); - if (!atlas->texObj) { - goto out_of_memory; - } - - atlas->texObj->Sampler.Attrib.MinFilter = GL_NEAREST; - atlas->texObj->Sampler.Attrib.MagFilter = GL_NEAREST; - atlas->texObj->Attrib.MaxLevel = 0; - atlas->texObj->Immutable = GL_TRUE; - - atlas->texImage = _mesa_get_tex_image(ctx, atlas->texObj, - GL_TEXTURE_RECTANGLE, 0); - if (!atlas->texImage) { - goto out_of_memory; - } - - if (ctx->Const.BitmapUsesRed) - _mesa_init_teximage_fields(ctx, atlas->texImage, - atlas->texWidth, atlas->texHeight, 1, 0, - GL_RED, MESA_FORMAT_R_UNORM8); - else - _mesa_init_teximage_fields(ctx, atlas->texImage, - atlas->texWidth, atlas->texHeight, 1, 0, - GL_ALPHA, MESA_FORMAT_A_UNORM8); - - /* alloc image storage */ - if (!ctx->Driver.AllocTextureImageBuffer(ctx, atlas->texImage)) { - goto out_of_memory; - } - - /* map teximage, load with bitmap glyphs */ - ctx->Driver.MapTextureImage(ctx, atlas->texImage, 0, - 0, 0, atlas->texWidth, atlas->texHeight, - GL_MAP_WRITE_BIT, &map, &map_stride); - if (!map) { - goto out_of_memory; - } - - /* Background/clear pixels are 0xff, foreground/set pixels are 0x0 */ - memset(map, 0xff, map_stride * atlas->texHeight); - - for (i = 0; i < atlas->numBitmaps; i++) { - const struct gl_display_list *list = _mesa_lookup_list(ctx, listBase + i); - const Node *n = list->Head; - - assert(n[0].opcode == OPCODE_BITMAP || - n[0].opcode == OPCODE_END_OF_LIST); - - if (n[0].opcode == OPCODE_BITMAP) { - unsigned bitmap_width = n[1].i; - unsigned bitmap_height = n[2].i; - unsigned xpos = atlas->glyphs[i].x; - unsigned ypos = atlas->glyphs[i].y; - const void *bitmap_image = get_pointer(&n[7]); - - assert(atlas->glyphs[i].w == bitmap_width); - assert(atlas->glyphs[i].h == bitmap_height); - - /* put the bitmap image into the texture image */ - _mesa_expand_bitmap(bitmap_width, bitmap_height, - &ctx->DefaultPacking, bitmap_image, - map + map_stride * ypos + xpos, /* dest addr */ - map_stride, 0x0); - } - } - - ctx->Driver.UnmapTextureImage(ctx, atlas->texImage, 0); - - atlas->complete = true; - - return; - -out_of_memory: - _mesa_error(ctx, GL_OUT_OF_MEMORY, "Display list bitmap atlas"); -fail: - if (atlas->texObj) { - ctx->Driver.DeleteTexture(ctx, atlas->texObj); - } - free(atlas->glyphs); - atlas->glyphs = NULL; - atlas->incomplete = true; + return dlist->small_list ? + &ctx->Shared->small_dlist_store.ptr[dlist->start] : + dlist->Head; } @@ -1111,8 +818,6 @@ make_list(GLuint name, GLuint count) dlist->Name = name; dlist->Head = malloc(sizeof(Node) * count); dlist->Head[0].opcode = OPCODE_END_OF_LIST; - /* All InstSize[] entries must be non-zero */ - InstSize[OPCODE_END_OF_LIST] = 1; return dlist; } @@ -1121,10 +826,10 @@ make_list(GLuint name, GLuint count) * Lookup function to just encapsulate casting. */ struct gl_display_list * -_mesa_lookup_list(struct gl_context *ctx, GLuint list) +_mesa_lookup_list(struct gl_context *ctx, GLuint list, bool locked) { return (struct gl_display_list *) - _mesa_HashLookup(ctx->Shared->DisplayList, list); + _mesa_HashLookupMaybeLocked(&ctx->Shared->DisplayList, list, locked); } @@ -1137,14 +842,14 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) { Node *n, *block; - if (!dlist->Head) { + n = block = get_list_head(ctx, dlist); + + if (!n) { free(dlist->Label); - free(dlist); + FREE(dlist); return; } - n = block = dlist->Head; - while (1) { const OpCode opcode = n[0].opcode; @@ -1162,9 +867,11 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) case OPCODE_DRAW_PIXELS: free(get_pointer(&n[5])); break; - case OPCODE_BITMAP: - free(get_pointer(&n[7])); + case OPCODE_BITMAP: { + struct pipe_resource *tex = get_pointer(&n[7]); + pipe_resource_reference(&tex, NULL); break; + } case OPCODE_POLYGON_STIPPLE: free(get_pointer(&n[1])); break; @@ -1355,15 +1062,26 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) free(get_pointer(&n[5])); break; case OPCODE_VERTEX_LIST: - vbo_destroy_vertex_list(ctx, (struct vbo_save_vertex_list *) &n[1]); + case OPCODE_VERTEX_LIST_LOOPBACK: + case OPCODE_VERTEX_LIST_COPY_CURRENT: + vbo_destroy_vertex_list(ctx, (struct vbo_save_vertex_list *) &n[0]); break; case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); + assert (!dlist->small_list); free(block); block = n; continue; case OPCODE_END_OF_LIST: - free(block); + if (dlist->small_list) { + unsigned start = dlist->start; + for (int i = 0; i < dlist->count; i++) { + util_idalloc_free(&ctx->Shared->small_dlist_store.free_idx, + start + i); + } + } else { + free(block); + } free(dlist->Label); free(dlist); return; @@ -1372,33 +1090,8 @@ _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist) ; } - assert(InstSize[opcode] > 0); - n += InstSize[opcode]; - } -} - - -/** - * Called by _mesa_HashWalk() to check if a display list which is being - * deleted belongs to a bitmap texture atlas. - */ -static void -check_atlas_for_deleted_list(void *data, void *userData) -{ - struct gl_bitmap_atlas *atlas = (struct gl_bitmap_atlas *) data; - GLuint list_id = *((GLuint *) userData); /* the list being deleted */ - const GLuint atlas_id = atlas->Id; - - /* See if the list_id falls in the range contained in this texture atlas */ - if (atlas->complete && - list_id >= atlas_id && - list_id < atlas_id + atlas->numBitmaps) { - /* Mark the atlas as incomplete so it doesn't get used. But don't - * delete it yet since we don't want to try to recreate it in the next - * glCallLists. - */ - atlas->complete = false; - atlas->incomplete = true; + assert(n[0].InstSize > 0); + n += n[0].InstSize; } } @@ -1415,22 +1108,12 @@ destroy_list(struct gl_context *ctx, GLuint list) if (list == 0) return; - dlist = _mesa_lookup_list(ctx, list); + dlist = _mesa_lookup_list(ctx, list, true); if (!dlist) return; - if (is_bitmap_list(dlist)) { - /* If we're destroying a simple glBitmap display list, there's a - * chance that we're destroying a bitmap image that's in a texture - * atlas. Examine all atlases to see if that's the case. There's - * usually few (if any) atlases so this isn't expensive. - */ - _mesa_HashWalk(ctx->Shared->BitmapAtlas, - check_atlas_for_deleted_list, &list); - } - _mesa_delete_list(ctx, dlist); - _mesa_HashRemove(ctx->Shared->DisplayList, list); + _mesa_HashRemoveLocked(&ctx->Shared->DisplayList, list); } @@ -1474,9 +1157,9 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, GLvoid *image; map = (GLubyte *) - ctx->Driver.MapBufferRange(ctx, 0, unpack->BufferObj->Size, - GL_MAP_READ_BIT, unpack->BufferObj, - MAP_INTERNAL); + _mesa_bufferobj_map_range(ctx, 0, unpack->BufferObj->Size, + GL_MAP_READ_BIT, unpack->BufferObj, + MAP_INTERNAL); if (!map) { /* unable to map src buffer! */ _mesa_error(ctx, GL_INVALID_OPERATION, "unable to map PBO"); @@ -1487,7 +1170,7 @@ unpack_image(struct gl_context *ctx, GLuint dimensions, image = _mesa_unpack_image(dimensions, width, height, depth, format, type, src, unpack); - ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, unpack->BufferObj, MAP_INTERNAL); if (!image) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "display list construction"); @@ -1525,39 +1208,22 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8) { const GLuint numNodes = 1 + (bytes + sizeof(Node) - 1) / sizeof(Node); const GLuint contNodes = 1 + POINTER_DWORDS; /* size of continue info */ - GLuint nopNode; - Node *n; assert(bytes <= BLOCK_SIZE * sizeof(Node)); - if (opcode < OPCODE_EXT_0) { - if (InstSize[opcode] == 0) { - /* save instruction size now */ - InstSize[opcode] = numNodes; - } - else { - /* make sure instruction size agrees */ - assert(numNodes == InstSize[opcode]); - } - } - - if (sizeof(void *) > sizeof(Node) && align8 - && ctx->ListState.CurrentPos % 2 == 0) { - /* The opcode would get placed at node[0] and the payload would start - * at node[1]. But the payload needs to be at an even offset (8-byte - * multiple). - */ - nopNode = 1; - } - else { - nopNode = 0; + /* If this node needs to start on an 8-byte boundary, pad the last node. */ + if (sizeof(void *) == 8 && align8 && + ctx->ListState.CurrentPos % 2 == 1) { + Node *last = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos - + ctx->ListState.LastInstSize; + last->InstSize++; + ctx->ListState.CurrentPos++; } - if (ctx->ListState.CurrentPos + nopNode + numNodes + contNodes - > BLOCK_SIZE) { + if (ctx->ListState.CurrentPos + numNodes + contNodes >= BLOCK_SIZE) { /* This block is full. Allocate a new block and chain to it */ Node *newblock; - n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; + Node *n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; n[0].opcode = OPCODE_CONTINUE; newblock = malloc(sizeof(Node) * BLOCK_SIZE); if (!newblock) { @@ -1571,75 +1237,33 @@ dlist_alloc(struct gl_context *ctx, OpCode opcode, GLuint bytes, bool align8) save_pointer(&n[1], newblock); ctx->ListState.CurrentBlock = newblock; ctx->ListState.CurrentPos = 0; - - /* Display list nodes are always 4 bytes. If we need 8-byte alignment - * we have to insert a NOP so that the payload of the real opcode lands - * on an even location: - * node[0] = OPCODE_NOP - * node[1] = OPCODE_x; - * node[2] = start of payload - */ - nopNode = sizeof(void *) > sizeof(Node) && align8; } - n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; - if (nopNode) { - assert(ctx->ListState.CurrentPos % 2 == 0); /* even value */ - n[0].opcode = OPCODE_NOP; - n++; - /* The "real" opcode will now be at an odd location and the payload - * will be at an even location. - */ - } - ctx->ListState.CurrentPos += nopNode + numNodes; + Node *n = ctx->ListState.CurrentBlock + ctx->ListState.CurrentPos; + ctx->ListState.CurrentPos += numNodes; n[0].opcode = opcode; + n[0].InstSize = numNodes; + ctx->ListState.LastInstSize = numNodes; return n; } - -/** - * Allocate space for a display list instruction. Used by callers outside - * this file for things like VBO vertex data. - * - * \param opcode the instruction opcode (OPCODE_* value) - * \param bytes instruction size in bytes, not counting opcode. - * \return pointer to the usable data area (not including the internal - * opcode). - */ -void * -_mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint bytes) -{ - Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, false); - if (n) - return n + 1; /* return pointer to payload area, after opcode */ - else - return NULL; -} - - -/** - * Same as _mesa_dlist_alloc(), but return a pointer which is 8-byte - * aligned in 64-bit environments, 4-byte aligned otherwise. - */ void * -_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes) -{ - Node *n = dlist_alloc(ctx, (OpCode) opcode, bytes, true); - if (n) - return n + 1; /* return pointer to payload area, after opcode */ - else +_mesa_dlist_alloc_vertex_list(struct gl_context *ctx, bool copy_to_current) +{ + Node *n = dlist_alloc(ctx, + copy_to_current ? OPCODE_VERTEX_LIST_COPY_CURRENT : + OPCODE_VERTEX_LIST, + sizeof(struct vbo_save_vertex_list) - sizeof(Node), + true); + if (!n) return NULL; -} - -void * -_mesa_dlist_alloc_vertex_list(struct gl_context *ctx) -{ - return _mesa_dlist_alloc_aligned(ctx, OPCODE_VERTEX_LIST, - sizeof(struct vbo_save_vertex_list)); + /* Clear all nodes except the header */ + memset(n + 1, 0, sizeof(struct vbo_save_vertex_list) - sizeof(Node)); + return n; } @@ -1659,42 +1283,10 @@ alloc_instruction(struct gl_context *ctx, OpCode opcode, GLuint nparams) } -/** - * Called by EndList to try to reduce memory used for the list. - */ -static void -trim_list(struct gl_context *ctx) -{ - /* If the list we're ending only has one allocated block of nodes/tokens - * and its size isn't a full block size, realloc the block to use less - * memory. This is important for apps that create many small display - * lists and apps that use glXUseXFont (many lists each containing one - * glBitmap call). - * Note: we currently only trim display lists that allocated one block - * of tokens. That hits the short list case which is what we're mainly - * concerned with. Trimming longer lists would involve traversing the - * linked list of blocks. - */ - struct gl_dlist_state *list = &ctx->ListState; - - if ((list->CurrentList->Head == list->CurrentBlock) && - (list->CurrentPos < BLOCK_SIZE)) { - /* There's only one block and it's not full, so realloc */ - GLuint newSize = list->CurrentPos * sizeof(Node); - list->CurrentList->Head = - list->CurrentBlock = realloc(list->CurrentBlock, newSize); - if (!list->CurrentBlock) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndList"); - } - } -} - - - /* * Display List compilation functions */ -static void GLAPIENTRY +void GLAPIENTRY save_Accum(GLenum op, GLfloat value) { GET_CURRENT_CONTEXT(ctx); @@ -1706,12 +1298,12 @@ save_Accum(GLenum op, GLfloat value) n[2].f = value; } if (ctx->ExecuteFlag) { - CALL_Accum(ctx->Exec, (op, value)); + CALL_Accum(ctx->Dispatch.Exec, (op, value)); } } -static void GLAPIENTRY +void GLAPIENTRY save_AlphaFunc(GLenum func, GLclampf ref) { GET_CURRENT_CONTEXT(ctx); @@ -1723,12 +1315,12 @@ save_AlphaFunc(GLenum func, GLclampf ref) n[2].f = (GLfloat) ref; } if (ctx->ExecuteFlag) { - CALL_AlphaFunc(ctx->Exec, (func, ref)); + CALL_AlphaFunc(ctx->Dispatch.Exec, (func, ref)); } } -static void GLAPIENTRY +void GLAPIENTRY save_BindTexture(GLenum target, GLuint texture) { GET_CURRENT_CONTEXT(ctx); @@ -1740,12 +1332,12 @@ save_BindTexture(GLenum target, GLuint texture) n[2].ui = texture; } if (ctx->ExecuteFlag) { - CALL_BindTexture(ctx->Exec, (target, texture)); + CALL_BindTexture(ctx->Dispatch.Exec, (target, texture)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Bitmap(GLsizei width, GLsizei height, GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, const GLubyte * pixels) @@ -1753,26 +1345,40 @@ save_Bitmap(GLsizei width, GLsizei height, GET_CURRENT_CONTEXT(ctx); Node *n; ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + struct pipe_resource *tex = NULL; + + if (width > 0 && height > 0) { + tex = st_make_bitmap_texture(ctx, width, height, &ctx->Unpack, pixels); + + if (!tex) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glNewList -> glBitmap"); + return; + } + } + n = alloc_instruction(ctx, OPCODE_BITMAP, 6 + POINTER_DWORDS); - if (n) { - n[1].i = (GLint) width; - n[2].i = (GLint) height; - n[3].f = xorig; - n[4].f = yorig; - n[5].f = xmove; - n[6].f = ymove; - save_pointer(&n[7], - unpack_image(ctx, 2, width, height, 1, GL_COLOR_INDEX, - GL_BITMAP, pixels, &ctx->Unpack)); + if (!n) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glNewList -> glBitmap (3)"); + pipe_resource_reference(&tex, NULL); + return; } + + n[1].i = (GLint) width; + n[2].i = (GLint) height; + n[3].f = xorig; + n[4].f = yorig; + n[5].f = xmove; + n[6].f = ymove; + save_pointer(&n[7], tex); + if (ctx->ExecuteFlag) { - CALL_Bitmap(ctx->Exec, (width, height, - xorig, yorig, xmove, ymove, pixels)); + ASSERT_OUTSIDE_BEGIN_END(ctx); + _mesa_bitmap(ctx, width, height, xorig, yorig, xmove, ymove, NULL, tex); } } -static void GLAPIENTRY +void GLAPIENTRY save_BlendEquation(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -1783,13 +1389,13 @@ save_BlendEquation(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_BlendEquation(ctx->Exec, (mode)); + CALL_BlendEquation(ctx->Dispatch.Exec, (mode)); } } -static void GLAPIENTRY -save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) +void GLAPIENTRY +save_BlendEquationSeparate(GLenum modeRGB, GLenum modeA) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -1800,13 +1406,13 @@ save_BlendEquationSeparateEXT(GLenum modeRGB, GLenum modeA) n[2].e = modeA; } if (ctx->ExecuteFlag) { - CALL_BlendEquationSeparate(ctx->Exec, (modeRGB, modeA)); + CALL_BlendEquationSeparate(ctx->Dispatch.Exec, (modeRGB, modeA)); } } -static void GLAPIENTRY -save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, +void GLAPIENTRY +save_BlendFuncSeparate(GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { GET_CURRENT_CONTEXT(ctx); @@ -1820,20 +1426,20 @@ save_BlendFuncSeparateEXT(GLenum sfactorRGB, GLenum dfactorRGB, n[4].e = dfactorA; } if (ctx->ExecuteFlag) { - CALL_BlendFuncSeparate(ctx->Exec, + CALL_BlendFuncSeparate(ctx->Dispatch.Exec, (sfactorRGB, dfactorRGB, sfactorA, dfactorA)); } } -static void GLAPIENTRY +void GLAPIENTRY save_BlendFunc(GLenum srcfactor, GLenum dstfactor) { - save_BlendFuncSeparateEXT(srcfactor, dstfactor, srcfactor, dstfactor); + save_BlendFuncSeparate(srcfactor, dstfactor, srcfactor, dstfactor); } -static void GLAPIENTRY +void GLAPIENTRY save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { GET_CURRENT_CONTEXT(ctx); @@ -1847,13 +1453,13 @@ save_BlendColor(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) n[4].f = alpha; } if (ctx->ExecuteFlag) { - CALL_BlendColor(ctx->Exec, (red, green, blue, alpha)); + CALL_BlendColor(ctx->Dispatch.Exec, (red, green, blue, alpha)); } } /* GL_ARB_draw_buffers_blend */ -static void GLAPIENTRY -save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, +void GLAPIENTRY +save_BlendFuncSeparateiARB(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA) { GET_CURRENT_CONTEXT(ctx); @@ -1868,14 +1474,14 @@ save_BlendFuncSeparatei(GLuint buf, GLenum sfactorRGB, GLenum dfactorRGB, n[5].e = dfactorA; } if (ctx->ExecuteFlag) { - CALL_BlendFuncSeparateiARB(ctx->Exec, (buf, sfactorRGB, dfactorRGB, + CALL_BlendFuncSeparateiARB(ctx->Dispatch.Exec, (buf, sfactorRGB, dfactorRGB, sfactorA, dfactorA)); } } /* GL_ARB_draw_buffers_blend */ -static void GLAPIENTRY -save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) +void GLAPIENTRY +save_BlendFunciARB(GLuint buf, GLenum sfactor, GLenum dfactor) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -1887,13 +1493,13 @@ save_BlendFunci(GLuint buf, GLenum sfactor, GLenum dfactor) n[3].e = dfactor; } if (ctx->ExecuteFlag) { - CALL_BlendFunciARB(ctx->Exec, (buf, sfactor, dfactor)); + CALL_BlendFunciARB(ctx->Dispatch.Exec, (buf, sfactor, dfactor)); } } /* GL_ARB_draw_buffers_blend */ -static void GLAPIENTRY -save_BlendEquationi(GLuint buf, GLenum mode) +void GLAPIENTRY +save_BlendEquationiARB(GLuint buf, GLenum mode) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -1904,13 +1510,13 @@ save_BlendEquationi(GLuint buf, GLenum mode) n[2].e = mode; } if (ctx->ExecuteFlag) { - CALL_BlendEquationiARB(ctx->Exec, (buf, mode)); + CALL_BlendEquationiARB(ctx->Dispatch.Exec, (buf, mode)); } } /* GL_ARB_draw_buffers_blend */ -static void GLAPIENTRY -save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA) +void GLAPIENTRY +save_BlendEquationSeparateiARB(GLuint buf, GLenum modeRGB, GLenum modeA) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -1922,37 +1528,37 @@ save_BlendEquationSeparatei(GLuint buf, GLenum modeRGB, GLenum modeA) n[3].e = modeA; } if (ctx->ExecuteFlag) { - CALL_BlendEquationSeparateiARB(ctx->Exec, (buf, modeRGB, modeA)); + CALL_BlendEquationSeparateiARB(ctx->Dispatch.Exec, (buf, modeRGB, modeA)); } } /* GL_ARB_draw_instanced. */ -static void GLAPIENTRY -save_DrawArraysInstancedARB(UNUSED GLenum mode, - UNUSED GLint first, - UNUSED GLsizei count, - UNUSED GLsizei primcount) +void GLAPIENTRY +save_DrawArraysInstanced(UNUSED GLenum mode, + UNUSED GLint first, + UNUSED GLsizei count, + UNUSED GLsizei primcount) { GET_CURRENT_CONTEXT(ctx); _mesa_error(ctx, GL_INVALID_OPERATION, "glDrawArraysInstanced() during display list compile"); } -static void GLAPIENTRY -save_DrawElementsInstancedARB(UNUSED GLenum mode, - UNUSED GLsizei count, - UNUSED GLenum type, - UNUSED const GLvoid *indices, - UNUSED GLsizei primcount) +void GLAPIENTRY +save_DrawElementsInstanced(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, "glDrawElementsInstanced() during display list compile"); } -static void GLAPIENTRY -save_DrawElementsInstancedBaseVertexARB(UNUSED GLenum mode, +void GLAPIENTRY +save_DrawElementsInstancedBaseVertex(UNUSED GLenum mode, UNUSED GLsizei count, UNUSED GLenum type, UNUSED const GLvoid *indices, @@ -1965,7 +1571,7 @@ save_DrawElementsInstancedBaseVertexARB(UNUSED GLenum mode, } /* GL_ARB_base_instance. */ -static void GLAPIENTRY +void GLAPIENTRY save_DrawArraysInstancedBaseInstance(UNUSED GLenum mode, UNUSED GLint first, UNUSED GLsizei count, @@ -1977,7 +1583,7 @@ save_DrawArraysInstancedBaseInstance(UNUSED GLenum mode, "glDrawArraysInstancedBaseInstance() during display list compile"); } -static void APIENTRY +void GLAPIENTRY save_DrawElementsInstancedBaseInstance(UNUSED GLenum mode, UNUSED GLsizei count, UNUSED GLenum type, @@ -1990,7 +1596,7 @@ save_DrawElementsInstancedBaseInstance(UNUSED GLenum mode, "glDrawElementsInstancedBaseInstance() during display list compile"); } -static void APIENTRY +void GLAPIENTRY save_DrawElementsInstancedBaseVertexBaseInstance(UNUSED GLenum mode, UNUSED GLsizei count, UNUSED GLenum type, @@ -2004,7 +1610,7 @@ save_DrawElementsInstancedBaseVertexBaseInstance(UNUSED GLenum mode, "glDrawElementsInstancedBaseVertexBaseInstance() during display list compile"); } -static void APIENTRY +void GLAPIENTRY save_DrawArraysIndirect(UNUSED GLenum mode, UNUSED const void *indirect) { @@ -2013,7 +1619,7 @@ save_DrawArraysIndirect(UNUSED GLenum mode, "glDrawArraysIndirect() during display list compile"); } -static void APIENTRY +void GLAPIENTRY save_DrawElementsIndirect(UNUSED GLenum mode, UNUSED GLenum type, UNUSED const void *indirect) @@ -2023,7 +1629,7 @@ save_DrawElementsIndirect(UNUSED GLenum mode, "glDrawElementsIndirect() during display list compile"); } -static void APIENTRY +void GLAPIENTRY save_MultiDrawArraysIndirect(UNUSED GLenum mode, UNUSED const void *indirect, UNUSED GLsizei primcount, @@ -2034,7 +1640,7 @@ save_MultiDrawArraysIndirect(UNUSED GLenum mode, "glMultiDrawArraysIndirect() during display list compile"); } -static void APIENTRY +void GLAPIENTRY save_MultiDrawElementsIndirect(UNUSED GLenum mode, UNUSED GLenum type, UNUSED const void *indirect, @@ -2062,7 +1668,10 @@ invalidate_saved_current_state(struct gl_context *ctx) for (i = 0; i < MAT_ATTRIB_MAX; i++) ctx->ListState.ActiveMaterialSize[i] = 0; + /* Loopback usage applies recursively, so remember this state */ + bool use_loopback = ctx->ListState.Current.UseLoopback; memset(&ctx->ListState.Current, 0, sizeof ctx->ListState.Current); + ctx->ListState.Current.UseLoopback = use_loopback; ctx->Driver.CurrentSavePrimitive = PRIM_UNKNOWN; } @@ -2144,12 +1753,12 @@ save_CallLists(GLsizei num, GLenum type, const GLvoid * lists) invalidate_saved_current_state( ctx ); if (ctx->ExecuteFlag) { - CALL_CallLists(ctx->Exec, (num, type, lists)); + CALL_CallLists(ctx->Dispatch.Exec, (num, type, lists)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Clear(GLbitfield mask) { GET_CURRENT_CONTEXT(ctx); @@ -2160,12 +1769,12 @@ save_Clear(GLbitfield mask) n[1].bf = mask; } if (ctx->ExecuteFlag) { - CALL_Clear(ctx->Exec, (mask)); + CALL_Clear(ctx->Dispatch.Exec, (mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) { GET_CURRENT_CONTEXT(ctx); @@ -2188,12 +1797,12 @@ save_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) } } if (ctx->ExecuteFlag) { - CALL_ClearBufferiv(ctx->Exec, (buffer, drawbuffer, value)); + CALL_ClearBufferiv(ctx->Dispatch.Exec, (buffer, drawbuffer, value)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); @@ -2216,12 +1825,12 @@ save_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) } } if (ctx->ExecuteFlag) { - CALL_ClearBufferuiv(ctx->Exec, (buffer, drawbuffer, value)); + CALL_ClearBufferuiv(ctx->Dispatch.Exec, (buffer, drawbuffer, value)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) { GET_CURRENT_CONTEXT(ctx); @@ -2244,12 +1853,12 @@ save_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) } } if (ctx->ExecuteFlag) { - CALL_ClearBufferfv(ctx->Exec, (buffer, drawbuffer, value)); + CALL_ClearBufferfv(ctx->Dispatch.Exec, (buffer, drawbuffer, value)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearBufferfi(GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil) { @@ -2264,12 +1873,12 @@ save_ClearBufferfi(GLenum buffer, GLint drawbuffer, n[4].i = stencil; } if (ctx->ExecuteFlag) { - CALL_ClearBufferfi(ctx->Exec, (buffer, drawbuffer, depth, stencil)); + CALL_ClearBufferfi(ctx->Dispatch.Exec, (buffer, drawbuffer, depth, stencil)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { GET_CURRENT_CONTEXT(ctx); @@ -2283,12 +1892,12 @@ save_ClearAccum(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) n[4].f = alpha; } if (ctx->ExecuteFlag) { - CALL_ClearAccum(ctx->Exec, (red, green, blue, alpha)); + CALL_ClearAccum(ctx->Dispatch.Exec, (red, green, blue, alpha)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) { GET_CURRENT_CONTEXT(ctx); @@ -2302,12 +1911,12 @@ save_ClearColor(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) n[4].f = alpha; } if (ctx->ExecuteFlag) { - CALL_ClearColor(ctx->Exec, (red, green, blue, alpha)); + CALL_ClearColor(ctx->Dispatch.Exec, (red, green, blue, alpha)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearDepth(GLclampd depth) { GET_CURRENT_CONTEXT(ctx); @@ -2318,12 +1927,12 @@ save_ClearDepth(GLclampd depth) n[1].f = (GLfloat) depth; } if (ctx->ExecuteFlag) { - CALL_ClearDepth(ctx->Exec, (depth)); + CALL_ClearDepth(ctx->Dispatch.Exec, (depth)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearIndex(GLfloat c) { GET_CURRENT_CONTEXT(ctx); @@ -2334,12 +1943,12 @@ save_ClearIndex(GLfloat c) n[1].f = c; } if (ctx->ExecuteFlag) { - CALL_ClearIndex(ctx->Exec, (c)); + CALL_ClearIndex(ctx->Dispatch.Exec, (c)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClearStencil(GLint s) { GET_CURRENT_CONTEXT(ctx); @@ -2350,12 +1959,12 @@ save_ClearStencil(GLint s) n[1].i = s; } if (ctx->ExecuteFlag) { - CALL_ClearStencil(ctx->Exec, (s)); + CALL_ClearStencil(ctx->Dispatch.Exec, (s)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClipPlane(GLenum plane, const GLdouble * equ) { GET_CURRENT_CONTEXT(ctx); @@ -2370,13 +1979,13 @@ save_ClipPlane(GLenum plane, const GLdouble * equ) n[5].f = (GLfloat) equ[3]; } if (ctx->ExecuteFlag) { - CALL_ClipPlane(ctx->Exec, (plane, equ)); + CALL_ClipPlane(ctx->Dispatch.Exec, (plane, equ)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { @@ -2391,13 +2000,13 @@ save_ColorMask(GLboolean red, GLboolean green, n[4].b = alpha; } if (ctx->ExecuteFlag) { - CALL_ColorMask(ctx->Exec, (red, green, blue, alpha)); + CALL_ColorMask(ctx->Dispatch.Exec, (red, green, blue, alpha)); } } -static void GLAPIENTRY -save_ColorMaskIndexed(GLuint buf, GLboolean red, GLboolean green, +void GLAPIENTRY +save_ColorMaski(GLuint buf, GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) { GET_CURRENT_CONTEXT(ctx); @@ -2412,12 +2021,12 @@ save_ColorMaskIndexed(GLuint buf, GLboolean red, GLboolean green, n[5].b = alpha; } if (ctx->ExecuteFlag) { - /*CALL_ColorMaski(ctx->Exec, (buf, red, green, blue, alpha));*/ + /*CALL_ColorMaski(ctx->Dispatch.Exec, (buf, red, green, blue, alpha));*/ } } -static void GLAPIENTRY +void GLAPIENTRY save_ColorMaterial(GLenum face, GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -2430,12 +2039,12 @@ save_ColorMaterial(GLenum face, GLenum mode) n[2].e = mode; } if (ctx->ExecuteFlag) { - CALL_ColorMaterial(ctx->Exec, (face, mode)); + CALL_ColorMaterial(ctx->Dispatch.Exec, (face, mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) { GET_CURRENT_CONTEXT(ctx); @@ -2450,13 +2059,13 @@ save_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) n[5].e = type; } if (ctx->ExecuteFlag) { - CALL_CopyPixels(ctx->Exec, (x, y, width, height, type)); + CALL_CopyPixels(ctx->Dispatch.Exec, (x, y, width, height, type)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) { @@ -2474,13 +2083,13 @@ save_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, n[7].i = border; } if (ctx->ExecuteFlag) { - CALL_CopyTexImage1D(ctx->Exec, (target, level, internalformat, + CALL_CopyTexImage1D(ctx->Dispatch.Exec, (target, level, internalformat, x, y, width, border)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTexImage2D(GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, @@ -2501,14 +2110,14 @@ save_CopyTexImage2D(GLenum target, GLint level, n[8].i = border; } if (ctx->ExecuteFlag) { - CALL_CopyTexImage2D(ctx->Exec, (target, level, internalformat, + CALL_CopyTexImage2D(ctx->Dispatch.Exec, (target, level, internalformat, x, y, width, height, border)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { @@ -2525,13 +2134,13 @@ save_CopyTexSubImage1D(GLenum target, GLint level, n[6].i = width; } if (ctx->ExecuteFlag) { - CALL_CopyTexSubImage1D(ctx->Exec, + CALL_CopyTexSubImage1D(ctx->Dispatch.Exec, (target, level, xoffset, x, y, width)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLint height) @@ -2551,13 +2160,13 @@ save_CopyTexSubImage2D(GLenum target, GLint level, n[8].i = height; } if (ctx->ExecuteFlag) { - CALL_CopyTexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset, + CALL_CopyTexSubImage2D(ctx->Dispatch.Exec, (target, level, xoffset, yoffset, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLint height) @@ -2578,14 +2187,14 @@ save_CopyTexSubImage3D(GLenum target, GLint level, n[9].i = height; } if (ctx->ExecuteFlag) { - CALL_CopyTexSubImage3D(ctx->Exec, (target, level, + CALL_CopyTexSubImage3D(ctx->Dispatch.Exec, (target, level, xoffset, yoffset, zoffset, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CullFace(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -2596,12 +2205,12 @@ save_CullFace(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_CullFace(ctx->Exec, (mode)); + CALL_CullFace(ctx->Dispatch.Exec, (mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DepthFunc(GLenum func) { GET_CURRENT_CONTEXT(ctx); @@ -2612,12 +2221,12 @@ save_DepthFunc(GLenum func) n[1].e = func; } if (ctx->ExecuteFlag) { - CALL_DepthFunc(ctx->Exec, (func)); + CALL_DepthFunc(ctx->Dispatch.Exec, (func)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DepthMask(GLboolean mask) { GET_CURRENT_CONTEXT(ctx); @@ -2628,12 +2237,12 @@ save_DepthMask(GLboolean mask) n[1].b = mask; } if (ctx->ExecuteFlag) { - CALL_DepthMask(ctx->Exec, (mask)); + CALL_DepthMask(ctx->Dispatch.Exec, (mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DepthRange(GLclampd nearval, GLclampd farval) { GET_CURRENT_CONTEXT(ctx); @@ -2645,12 +2254,12 @@ save_DepthRange(GLclampd nearval, GLclampd farval) n[2].f = (GLfloat) farval; } if (ctx->ExecuteFlag) { - CALL_DepthRange(ctx->Exec, (nearval, farval)); + CALL_DepthRange(ctx->Dispatch.Exec, (nearval, farval)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Disable(GLenum cap) { GET_CURRENT_CONTEXT(ctx); @@ -2661,13 +2270,13 @@ save_Disable(GLenum cap) n[1].e = cap; } if (ctx->ExecuteFlag) { - CALL_Disable(ctx->Exec, (cap)); + CALL_Disable(ctx->Dispatch.Exec, (cap)); } } -static void GLAPIENTRY -save_DisableIndexed(GLuint index, GLenum cap) +void GLAPIENTRY +save_Disablei(GLuint index, GLenum cap) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -2678,12 +2287,12 @@ save_DisableIndexed(GLuint index, GLenum cap) n[2].e = cap; } if (ctx->ExecuteFlag) { - CALL_Disablei(ctx->Exec, (index, cap)); + CALL_Disablei(ctx->Dispatch.Exec, (index, cap)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DrawBuffer(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -2694,12 +2303,12 @@ save_DrawBuffer(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_DrawBuffer(ctx->Exec, (mode)); + CALL_DrawBuffer(ctx->Dispatch.Exec, (mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DrawPixels(GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid * pixels) { @@ -2719,13 +2328,13 @@ save_DrawPixels(GLsizei width, GLsizei height, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_DrawPixels(ctx->Exec, (width, height, format, type, pixels)); + CALL_DrawPixels(ctx->Dispatch.Exec, (width, height, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Enable(GLenum cap) { GET_CURRENT_CONTEXT(ctx); @@ -2736,14 +2345,14 @@ save_Enable(GLenum cap) n[1].e = cap; } if (ctx->ExecuteFlag) { - CALL_Enable(ctx->Exec, (cap)); + CALL_Enable(ctx->Dispatch.Exec, (cap)); } } -static void GLAPIENTRY -save_EnableIndexed(GLuint index, GLenum cap) +void GLAPIENTRY +save_Enablei(GLuint index, GLenum cap) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -2754,13 +2363,13 @@ save_EnableIndexed(GLuint index, GLenum cap) n[2].e = cap; } if (ctx->ExecuteFlag) { - CALL_Enablei(ctx->Exec, (index, cap)); + CALL_Enablei(ctx->Dispatch.Exec, (index, cap)); } } -static void GLAPIENTRY +void GLAPIENTRY save_EvalMesh1(GLenum mode, GLint i1, GLint i2) { GET_CURRENT_CONTEXT(ctx); @@ -2773,12 +2382,12 @@ save_EvalMesh1(GLenum mode, GLint i1, GLint i2) n[3].i = i2; } if (ctx->ExecuteFlag) { - CALL_EvalMesh1(ctx->Exec, (mode, i1, i2)); + CALL_EvalMesh1(ctx->Dispatch.Exec, (mode, i1, i2)); } } -static void GLAPIENTRY +void GLAPIENTRY save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) { GET_CURRENT_CONTEXT(ctx); @@ -2793,14 +2402,14 @@ save_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) n[5].i = j2; } if (ctx->ExecuteFlag) { - CALL_EvalMesh2(ctx->Exec, (mode, i1, i2, j1, j2)); + CALL_EvalMesh2(ctx->Dispatch.Exec, (mode, i1, i2, j1, j2)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Fogfv(GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -2815,12 +2424,12 @@ save_Fogfv(GLenum pname, const GLfloat *params) n[5].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_Fogfv(ctx->Exec, (pname, params)); + CALL_Fogfv(ctx->Dispatch.Exec, (pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Fogf(GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -2830,7 +2439,7 @@ save_Fogf(GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_Fogiv(GLenum pname, const GLint *params) { GLfloat p[4]; @@ -2860,7 +2469,7 @@ save_Fogiv(GLenum pname, const GLint *params) } -static void GLAPIENTRY +void GLAPIENTRY save_Fogi(GLenum pname, GLint param) { GLint parray[4]; @@ -2870,7 +2479,7 @@ save_Fogi(GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_FrontFace(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -2881,12 +2490,12 @@ save_FrontFace(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_FrontFace(ctx->Exec, (mode)); + CALL_FrontFace(ctx->Dispatch.Exec, (mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) { @@ -2903,12 +2512,12 @@ save_Frustum(GLdouble left, GLdouble right, n[6].f = (GLfloat) farval; } if (ctx->ExecuteFlag) { - CALL_Frustum(ctx->Exec, (left, right, bottom, top, nearval, farval)); + CALL_Frustum(ctx->Dispatch.Exec, (left, right, bottom, top, nearval, farval)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Hint(GLenum target, GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -2920,12 +2529,12 @@ save_Hint(GLenum target, GLenum mode) n[2].e = mode; } if (ctx->ExecuteFlag) { - CALL_Hint(ctx->Exec, (target, mode)); + CALL_Hint(ctx->Dispatch.Exec, (target, mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_IndexMask(GLuint mask) { GET_CURRENT_CONTEXT(ctx); @@ -2936,24 +2545,24 @@ save_IndexMask(GLuint mask) n[1].ui = mask; } if (ctx->ExecuteFlag) { - CALL_IndexMask(ctx->Exec, (mask)); + CALL_IndexMask(ctx->Dispatch.Exec, (mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_InitNames(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_INIT_NAMES, 0); if (ctx->ExecuteFlag) { - CALL_InitNames(ctx->Exec, ()); + CALL_InitNames(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_Lightfv(GLenum light, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -3003,12 +2612,12 @@ save_Lightfv(GLenum light, GLenum pname, const GLfloat *params) } } if (ctx->ExecuteFlag) { - CALL_Lightfv(ctx->Exec, (light, pname, params)); + CALL_Lightfv(ctx->Dispatch.Exec, (light, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Lightf(GLenum light, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -3018,7 +2627,7 @@ save_Lightf(GLenum light, GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_Lightiv(GLenum light, GLenum pname, const GLint *params) { GLfloat fparam[4]; @@ -3057,7 +2666,7 @@ save_Lightiv(GLenum light, GLenum pname, const GLint *params) } -static void GLAPIENTRY +void GLAPIENTRY save_Lighti(GLenum light, GLenum pname, GLint param) { GLint parray[4]; @@ -3067,7 +2676,7 @@ save_Lighti(GLenum light, GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_LightModelfv(GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -3082,12 +2691,12 @@ save_LightModelfv(GLenum pname, const GLfloat *params) n[5].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_LightModelfv(ctx->Exec, (pname, params)); + CALL_LightModelfv(ctx->Dispatch.Exec, (pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_LightModelf(GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -3097,7 +2706,7 @@ save_LightModelf(GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_LightModeliv(GLenum pname, const GLint *params) { GLfloat fparam[4]; @@ -3124,7 +2733,7 @@ save_LightModeliv(GLenum pname, const GLint *params) } -static void GLAPIENTRY +void GLAPIENTRY save_LightModeli(GLenum pname, GLint param) { GLint parray[4]; @@ -3134,7 +2743,7 @@ save_LightModeli(GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_LineStipple(GLint factor, GLushort pattern) { GET_CURRENT_CONTEXT(ctx); @@ -3146,12 +2755,12 @@ save_LineStipple(GLint factor, GLushort pattern) n[2].us = pattern; } if (ctx->ExecuteFlag) { - CALL_LineStipple(ctx->Exec, (factor, pattern)); + CALL_LineStipple(ctx->Dispatch.Exec, (factor, pattern)); } } -static void GLAPIENTRY +void GLAPIENTRY save_LineWidth(GLfloat width) { GET_CURRENT_CONTEXT(ctx); @@ -3162,12 +2771,12 @@ save_LineWidth(GLfloat width) n[1].f = width; } if (ctx->ExecuteFlag) { - CALL_LineWidth(ctx->Exec, (width)); + CALL_LineWidth(ctx->Dispatch.Exec, (width)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ListBase(GLuint base) { GET_CURRENT_CONTEXT(ctx); @@ -3178,24 +2787,24 @@ save_ListBase(GLuint base) n[1].ui = base; } if (ctx->ExecuteFlag) { - CALL_ListBase(ctx->Exec, (base)); + CALL_ListBase(ctx->Dispatch.Exec, (base)); } } -static void GLAPIENTRY +void GLAPIENTRY save_LoadIdentity(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_LOAD_IDENTITY, 0); if (ctx->ExecuteFlag) { - CALL_LoadIdentity(ctx->Exec, ()); + CALL_LoadIdentity(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_LoadMatrixf(const GLfloat * m) { GET_CURRENT_CONTEXT(ctx); @@ -3209,12 +2818,12 @@ save_LoadMatrixf(const GLfloat * m) } } if (ctx->ExecuteFlag) { - CALL_LoadMatrixf(ctx->Exec, (m)); + CALL_LoadMatrixf(ctx->Dispatch.Exec, (m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_LoadMatrixd(const GLdouble * m) { GLfloat f[16]; @@ -3226,7 +2835,7 @@ save_LoadMatrixd(const GLdouble * m) } -static void GLAPIENTRY +void GLAPIENTRY save_LoadName(GLuint name) { GET_CURRENT_CONTEXT(ctx); @@ -3237,12 +2846,12 @@ save_LoadName(GLuint name) n[1].ui = name; } if (ctx->ExecuteFlag) { - CALL_LoadName(ctx->Exec, (name)); + CALL_LoadName(ctx->Dispatch.Exec, (name)); } } -static void GLAPIENTRY +void GLAPIENTRY save_LogicOp(GLenum opcode) { GET_CURRENT_CONTEXT(ctx); @@ -3253,12 +2862,12 @@ save_LogicOp(GLenum opcode) n[1].e = opcode; } if (ctx->ExecuteFlag) { - CALL_LogicOp(ctx->Exec, (opcode)); + CALL_LogicOp(ctx->Dispatch.Exec, (opcode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble * points) { @@ -3276,11 +2885,11 @@ save_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, save_pointer(&n[6], pnts); } if (ctx->ExecuteFlag) { - CALL_Map1d(ctx->Exec, (target, u1, u2, stride, order, points)); + CALL_Map1d(ctx->Dispatch.Exec, (target, u1, u2, stride, order, points)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, GLint order, const GLfloat * points) { @@ -3298,12 +2907,12 @@ save_Map1f(GLenum target, GLfloat u1, GLfloat u2, GLint stride, save_pointer(&n[6], pnts); } if (ctx->ExecuteFlag) { - CALL_Map1f(ctx->Exec, (target, u1, u2, stride, order, points)); + CALL_Map1f(ctx->Dispatch.Exec, (target, u1, u2, stride, order, points)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Map2d(GLenum target, GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, @@ -3329,14 +2938,14 @@ save_Map2d(GLenum target, save_pointer(&n[10], pnts); } if (ctx->ExecuteFlag) { - CALL_Map2d(ctx->Exec, (target, + CALL_Map2d(ctx->Dispatch.Exec, (target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Map2f(GLenum target, GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, @@ -3362,13 +2971,13 @@ save_Map2f(GLenum target, save_pointer(&n[10], pnts); } if (ctx->ExecuteFlag) { - CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder, + CALL_Map2f(ctx->Dispatch.Exec, (target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, points)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2) { GET_CURRENT_CONTEXT(ctx); @@ -3381,19 +2990,19 @@ save_MapGrid1f(GLint un, GLfloat u1, GLfloat u2) n[3].f = u2; } if (ctx->ExecuteFlag) { - CALL_MapGrid1f(ctx->Exec, (un, u1, u2)); + CALL_MapGrid1f(ctx->Dispatch.Exec, (un, u1, u2)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MapGrid1d(GLint un, GLdouble u1, GLdouble u2) { save_MapGrid1f(un, (GLfloat) u1, (GLfloat) u2); } -static void GLAPIENTRY +void GLAPIENTRY save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GLfloat v2) { @@ -3410,13 +3019,13 @@ save_MapGrid2f(GLint un, GLfloat u1, GLfloat u2, n[6].f = v2; } if (ctx->ExecuteFlag) { - CALL_MapGrid2f(ctx->Exec, (un, u1, u2, vn, v1, v2)); + CALL_MapGrid2f(ctx->Dispatch.Exec, (un, u1, u2, vn, v1, v2)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2, GLint vn, GLdouble v1, GLdouble v2) { @@ -3425,7 +3034,7 @@ save_MapGrid2d(GLint un, GLdouble u1, GLdouble u2, } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixMode(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -3436,12 +3045,12 @@ save_MatrixMode(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_MatrixMode(ctx->Exec, (mode)); + CALL_MatrixMode(ctx->Dispatch.Exec, (mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultMatrixf(const GLfloat * m) { GET_CURRENT_CONTEXT(ctx); @@ -3455,12 +3064,12 @@ save_MultMatrixf(const GLfloat * m) } } if (ctx->ExecuteFlag) { - CALL_MultMatrixf(ctx->Exec, (m)); + CALL_MultMatrixf(ctx->Dispatch.Exec, (m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultMatrixd(const GLdouble * m) { GLfloat f[16]; @@ -3472,7 +3081,7 @@ save_MultMatrixd(const GLdouble * m) } -static void GLAPIENTRY +void GLAPIENTRY save_NewList(GLuint name, GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -3484,7 +3093,7 @@ save_NewList(GLuint name, GLenum mode) -static void GLAPIENTRY +void GLAPIENTRY save_Ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) { @@ -3501,12 +3110,12 @@ save_Ortho(GLdouble left, GLdouble right, n[6].f = (GLfloat) farval; } if (ctx->ExecuteFlag) { - CALL_Ortho(ctx->Exec, (left, right, bottom, top, nearval, farval)); + CALL_Ortho(ctx->Dispatch.Exec, (left, right, bottom, top, nearval, farval)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PatchParameteri(GLenum pname, const GLint value) { GET_CURRENT_CONTEXT(ctx); @@ -3518,12 +3127,12 @@ save_PatchParameteri(GLenum pname, const GLint value) n[2].i = value; } if (ctx->ExecuteFlag) { - CALL_PatchParameteri(ctx->Exec, (pname, value)); + CALL_PatchParameteri(ctx->Dispatch.Exec, (pname, value)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PatchParameterfv(GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -3549,12 +3158,12 @@ save_PatchParameterfv(GLenum pname, const GLfloat *params) } } if (ctx->ExecuteFlag) { - CALL_PatchParameterfv(ctx->Exec, (pname, params)); + CALL_PatchParameterfv(ctx->Dispatch.Exec, (pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values) { GET_CURRENT_CONTEXT(ctx); @@ -3567,12 +3176,12 @@ save_PixelMapfv(GLenum map, GLint mapsize, const GLfloat *values) save_pointer(&n[3], memdup(values, mapsize * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_PixelMapfv(ctx->Exec, (map, mapsize, values)); + CALL_PixelMapfv(ctx->Dispatch.Exec, (map, mapsize, values)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values) { GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; @@ -3591,7 +3200,7 @@ save_PixelMapuiv(GLenum map, GLint mapsize, const GLuint *values) } -static void GLAPIENTRY +void GLAPIENTRY save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values) { GLfloat fvalues[MAX_PIXEL_MAP_TABLE]; @@ -3610,7 +3219,7 @@ save_PixelMapusv(GLenum map, GLint mapsize, const GLushort *values) } -static void GLAPIENTRY +void GLAPIENTRY save_PixelTransferf(GLenum pname, GLfloat param) { GET_CURRENT_CONTEXT(ctx); @@ -3622,19 +3231,19 @@ save_PixelTransferf(GLenum pname, GLfloat param) n[2].f = param; } if (ctx->ExecuteFlag) { - CALL_PixelTransferf(ctx->Exec, (pname, param)); + CALL_PixelTransferf(ctx->Dispatch.Exec, (pname, param)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PixelTransferi(GLenum pname, GLint param) { save_PixelTransferf(pname, (GLfloat) param); } -static void GLAPIENTRY +void GLAPIENTRY save_PixelZoom(GLfloat xfactor, GLfloat yfactor) { GET_CURRENT_CONTEXT(ctx); @@ -3646,13 +3255,13 @@ save_PixelZoom(GLfloat xfactor, GLfloat yfactor) n[2].f = yfactor; } if (ctx->ExecuteFlag) { - CALL_PixelZoom(ctx->Exec, (xfactor, yfactor)); + CALL_PixelZoom(ctx->Dispatch.Exec, (xfactor, yfactor)); } } -static void GLAPIENTRY -save_PointParameterfvEXT(GLenum pname, const GLfloat *params) +void GLAPIENTRY +save_PointParameterfv(GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -3665,40 +3274,40 @@ save_PointParameterfvEXT(GLenum pname, const GLfloat *params) n[4].f = params[2]; } if (ctx->ExecuteFlag) { - CALL_PointParameterfv(ctx->Exec, (pname, params)); + CALL_PointParameterfv(ctx->Dispatch.Exec, (pname, params)); } } -static void GLAPIENTRY -save_PointParameterfEXT(GLenum pname, GLfloat param) +void GLAPIENTRY +save_PointParameterf(GLenum pname, GLfloat param) { GLfloat parray[3]; parray[0] = param; parray[1] = parray[2] = 0.0F; - save_PointParameterfvEXT(pname, parray); + save_PointParameterfv(pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_PointParameteri(GLenum pname, GLint param) { GLfloat parray[3]; parray[0] = (GLfloat) param; parray[1] = parray[2] = 0.0F; - save_PointParameterfvEXT(pname, parray); + save_PointParameterfv(pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_PointParameteriv(GLenum pname, const GLint * param) { GLfloat parray[3]; parray[0] = (GLfloat) param[0]; parray[1] = parray[2] = 0.0F; - save_PointParameterfvEXT(pname, parray); + save_PointParameterfv(pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_PointSize(GLfloat size) { GET_CURRENT_CONTEXT(ctx); @@ -3709,12 +3318,12 @@ save_PointSize(GLfloat size) n[1].f = size; } if (ctx->ExecuteFlag) { - CALL_PointSize(ctx->Exec, (size)); + CALL_PointSize(ctx->Dispatch.Exec, (size)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PolygonMode(GLenum face, GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -3726,12 +3335,12 @@ save_PolygonMode(GLenum face, GLenum mode) n[2].e = mode; } if (ctx->ExecuteFlag) { - CALL_PolygonMode(ctx->Exec, (face, mode)); + CALL_PolygonMode(ctx->Dispatch.Exec, (face, mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PolygonStipple(const GLubyte * pattern) { GET_CURRENT_CONTEXT(ctx); @@ -3746,12 +3355,12 @@ save_PolygonStipple(const GLubyte * pattern) pattern, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_PolygonStipple(ctx->Exec, ((GLubyte *) pattern)); + CALL_PolygonStipple(ctx->Dispatch.Exec, ((GLubyte *) pattern)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PolygonOffset(GLfloat factor, GLfloat units) { GET_CURRENT_CONTEXT(ctx); @@ -3763,12 +3372,12 @@ save_PolygonOffset(GLfloat factor, GLfloat units) n[2].f = units; } if (ctx->ExecuteFlag) { - CALL_PolygonOffset(ctx->Exec, (factor, units)); + CALL_PolygonOffset(ctx->Dispatch.Exec, (factor, units)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) { GET_CURRENT_CONTEXT(ctx); @@ -3781,47 +3390,47 @@ save_PolygonOffsetClampEXT(GLfloat factor, GLfloat units, GLfloat clamp) n[3].f = clamp; } if (ctx->ExecuteFlag) { - CALL_PolygonOffsetClampEXT(ctx->Exec, (factor, units, clamp)); + CALL_PolygonOffsetClampEXT(ctx->Dispatch.Exec, (factor, units, clamp)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PopAttrib(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_POP_ATTRIB, 0); if (ctx->ExecuteFlag) { - CALL_PopAttrib(ctx->Exec, ()); + CALL_PopAttrib(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_PopMatrix(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_POP_MATRIX, 0); if (ctx->ExecuteFlag) { - CALL_PopMatrix(ctx->Exec, ()); + CALL_PopMatrix(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_PopName(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_POP_NAME, 0); if (ctx->ExecuteFlag) { - CALL_PopName(ctx->Exec, ()); + CALL_PopName(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_PrioritizeTextures(GLsizei num, const GLuint * textures, const GLclampf * priorities) { @@ -3838,12 +3447,12 @@ save_PrioritizeTextures(GLsizei num, const GLuint * textures, } } if (ctx->ExecuteFlag) { - CALL_PrioritizeTextures(ctx->Exec, (num, textures, priorities)); + CALL_PrioritizeTextures(ctx->Dispatch.Exec, (num, textures, priorities)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PushAttrib(GLbitfield mask) { GET_CURRENT_CONTEXT(ctx); @@ -3854,24 +3463,24 @@ save_PushAttrib(GLbitfield mask) n[1].bf = mask; } if (ctx->ExecuteFlag) { - CALL_PushAttrib(ctx->Exec, (mask)); + CALL_PushAttrib(ctx->Dispatch.Exec, (mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PushMatrix(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_PUSH_MATRIX, 0); if (ctx->ExecuteFlag) { - CALL_PushMatrix(ctx->Exec, ()); + CALL_PushMatrix(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_PushName(GLuint name) { GET_CURRENT_CONTEXT(ctx); @@ -3882,12 +3491,12 @@ save_PushName(GLuint name) n[1].ui = name; } if (ctx->ExecuteFlag) { - CALL_PushName(ctx->Exec, (name)); + CALL_PushName(ctx->Dispatch.Exec, (name)); } } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { GET_CURRENT_CONTEXT(ctx); @@ -3901,152 +3510,152 @@ save_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[4].f = w; } if (ctx->ExecuteFlag) { - CALL_RasterPos4f(ctx->Exec, (x, y, z, w)); + CALL_RasterPos4f(ctx->Dispatch.Exec, (x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2d(GLdouble x, GLdouble y) { save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2f(GLfloat x, GLfloat y) { save_RasterPos4f(x, y, 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2i(GLint x, GLint y) { save_RasterPos4f((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2s(GLshort x, GLshort y) { save_RasterPos4f(x, y, 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3d(GLdouble x, GLdouble y, GLdouble z) { save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3f(GLfloat x, GLfloat y, GLfloat z) { save_RasterPos4f(x, y, z, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3i(GLint x, GLint y, GLint z) { save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3s(GLshort x, GLshort y, GLshort z) { save_RasterPos4f(x, y, z, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4i(GLint x, GLint y, GLint z, GLint w) { save_RasterPos4f((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w) { save_RasterPos4f(x, y, z, w); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2dv(const GLdouble * v) { save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2fv(const GLfloat * v) { save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2iv(const GLint * v) { save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos2sv(const GLshort * v) { save_RasterPos4f(v[0], v[1], 0.0F, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3dv(const GLdouble * v) { save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3fv(const GLfloat * v) { save_RasterPos4f(v[0], v[1], v[2], 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3iv(const GLint * v) { save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos3sv(const GLshort * v) { save_RasterPos4f(v[0], v[1], v[2], 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4dv(const GLdouble * v) { save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4fv(const GLfloat * v) { save_RasterPos4f(v[0], v[1], v[2], v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4iv(const GLint * v) { save_RasterPos4f((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_RasterPos4sv(const GLshort * v) { save_RasterPos4f(v[0], v[1], v[2], v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_PassThrough(GLfloat token) { GET_CURRENT_CONTEXT(ctx); @@ -4057,12 +3666,12 @@ save_PassThrough(GLfloat token) n[1].f = token; } if (ctx->ExecuteFlag) { - CALL_PassThrough(ctx->Exec, (token)); + CALL_PassThrough(ctx->Dispatch.Exec, (token)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ReadBuffer(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -4073,12 +3682,12 @@ save_ReadBuffer(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_ReadBuffer(ctx->Exec, (mode)); + CALL_ReadBuffer(ctx->Dispatch.Exec, (mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -4092,19 +3701,19 @@ save_Rotatef(GLfloat angle, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } if (ctx->ExecuteFlag) { - CALL_Rotatef(ctx->Exec, (angle, x, y, z)); + CALL_Rotatef(ctx->Dispatch.Exec, (angle, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Rotated(GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { save_Rotatef((GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z); } -static void GLAPIENTRY +void GLAPIENTRY save_Scalef(GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -4117,19 +3726,19 @@ save_Scalef(GLfloat x, GLfloat y, GLfloat z) n[3].f = z; } if (ctx->ExecuteFlag) { - CALL_Scalef(ctx->Exec, (x, y, z)); + CALL_Scalef(ctx->Dispatch.Exec, (x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Scaled(GLdouble x, GLdouble y, GLdouble z) { save_Scalef((GLfloat) x, (GLfloat) y, (GLfloat) z); } -static void GLAPIENTRY +void GLAPIENTRY save_Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { GET_CURRENT_CONTEXT(ctx); @@ -4143,12 +3752,12 @@ save_Scissor(GLint x, GLint y, GLsizei width, GLsizei height) n[4].i = height; } if (ctx->ExecuteFlag) { - CALL_Scissor(ctx->Exec, (x, y, width, height)); + CALL_Scissor(ctx->Dispatch.Exec, (x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ShadeModel(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -4156,7 +3765,7 @@ save_ShadeModel(GLenum mode) ASSERT_OUTSIDE_SAVE_BEGIN_END(ctx); if (ctx->ExecuteFlag) { - CALL_ShadeModel(ctx->Exec, (mode)); + CALL_ShadeModel(ctx->Dispatch.Exec, (mode)); } /* Don't compile this call if it's a no-op. @@ -4177,7 +3786,7 @@ save_ShadeModel(GLenum mode) } -static void GLAPIENTRY +void GLAPIENTRY save_StencilFunc(GLenum func, GLint ref, GLuint mask) { GET_CURRENT_CONTEXT(ctx); @@ -4190,12 +3799,12 @@ save_StencilFunc(GLenum func, GLint ref, GLuint mask) n[3].ui = mask; } if (ctx->ExecuteFlag) { - CALL_StencilFunc(ctx->Exec, (func, ref, mask)); + CALL_StencilFunc(ctx->Dispatch.Exec, (func, ref, mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_StencilMask(GLuint mask) { GET_CURRENT_CONTEXT(ctx); @@ -4206,12 +3815,12 @@ save_StencilMask(GLuint mask) n[1].ui = mask; } if (ctx->ExecuteFlag) { - CALL_StencilMask(ctx->Exec, (mask)); + CALL_StencilMask(ctx->Dispatch.Exec, (mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) { GET_CURRENT_CONTEXT(ctx); @@ -4224,12 +3833,12 @@ save_StencilOp(GLenum fail, GLenum zfail, GLenum zpass) n[3].e = zpass; } if (ctx->ExecuteFlag) { - CALL_StencilOp(ctx->Exec, (fail, zfail, zpass)); + CALL_StencilOp(ctx->Dispatch.Exec, (fail, zfail, zpass)); } } -static void GLAPIENTRY +void GLAPIENTRY save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) { GET_CURRENT_CONTEXT(ctx); @@ -4243,12 +3852,12 @@ save_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) n[4].ui = mask; } if (ctx->ExecuteFlag) { - CALL_StencilFuncSeparate(ctx->Exec, (face, func, ref, mask)); + CALL_StencilFuncSeparate(ctx->Dispatch.Exec, (face, func, ref, mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask) { @@ -4272,13 +3881,13 @@ save_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref, n[4].ui = mask; } if (ctx->ExecuteFlag) { - CALL_StencilFuncSeparate(ctx->Exec, (GL_FRONT, frontfunc, ref, mask)); - CALL_StencilFuncSeparate(ctx->Exec, (GL_BACK, backfunc, ref, mask)); + CALL_StencilFuncSeparate(ctx->Dispatch.Exec, (GL_FRONT, frontfunc, ref, mask)); + CALL_StencilFuncSeparate(ctx->Dispatch.Exec, (GL_BACK, backfunc, ref, mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_StencilMaskSeparate(GLenum face, GLuint mask) { GET_CURRENT_CONTEXT(ctx); @@ -4290,12 +3899,12 @@ save_StencilMaskSeparate(GLenum face, GLuint mask) n[2].ui = mask; } if (ctx->ExecuteFlag) { - CALL_StencilMaskSeparate(ctx->Exec, (face, mask)); + CALL_StencilMaskSeparate(ctx->Dispatch.Exec, (face, mask)); } } -static void GLAPIENTRY +void GLAPIENTRY save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) { GET_CURRENT_CONTEXT(ctx); @@ -4309,12 +3918,12 @@ save_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass) n[4].e = zpass; } if (ctx->ExecuteFlag) { - CALL_StencilOpSeparate(ctx->Exec, (face, fail, zfail, zpass)); + CALL_StencilOpSeparate(ctx->Dispatch.Exec, (face, fail, zfail, zpass)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -4336,12 +3945,12 @@ save_TexEnvfv(GLenum target, GLenum pname, const GLfloat *params) } } if (ctx->ExecuteFlag) { - CALL_TexEnvfv(ctx->Exec, (target, pname, params)); + CALL_TexEnvfv(ctx->Dispatch.Exec, (target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TexEnvf(GLenum target, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -4351,7 +3960,7 @@ save_TexEnvf(GLenum target, GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexEnvi(GLenum target, GLenum pname, GLint param) { GLfloat p[4]; @@ -4361,7 +3970,7 @@ save_TexEnvi(GLenum target, GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexEnviv(GLenum target, GLenum pname, const GLint * param) { GLfloat p[4]; @@ -4379,7 +3988,7 @@ save_TexEnviv(GLenum target, GLenum pname, const GLint * param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -4395,12 +4004,12 @@ save_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) n[6].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_TexGenfv(ctx->Exec, (coord, pname, params)); + CALL_TexGenfv(ctx->Dispatch.Exec, (coord, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TexGeniv(GLenum coord, GLenum pname, const GLint *params) { GLfloat p[4]; @@ -4412,7 +4021,7 @@ save_TexGeniv(GLenum coord, GLenum pname, const GLint *params) } -static void GLAPIENTRY +void GLAPIENTRY save_TexGend(GLenum coord, GLenum pname, GLdouble param) { GLfloat parray[4]; @@ -4422,7 +4031,7 @@ save_TexGend(GLenum coord, GLenum pname, GLdouble param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params) { GLfloat p[4]; @@ -4434,7 +4043,7 @@ save_TexGendv(GLenum coord, GLenum pname, const GLdouble *params) } -static void GLAPIENTRY +void GLAPIENTRY save_TexGenf(GLenum coord, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -4444,7 +4053,7 @@ save_TexGenf(GLenum coord, GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexGeni(GLenum coord, GLenum pname, GLint param) { GLint parray[4]; @@ -4454,7 +4063,7 @@ save_TexGeni(GLenum coord, GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -4470,12 +4079,12 @@ save_TexParameterfv(GLenum target, GLenum pname, const GLfloat *params) n[6].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_TexParameterfv(ctx->Exec, (target, pname, params)); + CALL_TexParameterfv(ctx->Dispatch.Exec, (target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TexParameterf(GLenum target, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -4485,7 +4094,7 @@ save_TexParameterf(GLenum target, GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexParameteri(GLenum target, GLenum pname, GLint param) { GLfloat fparam[4]; @@ -4495,7 +4104,7 @@ save_TexParameteri(GLenum target, GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_TexParameteriv(GLenum target, GLenum pname, const GLint *params) { GLfloat fparam[4]; @@ -4505,7 +4114,7 @@ save_TexParameteriv(GLenum target, GLenum pname, const GLint *params) } -static void GLAPIENTRY +void GLAPIENTRY save_TexImage1D(GLenum target, GLint level, GLint components, GLsizei width, GLint border, @@ -4514,7 +4123,7 @@ save_TexImage1D(GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_1D) { /* don't compile, execute immediately */ - CALL_TexImage1D(ctx->Exec, (target, level, components, width, + CALL_TexImage1D(ctx->Dispatch.Exec, (target, level, components, width, border, format, type, pixels)); } else { @@ -4534,14 +4143,14 @@ save_TexImage1D(GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TexImage1D(ctx->Exec, (target, level, components, width, + CALL_TexImage1D(ctx->Dispatch.Exec, (target, level, components, width, border, format, type, pixels)); } } } -static void GLAPIENTRY +void GLAPIENTRY save_TexImage2D(GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, @@ -4550,7 +4159,7 @@ save_TexImage2D(GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_2D) { /* don't compile, execute immediately */ - CALL_TexImage2D(ctx->Exec, (target, level, components, width, + CALL_TexImage2D(ctx->Dispatch.Exec, (target, level, components, width, height, border, format, type, pixels)); } else { @@ -4571,14 +4180,14 @@ save_TexImage2D(GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TexImage2D(ctx->Exec, (target, level, components, width, + CALL_TexImage2D(ctx->Dispatch.Exec, (target, level, components, width, height, border, format, type, pixels)); } } } -static void GLAPIENTRY +void GLAPIENTRY save_TexImage3D(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, @@ -4588,7 +4197,7 @@ save_TexImage3D(GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_3D) { /* don't compile, execute immediately */ - CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width, + CALL_TexImage3D(ctx->Dispatch.Exec, (target, level, internalFormat, width, height, depth, border, format, type, pixels)); } @@ -4611,7 +4220,7 @@ save_TexImage3D(GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TexImage3D(ctx->Exec, (target, level, internalFormat, width, + CALL_TexImage3D(ctx->Dispatch.Exec, (target, level, internalFormat, width, height, depth, border, format, type, pixels)); } @@ -4619,7 +4228,7 @@ save_TexImage3D(GLenum target, } -static void GLAPIENTRY +void GLAPIENTRY save_TexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels) @@ -4642,13 +4251,13 @@ save_TexSubImage1D(GLenum target, GLint level, GLint xoffset, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TexSubImage1D(ctx->Exec, (target, level, xoffset, width, + CALL_TexSubImage1D(ctx->Dispatch.Exec, (target, level, xoffset, width, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, @@ -4674,13 +4283,13 @@ save_TexSubImage2D(GLenum target, GLint level, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TexSubImage2D(ctx->Exec, (target, level, xoffset, yoffset, + CALL_TexSubImage2D(ctx->Dispatch.Exec, (target, level, xoffset, yoffset, width, height, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, @@ -4708,7 +4317,7 @@ save_TexSubImage3D(GLenum target, GLint level, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TexSubImage3D(ctx->Exec, (target, level, + CALL_TexSubImage3D(ctx->Dispatch.Exec, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels)); @@ -4716,7 +4325,7 @@ save_TexSubImage3D(GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_Translatef(GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -4729,12 +4338,12 @@ save_Translatef(GLfloat x, GLfloat y, GLfloat z) n[3].f = z; } if (ctx->ExecuteFlag) { - CALL_Translatef(ctx->Exec, (x, y, z)); + CALL_Translatef(ctx->Dispatch.Exec, (x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Translated(GLdouble x, GLdouble y, GLdouble z) { save_Translatef((GLfloat) x, (GLfloat) y, (GLfloat) z); @@ -4742,7 +4351,7 @@ save_Translated(GLdouble x, GLdouble y, GLdouble z) -static void GLAPIENTRY +void GLAPIENTRY save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) { GET_CURRENT_CONTEXT(ctx); @@ -4756,11 +4365,11 @@ save_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) n[4].i = (GLint) height; } if (ctx->ExecuteFlag) { - CALL_Viewport(ctx->Exec, (x, y, width, height)); + CALL_Viewport(ctx->Dispatch.Exec, (x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat width, GLfloat height) { @@ -4776,11 +4385,11 @@ save_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat width, n[5].f = height; } if (ctx->ExecuteFlag) { - CALL_ViewportIndexedf(ctx->Exec, (index, x, y, width, height)); + CALL_ViewportIndexedf(ctx->Dispatch.Exec, (index, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ViewportIndexedfv(GLuint index, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); @@ -4795,11 +4404,11 @@ save_ViewportIndexedfv(GLuint index, const GLfloat *v) n[5].f = v[3]; } if (ctx->ExecuteFlag) { - CALL_ViewportIndexedfv(ctx->Exec, (index, v)); + CALL_ViewportIndexedfv(ctx->Dispatch.Exec, (index, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); @@ -4812,11 +4421,11 @@ save_ViewportArrayv(GLuint first, GLsizei count, const GLfloat *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ViewportArrayv(ctx->Exec, (first, count, v)); + CALL_ViewportArrayv(ctx->Dispatch.Exec, (first, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height) { @@ -4832,11 +4441,11 @@ save_ScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, n[5].si = height; } if (ctx->ExecuteFlag) { - CALL_ScissorIndexed(ctx->Exec, (index, left, bottom, width, height)); + CALL_ScissorIndexed(ctx->Dispatch.Exec, (index, left, bottom, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ScissorIndexedv(GLuint index, const GLint *v) { GET_CURRENT_CONTEXT(ctx); @@ -4851,11 +4460,11 @@ save_ScissorIndexedv(GLuint index, const GLint *v) n[5].si = v[3]; } if (ctx->ExecuteFlag) { - CALL_ScissorIndexedv(ctx->Exec, (index, v)); + CALL_ScissorIndexedv(ctx->Dispatch.Exec, (index, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ScissorArrayv(GLuint first, GLsizei count, const GLint *v) { GET_CURRENT_CONTEXT(ctx); @@ -4868,11 +4477,11 @@ save_ScissorArrayv(GLuint first, GLsizei count, const GLint *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_ScissorArrayv(ctx->Exec, (first, count, v)); + CALL_ScissorArrayv(ctx->Dispatch.Exec, (first, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DepthRangeIndexed(GLuint index, GLclampd n, GLclampd f) { GET_CURRENT_CONTEXT(ctx); @@ -4888,11 +4497,11 @@ save_DepthRangeIndexed(GLuint index, GLclampd n, GLclampd f) node[3].f = f; } if (ctx->ExecuteFlag) { - CALL_DepthRangeIndexed(ctx->Exec, (index, n, f)); + CALL_DepthRangeIndexed(ctx->Dispatch.Exec, (index, n, f)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v) { GET_CURRENT_CONTEXT(ctx); @@ -4905,11 +4514,11 @@ save_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLclampd))); } if (ctx->ExecuteFlag) { - CALL_DepthRangeArrayv(ctx->Exec, (first, count, v)); + CALL_DepthRangeArrayv(ctx->Dispatch.Exec, (first, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w) { GET_CURRENT_CONTEXT(ctx); @@ -4923,145 +4532,145 @@ save_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[4].f = w; } if (ctx->ExecuteFlag) { - CALL_WindowPos4fMESA(ctx->Exec, (x, y, z, w)); + CALL_WindowPos4fMESA(ctx->Dispatch.Exec, (x, y, z, w)); } } -static void GLAPIENTRY -save_WindowPos2dMESA(GLdouble x, GLdouble y) +void GLAPIENTRY +save_WindowPos2d(GLdouble x, GLdouble y) { save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos2fMESA(GLfloat x, GLfloat y) +void GLAPIENTRY +save_WindowPos2f(GLfloat x, GLfloat y) { save_WindowPos4fMESA(x, y, 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos2iMESA(GLint x, GLint y) +void GLAPIENTRY +save_WindowPos2i(GLint x, GLint y) { save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos2sMESA(GLshort x, GLshort y) +void GLAPIENTRY +save_WindowPos2s(GLshort x, GLshort y) { save_WindowPos4fMESA(x, y, 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos3dMESA(GLdouble x, GLdouble y, GLdouble z) +void GLAPIENTRY +save_WindowPos3d(GLdouble x, GLdouble y, GLdouble z) { save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); } -static void GLAPIENTRY -save_WindowPos3fMESA(GLfloat x, GLfloat y, GLfloat z) +void GLAPIENTRY +save_WindowPos3f(GLfloat x, GLfloat y, GLfloat z) { save_WindowPos4fMESA(x, y, z, 1.0F); } -static void GLAPIENTRY -save_WindowPos3iMESA(GLint x, GLint y, GLint z) +void GLAPIENTRY +save_WindowPos3i(GLint x, GLint y, GLint z) { save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, 1.0F); } -static void GLAPIENTRY -save_WindowPos3sMESA(GLshort x, GLshort y, GLshort z) +void GLAPIENTRY +save_WindowPos3s(GLshort x, GLshort y, GLshort z) { save_WindowPos4fMESA(x, y, z, 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w) { save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w) { save_WindowPos4fMESA((GLfloat) x, (GLfloat) y, (GLfloat) z, (GLfloat) w); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w) { save_WindowPos4fMESA(x, y, z, w); } -static void GLAPIENTRY -save_WindowPos2dvMESA(const GLdouble * v) +void GLAPIENTRY +save_WindowPos2dv(const GLdouble * v) { save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos2fvMESA(const GLfloat * v) +void GLAPIENTRY +save_WindowPos2fv(const GLfloat * v) { save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos2ivMESA(const GLint * v) +void GLAPIENTRY +save_WindowPos2iv(const GLint * v) { save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos2svMESA(const GLshort * v) +void GLAPIENTRY +save_WindowPos2sv(const GLshort * v) { save_WindowPos4fMESA(v[0], v[1], 0.0F, 1.0F); } -static void GLAPIENTRY -save_WindowPos3dvMESA(const GLdouble * v) +void GLAPIENTRY +save_WindowPos3dv(const GLdouble * v) { save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); } -static void GLAPIENTRY -save_WindowPos3fvMESA(const GLfloat * v) +void GLAPIENTRY +save_WindowPos3fv(const GLfloat * v) { save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); } -static void GLAPIENTRY -save_WindowPos3ivMESA(const GLint * v) +void GLAPIENTRY +save_WindowPos3iv(const GLint * v) { save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], 1.0F); } -static void GLAPIENTRY -save_WindowPos3svMESA(const GLshort * v) +void GLAPIENTRY +save_WindowPos3sv(const GLshort * v) { save_WindowPos4fMESA(v[0], v[1], v[2], 1.0F); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4dvMESA(const GLdouble * v) { save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4fvMESA(const GLfloat * v) { save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4ivMESA(const GLint * v) { save_WindowPos4fMESA((GLfloat) v[0], (GLfloat) v[1], (GLfloat) v[2], (GLfloat) v[3]); } -static void GLAPIENTRY +void GLAPIENTRY save_WindowPos4svMESA(const GLshort * v) { save_WindowPos4fMESA(v[0], v[1], v[2], v[3]); @@ -5070,8 +4679,8 @@ save_WindowPos4svMESA(const GLshort * v) /* GL_ARB_multitexture */ -static void GLAPIENTRY -save_ActiveTextureARB(GLenum target) +void GLAPIENTRY +save_ActiveTexture(GLenum target) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -5081,15 +4690,15 @@ save_ActiveTextureARB(GLenum target) n[1].e = target; } if (ctx->ExecuteFlag) { - CALL_ActiveTexture(ctx->Exec, (target)); + CALL_ActiveTexture(ctx->Dispatch.Exec, (target)); } } /* GL_ARB_transpose_matrix */ -static void GLAPIENTRY -save_LoadTransposeMatrixdARB(const GLdouble m[16]) +void GLAPIENTRY +save_LoadTransposeMatrixd(const GLdouble *m) { GLfloat tm[16]; _math_transposefd(tm, m); @@ -5097,8 +4706,8 @@ save_LoadTransposeMatrixdARB(const GLdouble m[16]) } -static void GLAPIENTRY -save_LoadTransposeMatrixfARB(const GLfloat m[16]) +void GLAPIENTRY +save_LoadTransposeMatrixf(const GLfloat *m) { GLfloat tm[16]; _math_transposef(tm, m); @@ -5106,8 +4715,8 @@ save_LoadTransposeMatrixfARB(const GLfloat m[16]) } -static void GLAPIENTRY -save_MultTransposeMatrixdARB(const GLdouble m[16]) +void GLAPIENTRY +save_MultTransposeMatrixd(const GLdouble *m) { GLfloat tm[16]; _math_transposefd(tm, m); @@ -5115,8 +4724,8 @@ save_MultTransposeMatrixdARB(const GLdouble m[16]) } -static void GLAPIENTRY -save_MultTransposeMatrixfARB(const GLfloat m[16]) +void GLAPIENTRY +save_MultTransposeMatrixf(const GLfloat *m) { GLfloat tm[16]; _math_transposef(tm, m); @@ -5143,8 +4752,8 @@ static GLvoid *copy_data(const GLvoid *data, GLsizei size, const char *func) /* GL_ARB_texture_compression */ -static void GLAPIENTRY -save_CompressedTexImage1DARB(GLenum target, GLint level, +void GLAPIENTRY +save_CompressedTexImage1D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, const GLvoid * data) @@ -5152,7 +4761,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_1D) { /* don't compile, execute immediately */ - CALL_CompressedTexImage1D(ctx->Exec, (target, level, internalFormat, + CALL_CompressedTexImage1D(ctx->Dispatch.Exec, (target, level, internalFormat, width, border, imageSize, data)); } @@ -5173,7 +4782,7 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTexImage1DARB")); } if (ctx->ExecuteFlag) { - CALL_CompressedTexImage1D(ctx->Exec, + CALL_CompressedTexImage1D(ctx->Dispatch.Exec, (target, level, internalFormat, width, border, imageSize, data)); } @@ -5181,8 +4790,8 @@ save_CompressedTexImage1DARB(GLenum target, GLint level, } -static void GLAPIENTRY -save_CompressedTexImage2DARB(GLenum target, GLint level, +void GLAPIENTRY +save_CompressedTexImage2D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid * data) @@ -5190,7 +4799,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_2D) { /* don't compile, execute immediately */ - CALL_CompressedTexImage2D(ctx->Exec, (target, level, internalFormat, + CALL_CompressedTexImage2D(ctx->Dispatch.Exec, (target, level, internalFormat, width, height, border, imageSize, data)); } @@ -5212,7 +4821,7 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTexImage2DARB")); } if (ctx->ExecuteFlag) { - CALL_CompressedTexImage2D(ctx->Exec, + CALL_CompressedTexImage2D(ctx->Dispatch.Exec, (target, level, internalFormat, width, height, border, imageSize, data)); } @@ -5220,8 +4829,8 @@ save_CompressedTexImage2DARB(GLenum target, GLint level, } -static void GLAPIENTRY -save_CompressedTexImage3DARB(GLenum target, GLint level, +void GLAPIENTRY +save_CompressedTexImage3D(GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLsizei imageSize, const GLvoid * data) @@ -5229,7 +4838,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_3D) { /* don't compile, execute immediately */ - CALL_CompressedTexImage3D(ctx->Exec, (target, level, internalFormat, + CALL_CompressedTexImage3D(ctx->Dispatch.Exec, (target, level, internalFormat, width, height, depth, border, imageSize, data)); } @@ -5252,7 +4861,7 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTexImage3DARB")); } if (ctx->ExecuteFlag) { - CALL_CompressedTexImage3D(ctx->Exec, + CALL_CompressedTexImage3D(ctx->Dispatch.Exec, (target, level, internalFormat, width, height, depth, border, imageSize, data)); @@ -5261,8 +4870,8 @@ save_CompressedTexImage3DARB(GLenum target, GLint level, } -static void GLAPIENTRY -save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, +void GLAPIENTRY +save_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data) { @@ -5283,15 +4892,15 @@ save_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset, copy_data(data, imageSize, "glCompressedTexSubImage1DARB")); } if (ctx->ExecuteFlag) { - CALL_CompressedTexSubImage1D(ctx->Exec, (target, level, xoffset, + CALL_CompressedTexSubImage1D(ctx->Dispatch.Exec, (target, level, xoffset, width, format, imageSize, data)); } } -static void GLAPIENTRY -save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, +void GLAPIENTRY +save_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const GLvoid * data) @@ -5315,15 +4924,15 @@ save_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset, copy_data(data, imageSize, "glCompressedTexSubImage2DARB")); } if (ctx->ExecuteFlag) { - CALL_CompressedTexSubImage2D(ctx->Exec, + CALL_CompressedTexSubImage2D(ctx->Dispatch.Exec, (target, level, xoffset, yoffset, width, height, format, imageSize, data)); } } -static void GLAPIENTRY -save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, +void GLAPIENTRY +save_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const GLvoid * data) @@ -5349,7 +4958,7 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, copy_data(data, imageSize, "glCompressedTexSubImage3DARB")); } if (ctx->ExecuteFlag) { - CALL_CompressedTexSubImage3D(ctx->Exec, + CALL_CompressedTexSubImage3D(ctx->Dispatch.Exec, (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data)); @@ -5358,8 +4967,8 @@ save_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset, /* GL_ARB_multisample */ -static void GLAPIENTRY -save_SampleCoverageARB(GLclampf value, GLboolean invert) +void GLAPIENTRY +save_SampleCoverage(GLclampf value, GLboolean invert) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -5370,7 +4979,7 @@ save_SampleCoverageARB(GLclampf value, GLboolean invert) n[2].b = invert; } if (ctx->ExecuteFlag) { - CALL_SampleCoverage(ctx->Exec, (value, invert)); + CALL_SampleCoverage(ctx->Dispatch.Exec, (value, invert)); } } @@ -5378,7 +4987,7 @@ save_SampleCoverageARB(GLclampf value, GLboolean invert) /* * GL_ARB_vertex_program */ -static void GLAPIENTRY +void GLAPIENTRY save_BindProgramARB(GLenum target, GLuint id) { GET_CURRENT_CONTEXT(ctx); @@ -5390,11 +4999,11 @@ save_BindProgramARB(GLenum target, GLuint id) n[2].ui = id; } if (ctx->ExecuteFlag) { - CALL_BindProgramARB(ctx->Exec, (target, id)); + CALL_BindProgramARB(ctx->Dispatch.Exec, (target, id)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramEnvParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { @@ -5411,12 +5020,12 @@ save_ProgramEnvParameter4fARB(GLenum target, GLuint index, n[6].f = w; } if (ctx->ExecuteFlag) { - CALL_ProgramEnvParameter4fARB(ctx->Exec, (target, index, x, y, z, w)); + CALL_ProgramEnvParameter4fARB(ctx->Dispatch.Exec, (target, index, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramEnvParameter4fvARB(GLenum target, GLuint index, const GLfloat *params) { @@ -5425,7 +5034,7 @@ save_ProgramEnvParameter4fvARB(GLenum target, GLuint index, } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat * params) { @@ -5452,12 +5061,12 @@ save_ProgramEnvParameters4fvEXT(GLenum target, GLuint index, GLsizei count, } if (ctx->ExecuteFlag) { - CALL_ProgramEnvParameters4fvEXT(ctx->Exec, (target, index, count, params)); + CALL_ProgramEnvParameters4fvEXT(ctx->Dispatch.Exec, (target, index, count, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramEnvParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { @@ -5467,7 +5076,7 @@ save_ProgramEnvParameter4dARB(GLenum target, GLuint index, } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramEnvParameter4dvARB(GLenum target, GLuint index, const GLdouble *params) { @@ -5478,7 +5087,7 @@ save_ProgramEnvParameter4dvARB(GLenum target, GLuint index, } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramLocalParameter4fARB(GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { @@ -5495,12 +5104,12 @@ save_ProgramLocalParameter4fARB(GLenum target, GLuint index, n[6].f = w; } if (ctx->ExecuteFlag) { - CALL_ProgramLocalParameter4fARB(ctx->Exec, (target, index, x, y, z, w)); + CALL_ProgramLocalParameter4fARB(ctx->Dispatch.Exec, (target, index, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramLocalParameter4fvARB(GLenum target, GLuint index, const GLfloat *params) { @@ -5517,12 +5126,12 @@ save_ProgramLocalParameter4fvARB(GLenum target, GLuint index, n[6].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_ProgramLocalParameter4fvARB(ctx->Exec, (target, index, params)); + CALL_ProgramLocalParameter4fvARB(ctx->Dispatch.Exec, (target, index, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, const GLfloat *params) { @@ -5549,12 +5158,12 @@ save_ProgramLocalParameters4fvEXT(GLenum target, GLuint index, GLsizei count, } if (ctx->ExecuteFlag) { - CALL_ProgramLocalParameters4fvEXT(ctx->Exec, (target, index, count, params)); + CALL_ProgramLocalParameters4fvEXT(ctx->Dispatch.Exec, (target, index, count, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramLocalParameter4dARB(GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) @@ -5572,12 +5181,12 @@ save_ProgramLocalParameter4dARB(GLenum target, GLuint index, n[6].f = (GLfloat) w; } if (ctx->ExecuteFlag) { - CALL_ProgramLocalParameter4dARB(ctx->Exec, (target, index, x, y, z, w)); + CALL_ProgramLocalParameter4dARB(ctx->Dispatch.Exec, (target, index, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramLocalParameter4dvARB(GLenum target, GLuint index, const GLdouble *params) { @@ -5594,13 +5203,13 @@ save_ProgramLocalParameter4dvARB(GLenum target, GLuint index, n[6].f = (GLfloat) params[3]; } if (ctx->ExecuteFlag) { - CALL_ProgramLocalParameter4dvARB(ctx->Exec, (target, index, params)); + CALL_ProgramLocalParameter4dvARB(ctx->Dispatch.Exec, (target, index, params)); } } /* GL_EXT_stencil_two_side */ -static void GLAPIENTRY +void GLAPIENTRY save_ActiveStencilFaceEXT(GLenum face) { GET_CURRENT_CONTEXT(ctx); @@ -5611,13 +5220,13 @@ save_ActiveStencilFaceEXT(GLenum face) n[1].e = face; } if (ctx->ExecuteFlag) { - CALL_ActiveStencilFaceEXT(ctx->Exec, (face)); + CALL_ActiveStencilFaceEXT(ctx->Dispatch.Exec, (face)); } } /* GL_EXT_depth_bounds_test */ -static void GLAPIENTRY +void GLAPIENTRY save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax) { GET_CURRENT_CONTEXT(ctx); @@ -5629,13 +5238,13 @@ save_DepthBoundsEXT(GLclampd zmin, GLclampd zmax) n[2].f = (GLfloat) zmax; } if (ctx->ExecuteFlag) { - CALL_DepthBoundsEXT(ctx->Exec, (zmin, zmax)); + CALL_DepthBoundsEXT(ctx->Dispatch.Exec, (zmin, zmax)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, const GLvoid * string) { @@ -5658,13 +5267,13 @@ save_ProgramStringARB(GLenum target, GLenum format, GLsizei len, save_pointer(&n[4], programCopy); } if (ctx->ExecuteFlag) { - CALL_ProgramStringARB(ctx->Exec, (target, format, len, string)); + CALL_ProgramStringARB(ctx->Dispatch.Exec, (target, format, len, string)); } } -static void GLAPIENTRY -save_BeginQueryARB(GLenum target, GLuint id) +void GLAPIENTRY +save_BeginQuery(GLenum target, GLuint id) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -5675,12 +5284,12 @@ save_BeginQueryARB(GLenum target, GLuint id) n[2].ui = id; } if (ctx->ExecuteFlag) { - CALL_BeginQuery(ctx->Exec, (target, id)); + CALL_BeginQuery(ctx->Dispatch.Exec, (target, id)); } } -static void GLAPIENTRY -save_EndQueryARB(GLenum target) +void GLAPIENTRY +save_EndQuery(GLenum target) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -5690,11 +5299,11 @@ save_EndQueryARB(GLenum target) n[1].e = target; } if (ctx->ExecuteFlag) { - CALL_EndQuery(ctx->Exec, (target)); + CALL_EndQuery(ctx->Dispatch.Exec, (target)); } } -static void GLAPIENTRY +void GLAPIENTRY save_QueryCounter(GLuint id, GLenum target) { GET_CURRENT_CONTEXT(ctx); @@ -5706,11 +5315,11 @@ save_QueryCounter(GLuint id, GLenum target) n[2].e = target; } if (ctx->ExecuteFlag) { - CALL_QueryCounter(ctx->Exec, (id, target)); + CALL_QueryCounter(ctx->Dispatch.Exec, (id, target)); } } -static void GLAPIENTRY +void GLAPIENTRY save_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) { GET_CURRENT_CONTEXT(ctx); @@ -5723,11 +5332,11 @@ save_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) n[3].ui = id; } if (ctx->ExecuteFlag) { - CALL_BeginQueryIndexed(ctx->Exec, (target, index, id)); + CALL_BeginQueryIndexed(ctx->Dispatch.Exec, (target, index, id)); } } -static void GLAPIENTRY +void GLAPIENTRY save_EndQueryIndexed(GLenum target, GLuint index) { GET_CURRENT_CONTEXT(ctx); @@ -5739,13 +5348,13 @@ save_EndQueryIndexed(GLenum target, GLuint index) n[2].ui = index; } if (ctx->ExecuteFlag) { - CALL_EndQueryIndexed(ctx->Exec, (target, index)); + CALL_EndQueryIndexed(ctx->Dispatch.Exec, (target, index)); } } -static void GLAPIENTRY -save_DrawBuffersARB(GLsizei count, const GLenum * buffers) +void GLAPIENTRY +save_DrawBuffers(GLsizei count, const GLenum * buffers) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -5761,11 +5370,11 @@ save_DrawBuffersARB(GLsizei count, const GLenum * buffers) } } if (ctx->ExecuteFlag) { - CALL_DrawBuffers(ctx->Exec, (count, buffers)); + CALL_DrawBuffers(ctx->Dispatch.Exec, (count, buffers)); } } -static void GLAPIENTRY +void GLAPIENTRY save_BindFragmentShaderATI(GLuint id) { GET_CURRENT_CONTEXT(ctx); @@ -5776,11 +5385,11 @@ save_BindFragmentShaderATI(GLuint id) n[1].ui = id; } if (ctx->ExecuteFlag) { - CALL_BindFragmentShaderATI(ctx->Exec, (id)); + CALL_BindFragmentShaderATI(ctx->Dispatch.Exec, (id)); } } -static void GLAPIENTRY +void GLAPIENTRY save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value) { GET_CURRENT_CONTEXT(ctx); @@ -5795,7 +5404,7 @@ save_SetFragmentShaderConstantATI(GLuint dst, const GLfloat *value) n[5].f = value[3]; } if (ctx->ExecuteFlag) { - CALL_SetFragmentShaderConstantATI(ctx->Exec, (dst, value)); + CALL_SetFragmentShaderConstantATI(ctx->Dispatch.Exec, (dst, value)); } } @@ -5810,7 +5419,7 @@ save_EvalCoord1f(GLfloat x) n[1].f = x; } if (ctx->ExecuteFlag) { - CALL_EvalCoord1f(ctx->Exec, (x)); + CALL_EvalCoord1f(ctx->Dispatch.Exec, (x)); } } @@ -5832,7 +5441,7 @@ save_EvalCoord2f(GLfloat x, GLfloat y) n[2].f = y; } if (ctx->ExecuteFlag) { - CALL_EvalCoord2f(ctx->Exec, (x, y)); + CALL_EvalCoord2f(ctx->Dispatch.Exec, (x, y)); } } @@ -5854,7 +5463,7 @@ save_EvalPoint1(GLint x) n[1].i = x; } if (ctx->ExecuteFlag) { - CALL_EvalPoint1(ctx->Exec, (x)); + CALL_EvalPoint1(ctx->Dispatch.Exec, (x)); } } @@ -5870,7 +5479,7 @@ save_EvalPoint2(GLint x, GLint y) n[2].i = y; } if (ctx->ExecuteFlag) { - CALL_EvalPoint2(ctx->Exec, (x, y)); + CALL_EvalPoint2(ctx->Dispatch.Exec, (x, y)); } } @@ -5928,7 +5537,7 @@ save_Materialfv(GLenum face, GLenum pname, const GLfloat * param) } if (ctx->ExecuteFlag) { - CALL_Materialfv(ctx->Exec, (face, pname, param)); + CALL_Materialfv(ctx->Dispatch.Exec, (face, pname, param)); } bitmask = _mesa_material_bitmask(ctx, face, pname, ~0, NULL); @@ -5994,7 +5603,7 @@ save_End(void) (void) alloc_instruction(ctx, OPCODE_END, 0); ctx->Driver.CurrentSavePrimitive = PRIM_OUTSIDE_BEGIN_END; if (ctx->ExecuteFlag) { - CALL_End(ctx->Exec, ()); + CALL_End(ctx->Dispatch.Exec, ()); } } @@ -6006,13 +5615,13 @@ save_PrimitiveRestartNV(void) ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_PRIMITIVE_RESTART_NV, 0); if (ctx->ExecuteFlag) { - CALL_PrimitiveRestartNV(ctx->Exec, ()); + CALL_PrimitiveRestartNV(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY -save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, +void GLAPIENTRY +save_BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) { @@ -6033,7 +5642,7 @@ save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, n[10].e = filter; } if (ctx->ExecuteFlag) { - CALL_BlitFramebuffer(ctx->Exec, (srcX0, srcY0, srcX1, srcY1, + CALL_BlitFramebuffer(ctx->Dispatch.Exec, (srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter)); } @@ -6041,8 +5650,8 @@ save_BlitFramebufferEXT(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, /** GL_EXT_provoking_vertex */ -static void GLAPIENTRY -save_ProvokingVertexEXT(GLenum mode) +void GLAPIENTRY +save_ProvokingVertex(GLenum mode) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6052,14 +5661,14 @@ save_ProvokingVertexEXT(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - /*CALL_ProvokingVertex(ctx->Exec, (mode));*/ + /*CALL_ProvokingVertex(ctx->Dispatch.Exec, (mode));*/ _mesa_ProvokingVertex(mode); } } /** GL_EXT_transform_feedback */ -static void GLAPIENTRY +void GLAPIENTRY save_BeginTransformFeedback(GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -6070,24 +5679,24 @@ save_BeginTransformFeedback(GLenum mode) n[1].e = mode; } if (ctx->ExecuteFlag) { - CALL_BeginTransformFeedback(ctx->Exec, (mode)); + CALL_BeginTransformFeedback(ctx->Dispatch.Exec, (mode)); } } /** GL_EXT_transform_feedback */ -static void GLAPIENTRY +void GLAPIENTRY save_EndTransformFeedback(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_END_TRANSFORM_FEEDBACK, 0); if (ctx->ExecuteFlag) { - CALL_EndTransformFeedback(ctx->Exec, ()); + CALL_EndTransformFeedback(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_BindTransformFeedback(GLenum target, GLuint name) { GET_CURRENT_CONTEXT(ctx); @@ -6099,33 +5708,33 @@ save_BindTransformFeedback(GLenum target, GLuint name) n[2].ui = name; } if (ctx->ExecuteFlag) { - CALL_BindTransformFeedback(ctx->Exec, (target, name)); + CALL_BindTransformFeedback(ctx->Dispatch.Exec, (target, name)); } } -static void GLAPIENTRY +void GLAPIENTRY save_PauseTransformFeedback(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_PAUSE_TRANSFORM_FEEDBACK, 0); if (ctx->ExecuteFlag) { - CALL_PauseTransformFeedback(ctx->Exec, ()); + CALL_PauseTransformFeedback(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_ResumeTransformFeedback(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); (void) alloc_instruction(ctx, OPCODE_RESUME_TRANSFORM_FEEDBACK, 0); if (ctx->ExecuteFlag) { - CALL_ResumeTransformFeedback(ctx->Exec, ()); + CALL_ResumeTransformFeedback(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_DrawTransformFeedback(GLenum mode, GLuint name) { GET_CURRENT_CONTEXT(ctx); @@ -6137,11 +5746,11 @@ save_DrawTransformFeedback(GLenum mode, GLuint name) n[2].ui = name; } if (ctx->ExecuteFlag) { - CALL_DrawTransformFeedback(ctx->Exec, (mode, name)); + CALL_DrawTransformFeedback(ctx->Dispatch.Exec, (mode, name)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) { GET_CURRENT_CONTEXT(ctx); @@ -6154,11 +5763,11 @@ save_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) n[3].ui = stream; } if (ctx->ExecuteFlag) { - CALL_DrawTransformFeedbackStream(ctx->Exec, (mode, name, stream)); + CALL_DrawTransformFeedbackStream(ctx->Dispatch.Exec, (mode, name, stream)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, GLsizei primcount) { @@ -6172,11 +5781,11 @@ save_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, n[3].si = primcount; } if (ctx->ExecuteFlag) { - CALL_DrawTransformFeedbackInstanced(ctx->Exec, (mode, name, primcount)); + CALL_DrawTransformFeedbackInstanced(ctx->Dispatch.Exec, (mode, name, primcount)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, GLuint stream, GLsizei primcount) { @@ -6191,12 +5800,12 @@ save_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, n[4].si = primcount; } if (ctx->ExecuteFlag) { - CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec, (mode, name, stream, + CALL_DrawTransformFeedbackStreamInstanced(ctx->Dispatch.Exec, (mode, name, stream, primcount)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z) { @@ -6210,12 +5819,12 @@ save_DispatchCompute(GLuint num_groups_x, GLuint num_groups_y, n[3].ui = num_groups_z; } if (ctx->ExecuteFlag) { - CALL_DispatchCompute(ctx->Exec, (num_groups_x, num_groups_y, + CALL_DispatchCompute(ctx->Dispatch.Exec, (num_groups_x, num_groups_y, num_groups_z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_DispatchComputeIndirect(GLintptr indirect) { GET_CURRENT_CONTEXT(ctx); @@ -6237,7 +5846,7 @@ save_Attr32bit(struct gl_context *ctx, unsigned attr, unsigned size, * FLOAT and INT. */ if (type == GL_FLOAT) { - if (attr >= VERT_ATTRIB_GENERIC0) { + if (VERT_BIT(attr) & VERT_BIT_GENERIC_ALL) { base_op = OPCODE_ATTR_1F_ARB; attr -= VERT_ATTRIB_GENERIC0; } else { @@ -6264,32 +5873,32 @@ save_Attr32bit(struct gl_context *ctx, unsigned attr, unsigned size, if (type == GL_FLOAT) { if (base_op == OPCODE_ATTR_1F_NV) { if (size == 4) - CALL_VertexAttrib4fNV(ctx->Exec, (attr, uif(x), uif(y), uif(z), uif(w))); + CALL_VertexAttrib4fNV(ctx->Dispatch.Exec, (attr, uif(x), uif(y), uif(z), uif(w))); else if (size == 3) - CALL_VertexAttrib3fNV(ctx->Exec, (attr, uif(x), uif(y), uif(z))); + CALL_VertexAttrib3fNV(ctx->Dispatch.Exec, (attr, uif(x), uif(y), uif(z))); else if (size == 2) - CALL_VertexAttrib2fNV(ctx->Exec, (attr, uif(x), uif(y))); + CALL_VertexAttrib2fNV(ctx->Dispatch.Exec, (attr, uif(x), uif(y))); else - CALL_VertexAttrib1fNV(ctx->Exec, (attr, uif(x))); + CALL_VertexAttrib1fNV(ctx->Dispatch.Exec, (attr, uif(x))); } else { if (size == 4) - CALL_VertexAttrib4fARB(ctx->Exec, (attr, uif(x), uif(y), uif(z), uif(w))); + CALL_VertexAttrib4fARB(ctx->Dispatch.Exec, (attr, uif(x), uif(y), uif(z), uif(w))); else if (size == 3) - CALL_VertexAttrib3fARB(ctx->Exec, (attr, uif(x), uif(y), uif(z))); + CALL_VertexAttrib3fARB(ctx->Dispatch.Exec, (attr, uif(x), uif(y), uif(z))); else if (size == 2) - CALL_VertexAttrib2fARB(ctx->Exec, (attr, uif(x), uif(y))); + CALL_VertexAttrib2fARB(ctx->Dispatch.Exec, (attr, uif(x), uif(y))); else - CALL_VertexAttrib1fARB(ctx->Exec, (attr, uif(x))); + CALL_VertexAttrib1fARB(ctx->Dispatch.Exec, (attr, uif(x))); } } else { if (size == 4) - CALL_VertexAttribI4iEXT(ctx->Exec, (attr, x, y, z, w)); + CALL_VertexAttribI4iEXT(ctx->Dispatch.Exec, (attr, x, y, z, w)); else if (size == 3) - CALL_VertexAttribI3iEXT(ctx->Exec, (attr, x, y, z)); + CALL_VertexAttribI3iEXT(ctx->Dispatch.Exec, (attr, x, y, z)); else if (size == 2) - CALL_VertexAttribI2iEXT(ctx->Exec, (attr, x, y)); + CALL_VertexAttribI2iEXT(ctx->Dispatch.Exec, (attr, x, y)); else - CALL_VertexAttribI1iEXT(ctx->Exec, (attr, x)); + CALL_VertexAttribI1iEXT(ctx->Dispatch.Exec, (attr, x)); } } } @@ -6327,15 +5936,15 @@ save_Attr64bit(struct gl_context *ctx, unsigned attr, unsigned size, uint64_t v[] = {x, y, z, w}; if (type == GL_DOUBLE) { if (size == 4) - CALL_VertexAttribL4dv(ctx->Exec, (attr, (GLdouble*)v)); + CALL_VertexAttribL4dv(ctx->Dispatch.Exec, (attr, (GLdouble*)v)); else if (size == 3) - CALL_VertexAttribL3dv(ctx->Exec, (attr, (GLdouble*)v)); + CALL_VertexAttribL3dv(ctx->Dispatch.Exec, (attr, (GLdouble*)v)); else if (size == 2) - CALL_VertexAttribL2dv(ctx->Exec, (attr, (GLdouble*)v)); + CALL_VertexAttribL2dv(ctx->Dispatch.Exec, (attr, (GLdouble*)v)); else - CALL_VertexAttribL1d(ctx->Exec, (attr, UINT64_AS_DOUBLE(x))); + CALL_VertexAttribL1d(ctx->Dispatch.Exec, (attr, UINT64_AS_DOUBLE(x))); } else { - CALL_VertexAttribL1ui64ARB(ctx->Exec, (attr, x)); + CALL_VertexAttribL1ui64ARB(ctx->Dispatch.Exec, (attr, x)); } } } @@ -6388,7 +5997,7 @@ do { \ #include "vbo/vbo_attrib_tmp.h" -static void GLAPIENTRY +void GLAPIENTRY save_UseProgram(GLuint program) { GET_CURRENT_CONTEXT(ctx); @@ -6399,13 +6008,13 @@ save_UseProgram(GLuint program) n[1].ui = program; } if (ctx->ExecuteFlag) { - CALL_UseProgram(ctx->Exec, (program)); + CALL_UseProgram(ctx->Dispatch.Exec, (program)); } } -static void GLAPIENTRY -save_Uniform1fARB(GLint location, GLfloat x) +void GLAPIENTRY +save_Uniform1f(GLint location, GLfloat x) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6416,13 +6025,13 @@ save_Uniform1fARB(GLint location, GLfloat x) n[2].f = x; } if (ctx->ExecuteFlag) { - CALL_Uniform1f(ctx->Exec, (location, x)); + CALL_Uniform1f(ctx->Dispatch.Exec, (location, x)); } } -static void GLAPIENTRY -save_Uniform2fARB(GLint location, GLfloat x, GLfloat y) +void GLAPIENTRY +save_Uniform2f(GLint location, GLfloat x, GLfloat y) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6434,13 +6043,13 @@ save_Uniform2fARB(GLint location, GLfloat x, GLfloat y) n[3].f = y; } if (ctx->ExecuteFlag) { - CALL_Uniform2f(ctx->Exec, (location, x, y)); + CALL_Uniform2f(ctx->Dispatch.Exec, (location, x, y)); } } -static void GLAPIENTRY -save_Uniform3fARB(GLint location, GLfloat x, GLfloat y, GLfloat z) +void GLAPIENTRY +save_Uniform3f(GLint location, GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6453,13 +6062,13 @@ save_Uniform3fARB(GLint location, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } if (ctx->ExecuteFlag) { - CALL_Uniform3f(ctx->Exec, (location, x, y, z)); + CALL_Uniform3f(ctx->Dispatch.Exec, (location, x, y, z)); } } -static void GLAPIENTRY -save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) +void GLAPIENTRY +save_Uniform4f(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6473,13 +6082,13 @@ save_Uniform4fARB(GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) n[5].f = w; } if (ctx->ExecuteFlag) { - CALL_Uniform4f(ctx->Exec, (location, x, y, z, w)); + CALL_Uniform4f(ctx->Dispatch.Exec, (location, x, y, z, w)); } } -static void GLAPIENTRY -save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v) +void GLAPIENTRY +save_Uniform1fv(GLint location, GLsizei count, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6491,12 +6100,12 @@ save_Uniform1fvARB(GLint location, GLsizei count, const GLfloat *v) save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_Uniform1fv(ctx->Exec, (location, count, v)); + CALL_Uniform1fv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v) +void GLAPIENTRY +save_Uniform2fv(GLint location, GLsizei count, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6508,12 +6117,12 @@ save_Uniform2fvARB(GLint location, GLsizei count, const GLfloat *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_Uniform2fv(ctx->Exec, (location, count, v)); + CALL_Uniform2fv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v) +void GLAPIENTRY +save_Uniform3fv(GLint location, GLsizei count, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6525,12 +6134,12 @@ save_Uniform3fvARB(GLint location, GLsizei count, const GLfloat *v) save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_Uniform3fv(ctx->Exec, (location, count, v)); + CALL_Uniform3fv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v) +void GLAPIENTRY +save_Uniform4fv(GLint location, GLsizei count, const GLfloat *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6542,12 +6151,12 @@ save_Uniform4fvARB(GLint location, GLsizei count, const GLfloat *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_Uniform4fv(ctx->Exec, (location, count, v)); + CALL_Uniform4fv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1d(GLint location, GLdouble x) { GET_CURRENT_CONTEXT(ctx); @@ -6559,12 +6168,12 @@ save_Uniform1d(GLint location, GLdouble x) ASSIGN_DOUBLE_TO_NODES(n, 2, x); } if (ctx->ExecuteFlag) { - CALL_Uniform1d(ctx->Exec, (location, x)); + CALL_Uniform1d(ctx->Dispatch.Exec, (location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2d(GLint location, GLdouble x, GLdouble y) { GET_CURRENT_CONTEXT(ctx); @@ -6577,12 +6186,12 @@ save_Uniform2d(GLint location, GLdouble x, GLdouble y) ASSIGN_DOUBLE_TO_NODES(n, 4, y); } if (ctx->ExecuteFlag) { - CALL_Uniform2d(ctx->Exec, (location, x, y)); + CALL_Uniform2d(ctx->Dispatch.Exec, (location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z) { GET_CURRENT_CONTEXT(ctx); @@ -6596,12 +6205,12 @@ save_Uniform3d(GLint location, GLdouble x, GLdouble y, GLdouble z) ASSIGN_DOUBLE_TO_NODES(n, 6, z); } if (ctx->ExecuteFlag) { - CALL_Uniform3d(ctx->Exec, (location, x, y, z)); + CALL_Uniform3d(ctx->Dispatch.Exec, (location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { GET_CURRENT_CONTEXT(ctx); @@ -6616,12 +6225,12 @@ save_Uniform4d(GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w) ASSIGN_DOUBLE_TO_NODES(n, 8, w); } if (ctx->ExecuteFlag) { - CALL_Uniform4d(ctx->Exec, (location, x, y, z, w)); + CALL_Uniform4d(ctx->Dispatch.Exec, (location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1dv(GLint location, GLsizei count, const GLdouble *v) { GET_CURRENT_CONTEXT(ctx); @@ -6634,12 +6243,12 @@ save_Uniform1dv(GLint location, GLsizei count, const GLdouble *v) save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_Uniform1dv(ctx->Exec, (location, count, v)); + CALL_Uniform1dv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2dv(GLint location, GLsizei count, const GLdouble *v) { GET_CURRENT_CONTEXT(ctx); @@ -6652,12 +6261,12 @@ save_Uniform2dv(GLint location, GLsizei count, const GLdouble *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_Uniform2dv(ctx->Exec, (location, count, v)); + CALL_Uniform2dv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3dv(GLint location, GLsizei count, const GLdouble *v) { GET_CURRENT_CONTEXT(ctx); @@ -6670,12 +6279,12 @@ save_Uniform3dv(GLint location, GLsizei count, const GLdouble *v) save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_Uniform3dv(ctx->Exec, (location, count, v)); + CALL_Uniform3dv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4dv(GLint location, GLsizei count, const GLdouble *v) { GET_CURRENT_CONTEXT(ctx); @@ -6688,13 +6297,13 @@ save_Uniform4dv(GLint location, GLsizei count, const GLdouble *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_Uniform4dv(ctx->Exec, (location, count, v)); + CALL_Uniform4dv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform1iARB(GLint location, GLint x) +void GLAPIENTRY +save_Uniform1i(GLint location, GLint x) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6705,12 +6314,12 @@ save_Uniform1iARB(GLint location, GLint x) n[2].i = x; } if (ctx->ExecuteFlag) { - CALL_Uniform1i(ctx->Exec, (location, x)); + CALL_Uniform1i(ctx->Dispatch.Exec, (location, x)); } } -static void GLAPIENTRY -save_Uniform2iARB(GLint location, GLint x, GLint y) +void GLAPIENTRY +save_Uniform2i(GLint location, GLint x, GLint y) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6722,12 +6331,12 @@ save_Uniform2iARB(GLint location, GLint x, GLint y) n[3].i = y; } if (ctx->ExecuteFlag) { - CALL_Uniform2i(ctx->Exec, (location, x, y)); + CALL_Uniform2i(ctx->Dispatch.Exec, (location, x, y)); } } -static void GLAPIENTRY -save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z) +void GLAPIENTRY +save_Uniform3i(GLint location, GLint x, GLint y, GLint z) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6740,12 +6349,12 @@ save_Uniform3iARB(GLint location, GLint x, GLint y, GLint z) n[4].i = z; } if (ctx->ExecuteFlag) { - CALL_Uniform3i(ctx->Exec, (location, x, y, z)); + CALL_Uniform3i(ctx->Dispatch.Exec, (location, x, y, z)); } } -static void GLAPIENTRY -save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w) +void GLAPIENTRY +save_Uniform4i(GLint location, GLint x, GLint y, GLint z, GLint w) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6759,14 +6368,14 @@ save_Uniform4iARB(GLint location, GLint x, GLint y, GLint z, GLint w) n[5].i = w; } if (ctx->ExecuteFlag) { - CALL_Uniform4i(ctx->Exec, (location, x, y, z, w)); + CALL_Uniform4i(ctx->Dispatch.Exec, (location, x, y, z, w)); } } -static void GLAPIENTRY -save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v) +void GLAPIENTRY +save_Uniform1iv(GLint location, GLsizei count, const GLint *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6778,12 +6387,12 @@ save_Uniform1ivARB(GLint location, GLsizei count, const GLint *v) save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_Uniform1iv(ctx->Exec, (location, count, v)); + CALL_Uniform1iv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v) +void GLAPIENTRY +save_Uniform2iv(GLint location, GLsizei count, const GLint *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6795,12 +6404,12 @@ save_Uniform2ivARB(GLint location, GLsizei count, const GLint *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_Uniform2iv(ctx->Exec, (location, count, v)); + CALL_Uniform2iv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v) +void GLAPIENTRY +save_Uniform3iv(GLint location, GLsizei count, const GLint *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6812,12 +6421,12 @@ save_Uniform3ivARB(GLint location, GLsizei count, const GLint *v) save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_Uniform3iv(ctx->Exec, (location, count, v)); + CALL_Uniform3iv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v) +void GLAPIENTRY +save_Uniform4iv(GLint location, GLsizei count, const GLint *v) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -6829,13 +6438,13 @@ save_Uniform4ivARB(GLint location, GLsizei count, const GLint *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_Uniform4iv(ctx->Exec, (location, count, v)); + CALL_Uniform4iv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1ui(GLint location, GLuint x) { GET_CURRENT_CONTEXT(ctx); @@ -6847,11 +6456,11 @@ save_Uniform1ui(GLint location, GLuint x) n[2].i = x; } if (ctx->ExecuteFlag) { - CALL_Uniform1ui(ctx->Exec, (location, x)); + CALL_Uniform1ui(ctx->Dispatch.Exec, (location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2ui(GLint location, GLuint x, GLuint y) { GET_CURRENT_CONTEXT(ctx); @@ -6864,11 +6473,11 @@ save_Uniform2ui(GLint location, GLuint x, GLuint y) n[3].i = y; } if (ctx->ExecuteFlag) { - CALL_Uniform2ui(ctx->Exec, (location, x, y)); + CALL_Uniform2ui(ctx->Dispatch.Exec, (location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) { GET_CURRENT_CONTEXT(ctx); @@ -6882,11 +6491,11 @@ save_Uniform3ui(GLint location, GLuint x, GLuint y, GLuint z) n[4].i = z; } if (ctx->ExecuteFlag) { - CALL_Uniform3ui(ctx->Exec, (location, x, y, z)); + CALL_Uniform3ui(ctx->Dispatch.Exec, (location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4ui(GLint location, GLuint x, GLuint y, GLuint z, GLuint w) { GET_CURRENT_CONTEXT(ctx); @@ -6901,13 +6510,13 @@ save_Uniform4ui(GLint location, GLuint x, GLuint y, GLuint z, GLuint w) n[5].i = w; } if (ctx->ExecuteFlag) { - CALL_Uniform4ui(ctx->Exec, (location, x, y, z, w)); + CALL_Uniform4ui(ctx->Dispatch.Exec, (location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1uiv(GLint location, GLsizei count, const GLuint *v) { GET_CURRENT_CONTEXT(ctx); @@ -6920,11 +6529,11 @@ save_Uniform1uiv(GLint location, GLsizei count, const GLuint *v) save_pointer(&n[3], memdup(v, count * 1 * sizeof(*v))); } if (ctx->ExecuteFlag) { - CALL_Uniform1uiv(ctx->Exec, (location, count, v)); + CALL_Uniform1uiv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2uiv(GLint location, GLsizei count, const GLuint *v) { GET_CURRENT_CONTEXT(ctx); @@ -6937,11 +6546,11 @@ save_Uniform2uiv(GLint location, GLsizei count, const GLuint *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(*v))); } if (ctx->ExecuteFlag) { - CALL_Uniform2uiv(ctx->Exec, (location, count, v)); + CALL_Uniform2uiv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3uiv(GLint location, GLsizei count, const GLuint *v) { GET_CURRENT_CONTEXT(ctx); @@ -6954,11 +6563,11 @@ save_Uniform3uiv(GLint location, GLsizei count, const GLuint *v) save_pointer(&n[3], memdup(v, count * 3 * sizeof(*v))); } if (ctx->ExecuteFlag) { - CALL_Uniform3uiv(ctx->Exec, (location, count, v)); + CALL_Uniform3uiv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4uiv(GLint location, GLsizei count, const GLuint *v) { GET_CURRENT_CONTEXT(ctx); @@ -6971,14 +6580,14 @@ save_Uniform4uiv(GLint location, GLsizei count, const GLuint *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(*v))); } if (ctx->ExecuteFlag) { - CALL_Uniform4uiv(ctx->Exec, (location, count, v)); + CALL_Uniform4uiv(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY -save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, +void GLAPIENTRY +save_UniformMatrix2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { GET_CURRENT_CONTEXT(ctx); @@ -6992,12 +6601,12 @@ save_UniformMatrix2fvARB(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 2 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix2fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix2fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY -save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, +void GLAPIENTRY +save_UniformMatrix3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { GET_CURRENT_CONTEXT(ctx); @@ -7011,12 +6620,12 @@ save_UniformMatrix3fvARB(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 3 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix3fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix3fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY -save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, +void GLAPIENTRY +save_UniformMatrix4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { GET_CURRENT_CONTEXT(ctx); @@ -7030,12 +6639,12 @@ save_UniformMatrix4fvARB(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 4 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix4fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix4fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { @@ -7050,11 +6659,11 @@ save_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 2 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix2x3fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix2x3fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { @@ -7069,12 +6678,12 @@ save_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 3 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix3x2fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix3x2fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { @@ -7089,11 +6698,11 @@ save_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 2 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix2x4fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix2x4fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { @@ -7108,12 +6717,12 @@ save_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 4 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix4x2fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix4x2fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { @@ -7128,11 +6737,11 @@ save_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 3 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix3x4fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix3x4fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, const GLfloat *m) { @@ -7147,12 +6756,12 @@ save_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 4 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix4x3fv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix4x3fv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7167,11 +6776,11 @@ save_UniformMatrix2dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 2 * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix2dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix2dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7186,11 +6795,11 @@ save_UniformMatrix3dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 3 * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix3dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix3dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7205,12 +6814,12 @@ save_UniformMatrix4dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 4 * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix4dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix4dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7225,12 +6834,12 @@ save_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 2 * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix2x3dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix2x3dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7245,12 +6854,12 @@ save_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 3 * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix3x2dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix3x2dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7265,11 +6874,11 @@ save_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 2 * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix2x4dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix2x4dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7284,12 +6893,12 @@ save_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 4 * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix4x2dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix4x2dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7304,12 +6913,12 @@ save_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 3 * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix3x4dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix3x4dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, const GLdouble *m) { @@ -7324,11 +6933,11 @@ save_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, save_pointer(&n[4], memdup(m, count * 4 * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_UniformMatrix4x3dv(ctx->Exec, (location, count, transpose, m)); + CALL_UniformMatrix4x3dv(ctx->Dispatch.Exec, (location, count, transpose, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1i64ARB(GLint location, GLint64 x) { GET_CURRENT_CONTEXT(ctx); @@ -7340,11 +6949,11 @@ save_Uniform1i64ARB(GLint location, GLint64 x) ASSIGN_INT64_TO_NODES(n, 2, x); } if (ctx->ExecuteFlag) { - CALL_Uniform1i64ARB(ctx->Exec, (location, x)); + CALL_Uniform1i64ARB(ctx->Dispatch.Exec, (location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2i64ARB(GLint location, GLint64 x, GLint64 y) { GET_CURRENT_CONTEXT(ctx); @@ -7357,11 +6966,11 @@ save_Uniform2i64ARB(GLint location, GLint64 x, GLint64 y) ASSIGN_INT64_TO_NODES(n, 4, y); } if (ctx->ExecuteFlag) { - CALL_Uniform2i64ARB(ctx->Exec, (location, x, y)); + CALL_Uniform2i64ARB(ctx->Dispatch.Exec, (location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3i64ARB(GLint location, GLint64 x, GLint64 y, GLint64 z) { GET_CURRENT_CONTEXT(ctx); @@ -7375,11 +6984,11 @@ save_Uniform3i64ARB(GLint location, GLint64 x, GLint64 y, GLint64 z) ASSIGN_INT64_TO_NODES(n, 6, z); } if (ctx->ExecuteFlag) { - CALL_Uniform3i64ARB(ctx->Exec, (location, x, y, z)); + CALL_Uniform3i64ARB(ctx->Dispatch.Exec, (location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4i64ARB(GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w) { GET_CURRENT_CONTEXT(ctx); @@ -7394,11 +7003,11 @@ save_Uniform4i64ARB(GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w) ASSIGN_INT64_TO_NODES(n, 8, w); } if (ctx->ExecuteFlag) { - CALL_Uniform4i64ARB(ctx->Exec, (location, x, y, z, w)); + CALL_Uniform4i64ARB(ctx->Dispatch.Exec, (location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1i64vARB(GLint location, GLsizei count, const GLint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7411,11 +7020,11 @@ save_Uniform1i64vARB(GLint location, GLsizei count, const GLint64 *v) save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform1i64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform1i64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2i64vARB(GLint location, GLsizei count, const GLint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7428,11 +7037,11 @@ save_Uniform2i64vARB(GLint location, GLsizei count, const GLint64 *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform2i64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform2i64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3i64vARB(GLint location, GLsizei count, const GLint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7445,11 +7054,11 @@ save_Uniform3i64vARB(GLint location, GLsizei count, const GLint64 *v) save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform3i64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform3i64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4i64vARB(GLint location, GLsizei count, const GLint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7462,11 +7071,11 @@ save_Uniform4i64vARB(GLint location, GLsizei count, const GLint64 *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform4i64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform4i64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1ui64ARB(GLint location, GLuint64 x) { GET_CURRENT_CONTEXT(ctx); @@ -7478,11 +7087,11 @@ save_Uniform1ui64ARB(GLint location, GLuint64 x) ASSIGN_UINT64_TO_NODES(n, 2, x); } if (ctx->ExecuteFlag) { - CALL_Uniform1ui64ARB(ctx->Exec, (location, x)); + CALL_Uniform1ui64ARB(ctx->Dispatch.Exec, (location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2ui64ARB(GLint location, GLuint64 x, GLuint64 y) { GET_CURRENT_CONTEXT(ctx); @@ -7495,11 +7104,11 @@ save_Uniform2ui64ARB(GLint location, GLuint64 x, GLuint64 y) ASSIGN_UINT64_TO_NODES(n, 4, y); } if (ctx->ExecuteFlag) { - CALL_Uniform2ui64ARB(ctx->Exec, (location, x, y)); + CALL_Uniform2ui64ARB(ctx->Dispatch.Exec, (location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3ui64ARB(GLint location, GLuint64 x, GLuint64 y, GLuint64 z) { GET_CURRENT_CONTEXT(ctx); @@ -7513,11 +7122,11 @@ save_Uniform3ui64ARB(GLint location, GLuint64 x, GLuint64 y, GLuint64 z) ASSIGN_UINT64_TO_NODES(n, 6, z); } if (ctx->ExecuteFlag) { - CALL_Uniform3ui64ARB(ctx->Exec, (location, x, y, z)); + CALL_Uniform3ui64ARB(ctx->Dispatch.Exec, (location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4ui64ARB(GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w) { GET_CURRENT_CONTEXT(ctx); @@ -7532,11 +7141,11 @@ save_Uniform4ui64ARB(GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint6 ASSIGN_UINT64_TO_NODES(n, 8, w); } if (ctx->ExecuteFlag) { - CALL_Uniform4ui64ARB(ctx->Exec, (location, x, y, z, w)); + CALL_Uniform4ui64ARB(ctx->Dispatch.Exec, (location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform1ui64vARB(GLint location, GLsizei count, const GLuint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7549,11 +7158,11 @@ save_Uniform1ui64vARB(GLint location, GLsizei count, const GLuint64 *v) save_pointer(&n[3], memdup(v, count * 1 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform1ui64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform1ui64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform2ui64vARB(GLint location, GLsizei count, const GLuint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7566,11 +7175,11 @@ save_Uniform2ui64vARB(GLint location, GLsizei count, const GLuint64 *v) save_pointer(&n[3], memdup(v, count * 2 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform2ui64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform2ui64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform3ui64vARB(GLint location, GLsizei count, const GLuint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7583,11 +7192,11 @@ save_Uniform3ui64vARB(GLint location, GLsizei count, const GLuint64 *v) save_pointer(&n[3], memdup(v, count * 3 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform3ui64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform3ui64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_Uniform4ui64vARB(GLint location, GLsizei count, const GLuint64 *v) { GET_CURRENT_CONTEXT(ctx); @@ -7600,11 +7209,11 @@ save_Uniform4ui64vARB(GLint location, GLsizei count, const GLuint64 *v) save_pointer(&n[3], memdup(v, count * 4 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_Uniform4ui64vARB(ctx->Exec, (location, count, v)); + CALL_Uniform4ui64vARB(ctx->Dispatch.Exec, (location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1i64ARB(GLuint program, GLint location, GLint64 x) { GET_CURRENT_CONTEXT(ctx); @@ -7617,11 +7226,11 @@ save_ProgramUniform1i64ARB(GLuint program, GLint location, GLint64 x) ASSIGN_INT64_TO_NODES(n, 3, x); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1i64ARB(ctx->Exec, (program, location, x)); + CALL_ProgramUniform1i64ARB(ctx->Dispatch.Exec, (program, location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2i64ARB(GLuint program, GLint location, GLint64 x, GLint64 y) { @@ -7636,11 +7245,11 @@ save_ProgramUniform2i64ARB(GLuint program, GLint location, GLint64 x, ASSIGN_INT64_TO_NODES(n, 5, y); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2i64ARB(ctx->Exec, (program, location, x, y)); + CALL_ProgramUniform2i64ARB(ctx->Dispatch.Exec, (program, location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3i64ARB(GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z) { @@ -7656,11 +7265,11 @@ save_ProgramUniform3i64ARB(GLuint program, GLint location, GLint64 x, ASSIGN_INT64_TO_NODES(n, 7, z); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3i64ARB(ctx->Exec, (program, location, x, y, z)); + CALL_ProgramUniform3i64ARB(ctx->Dispatch.Exec, (program, location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4i64ARB(GLuint program, GLint location, GLint64 x, GLint64 y, GLint64 z, GLint64 w) { @@ -7677,11 +7286,11 @@ save_ProgramUniform4i64ARB(GLuint program, GLint location, GLint64 x, ASSIGN_INT64_TO_NODES(n, 9, w); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4i64ARB(ctx->Exec, (program, location, x, y, z, w)); + CALL_ProgramUniform4i64ARB(ctx->Dispatch.Exec, (program, location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1i64vARB(GLuint program, GLint location, GLsizei count, const GLint64 *v) { @@ -7696,11 +7305,11 @@ save_ProgramUniform1i64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1i64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform1i64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2i64vARB(GLuint program, GLint location, GLsizei count, const GLint64 *v) { @@ -7715,11 +7324,11 @@ save_ProgramUniform2i64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2i64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform2i64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3i64vARB(GLuint program, GLint location, GLsizei count, const GLint64 *v) { @@ -7734,11 +7343,11 @@ save_ProgramUniform3i64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3i64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform3i64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4i64vARB(GLuint program, GLint location, GLsizei count, const GLint64 *v) { @@ -7753,11 +7362,11 @@ save_ProgramUniform4i64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4i64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform4i64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1ui64ARB(GLuint program, GLint location, GLuint64 x) { GET_CURRENT_CONTEXT(ctx); @@ -7770,11 +7379,11 @@ save_ProgramUniform1ui64ARB(GLuint program, GLint location, GLuint64 x) ASSIGN_UINT64_TO_NODES(n, 3, x); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1ui64ARB(ctx->Exec, (program, location, x)); + CALL_ProgramUniform1ui64ARB(ctx->Dispatch.Exec, (program, location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2ui64ARB(GLuint program, GLint location, GLuint64 x, GLuint64 y) { @@ -7789,11 +7398,11 @@ save_ProgramUniform2ui64ARB(GLuint program, GLint location, GLuint64 x, ASSIGN_UINT64_TO_NODES(n, 5, y); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2ui64ARB(ctx->Exec, (program, location, x, y)); + CALL_ProgramUniform2ui64ARB(ctx->Dispatch.Exec, (program, location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3ui64ARB(GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z) { @@ -7809,11 +7418,11 @@ save_ProgramUniform3ui64ARB(GLuint program, GLint location, GLuint64 x, ASSIGN_UINT64_TO_NODES(n, 7, z); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3ui64ARB(ctx->Exec, (program, location, x, y, z)); + CALL_ProgramUniform3ui64ARB(ctx->Dispatch.Exec, (program, location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4ui64ARB(GLuint program, GLint location, GLuint64 x, GLuint64 y, GLuint64 z, GLuint64 w) { @@ -7830,11 +7439,11 @@ save_ProgramUniform4ui64ARB(GLuint program, GLint location, GLuint64 x, ASSIGN_UINT64_TO_NODES(n, 9, w); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4i64ARB(ctx->Exec, (program, location, x, y, z, w)); + CALL_ProgramUniform4i64ARB(ctx->Dispatch.Exec, (program, location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1ui64vARB(GLuint program, GLint location, GLsizei count, const GLuint64 *v) { @@ -7850,11 +7459,11 @@ save_ProgramUniform1ui64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1ui64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform1ui64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2ui64vARB(GLuint program, GLint location, GLsizei count, const GLuint64 *v) { @@ -7870,11 +7479,11 @@ save_ProgramUniform2ui64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2ui64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform2ui64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3ui64vARB(GLuint program, GLint location, GLsizei count, const GLuint64 *v) { @@ -7890,11 +7499,11 @@ save_ProgramUniform3ui64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3ui64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform3ui64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4ui64vARB(GLuint program, GLint location, GLsizei count, const GLuint64 *v) { @@ -7910,12 +7519,12 @@ save_ProgramUniform4ui64vARB(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint64))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4ui64vARB(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform4ui64vARB(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) { GET_CURRENT_CONTEXT(ctx); @@ -7928,11 +7537,11 @@ save_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program) n[3].ui = program; } if (ctx->ExecuteFlag) { - CALL_UseProgramStages(ctx->Exec, (pipeline, stages, program)); + CALL_UseProgramStages(ctx->Dispatch.Exec, (pipeline, stages, program)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1f(GLuint program, GLint location, GLfloat x) { GET_CURRENT_CONTEXT(ctx); @@ -7945,11 +7554,11 @@ save_ProgramUniform1f(GLuint program, GLint location, GLfloat x) n[3].f = x; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1f(ctx->Exec, (program, location, x)); + CALL_ProgramUniform1f(ctx->Dispatch.Exec, (program, location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2f(GLuint program, GLint location, GLfloat x, GLfloat y) { GET_CURRENT_CONTEXT(ctx); @@ -7963,11 +7572,11 @@ save_ProgramUniform2f(GLuint program, GLint location, GLfloat x, GLfloat y) n[4].f = y; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2f(ctx->Exec, (program, location, x, y)); + CALL_ProgramUniform2f(ctx->Dispatch.Exec, (program, location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3f(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z) { @@ -7983,11 +7592,11 @@ save_ProgramUniform3f(GLuint program, GLint location, n[5].f = z; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3f(ctx->Exec, (program, location, x, y, z)); + CALL_ProgramUniform3f(ctx->Dispatch.Exec, (program, location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4f(GLuint program, GLint location, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { @@ -8004,11 +7613,11 @@ save_ProgramUniform4f(GLuint program, GLint location, n[6].f = w; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4f(ctx->Exec, (program, location, x, y, z, w)); + CALL_ProgramUniform4f(ctx->Dispatch.Exec, (program, location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1fv(GLuint program, GLint location, GLsizei count, const GLfloat *v) { @@ -8023,11 +7632,11 @@ save_ProgramUniform1fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1fv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform1fv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2fv(GLuint program, GLint location, GLsizei count, const GLfloat *v) { @@ -8042,11 +7651,11 @@ save_ProgramUniform2fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2fv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform2fv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3fv(GLuint program, GLint location, GLsizei count, const GLfloat *v) { @@ -8061,11 +7670,11 @@ save_ProgramUniform3fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3fv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform3fv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4fv(GLuint program, GLint location, GLsizei count, const GLfloat *v) { @@ -8080,11 +7689,11 @@ save_ProgramUniform4fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4fv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform4fv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1d(GLuint program, GLint location, GLdouble x) { GET_CURRENT_CONTEXT(ctx); @@ -8097,11 +7706,11 @@ save_ProgramUniform1d(GLuint program, GLint location, GLdouble x) ASSIGN_DOUBLE_TO_NODES(n, 3, x); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1d(ctx->Exec, (program, location, x)); + CALL_ProgramUniform1d(ctx->Dispatch.Exec, (program, location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2d(GLuint program, GLint location, GLdouble x, GLdouble y) { GET_CURRENT_CONTEXT(ctx); @@ -8115,11 +7724,11 @@ save_ProgramUniform2d(GLuint program, GLint location, GLdouble x, GLdouble y) ASSIGN_DOUBLE_TO_NODES(n, 5, y); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2d(ctx->Exec, (program, location, x, y)); + CALL_ProgramUniform2d(ctx->Dispatch.Exec, (program, location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3d(GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z) { @@ -8135,11 +7744,11 @@ save_ProgramUniform3d(GLuint program, GLint location, ASSIGN_DOUBLE_TO_NODES(n, 7, z); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3d(ctx->Exec, (program, location, x, y, z)); + CALL_ProgramUniform3d(ctx->Dispatch.Exec, (program, location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4d(GLuint program, GLint location, GLdouble x, GLdouble y, GLdouble z, GLdouble w) { @@ -8156,11 +7765,11 @@ save_ProgramUniform4d(GLuint program, GLint location, ASSIGN_DOUBLE_TO_NODES(n, 9, w); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4d(ctx->Exec, (program, location, x, y, z, w)); + CALL_ProgramUniform4d(ctx->Dispatch.Exec, (program, location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1dv(GLuint program, GLint location, GLsizei count, const GLdouble *v) { @@ -8175,11 +7784,11 @@ save_ProgramUniform1dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1dv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform1dv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2dv(GLuint program, GLint location, GLsizei count, const GLdouble *v) { @@ -8194,11 +7803,11 @@ save_ProgramUniform2dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2dv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform2dv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3dv(GLuint program, GLint location, GLsizei count, const GLdouble *v) { @@ -8213,11 +7822,11 @@ save_ProgramUniform3dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3dv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform3dv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4dv(GLuint program, GLint location, GLsizei count, const GLdouble *v) { @@ -8232,11 +7841,11 @@ save_ProgramUniform4dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4dv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform4dv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1i(GLuint program, GLint location, GLint x) { GET_CURRENT_CONTEXT(ctx); @@ -8249,11 +7858,11 @@ save_ProgramUniform1i(GLuint program, GLint location, GLint x) n[3].i = x; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1i(ctx->Exec, (program, location, x)); + CALL_ProgramUniform1i(ctx->Dispatch.Exec, (program, location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2i(GLuint program, GLint location, GLint x, GLint y) { GET_CURRENT_CONTEXT(ctx); @@ -8267,11 +7876,11 @@ save_ProgramUniform2i(GLuint program, GLint location, GLint x, GLint y) n[4].i = y; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2i(ctx->Exec, (program, location, x, y)); + CALL_ProgramUniform2i(ctx->Dispatch.Exec, (program, location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3i(GLuint program, GLint location, GLint x, GLint y, GLint z) { @@ -8287,11 +7896,11 @@ save_ProgramUniform3i(GLuint program, GLint location, n[5].i = z; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3i(ctx->Exec, (program, location, x, y, z)); + CALL_ProgramUniform3i(ctx->Dispatch.Exec, (program, location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4i(GLuint program, GLint location, GLint x, GLint y, GLint z, GLint w) { @@ -8308,11 +7917,11 @@ save_ProgramUniform4i(GLuint program, GLint location, n[6].i = w; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4i(ctx->Exec, (program, location, x, y, z, w)); + CALL_ProgramUniform4i(ctx->Dispatch.Exec, (program, location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1iv(GLuint program, GLint location, GLsizei count, const GLint *v) { @@ -8327,11 +7936,11 @@ save_ProgramUniform1iv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1iv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform1iv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2iv(GLuint program, GLint location, GLsizei count, const GLint *v) { @@ -8346,11 +7955,11 @@ save_ProgramUniform2iv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2iv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform2iv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3iv(GLuint program, GLint location, GLsizei count, const GLint *v) { @@ -8365,11 +7974,11 @@ save_ProgramUniform3iv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3iv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform3iv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4iv(GLuint program, GLint location, GLsizei count, const GLint *v) { @@ -8384,11 +7993,11 @@ save_ProgramUniform4iv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4iv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform4iv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1ui(GLuint program, GLint location, GLuint x) { GET_CURRENT_CONTEXT(ctx); @@ -8401,11 +8010,11 @@ save_ProgramUniform1ui(GLuint program, GLint location, GLuint x) n[3].ui = x; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1ui(ctx->Exec, (program, location, x)); + CALL_ProgramUniform1ui(ctx->Dispatch.Exec, (program, location, x)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2ui(GLuint program, GLint location, GLuint x, GLuint y) { GET_CURRENT_CONTEXT(ctx); @@ -8419,11 +8028,11 @@ save_ProgramUniform2ui(GLuint program, GLint location, GLuint x, GLuint y) n[4].ui = y; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2ui(ctx->Exec, (program, location, x, y)); + CALL_ProgramUniform2ui(ctx->Dispatch.Exec, (program, location, x, y)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3ui(GLuint program, GLint location, GLuint x, GLuint y, GLuint z) { @@ -8439,11 +8048,11 @@ save_ProgramUniform3ui(GLuint program, GLint location, n[5].ui = z; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3ui(ctx->Exec, (program, location, x, y, z)); + CALL_ProgramUniform3ui(ctx->Dispatch.Exec, (program, location, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4ui(GLuint program, GLint location, GLuint x, GLuint y, GLuint z, GLuint w) { @@ -8460,11 +8069,11 @@ save_ProgramUniform4ui(GLuint program, GLint location, n[6].ui = w; } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4ui(ctx->Exec, (program, location, x, y, z, w)); + CALL_ProgramUniform4ui(ctx->Dispatch.Exec, (program, location, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count, const GLuint *v) { @@ -8479,11 +8088,11 @@ save_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 1 * sizeof(GLuint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform1uiv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform1uiv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count, const GLuint *v) { @@ -8498,11 +8107,11 @@ save_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 2 * sizeof(GLuint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform2uiv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform2uiv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count, const GLuint *v) { @@ -8517,11 +8126,11 @@ save_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 3 * sizeof(GLuint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform3uiv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform3uiv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count, const GLuint *v) { @@ -8536,11 +8145,11 @@ save_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count, save_pointer(&n[4], memdup(v, count * 4 * sizeof(GLuint))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniform4uiv(ctx->Exec, (program, location, count, v)); + CALL_ProgramUniform4uiv(ctx->Dispatch.Exec, (program, location, count, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8557,12 +8166,12 @@ save_ProgramUniformMatrix2fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 2 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix2fv(ctx->Exec, + CALL_ProgramUniformMatrix2fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8579,12 +8188,12 @@ save_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 2 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix2x3fv(ctx->Exec, + CALL_ProgramUniformMatrix2x3fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8601,12 +8210,12 @@ save_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 2 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix2x4fv(ctx->Exec, + CALL_ProgramUniformMatrix2x4fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8623,12 +8232,12 @@ save_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 3 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix3x2fv(ctx->Exec, + CALL_ProgramUniformMatrix3x2fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8645,12 +8254,12 @@ save_ProgramUniformMatrix3fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 3 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix3fv(ctx->Exec, + CALL_ProgramUniformMatrix3fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8667,12 +8276,12 @@ save_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 3 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix3x4fv(ctx->Exec, + CALL_ProgramUniformMatrix3x4fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8689,12 +8298,12 @@ save_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 4 * 2 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix4x2fv(ctx->Exec, + CALL_ProgramUniformMatrix4x2fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8711,12 +8320,12 @@ save_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 4 * 3 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix4x3fv(ctx->Exec, + CALL_ProgramUniformMatrix4x3fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *v) { @@ -8733,12 +8342,12 @@ save_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 4 * 4 * sizeof(GLfloat))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix4fv(ctx->Exec, + CALL_ProgramUniformMatrix4fv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8755,12 +8364,12 @@ save_ProgramUniformMatrix2dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 2 * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix2dv(ctx->Exec, + CALL_ProgramUniformMatrix2dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8777,12 +8386,12 @@ save_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 2 * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix2x3dv(ctx->Exec, + CALL_ProgramUniformMatrix2x3dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8799,12 +8408,12 @@ save_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 2 * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix2x4dv(ctx->Exec, + CALL_ProgramUniformMatrix2x4dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8821,12 +8430,12 @@ save_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 3 * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix3x2dv(ctx->Exec, + CALL_ProgramUniformMatrix3x2dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8843,12 +8452,12 @@ save_ProgramUniformMatrix3dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 3 * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix3dv(ctx->Exec, + CALL_ProgramUniformMatrix3dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8865,12 +8474,12 @@ save_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 3 * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix3x4dv(ctx->Exec, + CALL_ProgramUniformMatrix3x4dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8887,12 +8496,12 @@ save_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 4 * 2 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix4x2dv(ctx->Exec, + CALL_ProgramUniformMatrix4x2dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8909,12 +8518,12 @@ save_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 4 * 3 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix4x3dv(ctx->Exec, + CALL_ProgramUniformMatrix4x3dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLdouble *v) { @@ -8931,12 +8540,12 @@ save_ProgramUniformMatrix4dv(GLuint program, GLint location, GLsizei count, save_pointer(&n[5], memdup(v, count * 4 * 4 * sizeof(GLdouble))); } if (ctx->ExecuteFlag) { - CALL_ProgramUniformMatrix4dv(ctx->Exec, + CALL_ProgramUniformMatrix4dv(ctx->Dispatch.Exec, (program, location, count, transpose, v)); } } -static void GLAPIENTRY +void GLAPIENTRY save_ClipControl(GLenum origin, GLenum depth) { GET_CURRENT_CONTEXT(ctx); @@ -8948,12 +8557,12 @@ save_ClipControl(GLenum origin, GLenum depth) n[2].e = depth; } if (ctx->ExecuteFlag) { - CALL_ClipControl(ctx->Exec, (origin, depth)); + CALL_ClipControl(ctx->Dispatch.Exec, (origin, depth)); } } -static void GLAPIENTRY -save_ClampColorARB(GLenum target, GLenum clamp) +void GLAPIENTRY +save_ClampColor(GLenum target, GLenum clamp) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -8964,13 +8573,13 @@ save_ClampColorARB(GLenum target, GLenum clamp) n[2].e = clamp; } if (ctx->ExecuteFlag) { - CALL_ClampColor(ctx->Exec, (target, clamp)); + CALL_ClampColor(ctx->Dispatch.Exec, (target, clamp)); } } /** GL_EXT_texture_integer */ -static void GLAPIENTRY -save_ClearColorIi(GLint red, GLint green, GLint blue, GLint alpha) +void GLAPIENTRY +save_ClearColorIiEXT(GLint red, GLint green, GLint blue, GLint alpha) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -8983,13 +8592,13 @@ save_ClearColorIi(GLint red, GLint green, GLint blue, GLint alpha) n[4].i = alpha; } if (ctx->ExecuteFlag) { - CALL_ClearColorIiEXT(ctx->Exec, (red, green, blue, alpha)); + CALL_ClearColorIiEXT(ctx->Dispatch.Exec, (red, green, blue, alpha)); } } /** GL_EXT_texture_integer */ -static void GLAPIENTRY -save_ClearColorIui(GLuint red, GLuint green, GLuint blue, GLuint alpha) +void GLAPIENTRY +save_ClearColorIuiEXT(GLuint red, GLuint green, GLuint blue, GLuint alpha) { GET_CURRENT_CONTEXT(ctx); Node *n; @@ -9002,12 +8611,12 @@ save_ClearColorIui(GLuint red, GLuint green, GLuint blue, GLuint alpha) n[4].ui = alpha; } if (ctx->ExecuteFlag) { - CALL_ClearColorIuiEXT(ctx->Exec, (red, green, blue, alpha)); + CALL_ClearColorIuiEXT(ctx->Dispatch.Exec, (red, green, blue, alpha)); } } /** GL_EXT_texture_integer */ -static void GLAPIENTRY +void GLAPIENTRY save_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); @@ -9023,12 +8632,12 @@ save_TexParameterIiv(GLenum target, GLenum pname, const GLint *params) n[6].i = params[3]; } if (ctx->ExecuteFlag) { - CALL_TexParameterIiv(ctx->Exec, (target, pname, params)); + CALL_TexParameterIiv(ctx->Dispatch.Exec, (target, pname, params)); } } /** GL_EXT_texture_integer */ -static void GLAPIENTRY +void GLAPIENTRY save_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) { GET_CURRENT_CONTEXT(ctx); @@ -9044,12 +8653,12 @@ save_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params) n[6].ui = params[3]; } if (ctx->ExecuteFlag) { - CALL_TexParameterIuiv(ctx->Exec, (target, pname, params)); + CALL_TexParameterIuiv(ctx->Dispatch.Exec, (target, pname, params)); } } -/* GL_ARB_instanced_arrays */ -static void GLAPIENTRY +/* GL_EXT/ARB_instanced_arrays */ +void GLAPIENTRY save_VertexAttribDivisor(GLuint index, GLuint divisor) { GET_CURRENT_CONTEXT(ctx); @@ -9061,26 +8670,26 @@ save_VertexAttribDivisor(GLuint index, GLuint divisor) n[2].ui = divisor; } if (ctx->ExecuteFlag) { - CALL_VertexAttribDivisor(ctx->Exec, (index, divisor)); + CALL_VertexAttribDivisor(ctx->Dispatch.Exec, (index, divisor)); } } /* GL_NV_texture_barrier */ -static void GLAPIENTRY +void GLAPIENTRY save_TextureBarrierNV(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); alloc_instruction(ctx, OPCODE_TEXTURE_BARRIER_NV, 0); if (ctx->ExecuteFlag) { - CALL_TextureBarrierNV(ctx->Exec, ()); + CALL_TextureBarrierNV(ctx->Dispatch.Exec, ()); } } /* GL_ARB_sampler_objects */ -static void GLAPIENTRY +void GLAPIENTRY save_BindSampler(GLuint unit, GLuint sampler) { Node *n; @@ -9092,11 +8701,11 @@ save_BindSampler(GLuint unit, GLuint sampler) n[2].ui = sampler; } if (ctx->ExecuteFlag) { - CALL_BindSampler(ctx->Exec, (unit, sampler)); + CALL_BindSampler(ctx->Dispatch.Exec, (unit, sampler)); } } -static void GLAPIENTRY +void GLAPIENTRY save_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) { Node *n; @@ -9117,11 +8726,11 @@ save_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params) } } if (ctx->ExecuteFlag) { - CALL_SamplerParameteriv(ctx->Exec, (sampler, pname, params)); + CALL_SamplerParameteriv(ctx->Dispatch.Exec, (sampler, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) { GLint parray[4]; @@ -9130,7 +8739,7 @@ save_SamplerParameteri(GLuint sampler, GLenum pname, GLint param) save_SamplerParameteriv(sampler, pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) { Node *n; @@ -9151,11 +8760,11 @@ save_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params) } } if (ctx->ExecuteFlag) { - CALL_SamplerParameterfv(ctx->Exec, (sampler, pname, params)); + CALL_SamplerParameterfv(ctx->Dispatch.Exec, (sampler, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -9164,7 +8773,7 @@ save_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param) save_SamplerParameterfv(sampler, pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) { Node *n; @@ -9185,11 +8794,11 @@ save_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params) } } if (ctx->ExecuteFlag) { - CALL_SamplerParameterIiv(ctx->Exec, (sampler, pname, params)); + CALL_SamplerParameterIiv(ctx->Dispatch.Exec, (sampler, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) { Node *n; @@ -9210,11 +8819,11 @@ save_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params) } } if (ctx->ExecuteFlag) { - CALL_SamplerParameterIuiv(ctx->Exec, (sampler, pname, params)); + CALL_SamplerParameterIuiv(ctx->Dispatch.Exec, (sampler, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) { Node *n; @@ -9230,13 +8839,13 @@ save_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) save_pointer(&n[4], sync); } if (ctx->ExecuteFlag) { - CALL_WaitSync(ctx->Exec, (sync, flags, timeout)); + CALL_WaitSync(ctx->Dispatch.Exec, (sync, flags, timeout)); } } /** GL_NV_conditional_render */ -static void GLAPIENTRY +void GLAPIENTRY save_BeginConditionalRender(GLuint queryId, GLenum mode) { GET_CURRENT_CONTEXT(ctx); @@ -9248,22 +8857,22 @@ save_BeginConditionalRender(GLuint queryId, GLenum mode) n[2].e = mode; } if (ctx->ExecuteFlag) { - CALL_BeginConditionalRender(ctx->Exec, (queryId, mode)); + CALL_BeginConditionalRender(ctx->Dispatch.Exec, (queryId, mode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_EndConditionalRender(void) { GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); alloc_instruction(ctx, OPCODE_END_CONDITIONAL_RENDER, 0); if (ctx->ExecuteFlag) { - CALL_EndConditionalRender(ctx->Exec, ()); + CALL_EndConditionalRender(ctx->Dispatch.Exec, ()); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding) { GET_CURRENT_CONTEXT(ctx); @@ -9276,11 +8885,11 @@ save_UniformBlockBinding(GLuint prog, GLuint index, GLuint binding) n[3].ui = binding; } if (ctx->ExecuteFlag) { - CALL_UniformBlockBinding(ctx->Exec, (prog, index, binding)); + CALL_UniformBlockBinding(ctx->Dispatch.Exec, (prog, index, binding)); } } -static void GLAPIENTRY +void GLAPIENTRY save_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, const GLuint *indices) { @@ -9298,12 +8907,12 @@ save_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, save_pointer(&n[3], indices_copy); } if (ctx->ExecuteFlag) { - CALL_UniformSubroutinesuiv(ctx->Exec, (shadertype, count, indices)); + CALL_UniformSubroutinesuiv(ctx->Dispatch.Exec, (shadertype, count, indices)); } } /** GL_EXT_window_rectangles */ -static void GLAPIENTRY +void GLAPIENTRY save_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box) { GET_CURRENT_CONTEXT(ctx); @@ -9320,13 +8929,13 @@ save_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box) save_pointer(&n[3], box_copy); } if (ctx->ExecuteFlag) { - CALL_WindowRectanglesEXT(ctx->Exec, (mode, count, box)); + CALL_WindowRectanglesEXT(ctx->Dispatch.Exec, (mode, count, box)); } } /** GL_NV_conservative_raster */ -static void GLAPIENTRY +void GLAPIENTRY save_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits) { GET_CURRENT_CONTEXT(ctx); @@ -9338,12 +8947,12 @@ save_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits) n[2].ui = ybits; } if (ctx->ExecuteFlag) { - CALL_SubpixelPrecisionBiasNV(ctx->Exec, (xbits, ybits)); + CALL_SubpixelPrecisionBiasNV(ctx->Dispatch.Exec, (xbits, ybits)); } } /** GL_NV_conservative_raster_dilate */ -static void GLAPIENTRY +void GLAPIENTRY save_ConservativeRasterParameterfNV(GLenum pname, GLfloat param) { GET_CURRENT_CONTEXT(ctx); @@ -9355,12 +8964,12 @@ save_ConservativeRasterParameterfNV(GLenum pname, GLfloat param) n[2].f = param; } if (ctx->ExecuteFlag) { - CALL_ConservativeRasterParameterfNV(ctx->Exec, (pname, param)); + CALL_ConservativeRasterParameterfNV(ctx->Dispatch.Exec, (pname, param)); } } /** GL_NV_conservative_raster_pre_snap_triangles */ -static void GLAPIENTRY +void GLAPIENTRY save_ConservativeRasterParameteriNV(GLenum pname, GLint param) { GET_CURRENT_CONTEXT(ctx); @@ -9372,13 +8981,13 @@ save_ConservativeRasterParameteriNV(GLenum pname, GLint param) n[2].i = param; } if (ctx->ExecuteFlag) { - CALL_ConservativeRasterParameteriNV(ctx->Exec, (pname, param)); + CALL_ConservativeRasterParameteriNV(ctx->Dispatch.Exec, (pname, param)); } } /** GL_EXT_direct_state_access */ -static void GLAPIENTRY +void GLAPIENTRY save_MatrixLoadfEXT(GLenum matrixMode, const GLfloat *m) { GET_CURRENT_CONTEXT(ctx); @@ -9392,11 +9001,11 @@ save_MatrixLoadfEXT(GLenum matrixMode, const GLfloat *m) } } if (ctx->ExecuteFlag) { - CALL_MatrixLoadfEXT(ctx->Exec, (matrixMode, m)); + CALL_MatrixLoadfEXT(ctx->Dispatch.Exec, (matrixMode, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixLoaddEXT(GLenum matrixMode, const GLdouble *m) { GLfloat f[16]; @@ -9406,7 +9015,7 @@ save_MatrixLoaddEXT(GLenum matrixMode, const GLdouble *m) save_MatrixLoadfEXT(matrixMode, f); } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixMultfEXT(GLenum matrixMode, const GLfloat * m) { GET_CURRENT_CONTEXT(ctx); @@ -9420,11 +9029,11 @@ save_MatrixMultfEXT(GLenum matrixMode, const GLfloat * m) } } if (ctx->ExecuteFlag) { - CALL_MatrixMultfEXT(ctx->Exec, (matrixMode, m)); + CALL_MatrixMultfEXT(ctx->Dispatch.Exec, (matrixMode, m)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixMultdEXT(GLenum matrixMode, const GLdouble * m) { GLfloat f[16]; @@ -9434,7 +9043,7 @@ save_MatrixMultdEXT(GLenum matrixMode, const GLdouble * m) save_MatrixMultfEXT(matrixMode, f); } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixRotatefEXT(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -9449,17 +9058,17 @@ save_MatrixRotatefEXT(GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GL n[5].f = z; } if (ctx->ExecuteFlag) { - CALL_MatrixRotatefEXT(ctx->Exec, (matrixMode, angle, x, y, z)); + CALL_MatrixRotatefEXT(ctx->Dispatch.Exec, (matrixMode, angle, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixRotatedEXT(GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z) { save_MatrixRotatefEXT(matrixMode, (GLfloat) angle, (GLfloat) x, (GLfloat) y, (GLfloat) z); } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixScalefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -9473,17 +9082,17 @@ save_MatrixScalefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } if (ctx->ExecuteFlag) { - CALL_MatrixScalefEXT(ctx->Exec, (matrixMode, x, y, z)); + CALL_MatrixScalefEXT(ctx->Dispatch.Exec, (matrixMode, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixScaledEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z) { save_MatrixScalefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixTranslatefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) { GET_CURRENT_CONTEXT(ctx); @@ -9497,17 +9106,17 @@ save_MatrixTranslatefEXT(GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z) n[4].f = z; } if (ctx->ExecuteFlag) { - CALL_MatrixTranslatefEXT(ctx->Exec, (matrixMode, x, y, z)); + CALL_MatrixTranslatefEXT(ctx->Dispatch.Exec, (matrixMode, x, y, z)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixTranslatedEXT(GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z) { save_MatrixTranslatefEXT(matrixMode, (GLfloat) x, (GLfloat) y, (GLfloat) z); } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixLoadIdentityEXT(GLenum matrixMode) { GET_CURRENT_CONTEXT(ctx); @@ -9518,11 +9127,11 @@ save_MatrixLoadIdentityEXT(GLenum matrixMode) n[1].e = matrixMode; } if (ctx->ExecuteFlag) { - CALL_MatrixLoadIdentityEXT(ctx->Exec, (matrixMode)); + CALL_MatrixLoadIdentityEXT(ctx->Dispatch.Exec, (matrixMode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixOrthoEXT(GLenum matrixMode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) { @@ -9540,12 +9149,12 @@ save_MatrixOrthoEXT(GLenum matrixMode, GLdouble left, GLdouble right, n[7].f = (GLfloat) farval; } if (ctx->ExecuteFlag) { - CALL_MatrixOrthoEXT(ctx->Exec, (matrixMode, left, right, bottom, top, nearval, farval)); + CALL_MatrixOrthoEXT(ctx->Dispatch.Exec, (matrixMode, left, right, bottom, top, nearval, farval)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixFrustumEXT(GLenum matrixMode, GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble nearval, GLdouble farval) { @@ -9563,11 +9172,11 @@ save_MatrixFrustumEXT(GLenum matrixMode, GLdouble left, GLdouble right, n[7].f = (GLfloat) farval; } if (ctx->ExecuteFlag) { - CALL_MatrixFrustumEXT(ctx->Exec, (matrixMode, left, right, bottom, top, nearval, farval)); + CALL_MatrixFrustumEXT(ctx->Dispatch.Exec, (matrixMode, left, right, bottom, top, nearval, farval)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixPushEXT(GLenum matrixMode) { GET_CURRENT_CONTEXT(ctx); @@ -9578,11 +9187,11 @@ save_MatrixPushEXT(GLenum matrixMode) n[1].e = matrixMode; } if (ctx->ExecuteFlag) { - CALL_MatrixPushEXT(ctx->Exec, (matrixMode)); + CALL_MatrixPushEXT(ctx->Dispatch.Exec, (matrixMode)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MatrixPopEXT(GLenum matrixMode) { GET_CURRENT_CONTEXT(ctx); @@ -9593,43 +9202,43 @@ save_MatrixPopEXT(GLenum matrixMode) n[1].e = matrixMode; } if (ctx->ExecuteFlag) { - CALL_MatrixPopEXT(ctx->Exec, (matrixMode)); + CALL_MatrixPopEXT(ctx->Dispatch.Exec, (matrixMode)); } } -static void GLAPIENTRY -save_MatrixLoadTransposefEXT(GLenum matrixMode, const GLfloat m[16]) +void GLAPIENTRY +save_MatrixLoadTransposefEXT(GLenum matrixMode, const GLfloat *m) { GLfloat tm[16]; _math_transposef(tm, m); save_MatrixLoadfEXT(matrixMode, tm); } -static void GLAPIENTRY -save_MatrixLoadTransposedEXT(GLenum matrixMode, const GLdouble m[16]) +void GLAPIENTRY +save_MatrixLoadTransposedEXT(GLenum matrixMode, const GLdouble *m) { GLfloat tm[16]; _math_transposefd(tm, m); save_MatrixLoadfEXT(matrixMode, tm); } -static void GLAPIENTRY -save_MatrixMultTransposefEXT(GLenum matrixMode, const GLfloat m[16]) +void GLAPIENTRY +save_MatrixMultTransposefEXT(GLenum matrixMode, const GLfloat *m) { GLfloat tm[16]; _math_transposef(tm, m); save_MatrixMultfEXT(matrixMode, tm); } -static void GLAPIENTRY -save_MatrixMultTransposedEXT(GLenum matrixMode, const GLdouble m[16]) +void GLAPIENTRY +save_MatrixMultTransposedEXT(GLenum matrixMode, const GLdouble *m) { GLfloat tm[16]; _math_transposefd(tm, m); save_MatrixMultfEXT(matrixMode, tm); } -static void GLAPIENTRY +void GLAPIENTRY save_TextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params) { @@ -9647,12 +9256,12 @@ save_TextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, n[7].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_TextureParameterfvEXT(ctx->Exec, (texture, target, pname, params)); + CALL_TextureParameterfvEXT(ctx->Dispatch.Exec, (texture, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -9661,7 +9270,7 @@ save_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat p save_TextureParameterfvEXT(texture, target, pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_TextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); @@ -9678,11 +9287,11 @@ save_TextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GL n[7].i = params[3]; } if (ctx->ExecuteFlag) { - CALL_TextureParameterivEXT(ctx->Exec, (texture, target, pname, params)); + CALL_TextureParameterivEXT(ctx->Dispatch.Exec, (texture, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param) { GLint fparam[4]; @@ -9691,7 +9300,7 @@ save_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint par save_TextureParameterivEXT(texture, target, pname, fparam); } -static void GLAPIENTRY +void GLAPIENTRY save_TextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint* params) { GET_CURRENT_CONTEXT(ctx); @@ -9708,11 +9317,11 @@ save_TextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const G n[7].i = params[3]; } if (ctx->ExecuteFlag) { - CALL_TextureParameterIivEXT(ctx->Exec, (texture, target, pname, params)); + CALL_TextureParameterIivEXT(ctx->Dispatch.Exec, (texture, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint* params) { GET_CURRENT_CONTEXT(ctx); @@ -9729,12 +9338,12 @@ save_TextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const n[7].ui = params[3]; } if (ctx->ExecuteFlag) { - CALL_TextureParameterIuivEXT(ctx->Exec, (texture, target, pname, params)); + CALL_TextureParameterIuivEXT(ctx->Dispatch.Exec, (texture, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLint components, GLsizei width, GLint border, @@ -9743,7 +9352,7 @@ save_TextureImage1DEXT(GLuint texture, GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_1D) { /* don't compile, execute immediately */ - CALL_TextureImage1DEXT(ctx->Exec, (texture, target, level, components, width, + CALL_TextureImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, components, width, border, format, type, pixels)); } else { @@ -9764,14 +9373,14 @@ save_TextureImage1DEXT(GLuint texture, GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TextureImage1DEXT(ctx->Exec, (texture, target, level, components, width, + CALL_TextureImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, components, width, border, format, type, pixels)); } } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, @@ -9780,7 +9389,7 @@ save_TextureImage2DEXT(GLuint texture, GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_2D) { /* don't compile, execute immediately */ - CALL_TextureImage2DEXT(ctx->Exec, (texture, target, level, components, width, + CALL_TextureImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, components, width, height, border, format, type, pixels)); } else { @@ -9802,14 +9411,14 @@ save_TextureImage2DEXT(GLuint texture, GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TextureImage2DEXT(ctx->Exec, (texture, target, level, components, width, + CALL_TextureImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, components, width, height, border, format, type, pixels)); } } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, @@ -9819,7 +9428,7 @@ save_TextureImage3DEXT(GLuint texture, GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_3D) { /* don't compile, execute immediately */ - CALL_TextureImage3DEXT(ctx->Exec, (texture, target, level, internalFormat, width, + CALL_TextureImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, height, depth, border, format, type, pixels)); } @@ -9843,7 +9452,7 @@ save_TextureImage3DEXT(GLuint texture, GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TextureImage3DEXT(ctx->Exec, (texture, target, level, internalFormat, + CALL_TextureImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, height, depth, border, format, type, pixels)); } @@ -9851,7 +9460,7 @@ save_TextureImage3DEXT(GLuint texture, GLenum target, } -static void GLAPIENTRY +void GLAPIENTRY save_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels) @@ -9875,13 +9484,13 @@ save_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoff pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TextureSubImage1DEXT(ctx->Exec, (texture, target, level, xoffset, width, + CALL_TextureSubImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, width, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, @@ -9908,13 +9517,13 @@ save_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TextureSubImage2DEXT(ctx->Exec, (texture, target, level, xoffset, yoffset, + CALL_TextureSubImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, yoffset, width, height, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, @@ -9943,14 +9552,14 @@ save_TextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_TextureSubImage3DEXT(ctx->Exec, (texture, target, level, + CALL_TextureSubImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) @@ -9970,13 +9579,13 @@ save_CopyTextureImage1DEXT(GLuint texture, GLenum target, GLint level, n[8].i = border; } if (ctx->ExecuteFlag) { - CALL_CopyTextureImage1DEXT(ctx->Exec, (texture, target, level, + CALL_CopyTextureImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, internalformat, x, y, width, border)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, @@ -9998,13 +9607,13 @@ save_CopyTextureImage2DEXT(GLuint texture, GLenum target, GLint level, n[9].i = border; } if (ctx->ExecuteFlag) { - CALL_CopyTextureImage2DEXT(ctx->Exec, (texture, target, level, + CALL_CopyTextureImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, internalformat, x, y, width, height, border)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { @@ -10022,12 +9631,12 @@ save_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, n[7].i = width; } if (ctx->ExecuteFlag) { - CALL_CopyTextureSubImage1DEXT(ctx->Exec, + CALL_CopyTextureSubImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, x, y, width)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLint height) @@ -10048,14 +9657,14 @@ save_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, n[9].i = height; } if (ctx->ExecuteFlag) { - CALL_CopyTextureSubImage2DEXT(ctx->Exec, (texture, target, level, + CALL_CopyTextureSubImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, yoffset, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLint height) @@ -10077,14 +9686,14 @@ save_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, n[10].i = height; } if (ctx->ExecuteFlag) { - CALL_CopyTextureSubImage3DEXT(ctx->Exec, (texture, target, level, + CALL_CopyTextureSubImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, yoffset, zoffset, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) { GET_CURRENT_CONTEXT(ctx); @@ -10097,12 +9706,12 @@ save_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture) n[3].ui = texture; } if (ctx->ExecuteFlag) { - CALL_BindMultiTextureEXT(ctx->Exec, (texunit, target, texture)); + CALL_BindMultiTextureEXT(ctx->Dispatch.Exec, (texunit, target, texture)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params) { @@ -10120,12 +9729,12 @@ save_MultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, n[7].f = params[3]; } if (ctx->ExecuteFlag) { - CALL_MultiTexParameterfvEXT(ctx->Exec, (texunit, target, pname, params)); + CALL_MultiTexParameterfvEXT(ctx->Dispatch.Exec, (texunit, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -10134,7 +9743,7 @@ save_MultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat save_MultiTexParameterfvEXT(texunit, target, pname, parray); } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); @@ -10151,11 +9760,11 @@ save_MultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const G n[7].i = params[3]; } if (ctx->ExecuteFlag) { - CALL_MultiTexParameterivEXT(ctx->Exec, (texunit, target, pname, params)); + CALL_MultiTexParameterivEXT(ctx->Dispatch.Exec, (texunit, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params) { GET_CURRENT_CONTEXT(ctx); @@ -10172,11 +9781,11 @@ save_MultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const n[7].i = params[3]; } if (ctx->ExecuteFlag) { - CALL_MultiTexParameterIivEXT(ctx->Exec, (texunit, target, pname, params)); + CALL_MultiTexParameterIivEXT(ctx->Dispatch.Exec, (texunit, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint *params) { GET_CURRENT_CONTEXT(ctx); @@ -10193,11 +9802,11 @@ save_MultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const n[7].ui = params[3]; } if (ctx->ExecuteFlag) { - CALL_MultiTexParameterIuivEXT(ctx->Exec, (texunit, target, pname, params)); + CALL_MultiTexParameterIuivEXT(ctx->Dispatch.Exec, (texunit, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) { GLint fparam[4]; @@ -10207,7 +9816,7 @@ save_MultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint pa } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint components, GLsizei width, GLint border, @@ -10216,7 +9825,7 @@ save_MultiTexImage1DEXT(GLenum texunit, GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_1D) { /* don't compile, execute immediately */ - CALL_MultiTexImage1DEXT(ctx->Exec, (texunit, target, level, components, width, + CALL_MultiTexImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, components, width, border, format, type, pixels)); } else { @@ -10237,14 +9846,14 @@ save_MultiTexImage1DEXT(GLenum texunit, GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_MultiTexImage1DEXT(ctx->Exec, (texunit, target, level, components, width, + CALL_MultiTexImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, components, width, border, format, type, pixels)); } } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint components, GLsizei width, GLsizei height, GLint border, @@ -10253,7 +9862,7 @@ save_MultiTexImage2DEXT(GLenum texunit, GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_2D) { /* don't compile, execute immediately */ - CALL_MultiTexImage2DEXT(ctx->Exec, (texunit, target, level, components, width, + CALL_MultiTexImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, components, width, height, border, format, type, pixels)); } else { @@ -10275,14 +9884,14 @@ save_MultiTexImage2DEXT(GLenum texunit, GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_MultiTexImage2DEXT(ctx->Exec, (texunit, target, level, components, width, + CALL_MultiTexImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, components, width, height, border, format, type, pixels)); } } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint internalFormat, GLsizei width, GLsizei height, GLsizei depth, @@ -10292,7 +9901,7 @@ save_MultiTexImage3DEXT(GLenum texunit, GLenum target, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_3D) { /* don't compile, execute immediately */ - CALL_MultiTexImage3DEXT(ctx->Exec, (texunit, target, level, internalFormat, width, + CALL_MultiTexImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, height, depth, border, format, type, pixels)); } @@ -10316,7 +9925,7 @@ save_MultiTexImage3DEXT(GLenum texunit, GLenum target, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_MultiTexImage3DEXT(ctx->Exec, (texunit, target, level, internalFormat, + CALL_MultiTexImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, height, depth, border, format, type, pixels)); } @@ -10324,7 +9933,7 @@ save_MultiTexImage3DEXT(GLenum texunit, GLenum target, } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLenum type, const GLvoid * pixels) @@ -10348,13 +9957,13 @@ save_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xof pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_MultiTexSubImage1DEXT(ctx->Exec, (texunit, target, level, xoffset, width, + CALL_MultiTexSubImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, width, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, @@ -10381,13 +9990,13 @@ save_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_MultiTexSubImage2DEXT(ctx->Exec, (texunit, target, level, xoffset, yoffset, + CALL_MultiTexSubImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, yoffset, width, height, format, type, pixels)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, @@ -10416,7 +10025,7 @@ save_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, pixels, &ctx->Unpack)); } if (ctx->ExecuteFlag) { - CALL_MultiTexSubImage3DEXT(ctx->Exec, (texunit, target, level, + CALL_MultiTexSubImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels)); @@ -10424,7 +10033,7 @@ save_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, GLint border) @@ -10444,14 +10053,14 @@ save_CopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, n[8].i = border; } if (ctx->ExecuteFlag) { - CALL_CopyMultiTexImage1DEXT(ctx->Exec, (texunit, target, level, + CALL_CopyMultiTexImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalformat, x, y, width, border)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalformat, GLint x, GLint y, GLsizei width, @@ -10473,14 +10082,14 @@ save_CopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, n[9].i = border; } if (ctx->ExecuteFlag) { - CALL_CopyMultiTexImage2DEXT(ctx->Exec, (texunit, target, level, + CALL_CopyMultiTexImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalformat, x, y, width, height, border)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint x, GLint y, GLsizei width) { @@ -10498,13 +10107,13 @@ save_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, n[7].i = width; } if (ctx->ExecuteFlag) { - CALL_CopyMultiTexSubImage1DEXT(ctx->Exec, + CALL_CopyMultiTexSubImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, x, y, width)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLint height) @@ -10525,14 +10134,14 @@ save_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, n[9].i = height; } if (ctx->ExecuteFlag) { - CALL_CopyMultiTexSubImage2DEXT(ctx->Exec, (texunit, target, level, + CALL_CopyMultiTexSubImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, yoffset, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLint x, GLint y, GLsizei width, GLint height) @@ -10554,14 +10163,14 @@ save_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, n[10].i = height; } if (ctx->ExecuteFlag) { - CALL_CopyMultiTexSubImage3DEXT(ctx->Exec, (texunit, target, level, + CALL_CopyMultiTexSubImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, yoffset, zoffset, x, y, width, height)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); @@ -10584,12 +10193,12 @@ save_MultiTexEnvfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat } } if (ctx->ExecuteFlag) { - CALL_MultiTexEnvfvEXT(ctx->Exec, (texunit, target, pname, params)); + CALL_MultiTexEnvfvEXT(ctx->Dispatch.Exec, (texunit, target, pname, params)); } } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) { GLfloat parray[4]; @@ -10599,7 +10208,7 @@ save_MultiTexEnvfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param) } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) { GLfloat p[4]; @@ -10609,7 +10218,7 @@ save_MultiTexEnviEXT(GLenum texunit, GLenum target, GLenum pname, GLint param) } -static void GLAPIENTRY +void GLAPIENTRY save_MultiTexEnvivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint * param) { GLfloat p[4]; @@ -10627,7 +10236,7 @@ save_MultiTexEnvivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint * } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, @@ -10636,7 +10245,7 @@ save_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_1D) { /* don't compile, execute immediately */ - CALL_CompressedTextureImage1DEXT(ctx->Exec, (texture, target, level, + CALL_CompressedTextureImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, border, imageSize, data)); @@ -10659,7 +10268,7 @@ save_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTextureImage1DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedTextureImage1DEXT(ctx->Exec, + CALL_CompressedTextureImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, border, imageSize, data)); } @@ -10667,7 +10276,7 @@ save_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, @@ -10676,7 +10285,7 @@ save_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_2D) { /* don't compile, execute immediately */ - CALL_CompressedTextureImage2DEXT(ctx->Exec, (texture, target, level, + CALL_CompressedTextureImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, height, border, imageSize, data)); } @@ -10699,7 +10308,7 @@ save_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTextureImage2DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedTextureImage2DEXT(ctx->Exec, + CALL_CompressedTextureImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, height, border, imageSize, data)); } @@ -10707,7 +10316,7 @@ save_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, @@ -10716,7 +10325,7 @@ save_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_3D) { /* don't compile, execute immediately */ - CALL_CompressedTextureImage3DEXT(ctx->Exec, (texture, target, level, + CALL_CompressedTextureImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, height, depth, border, imageSize, data)); @@ -10741,7 +10350,7 @@ save_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTextureImage3DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedTextureImage3DEXT(ctx->Exec, + CALL_CompressedTextureImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, internalFormat, width, height, depth, border, imageSize, data)); @@ -10750,7 +10359,7 @@ save_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data) @@ -10773,13 +10382,13 @@ save_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTextureSubImage1DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedTextureSubImage1DEXT(ctx->Exec, (texture, target, level, xoffset, + CALL_CompressedTextureSubImage1DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, width, format, imageSize, data)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, @@ -10805,14 +10414,14 @@ save_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTextureSubImage2DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedTextureSubImage2DEXT(ctx->Exec, + CALL_CompressedTextureSubImage2DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, yoffset, width, height, format, imageSize, data)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, @@ -10840,7 +10449,7 @@ save_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedTextureSubImage3DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedTextureSubImage3DEXT(ctx->Exec, + CALL_CompressedTextureSubImage3DEXT(ctx->Dispatch.Exec, (texture, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data)); @@ -10848,7 +10457,7 @@ save_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLint border, GLsizei imageSize, @@ -10857,7 +10466,7 @@ save_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_1D) { /* don't compile, execute immediately */ - CALL_CompressedMultiTexImage1DEXT(ctx->Exec, (texunit, target, level, + CALL_CompressedMultiTexImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, border, imageSize, data)); @@ -10880,7 +10489,7 @@ save_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedMultiTexImage1DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedMultiTexImage1DEXT(ctx->Exec, + CALL_CompressedMultiTexImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, border, imageSize, data)); } @@ -10888,7 +10497,7 @@ save_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLint border, GLsizei imageSize, @@ -10897,7 +10506,7 @@ save_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_2D) { /* don't compile, execute immediately */ - CALL_CompressedMultiTexImage2DEXT(ctx->Exec, (texunit, target, level, + CALL_CompressedMultiTexImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, height, border, imageSize, data)); } @@ -10920,7 +10529,7 @@ save_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedMultiTexImage2DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedMultiTexImage2DEXT(ctx->Exec, + CALL_CompressedMultiTexImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, height, border, imageSize, data)); } @@ -10928,7 +10537,7 @@ save_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GLenum internalFormat, GLsizei width, GLsizei height, GLsizei depth, GLint border, @@ -10937,7 +10546,7 @@ save_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, GET_CURRENT_CONTEXT(ctx); if (target == GL_PROXY_TEXTURE_3D) { /* don't compile, execute immediately */ - CALL_CompressedMultiTexImage3DEXT(ctx->Exec, (texunit, target, level, + CALL_CompressedMultiTexImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, height, depth, border, imageSize, data)); @@ -10962,7 +10571,7 @@ save_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedMultiTexImage3DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedMultiTexImage3DEXT(ctx->Exec, + CALL_CompressedMultiTexImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, internalFormat, width, height, depth, border, imageSize, data)); @@ -10971,7 +10580,7 @@ save_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLsizei width, GLenum format, GLsizei imageSize, const GLvoid * data) @@ -10994,13 +10603,13 @@ save_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedMultiTexSubImage1DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedMultiTexSubImage1DEXT(ctx->Exec, (texunit, target, level, xoffset, + CALL_CompressedMultiTexSubImage1DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, width, format, imageSize, data)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, @@ -11026,14 +10635,14 @@ save_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedMultiTexSubImage2DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedMultiTexSubImage2DEXT(ctx->Exec, + CALL_CompressedMultiTexSubImage2DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, yoffset, width, height, format, imageSize, data)); } } -static void GLAPIENTRY +void GLAPIENTRY save_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, @@ -11061,7 +10670,7 @@ save_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, copy_data(data, imageSize, "glCompressedMultiTexSubImage3DEXT")); } if (ctx->ExecuteFlag) { - CALL_CompressedMultiTexSubImage3DEXT(ctx->Exec, + CALL_CompressedMultiTexSubImage3DEXT(ctx->Dispatch.Exec, (texunit, target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data)); @@ -11069,7 +10678,7 @@ save_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, } -static void GLAPIENTRY +void GLAPIENTRY save_NamedProgramStringEXT(GLuint program, GLenum target, GLenum format, GLsizei len, const GLvoid * string) { @@ -11093,12 +10702,12 @@ save_NamedProgramStringEXT(GLuint program, GLenum target, GLenum format, GLsizei save_pointer(&n[5], programCopy); } if (ctx->ExecuteFlag) { - CALL_NamedProgramStringEXT(ctx->Exec, (program, target, format, len, string)); + CALL_NamedProgramStringEXT(ctx->Dispatch.Exec, (program, target, format, len, string)); } } -static void GLAPIENTRY +void GLAPIENTRY save_NamedProgramLocalParameter4fEXT(GLuint program, GLenum target, GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w) { @@ -11116,12 +10725,12 @@ save_NamedProgramLocalParameter4fEXT(GLuint program, GLenum target, GLuint index n[7].f = w; } if (ctx->ExecuteFlag) { - CALL_NamedProgramLocalParameter4fEXT(ctx->Exec, (program, target, index, x, y, z, w)); + CALL_NamedProgramLocalParameter4fEXT(ctx->Dispatch.Exec, (program, target, index, x, y, z, w)); } } -static void GLAPIENTRY +void GLAPIENTRY save_NamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint index, const GLfloat *params) { @@ -11130,7 +10739,7 @@ save_NamedProgramLocalParameter4fvEXT(GLuint program, GLenum target, GLuint inde } -static void GLAPIENTRY +void GLAPIENTRY save_NamedProgramLocalParameter4dEXT(GLuint program, GLenum target, GLuint index, GLdouble x, GLdouble y, GLdouble z, GLdouble w) @@ -11140,7 +10749,7 @@ save_NamedProgramLocalParameter4dEXT(GLuint program, GLenum target, GLuint index } -static void GLAPIENTRY +void GLAPIENTRY save_NamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, GLuint index, const GLdouble *params) { @@ -11149,6 +10758,29 @@ save_NamedProgramLocalParameter4dvEXT(GLuint program, GLenum target, GLuint inde (GLfloat) params[3]); } +void GLAPIENTRY +save_PrimitiveBoundingBox(float minX, float minY, float minZ, float minW, + float maxX, float maxY, float maxZ, float maxW) +{ + GET_CURRENT_CONTEXT(ctx); + Node *n; + ASSERT_OUTSIDE_SAVE_BEGIN_END_AND_FLUSH(ctx); + n = alloc_instruction(ctx, OPCODE_PRIMITIVE_BOUNDING_BOX, 8); + if (n) { + n[1].f = minX; + n[2].f = minY; + n[3].f = minZ; + n[4].f = minW; + n[5].f = maxX; + n[6].f = maxY; + n[7].f = maxZ; + n[8].f = maxW; + } + if (ctx->ExecuteFlag) { + CALL_PrimitiveBoundingBox(ctx->Dispatch.Exec, (minX, minY, minZ, minW, + maxX, maxY, maxZ, maxW)); + } +} /** * Save an error-generating command into display list. @@ -11190,10 +10822,11 @@ _mesa_compile_error(struct gl_context *ctx, GLenum error, const char *s) */ bool _mesa_get_list(struct gl_context *ctx, GLuint list, - struct gl_display_list **dlist) + struct gl_display_list **dlist, + bool locked) { struct gl_display_list * dl = - list > 0 ? _mesa_lookup_list(ctx, list) : NULL; + list > 0 ? _mesa_lookup_list(ctx, list, locked) : NULL; if (dlist) *dlist = dl; @@ -11212,6 +10845,7 @@ _mesa_get_list(struct gl_context *ctx, GLuint list, * Execute a display list. Note that the ListBase offset must have already * been added before calling this function. I.e. the list argument is * the absolute list number, not relative to ListBase. + * Must be called with ctx->Shared->DisplayList locked. * \param list - display list number */ static void @@ -11220,19 +10854,10 @@ execute_list(struct gl_context *ctx, GLuint list) struct gl_display_list *dlist; Node *n; - if (list == 0 || !_mesa_get_list(ctx, list, &dlist)) + if (list == 0 || !_mesa_get_list(ctx, list, &dlist, true)) return; - if (ctx->ListState.CallDepth == MAX_LIST_NESTING) { - /* raise an error? */ - return; - } - - ctx->ListState.CallDepth++; - - vbo_save_BeginCallList(ctx, dlist); - - n = dlist->Head; + n = get_list_head(ctx, dlist); while (1) { const OpCode opcode = n[0].opcode; @@ -11242,70 +10867,75 @@ execute_list(struct gl_context *ctx, GLuint list) _mesa_error(ctx, n[1].e, "%s", (const char *) get_pointer(&n[2])); break; case OPCODE_ACCUM: - CALL_Accum(ctx->Exec, (n[1].e, n[2].f)); + CALL_Accum(ctx->Dispatch.Exec, (n[1].e, n[2].f)); break; case OPCODE_ALPHA_FUNC: - CALL_AlphaFunc(ctx->Exec, (n[1].e, n[2].f)); + CALL_AlphaFunc(ctx->Dispatch.Exec, (n[1].e, n[2].f)); break; case OPCODE_BIND_TEXTURE: - CALL_BindTexture(ctx->Exec, (n[1].e, n[2].ui)); + CALL_BindTexture(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_BITMAP: - { - const struct gl_pixelstore_attrib save = ctx->Unpack; - ctx->Unpack = ctx->DefaultPacking; - CALL_Bitmap(ctx->Exec, ((GLsizei) n[1].i, (GLsizei) n[2].i, - n[3].f, n[4].f, n[5].f, n[6].f, - get_pointer(&n[7]))); - ctx->Unpack = save; /* restore */ + if (_mesa_inside_begin_end(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glCallList -> glBitmap inside Begin/End"); + } else { + _mesa_bitmap(ctx, n[1].i, n[2].i, n[3].f, n[4].f, n[5].f, + n[6].f, NULL, get_pointer(&n[7])); } break; case OPCODE_BLEND_COLOR: - CALL_BlendColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); + CALL_BlendColor(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; case OPCODE_BLEND_EQUATION: - CALL_BlendEquation(ctx->Exec, (n[1].e)); + CALL_BlendEquation(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_BLEND_EQUATION_SEPARATE: - CALL_BlendEquationSeparate(ctx->Exec, (n[1].e, n[2].e)); + CALL_BlendEquationSeparate(ctx->Dispatch.Exec, (n[1].e, n[2].e)); break; case OPCODE_BLEND_FUNC_SEPARATE: - CALL_BlendFuncSeparate(ctx->Exec, + CALL_BlendFuncSeparate(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, n[4].e)); break; case OPCODE_BLEND_FUNC_I: /* GL_ARB_draw_buffers_blend */ - CALL_BlendFunciARB(ctx->Exec, (n[1].ui, n[2].e, n[3].e)); + CALL_BlendFunciARB(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e)); break; case OPCODE_BLEND_FUNC_SEPARATE_I: /* GL_ARB_draw_buffers_blend */ - CALL_BlendFuncSeparateiARB(ctx->Exec, (n[1].ui, n[2].e, n[3].e, + CALL_BlendFuncSeparateiARB(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e, n[4].e, n[5].e)); break; case OPCODE_BLEND_EQUATION_I: /* GL_ARB_draw_buffers_blend */ - CALL_BlendEquationiARB(ctx->Exec, (n[1].ui, n[2].e)); + CALL_BlendEquationiARB(ctx->Dispatch.Exec, (n[1].ui, n[2].e)); break; case OPCODE_BLEND_EQUATION_SEPARATE_I: /* GL_ARB_draw_buffers_blend */ - CALL_BlendEquationSeparateiARB(ctx->Exec, + CALL_BlendEquationSeparateiARB(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e)); break; case OPCODE_CALL_LIST: /* Generated by glCallList(), don't add ListBase */ if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { + ctx->ListState.CallDepth++; execute_list(ctx, n[1].ui); + ctx->ListState.CallDepth--; } break; case OPCODE_CALL_LISTS: if (ctx->ListState.CallDepth < MAX_LIST_NESTING) { - CALL_CallLists(ctx->Exec, (n[1].i, n[2].e, get_pointer(&n[3]))); + ctx->ListState.CallDepth++; + _mesa_HashUnlockMutex(&ctx->Shared->DisplayList); + CALL_CallLists(ctx->Dispatch.Exec, (n[1].i, n[2].e, get_pointer(&n[3]))); + _mesa_HashLockMutex(&ctx->Shared->DisplayList); + ctx->ListState.CallDepth--; } break; case OPCODE_CLEAR: - CALL_Clear(ctx->Exec, (n[1].bf)); + CALL_Clear(ctx->Dispatch.Exec, (n[1].bf)); break; case OPCODE_CLEAR_BUFFER_IV: { @@ -11314,7 +10944,7 @@ execute_list(struct gl_context *ctx, GLuint list) value[1] = n[4].i; value[2] = n[5].i; value[3] = n[6].i; - CALL_ClearBufferiv(ctx->Exec, (n[1].e, n[2].i, value)); + CALL_ClearBufferiv(ctx->Dispatch.Exec, (n[1].e, n[2].i, value)); } break; case OPCODE_CLEAR_BUFFER_UIV: @@ -11324,7 +10954,7 @@ execute_list(struct gl_context *ctx, GLuint list) value[1] = n[4].ui; value[2] = n[5].ui; value[3] = n[6].ui; - CALL_ClearBufferuiv(ctx->Exec, (n[1].e, n[2].i, value)); + CALL_ClearBufferuiv(ctx->Dispatch.Exec, (n[1].e, n[2].i, value)); } break; case OPCODE_CLEAR_BUFFER_FV: @@ -11334,26 +10964,26 @@ execute_list(struct gl_context *ctx, GLuint list) value[1] = n[4].f; value[2] = n[5].f; value[3] = n[6].f; - CALL_ClearBufferfv(ctx->Exec, (n[1].e, n[2].i, value)); + CALL_ClearBufferfv(ctx->Dispatch.Exec, (n[1].e, n[2].i, value)); } break; case OPCODE_CLEAR_BUFFER_FI: - CALL_ClearBufferfi(ctx->Exec, (n[1].e, n[2].i, n[3].f, n[4].i)); + CALL_ClearBufferfi(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].f, n[4].i)); break; case OPCODE_CLEAR_COLOR: - CALL_ClearColor(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); + CALL_ClearColor(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; case OPCODE_CLEAR_ACCUM: - CALL_ClearAccum(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); + CALL_ClearAccum(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; case OPCODE_CLEAR_DEPTH: - CALL_ClearDepth(ctx->Exec, ((GLclampd) n[1].f)); + CALL_ClearDepth(ctx->Dispatch.Exec, ((GLclampd) n[1].f)); break; case OPCODE_CLEAR_INDEX: - CALL_ClearIndex(ctx->Exec, ((GLfloat) n[1].ui)); + CALL_ClearIndex(ctx->Dispatch.Exec, ((GLfloat) n[1].ui)); break; case OPCODE_CLEAR_STENCIL: - CALL_ClearStencil(ctx->Exec, (n[1].i)); + CALL_ClearStencil(ctx->Dispatch.Exec, (n[1].i)); break; case OPCODE_CLIP_PLANE: { @@ -11362,88 +10992,88 @@ execute_list(struct gl_context *ctx, GLuint list) eq[1] = n[3].f; eq[2] = n[4].f; eq[3] = n[5].f; - CALL_ClipPlane(ctx->Exec, (n[1].e, eq)); + CALL_ClipPlane(ctx->Dispatch.Exec, (n[1].e, eq)); } break; case OPCODE_COLOR_MASK: - CALL_ColorMask(ctx->Exec, (n[1].b, n[2].b, n[3].b, n[4].b)); + CALL_ColorMask(ctx->Dispatch.Exec, (n[1].b, n[2].b, n[3].b, n[4].b)); break; case OPCODE_COLOR_MASK_INDEXED: - CALL_ColorMaski(ctx->Exec, (n[1].ui, n[2].b, n[3].b, + CALL_ColorMaski(ctx->Dispatch.Exec, (n[1].ui, n[2].b, n[3].b, n[4].b, n[5].b)); break; case OPCODE_COLOR_MATERIAL: - CALL_ColorMaterial(ctx->Exec, (n[1].e, n[2].e)); + CALL_ColorMaterial(ctx->Dispatch.Exec, (n[1].e, n[2].e)); break; case OPCODE_COPY_PIXELS: - CALL_CopyPixels(ctx->Exec, (n[1].i, n[2].i, + CALL_CopyPixels(ctx->Dispatch.Exec, (n[1].i, n[2].i, (GLsizei) n[3].i, (GLsizei) n[4].i, n[5].e)); break; case OPCODE_COPY_TEX_IMAGE1D: - CALL_CopyTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i, + CALL_CopyTexImage1D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].e, n[4].i, n[5].i, n[6].i, n[7].i)); break; case OPCODE_COPY_TEX_IMAGE2D: - CALL_CopyTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e, n[4].i, + CALL_CopyTexImage2D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].e, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i)); break; case OPCODE_COPY_TEX_SUB_IMAGE1D: - CALL_CopyTexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i, + CALL_CopyTexSubImage1D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i)); break; case OPCODE_COPY_TEX_SUB_IMAGE2D: - CALL_CopyTexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i, + CALL_CopyTexSubImage2D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i)); break; case OPCODE_COPY_TEX_SUB_IMAGE3D: - CALL_CopyTexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i, + CALL_CopyTexSubImage3D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i)); break; case OPCODE_CULL_FACE: - CALL_CullFace(ctx->Exec, (n[1].e)); + CALL_CullFace(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_DEPTH_FUNC: - CALL_DepthFunc(ctx->Exec, (n[1].e)); + CALL_DepthFunc(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_DEPTH_MASK: - CALL_DepthMask(ctx->Exec, (n[1].b)); + CALL_DepthMask(ctx->Dispatch.Exec, (n[1].b)); break; case OPCODE_DEPTH_RANGE: - CALL_DepthRange(ctx->Exec, + CALL_DepthRange(ctx->Dispatch.Exec, ((GLclampd) n[1].f, (GLclampd) n[2].f)); break; case OPCODE_DISABLE: - CALL_Disable(ctx->Exec, (n[1].e)); + CALL_Disable(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_DISABLE_INDEXED: - CALL_Disablei(ctx->Exec, (n[1].ui, n[2].e)); + CALL_Disablei(ctx->Dispatch.Exec, (n[1].ui, n[2].e)); break; case OPCODE_DRAW_BUFFER: - CALL_DrawBuffer(ctx->Exec, (n[1].e)); + CALL_DrawBuffer(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_DRAW_PIXELS: { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_DrawPixels(ctx->Exec, (n[1].i, n[2].i, n[3].e, n[4].e, + CALL_DrawPixels(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].e, n[4].e, get_pointer(&n[5]))); ctx->Unpack = save; /* restore */ } break; case OPCODE_ENABLE: - CALL_Enable(ctx->Exec, (n[1].e)); + CALL_Enable(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_ENABLE_INDEXED: - CALL_Enablei(ctx->Exec, (n[1].ui, n[2].e)); + CALL_Enablei(ctx->Dispatch.Exec, (n[1].ui, n[2].e)); break; case OPCODE_EVALMESH1: - CALL_EvalMesh1(ctx->Exec, (n[1].e, n[2].i, n[3].i)); + CALL_EvalMesh1(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i)); break; case OPCODE_EVALMESH2: - CALL_EvalMesh2(ctx->Exec, + CALL_EvalMesh2(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i)); break; case OPCODE_FOG: @@ -11453,24 +11083,24 @@ execute_list(struct gl_context *ctx, GLuint list) p[1] = n[3].f; p[2] = n[4].f; p[3] = n[5].f; - CALL_Fogfv(ctx->Exec, (n[1].e, p)); + CALL_Fogfv(ctx->Dispatch.Exec, (n[1].e, p)); } break; case OPCODE_FRONT_FACE: - CALL_FrontFace(ctx->Exec, (n[1].e)); + CALL_FrontFace(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_FRUSTUM: - CALL_Frustum(ctx->Exec, + CALL_Frustum(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f)); break; case OPCODE_HINT: - CALL_Hint(ctx->Exec, (n[1].e, n[2].e)); + CALL_Hint(ctx->Dispatch.Exec, (n[1].e, n[2].e)); break; case OPCODE_INDEX_MASK: - CALL_IndexMask(ctx->Exec, (n[1].ui)); + CALL_IndexMask(ctx->Dispatch.Exec, (n[1].ui)); break; case OPCODE_INIT_NAMES: - CALL_InitNames(ctx->Exec, ()); + CALL_InitNames(ctx->Dispatch.Exec, ()); break; case OPCODE_LIGHT: { @@ -11479,7 +11109,7 @@ execute_list(struct gl_context *ctx, GLuint list) p[1] = n[4].f; p[2] = n[5].f; p[3] = n[6].f; - CALL_Lightfv(ctx->Exec, (n[1].e, n[2].e, p)); + CALL_Lightfv(ctx->Dispatch.Exec, (n[1].e, n[2].e, p)); } break; case OPCODE_LIGHT_MODEL: @@ -11489,30 +11119,30 @@ execute_list(struct gl_context *ctx, GLuint list) p[1] = n[3].f; p[2] = n[4].f; p[3] = n[5].f; - CALL_LightModelfv(ctx->Exec, (n[1].e, p)); + CALL_LightModelfv(ctx->Dispatch.Exec, (n[1].e, p)); } break; case OPCODE_LINE_STIPPLE: - CALL_LineStipple(ctx->Exec, (n[1].i, n[2].us)); + CALL_LineStipple(ctx->Dispatch.Exec, (n[1].i, n[2].us)); break; case OPCODE_LINE_WIDTH: - CALL_LineWidth(ctx->Exec, (n[1].f)); + CALL_LineWidth(ctx->Dispatch.Exec, (n[1].f)); break; case OPCODE_LIST_BASE: - CALL_ListBase(ctx->Exec, (n[1].ui)); + CALL_ListBase(ctx->Dispatch.Exec, (n[1].ui)); break; case OPCODE_LOAD_IDENTITY: - CALL_LoadIdentity(ctx->Exec, ()); + CALL_LoadIdentity(ctx->Dispatch.Exec, ()); break; case OPCODE_LOAD_MATRIX: STATIC_ASSERT(sizeof(Node) == sizeof(GLfloat)); - CALL_LoadMatrixf(ctx->Exec, (&n[1].f)); + CALL_LoadMatrixf(ctx->Dispatch.Exec, (&n[1].f)); break; case OPCODE_LOAD_NAME: - CALL_LoadName(ctx->Exec, (n[1].ui)); + CALL_LoadName(ctx->Dispatch.Exec, (n[1].ui)); break; case OPCODE_LOGIC_OP: - CALL_LogicOp(ctx->Exec, (n[1].e)); + CALL_LogicOp(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_MAP1: { @@ -11521,7 +11151,7 @@ execute_list(struct gl_context *ctx, GLuint list) GLint uorder = n[5].i; GLfloat u1 = n[2].f; GLfloat u2 = n[3].f; - CALL_Map1f(ctx->Exec, (target, u1, u2, ustride, uorder, + CALL_Map1f(ctx->Dispatch.Exec, (target, u1, u2, ustride, uorder, (GLfloat *) get_pointer(&n[6]))); } break; @@ -11536,40 +11166,40 @@ execute_list(struct gl_context *ctx, GLuint list) GLint vstride = n[7].i; GLint uorder = n[8].i; GLint vorder = n[9].i; - CALL_Map2f(ctx->Exec, (target, u1, u2, ustride, uorder, + CALL_Map2f(ctx->Dispatch.Exec, (target, u1, u2, ustride, uorder, v1, v2, vstride, vorder, (GLfloat *) get_pointer(&n[10]))); } break; case OPCODE_MAPGRID1: - CALL_MapGrid1f(ctx->Exec, (n[1].i, n[2].f, n[3].f)); + CALL_MapGrid1f(ctx->Dispatch.Exec, (n[1].i, n[2].f, n[3].f)); break; case OPCODE_MAPGRID2: - CALL_MapGrid2f(ctx->Exec, + CALL_MapGrid2f(ctx->Dispatch.Exec, (n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f)); break; case OPCODE_MATRIX_MODE: - CALL_MatrixMode(ctx->Exec, (n[1].e)); + CALL_MatrixMode(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_MULT_MATRIX: - CALL_MultMatrixf(ctx->Exec, (&n[1].f)); + CALL_MultMatrixf(ctx->Dispatch.Exec, (&n[1].f)); break; case OPCODE_ORTHO: - CALL_Ortho(ctx->Exec, + CALL_Ortho(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f)); break; case OPCODE_PASSTHROUGH: - CALL_PassThrough(ctx->Exec, (n[1].f)); + CALL_PassThrough(ctx->Dispatch.Exec, (n[1].f)); break; case OPCODE_PATCH_PARAMETER_I: - CALL_PatchParameteri(ctx->Exec, (n[1].e, n[2].i)); + CALL_PatchParameteri(ctx->Dispatch.Exec, (n[1].e, n[2].i)); break; case OPCODE_PATCH_PARAMETER_FV_INNER: { GLfloat params[2]; params[0] = n[2].f; params[1] = n[3].f; - CALL_PatchParameterfv(ctx->Exec, (n[1].e, params)); + CALL_PatchParameterfv(ctx->Dispatch.Exec, (n[1].e, params)); } break; case OPCODE_PATCH_PARAMETER_FV_OUTER: @@ -11579,21 +11209,21 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[3].f; params[2] = n[4].f; params[3] = n[5].f; - CALL_PatchParameterfv(ctx->Exec, (n[1].e, params)); + CALL_PatchParameterfv(ctx->Dispatch.Exec, (n[1].e, params)); } break; case OPCODE_PIXEL_MAP: - CALL_PixelMapfv(ctx->Exec, + CALL_PixelMapfv(ctx->Dispatch.Exec, (n[1].e, n[2].i, get_pointer(&n[3]))); break; case OPCODE_PIXEL_TRANSFER: - CALL_PixelTransferf(ctx->Exec, (n[1].e, n[2].f)); + CALL_PixelTransferf(ctx->Dispatch.Exec, (n[1].e, n[2].f)); break; case OPCODE_PIXEL_ZOOM: - CALL_PixelZoom(ctx->Exec, (n[1].f, n[2].f)); + CALL_PixelZoom(ctx->Dispatch.Exec, (n[1].f, n[2].f)); break; case OPCODE_POINT_SIZE: - CALL_PointSize(ctx->Exec, (n[1].f)); + CALL_PointSize(ctx->Dispatch.Exec, (n[1].f)); break; case OPCODE_POINT_PARAMETERS: { @@ -11601,86 +11231,86 @@ execute_list(struct gl_context *ctx, GLuint list) params[0] = n[2].f; params[1] = n[3].f; params[2] = n[4].f; - CALL_PointParameterfv(ctx->Exec, (n[1].e, params)); + CALL_PointParameterfv(ctx->Dispatch.Exec, (n[1].e, params)); } break; case OPCODE_POLYGON_MODE: - CALL_PolygonMode(ctx->Exec, (n[1].e, n[2].e)); + CALL_PolygonMode(ctx->Dispatch.Exec, (n[1].e, n[2].e)); break; case OPCODE_POLYGON_STIPPLE: { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_PolygonStipple(ctx->Exec, (get_pointer(&n[1]))); + CALL_PolygonStipple(ctx->Dispatch.Exec, (get_pointer(&n[1]))); ctx->Unpack = save; /* restore */ } break; case OPCODE_POLYGON_OFFSET: - CALL_PolygonOffset(ctx->Exec, (n[1].f, n[2].f)); + CALL_PolygonOffset(ctx->Dispatch.Exec, (n[1].f, n[2].f)); break; case OPCODE_POLYGON_OFFSET_CLAMP: - CALL_PolygonOffsetClampEXT(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + CALL_PolygonOffsetClampEXT(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f)); break; case OPCODE_POP_ATTRIB: - CALL_PopAttrib(ctx->Exec, ()); + CALL_PopAttrib(ctx->Dispatch.Exec, ()); break; case OPCODE_POP_MATRIX: - CALL_PopMatrix(ctx->Exec, ()); + CALL_PopMatrix(ctx->Dispatch.Exec, ()); break; case OPCODE_POP_NAME: - CALL_PopName(ctx->Exec, ()); + CALL_PopName(ctx->Dispatch.Exec, ()); break; case OPCODE_PRIORITIZE_TEXTURE: - CALL_PrioritizeTextures(ctx->Exec, (1, &n[1].ui, &n[2].f)); + CALL_PrioritizeTextures(ctx->Dispatch.Exec, (1, &n[1].ui, &n[2].f)); break; case OPCODE_PUSH_ATTRIB: - CALL_PushAttrib(ctx->Exec, (n[1].bf)); + CALL_PushAttrib(ctx->Dispatch.Exec, (n[1].bf)); break; case OPCODE_PUSH_MATRIX: - CALL_PushMatrix(ctx->Exec, ()); + CALL_PushMatrix(ctx->Dispatch.Exec, ()); break; case OPCODE_PUSH_NAME: - CALL_PushName(ctx->Exec, (n[1].ui)); + CALL_PushName(ctx->Dispatch.Exec, (n[1].ui)); break; case OPCODE_RASTER_POS: - CALL_RasterPos4f(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); + CALL_RasterPos4f(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; case OPCODE_READ_BUFFER: - CALL_ReadBuffer(ctx->Exec, (n[1].e)); + CALL_ReadBuffer(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_ROTATE: - CALL_Rotatef(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); + CALL_Rotatef(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; case OPCODE_SCALE: - CALL_Scalef(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + CALL_Scalef(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f)); break; case OPCODE_SCISSOR: - CALL_Scissor(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); + CALL_Scissor(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); break; case OPCODE_SHADE_MODEL: - CALL_ShadeModel(ctx->Exec, (n[1].e)); + CALL_ShadeModel(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_PROVOKING_VERTEX: - CALL_ProvokingVertex(ctx->Exec, (n[1].e)); + CALL_ProvokingVertex(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_STENCIL_FUNC: - CALL_StencilFunc(ctx->Exec, (n[1].e, n[2].i, n[3].ui)); + CALL_StencilFunc(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].ui)); break; case OPCODE_STENCIL_MASK: - CALL_StencilMask(ctx->Exec, (n[1].ui)); + CALL_StencilMask(ctx->Dispatch.Exec, (n[1].ui)); break; case OPCODE_STENCIL_OP: - CALL_StencilOp(ctx->Exec, (n[1].e, n[2].e, n[3].e)); + CALL_StencilOp(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e)); break; case OPCODE_STENCIL_FUNC_SEPARATE: - CALL_StencilFuncSeparate(ctx->Exec, + CALL_StencilFuncSeparate(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].ui)); break; case OPCODE_STENCIL_MASK_SEPARATE: - CALL_StencilMaskSeparate(ctx->Exec, (n[1].e, n[2].ui)); + CALL_StencilMaskSeparate(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_STENCIL_OP_SEPARATE: - CALL_StencilOpSeparate(ctx->Exec, + CALL_StencilOpSeparate(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, n[4].e)); break; case OPCODE_TEXENV: @@ -11690,7 +11320,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].f; params[2] = n[5].f; params[3] = n[6].f; - CALL_TexEnvfv(ctx->Exec, (n[1].e, n[2].e, params)); + CALL_TexEnvfv(ctx->Dispatch.Exec, (n[1].e, n[2].e, params)); } break; case OPCODE_TEXGEN: @@ -11700,7 +11330,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].f; params[2] = n[5].f; params[3] = n[6].f; - CALL_TexGenfv(ctx->Exec, (n[1].e, n[2].e, params)); + CALL_TexGenfv(ctx->Dispatch.Exec, (n[1].e, n[2].e, params)); } break; case OPCODE_TEXPARAMETER: @@ -11710,14 +11340,14 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].f; params[2] = n[5].f; params[3] = n[6].f; - CALL_TexParameterfv(ctx->Exec, (n[1].e, n[2].e, params)); + CALL_TexParameterfv(ctx->Dispatch.Exec, (n[1].e, n[2].e, params)); } break; case OPCODE_TEX_IMAGE1D: { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TexImage1D(ctx->Exec, (n[1].e, /* target */ + CALL_TexImage1D(ctx->Dispatch.Exec, (n[1].e, /* target */ n[2].i, /* level */ n[3].i, /* components */ n[4].i, /* width */ @@ -11732,7 +11362,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TexImage2D(ctx->Exec, (n[1].e, /* target */ + CALL_TexImage2D(ctx->Dispatch.Exec, (n[1].e, /* target */ n[2].i, /* level */ n[3].i, /* components */ n[4].i, /* width */ @@ -11748,7 +11378,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TexImage3D(ctx->Exec, (n[1].e, /* target */ + CALL_TexImage3D(ctx->Dispatch.Exec, (n[1].e, /* target */ n[2].i, /* level */ n[3].i, /* components */ n[4].i, /* width */ @@ -11765,7 +11395,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TexSubImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].i, + CALL_TexSubImage1D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].e, n[6].e, get_pointer(&n[7]))); ctx->Unpack = save; /* restore */ @@ -11775,7 +11405,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TexSubImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].i, + CALL_TexSubImage2D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].e, n[6].i, n[7].e, n[8].e, get_pointer(&n[9]))); @@ -11786,7 +11416,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TexSubImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].i, + CALL_TexSubImage3D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].e, n[10].e, get_pointer(&n[11]))); @@ -11794,21 +11424,21 @@ execute_list(struct gl_context *ctx, GLuint list) } break; case OPCODE_TRANSLATE: - CALL_Translatef(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + CALL_Translatef(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f)); break; case OPCODE_VIEWPORT: - CALL_Viewport(ctx->Exec, (n[1].i, n[2].i, + CALL_Viewport(ctx->Dispatch.Exec, (n[1].i, n[2].i, (GLsizei) n[3].i, (GLsizei) n[4].i)); break; case OPCODE_WINDOW_POS: - CALL_WindowPos4fMESA(ctx->Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); + CALL_WindowPos4fMESA(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f, n[4].f)); break; case OPCODE_VIEWPORT_ARRAY_V: - CALL_ViewportArrayv(ctx->Exec, (n[1].ui, n[2].si, + CALL_ViewportArrayv(ctx->Dispatch.Exec, (n[1].ui, n[2].si, get_pointer(&n[3]))); break; case OPCODE_VIEWPORT_INDEXED_F: - CALL_ViewportIndexedf(ctx->Exec, (n[1].ui, n[2].f, n[3].f, n[4].f, + CALL_ViewportIndexedf(ctx->Dispatch.Exec, (n[1].ui, n[2].f, n[3].f, n[4].f, n[5].f)); break; case OPCODE_VIEWPORT_INDEXED_FV: { @@ -11817,15 +11447,15 @@ execute_list(struct gl_context *ctx, GLuint list) v[1] = n[3].f; v[2] = n[4].f; v[3] = n[5].f; - CALL_ViewportIndexedfv(ctx->Exec, (n[1].ui, v)); + CALL_ViewportIndexedfv(ctx->Dispatch.Exec, (n[1].ui, v)); break; } case OPCODE_SCISSOR_ARRAY_V: - CALL_ScissorArrayv(ctx->Exec, (n[1].ui, n[2].si, + CALL_ScissorArrayv(ctx->Dispatch.Exec, (n[1].ui, n[2].si, get_pointer(&n[3]))); break; case OPCODE_SCISSOR_INDEXED: - CALL_ScissorIndexed(ctx->Exec, (n[1].ui, n[2].i, n[3].i, n[4].si, + CALL_ScissorIndexed(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].si, n[5].si)); break; case OPCODE_SCISSOR_INDEXED_V: { @@ -11834,98 +11464,98 @@ execute_list(struct gl_context *ctx, GLuint list) v[1] = n[3].i; v[2] = n[4].si; v[3] = n[5].si; - CALL_ScissorIndexedv(ctx->Exec, (n[1].ui, v)); + CALL_ScissorIndexedv(ctx->Dispatch.Exec, (n[1].ui, v)); break; } case OPCODE_DEPTH_ARRAY_V: - CALL_DepthRangeArrayv(ctx->Exec, (n[1].ui, n[2].si, + CALL_DepthRangeArrayv(ctx->Dispatch.Exec, (n[1].ui, n[2].si, get_pointer(&n[3]))); break; case OPCODE_DEPTH_INDEXED: - CALL_DepthRangeIndexed(ctx->Exec, (n[1].ui, n[2].f, n[3].f)); + CALL_DepthRangeIndexed(ctx->Dispatch.Exec, (n[1].ui, n[2].f, n[3].f)); break; case OPCODE_ACTIVE_TEXTURE: /* GL_ARB_multitexture */ - CALL_ActiveTexture(ctx->Exec, (n[1].e)); + CALL_ActiveTexture(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_COMPRESSED_TEX_IMAGE_1D: /* GL_ARB_texture_compression */ - CALL_CompressedTexImage1D(ctx->Exec, (n[1].e, n[2].i, n[3].e, + CALL_CompressedTexImage1D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].e, n[4].i, n[5].i, n[6].i, get_pointer(&n[7]))); break; case OPCODE_COMPRESSED_TEX_IMAGE_2D: /* GL_ARB_texture_compression */ - CALL_CompressedTexImage2D(ctx->Exec, (n[1].e, n[2].i, n[3].e, + CALL_CompressedTexImage2D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].e, n[4].i, n[5].i, n[6].i, n[7].i, get_pointer(&n[8]))); break; case OPCODE_COMPRESSED_TEX_IMAGE_3D: /* GL_ARB_texture_compression */ - CALL_CompressedTexImage3D(ctx->Exec, (n[1].e, n[2].i, n[3].e, + CALL_CompressedTexImage3D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].e, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, get_pointer(&n[9]))); break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_1D: /* GL_ARB_texture_compress */ - CALL_CompressedTexSubImage1D(ctx->Exec, + CALL_CompressedTexSubImage1D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].e, n[6].i, get_pointer(&n[7]))); break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_2D: /* GL_ARB_texture_compress */ - CALL_CompressedTexSubImage2D(ctx->Exec, + CALL_CompressedTexSubImage2D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].e, n[8].i, get_pointer(&n[9]))); break; case OPCODE_COMPRESSED_TEX_SUB_IMAGE_3D: /* GL_ARB_texture_compress */ - CALL_CompressedTexSubImage3D(ctx->Exec, + CALL_CompressedTexSubImage3D(ctx->Dispatch.Exec, (n[1].e, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].e, n[10].i, get_pointer(&n[11]))); break; case OPCODE_SAMPLE_COVERAGE: /* GL_ARB_multisample */ - CALL_SampleCoverage(ctx->Exec, (n[1].f, n[2].b)); + CALL_SampleCoverage(ctx->Dispatch.Exec, (n[1].f, n[2].b)); break; case OPCODE_WINDOW_POS_ARB: /* GL_ARB_window_pos */ - CALL_WindowPos3f(ctx->Exec, (n[1].f, n[2].f, n[3].f)); + CALL_WindowPos3f(ctx->Dispatch.Exec, (n[1].f, n[2].f, n[3].f)); break; case OPCODE_BIND_PROGRAM_ARB: /* GL_ARB_vertex_program */ - CALL_BindProgramARB(ctx->Exec, (n[1].e, n[2].ui)); + CALL_BindProgramARB(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_PROGRAM_LOCAL_PARAMETER_ARB: - CALL_ProgramLocalParameter4fARB(ctx->Exec, + CALL_ProgramLocalParameter4fARB(ctx->Dispatch.Exec, (n[1].e, n[2].ui, n[3].f, n[4].f, n[5].f, n[6].f)); break; case OPCODE_ACTIVE_STENCIL_FACE_EXT: - CALL_ActiveStencilFaceEXT(ctx->Exec, (n[1].e)); + CALL_ActiveStencilFaceEXT(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_DEPTH_BOUNDS_EXT: - CALL_DepthBoundsEXT(ctx->Exec, (n[1].f, n[2].f)); + CALL_DepthBoundsEXT(ctx->Dispatch.Exec, (n[1].f, n[2].f)); break; case OPCODE_PROGRAM_STRING_ARB: - CALL_ProgramStringARB(ctx->Exec, + CALL_ProgramStringARB(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_ENV_PARAMETER_ARB: - CALL_ProgramEnvParameter4fARB(ctx->Exec, (n[1].e, n[2].ui, n[3].f, + CALL_ProgramEnvParameter4fARB(ctx->Dispatch.Exec, (n[1].e, n[2].ui, n[3].f, n[4].f, n[5].f, n[6].f)); break; case OPCODE_BEGIN_QUERY_ARB: - CALL_BeginQuery(ctx->Exec, (n[1].e, n[2].ui)); + CALL_BeginQuery(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_END_QUERY_ARB: - CALL_EndQuery(ctx->Exec, (n[1].e)); + CALL_EndQuery(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_QUERY_COUNTER: - CALL_QueryCounter(ctx->Exec, (n[1].ui, n[2].e)); + CALL_QueryCounter(ctx->Dispatch.Exec, (n[1].ui, n[2].e)); break; case OPCODE_BEGIN_QUERY_INDEXED: - CALL_BeginQueryIndexed(ctx->Exec, (n[1].e, n[2].ui, n[3].ui)); + CALL_BeginQueryIndexed(ctx->Dispatch.Exec, (n[1].e, n[2].ui, n[3].ui)); break; case OPCODE_END_QUERY_INDEXED: - CALL_EndQueryIndexed(ctx->Exec, (n[1].e, n[2].ui)); + CALL_EndQueryIndexed(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_DRAW_BUFFERS_ARB: { @@ -11933,45 +11563,45 @@ execute_list(struct gl_context *ctx, GLuint list) GLint i, count = MIN2(n[1].i, MAX_DRAW_BUFFERS); for (i = 0; i < count; i++) buffers[i] = n[2 + i].e; - CALL_DrawBuffers(ctx->Exec, (n[1].i, buffers)); + CALL_DrawBuffers(ctx->Dispatch.Exec, (n[1].i, buffers)); } break; case OPCODE_BLIT_FRAMEBUFFER: - CALL_BlitFramebuffer(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i, + CALL_BlitFramebuffer(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i, 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, ()); + CALL_PrimitiveRestartNV(ctx->Dispatch.Exec, ()); break; case OPCODE_USE_PROGRAM: - CALL_UseProgram(ctx->Exec, (n[1].ui)); + CALL_UseProgram(ctx->Dispatch.Exec, (n[1].ui)); break; case OPCODE_UNIFORM_1F: - CALL_Uniform1f(ctx->Exec, (n[1].i, n[2].f)); + CALL_Uniform1f(ctx->Dispatch.Exec, (n[1].i, n[2].f)); break; case OPCODE_UNIFORM_2F: - CALL_Uniform2f(ctx->Exec, (n[1].i, n[2].f, n[3].f)); + CALL_Uniform2f(ctx->Dispatch.Exec, (n[1].i, n[2].f, n[3].f)); break; case OPCODE_UNIFORM_3F: - CALL_Uniform3f(ctx->Exec, (n[1].i, n[2].f, n[3].f, n[4].f)); + CALL_Uniform3f(ctx->Dispatch.Exec, (n[1].i, n[2].f, n[3].f, n[4].f)); break; case OPCODE_UNIFORM_4F: - CALL_Uniform4f(ctx->Exec, + CALL_Uniform4f(ctx->Dispatch.Exec, (n[1].i, n[2].f, n[3].f, n[4].f, n[5].f)); break; case OPCODE_UNIFORM_1FV: - CALL_Uniform1fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform1fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2FV: - CALL_Uniform2fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform2fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3FV: - CALL_Uniform3fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform3fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4FV: - CALL_Uniform4fv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform4fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_1D: { union float64_pair x; @@ -11979,7 +11609,7 @@ execute_list(struct gl_context *ctx, GLuint list) x.uint32[0] = n[2].ui; x.uint32[1] = n[3].ui; - CALL_Uniform1d(ctx->Exec, (n[1].i, x.d)); + CALL_Uniform1d(ctx->Dispatch.Exec, (n[1].i, x.d)); break; } case OPCODE_UNIFORM_2D: { @@ -11991,7 +11621,7 @@ execute_list(struct gl_context *ctx, GLuint list) y.uint32[0] = n[4].ui; y.uint32[1] = n[5].ui; - CALL_Uniform2d(ctx->Exec, (n[1].i, x.d, y.d)); + CALL_Uniform2d(ctx->Dispatch.Exec, (n[1].i, x.d, y.d)); break; } case OPCODE_UNIFORM_3D: { @@ -12006,7 +11636,7 @@ execute_list(struct gl_context *ctx, GLuint list) z.uint32[0] = n[6].ui; z.uint32[1] = n[7].ui; - CALL_Uniform3d(ctx->Exec, (n[1].i, x.d, y.d, z.d)); + CALL_Uniform3d(ctx->Dispatch.Exec, (n[1].i, x.d, y.d, z.d)); break; } case OPCODE_UNIFORM_4D: { @@ -12024,141 +11654,141 @@ execute_list(struct gl_context *ctx, GLuint list) w.uint32[0] = n[8].ui; w.uint32[1] = n[9].ui; - CALL_Uniform4d(ctx->Exec, (n[1].i, x.d, y.d, z.d, w.d)); + CALL_Uniform4d(ctx->Dispatch.Exec, (n[1].i, x.d, y.d, z.d, w.d)); break; } case OPCODE_UNIFORM_1DV: - CALL_Uniform1dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform1dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2DV: - CALL_Uniform2dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform2dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3DV: - CALL_Uniform3dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform3dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4DV: - CALL_Uniform4dv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform4dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_1I: - CALL_Uniform1i(ctx->Exec, (n[1].i, n[2].i)); + CALL_Uniform1i(ctx->Dispatch.Exec, (n[1].i, n[2].i)); break; case OPCODE_UNIFORM_2I: - CALL_Uniform2i(ctx->Exec, (n[1].i, n[2].i, n[3].i)); + CALL_Uniform2i(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i)); break; case OPCODE_UNIFORM_3I: - CALL_Uniform3i(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); + CALL_Uniform3i(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); break; case OPCODE_UNIFORM_4I: - CALL_Uniform4i(ctx->Exec, + CALL_Uniform4i(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i)); break; case OPCODE_UNIFORM_1IV: - CALL_Uniform1iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform1iv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2IV: - CALL_Uniform2iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform2iv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3IV: - CALL_Uniform3iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform3iv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4IV: - CALL_Uniform4iv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform4iv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_1UI: - CALL_Uniform1ui(ctx->Exec, (n[1].i, n[2].i)); + CALL_Uniform1ui(ctx->Dispatch.Exec, (n[1].i, n[2].i)); break; case OPCODE_UNIFORM_2UI: - CALL_Uniform2ui(ctx->Exec, (n[1].i, n[2].i, n[3].i)); + CALL_Uniform2ui(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i)); break; case OPCODE_UNIFORM_3UI: - CALL_Uniform3ui(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); + CALL_Uniform3ui(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); break; case OPCODE_UNIFORM_4UI: - CALL_Uniform4ui(ctx->Exec, + CALL_Uniform4ui(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i, n[5].i)); break; case OPCODE_UNIFORM_1UIV: - CALL_Uniform1uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform1uiv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2UIV: - CALL_Uniform2uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform2uiv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3UIV: - CALL_Uniform3uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform3uiv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4UIV: - CALL_Uniform4uiv(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform4uiv(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_MATRIX22: - CALL_UniformMatrix2fv(ctx->Exec, + CALL_UniformMatrix2fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX33: - CALL_UniformMatrix3fv(ctx->Exec, + CALL_UniformMatrix3fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX44: - CALL_UniformMatrix4fv(ctx->Exec, + CALL_UniformMatrix4fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX23: - CALL_UniformMatrix2x3fv(ctx->Exec, + CALL_UniformMatrix2x3fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX32: - CALL_UniformMatrix3x2fv(ctx->Exec, + CALL_UniformMatrix3x2fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX24: - CALL_UniformMatrix2x4fv(ctx->Exec, + CALL_UniformMatrix2x4fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX42: - CALL_UniformMatrix4x2fv(ctx->Exec, + CALL_UniformMatrix4x2fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX34: - CALL_UniformMatrix3x4fv(ctx->Exec, + CALL_UniformMatrix3x4fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX43: - CALL_UniformMatrix4x3fv(ctx->Exec, + CALL_UniformMatrix4x3fv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX22D: - CALL_UniformMatrix2dv(ctx->Exec, + CALL_UniformMatrix2dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX33D: - CALL_UniformMatrix3dv(ctx->Exec, + CALL_UniformMatrix3dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX44D: - CALL_UniformMatrix4dv(ctx->Exec, + CALL_UniformMatrix4dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX23D: - CALL_UniformMatrix2x3dv(ctx->Exec, + CALL_UniformMatrix2x3dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX32D: - CALL_UniformMatrix3x2dv(ctx->Exec, + CALL_UniformMatrix3x2dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX24D: - CALL_UniformMatrix2x4dv(ctx->Exec, + CALL_UniformMatrix2x4dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX42D: - CALL_UniformMatrix4x2dv(ctx->Exec, + CALL_UniformMatrix4x2dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX34D: - CALL_UniformMatrix3x4dv(ctx->Exec, + CALL_UniformMatrix3x4dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; case OPCODE_UNIFORM_MATRIX43D: - CALL_UniformMatrix4x3dv(ctx->Exec, + CALL_UniformMatrix4x3dv(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].b, get_pointer(&n[4]))); break; @@ -12168,7 +11798,7 @@ execute_list(struct gl_context *ctx, GLuint list) x.int32[0] = n[2].i; x.int32[1] = n[3].i; - CALL_Uniform1i64ARB(ctx->Exec, (n[1].i, x.int64)); + CALL_Uniform1i64ARB(ctx->Dispatch.Exec, (n[1].i, x.int64)); break; } case OPCODE_UNIFORM_2I64: { @@ -12180,7 +11810,7 @@ execute_list(struct gl_context *ctx, GLuint list) y.int32[0] = n[4].i; y.int32[1] = n[5].i; - CALL_Uniform2i64ARB(ctx->Exec, (n[1].i, x.int64, y.int64)); + CALL_Uniform2i64ARB(ctx->Dispatch.Exec, (n[1].i, x.int64, y.int64)); break; } case OPCODE_UNIFORM_3I64: { @@ -12196,7 +11826,7 @@ execute_list(struct gl_context *ctx, GLuint list) z.int32[1] = n[7].i; - CALL_Uniform3i64ARB(ctx->Exec, (n[1].i, x.int64, y.int64, z.int64)); + CALL_Uniform3i64ARB(ctx->Dispatch.Exec, (n[1].i, x.int64, y.int64, z.int64)); break; } case OPCODE_UNIFORM_4I64: { @@ -12214,20 +11844,20 @@ execute_list(struct gl_context *ctx, GLuint list) w.int32[0] = n[8].i; w.int32[1] = n[9].i; - CALL_Uniform4i64ARB(ctx->Exec, (n[1].i, x.int64, y.int64, z.int64, w.int64)); + CALL_Uniform4i64ARB(ctx->Dispatch.Exec, (n[1].i, x.int64, y.int64, z.int64, w.int64)); break; } case OPCODE_UNIFORM_1I64V: - CALL_Uniform1i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform1i64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2I64V: - CALL_Uniform2i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform2i64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3I64V: - CALL_Uniform3i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform3i64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4I64V: - CALL_Uniform4i64vARB(ctx->Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); + CALL_Uniform4i64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_1UI64: { union uint64_pair x; @@ -12235,7 +11865,7 @@ execute_list(struct gl_context *ctx, GLuint list) x.uint32[0] = n[2].ui; x.uint32[1] = n[3].ui; - CALL_Uniform1ui64ARB(ctx->Exec, (n[1].i, x.uint64)); + CALL_Uniform1ui64ARB(ctx->Dispatch.Exec, (n[1].i, x.uint64)); break; } case OPCODE_UNIFORM_2UI64: { @@ -12247,7 +11877,7 @@ execute_list(struct gl_context *ctx, GLuint list) y.uint32[0] = n[4].ui; y.uint32[1] = n[5].ui; - CALL_Uniform2ui64ARB(ctx->Exec, (n[1].i, x.uint64, y.uint64)); + CALL_Uniform2ui64ARB(ctx->Dispatch.Exec, (n[1].i, x.uint64, y.uint64)); break; } case OPCODE_UNIFORM_3UI64: { @@ -12263,7 +11893,7 @@ execute_list(struct gl_context *ctx, GLuint list) z.uint32[1] = n[7].ui; - CALL_Uniform3ui64ARB(ctx->Exec, (n[1].i, x.uint64, y.uint64, + CALL_Uniform3ui64ARB(ctx->Dispatch.Exec, (n[1].i, x.uint64, y.uint64, z.uint64)); break; } @@ -12282,24 +11912,24 @@ execute_list(struct gl_context *ctx, GLuint list) w.uint32[0] = n[8].ui; w.uint32[1] = n[9].ui; - CALL_Uniform4ui64ARB(ctx->Exec, (n[1].i, x.uint64, y.uint64, + CALL_Uniform4ui64ARB(ctx->Dispatch.Exec, (n[1].i, x.uint64, y.uint64, z.uint64, w.uint64)); break; } case OPCODE_UNIFORM_1UI64V: - CALL_Uniform1ui64vARB(ctx->Exec, (n[1].i, n[2].i, + CALL_Uniform1ui64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_2UI64V: - CALL_Uniform2ui64vARB(ctx->Exec, (n[1].i, n[2].i, + CALL_Uniform2ui64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_3UI64V: - CALL_Uniform3ui64vARB(ctx->Exec, (n[1].i, n[2].i, + CALL_Uniform3ui64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; case OPCODE_UNIFORM_4UI64V: - CALL_Uniform4ui64vARB(ctx->Exec, (n[1].i, n[2].i, + CALL_Uniform4ui64vARB(ctx->Dispatch.Exec, (n[1].i, n[2].i, get_pointer(&n[3]))); break; @@ -12309,7 +11939,7 @@ execute_list(struct gl_context *ctx, GLuint list) x.int32[0] = n[3].i; x.int32[1] = n[4].i; - CALL_ProgramUniform1i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64)); + CALL_ProgramUniform1i64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.int64)); break; } case OPCODE_PROGRAM_UNIFORM_2I64: { @@ -12321,7 +11951,7 @@ execute_list(struct gl_context *ctx, GLuint list) y.int32[0] = n[5].i; y.int32[1] = n[6].i; - CALL_ProgramUniform2i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64, + CALL_ProgramUniform2i64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.int64, y.int64)); break; } @@ -12337,7 +11967,7 @@ execute_list(struct gl_context *ctx, GLuint list) z.int32[0] = n[7].i; z.int32[1] = n[8].i; - CALL_ProgramUniform3i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64, + CALL_ProgramUniform3i64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.int64, y.int64, z.int64)); break; } @@ -12356,24 +11986,24 @@ execute_list(struct gl_context *ctx, GLuint list) w.int32[0] = n[9].i; w.int32[1] = n[10].i; - CALL_ProgramUniform4i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.int64, + CALL_ProgramUniform4i64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.int64, y.int64, z.int64, w.int64)); break; } case OPCODE_PROGRAM_UNIFORM_1I64V: - CALL_ProgramUniform1i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform1i64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_2I64V: - CALL_ProgramUniform2i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform2i64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_3I64V: - CALL_ProgramUniform3i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform3i64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_4I64V: - CALL_ProgramUniform4i64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform4i64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_1UI64: { @@ -12382,7 +12012,7 @@ execute_list(struct gl_context *ctx, GLuint list) x.uint32[0] = n[3].ui; x.uint32[1] = n[4].ui; - CALL_ProgramUniform1i64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64)); + CALL_ProgramUniform1i64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.uint64)); break; } case OPCODE_PROGRAM_UNIFORM_2UI64: { @@ -12394,7 +12024,7 @@ execute_list(struct gl_context *ctx, GLuint list) y.uint32[0] = n[5].ui; y.uint32[1] = n[6].ui; - CALL_ProgramUniform2ui64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64, + CALL_ProgramUniform2ui64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.uint64, y.uint64)); break; } @@ -12410,7 +12040,7 @@ execute_list(struct gl_context *ctx, GLuint list) z.uint32[0] = n[7].ui; z.uint32[1] = n[8].ui; - CALL_ProgramUniform3ui64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64, + CALL_ProgramUniform3ui64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.uint64, y.uint64, z.uint64)); break; } @@ -12429,58 +12059,58 @@ execute_list(struct gl_context *ctx, GLuint list) w.uint32[0] = n[9].ui; w.uint32[1] = n[10].ui; - CALL_ProgramUniform4ui64ARB(ctx->Exec, (n[1].ui, n[2].i, x.uint64, + CALL_ProgramUniform4ui64ARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.uint64, y.uint64, z.uint64, w.uint64)); break; } case OPCODE_PROGRAM_UNIFORM_1UI64V: - CALL_ProgramUniform1ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform1ui64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_2UI64V: - CALL_ProgramUniform2ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform2ui64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_3UI64V: - CALL_ProgramUniform3ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform3ui64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_4UI64V: - CALL_ProgramUniform4ui64vARB(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform4ui64vARB(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_USE_PROGRAM_STAGES: - CALL_UseProgramStages(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui)); + CALL_UseProgramStages(ctx->Dispatch.Exec, (n[1].ui, n[2].ui, n[3].ui)); break; case OPCODE_PROGRAM_UNIFORM_1F: - CALL_ProgramUniform1f(ctx->Exec, (n[1].ui, n[2].i, n[3].f)); + CALL_ProgramUniform1f(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].f)); break; case OPCODE_PROGRAM_UNIFORM_2F: - CALL_ProgramUniform2f(ctx->Exec, (n[1].ui, n[2].i, n[3].f, n[4].f)); + CALL_ProgramUniform2f(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].f, n[4].f)); break; case OPCODE_PROGRAM_UNIFORM_3F: - CALL_ProgramUniform3f(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform3f(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].f, n[4].f, n[5].f)); break; case OPCODE_PROGRAM_UNIFORM_4F: - CALL_ProgramUniform4f(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform4f(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].f, n[4].f, n[5].f, n[6].f)); break; case OPCODE_PROGRAM_UNIFORM_1FV: - CALL_ProgramUniform1fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform1fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_2FV: - CALL_ProgramUniform2fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform2fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_3FV: - CALL_ProgramUniform3fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform3fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_4FV: - CALL_ProgramUniform4fv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform4fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_1D: { @@ -12489,7 +12119,7 @@ execute_list(struct gl_context *ctx, GLuint list) x.uint32[0] = n[3].ui; x.uint32[1] = n[4].ui; - CALL_ProgramUniform1d(ctx->Exec, (n[1].ui, n[2].i, x.d)); + CALL_ProgramUniform1d(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.d)); break; } case OPCODE_PROGRAM_UNIFORM_2D: { @@ -12501,7 +12131,7 @@ execute_list(struct gl_context *ctx, GLuint list) y.uint32[0] = n[5].ui; y.uint32[1] = n[6].ui; - CALL_ProgramUniform2d(ctx->Exec, (n[1].ui, n[2].i, x.d, y.d)); + CALL_ProgramUniform2d(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.d, y.d)); break; } case OPCODE_PROGRAM_UNIFORM_3D: { @@ -12516,7 +12146,7 @@ execute_list(struct gl_context *ctx, GLuint list) z.uint32[0] = n[7].ui; z.uint32[1] = n[8].ui; - CALL_ProgramUniform3d(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform3d(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.d, y.d, z.d)); break; } @@ -12535,282 +12165,282 @@ execute_list(struct gl_context *ctx, GLuint list) w.uint32[0] = n[9].ui; w.uint32[1] = n[10].ui; - CALL_ProgramUniform4d(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform4d(ctx->Dispatch.Exec, (n[1].ui, n[2].i, x.d, y.d, z.d, w.d)); break; } case OPCODE_PROGRAM_UNIFORM_1DV: - CALL_ProgramUniform1dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform1dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_2DV: - CALL_ProgramUniform2dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform2dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_3DV: - CALL_ProgramUniform3dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform3dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_4DV: - CALL_ProgramUniform4dv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform4dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_1I: - CALL_ProgramUniform1i(ctx->Exec, (n[1].ui, n[2].i, n[3].i)); + CALL_ProgramUniform1i(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i)); break; case OPCODE_PROGRAM_UNIFORM_2I: - CALL_ProgramUniform2i(ctx->Exec, (n[1].ui, n[2].i, n[3].i, n[4].i)); + CALL_ProgramUniform2i(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].i)); break; case OPCODE_PROGRAM_UNIFORM_3I: - CALL_ProgramUniform3i(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform3i(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].i, n[5].i)); break; case OPCODE_PROGRAM_UNIFORM_4I: - CALL_ProgramUniform4i(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform4i(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].i, n[5].i, n[6].i)); break; case OPCODE_PROGRAM_UNIFORM_1IV: - CALL_ProgramUniform1iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform1iv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_2IV: - CALL_ProgramUniform2iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform2iv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_3IV: - CALL_ProgramUniform3iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform3iv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_4IV: - CALL_ProgramUniform4iv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform4iv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_1UI: - CALL_ProgramUniform1ui(ctx->Exec, (n[1].ui, n[2].i, n[3].ui)); + CALL_ProgramUniform1ui(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].ui)); break; case OPCODE_PROGRAM_UNIFORM_2UI: - CALL_ProgramUniform2ui(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform2ui(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].ui, n[4].ui)); break; case OPCODE_PROGRAM_UNIFORM_3UI: - CALL_ProgramUniform3ui(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform3ui(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].ui, n[4].ui, n[5].ui)); break; case OPCODE_PROGRAM_UNIFORM_4UI: - CALL_ProgramUniform4ui(ctx->Exec, (n[1].ui, n[2].i, + CALL_ProgramUniform4ui(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].ui, n[4].ui, n[5].ui, n[6].ui)); break; case OPCODE_PROGRAM_UNIFORM_1UIV: - CALL_ProgramUniform1uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform1uiv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_2UIV: - CALL_ProgramUniform2uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform2uiv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_3UIV: - CALL_ProgramUniform3uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform3uiv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_4UIV: - CALL_ProgramUniform4uiv(ctx->Exec, (n[1].ui, n[2].i, n[3].i, + CALL_ProgramUniform4uiv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, get_pointer(&n[4]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX22F: - CALL_ProgramUniformMatrix2fv(ctx->Exec, + CALL_ProgramUniformMatrix2fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX23F: - CALL_ProgramUniformMatrix2x3fv(ctx->Exec, + CALL_ProgramUniformMatrix2x3fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX24F: - CALL_ProgramUniformMatrix2x4fv(ctx->Exec, + CALL_ProgramUniformMatrix2x4fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX32F: - CALL_ProgramUniformMatrix3x2fv(ctx->Exec, + CALL_ProgramUniformMatrix3x2fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX33F: - CALL_ProgramUniformMatrix3fv(ctx->Exec, + CALL_ProgramUniformMatrix3fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX34F: - CALL_ProgramUniformMatrix3x4fv(ctx->Exec, + CALL_ProgramUniformMatrix3x4fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX42F: - CALL_ProgramUniformMatrix4x2fv(ctx->Exec, + CALL_ProgramUniformMatrix4x2fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX43F: - CALL_ProgramUniformMatrix4x3fv(ctx->Exec, + CALL_ProgramUniformMatrix4x3fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX44F: - CALL_ProgramUniformMatrix4fv(ctx->Exec, + CALL_ProgramUniformMatrix4fv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX22D: - CALL_ProgramUniformMatrix2dv(ctx->Exec, + CALL_ProgramUniformMatrix2dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX23D: - CALL_ProgramUniformMatrix2x3dv(ctx->Exec, + CALL_ProgramUniformMatrix2x3dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX24D: - CALL_ProgramUniformMatrix2x4dv(ctx->Exec, + CALL_ProgramUniformMatrix2x4dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX32D: - CALL_ProgramUniformMatrix3x2dv(ctx->Exec, + CALL_ProgramUniformMatrix3x2dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX33D: - CALL_ProgramUniformMatrix3dv(ctx->Exec, + CALL_ProgramUniformMatrix3dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX34D: - CALL_ProgramUniformMatrix3x4dv(ctx->Exec, + CALL_ProgramUniformMatrix3x4dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX42D: - CALL_ProgramUniformMatrix4x2dv(ctx->Exec, + CALL_ProgramUniformMatrix4x2dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX43D: - CALL_ProgramUniformMatrix4x3dv(ctx->Exec, + CALL_ProgramUniformMatrix4x3dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_PROGRAM_UNIFORM_MATRIX44D: - CALL_ProgramUniformMatrix4dv(ctx->Exec, + CALL_ProgramUniformMatrix4dv(ctx->Dispatch.Exec, (n[1].ui, n[2].i, n[3].i, n[4].b, get_pointer(&n[5]))); break; case OPCODE_CLIP_CONTROL: - CALL_ClipControl(ctx->Exec, (n[1].e, n[2].e)); + CALL_ClipControl(ctx->Dispatch.Exec, (n[1].e, n[2].e)); break; case OPCODE_CLAMP_COLOR: - CALL_ClampColor(ctx->Exec, (n[1].e, n[2].e)); + CALL_ClampColor(ctx->Dispatch.Exec, (n[1].e, n[2].e)); break; case OPCODE_BIND_FRAGMENT_SHADER_ATI: - CALL_BindFragmentShaderATI(ctx->Exec, (n[1].i)); + CALL_BindFragmentShaderATI(ctx->Dispatch.Exec, (n[1].i)); break; case OPCODE_SET_FRAGMENT_SHADER_CONSTANTS_ATI: - CALL_SetFragmentShaderConstantATI(ctx->Exec, (n[1].ui, &n[2].f)); + CALL_SetFragmentShaderConstantATI(ctx->Dispatch.Exec, (n[1].ui, &n[2].f)); break; case OPCODE_ATTR_1F_NV: - CALL_VertexAttrib1fNV(ctx->Exec, (n[1].e, n[2].f)); + CALL_VertexAttrib1fNV(ctx->Dispatch.Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_NV: - CALL_VertexAttrib2fvNV(ctx->Exec, (n[1].e, &n[2].f)); + CALL_VertexAttrib2fvNV(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_NV: - CALL_VertexAttrib3fvNV(ctx->Exec, (n[1].e, &n[2].f)); + CALL_VertexAttrib3fvNV(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_NV: - CALL_VertexAttrib4fvNV(ctx->Exec, (n[1].e, &n[2].f)); + CALL_VertexAttrib4fvNV(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_1F_ARB: - CALL_VertexAttrib1fARB(ctx->Exec, (n[1].e, n[2].f)); + CALL_VertexAttrib1fARB(ctx->Dispatch.Exec, (n[1].e, n[2].f)); break; case OPCODE_ATTR_2F_ARB: - CALL_VertexAttrib2fvARB(ctx->Exec, (n[1].e, &n[2].f)); + CALL_VertexAttrib2fvARB(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_3F_ARB: - CALL_VertexAttrib3fvARB(ctx->Exec, (n[1].e, &n[2].f)); + CALL_VertexAttrib3fvARB(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_4F_ARB: - CALL_VertexAttrib4fvARB(ctx->Exec, (n[1].e, &n[2].f)); + CALL_VertexAttrib4fvARB(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_ATTR_1I: - CALL_VertexAttribI1iEXT(ctx->Exec, (n[1].e, n[2].i)); + CALL_VertexAttribI1iEXT(ctx->Dispatch.Exec, (n[1].e, n[2].i)); break; case OPCODE_ATTR_2I: - CALL_VertexAttribI2ivEXT(ctx->Exec, (n[1].e, &n[2].i)); + CALL_VertexAttribI2ivEXT(ctx->Dispatch.Exec, (n[1].e, &n[2].i)); break; case OPCODE_ATTR_3I: - CALL_VertexAttribI3ivEXT(ctx->Exec, (n[1].e, &n[2].i)); + CALL_VertexAttribI3ivEXT(ctx->Dispatch.Exec, (n[1].e, &n[2].i)); break; case OPCODE_ATTR_4I: - CALL_VertexAttribI4ivEXT(ctx->Exec, (n[1].e, &n[2].i)); + CALL_VertexAttribI4ivEXT(ctx->Dispatch.Exec, (n[1].e, &n[2].i)); break; case OPCODE_ATTR_1D: { GLdouble *d = (GLdouble *) &n[2]; - CALL_VertexAttribL1d(ctx->Exec, (n[1].ui, *d)); + CALL_VertexAttribL1d(ctx->Dispatch.Exec, (n[1].ui, *d)); break; } case OPCODE_ATTR_2D: { GLdouble *d = (GLdouble *) &n[2]; - CALL_VertexAttribL2dv(ctx->Exec, (n[1].ui, d)); + CALL_VertexAttribL2dv(ctx->Dispatch.Exec, (n[1].ui, d)); break; } case OPCODE_ATTR_3D: { GLdouble *d = (GLdouble *) &n[2]; - CALL_VertexAttribL3dv(ctx->Exec, (n[1].ui, d)); + CALL_VertexAttribL3dv(ctx->Dispatch.Exec, (n[1].ui, d)); break; } case OPCODE_ATTR_4D: { GLdouble *d = (GLdouble *) &n[2]; - CALL_VertexAttribL4dv(ctx->Exec, (n[1].ui, d)); + CALL_VertexAttribL4dv(ctx->Dispatch.Exec, (n[1].ui, d)); break; } case OPCODE_ATTR_1UI64: { uint64_t *ui64 = (uint64_t *) &n[2]; - CALL_VertexAttribL1ui64ARB(ctx->Exec, (n[1].ui, *ui64)); + CALL_VertexAttribL1ui64ARB(ctx->Dispatch.Exec, (n[1].ui, *ui64)); break; } case OPCODE_MATERIAL: - CALL_Materialfv(ctx->Exec, (n[1].e, n[2].e, &n[3].f)); + CALL_Materialfv(ctx->Dispatch.Exec, (n[1].e, n[2].e, &n[3].f)); break; case OPCODE_BEGIN: - CALL_Begin(ctx->Exec, (n[1].e)); + CALL_Begin(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_END: - CALL_End(ctx->Exec, ()); + CALL_End(ctx->Dispatch.Exec, ()); break; case OPCODE_EVAL_C1: - CALL_EvalCoord1f(ctx->Exec, (n[1].f)); + CALL_EvalCoord1f(ctx->Dispatch.Exec, (n[1].f)); break; case OPCODE_EVAL_C2: - CALL_EvalCoord2f(ctx->Exec, (n[1].f, n[2].f)); + CALL_EvalCoord2f(ctx->Dispatch.Exec, (n[1].f, n[2].f)); break; case OPCODE_EVAL_P1: - CALL_EvalPoint1(ctx->Exec, (n[1].i)); + CALL_EvalPoint1(ctx->Dispatch.Exec, (n[1].i)); break; case OPCODE_EVAL_P2: - CALL_EvalPoint2(ctx->Exec, (n[1].i, n[2].i)); + CALL_EvalPoint2(ctx->Dispatch.Exec, (n[1].i, n[2].i)); break; /* GL_EXT_texture_integer */ case OPCODE_CLEARCOLOR_I: - CALL_ClearColorIiEXT(ctx->Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); + CALL_ClearColorIiEXT(ctx->Dispatch.Exec, (n[1].i, n[2].i, n[3].i, n[4].i)); break; case OPCODE_CLEARCOLOR_UI: - CALL_ClearColorIuiEXT(ctx->Exec, + CALL_ClearColorIuiEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].ui, n[3].ui, n[4].ui)); break; case OPCODE_TEXPARAMETER_I: @@ -12820,7 +12450,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].i; params[2] = n[5].i; params[3] = n[6].i; - CALL_TexParameterIiv(ctx->Exec, (n[1].e, n[2].e, params)); + CALL_TexParameterIiv(ctx->Dispatch.Exec, (n[1].e, n[2].e, params)); } break; case OPCODE_TEXPARAMETER_UI: @@ -12830,54 +12460,54 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].ui; params[2] = n[5].ui; params[3] = n[6].ui; - CALL_TexParameterIuiv(ctx->Exec, (n[1].e, n[2].e, params)); + CALL_TexParameterIuiv(ctx->Dispatch.Exec, (n[1].e, n[2].e, params)); } break; case OPCODE_VERTEX_ATTRIB_DIVISOR: - /* GL_ARB_instanced_arrays */ - CALL_VertexAttribDivisor(ctx->Exec, (n[1].ui, n[2].ui)); + /* GL_EXT/ARB_instanced_arrays */ + CALL_VertexAttribDivisor(ctx->Dispatch.Exec, (n[1].ui, n[2].ui)); break; case OPCODE_TEXTURE_BARRIER_NV: - CALL_TextureBarrierNV(ctx->Exec, ()); + CALL_TextureBarrierNV(ctx->Dispatch.Exec, ()); break; /* GL_EXT/ARB_transform_feedback */ case OPCODE_BEGIN_TRANSFORM_FEEDBACK: - CALL_BeginTransformFeedback(ctx->Exec, (n[1].e)); + CALL_BeginTransformFeedback(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_END_TRANSFORM_FEEDBACK: - CALL_EndTransformFeedback(ctx->Exec, ()); + CALL_EndTransformFeedback(ctx->Dispatch.Exec, ()); break; case OPCODE_BIND_TRANSFORM_FEEDBACK: - CALL_BindTransformFeedback(ctx->Exec, (n[1].e, n[2].ui)); + CALL_BindTransformFeedback(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_PAUSE_TRANSFORM_FEEDBACK: - CALL_PauseTransformFeedback(ctx->Exec, ()); + CALL_PauseTransformFeedback(ctx->Dispatch.Exec, ()); break; case OPCODE_RESUME_TRANSFORM_FEEDBACK: - CALL_ResumeTransformFeedback(ctx->Exec, ()); + CALL_ResumeTransformFeedback(ctx->Dispatch.Exec, ()); break; case OPCODE_DRAW_TRANSFORM_FEEDBACK: - CALL_DrawTransformFeedback(ctx->Exec, (n[1].e, n[2].ui)); + CALL_DrawTransformFeedback(ctx->Dispatch.Exec, (n[1].e, n[2].ui)); break; case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM: - CALL_DrawTransformFeedbackStream(ctx->Exec, + CALL_DrawTransformFeedbackStream(ctx->Dispatch.Exec, (n[1].e, n[2].ui, n[3].ui)); break; case OPCODE_DRAW_TRANSFORM_FEEDBACK_INSTANCED: - CALL_DrawTransformFeedbackInstanced(ctx->Exec, + CALL_DrawTransformFeedbackInstanced(ctx->Dispatch.Exec, (n[1].e, n[2].ui, n[3].si)); break; case OPCODE_DRAW_TRANSFORM_FEEDBACK_STREAM_INSTANCED: - CALL_DrawTransformFeedbackStreamInstanced(ctx->Exec, + CALL_DrawTransformFeedbackStreamInstanced(ctx->Dispatch.Exec, (n[1].e, n[2].ui, n[3].ui, n[4].si)); break; case OPCODE_BIND_SAMPLER: - CALL_BindSampler(ctx->Exec, (n[1].ui, n[2].ui)); + CALL_BindSampler(ctx->Dispatch.Exec, (n[1].ui, n[2].ui)); break; case OPCODE_SAMPLER_PARAMETERIV: { @@ -12886,7 +12516,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].i; params[2] = n[5].i; params[3] = n[6].i; - CALL_SamplerParameteriv(ctx->Exec, (n[1].ui, n[2].e, params)); + CALL_SamplerParameteriv(ctx->Dispatch.Exec, (n[1].ui, n[2].e, params)); } break; case OPCODE_SAMPLER_PARAMETERFV: @@ -12896,7 +12526,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].f; params[2] = n[5].f; params[3] = n[6].f; - CALL_SamplerParameterfv(ctx->Exec, (n[1].ui, n[2].e, params)); + CALL_SamplerParameterfv(ctx->Dispatch.Exec, (n[1].ui, n[2].e, params)); } break; case OPCODE_SAMPLER_PARAMETERIIV: @@ -12906,7 +12536,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].i; params[2] = n[5].i; params[3] = n[6].i; - CALL_SamplerParameterIiv(ctx->Exec, (n[1].ui, n[2].e, params)); + CALL_SamplerParameterIiv(ctx->Dispatch.Exec, (n[1].ui, n[2].e, params)); } break; case OPCODE_SAMPLER_PARAMETERUIV: @@ -12916,13 +12546,13 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[4].ui; params[2] = n[5].ui; params[3] = n[6].ui; - CALL_SamplerParameterIuiv(ctx->Exec, (n[1].ui, n[2].e, params)); + CALL_SamplerParameterIuiv(ctx->Dispatch.Exec, (n[1].ui, n[2].e, params)); } break; /* ARB_compute_shader */ case OPCODE_DISPATCH_COMPUTE: - CALL_DispatchCompute(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui)); + CALL_DispatchCompute(ctx->Dispatch.Exec, (n[1].ui, n[2].ui, n[3].ui)); break; /* GL_ARB_sync */ @@ -12931,83 +12561,83 @@ execute_list(struct gl_context *ctx, GLuint list) union uint64_pair p; p.uint32[0] = n[2].ui; p.uint32[1] = n[3].ui; - CALL_WaitSync(ctx->Exec, + CALL_WaitSync(ctx->Dispatch.Exec, (get_pointer(&n[4]), n[1].bf, p.uint64)); } break; /* GL_NV_conditional_render */ case OPCODE_BEGIN_CONDITIONAL_RENDER: - CALL_BeginConditionalRender(ctx->Exec, (n[1].i, n[2].e)); + CALL_BeginConditionalRender(ctx->Dispatch.Exec, (n[1].i, n[2].e)); break; case OPCODE_END_CONDITIONAL_RENDER: - CALL_EndConditionalRender(ctx->Exec, ()); + CALL_EndConditionalRender(ctx->Dispatch.Exec, ()); break; case OPCODE_UNIFORM_BLOCK_BINDING: - CALL_UniformBlockBinding(ctx->Exec, (n[1].ui, n[2].ui, n[3].ui)); + CALL_UniformBlockBinding(ctx->Dispatch.Exec, (n[1].ui, n[2].ui, n[3].ui)); break; case OPCODE_UNIFORM_SUBROUTINES: - CALL_UniformSubroutinesuiv(ctx->Exec, (n[1].e, n[2].si, + CALL_UniformSubroutinesuiv(ctx->Dispatch.Exec, (n[1].e, n[2].si, get_pointer(&n[3]))); break; /* GL_EXT_window_rectangles */ case OPCODE_WINDOW_RECTANGLES: CALL_WindowRectanglesEXT( - ctx->Exec, (n[1].e, n[2].si, get_pointer(&n[3]))); + ctx->Dispatch.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)); + CALL_SubpixelPrecisionBiasNV(ctx->Dispatch.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)); + CALL_ConservativeRasterParameterfNV(ctx->Dispatch.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)); + CALL_ConservativeRasterParameteriNV(ctx->Dispatch.Exec, (n[1].e, n[2].i)); break; /* GL_EXT_direct_state_access */ case OPCODE_MATRIX_LOAD: - CALL_MatrixLoadfEXT(ctx->Exec, (n[1].e, &n[2].f)); + CALL_MatrixLoadfEXT(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_MATRIX_MULT: - CALL_MatrixMultfEXT(ctx->Exec, (n[1].e, &n[2].f)); + CALL_MatrixMultfEXT(ctx->Dispatch.Exec, (n[1].e, &n[2].f)); break; case OPCODE_MATRIX_ROTATE: - CALL_MatrixRotatefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f, n[5].f)); + CALL_MatrixRotatefEXT(ctx->Dispatch.Exec, (n[1].e, n[2].f, n[3].f, n[4].f, n[5].f)); break; case OPCODE_MATRIX_SCALE: - CALL_MatrixScalefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f)); + CALL_MatrixScalefEXT(ctx->Dispatch.Exec, (n[1].e, n[2].f, n[3].f, n[4].f)); break; case OPCODE_MATRIX_TRANSLATE: - CALL_MatrixTranslatefEXT(ctx->Exec, (n[1].e, n[2].f, n[3].f, n[4].f)); + CALL_MatrixTranslatefEXT(ctx->Dispatch.Exec, (n[1].e, n[2].f, n[3].f, n[4].f)); break; case OPCODE_MATRIX_LOAD_IDENTITY: - CALL_MatrixLoadIdentityEXT(ctx->Exec, (n[1].e)); + CALL_MatrixLoadIdentityEXT(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_MATRIX_ORTHO: - CALL_MatrixOrthoEXT(ctx->Exec, (n[1].e, + CALL_MatrixOrthoEXT(ctx->Dispatch.Exec, (n[1].e, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f, n[7].f)); break; case OPCODE_MATRIX_FRUSTUM: - CALL_MatrixFrustumEXT(ctx->Exec, (n[1].e, + CALL_MatrixFrustumEXT(ctx->Dispatch.Exec, (n[1].e, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f, n[7].f)); break; case OPCODE_MATRIX_PUSH: - CALL_MatrixPushEXT(ctx->Exec, (n[1].e)); + CALL_MatrixPushEXT(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_MATRIX_POP: - CALL_MatrixPopEXT(ctx->Exec, (n[1].e)); + CALL_MatrixPopEXT(ctx->Dispatch.Exec, (n[1].e)); break; case OPCODE_TEXTUREPARAMETER_F: { @@ -13016,7 +12646,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].f; params[2] = n[6].f; params[3] = n[7].f; - CALL_TextureParameterfvEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params)); + CALL_TextureParameterfvEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e, params)); } break; case OPCODE_TEXTUREPARAMETER_I: @@ -13026,7 +12656,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].i; params[2] = n[6].i; params[3] = n[7].i; - CALL_TextureParameterivEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params)); + CALL_TextureParameterivEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e, params)); } break; case OPCODE_TEXTUREPARAMETER_II: @@ -13036,7 +12666,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].i; params[2] = n[6].i; params[3] = n[7].i; - CALL_TextureParameterIivEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params)); + CALL_TextureParameterIivEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e, params)); } break; case OPCODE_TEXTUREPARAMETER_IUI: @@ -13046,14 +12676,14 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].ui; params[2] = n[6].ui; params[3] = n[7].ui; - CALL_TextureParameterIuivEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].e, params)); + CALL_TextureParameterIuivEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e, params)); } break; case OPCODE_TEXTURE_IMAGE1D: { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TextureImage1DEXT(ctx->Exec, (n[1].ui, /* texture */ + CALL_TextureImage1DEXT(ctx->Dispatch.Exec, (n[1].ui, /* texture */ n[2].e, /* target */ n[3].i, /* level */ n[4].i, /* components */ @@ -13069,7 +12699,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TextureImage2DEXT(ctx->Exec, (n[1].ui, /* texture */ + CALL_TextureImage2DEXT(ctx->Dispatch.Exec, (n[1].ui, /* texture */ n[2].e, /* target */ n[3].i, /* level */ n[4].i, /* components */ @@ -13086,7 +12716,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TextureImage3DEXT(ctx->Exec, (n[1].ui, /* texture */ + CALL_TextureImage3DEXT(ctx->Dispatch.Exec, (n[1].ui, /* texture */ n[2].e, /* target */ n[3].i, /* level */ n[4].i, /* components */ @@ -13104,7 +12734,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TextureSubImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_TextureSubImage1DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].e, n[7].e, get_pointer(&n[8]))); ctx->Unpack = save; /* restore */ @@ -13114,7 +12744,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TextureSubImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_TextureSubImage2DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].e, n[7].i, n[8].e, n[9].e, get_pointer(&n[10]))); @@ -13125,7 +12755,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_TextureSubImage3DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_TextureSubImage3DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, n[10].e, n[11].e, @@ -13134,33 +12764,33 @@ execute_list(struct gl_context *ctx, GLuint list) } break; case OPCODE_COPY_TEXTURE_IMAGE1D: - CALL_CopyTextureImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CopyTextureImage1DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i)); break; case OPCODE_COPY_TEXTURE_IMAGE2D: - CALL_CopyTextureImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CopyTextureImage2DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i)); break; case OPCODE_COPY_TEXTURE_SUB_IMAGE1D: - CALL_CopyTextureSubImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CopyTextureSubImage1DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i)); break; case OPCODE_COPY_TEXTURE_SUB_IMAGE2D: - CALL_CopyTextureSubImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CopyTextureSubImage2DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i)); break; case OPCODE_COPY_TEXTURE_SUB_IMAGE3D: - CALL_CopyTextureSubImage3DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CopyTextureSubImage3DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, n[10].i)); break; case OPCODE_BIND_MULTITEXTURE: - CALL_BindMultiTextureEXT(ctx->Exec, (n[1].e, n[2].e, n[3].ui)); + CALL_BindMultiTextureEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].ui)); break; case OPCODE_MULTITEXPARAMETER_F: { @@ -13169,7 +12799,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].f; params[2] = n[6].f; params[3] = n[7].f; - CALL_MultiTexParameterfvEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params)); + CALL_MultiTexParameterfvEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, params)); } break; case OPCODE_MULTITEXPARAMETER_I: @@ -13179,7 +12809,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].i; params[2] = n[6].i; params[3] = n[7].i; - CALL_MultiTexParameterivEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params)); + CALL_MultiTexParameterivEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, params)); } break; case OPCODE_MULTITEXPARAMETER_II: @@ -13189,7 +12819,7 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].i; params[2] = n[6].i; params[3] = n[7].i; - CALL_MultiTexParameterIivEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params)); + CALL_MultiTexParameterIivEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, params)); } break; case OPCODE_MULTITEXPARAMETER_IUI: @@ -13199,14 +12829,14 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].ui; params[2] = n[6].ui; params[3] = n[7].ui; - CALL_MultiTexParameterIuivEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params)); + CALL_MultiTexParameterIuivEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, params)); } break; case OPCODE_MULTITEX_IMAGE1D: { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_MultiTexImage1DEXT(ctx->Exec, (n[1].e, /* texture */ + CALL_MultiTexImage1DEXT(ctx->Dispatch.Exec, (n[1].e, /* texture */ n[2].e, /* target */ n[3].i, /* level */ n[4].i, /* components */ @@ -13222,7 +12852,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_MultiTexImage2DEXT(ctx->Exec, (n[1].e, /* texture */ + CALL_MultiTexImage2DEXT(ctx->Dispatch.Exec, (n[1].e, /* texture */ n[2].e, /* target */ n[3].i, /* level */ n[4].i, /* components */ @@ -13239,7 +12869,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_MultiTexImage3DEXT(ctx->Exec, (n[1].e, /* texture */ + CALL_MultiTexImage3DEXT(ctx->Dispatch.Exec, (n[1].e, /* texture */ n[2].e, /* target */ n[3].i, /* level */ n[4].i, /* components */ @@ -13257,7 +12887,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_MultiTexSubImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_MultiTexSubImage1DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].e, n[7].e, get_pointer(&n[8]))); ctx->Unpack = save; /* restore */ @@ -13267,7 +12897,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_MultiTexSubImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_MultiTexSubImage2DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].e, n[7].i, n[8].e, n[9].e, get_pointer(&n[10]))); @@ -13278,7 +12908,7 @@ execute_list(struct gl_context *ctx, GLuint list) { const struct gl_pixelstore_attrib save = ctx->Unpack; ctx->Unpack = ctx->DefaultPacking; - CALL_MultiTexSubImage3DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_MultiTexSubImage3DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, n[10].e, n[11].e, @@ -13287,27 +12917,27 @@ execute_list(struct gl_context *ctx, GLuint list) } break; case OPCODE_COPY_MULTITEX_IMAGE1D: - CALL_CopyMultiTexImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CopyMultiTexImage1DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i)); break; case OPCODE_COPY_MULTITEX_IMAGE2D: - CALL_CopyMultiTexImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CopyMultiTexImage2DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i)); break; case OPCODE_COPY_MULTITEX_SUB_IMAGE1D: - CALL_CopyMultiTexSubImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CopyMultiTexSubImage1DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i)); break; case OPCODE_COPY_MULTITEX_SUB_IMAGE2D: - CALL_CopyMultiTexSubImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CopyMultiTexSubImage2DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i)); break; case OPCODE_COPY_MULTITEX_SUB_IMAGE3D: - CALL_CopyMultiTexSubImage3DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CopyMultiTexSubImage3DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, n[10].i)); @@ -13319,102 +12949,112 @@ execute_list(struct gl_context *ctx, GLuint list) params[1] = n[5].f; params[2] = n[6].f; params[3] = n[7].f; - CALL_MultiTexEnvfvEXT(ctx->Exec, (n[1].e, n[2].e, n[3].e, params)); + CALL_MultiTexEnvfvEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].e, params)); } break; case OPCODE_COMPRESSED_TEXTURE_IMAGE_1D: - CALL_CompressedTextureImage1DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CompressedTextureImage1DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, get_pointer(&n[8]))); break; case OPCODE_COMPRESSED_TEXTURE_IMAGE_2D: - CALL_CompressedTextureImage2DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CompressedTextureImage2DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i, get_pointer(&n[9]))); break; case OPCODE_COMPRESSED_TEXTURE_IMAGE_3D: - CALL_CompressedTextureImage3DEXT(ctx->Exec, (n[1].ui, n[2].e, n[3].i, + CALL_CompressedTextureImage3DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, get_pointer(&n[10]))); break; case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_1D: - CALL_CompressedTextureSubImage1DEXT(ctx->Exec, + CALL_CompressedTextureSubImage1DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].e, n[7].i, get_pointer(&n[8]))); break; case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_2D: - CALL_CompressedTextureSubImage2DEXT(ctx->Exec, + CALL_CompressedTextureSubImage2DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].e, n[9].i, get_pointer(&n[10]))); break; case OPCODE_COMPRESSED_TEXTURE_SUB_IMAGE_3D: - CALL_CompressedTextureSubImage3DEXT(ctx->Exec, + CALL_CompressedTextureSubImage3DEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, n[10].e, n[11].i, get_pointer(&n[12]))); break; case OPCODE_COMPRESSED_MULTITEX_IMAGE_1D: - CALL_CompressedMultiTexImage1DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CompressedMultiTexImage1DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, get_pointer(&n[8]))); break; case OPCODE_COMPRESSED_MULTITEX_IMAGE_2D: - CALL_CompressedMultiTexImage2DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CompressedMultiTexImage2DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i, get_pointer(&n[9]))); break; case OPCODE_COMPRESSED_MULTITEX_IMAGE_3D: - CALL_CompressedMultiTexImage3DEXT(ctx->Exec, (n[1].e, n[2].e, n[3].i, + CALL_CompressedMultiTexImage3DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].e, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, get_pointer(&n[10]))); break; case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_1D: - CALL_CompressedMultiTexSubImage1DEXT(ctx->Exec, + CALL_CompressedMultiTexSubImage1DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].e, n[7].i, get_pointer(&n[8]))); break; case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_2D: - CALL_CompressedMultiTexSubImage2DEXT(ctx->Exec, + CALL_CompressedMultiTexSubImage2DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].e, n[9].i, get_pointer(&n[10]))); break; case OPCODE_COMPRESSED_MULTITEX_SUB_IMAGE_3D: - CALL_CompressedMultiTexSubImage3DEXT(ctx->Exec, + CALL_CompressedMultiTexSubImage3DEXT(ctx->Dispatch.Exec, (n[1].e, n[2].e, n[3].i, n[4].i, n[5].i, n[6].i, n[7].i, n[8].i, n[9].i, n[10].e, n[11].i, get_pointer(&n[12]))); break; case OPCODE_NAMED_PROGRAM_STRING: - CALL_NamedProgramStringEXT(ctx->Exec, + CALL_NamedProgramStringEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].e, n[4].i, get_pointer(&n[5]))); break; case OPCODE_NAMED_PROGRAM_LOCAL_PARAMETER: - CALL_NamedProgramLocalParameter4fEXT(ctx->Exec, + CALL_NamedProgramLocalParameter4fEXT(ctx->Dispatch.Exec, (n[1].ui, n[2].e, n[3].ui, n[4].f, n[5].f, n[6].f, n[7].f)); break; + case OPCODE_PRIMITIVE_BOUNDING_BOX: + CALL_PrimitiveBoundingBox(ctx->Dispatch.Exec, + (n[1].f, n[2].f, n[3].f, n[4].f, + n[5].f, n[6].f, n[7].f, n[8].f)); + break; case OPCODE_VERTEX_LIST: - vbo_save_playback_vertex_list(ctx, &n[1]); + vbo_save_playback_vertex_list(ctx, &n[0], false); + break; + + case OPCODE_VERTEX_LIST_COPY_CURRENT: + vbo_save_playback_vertex_list(ctx, &n[0], true); + break; + + case OPCODE_VERTEX_LIST_LOOPBACK: + vbo_save_playback_vertex_list_loopback(ctx, &n[0]); break; case OPCODE_CONTINUE: n = (Node *) get_pointer(&n[1]); continue; - case OPCODE_NOP: - /* no-op */ - break; default: { char msg[1000]; @@ -13424,14 +13064,12 @@ execute_list(struct gl_context *ctx, GLuint list) } FALLTHROUGH; case OPCODE_END_OF_LIST: - vbo_save_EndCallList(ctx); - ctx->ListState.CallDepth--; return; } /* increment n to point to next compiled command */ - assert(InstSize[opcode] > 0); - n += InstSize[opcode]; + assert(n[0].InstSize > 0); + n += n[0].InstSize; } } @@ -13450,7 +13088,7 @@ _mesa_IsList(GLuint list) GET_CURRENT_CONTEXT(ctx); FLUSH_VERTICES(ctx, 0, 0); /* must be called before assert */ ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - return _mesa_get_list(ctx, list, NULL); + return _mesa_get_list(ctx, list, NULL, false); } @@ -13470,20 +13108,11 @@ _mesa_DeleteLists(GLuint list, GLsizei range) return; } - if (range > 1) { - /* We may be deleting a set of bitmap lists. See if there's a - * bitmap atlas to free. - */ - struct gl_bitmap_atlas *atlas = lookup_bitmap_atlas(ctx, list); - if (atlas) { - _mesa_delete_bitmap_atlas(ctx, atlas); - _mesa_HashRemove(ctx->Shared->BitmapAtlas, list); - } - } - + _mesa_HashLockMutex(&ctx->Shared->DisplayList); for (i = list; i < list + range; i++) { destroy_list(ctx, i); } + _mesa_HashUnlockMutex(&ctx->Shared->DisplayList); } @@ -13510,37 +13139,19 @@ _mesa_GenLists(GLsizei range) /* * Make this an atomic operation */ - _mesa_HashLockMutex(ctx->Shared->DisplayList); + _mesa_HashLockMutex(&ctx->Shared->DisplayList); - base = _mesa_HashFindFreeKeyBlock(ctx->Shared->DisplayList, range); + base = _mesa_HashFindFreeKeyBlock(&ctx->Shared->DisplayList, range); if (base) { /* reserve the list IDs by with empty/dummy lists */ GLint i; for (i = 0; i < range; i++) { - _mesa_HashInsertLocked(ctx->Shared->DisplayList, base + i, - make_list(base + i, 1), true); + _mesa_HashInsertLocked(&ctx->Shared->DisplayList, base + i, + make_list(base + i, 1)); } } - if (USE_BITMAP_ATLAS && - range > 16 && - ctx->Driver.DrawAtlasBitmaps) { - /* "range > 16" is a rough heuristic to guess when glGenLists might be - * used to allocate display lists for glXUseXFont or wglUseFontBitmaps. - * Create the empty atlas now. - */ - struct gl_bitmap_atlas *atlas = lookup_bitmap_atlas(ctx, base); - if (!atlas) { - atlas = alloc_bitmap_atlas(ctx, base, true); - } - if (atlas) { - /* Atlas _should_ be new/empty now, but clobbering is OK */ - assert(atlas->numBitmaps == 0); - atlas->numBitmaps = range; - } - } - - _mesa_HashUnlockMutex(ctx->Shared->DisplayList); + _mesa_HashUnlockMutex(&ctx->Shared->DisplayList); return base; } @@ -13587,13 +13198,120 @@ _mesa_NewList(GLuint name, GLenum mode) ctx->ListState.CurrentList = make_list(name, BLOCK_SIZE); ctx->ListState.CurrentBlock = ctx->ListState.CurrentList->Head; ctx->ListState.CurrentPos = 0; + ctx->ListState.LastInstSize = 0; + ctx->ListState.Current.UseLoopback = false; vbo_save_NewList(ctx, name, mode); - ctx->CurrentServerDispatch = ctx->Save; - _glapi_set_dispatch(ctx->CurrentServerDispatch); - if (ctx->MarshalExec == NULL) { - ctx->CurrentClientDispatch = ctx->CurrentServerDispatch; + ctx->Dispatch.Current = ctx->Dispatch.Save; + _glapi_set_dispatch(ctx->Dispatch.Current); + if (!ctx->GLThread.enabled) { + ctx->GLApi = ctx->Dispatch.Current; + } +} + + +/** + * Walk all the opcode from a given list, recursively if OPCODE_CALL_LIST(S) is used, + * and replace OPCODE_VERTEX_LIST[_COPY_CURRENT] occurences by OPCODE_VERTEX_LIST_LOOPBACK. + */ +static void +replace_op_vertex_list_recursively(struct gl_context *ctx, struct gl_display_list *dlist) +{ + Node *n = get_list_head(ctx, dlist); + while (true) { + const OpCode opcode = n[0].opcode; + switch (opcode) { + case OPCODE_VERTEX_LIST: + case OPCODE_VERTEX_LIST_COPY_CURRENT: + n[0].opcode = OPCODE_VERTEX_LIST_LOOPBACK; + break; + case OPCODE_CONTINUE: + n = (Node *)get_pointer(&n[1]); + continue; + case OPCODE_CALL_LIST: + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)n[1].ui, true)); + break; + case OPCODE_CALL_LISTS: { + GLbyte *bptr; + GLubyte *ubptr; + GLshort *sptr; + GLushort *usptr; + GLint *iptr; + GLuint *uiptr; + GLfloat *fptr; + switch(n[2].e) { + case GL_BYTE: + bptr = (GLbyte *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)bptr[i], true)); + break; + case GL_UNSIGNED_BYTE: + ubptr = (GLubyte *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)ubptr[i], true)); + break; + case GL_SHORT: + sptr = (GLshort *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)sptr[i], true)); + break; + case GL_UNSIGNED_SHORT: + usptr = (GLushort *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)usptr[i], true)); + break; + case GL_INT: + iptr = (GLint *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)iptr[i], true)); + break; + case GL_UNSIGNED_INT: + uiptr = (GLuint *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)uiptr[i], true)); + break; + case GL_FLOAT: + fptr = (GLfloat *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) + replace_op_vertex_list_recursively(ctx, _mesa_lookup_list(ctx, (int)fptr[i], true)); + break; + case GL_2_BYTES: + ubptr = (GLubyte *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) { + replace_op_vertex_list_recursively(ctx, + _mesa_lookup_list(ctx, (int)ubptr[2 * i] * 256 + + (int)ubptr[2 * i + 1], true)); + } + break; + case GL_3_BYTES: + ubptr = (GLubyte *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) { + replace_op_vertex_list_recursively(ctx, + _mesa_lookup_list(ctx, (int)ubptr[3 * i] * 65536 + + (int)ubptr[3 * i + 1] * 256 + + (int)ubptr[3 * i + 2], true)); + } + break; + case GL_4_BYTES: + ubptr = (GLubyte *) get_pointer(&n[3]); + for (unsigned i = 0; i < n[1].i; i++) { + replace_op_vertex_list_recursively(ctx, + _mesa_lookup_list(ctx, (int)ubptr[4 * i] * 16777216 + + (int)ubptr[4 * i + 1] * 65536 + + (int)ubptr[4 * i + 2] * 256 + + (int)ubptr[4 * i + 3], true)); + } + break; + } + break; + } + case OPCODE_END_OF_LIST: + return; + default: + break; + } + n += n[0].InstSize; } } @@ -13629,30 +13347,78 @@ _mesa_EndList(void) (void) alloc_instruction(ctx, OPCODE_END_OF_LIST, 0); - trim_list(ctx); + _mesa_HashLockMutex(&ctx->Shared->DisplayList); + + if (ctx->ListState.Current.UseLoopback) + replace_op_vertex_list_recursively(ctx, ctx->ListState.CurrentList); + + struct gl_dlist_state *list = &ctx->ListState; + list->CurrentList->execute_glthread = + _mesa_glthread_should_execute_list(ctx, list->CurrentList); + ctx->Shared->DisplayListsAffectGLThread |= list->CurrentList->execute_glthread; + + if ((list->CurrentList->Head == list->CurrentBlock) && + (list->CurrentPos < BLOCK_SIZE)) { + /* This list has a low number of commands. Instead of storing them in a malloc-ed block + * of memory (list->CurrentBlock), we store them in ctx->Shared->small_dlist_store.ptr. + * This reduces cache misses in execute_list on successive lists since their commands + * are now stored in the same array instead of being scattered in memory. + */ + list->CurrentList->small_list = true; + unsigned start; + + if (ctx->Shared->small_dlist_store.size == 0) { + util_idalloc_init(&ctx->Shared->small_dlist_store.free_idx, MAX2(1, list->CurrentPos)); + } + + start = util_idalloc_alloc_range(&ctx->Shared->small_dlist_store.free_idx, list->CurrentPos); + + if ((start + list->CurrentPos) > ctx->Shared->small_dlist_store.size) { + ctx->Shared->small_dlist_store.size = + ctx->Shared->small_dlist_store.free_idx.num_elements * 32; + ctx->Shared->small_dlist_store.ptr = realloc( + ctx->Shared->small_dlist_store.ptr, + ctx->Shared->small_dlist_store.size * sizeof(Node)); + } + list->CurrentList->start = start; + list->CurrentList->count = list->CurrentPos; + + memcpy(&ctx->Shared->small_dlist_store.ptr[start], + list->CurrentBlock, + list->CurrentList->count * sizeof(Node)); + + assert (ctx->Shared->small_dlist_store.ptr[start + list->CurrentList->count - 1].opcode == OPCODE_END_OF_LIST); + + free(list->CurrentBlock); + } else { + /* Keep the mallocated storage */ + list->CurrentList->small_list = false; + } /* Destroy old list, if any */ destroy_list(ctx, ctx->ListState.CurrentList->Name); /* Install the new list */ - _mesa_HashInsert(ctx->Shared->DisplayList, - ctx->ListState.CurrentList->Name, - ctx->ListState.CurrentList, true); - + _mesa_HashInsertLocked(&ctx->Shared->DisplayList, + ctx->ListState.CurrentList->Name, + ctx->ListState.CurrentList); if (MESA_VERBOSE & VERBOSE_DISPLAY_LIST) mesa_print_display_list(ctx->ListState.CurrentList->Name); + _mesa_HashUnlockMutex(&ctx->Shared->DisplayList); + ctx->ListState.CurrentList = NULL; ctx->ListState.CurrentBlock = NULL; ctx->ListState.CurrentPos = 0; + ctx->ListState.LastInstSize = 0; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; - ctx->CurrentServerDispatch = ctx->Exec; - _glapi_set_dispatch(ctx->CurrentServerDispatch); - if (ctx->MarshalExec == NULL) { - ctx->CurrentClientDispatch = ctx->CurrentServerDispatch; + ctx->Dispatch.Current = ctx->Dispatch.Exec; + _glapi_set_dispatch(ctx->Dispatch.Current); + if (!ctx->GLThread.enabled) { + ctx->GLApi = ctx->Dispatch.Current; } } @@ -13684,80 +13450,22 @@ _mesa_CallList(GLuint list) ctx->CompileFlag = GL_FALSE; } + _mesa_HashLockMutex(&ctx->Shared->DisplayList); execute_list(ctx, list); + _mesa_HashUnlockMutex(&ctx->Shared->DisplayList); ctx->CompileFlag = save_compile_flag; /* also restore API function pointers to point to "save" versions */ if (save_compile_flag) { - ctx->CurrentServerDispatch = ctx->Save; - _glapi_set_dispatch(ctx->CurrentServerDispatch); - if (ctx->MarshalExec == NULL) { - ctx->CurrentClientDispatch = ctx->CurrentServerDispatch; + ctx->Dispatch.Current = ctx->Dispatch.Save; + if (!ctx->GLThread.enabled) { + ctx->GLApi = ctx->Dispatch.Current; } } } /** - * Try to execute a glCallLists() command where the display lists contain - * glBitmap commands with a texture atlas. - * \return true for success, false otherwise - */ -static bool -render_bitmap_atlas(struct gl_context *ctx, GLsizei n, GLenum type, - const void *lists) -{ - struct gl_bitmap_atlas *atlas; - int i; - - if (!USE_BITMAP_ATLAS || - !ctx->Current.RasterPosValid || - ctx->List.ListBase == 0 || - type != GL_UNSIGNED_BYTE || - !ctx->Driver.DrawAtlasBitmaps) { - /* unsupported */ - return false; - } - - atlas = lookup_bitmap_atlas(ctx, ctx->List.ListBase); - - if (!atlas) { - /* Even if glGenLists wasn't called, we can still try to create - * the atlas now. - */ - atlas = alloc_bitmap_atlas(ctx, ctx->List.ListBase, false); - } - - if (atlas && !atlas->complete && !atlas->incomplete) { - /* Try to build the bitmap atlas now. - * If the atlas was created in glGenLists, we'll have recorded the - * number of lists (bitmaps). Otherwise, take a guess at 256. - */ - if (atlas->numBitmaps == 0) - atlas->numBitmaps = 256; - build_bitmap_atlas(ctx, atlas, ctx->List.ListBase); - } - - if (!atlas || !atlas->complete) { - return false; - } - - /* check that all display list IDs are in the atlas */ - for (i = 0; i < n; i++) { - const GLubyte *ids = (const GLubyte *) lists; - - if (ids[i] >= atlas->numBitmaps) { - return false; - } - } - - ctx->Driver.DrawAtlasBitmaps(ctx, atlas, n, (const GLubyte *) lists); - - return true; -} - - -/** * Execute glCallLists: call multiple display lists. */ void GLAPIENTRY @@ -13782,10 +13490,6 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists) return; } - if (render_bitmap_atlas(ctx, n, type, lists)) { - return; - } - /* Save the CompileFlag status, turn it off, execute the display lists, * and restore the CompileFlag. This is needed for GL_COMPILE_AND_EXECUTE * because the call is already recorded and we just need to execute it. @@ -13803,6 +13507,8 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists) GLuint base = ctx->List.ListBase; + _mesa_HashLockMutex(&ctx->Shared->DisplayList); + /* A loop inside a switch is faster than a switch inside a loop. */ switch (type) { case GL_BYTE: @@ -13869,14 +13575,14 @@ _mesa_CallLists(GLsizei n, GLenum type, const GLvoid * lists) break; } + _mesa_HashUnlockMutex(&ctx->Shared->DisplayList); ctx->CompileFlag = save_compile_flag; /* also restore API function pointers to point to "save" versions */ if (save_compile_flag) { - ctx->CurrentServerDispatch = ctx->Save; - _glapi_set_dispatch(ctx->CurrentServerDispatch); - if (ctx->MarshalExec == NULL) { - ctx->CurrentClientDispatch = ctx->CurrentServerDispatch; + ctx->Dispatch.Current = ctx->Dispatch.Save; + if (!ctx->GLThread.enabled) { + ctx->GLApi = ctx->Dispatch.Current; } } } @@ -13897,650 +13603,21 @@ _mesa_ListBase(GLuint base) /** * Setup the given dispatch table to point to Mesa's display list * building functions. - * - * This does not include any of the tnl functions - they are - * initialized from _mesa_init_api_defaults and from the active vtxfmt - * struct. */ void -_mesa_initialize_save_table(const struct gl_context *ctx) +_mesa_init_dispatch_save(const struct gl_context *ctx) { - struct _glapi_table *table = ctx->Save; + struct _glapi_table *table = ctx->Dispatch.Save; int numEntries = MAX2(_gloffset_COUNT, _glapi_get_dispatch_table_size()); /* Initially populate the dispatch table with the contents of the * normal-execution dispatch table. This lets us skip populating functions * that should be called directly instead of compiled into display lists. */ - memcpy(table, ctx->Exec, numEntries * sizeof(_glapi_proc)); - - /* VBO functions */ - vbo_initialize_save_dispatch(ctx, table); - - /* GL 1.0 */ - SET_Accum(table, save_Accum); - SET_AlphaFunc(table, save_AlphaFunc); - SET_Bitmap(table, save_Bitmap); - SET_BlendFunc(table, save_BlendFunc); - SET_CallList(table, save_CallList); - SET_CallLists(table, save_CallLists); - SET_Clear(table, save_Clear); - SET_ClearAccum(table, save_ClearAccum); - SET_ClearColor(table, save_ClearColor); - SET_ClearDepth(table, save_ClearDepth); - SET_ClearIndex(table, save_ClearIndex); - SET_ClearStencil(table, save_ClearStencil); - SET_ClipPlane(table, save_ClipPlane); - SET_ColorMask(table, save_ColorMask); - SET_ColorMaski(table, save_ColorMaskIndexed); - SET_ColorMaterial(table, save_ColorMaterial); - SET_CopyPixels(table, save_CopyPixels); - SET_CullFace(table, save_CullFace); - SET_DepthFunc(table, save_DepthFunc); - SET_DepthMask(table, save_DepthMask); - SET_DepthRange(table, save_DepthRange); - SET_Disable(table, save_Disable); - SET_Disablei(table, save_DisableIndexed); - SET_DrawBuffer(table, save_DrawBuffer); - SET_DrawPixels(table, save_DrawPixels); - SET_Enable(table, save_Enable); - SET_Enablei(table, save_EnableIndexed); - SET_EvalMesh1(table, save_EvalMesh1); - SET_EvalMesh2(table, save_EvalMesh2); - SET_Fogf(table, save_Fogf); - SET_Fogfv(table, save_Fogfv); - SET_Fogi(table, save_Fogi); - SET_Fogiv(table, save_Fogiv); - SET_FrontFace(table, save_FrontFace); - SET_Frustum(table, save_Frustum); - SET_Hint(table, save_Hint); - SET_IndexMask(table, save_IndexMask); - SET_InitNames(table, save_InitNames); - SET_LightModelf(table, save_LightModelf); - SET_LightModelfv(table, save_LightModelfv); - SET_LightModeli(table, save_LightModeli); - SET_LightModeliv(table, save_LightModeliv); - SET_Lightf(table, save_Lightf); - SET_Lightfv(table, save_Lightfv); - SET_Lighti(table, save_Lighti); - SET_Lightiv(table, save_Lightiv); - SET_LineStipple(table, save_LineStipple); - SET_LineWidth(table, save_LineWidth); - SET_ListBase(table, save_ListBase); - SET_LoadIdentity(table, save_LoadIdentity); - SET_LoadMatrixd(table, save_LoadMatrixd); - SET_LoadMatrixf(table, save_LoadMatrixf); - SET_LoadName(table, save_LoadName); - SET_LogicOp(table, save_LogicOp); - SET_Map1d(table, save_Map1d); - SET_Map1f(table, save_Map1f); - SET_Map2d(table, save_Map2d); - SET_Map2f(table, save_Map2f); - SET_MapGrid1d(table, save_MapGrid1d); - SET_MapGrid1f(table, save_MapGrid1f); - SET_MapGrid2d(table, save_MapGrid2d); - SET_MapGrid2f(table, save_MapGrid2f); - SET_MatrixMode(table, save_MatrixMode); - SET_MultMatrixd(table, save_MultMatrixd); - SET_MultMatrixf(table, save_MultMatrixf); - SET_NewList(table, save_NewList); - SET_Ortho(table, save_Ortho); - SET_PassThrough(table, save_PassThrough); - SET_PixelMapfv(table, save_PixelMapfv); - SET_PixelMapuiv(table, save_PixelMapuiv); - SET_PixelMapusv(table, save_PixelMapusv); - SET_PixelTransferf(table, save_PixelTransferf); - SET_PixelTransferi(table, save_PixelTransferi); - SET_PixelZoom(table, save_PixelZoom); - SET_PointSize(table, save_PointSize); - SET_PolygonMode(table, save_PolygonMode); - SET_PolygonOffset(table, save_PolygonOffset); - SET_PolygonStipple(table, save_PolygonStipple); - SET_PopAttrib(table, save_PopAttrib); - SET_PopMatrix(table, save_PopMatrix); - SET_PopName(table, save_PopName); - SET_PushAttrib(table, save_PushAttrib); - SET_PushMatrix(table, save_PushMatrix); - SET_PushName(table, save_PushName); - SET_RasterPos2d(table, save_RasterPos2d); - SET_RasterPos2dv(table, save_RasterPos2dv); - SET_RasterPos2f(table, save_RasterPos2f); - SET_RasterPos2fv(table, save_RasterPos2fv); - SET_RasterPos2i(table, save_RasterPos2i); - SET_RasterPos2iv(table, save_RasterPos2iv); - SET_RasterPos2s(table, save_RasterPos2s); - SET_RasterPos2sv(table, save_RasterPos2sv); - SET_RasterPos3d(table, save_RasterPos3d); - SET_RasterPos3dv(table, save_RasterPos3dv); - SET_RasterPos3f(table, save_RasterPos3f); - SET_RasterPos3fv(table, save_RasterPos3fv); - SET_RasterPos3i(table, save_RasterPos3i); - SET_RasterPos3iv(table, save_RasterPos3iv); - SET_RasterPos3s(table, save_RasterPos3s); - SET_RasterPos3sv(table, save_RasterPos3sv); - SET_RasterPos4d(table, save_RasterPos4d); - SET_RasterPos4dv(table, save_RasterPos4dv); - SET_RasterPos4f(table, save_RasterPos4f); - SET_RasterPos4fv(table, save_RasterPos4fv); - SET_RasterPos4i(table, save_RasterPos4i); - SET_RasterPos4iv(table, save_RasterPos4iv); - SET_RasterPos4s(table, save_RasterPos4s); - SET_RasterPos4sv(table, save_RasterPos4sv); - SET_ReadBuffer(table, save_ReadBuffer); - SET_Rotated(table, save_Rotated); - SET_Rotatef(table, save_Rotatef); - SET_Scaled(table, save_Scaled); - SET_Scalef(table, save_Scalef); - SET_Scissor(table, save_Scissor); - SET_ShadeModel(table, save_ShadeModel); - SET_StencilFunc(table, save_StencilFunc); - SET_StencilMask(table, save_StencilMask); - SET_StencilOp(table, save_StencilOp); - SET_TexEnvf(table, save_TexEnvf); - SET_TexEnvfv(table, save_TexEnvfv); - SET_TexEnvi(table, save_TexEnvi); - SET_TexEnviv(table, save_TexEnviv); - SET_TexGend(table, save_TexGend); - SET_TexGendv(table, save_TexGendv); - SET_TexGenf(table, save_TexGenf); - SET_TexGenfv(table, save_TexGenfv); - SET_TexGeni(table, save_TexGeni); - SET_TexGeniv(table, save_TexGeniv); - SET_TexImage1D(table, save_TexImage1D); - SET_TexImage2D(table, save_TexImage2D); - SET_TexParameterf(table, save_TexParameterf); - SET_TexParameterfv(table, save_TexParameterfv); - SET_TexParameteri(table, save_TexParameteri); - SET_TexParameteriv(table, save_TexParameteriv); - SET_Translated(table, save_Translated); - SET_Translatef(table, save_Translatef); - SET_Viewport(table, save_Viewport); - - /* GL 1.1 */ - SET_BindTexture(table, save_BindTexture); - SET_CopyTexImage1D(table, save_CopyTexImage1D); - SET_CopyTexImage2D(table, save_CopyTexImage2D); - SET_CopyTexSubImage1D(table, save_CopyTexSubImage1D); - SET_CopyTexSubImage2D(table, save_CopyTexSubImage2D); - SET_PrioritizeTextures(table, save_PrioritizeTextures); - SET_TexSubImage1D(table, save_TexSubImage1D); - SET_TexSubImage2D(table, save_TexSubImage2D); - - /* GL 1.2 */ - SET_CopyTexSubImage3D(table, save_CopyTexSubImage3D); - SET_TexImage3D(table, save_TexImage3D); - SET_TexSubImage3D(table, save_TexSubImage3D); - - /* GL 2.0 */ - SET_StencilFuncSeparate(table, save_StencilFuncSeparate); - SET_StencilMaskSeparate(table, save_StencilMaskSeparate); - SET_StencilOpSeparate(table, save_StencilOpSeparate); - - /* ATI_separate_stencil */ - SET_StencilFuncSeparateATI(table, save_StencilFuncSeparateATI); - - /* GL_ARB_imaging */ - /* Not all are supported */ - SET_BlendColor(table, save_BlendColor); - SET_BlendEquation(table, save_BlendEquation); - - /* 2. GL_EXT_blend_color */ -#if 0 - SET_BlendColorEXT(table, save_BlendColorEXT); -#endif - - /* 6. GL_EXT_texture3d */ -#if 0 - SET_CopyTexSubImage3DEXT(table, save_CopyTexSubImage3D); - SET_TexImage3DEXT(table, save_TexImage3DEXT); - SET_TexSubImage3DEXT(table, save_TexSubImage3D); -#endif - - /* 37. GL_EXT_blend_minmax */ -#if 0 - SET_BlendEquationEXT(table, save_BlendEquationEXT); -#endif - - /* 54. GL_EXT_point_parameters */ - SET_PointParameterf(table, save_PointParameterfEXT); - SET_PointParameterfv(table, save_PointParameterfvEXT); - - /* 91. GL_ARB_tessellation_shader */ - SET_PatchParameteri(table, save_PatchParameteri); - SET_PatchParameterfv(table, save_PatchParameterfv); - - /* 100. ARB_viewport_array */ - SET_ViewportArrayv(table, save_ViewportArrayv); - SET_ViewportIndexedf(table, save_ViewportIndexedf); - SET_ViewportIndexedfv(table, save_ViewportIndexedfv); - SET_ScissorArrayv(table, save_ScissorArrayv); - SET_ScissorIndexed(table, save_ScissorIndexed); - SET_ScissorIndexedv(table, save_ScissorIndexedv); - SET_DepthRangeArrayv(table, save_DepthRangeArrayv); - SET_DepthRangeIndexed(table, save_DepthRangeIndexed); - - /* 122. ARB_compute_shader */ - SET_DispatchCompute(table, save_DispatchCompute); - SET_DispatchComputeIndirect(table, save_DispatchComputeIndirect); - - /* 173. GL_EXT_blend_func_separate */ - SET_BlendFuncSeparate(table, save_BlendFuncSeparateEXT); - - /* 197. GL_MESA_window_pos */ - SET_WindowPos2d(table, save_WindowPos2dMESA); - SET_WindowPos2dv(table, save_WindowPos2dvMESA); - SET_WindowPos2f(table, save_WindowPos2fMESA); - SET_WindowPos2fv(table, save_WindowPos2fvMESA); - SET_WindowPos2i(table, save_WindowPos2iMESA); - SET_WindowPos2iv(table, save_WindowPos2ivMESA); - SET_WindowPos2s(table, save_WindowPos2sMESA); - SET_WindowPos2sv(table, save_WindowPos2svMESA); - SET_WindowPos3d(table, save_WindowPos3dMESA); - SET_WindowPos3dv(table, save_WindowPos3dvMESA); - SET_WindowPos3f(table, save_WindowPos3fMESA); - SET_WindowPos3fv(table, save_WindowPos3fvMESA); - SET_WindowPos3i(table, save_WindowPos3iMESA); - SET_WindowPos3iv(table, save_WindowPos3ivMESA); - SET_WindowPos3s(table, save_WindowPos3sMESA); - SET_WindowPos3sv(table, save_WindowPos3svMESA); - SET_WindowPos4dMESA(table, save_WindowPos4dMESA); - SET_WindowPos4dvMESA(table, save_WindowPos4dvMESA); - SET_WindowPos4fMESA(table, save_WindowPos4fMESA); - SET_WindowPos4fvMESA(table, save_WindowPos4fvMESA); - SET_WindowPos4iMESA(table, save_WindowPos4iMESA); - SET_WindowPos4ivMESA(table, save_WindowPos4ivMESA); - SET_WindowPos4sMESA(table, save_WindowPos4sMESA); - SET_WindowPos4svMESA(table, save_WindowPos4svMESA); - - /* 245. GL_ATI_fragment_shader */ - SET_BindFragmentShaderATI(table, save_BindFragmentShaderATI); - SET_SetFragmentShaderConstantATI(table, save_SetFragmentShaderConstantATI); - - /* 262. GL_ARB_point_sprite */ - SET_PointParameteri(table, save_PointParameteri); - SET_PointParameteriv(table, save_PointParameteriv); - - /* 268. GL_EXT_stencil_two_side */ - SET_ActiveStencilFaceEXT(table, save_ActiveStencilFaceEXT); - - /* ???. GL_EXT_depth_bounds_test */ - SET_DepthBoundsEXT(table, save_DepthBoundsEXT); - - /* ARB 1. GL_ARB_multitexture */ - SET_ActiveTexture(table, save_ActiveTextureARB); - - /* ARB 3. GL_ARB_transpose_matrix */ - SET_LoadTransposeMatrixd(table, save_LoadTransposeMatrixdARB); - SET_LoadTransposeMatrixf(table, save_LoadTransposeMatrixfARB); - SET_MultTransposeMatrixd(table, save_MultTransposeMatrixdARB); - SET_MultTransposeMatrixf(table, save_MultTransposeMatrixfARB); - - /* ARB 5. GL_ARB_multisample */ - SET_SampleCoverage(table, save_SampleCoverageARB); - - /* ARB 12. GL_ARB_texture_compression */ - SET_CompressedTexImage3D(table, save_CompressedTexImage3DARB); - SET_CompressedTexImage2D(table, save_CompressedTexImage2DARB); - SET_CompressedTexImage1D(table, save_CompressedTexImage1DARB); - SET_CompressedTexSubImage3D(table, save_CompressedTexSubImage3DARB); - SET_CompressedTexSubImage2D(table, save_CompressedTexSubImage2DARB); - SET_CompressedTexSubImage1D(table, save_CompressedTexSubImage1DARB); - - /* ARB 14. GL_ARB_point_parameters */ - /* aliased with EXT_point_parameters functions */ - - /* ARB 25. GL_ARB_window_pos */ - /* aliased with MESA_window_pos functions */ - - /* ARB 26. GL_ARB_vertex_program */ - /* ARB 27. GL_ARB_fragment_program */ - /* glVertexAttrib* functions alias the NV ones, handled elsewhere */ - SET_ProgramStringARB(table, save_ProgramStringARB); - SET_BindProgramARB(table, save_BindProgramARB); - SET_ProgramEnvParameter4dARB(table, save_ProgramEnvParameter4dARB); - SET_ProgramEnvParameter4dvARB(table, save_ProgramEnvParameter4dvARB); - SET_ProgramEnvParameter4fARB(table, save_ProgramEnvParameter4fARB); - SET_ProgramEnvParameter4fvARB(table, save_ProgramEnvParameter4fvARB); - SET_ProgramLocalParameter4dARB(table, save_ProgramLocalParameter4dARB); - SET_ProgramLocalParameter4dvARB(table, save_ProgramLocalParameter4dvARB); - SET_ProgramLocalParameter4fARB(table, save_ProgramLocalParameter4fARB); - SET_ProgramLocalParameter4fvARB(table, save_ProgramLocalParameter4fvARB); - - SET_BeginQuery(table, save_BeginQueryARB); - SET_EndQuery(table, save_EndQueryARB); - SET_QueryCounter(table, save_QueryCounter); - - SET_DrawBuffers(table, save_DrawBuffersARB); - - SET_BlitFramebuffer(table, save_BlitFramebufferEXT); - - SET_UseProgram(table, save_UseProgram); - SET_Uniform1f(table, save_Uniform1fARB); - SET_Uniform2f(table, save_Uniform2fARB); - SET_Uniform3f(table, save_Uniform3fARB); - SET_Uniform4f(table, save_Uniform4fARB); - SET_Uniform1fv(table, save_Uniform1fvARB); - SET_Uniform2fv(table, save_Uniform2fvARB); - SET_Uniform3fv(table, save_Uniform3fvARB); - SET_Uniform4fv(table, save_Uniform4fvARB); - SET_Uniform1i(table, save_Uniform1iARB); - SET_Uniform2i(table, save_Uniform2iARB); - SET_Uniform3i(table, save_Uniform3iARB); - SET_Uniform4i(table, save_Uniform4iARB); - SET_Uniform1iv(table, save_Uniform1ivARB); - SET_Uniform2iv(table, save_Uniform2ivARB); - SET_Uniform3iv(table, save_Uniform3ivARB); - SET_Uniform4iv(table, save_Uniform4ivARB); - SET_UniformMatrix2fv(table, save_UniformMatrix2fvARB); - SET_UniformMatrix3fv(table, save_UniformMatrix3fvARB); - SET_UniformMatrix4fv(table, save_UniformMatrix4fvARB); - SET_UniformMatrix2x3fv(table, save_UniformMatrix2x3fv); - SET_UniformMatrix3x2fv(table, save_UniformMatrix3x2fv); - SET_UniformMatrix2x4fv(table, save_UniformMatrix2x4fv); - SET_UniformMatrix4x2fv(table, save_UniformMatrix4x2fv); - SET_UniformMatrix3x4fv(table, save_UniformMatrix3x4fv); - SET_UniformMatrix4x3fv(table, save_UniformMatrix4x3fv); - - /* 299. GL_EXT_blend_equation_separate */ - SET_BlendEquationSeparate(table, save_BlendEquationSeparateEXT); - - /* GL_EXT_gpu_program_parameters */ - SET_ProgramEnvParameters4fvEXT(table, save_ProgramEnvParameters4fvEXT); - SET_ProgramLocalParameters4fvEXT(table, save_ProgramLocalParameters4fvEXT); - - /* 364. GL_EXT_provoking_vertex */ - SET_ProvokingVertex(table, save_ProvokingVertexEXT); - - /* GL_EXT_texture_integer */ - SET_ClearColorIiEXT(table, save_ClearColorIi); - SET_ClearColorIuiEXT(table, save_ClearColorIui); - SET_TexParameterIiv(table, save_TexParameterIiv); - SET_TexParameterIuiv(table, save_TexParameterIuiv); - - /* GL_ARB_clip_control */ - SET_ClipControl(table, save_ClipControl); - - /* GL_ARB_color_buffer_float */ - SET_ClampColor(table, save_ClampColorARB); - - /* GL 3.0 */ - SET_ClearBufferiv(table, save_ClearBufferiv); - SET_ClearBufferuiv(table, save_ClearBufferuiv); - SET_ClearBufferfv(table, save_ClearBufferfv); - SET_ClearBufferfi(table, save_ClearBufferfi); - SET_Uniform1ui(table, save_Uniform1ui); - SET_Uniform2ui(table, save_Uniform2ui); - SET_Uniform3ui(table, save_Uniform3ui); - SET_Uniform4ui(table, save_Uniform4ui); - SET_Uniform1uiv(table, save_Uniform1uiv); - SET_Uniform2uiv(table, save_Uniform2uiv); - SET_Uniform3uiv(table, save_Uniform3uiv); - SET_Uniform4uiv(table, save_Uniform4uiv); - - /* GL_ARB_gpu_shader_fp64 */ - SET_Uniform1d(table, save_Uniform1d); - SET_Uniform2d(table, save_Uniform2d); - SET_Uniform3d(table, save_Uniform3d); - SET_Uniform4d(table, save_Uniform4d); - SET_Uniform1dv(table, save_Uniform1dv); - SET_Uniform2dv(table, save_Uniform2dv); - SET_Uniform3dv(table, save_Uniform3dv); - SET_Uniform4dv(table, save_Uniform4dv); - SET_UniformMatrix2dv(table, save_UniformMatrix2dv); - SET_UniformMatrix3dv(table, save_UniformMatrix3dv); - SET_UniformMatrix4dv(table, save_UniformMatrix4dv); - SET_UniformMatrix2x3dv(table, save_UniformMatrix2x3dv); - SET_UniformMatrix3x2dv(table, save_UniformMatrix3x2dv); - SET_UniformMatrix2x4dv(table, save_UniformMatrix2x4dv); - SET_UniformMatrix4x2dv(table, save_UniformMatrix4x2dv); - SET_UniformMatrix3x4dv(table, save_UniformMatrix3x4dv); - SET_UniformMatrix4x3dv(table, save_UniformMatrix4x3dv); - - /* GL_ARB_gpu_shader_int64 */ - SET_Uniform1i64ARB(table, save_Uniform1i64ARB); - SET_Uniform2i64ARB(table, save_Uniform2i64ARB); - SET_Uniform3i64ARB(table, save_Uniform3i64ARB); - SET_Uniform4i64ARB(table, save_Uniform4i64ARB); - SET_Uniform1i64vARB(table, save_Uniform1i64vARB); - SET_Uniform2i64vARB(table, save_Uniform2i64vARB); - SET_Uniform3i64vARB(table, save_Uniform3i64vARB); - SET_Uniform4i64vARB(table, save_Uniform4i64vARB); - SET_Uniform1ui64ARB(table, save_Uniform1ui64ARB); - SET_Uniform2ui64ARB(table, save_Uniform2ui64ARB); - SET_Uniform3ui64ARB(table, save_Uniform3ui64ARB); - SET_Uniform4ui64ARB(table, save_Uniform4ui64ARB); - SET_Uniform1ui64vARB(table, save_Uniform1ui64vARB); - SET_Uniform2ui64vARB(table, save_Uniform2ui64vARB); - SET_Uniform3ui64vARB(table, save_Uniform3ui64vARB); - SET_Uniform4ui64vARB(table, save_Uniform4ui64vARB); - - SET_ProgramUniform1i64ARB(table, save_ProgramUniform1i64ARB); - SET_ProgramUniform2i64ARB(table, save_ProgramUniform2i64ARB); - SET_ProgramUniform3i64ARB(table, save_ProgramUniform3i64ARB); - SET_ProgramUniform4i64ARB(table, save_ProgramUniform4i64ARB); - SET_ProgramUniform1i64vARB(table, save_ProgramUniform1i64vARB); - SET_ProgramUniform2i64vARB(table, save_ProgramUniform2i64vARB); - SET_ProgramUniform3i64vARB(table, save_ProgramUniform3i64vARB); - SET_ProgramUniform4i64vARB(table, save_ProgramUniform4i64vARB); - SET_ProgramUniform1ui64ARB(table, save_ProgramUniform1ui64ARB); - SET_ProgramUniform2ui64ARB(table, save_ProgramUniform2ui64ARB); - SET_ProgramUniform3ui64ARB(table, save_ProgramUniform3ui64ARB); - SET_ProgramUniform4ui64ARB(table, save_ProgramUniform4ui64ARB); - SET_ProgramUniform1ui64vARB(table, save_ProgramUniform1ui64vARB); - SET_ProgramUniform2ui64vARB(table, save_ProgramUniform2ui64vARB); - SET_ProgramUniform3ui64vARB(table, save_ProgramUniform3ui64vARB); - SET_ProgramUniform4ui64vARB(table, save_ProgramUniform4ui64vARB); - - /* These are: */ - SET_BeginTransformFeedback(table, save_BeginTransformFeedback); - SET_EndTransformFeedback(table, save_EndTransformFeedback); - SET_BindTransformFeedback(table, save_BindTransformFeedback); - SET_PauseTransformFeedback(table, save_PauseTransformFeedback); - SET_ResumeTransformFeedback(table, save_ResumeTransformFeedback); - SET_DrawTransformFeedback(table, save_DrawTransformFeedback); - SET_DrawTransformFeedbackStream(table, save_DrawTransformFeedbackStream); - SET_DrawTransformFeedbackInstanced(table, - save_DrawTransformFeedbackInstanced); - SET_DrawTransformFeedbackStreamInstanced(table, - save_DrawTransformFeedbackStreamInstanced); - SET_BeginQueryIndexed(table, save_BeginQueryIndexed); - SET_EndQueryIndexed(table, save_EndQueryIndexed); - - /* GL_ARB_instanced_arrays */ - SET_VertexAttribDivisor(table, save_VertexAttribDivisor); - - /* GL_NV_texture_barrier */ - SET_TextureBarrierNV(table, save_TextureBarrierNV); - - SET_BindSampler(table, save_BindSampler); - SET_SamplerParameteri(table, save_SamplerParameteri); - SET_SamplerParameterf(table, save_SamplerParameterf); - SET_SamplerParameteriv(table, save_SamplerParameteriv); - SET_SamplerParameterfv(table, save_SamplerParameterfv); - SET_SamplerParameterIiv(table, save_SamplerParameterIiv); - SET_SamplerParameterIuiv(table, save_SamplerParameterIuiv); - - /* GL_ARB_draw_buffer_blend */ - SET_BlendFunciARB(table, save_BlendFunci); - SET_BlendFuncSeparateiARB(table, save_BlendFuncSeparatei); - SET_BlendEquationiARB(table, save_BlendEquationi); - SET_BlendEquationSeparateiARB(table, save_BlendEquationSeparatei); - - /* GL_NV_conditional_render */ - SET_BeginConditionalRender(table, save_BeginConditionalRender); - SET_EndConditionalRender(table, save_EndConditionalRender); - - /* GL_ARB_sync */ - SET_WaitSync(table, save_WaitSync); - - /* GL_ARB_uniform_buffer_object */ - SET_UniformBlockBinding(table, save_UniformBlockBinding); - - /* GL_ARB_shader_subroutines */ - SET_UniformSubroutinesuiv(table, save_UniformSubroutinesuiv); + memcpy(table, ctx->Dispatch.OutsideBeginEnd, + numEntries * sizeof(_glapi_proc)); - /* GL_ARB_draw_instanced */ - SET_DrawArraysInstancedARB(table, save_DrawArraysInstancedARB); - SET_DrawElementsInstancedARB(table, save_DrawElementsInstancedARB); - - /* GL_ARB_draw_elements_base_vertex */ - SET_DrawElementsInstancedBaseVertex(table, save_DrawElementsInstancedBaseVertexARB); - - /* GL_ARB_base_instance */ - SET_DrawArraysInstancedBaseInstance(table, save_DrawArraysInstancedBaseInstance); - SET_DrawElementsInstancedBaseInstance(table, save_DrawElementsInstancedBaseInstance); - SET_DrawElementsInstancedBaseVertexBaseInstance(table, save_DrawElementsInstancedBaseVertexBaseInstance); - - /* GL_ARB_draw_indirect / GL_ARB_multi_draw_indirect */ - SET_DrawArraysIndirect(table, save_DrawArraysIndirect); - SET_DrawElementsIndirect(table, save_DrawElementsIndirect); - SET_MultiDrawArraysIndirect(table, save_MultiDrawArraysIndirect); - SET_MultiDrawElementsIndirect(table, save_MultiDrawElementsIndirect); - - /* OpenGL 4.2 / GL_ARB_separate_shader_objects */ - SET_UseProgramStages(table, save_UseProgramStages); - SET_ProgramUniform1f(table, save_ProgramUniform1f); - SET_ProgramUniform2f(table, save_ProgramUniform2f); - SET_ProgramUniform3f(table, save_ProgramUniform3f); - SET_ProgramUniform4f(table, save_ProgramUniform4f); - SET_ProgramUniform1fv(table, save_ProgramUniform1fv); - SET_ProgramUniform2fv(table, save_ProgramUniform2fv); - SET_ProgramUniform3fv(table, save_ProgramUniform3fv); - SET_ProgramUniform4fv(table, save_ProgramUniform4fv); - SET_ProgramUniform1d(table, save_ProgramUniform1d); - SET_ProgramUniform2d(table, save_ProgramUniform2d); - SET_ProgramUniform3d(table, save_ProgramUniform3d); - SET_ProgramUniform4d(table, save_ProgramUniform4d); - SET_ProgramUniform1dv(table, save_ProgramUniform1dv); - SET_ProgramUniform2dv(table, save_ProgramUniform2dv); - SET_ProgramUniform3dv(table, save_ProgramUniform3dv); - SET_ProgramUniform4dv(table, save_ProgramUniform4dv); - SET_ProgramUniform1i(table, save_ProgramUniform1i); - SET_ProgramUniform2i(table, save_ProgramUniform2i); - SET_ProgramUniform3i(table, save_ProgramUniform3i); - SET_ProgramUniform4i(table, save_ProgramUniform4i); - SET_ProgramUniform1iv(table, save_ProgramUniform1iv); - SET_ProgramUniform2iv(table, save_ProgramUniform2iv); - SET_ProgramUniform3iv(table, save_ProgramUniform3iv); - SET_ProgramUniform4iv(table, save_ProgramUniform4iv); - SET_ProgramUniform1ui(table, save_ProgramUniform1ui); - SET_ProgramUniform2ui(table, save_ProgramUniform2ui); - SET_ProgramUniform3ui(table, save_ProgramUniform3ui); - SET_ProgramUniform4ui(table, save_ProgramUniform4ui); - SET_ProgramUniform1uiv(table, save_ProgramUniform1uiv); - SET_ProgramUniform2uiv(table, save_ProgramUniform2uiv); - SET_ProgramUniform3uiv(table, save_ProgramUniform3uiv); - SET_ProgramUniform4uiv(table, save_ProgramUniform4uiv); - SET_ProgramUniformMatrix2fv(table, save_ProgramUniformMatrix2fv); - SET_ProgramUniformMatrix3fv(table, save_ProgramUniformMatrix3fv); - SET_ProgramUniformMatrix4fv(table, save_ProgramUniformMatrix4fv); - SET_ProgramUniformMatrix2x3fv(table, save_ProgramUniformMatrix2x3fv); - SET_ProgramUniformMatrix3x2fv(table, save_ProgramUniformMatrix3x2fv); - SET_ProgramUniformMatrix2x4fv(table, save_ProgramUniformMatrix2x4fv); - SET_ProgramUniformMatrix4x2fv(table, save_ProgramUniformMatrix4x2fv); - SET_ProgramUniformMatrix3x4fv(table, save_ProgramUniformMatrix3x4fv); - SET_ProgramUniformMatrix4x3fv(table, save_ProgramUniformMatrix4x3fv); - SET_ProgramUniformMatrix2dv(table, save_ProgramUniformMatrix2dv); - SET_ProgramUniformMatrix3dv(table, save_ProgramUniformMatrix3dv); - SET_ProgramUniformMatrix4dv(table, save_ProgramUniformMatrix4dv); - SET_ProgramUniformMatrix2x3dv(table, save_ProgramUniformMatrix2x3dv); - SET_ProgramUniformMatrix3x2dv(table, save_ProgramUniformMatrix3x2dv); - SET_ProgramUniformMatrix2x4dv(table, save_ProgramUniformMatrix2x4dv); - SET_ProgramUniformMatrix4x2dv(table, save_ProgramUniformMatrix4x2dv); - SET_ProgramUniformMatrix3x4dv(table, save_ProgramUniformMatrix3x4dv); - SET_ProgramUniformMatrix4x3dv(table, save_ProgramUniformMatrix4x3dv); - - /* 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); - - /* GL_EXT_direct_state_access */ - SET_MatrixLoadfEXT(table, save_MatrixLoadfEXT); - SET_MatrixLoaddEXT(table, save_MatrixLoaddEXT); - SET_MatrixMultfEXT(table, save_MatrixMultfEXT); - SET_MatrixMultdEXT(table, save_MatrixMultdEXT); - SET_MatrixRotatefEXT(table, save_MatrixRotatefEXT); - SET_MatrixRotatedEXT(table, save_MatrixRotatedEXT); - SET_MatrixScalefEXT(table, save_MatrixScalefEXT); - SET_MatrixScaledEXT(table, save_MatrixScaledEXT); - SET_MatrixTranslatefEXT(table, save_MatrixTranslatefEXT); - SET_MatrixTranslatedEXT(table, save_MatrixTranslatedEXT); - SET_MatrixLoadIdentityEXT(table, save_MatrixLoadIdentityEXT); - SET_MatrixOrthoEXT(table, save_MatrixOrthoEXT); - SET_MatrixFrustumEXT(table, save_MatrixFrustumEXT); - SET_MatrixPushEXT(table, save_MatrixPushEXT); - SET_MatrixPopEXT(table, save_MatrixPopEXT); - SET_MatrixLoadTransposefEXT(table, save_MatrixLoadTransposefEXT); - SET_MatrixLoadTransposedEXT(table, save_MatrixLoadTransposedEXT); - SET_MatrixMultTransposefEXT(table, save_MatrixMultTransposefEXT); - SET_MatrixMultTransposedEXT(table, save_MatrixMultTransposedEXT); - SET_TextureParameteriEXT(table, save_TextureParameteriEXT); - SET_TextureParameterivEXT(table, save_TextureParameterivEXT); - SET_TextureParameterfEXT(table, save_TextureParameterfEXT); - SET_TextureParameterfvEXT(table, save_TextureParameterfvEXT); - SET_TextureParameterIivEXT(table, save_TextureParameterIivEXT); - SET_TextureParameterIuivEXT(table, save_TextureParameterIuivEXT); - SET_TextureImage1DEXT(table, save_TextureImage1DEXT); - SET_TextureImage2DEXT(table, save_TextureImage2DEXT); - SET_TextureImage3DEXT(table, save_TextureImage3DEXT); - SET_TextureSubImage1DEXT(table, save_TextureSubImage1DEXT); - SET_TextureSubImage2DEXT(table, save_TextureSubImage2DEXT); - SET_TextureSubImage3DEXT(table, save_TextureSubImage3DEXT); - SET_CopyTextureImage1DEXT(table, save_CopyTextureImage1DEXT); - SET_CopyTextureImage2DEXT(table, save_CopyTextureImage2DEXT); - SET_CopyTextureSubImage1DEXT(table, save_CopyTextureSubImage1DEXT); - SET_CopyTextureSubImage2DEXT(table, save_CopyTextureSubImage2DEXT); - SET_CopyTextureSubImage3DEXT(table, save_CopyTextureSubImage3DEXT); - SET_BindMultiTextureEXT(table, save_BindMultiTextureEXT); - SET_MultiTexParameteriEXT(table, save_MultiTexParameteriEXT); - SET_MultiTexParameterivEXT(table, save_MultiTexParameterivEXT); - SET_MultiTexParameterIivEXT(table, save_MultiTexParameterIivEXT); - SET_MultiTexParameterIuivEXT(table, save_MultiTexParameterIuivEXT); - SET_MultiTexParameterfEXT(table, save_MultiTexParameterfEXT); - SET_MultiTexParameterfvEXT(table, save_MultiTexParameterfvEXT); - SET_MultiTexImage1DEXT(table, save_MultiTexImage1DEXT); - SET_MultiTexImage2DEXT(table, save_MultiTexImage2DEXT); - SET_MultiTexImage3DEXT(table, save_MultiTexImage3DEXT); - SET_MultiTexSubImage1DEXT(table, save_MultiTexSubImage1DEXT); - SET_MultiTexSubImage2DEXT(table, save_MultiTexSubImage2DEXT); - SET_MultiTexSubImage3DEXT(table, save_MultiTexSubImage3DEXT); - SET_CopyMultiTexImage1DEXT(table, save_CopyMultiTexImage1DEXT); - SET_CopyMultiTexImage2DEXT(table, save_CopyMultiTexImage2DEXT); - SET_CopyMultiTexSubImage1DEXT(table, save_CopyMultiTexSubImage1DEXT); - SET_CopyMultiTexSubImage2DEXT(table, save_CopyMultiTexSubImage2DEXT); - SET_CopyMultiTexSubImage3DEXT(table, save_CopyMultiTexSubImage3DEXT); - SET_MultiTexEnvfEXT(table, save_MultiTexEnvfEXT); - SET_MultiTexEnvfvEXT(table, save_MultiTexEnvfvEXT); - SET_MultiTexEnviEXT(table, save_MultiTexEnviEXT); - SET_MultiTexEnvivEXT(table, save_MultiTexEnvivEXT); - SET_CompressedTextureImage1DEXT(table, save_CompressedTextureImage1DEXT); - SET_CompressedTextureImage2DEXT(table, save_CompressedTextureImage2DEXT); - SET_CompressedTextureImage3DEXT(table, save_CompressedTextureImage3DEXT); - SET_CompressedTextureSubImage1DEXT(table, save_CompressedTextureSubImage1DEXT); - SET_CompressedTextureSubImage2DEXT(table, save_CompressedTextureSubImage2DEXT); - SET_CompressedTextureSubImage3DEXT(table, save_CompressedTextureSubImage3DEXT); - SET_CompressedMultiTexImage1DEXT(table, save_CompressedMultiTexImage1DEXT); - SET_CompressedMultiTexImage2DEXT(table, save_CompressedMultiTexImage2DEXT); - SET_CompressedMultiTexImage3DEXT(table, save_CompressedMultiTexImage3DEXT); - SET_CompressedMultiTexSubImage1DEXT(table, save_CompressedMultiTexSubImage1DEXT); - SET_CompressedMultiTexSubImage2DEXT(table, save_CompressedMultiTexSubImage2DEXT); - SET_CompressedMultiTexSubImage3DEXT(table, save_CompressedMultiTexSubImage3DEXT); - SET_NamedProgramStringEXT(table, save_NamedProgramStringEXT); - SET_NamedProgramLocalParameter4dEXT(table, save_NamedProgramLocalParameter4dEXT); - SET_NamedProgramLocalParameter4dvEXT(table, save_NamedProgramLocalParameter4dvEXT); - SET_NamedProgramLocalParameter4fEXT(table, save_NamedProgramLocalParameter4fEXT); - SET_NamedProgramLocalParameter4fvEXT(table, save_NamedProgramLocalParameter4fvEXT); +#include "api_save_init.h" } @@ -14557,7 +13634,7 @@ enum_string(GLenum k) * TODO: many commands aren't handled yet. * \param fname filename to write display list to. If null, use stdout. */ -static void GLAPIENTRY +static void print_list(struct gl_context *ctx, GLuint list, const char *fname) { struct gl_display_list *dlist; @@ -14570,7 +13647,7 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) return; } - if (!_mesa_get_list(ctx, list, &dlist)) { + if (!_mesa_get_list(ctx, list, &dlist, true)) { fprintf(f, "%u is not a display list ID\n", list); fflush(f); if (fname) @@ -14578,7 +13655,7 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) return; } - n = dlist->Head; + n = get_list_head(ctx, dlist); fprintf(f, "START-LIST %u, address %p\n", list, (void *) n); @@ -14826,11 +13903,10 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) fprintf(f, "DISPLAY-LIST-CONTINUE\n"); n = (Node *) get_pointer(&n[1]); continue; - case OPCODE_NOP: - fprintf(f, "NOP\n"); - break; case OPCODE_VERTEX_LIST: - vbo_print_vertex_list(ctx, (struct vbo_save_vertex_list *) &n[1], f); + case OPCODE_VERTEX_LIST_LOOPBACK: + case OPCODE_VERTEX_LIST_COPY_CURRENT: + vbo_print_vertex_list(ctx, (struct vbo_save_vertex_list *) &n[0], opcode, f); break; default: if (opcode < 0 || opcode > OPCODE_END_OF_LIST) { @@ -14839,7 +13915,7 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) opcode, (void *) n); } else { fprintf(f, "command %d, %u operands\n", opcode, - InstSize[opcode]); + n[0].InstSize); break; } FALLTHROUGH; @@ -14852,8 +13928,8 @@ print_list(struct gl_context *ctx, GLuint list, const char *fname) } /* increment n to point to next compiled command */ - assert(InstSize[opcode] > 0); - n += InstSize[opcode]; + assert(n[0].InstSize > 0); + n += n[0].InstSize; } } @@ -14864,13 +13940,11 @@ _mesa_glthread_execute_list(struct gl_context *ctx, GLuint list) struct gl_display_list *dlist; if (list == 0 || - ctx->GLThread.ListCallDepth == MAX_LIST_NESTING || - !_mesa_get_list(ctx, list, &dlist)) + !_mesa_get_list(ctx, list, &dlist, true) || + !dlist->execute_glthread) return; - ctx->GLThread.ListCallDepth++; - - Node *n = dlist->Head; + Node *n = get_list_head(ctx, dlist); while (1) { const OpCode opcode = n[0].opcode; @@ -14878,12 +13952,18 @@ _mesa_glthread_execute_list(struct gl_context *ctx, GLuint list) switch (opcode) { case OPCODE_CALL_LIST: /* Generated by glCallList(), don't add ListBase */ - if (ctx->GLThread.ListCallDepth < MAX_LIST_NESTING) + if (ctx->GLThread.ListCallDepth < MAX_LIST_NESTING) { + ctx->GLThread.ListCallDepth++; _mesa_glthread_execute_list(ctx, n[1].ui); + ctx->GLThread.ListCallDepth--; + } break; case OPCODE_CALL_LISTS: - if (ctx->GLThread.ListCallDepth < MAX_LIST_NESTING) + if (ctx->GLThread.ListCallDepth < MAX_LIST_NESTING) { + ctx->GLThread.ListCallDepth++; _mesa_glthread_CallLists(ctx, n[1].i, n[2].e, get_pointer(&n[3])); + ctx->GLThread.ListCallDepth--; + } break; case OPCODE_DISABLE: _mesa_glthread_Disable(ctx, n[1].e); @@ -14930,11 +14010,52 @@ _mesa_glthread_execute_list(struct gl_context *ctx, GLuint list) } /* increment n to point to next compiled command */ - assert(InstSize[opcode] > 0); - n += InstSize[opcode]; + assert(n[0].InstSize > 0); + n += n[0].InstSize; } } +static bool +_mesa_glthread_should_execute_list(struct gl_context *ctx, + struct gl_display_list *dlist) +{ + Node *n = get_list_head(ctx, dlist); + + while (1) { + const OpCode opcode = n[0].opcode; + + switch (opcode) { + case OPCODE_CALL_LIST: + case OPCODE_CALL_LISTS: + case OPCODE_DISABLE: + case OPCODE_ENABLE: + case OPCODE_LIST_BASE: + case OPCODE_MATRIX_MODE: + case OPCODE_POP_ATTRIB: + case OPCODE_POP_MATRIX: + case OPCODE_PUSH_ATTRIB: + case OPCODE_PUSH_MATRIX: + case OPCODE_ACTIVE_TEXTURE: /* GL_ARB_multitexture */ + case OPCODE_MATRIX_PUSH: + case OPCODE_MATRIX_POP: + return true; + case OPCODE_CONTINUE: + n = (Node *)get_pointer(&n[1]); + continue; + case OPCODE_END_OF_LIST: + return false; + default: + /* ignore */ + break; + } + + /* increment n to point to next compiled command */ + assert(n[0].InstSize > 0); + n += n[0].InstSize; + } + return false; +} + /** * Clients may call this function to help debug display list problems. @@ -14953,47 +14074,35 @@ mesa_print_display_list(GLuint list) /***** Initialization *****/ /**********************************************************************/ -void -_mesa_install_dlist_vtxfmt(struct _glapi_table *disp, - const GLvertexformat *vfmt) -{ - SET_CallList(disp, vfmt->CallList); - SET_CallLists(disp, vfmt->CallLists); -} - - /** * Initialize display list state for given context. */ void _mesa_init_display_list(struct gl_context *ctx) { - static GLboolean tableInitialized = GL_FALSE; - GLvertexformat *vfmt = &ctx->ListState.ListVtxfmt; - - /* zero-out the instruction size table, just once */ - if (!tableInitialized) { - memset(InstSize, 0, sizeof(InstSize)); - tableInitialized = GL_TRUE; - } - /* Display list */ - ctx->ListState.CallDepth = 0; + ctx->ListState.CallDepth = 1; ctx->ExecuteFlag = GL_TRUE; ctx->CompileFlag = GL_FALSE; ctx->ListState.CurrentBlock = NULL; ctx->ListState.CurrentPos = 0; + ctx->ListState.LastInstSize = 0; /* Display List group */ ctx->List.ListBase = 0; +} + - InstSize[OPCODE_NOP] = 1; - InstSize[OPCODE_VERTEX_LIST] = 1 + align(sizeof(struct vbo_save_vertex_list), sizeof(Node)) / sizeof(Node); +void +_mesa_init_dispatch_save_begin_end(struct gl_context *ctx) +{ + struct _glapi_table *tab = ctx->Dispatch.Save; + assert(_mesa_is_desktop_gl_compat(ctx)); -#define NAME_AE(x) _ae_##x +#define NAME_AE(x) _mesa_##x #define NAME_CALLLIST(x) save_##x #define NAME(x) save_##x -#define NAME_ES(x) save_##x##ARB +#define NAME_ES(x) save_##x -#include "vbo/vbo_init_tmp.h" + #include "api_beginend_init.h" } diff --git a/src/mesa/main/dlist.h b/src/mesa/main/dlist.h index 52aa9a3da7a..8af3b8196e8 100644 --- a/src/mesa/main/dlist.h +++ b/src/mesa/main/dlist.h @@ -37,98 +37,63 @@ struct gl_context; /** - * Describes the location and size of a glBitmap image in a texture atlas. - */ -struct gl_bitmap_glyph -{ - unsigned short x, y, w, h; /**< position and size in the texture */ - float xorig, yorig; /**< bitmap origin */ - float xmove, ymove; /**< rasterpos move */ -}; - - -/** - * Describes a set of glBitmap display lists which live in a texture atlas. - * The idea is when we see a code sequence of glListBase(b), glCallLists(n) - * we're probably drawing bitmap font glyphs. We try to put all the bitmap - * glyphs into one texture map then render the glCallLists as a textured - * quadstrip. + * Display list node. + * + * Display list instructions are stored as sequences of "nodes". Nodes + * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks + * are linked together with a pointer. + * + * Each instruction in the display list is stored as a sequence of + * contiguous nodes in memory. + * Each node is the union of a variety of data types. + * + * Note, all of these members should be 4 bytes in size or less for the + * sake of compact display lists. We store 8-byte pointers in a pair of + * these nodes using the save/get_pointer() functions below. */ -struct gl_bitmap_atlas +union gl_dlist_node { - GLint Id; - bool complete; /**< Is the atlas ready to use? */ - bool incomplete; /**< Did we fail to construct this atlas? */ - - unsigned numBitmaps; - unsigned texWidth, texHeight; - struct gl_texture_object *texObj; - struct gl_texture_image *texImage; - - unsigned glyphHeight; - - struct gl_bitmap_glyph *glyphs; + struct { + uint16_t opcode; /* dlist.c : enum Opcode */ + uint16_t InstSize; + }; + GLboolean b; + GLbitfield bf; + GLubyte ub; + GLshort s; + GLushort us; + GLint i; + GLuint ui; + GLenum e; + GLfloat f; + GLsizei si; }; -void -_mesa_delete_bitmap_atlas(struct gl_context *ctx, - struct gl_bitmap_atlas *atlas); - - -GLboolean GLAPIENTRY -_mesa_IsList(GLuint list); - -void GLAPIENTRY -_mesa_DeleteLists(GLuint list, GLsizei range); - -GLuint GLAPIENTRY -_mesa_GenLists(GLsizei range); - -void GLAPIENTRY -_mesa_NewList(GLuint name, GLenum mode); - -void GLAPIENTRY -_mesa_EndList(void); - -void GLAPIENTRY -_mesa_CallList(GLuint list); - -void GLAPIENTRY -_mesa_CallLists(GLsizei n, GLenum type, const GLvoid *lists); - -void GLAPIENTRY -_mesa_ListBase(GLuint base); - struct gl_display_list * -_mesa_lookup_list(struct gl_context *ctx, GLuint list); +_mesa_lookup_list(struct gl_context *ctx, GLuint list, bool locked); void _mesa_compile_error(struct gl_context *ctx, GLenum error, const char *s); void * -_mesa_dlist_alloc(struct gl_context *ctx, GLuint opcode, GLuint sz); - -void * -_mesa_dlist_alloc_aligned(struct gl_context *ctx, GLuint opcode, GLuint bytes); - -void * -_mesa_dlist_alloc_vertex_list(struct gl_context *ctx); +_mesa_dlist_alloc_vertex_list(struct gl_context *ctx, + bool copy_to_current); void _mesa_delete_list(struct gl_context *ctx, struct gl_display_list *dlist); void -_mesa_initialize_save_table(const struct gl_context *); +_mesa_init_dispatch_save(const struct gl_context *); void -_mesa_install_dlist_vtxfmt(struct _glapi_table *disp, - const GLvertexformat *vfmt); +_mesa_init_display_list(struct gl_context * ctx); void -_mesa_init_display_list(struct gl_context * ctx); +_mesa_init_dispatch_save_begin_end(struct gl_context *ctx); bool _mesa_get_list(struct gl_context *ctx, GLuint list, - struct gl_display_list **dlist); + struct gl_display_list **dlist, + bool locked); #endif /* DLIST_H */ diff --git a/src/mesa/main/draw.c b/src/mesa/main/draw.c index 241e63bc0b7..848c9bf1aa4 100644 --- a/src/mesa/main/draw.c +++ b/src/mesa/main/draw.c @@ -28,7 +28,7 @@ #include <stdio.h> #include "arrayobj.h" -#include "glheader.h" +#include "util/glheader.h" #include "c99_alloca.h" #include "context.h" #include "state.h" @@ -41,6 +41,14 @@ #include "macros.h" #include "transformfeedback.h" #include "pipe/p_state.h" +#include "api_exec_decl.h" +#include "glthread_marshal.h" + +#include "cso_cache/cso_context.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_draw.h" +#include "util/u_draw.h" +#include "util/u_threaded_context.h" typedef struct { GLuint count; @@ -100,41 +108,68 @@ _mesa_set_varying_vp_inputs(struct gl_context *ctx, GLbitfield varying_inputs) * enabled arrays when a fixed function array draw is executed. */ void -_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao, - GLbitfield filter) +_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao) { struct gl_vertex_array_object **ptr = &ctx->Array._DrawVAO; - bool new_array = false; + if (*ptr != vao) { _mesa_reference_vao_(ctx, ptr, vao); - - new_array = true; + _mesa_update_edgeflag_state_vao(ctx); + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; } +} - if (vao->NewArrays) { - _mesa_update_vao_derived_arrays(ctx, vao); - vao->NewArrays = 0; - - new_array = true; - } +/** + * Other than setting the new VAO, this returns a VAO reference to + * the previously-bound VAO and the previous _VPModeInputFilter value through + * parameters. The caller must call _mesa_restore_draw_vao to ensure + * reference counting is done properly and the affected states are restored. + * + * \param ctx GL context + * \param vao VAO to set. + * \param vp_input_filter Mask of enabled vertex attribs. + * Possible values that can also be OR'd with each other: + * - VERT_BIT_FF_ALL + * - VERT_BIT_MAT_ALL + * - VERT_BIT_ALL + * - VERT_BIT_SELECT_RESULT_OFFSET + * \param old_vao Previous bound VAO. + * \param old_vp_input_filter Previous value of vp_input_filter. + */ +void +_mesa_save_and_set_draw_vao(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + GLbitfield vp_input_filter, + struct gl_vertex_array_object **old_vao, + GLbitfield *old_vp_input_filter) +{ + *old_vao = ctx->Array._DrawVAO; + *old_vp_input_filter = ctx->VertexProgram._VPModeInputFilter; - assert(vao->_EnabledWithMapMode == - _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled)); + ctx->Array._DrawVAO = NULL; + ctx->VertexProgram._VPModeInputFilter = vp_input_filter; + _mesa_set_draw_vao(ctx, vao); +} - /* Filter out unwanted arrays. */ - const GLbitfield enabled = filter & vao->_EnabledWithMapMode; - if (ctx->Array._DrawVAOEnabledAttribs != enabled) { - ctx->Array._DrawVAOEnabledAttribs = enabled; - new_array = true; - } +void +_mesa_restore_draw_vao(struct gl_context *ctx, + struct gl_vertex_array_object *saved, + GLbitfield saved_vp_input_filter) +{ + /* Restore states. */ + _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, NULL); + ctx->Array._DrawVAO = saved; + ctx->VertexProgram._VPModeInputFilter = saved_vp_input_filter; - if (new_array) - ctx->NewDriverState |= ctx->DriverFlags.NewArray; + /* Update states. */ + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; - _mesa_set_varying_vp_inputs(ctx, enabled); + /* Restore original states. */ + _mesa_update_edgeflag_state_vao(ctx); } - /** * Is 'mode' a valid value for glBegin(), glDrawArrays(), glDrawElements(), * etc? Also, do additional checking related to transformation feedback. @@ -146,10 +181,10 @@ static GLenum valid_prim_mode_custom(struct gl_context *ctx, GLenum mode, GLbitfield valid_prim_mask) { -#if DEBUG - unsigned mask = ctx->ValidPrimMask; - unsigned mask_indexed = ctx->ValidPrimMaskIndexed; - bool drawpix_valid = ctx->DrawPixValid; +#if MESA_DEBUG + ASSERTED unsigned mask = ctx->ValidPrimMask; + ASSERTED unsigned mask_indexed = ctx->ValidPrimMaskIndexed; + ASSERTED bool drawpix_valid = ctx->DrawPixValid; _mesa_update_valid_to_render_state(ctx); assert(mask == ctx->ValidPrimMask && mask_indexed == ctx->ValidPrimMaskIndexed && @@ -188,24 +223,28 @@ valid_prim_mode_indexed(struct gl_context *ctx, GLenum mode) static GLenum valid_elements_type(struct gl_context *ctx, GLenum type) { - /* GL_UNSIGNED_BYTE = 0x1401 - * GL_UNSIGNED_SHORT = 0x1403 - * GL_UNSIGNED_INT = 0x1405 + return _mesa_is_index_type_valid(type) ? GL_NO_ERROR : GL_INVALID_ENUM; +} + +static inline bool +indices_aligned(unsigned index_size_shift, const GLvoid *indices) +{ + /* Require that indices are aligned to the element size. GL doesn't specify + * an error for this, but the ES 3.0 spec says: + * + * "Clients must align data elements consistently with the requirements + * of the client platform, with an additional base-level requirement + * that an offset within a buffer to a datum comprising N basic machine + * units be a multiple of N" * - * The trick is that bit 1 and bit 2 mean USHORT and UINT, respectively. - * After clearing those two bits (with ~6), we should get UBYTE. - * Both bits can't be set, because the enum would be greater than UINT. + * This is only required by index buffers, not user indices. */ - if (!(type <= GL_UNSIGNED_INT && (type & ~6) == GL_UNSIGNED_BYTE)) - return GL_INVALID_ENUM; - - return GL_NO_ERROR; + return ((uintptr_t)indices & ((1 << index_size_shift) - 1)) == 0; } static GLenum validate_DrawElements_common(struct gl_context *ctx, GLenum mode, - GLsizei count, GLsizei numInstances, GLenum type, - const GLvoid *indices) + GLsizei count, GLsizei numInstances, GLenum type) { if (count < 0 || numInstances < 0) return GL_INVALID_VALUE; @@ -224,11 +263,9 @@ validate_DrawElements_common(struct gl_context *ctx, GLenum mode, */ static GLboolean _mesa_validate_DrawElements(struct gl_context *ctx, - GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices) + GLenum mode, GLsizei count, GLenum type) { - GLenum error = validate_DrawElements_common(ctx, mode, count, 1, type, - indices); + GLenum error = validate_DrawElements_common(ctx, mode, count, 1, type); if (error) _mesa_error(ctx, error, "glDrawElements"); @@ -245,7 +282,8 @@ static GLboolean _mesa_validate_MultiDrawElements(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid * const *indices, - GLsizei primcount) + GLsizei primcount, + struct gl_buffer_object *index_bo) { GLenum error; @@ -287,7 +325,7 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx, /* Not using a VBO for indices, so avoid NULL pointer derefs later. */ - if (!ctx->Array.VAO->IndexBufferObj) { + if (!index_bo) { for (int i = 0; i < primcount; i++) { if (!indices[i]) return GL_FALSE; @@ -306,15 +344,14 @@ _mesa_validate_MultiDrawElements(struct gl_context *ctx, static GLboolean _mesa_validate_DrawRangeElements(struct gl_context *ctx, GLenum mode, GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices) + GLsizei count, GLenum type) { GLenum error; if (end < start) { error = GL_INVALID_VALUE; } else { - error = validate_DrawElements_common(ctx, mode, count, 1, type, indices); + error = validate_DrawElements_common(ctx, mode, count, 1, type); } if (error) @@ -460,9 +497,6 @@ _mesa_validate_DrawArrays(struct gl_context *ctx, GLenum mode, GLsizei count) if (error) _mesa_error(ctx, error, "glDrawArrays"); - if (count == 0) - return false; - return !error; } @@ -542,11 +576,10 @@ _mesa_validate_MultiDrawArrays(struct gl_context *ctx, GLenum mode, static GLboolean _mesa_validate_DrawElementsInstanced(struct gl_context *ctx, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei numInstances) + GLsizei numInstances) { GLenum error = - validate_DrawElements_common(ctx, mode, count, numInstances, type, - indices); + validate_DrawElements_common(ctx, mode, count, numInstances, type); if (error) _mesa_error(ctx, error, "glDrawElementsInstanced"); @@ -907,183 +940,26 @@ _mesa_validate_MultiDrawElementsIndirectCount(struct gl_context *ctx, return !error; } +static inline struct pipe_draw_start_count_bias * +get_temp_draws(struct gl_context *ctx, unsigned primcount) +{ + if (primcount > ctx->num_tmp_draws) { + struct pipe_draw_start_count_bias *tmp = + realloc(ctx->tmp_draws, primcount * sizeof(ctx->tmp_draws[0])); -#define MAX_ALLOCA_PRIMS(prim) (50000 / sizeof(*prim)) - -/* Use calloc for large allocations and alloca for small allocations. */ -/* We have to use a macro because alloca is local within the function. */ -#define ALLOC_PRIMS(prim, primcount, func) do { \ - if (unlikely(primcount > MAX_ALLOCA_PRIMS(prim))) { \ - prim = calloc(primcount, sizeof(*prim)); \ - if (!prim) { \ - _mesa_error(ctx, GL_OUT_OF_MEMORY, func); \ - return; \ - } \ - } else { \ - prim = alloca(primcount * sizeof(*prim)); \ - } \ -} while (0) - -#define FREE_PRIMS(prim, primcount) do { \ - if (primcount > MAX_ALLOCA_PRIMS(prim)) \ - free(prim); \ -} while (0) - - -/** - * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw. - */ -void -_mesa_draw_gallium_fallback(struct gl_context *ctx, - struct pipe_draw_info *info, - unsigned drawid_offset, - const struct pipe_draw_start_count_bias *draws, - unsigned num_draws) -{ - struct _mesa_index_buffer ib; - unsigned index_size = info->index_size; - unsigned min_index = 0, max_index = ~0u; - bool index_bounds_valid = false; - - if (!info->instance_count) - return; - - if (index_size) { - if (info->index_bounds_valid) { - min_index = info->min_index; - max_index = info->max_index; - index_bounds_valid = true; - } - } else { - /* The index_bounds_valid field and min/max_index are not used for - * non-indexed draw calls (they are undefined), but classic drivers - * need the index bounds. They will be computed manually. - */ - index_bounds_valid = true; - } - - ib.index_size_shift = util_logbase2(index_size); - - /* Single draw or a fallback for user indices. */ - if (num_draws == 1 || - (info->index_size && info->has_user_indices && - !ctx->Const.MultiDrawWithUserIndices)) { - for (unsigned i = 0; i < num_draws; i++) { - if (!draws[i].count) - continue; - - if (index_size) { - ib.count = draws[i].count; - - if (info->has_user_indices) { - ib.obj = NULL; - /* User indices require start to be added here if - * Const.MultiDrawWithUserIndices is false. - */ - ib.ptr = (const char*)info->index.user + - draws[i].start * index_size; - } else { - ib.obj = info->index.gl_bo; - ib.ptr = NULL; - } - } - - struct _mesa_prim prim; - prim.mode = info->mode; - prim.begin = 1; - prim.end = 1; - prim.start = index_size && info->has_user_indices ? 0 : draws[i].start; - prim.count = draws[i].count; - prim.basevertex = index_size ? draws[i].index_bias : 0; - prim.draw_id = drawid_offset + (info->increment_draw_id ? i : 0); - - if (!index_size) { - min_index = draws[i].start; - max_index = draws[i].start + draws[i].count - 1; - } - - ctx->Driver.Draw(ctx, &prim, 1, index_size ? &ib : NULL, - index_bounds_valid, info->primitive_restart, - info->restart_index, min_index, max_index, - info->instance_count, info->start_instance); - } - return; - } - - struct _mesa_prim *prim; - unsigned max_count = 0; - unsigned num_prims = 0; - - ALLOC_PRIMS(prim, num_draws, "DrawGallium"); - - min_index = ~0u; - max_index = 0; - - for (unsigned i = 0; i < num_draws; i++) { - if (!draws[i].count) - continue; - - prim[num_prims].mode = info->mode; - prim[num_prims].begin = 1; - prim[num_prims].end = 1; - prim[num_prims].start = draws[i].start; - prim[num_prims].count = draws[i].count; - prim[num_prims].basevertex = info->index_size ? draws[i].index_bias : 0; - prim[num_prims].draw_id = drawid_offset + (info->increment_draw_id ? i : 0); - - if (!index_size) { - min_index = MIN2(min_index, draws[i].start); - max_index = MAX2(max_index, draws[i].start + draws[i].count - 1); - } - - max_count = MAX2(max_count, prim[num_prims].count); - num_prims++; - } - - if (info->index_size) { - ib.count = max_count; - ib.index_size_shift = util_logbase2(index_size); - - if (info->has_user_indices) { - ib.obj = NULL; - ib.ptr = (const char*)info->index.user; + if (tmp) { + ctx->tmp_draws = tmp; + ctx->num_tmp_draws = primcount; } else { - ib.obj = info->index.gl_bo; - ib.ptr = NULL; + _mesa_error(ctx, GL_OUT_OF_MEMORY, "can't alloc tmp_draws"); + free(ctx->tmp_draws); /* realloc doesn't free on failure */ + ctx->tmp_draws = NULL; + ctx->num_tmp_draws = 0; } } - - ctx->Driver.Draw(ctx, prim, num_prims, index_size ? &ib : NULL, - index_bounds_valid, info->primitive_restart, - info->restart_index, min_index, max_index, - info->instance_count, info->start_instance); - FREE_PRIMS(prim, num_draws); + return ctx->tmp_draws; } - -/** - * Called via Driver.DrawGallium. This is a fallback invoking Driver.Draw. - */ -void -_mesa_draw_gallium_multimode_fallback(struct gl_context *ctx, - struct pipe_draw_info *info, - unsigned drawid_offset, - const struct pipe_draw_start_count_bias *draws, - const unsigned char *mode, - unsigned num_draws) -{ - unsigned i, first; - - /* Find consecutive draws where mode and base_vertex don't vary. */ - for (i = 0, first = 0; i <= num_draws; i++) { - if (i == num_draws || mode[i] != mode[first]) { - info->mode = mode[first]; - ctx->Driver.DrawGallium(ctx, info, drawid_offset, &draws[first], i - first); - first = i; - } - } -} - /** * Check that element 'j' of the array has reasonable data. * Map VBO if needed. @@ -1103,18 +979,18 @@ check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, data = ADD_POINTERS(_mesa_vertex_attrib_address(array, binding), bo->Mappings[MAP_INTERNAL].Pointer); } - switch (array->Format.Type) { + switch (array->Format.User.Type) { case GL_FLOAT: { GLfloat *f = (GLfloat *) ((GLubyte *) data + binding->Stride * j); GLint k; - for (k = 0; k < array->Format.Size; k++) { + for (k = 0; k < array->Format.User.Size; k++) { if (util_is_inf_or_nan(f[k]) || f[k] >= 1.0e20F || f[k] <= -1.0e10F) { printf("Bad array data:\n"); printf(" Element[%u].%u = %f\n", j, k, f[k]); printf(" Array %u at %p\n", attrib, (void *) array); printf(" Type 0x%x, Size %d, Stride %d\n", - array->Format.Type, array->Format.Size, + array->Format.User.Type, array->Format.User.Size, binding->Stride); printf(" Address/offset %p in Buffer Object %u\n", array->Ptr, bo ? bo->Name : 0); @@ -1131,20 +1007,6 @@ check_array_data(struct gl_context *ctx, struct gl_vertex_array_object *vao, } -static inline unsigned -get_index_size_shift(GLenum type) -{ - /* The type is already validated, so use a fast conversion. - * - * GL_UNSIGNED_BYTE - GL_UNSIGNED_BYTE = 0 - * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2 - * GL_UNSIGNED_INT - GL_UNSIGNED_BYTE = 4 - * - * Divide by 2 to get 0,1,2. - */ - return (type - GL_UNSIGNED_BYTE) >> 1; -} - /** * Examine the array's data for NaNs, etc. * For debug purposes; not normally used. @@ -1228,7 +1090,7 @@ print_draw_arrays(struct gl_context *ctx, printf("attr %s: size %d stride %d " "ptr %p Bufobj %u\n", gl_vert_attrib_name((gl_vert_attrib) i), - array->Format.Size, binding->Stride, + array->Format.User.Size, binding->Stride, array->Ptr, bufObj ? bufObj->Name : 0); if (bufObj) { @@ -1237,7 +1099,7 @@ print_draw_arrays(struct gl_context *ctx, _mesa_vertex_attrib_address(array, binding); unsigned multiplier; - switch (array->Format.Type) { + switch (array->Format.User.Type) { case GL_DOUBLE: case GL_INT64_ARB: case GL_UNSIGNED_INT64_ARB: @@ -1251,7 +1113,7 @@ print_draw_arrays(struct gl_context *ctx, int *k = (int *) f; int i = 0; int n = (count - 1) * (binding->Stride / (4 * multiplier)) - + array->Format.Size; + + array->Format.User.Size; if (n > 32) n = 32; printf(" Data at offset %d:\n", offset); @@ -1280,6 +1142,12 @@ static void _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, GLsizei count, GLuint numInstances, GLuint baseInstance) { + /* Viewperf has many draws with count=0. Discarding them is faster than + * processing them. + */ + if (!count || !numInstances) + return; + /* OpenGL 4.5 says that primitive restart is ignored with non-indexed * draws. */ @@ -1287,13 +1155,13 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, struct pipe_draw_start_count_bias draw; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 0; /* Packed section begin. */ info.primitive_restart = false; info.has_user_indices = false; info.index_bounds_valid = true; info.increment_draw_id = false; + info.was_line_loop = false; info.take_index_buffer_ownership = false; info.index_bias_varies = false; /* Packed section end. */ @@ -1306,7 +1174,9 @@ _mesa_draw_arrays(struct gl_context *ctx, GLenum mode, GLint start, draw.start = start; draw.count = count; - ctx->Driver.DrawGallium(ctx, &info, 0, &draw, 1); + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + + ctx->Driver.DrawGallium(ctx, &info, ctx->DrawID, NULL, &draw, 1); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); @@ -1323,9 +1193,9 @@ _mesa_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2) GET_CURRENT_CONTEXT(ctx); ASSERT_OUTSIDE_BEGIN_END(ctx); - CALL_Begin(ctx->CurrentServerDispatch, (GL_QUADS)); - /* Begin can change CurrentServerDispatch. */ - struct _glapi_table *dispatch = ctx->CurrentServerDispatch; + CALL_Begin(ctx->Dispatch.Current, (GL_QUADS)); + /* Begin can change Dispatch.Current. */ + struct _glapi_table *dispatch = ctx->Dispatch.Current; CALL_Vertex2f(dispatch, (x1, y1)); CALL_Vertex2f(dispatch, (x2, y1)); CALL_Vertex2f(dispatch, (x2, y2)); @@ -1406,9 +1276,9 @@ _mesa_EvalMesh1(GLenum mode, GLint i1, GLint i2) u = ctx->Eval.MapGrid1u1 + i1 * du; - CALL_Begin(ctx->CurrentServerDispatch, (prim)); - /* Begin can change CurrentServerDispatch. */ - struct _glapi_table *dispatch = ctx->CurrentServerDispatch; + CALL_Begin(ctx->Dispatch.Current, (prim)); + /* Begin can change Dispatch.Current. */ + struct _glapi_table *dispatch = ctx->Dispatch.Current; for (i = i1; i <= i2; i++, u += du) { CALL_EvalCoord1f(dispatch, (u)); } @@ -1447,9 +1317,9 @@ _mesa_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) switch (mode) { case GL_POINT: - CALL_Begin(ctx->CurrentServerDispatch, (GL_POINTS)); - /* Begin can change CurrentServerDispatch. */ - dispatch = ctx->CurrentServerDispatch; + CALL_Begin(ctx->Dispatch.Current, (GL_POINTS)); + /* Begin can change Dispatch.Current. */ + dispatch = ctx->Dispatch.Current; for (v = v1, j = j1; j <= j2; j++, v += dv) { for (u = u1, i = i1; i <= i2; i++, u += du) { CALL_EvalCoord2f(dispatch, (u, v)); @@ -1459,18 +1329,18 @@ _mesa_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) break; case GL_LINE: for (v = v1, j = j1; j <= j2; j++, v += dv) { - CALL_Begin(ctx->CurrentServerDispatch, (GL_LINE_STRIP)); - /* Begin can change CurrentServerDispatch. */ - dispatch = ctx->CurrentServerDispatch; + CALL_Begin(ctx->Dispatch.Current, (GL_LINE_STRIP)); + /* Begin can change Dispatch.Current. */ + dispatch = ctx->Dispatch.Current; for (u = u1, i = i1; i <= i2; i++, u += du) { CALL_EvalCoord2f(dispatch, (u, v)); } CALL_End(dispatch, ()); } for (u = u1, i = i1; i <= i2; i++, u += du) { - CALL_Begin(ctx->CurrentServerDispatch, (GL_LINE_STRIP)); - /* Begin can change CurrentServerDispatch. */ - dispatch = ctx->CurrentServerDispatch; + CALL_Begin(ctx->Dispatch.Current, (GL_LINE_STRIP)); + /* Begin can change Dispatch.Current. */ + dispatch = ctx->Dispatch.Current; for (v = v1, j = j1; j <= j2; j++, v += dv) { CALL_EvalCoord2f(dispatch, (u, v)); } @@ -1479,9 +1349,9 @@ _mesa_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2) break; case GL_FILL: for (v = v1, j = j1; j < j2; j++, v += dv) { - CALL_Begin(ctx->CurrentServerDispatch, (GL_TRIANGLE_STRIP)); - /* Begin can change CurrentServerDispatch. */ - dispatch = ctx->CurrentServerDispatch; + CALL_Begin(ctx->Dispatch.Current, (GL_TRIANGLE_STRIP)); + /* Begin can change Dispatch.Current. */ + dispatch = ctx->Dispatch.Current; for (u = u1, i = i1; i <= i2; i++, u += du) { CALL_EvalCoord2f(dispatch, (u, v)); CALL_EvalCoord2f(dispatch, (u, v + dv)); @@ -1502,9 +1372,8 @@ _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -1527,30 +1396,10 @@ _mesa_DrawArrays(GLenum mode, GLint start, GLsizei count) * display list mode). */ void GLAPIENTRY -_mesa_DrawArraysInstancedARB(GLenum mode, GLint start, GLsizei count, - GLsizei numInstances) +_mesa_DrawArraysInstanced(GLenum mode, GLint start, GLsizei count, + GLsizei numInstances) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_FOR_DRAW(ctx); - - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawArraysInstanced(ctx, mode, start, count, - numInstances)) - return; - - if (0) - check_draw_arrays_data(ctx, start, count); - - _mesa_draw_arrays(ctx, mode, start, count, numInstances, 0); - - if (0) - print_draw_arrays(ctx, mode, start, count); + _mesa_DrawArraysInstancedBaseInstance(mode, start, count, numInstances, 0); } @@ -1565,9 +1414,8 @@ _mesa_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -1596,9 +1444,8 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first, GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -1610,18 +1457,18 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first, return; struct pipe_draw_info info; - struct pipe_draw_start_count_bias *draw; - - ALLOC_PRIMS(draw, primcount, "glMultiDrawElements"); + struct pipe_draw_start_count_bias *draw = get_temp_draws(ctx, primcount); + if (!draw) + return; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 0; /* Packed section begin. */ info.primitive_restart = false; info.has_user_indices = false; info.index_bounds_valid = false; info.increment_draw_id = primcount > 1; + info.was_line_loop = false; info.take_index_buffer_ownership = false; info.index_bias_varies = false; /* Packed section end. */ @@ -1634,12 +1481,12 @@ _mesa_MultiDrawArrays(GLenum mode, const GLint *first, draw[i].count = count[i]; } - ctx->Driver.DrawGallium(ctx, &info, 0, draw, primcount); + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + + ctx->Driver.DrawGallium(ctx, &info, 0, NULL, draw, primcount); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) _mesa_flush(ctx); - - FREE_PRIMS(draw, primcount); } @@ -1703,6 +1550,23 @@ dump_element_buffer(struct gl_context *ctx, GLenum type) } #endif +static bool +validate_index_bounds(struct gl_context *ctx, struct pipe_draw_info *info, + const struct pipe_draw_start_count_bias *draws, + unsigned num_draws) +{ + assert(info->index_size); + + /* Get index bounds for user buffers. */ + if (!info->index_bounds_valid && ctx->st->draw_needs_minmax_index) { + /* Return if this fails, which means all draws have count == 0. */ + if (!vbo_get_minmax_indices_gallium(ctx, info, draws, num_draws)) + return false; + + info->index_bounds_valid = true; + } + return true; +} /** * Inner support for both _mesa_DrawElements and _mesa_DrawRangeElements. @@ -1710,7 +1574,9 @@ dump_element_buffer(struct gl_context *ctx, GLenum type) * we've validated buffer bounds, etc. */ static void -_mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, +_mesa_validated_drawrangeelements(struct gl_context *ctx, + struct gl_buffer_object *index_bo, + GLenum mode, bool index_bounds_valid, GLuint start, GLuint end, GLsizei count, GLenum type, @@ -1718,24 +1584,97 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, GLint basevertex, GLuint numInstances, GLuint baseInstance) { + /* Viewperf has many draws with count=0. Discarding them is faster than + * processing them. + */ + if (!count || !numInstances) + return; + if (!index_bounds_valid) { assert(start == 0u); assert(end == ~0u); } + unsigned index_size_shift = _mesa_get_index_size_shift(type); + + if (index_bo) { + if (!indices_aligned(index_size_shift, indices)) + return; + + if (unlikely(index_bo->Size < (uintptr_t)indices || !index_bo->buffer)) { +#ifndef NDEBUG + _mesa_warning(ctx, "Invalid indices offset 0x%" PRIxPTR + " (indices buffer size is %ld bytes)" + " or unallocated buffer (%u). Draw skipped.", + (uintptr_t)indices, (long)index_bo->Size, + !!index_bo->buffer); +#endif + return; + } + } + + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + + /* Fast path for a very common DrawElements case: + * - there are no user indices here (always true with glthread) + * - DrawGallium is st_draw_gallium (regular render mode, almost always + * true), which only calls cso_context::draw_vbo + * - the threaded context is enabled while u_vbuf is bypassed (cso_context + * always calls tc_draw_vbo, which is always true with glthread if all + * vertex formats are also supported by the driver) + * - DrawID is 0 (true if glthread isn't unrolling an indirect multi draw, + * which is almost always true) + */ + struct st_context *st = st_context(ctx); + if (index_bo && ctx->Driver.DrawGallium == st_draw_gallium && + st->cso_context->draw_vbo == tc_draw_vbo && ctx->DrawID == 0) { + assert(!st->draw_needs_minmax_index); + struct pipe_resource *index_buffer = + _mesa_get_bufferobj_reference(ctx, index_bo); + struct tc_draw_single *draw = + tc_add_draw_single_call(st->pipe, index_buffer); + bool primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; + + /* This must be set exactly like u_threaded_context sets it, not like + * it would be set for draw_vbo. + */ + draw->info.mode = mode; + draw->info.index_size = 1 << index_size_shift; + draw->info.view_mask = 0; + /* Packed section begin. */ + draw->info.primitive_restart = primitive_restart; + draw->info.has_user_indices = false; + draw->info.index_bounds_valid = false; + draw->info.increment_draw_id = false; + draw->info.take_index_buffer_ownership = false; + draw->info.index_bias_varies = false; + draw->info.was_line_loop = false; + draw->info._pad = 0; + /* Packed section end. */ + draw->info.start_instance = baseInstance; + draw->info.instance_count = numInstances; + draw->info.restart_index = + primitive_restart ? ctx->Array._RestartIndex[index_size_shift] : 0; + draw->info.index.resource = index_buffer; + + /* u_threaded_context stores start/count in min/max_index for single draws. */ + draw->info.min_index = (uintptr_t)indices >> index_size_shift; + draw->info.max_index = count; + draw->index_bias = basevertex; + return; + } + struct pipe_draw_info info; struct pipe_draw_start_count_bias draw; - unsigned index_size_shift = get_index_size_shift(type); - struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 1 << index_size_shift; /* Packed section begin. */ info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; info.has_user_indices = index_bo == NULL; info.index_bounds_valid = index_bounds_valid; info.increment_draw_id = false; + info.was_line_loop = false; info.take_index_buffer_ownership = false; info.index_bias_varies = false; /* Packed section end. */ @@ -1748,8 +1687,15 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, info.index.user = indices; draw.start = 0; } else { - info.index.gl_bo = index_bo; draw.start = (uintptr_t)indices >> index_size_shift; + + if (ctx->pipe->draw_vbo == tc_draw_vbo) { + /* Fast path for u_threaded_context to eliminate atomics. */ + info.index.resource = _mesa_get_bufferobj_reference(ctx, index_bo); + info.take_index_buffer_ownership = true; + } else { + info.index.resource = index_bo->buffer; + } } draw.index_bias = basevertex; @@ -1757,38 +1703,10 @@ _mesa_validated_drawrangeelements(struct gl_context *ctx, GLenum mode, info.max_index = end; draw.count = count; - /* Need to give special consideration to rendering a range of - * indices starting somewhere above zero. Typically the - * application is issuing multiple DrawRangeElements() to draw - * successive primitives layed out linearly in the vertex arrays. - * Unless the vertex arrays are all in a VBO (or locked as with - * CVA), the OpenGL semantics imply that we need to re-read or - * re-upload the vertex data on each draw call. - * - * In the case of hardware tnl, we want to avoid starting the - * upload at zero, as it will mean every draw call uploads an - * increasing amount of not-used vertex data. Worse - in the - * software tnl module, all those vertices might be transformed and - * lit but never rendered. - * - * If we just upload or transform the vertices in start..end, - * however, the indices will be incorrect. - * - * At this level, we don't know exactly what the requirements of - * the backend are going to be, though it will likely boil down to - * either: - * - * 1) Do nothing, everything is in a VBO and is processed once - * only. - * - * 2) Adjust the indices and vertex arrays so that start becomes - * zero. - * - * Rather than doing anything here, I'll provide a helper function - * for the latter case elsewhere. - */ + if (!validate_index_bounds(ctx, &info, &draw, 1)) + return; - ctx->Driver.DrawGallium(ctx, &info, 0, &draw, 1); + ctx->Driver.DrawGallium(ctx, &info, ctx->DrawID, NULL, &draw, 1); if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); @@ -1815,15 +1733,14 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); if (!_mesa_is_no_error_enabled(ctx) && !_mesa_validate_DrawRangeElements(ctx, mode, start, end, count, - type, indices)) + type)) return; if ((int) end + basevertex < 0 || start + basevertex >= max_element) { @@ -1884,7 +1801,8 @@ _mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, end = ~0; } - _mesa_validated_drawrangeelements(ctx, mode, index_bounds_valid, start, end, + _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj, + mode, index_bounds_valid, start, end, count, type, indices, basevertex, 1, 0); } @@ -1908,21 +1826,7 @@ void GLAPIENTRY _mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid * indices) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_FOR_DRAW(ctx); - - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawElements(ctx, mode, count, type, indices)) - return; - - _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, - count, type, indices, 0, 1, 0); + _mesa_DrawElementsBaseVertex(mode, count, type, indices, 0); } @@ -1936,17 +1840,17 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawElements(ctx, mode, count, type, indices)) + !_mesa_validate_DrawElements(ctx, mode, count, type)) return; - _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, + _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj, + mode, false, 0, ~0, count, type, indices, basevertex, 1, 0); } @@ -1955,25 +1859,12 @@ _mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, * Called by glDrawElementsInstanced() in immediate mode. */ void GLAPIENTRY -_mesa_DrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices, GLsizei numInstances) +_mesa_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + const GLvoid * indices, GLsizei numInstances) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_FOR_DRAW(ctx); - - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, - indices, numInstances)) - return; - - _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, - count, type, indices, 0, numInstances, 0); + _mesa_DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, + indices, numInstances, + 0, 0); } @@ -1986,23 +1877,9 @@ _mesa_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLsizei numInstances, GLint basevertex) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_FOR_DRAW(ctx); - - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, - indices, numInstances)) - return; - - _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, - count, type, indices, - basevertex, numInstances, 0); + _mesa_DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, + indices, numInstances, + basevertex, 0); } @@ -2016,23 +1893,9 @@ _mesa_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLsizei numInstances, GLuint baseInstance) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_FOR_DRAW(ctx); - - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - - if (ctx->NewState) - _mesa_update_state(ctx); - - if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, - indices, numInstances)) - return; - - _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, - count, type, indices, 0, numInstances, - baseInstance); + _mesa_DrawElementsInstancedBaseVertexBaseInstance(mode, count, type, + indices, numInstances, + 0, baseInstance); } @@ -2051,22 +1914,99 @@ _mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); if (!_mesa_is_no_error_enabled(ctx) && !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, - indices, numInstances)) + numInstances)) return; - _mesa_validated_drawrangeelements(ctx, mode, false, 0, ~0, + _mesa_validated_drawrangeelements(ctx, ctx->Array.VAO->IndexBufferObj, + mode, false, 0, ~0, count, type, indices, basevertex, numInstances, baseInstance); } +/** + * Same as glDrawElementsInstancedBaseVertexBaseInstance, but the index + * buffer is set by the indexBuf parameter instead of using the bound + * GL_ELEMENT_ARRAY_BUFFER if indexBuf != NULL. + */ +void GLAPIENTRY +_mesa_DrawElementsUserBuf(const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_FOR_DRAW(ctx); + + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); + if (ctx->NewState) + _mesa_update_state(ctx); + + const struct marshal_cmd_DrawElementsUserBuf *cmd = + (const struct marshal_cmd_DrawElementsUserBuf *)ptr; + const GLenum mode = cmd->mode; + const GLsizei count = cmd->count; + const GLenum type = _mesa_decode_index_type(cmd->type); + const GLsizei instance_count = cmd->instance_count; + + if (!_mesa_is_no_error_enabled(ctx) && + !_mesa_validate_DrawElementsInstanced(ctx, mode, count, type, + instance_count)) + return; + + struct gl_buffer_object *index_bo = + cmd->index_buffer ? cmd->index_buffer : ctx->Array.VAO->IndexBufferObj; + + const GLvoid *indices = cmd->indices; + const GLint basevertex = cmd->basevertex; + const GLuint baseinstance = cmd->baseinstance; + + ctx->DrawID = cmd->drawid; + _mesa_validated_drawrangeelements(ctx, index_bo, + mode, false, 0, ~0, + count, type, indices, basevertex, + instance_count, baseinstance); + ctx->DrawID = 0; +} + +/** + * Same as glDrawElementsInstancedBaseVertexBaseInstance, but the index + * buffer is set by the indexBuf parameter instead of using the bound + * GL_ELEMENT_ARRAY_BUFFER if indexBuf != NULL. + */ +void GLAPIENTRY +_mesa_DrawElementsUserBufPacked(const GLvoid *ptr) +{ + GET_CURRENT_CONTEXT(ctx); + FLUSH_FOR_DRAW(ctx); + + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); + if (ctx->NewState) + _mesa_update_state(ctx); + + const struct marshal_cmd_DrawElementsUserBufPacked *cmd = + (const struct marshal_cmd_DrawElementsUserBufPacked *)ptr; + const GLenum mode = cmd->mode; + const GLsizei count = cmd->count; + const GLenum type = _mesa_decode_index_type(cmd->type); + + if (!_mesa_is_no_error_enabled(ctx) && + !_mesa_validate_DrawElements(ctx, mode, count, type)) + return; + + struct gl_buffer_object *index_bo = + cmd->index_buffer ? cmd->index_buffer : ctx->Array.VAO->IndexBufferObj; + + const GLvoid *indices = (void*)(uintptr_t)cmd->indices; + + _mesa_validated_drawrangeelements(ctx, index_bo, mode, false, 0, ~0, + count, type, indices, 0, 1, 0); +} /** * Inner support for both _mesa_MultiDrawElements() and @@ -2074,9 +2014,10 @@ _mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, * This does the actual rendering after we've checked array indexes, etc. */ static void -_mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, - const GLsizei *count, GLenum type, - const GLvoid * const *indices, +_mesa_validated_multidrawelements(struct gl_context *ctx, + struct gl_buffer_object *index_bo, + GLenum mode, const GLsizei *count, + GLenum type, const GLvoid * const *indices, GLsizei primcount, const GLint *basevertex) { uintptr_t min_index_ptr, max_index_ptr; @@ -2086,14 +2027,16 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, if (primcount == 0) return; - unsigned index_size_shift = get_index_size_shift(type); + unsigned index_size_shift = _mesa_get_index_size_shift(type); min_index_ptr = (uintptr_t) indices[0]; max_index_ptr = 0; for (i = 0; i < primcount; i++) { - min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); - max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + - (count[i] << index_size_shift)); + if (count[i]) { + min_index_ptr = MIN2(min_index_ptr, (uintptr_t) indices[i]); + max_index_ptr = MAX2(max_index_ptr, (uintptr_t) indices[i] + + (count[i] << index_size_shift)); + } } /* Check if we can handle this thing as a bunch of index offsets from the @@ -2104,7 +2047,8 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, */ if (index_size_shift) { for (i = 0; i < primcount; i++) { - if ((((uintptr_t) indices[i] - min_index_ptr) & + if (count[i] && + (((uintptr_t)indices[i] - min_index_ptr) & ((1 << index_size_shift) - 1)) != 0) { fallback = true; break; @@ -2112,17 +2056,16 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } } - struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; struct pipe_draw_info info; info.mode = mode; - info.vertices_per_patch = ctx->TessCtrlProgram.patch_vertices; info.index_size = 1 << index_size_shift; /* Packed section begin. */ info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; info.has_user_indices = index_bo == NULL; info.index_bounds_valid = false; info.increment_draw_id = primcount > 1; + info.was_line_loop = false; info.take_index_buffer_ownership = false; info.index_bias_varies = !!basevertex; /* Packed section end. */ @@ -2131,10 +2074,21 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, info.view_mask = 0; info.restart_index = ctx->Array._RestartIndex[index_size_shift]; - if (info.has_user_indices) + if (info.has_user_indices) { info.index.user = (void*)min_index_ptr; - else - info.index.gl_bo = index_bo; + } else { + if (ctx->pipe->draw_vbo == tc_draw_vbo) { + /* Fast path for u_threaded_context to eliminate atomics. */ + info.index.resource = _mesa_get_bufferobj_reference(ctx, index_bo); + info.take_index_buffer_ownership = true; + } else { + info.index.resource = index_bo->buffer; + } + + /* No index buffer storage allocated - nothing to do. */ + if (!info.index.resource) + return; + } if (!fallback && (!info.has_user_indices || @@ -2146,9 +2100,9 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, * greater than UINT32_MAX bytes. */ max_index_ptr - min_index_ptr <= UINT32_MAX)) { - struct pipe_draw_start_count_bias *draw; - - ALLOC_PRIMS(draw, primcount, "glMultiDrawElements"); + struct pipe_draw_start_count_bias *draw = get_temp_draws(ctx, primcount); + if (!draw) + return; if (info.has_user_indices) { for (int i = 0; i < primcount; i++) { @@ -2160,18 +2114,24 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, } else { for (int i = 0; i < primcount; i++) { draw[i].start = (uintptr_t)indices[i] >> index_size_shift; - draw[i].count = count[i]; + draw[i].count = + indices_aligned(index_size_shift, indices[i]) ? count[i] : 0; draw[i].index_bias = basevertex ? basevertex[i] : 0; } } - ctx->Driver.DrawGallium(ctx, &info, 0, draw, primcount); - FREE_PRIMS(draw, primcount); + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + if (!validate_index_bounds(ctx, &info, draw, primcount)) + return; + + ctx->Driver.DrawGallium(ctx, &info, 0, NULL, draw, primcount); } else { /* draw[i].start would overflow. Draw one at a time. */ assert(info.has_user_indices); info.increment_draw_id = false; + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + for (int i = 0; i < primcount; i++) { struct pipe_draw_start_count_bias draw; @@ -2185,7 +2145,10 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, draw.index_bias = basevertex ? basevertex[i] : 0; draw.count = count[i]; - ctx->Driver.DrawGallium(ctx, &info, i, &draw, 1); + if (!draw.count || !validate_index_bounds(ctx, &info, &draw, 1)) + continue; + + ctx->Driver.DrawGallium(ctx, &info, i, NULL, &draw, 1); } } @@ -2196,25 +2159,26 @@ _mesa_validated_multidrawelements(struct gl_context *ctx, GLenum mode, void GLAPIENTRY -_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, - const GLvoid * const *indices, GLsizei primcount) +_mesa_MultiDrawElements(GLenum mode, const GLsizei *count, GLenum type, + const GLvoid * const *indices, GLsizei primcount) { GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); + struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; + if (!_mesa_is_no_error_enabled(ctx) && !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, - primcount)) + primcount, index_bo)) return; - _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, - NULL); + _mesa_validated_multidrawelements(ctx, index_bo, mode, count, type, + indices, primcount, NULL); } @@ -2228,66 +2192,53 @@ _mesa_MultiDrawElementsBaseVertex(GLenum mode, GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); + struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; + if (!_mesa_is_no_error_enabled(ctx) && !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, - primcount)) + primcount, index_bo)) return; - _mesa_validated_multidrawelements(ctx, mode, count, type, indices, primcount, - basevertex); + _mesa_validated_multidrawelements(ctx, index_bo, mode, count, type, + indices, primcount, basevertex); } /** - * Draw a GL primitive using a vertex count obtained from transform feedback. - * \param mode the type of GL primitive to draw - * \param obj the transform feedback object to use - * \param stream index of the transform feedback stream from which to - * get the primitive count. - * \param numInstances number of instances to draw + * Same as glMultiDrawElementsBaseVertex, but the index buffer is set by + * the indexBuf parameter instead of using the bound GL_ELEMENT_ARRAY_BUFFER + * if indexBuf != NULL. */ -static void -_mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj, - GLuint stream, GLuint numInstances) +void GLAPIENTRY +_mesa_MultiDrawElementsUserBuf(GLintptr indexBuf, GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid * const * indices, + GLsizei primcount, const GLint * basevertex) { + GET_CURRENT_CONTEXT(ctx); FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); - if (!_mesa_is_no_error_enabled(ctx) && - !_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, - numInstances)) - return; + struct gl_buffer_object *index_bo = + indexBuf ? (struct gl_buffer_object*)indexBuf : + ctx->Array.VAO->IndexBufferObj; - if (ctx->Driver.GetTransformFeedbackVertexCount && - (ctx->Const.AlwaysUseGetTransformFeedbackVertexCount || - !_mesa_all_varyings_in_vbos(ctx->Array.VAO))) { - GLsizei n = - ctx->Driver.GetTransformFeedbackVertexCount(ctx, obj, stream); - _mesa_draw_arrays(ctx, mode, 0, n, numInstances, 0); + if (!_mesa_is_no_error_enabled(ctx) && + !_mesa_validate_MultiDrawElements(ctx, mode, count, type, indices, + primcount, index_bo)) return; - } - - /* Maybe we should do some primitive splitting for primitive restart - * (like in DrawArrays), but we have no way to know how many vertices - * will be rendered. */ - ctx->Driver.DrawTransformFeedback(ctx, mode, numInstances, stream, obj); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { - _mesa_flush(ctx); - } + _mesa_validated_multidrawelements(ctx, index_bo, mode, count, type, + indices, primcount, basevertex); } @@ -2302,22 +2253,14 @@ _mesa_draw_transform_feedback(struct gl_context *ctx, GLenum mode, void GLAPIENTRY _mesa_DrawTransformFeedback(GLenum mode, GLuint name) { - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - _mesa_draw_transform_feedback(ctx, mode, obj, 0, 1); + _mesa_DrawTransformFeedbackStreamInstanced(mode, name, 0, 1); } void GLAPIENTRY _mesa_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream) { - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - _mesa_draw_transform_feedback(ctx, mode, obj, stream, 1); + _mesa_DrawTransformFeedbackStreamInstanced(mode, name, stream, 1); } @@ -2325,11 +2268,7 @@ void GLAPIENTRY _mesa_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, GLsizei primcount) { - GET_CURRENT_CONTEXT(ctx); - struct gl_transform_feedback_object *obj = - _mesa_lookup_transform_feedback_object(ctx, name); - - _mesa_draw_transform_feedback(ctx, mode, obj, 0, primcount); + _mesa_DrawTransformFeedbackStreamInstanced(mode, name, 0, primcount); } @@ -2342,57 +2281,38 @@ _mesa_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, struct gl_transform_feedback_object *obj = _mesa_lookup_transform_feedback_object(ctx, name); - _mesa_draw_transform_feedback(ctx, mode, obj, stream, primcount); -} + FLUSH_FOR_DRAW(ctx); + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); + if (ctx->NewState) + _mesa_update_state(ctx); -static void -_mesa_validated_multidrawarraysindirect(struct gl_context *ctx, GLenum mode, - GLintptr indirect, - GLintptr drawcount_offset, - GLsizei drawcount, GLsizei stride, - struct gl_buffer_object *drawcount_buffer) -{ - /* If drawcount_buffer is set, drawcount is the maximum draw count.*/ - if (drawcount == 0) + if (!_mesa_is_no_error_enabled(ctx) && + !_mesa_validate_DrawTransformFeedback(ctx, mode, obj, stream, + primcount)) return; - ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, indirect, - drawcount, stride, drawcount_buffer, - drawcount_offset, NULL, false, 0); - - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) - _mesa_flush(ctx); -} + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); - -static void -_mesa_validated_multidrawelementsindirect(struct gl_context *ctx, - GLenum mode, GLenum type, - GLintptr indirect, - GLintptr drawcount_offset, - GLsizei drawcount, GLsizei stride, - struct gl_buffer_object *drawcount_buffer) -{ - /* If drawcount_buffer is set, drawcount is the maximum draw count.*/ - if (drawcount == 0) + struct pipe_draw_indirect_info indirect; + memset(&indirect, 0, sizeof(indirect)); + indirect.count_from_stream_output = obj->draw_count[stream]; + if (indirect.count_from_stream_output == NULL) return; - /* NOTE: IndexBufferObj is guaranteed to be a VBO. */ - struct _mesa_index_buffer ib; - ib.count = 0; /* unknown */ - ib.obj = ctx->Array.VAO->IndexBufferObj; - ib.ptr = NULL; - ib.index_size_shift = get_index_size_shift(type); + struct pipe_draw_start_count_bias draw = {0}; + struct pipe_draw_info info; + util_draw_init_info(&info); + info.max_index = ~0u; /* so that u_vbuf can tell that it's unknown */ + info.mode = mode; + info.instance_count = primcount; - ctx->Driver.DrawIndirect(ctx, mode, ctx->DrawIndirectBuffer, indirect, - drawcount, stride, drawcount_buffer, - drawcount_offset, &ib, - ctx->Array._PrimitiveRestart[ib.index_size_shift], - ctx->Array._RestartIndex[ib.index_size_shift]); + ctx->Driver.DrawGallium(ctx, &info, 0, &indirect, &draw, 1); - if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) + if (MESA_DEBUG_FLAGS & DEBUG_ALWAYS_FLUSH) { _mesa_flush(ctx); + } } @@ -2412,7 +2332,7 @@ _mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) * DrawElementsIndirect are to source their arguments directly from the * pointer passed as their <indirect> parameters." */ - if (ctx->API == API_OPENGL_COMPAT && + if (_mesa_is_desktop_gl_compat(ctx) && !ctx->DrawIndirectBuffer) { DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) indirect; @@ -2424,9 +2344,8 @@ _mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -2434,8 +2353,7 @@ _mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) !_mesa_validate_DrawArraysIndirect(ctx, mode, indirect)) return; - _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, - 0, 1, 16, NULL); + st_indirect_draw_vbo(ctx, mode, 0, (GLintptr)indirect, 0, 1, 16); } @@ -2451,7 +2369,7 @@ _mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) * DrawElementsIndirect are to source their arguments directly from the * pointer passed as their <indirect> parameters." */ - if (ctx->API == API_OPENGL_COMPAT && + if (_mesa_is_desktop_gl_compat(ctx) && !ctx->DrawIndirectBuffer) { /* * Unlike regular DrawElementsInstancedBaseVertex commands, the indices @@ -2483,9 +2401,8 @@ _mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) FLUSH_FOR_DRAW(ctx); - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -2493,9 +2410,7 @@ _mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) !_mesa_validate_DrawElementsIndirect(ctx, mode, type, indirect)) return; - _mesa_validated_multidrawelementsindirect(ctx, mode, type, - (GLintptr)indirect, 0, - 1, 20, NULL); + st_indirect_draw_vbo(ctx, mode, type, (GLintptr)indirect, 0, 1, 20); } @@ -2509,6 +2424,13 @@ _mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, if (stride == 0) stride = sizeof(DrawArraysIndirectCommand); + FLUSH_FOR_DRAW(ctx); + + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); + if (ctx->NewState) + _mesa_update_state(ctx); + /* From the ARB_draw_indirect spec: * * "Initially zero is bound to DRAW_INDIRECT_BUFFER. In the @@ -2516,45 +2438,58 @@ _mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, * DrawElementsIndirect are to source their arguments directly from the * pointer passed as their <indirect> parameters." */ - if (ctx->API == API_OPENGL_COMPAT && + if (_mesa_is_desktop_gl_compat(ctx) && !ctx->DrawIndirectBuffer) { - if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, - "glMultiDrawArraysIndirect")) + if (!_mesa_is_no_error_enabled(ctx) && + (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, + "glMultiDrawArraysIndirect") || + !_mesa_validate_DrawArrays(ctx, mode, 1))) return; + struct pipe_draw_info info; + info.mode = mode; + info.index_size = 0; + info.view_mask = 0; + /* Packed section begin. */ + info.primitive_restart = false; + info.has_user_indices = false; + info.index_bounds_valid = false; + info.increment_draw_id = primcount > 1; + info.was_line_loop = false; + info.take_index_buffer_ownership = false; + info.index_bias_varies = false; + /* Packed section end. */ + + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + const uint8_t *ptr = (const uint8_t *) indirect; for (unsigned i = 0; i < primcount; i++) { DrawArraysIndirectCommand *cmd = (DrawArraysIndirectCommand *) ptr; - _mesa_DrawArraysInstancedBaseInstance(mode, cmd->first, - cmd->count, cmd->primCount, - cmd->baseInstance); - - if (stride == 0) { - ptr += sizeof(DrawArraysIndirectCommand); - } else { - ptr += stride; - } - } - return; - } + info.start_instance = cmd->baseInstance; + info.instance_count = cmd->primCount; - FLUSH_FOR_DRAW(ctx); + struct pipe_draw_start_count_bias draw; + draw.start = cmd->first; + draw.count = cmd->count; - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); + if (!draw.count) + continue; - if (ctx->NewState) - _mesa_update_state(ctx); + ctx->Driver.DrawGallium(ctx, &info, i, NULL, &draw, 1); + ptr += stride; + } + + return; + } if (!_mesa_is_no_error_enabled(ctx) && !_mesa_validate_MultiDrawArraysIndirect(ctx, mode, indirect, primcount, stride)) return; - _mesa_validated_multidrawarraysindirect(ctx, mode, (GLintptr)indirect, 0, - primcount, stride, NULL); + st_indirect_draw_vbo(ctx, mode, 0, (GLintptr)indirect, 0, primcount, stride); } @@ -2565,6 +2500,13 @@ _mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type, { GET_CURRENT_CONTEXT(ctx); + FLUSH_FOR_DRAW(ctx); + + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); + if (ctx->NewState) + _mesa_update_state(ctx); + /* If <stride> is zero, the array elements are treated as tightly packed. */ if (stride == 0) stride = sizeof(DrawElementsIndirectCommand); @@ -2576,7 +2518,7 @@ _mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type, * DrawElementsIndirect are to source their arguments directly from the * pointer passed as their <indirect> parameters." */ - if (ctx->API == API_OPENGL_COMPAT && + if (_mesa_is_desktop_gl_compat(ctx) && !ctx->DrawIndirectBuffer) { /* * Unlike regular DrawElementsInstancedBaseVertex commands, the indices @@ -2592,40 +2534,78 @@ _mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type, return; } - if (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, - "glMultiDrawArraysIndirect")) + if (!_mesa_is_no_error_enabled(ctx) && + (!_mesa_valid_draw_indirect_multi(ctx, primcount, stride, + "glMultiDrawArraysIndirect") || + !_mesa_validate_DrawElements(ctx, mode, 1, type))) + return; + + unsigned index_size_shift = _mesa_get_index_size_shift(type); + + struct pipe_draw_info info; + info.mode = mode; + info.index_size = 1 << index_size_shift; + info.view_mask = 0; + /* Packed section begin. */ + info.primitive_restart = ctx->Array._PrimitiveRestart[index_size_shift]; + info.has_user_indices = false; + info.index_bounds_valid = false; + info.increment_draw_id = primcount > 1; + info.was_line_loop = false; + info.take_index_buffer_ownership = false; + info.index_bias_varies = false; + /* Packed section end. */ + info.restart_index = ctx->Array._RestartIndex[index_size_shift]; + + struct gl_buffer_object *index_bo = ctx->Array.VAO->IndexBufferObj; + + if (ctx->pipe->draw_vbo == tc_draw_vbo) { + /* Fast path for u_threaded_context to eliminate atomics. */ + info.index.resource = _mesa_get_bufferobj_reference(ctx, index_bo); + info.take_index_buffer_ownership = true; + /* Increase refcount so be able to use take_index_buffer_ownership with + * multiple draws. + */ + if (primcount > 1 && info.index.resource) + p_atomic_add(&info.index.resource->reference.count, primcount - 1); + } else { + info.index.resource = index_bo->buffer; + } + + /* No index buffer storage allocated - nothing to do. */ + if (!info.index.resource) return; + st_prepare_draw(ctx, ST_PIPELINE_RENDER_STATE_MASK); + const uint8_t *ptr = (const uint8_t *) indirect; for (unsigned i = 0; i < primcount; i++) { - _mesa_DrawElementsIndirect(mode, type, ptr); + DrawElementsIndirectCommand *cmd = (DrawElementsIndirectCommand*)ptr; - if (stride == 0) { - ptr += sizeof(DrawElementsIndirectCommand); - } else { - ptr += stride; - } - } + info.start_instance = cmd->baseInstance; + info.instance_count = cmd->primCount; - return; - } + struct pipe_draw_start_count_bias draw; + draw.start = cmd->firstIndex; + draw.count = cmd->count; + draw.index_bias = cmd->baseVertex; - FLUSH_FOR_DRAW(ctx); + if (!draw.count || !validate_index_bounds(ctx, &info, &draw, 1)) + continue; - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); + ctx->Driver.DrawGallium(ctx, &info, i, NULL, &draw, 1); + ptr += stride; + } - if (ctx->NewState) - _mesa_update_state(ctx); + return; + } if (!_mesa_is_no_error_enabled(ctx) && !_mesa_validate_MultiDrawElementsIndirect(ctx, mode, type, indirect, primcount, stride)) return; - _mesa_validated_multidrawelementsindirect(ctx, mode, type, - (GLintptr)indirect, 0, primcount, - stride, NULL); + st_indirect_draw_vbo(ctx, mode, type, (GLintptr)indirect, 0, primcount, stride); } @@ -2641,9 +2621,8 @@ _mesa_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, if (stride == 0) stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -2653,9 +2632,8 @@ _mesa_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, maxdrawcount, stride)) return; - _mesa_validated_multidrawarraysindirect(ctx, mode, indirect, - drawcount_offset, maxdrawcount, - stride, ctx->ParameterBuffer); + st_indirect_draw_vbo(ctx, mode, 0, (GLintptr)indirect, drawcount_offset, + maxdrawcount, stride); } @@ -2672,9 +2650,8 @@ _mesa_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, if (stride == 0) stride = 5 * sizeof(GLuint); /* sizeof(DrawElementsIndirectCommand) */ - _mesa_set_draw_vao(ctx, ctx->Array.VAO, - ctx->VertexProgram._VPModeInputFilter); - + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); if (ctx->NewState) _mesa_update_state(ctx); @@ -2685,9 +2662,8 @@ _mesa_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, maxdrawcount, stride)) return; - _mesa_validated_multidrawelementsindirect(ctx, mode, type, indirect, - drawcount_offset, maxdrawcount, - stride, ctx->ParameterBuffer); + st_indirect_draw_vbo(ctx, mode, type, (GLintptr)indirect, drawcount_offset, + maxdrawcount, stride); } @@ -2703,7 +2679,7 @@ _mesa_MultiModeDrawArraysIBM( const GLenum * mode, const GLint * first, for ( i = 0 ; i < primcount ; i++ ) { if ( count[i] > 0 ) { GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); - CALL_DrawArrays(ctx->CurrentServerDispatch, ( m, first[i], count[i] )); + CALL_DrawArrays(ctx->Dispatch.Current, ( m, first[i], count[i] )); } } } @@ -2721,7 +2697,7 @@ _mesa_MultiModeDrawElementsIBM( const GLenum * mode, const GLsizei * count, for ( i = 0 ; i < primcount ; i++ ) { if ( count[i] > 0 ) { GLenum m = *((GLenum *) ((GLubyte *) mode + i * modestride)); - CALL_DrawElements(ctx->CurrentServerDispatch, ( m, count[i], type, + CALL_DrawElements(ctx->Dispatch.Current, ( m, count[i], type, indices[i] )); } } diff --git a/src/mesa/main/draw.h b/src/mesa/main/draw.h index 061919815a9..64f8c9ca6ab 100644 --- a/src/mesa/main/draw.h +++ b/src/mesa/main/draw.h @@ -32,7 +32,7 @@ #define DRAW_H #include <stdbool.h> -#include "main/glheader.h" +#include "util/glheader.h" #ifdef __cplusplus extern "C" { @@ -80,189 +80,53 @@ struct _mesa_index_buffer void _mesa_set_varying_vp_inputs(struct gl_context *ctx, GLbitfield varying_inputs); -/** - * Set the _DrawVAO and the net enabled arrays. - */ void -_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao, - GLbitfield filter); +_mesa_set_draw_vao(struct gl_context *ctx, struct gl_vertex_array_object *vao); void -_mesa_draw_gallium_fallback(struct gl_context *ctx, - struct pipe_draw_info *info, - unsigned drawid_offset, - const struct pipe_draw_start_count_bias *draws, - unsigned num_draws); +_mesa_save_and_set_draw_vao(struct gl_context *ctx, + struct gl_vertex_array_object *vao, + GLbitfield vp_input_filter, + struct gl_vertex_array_object **old_vao, + GLbitfield *old_vp_input_filter); void -_mesa_draw_gallium_multimode_fallback(struct gl_context *ctx, - struct pipe_draw_info *info, - unsigned drawid_offset, - const struct pipe_draw_start_count_bias *draws, - const unsigned char *mode, - unsigned num_draws); - -void GLAPIENTRY -_mesa_EvalMesh1(GLenum mode, GLint i1, GLint i2); - -void GLAPIENTRY -_mesa_EvalMesh2(GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2); - -void GLAPIENTRY -_mesa_DrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, - const GLvoid * indices, GLsizei numInstances); - -void GLAPIENTRY -_mesa_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, - GLsizei count, GLsizei numInstances, - GLuint baseInstance); - -void GLAPIENTRY -_mesa_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, - GLenum type, const GLvoid * indices, - GLsizei numInstances, - GLint basevertex); - -void GLAPIENTRY -_mesa_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei numInstances, - GLuint baseInstance); - -void GLAPIENTRY -_mesa_DrawTransformFeedbackStream(GLenum mode, GLuint name, GLuint stream); - -void GLAPIENTRY -_mesa_DrawTransformFeedbackInstanced(GLenum mode, GLuint name, - GLsizei primcount); - -void GLAPIENTRY -_mesa_DrawTransformFeedbackStreamInstanced(GLenum mode, GLuint name, - GLuint stream, - GLsizei primcount); - -void GLAPIENTRY -_mesa_DrawArraysIndirect(GLenum mode, const GLvoid *indirect); - -void GLAPIENTRY -_mesa_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect); - -void GLAPIENTRY -_mesa_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, - GLsizei primcount, GLsizei stride); - -void GLAPIENTRY -_mesa_MultiDrawElementsIndirect(GLenum mode, GLenum type, - const GLvoid *indirect, - GLsizei primcount, GLsizei stride); - -void GLAPIENTRY -_mesa_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, - GLintptr drawcount_offset, - GLsizei maxdrawcount, GLsizei stride); - -void GLAPIENTRY -_mesa_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, - GLintptr indirect, - GLintptr drawcount_offset, - GLsizei maxdrawcount, GLsizei stride); - -void GLAPIENTRY -_mesa_DrawArrays(GLenum mode, GLint first, GLsizei count); - - -void GLAPIENTRY -_mesa_DrawArraysInstancedARB(GLenum mode, GLint first, GLsizei count, - GLsizei primcount); - -void GLAPIENTRY -_mesa_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, - GLsizei count, - GLenum type, - const GLvoid *indices, - GLsizei numInstances, - GLint basevertex, - GLuint baseInstance); - -void GLAPIENTRY -_mesa_DrawElements(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices); - - -void GLAPIENTRY -_mesa_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, - GLenum type, const GLvoid *indices); - - -void GLAPIENTRY -_mesa_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLint basevertex); +_mesa_restore_draw_vao(struct gl_context *ctx, + struct gl_vertex_array_object *saved, + GLbitfield saved_vp_input_filter); +void +_mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap, struct pipe_resource *tex); -void GLAPIENTRY -_mesa_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, - GLsizei count, GLenum type, - const GLvoid *indices, - GLint basevertex); - - -void GLAPIENTRY -_mesa_DrawTransformFeedback(GLenum mode, GLuint name); - - - -void GLAPIENTRY -_mesa_MultiDrawArrays(GLenum mode, const GLint *first, - const GLsizei *count, GLsizei primcount); - - -void GLAPIENTRY -_mesa_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, GLenum type, - const GLvoid *const *indices, GLsizei primcount); - - -void GLAPIENTRY -_mesa_MultiDrawElementsBaseVertex(GLenum mode, - const GLsizei *count, GLenum type, - const GLvoid * const * indices, GLsizei primcount, - const GLint *basevertex); - - -void GLAPIENTRY -_mesa_MultiModeDrawArraysIBM(const GLenum * mode, const GLint * first, - const GLsizei * count, - GLsizei primcount, GLint modestride); - - -void GLAPIENTRY -_mesa_MultiModeDrawElementsIBM(const GLenum * mode, const GLsizei * count, - GLenum type, const GLvoid * const * indices, - GLsizei primcount, GLint modestride); - -void GLAPIENTRY -_mesa_Rectf(GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2); - -void GLAPIENTRY -_mesa_Rectd(GLdouble x1, GLdouble y1, GLdouble x2, GLdouble y2); - -void GLAPIENTRY -_mesa_Rectdv(const GLdouble *v1, const GLdouble *v2); - -void GLAPIENTRY -_mesa_Rectfv(const GLfloat *v1, const GLfloat *v2); - -void GLAPIENTRY -_mesa_Recti(GLint x1, GLint y1, GLint x2, GLint y2); - -void GLAPIENTRY -_mesa_Rectiv(const GLint *v1, const GLint *v2); - -void GLAPIENTRY -_mesa_Rects(GLshort x1, GLshort y1, GLshort x2, GLshort y2); +static inline unsigned +_mesa_get_index_size_shift(GLenum type) +{ + /* The type is already validated, so use a fast conversion. + * + * GL_UNSIGNED_BYTE - GL_UNSIGNED_BYTE = 0 + * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2 + * GL_UNSIGNED_INT - GL_UNSIGNED_BYTE = 4 + * + * Divide by 2 to get 0,1,2. + */ + return (type - GL_UNSIGNED_BYTE) >> 1; +} -void GLAPIENTRY -_mesa_Rectsv(const GLshort *v1, const GLshort *v2); +static inline bool +_mesa_is_index_type_valid(GLenum type) +{ + /* GL_UNSIGNED_BYTE = 0x1401 + * GL_UNSIGNED_SHORT = 0x1403 + * GL_UNSIGNED_INT = 0x1405 + * + * The trick is that bit 1 and bit 2 mean USHORT and UINT, respectively. + * After clearing those two bits (with ~6), we should get UBYTE. + * Both bits can't be set, because the enum would be greater than UINT. + */ + return type <= GL_UNSIGNED_INT && (type & ~6) == GL_UNSIGNED_BYTE; +} #ifdef __cplusplus } // extern "C" diff --git a/src/mesa/main/draw_validate.c b/src/mesa/main/draw_validate.c index eb5a05e0065..9e77284c3f9 100644 --- a/src/mesa/main/draw_validate.c +++ b/src/mesa/main/draw_validate.c @@ -23,7 +23,7 @@ */ #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" #include "draw_validate.h" #include "arrayobj.h" #include "bufferobj.h" @@ -140,13 +140,13 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx) */ const struct gl_program *prog = ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; - const GLbitfield blend_support = !prog ? 0 : prog->sh.fs.BlendSupport; + const GLbitfield blend_support = !prog ? 0 : prog->info.fs.advanced_blend_modes; if ((blend_support & BITFIELD_BIT(ctx->Color._AdvancedBlendMode)) == 0) return; } - if (ctx->API == API_OPENGL_COMPAT) { + if (_mesa_is_desktop_gl_compat(ctx)) { if (!shader->CurrentProgram[MESA_SHADER_FRAGMENT]) { if (ctx->FragmentProgram.Enabled && !_mesa_arb_fragment_program_enabled(ctx)) @@ -316,7 +316,7 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx) if (tes->info.tess.point_mode) { if (ctx->TransformFeedback.Mode != GL_POINTS) mask = 0; - } else if (tes->info.tess.primitive_mode == GL_ISOLINES) { + } else if (tes->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES) { if (ctx->TransformFeedback.Mode != GL_LINES) mask = 0; } else { @@ -388,7 +388,7 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx) if (tes->info.tess.point_mode) valid = geom_mode == GL_POINTS; - else if (tes->info.tess.primitive_mode == GL_ISOLINES) + else if (tes->info.tess._primitive_mode == TESS_PRIMITIVE_ISOLINES) valid = geom_mode == GL_LINES; else /* the GL_QUADS mode generates triangles too */ @@ -446,7 +446,7 @@ _mesa_update_valid_to_render_state(struct gl_context *ctx) mask &= ~(1 << GL_PATCHES); } -#ifdef DEBUG +#if MESA_DEBUG if (shader->Flags & GLSL_LOG) { struct gl_program **prog = shader->CurrentProgram; diff --git a/src/mesa/main/drawpix.c b/src/mesa/main/drawpix.c index a6c48f2d2e4..e9362829f70 100644 --- a/src/mesa/main/drawpix.c +++ b/src/mesa/main/drawpix.c @@ -22,11 +22,10 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "glheader.h" +#include "util/glheader.h" #include "draw_validate.h" #include "bufferobj.h" #include "context.h" -#include "drawpix.h" #include "enums.h" #include "feedback.h" #include "framebuffer.h" @@ -38,7 +37,10 @@ #include "fbobject.h" #include "util/u_math.h" #include "util/rounding.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_cb_drawpixels.h" /* * Execute glDrawPixels @@ -73,8 +75,7 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, */ _mesa_set_vp_override(ctx, GL_TRUE); - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); if (ctx->NewState) _mesa_update_state(ctx); @@ -167,8 +168,8 @@ _mesa_DrawPixels( GLsizei width, GLsizei height, } } - ctx->Driver.DrawPixels(ctx, x, y, width, height, format, type, - &ctx->Unpack, pixels); + st_DrawPixels(ctx, x, y, width, height, format, type, + &ctx->Unpack, pixels); } } else if (ctx->RenderMode == GL_FEEDBACK) { @@ -245,8 +246,7 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, */ _mesa_set_vp_override(ctx, GL_TRUE); - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); if (ctx->NewState) _mesa_update_state(ctx); @@ -290,8 +290,8 @@ _mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, if (width > 0 && height > 0) { GLint destx = lroundf(ctx->Current.RasterPos[0]); GLint desty = lroundf(ctx->Current.RasterPos[1]); - ctx->Driver.CopyPixels( ctx, srcx, srcy, width, height, destx, desty, - type ); + st_CopyPixels( ctx, srcx, srcy, width, height, destx, desty, + type ); } } else if (ctx->RenderMode == GL_FEEDBACK) { @@ -316,13 +316,11 @@ end: } -void GLAPIENTRY -_mesa_Bitmap( GLsizei width, GLsizei height, - GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ) +void +_mesa_bitmap(struct gl_context *ctx, GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap, struct pipe_resource *tex) { - GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0, 0); if (width < 0 || height < 0) { @@ -334,8 +332,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, return; /* do nothing */ } - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); if (ctx->NewState) _mesa_update_state(ctx); @@ -355,7 +352,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, GLint x = util_ifloor(ctx->Current.RasterPos[0] + epsilon - xorig); GLint y = util_ifloor(ctx->Current.RasterPos[1] + epsilon - yorig); - if (ctx->Unpack.BufferObj) { + if (!tex && ctx->Unpack.BufferObj) { /* unpack from PBO */ if (!_mesa_validate_pbo_access(2, &ctx->Unpack, width, height, 1, GL_COLOR_INDEX, GL_BITMAP, @@ -372,7 +369,7 @@ _mesa_Bitmap( GLsizei width, GLsizei height, } } - ctx->Driver.Bitmap( ctx, x, y, width, height, &ctx->Unpack, bitmap ); + st_Bitmap(ctx, x, y, width, height, &ctx->Unpack, bitmap, tex); } } else if (ctx->RenderMode == GL_FEEDBACK) { @@ -397,3 +394,13 @@ _mesa_Bitmap( GLsizei width, GLsizei height, _mesa_flush(ctx); } } + +void GLAPIENTRY +_mesa_Bitmap(GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap) +{ + GET_CURRENT_CONTEXT(ctx); + + _mesa_bitmap(ctx, width, height, xorig, yorig, xmove, ymove, bitmap, NULL); +} diff --git a/src/mesa/main/drawpix.h b/src/mesa/main/drawpix.h deleted file mode 100644 index 181c05ca50e..00000000000 --- a/src/mesa/main/drawpix.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef DRAWPIX_H -#define DRAWPIX_H - - -#include "glheader.h" - - -void GLAPIENTRY -_mesa_DrawPixels( GLsizei width, GLsizei height, - GLenum format, GLenum type, const GLvoid *pixels ); -void GLAPIENTRY -_mesa_CopyPixels( GLint srcx, GLint srcy, GLsizei width, GLsizei height, - GLenum type ); -void GLAPIENTRY -_mesa_Bitmap( GLsizei width, GLsizei height, - GLfloat xorig, GLfloat yorig, GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ); - - -#endif /* DRAWPIX_H */ diff --git a/src/mesa/main/drawtex.c b/src/mesa/main/drawtex.c index e7c76d1b044..6e3fc875c0f 100644 --- a/src/mesa/main/drawtex.c +++ b/src/mesa/main/drawtex.c @@ -22,11 +22,12 @@ */ #include "main/errors.h" -#include "main/drawtex.h" #include "main/state.h" #include "main/mtypes.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_drawtex.h" static void draw_texture(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, @@ -47,8 +48,7 @@ draw_texture(struct gl_context *ctx, GLfloat x, GLfloat y, GLfloat z, if (ctx->NewState) _mesa_update_state(ctx); - assert(ctx->Driver.DrawTex); - ctx->Driver.DrawTex(ctx, x, y, z, width, height); + st_DrawTex(ctx, x, y, z, width, height); _mesa_set_vp_override(ctx, GL_FALSE); } @@ -104,29 +104,3 @@ _mesa_DrawTexsvOES(const GLshort *coords) draw_texture(ctx, (GLfloat) coords[0], (GLfloat) coords[1], (GLfloat) coords[2], (GLfloat) coords[3], (GLfloat) coords[4]); } - - -void GLAPIENTRY -_mesa_DrawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height) -{ - GET_CURRENT_CONTEXT(ctx); - draw_texture(ctx, - (GLfloat) x / 65536.0f, - (GLfloat) y / 65536.0f, - (GLfloat) z / 65536.0f, - (GLfloat) width / 65536.0f, - (GLfloat) height / 65536.0f); -} - - -void GLAPIENTRY -_mesa_DrawTexxv(const GLfixed *coords) -{ - GET_CURRENT_CONTEXT(ctx); - draw_texture(ctx, - (GLfloat) coords[0] / 65536.0f, - (GLfloat) coords[1] / 65536.0f, - (GLfloat) coords[2] / 65536.0f, - (GLfloat) coords[3] / 65536.0f, - (GLfloat) coords[4] / 65536.0f); -} diff --git a/src/mesa/main/drawtex.h b/src/mesa/main/drawtex.h deleted file mode 100644 index 28e2435c8a8..00000000000 --- a/src/mesa/main/drawtex.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2009 Chia-I Wu <olv@0xlab.org> - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -#ifndef DRAWTEX_H -#define DRAWTEX_H - - -#include "glheader.h" - - -extern void GLAPIENTRY -_mesa_DrawTexfOES(GLfloat x, GLfloat y, GLfloat z, GLfloat width, GLfloat height); - -extern void GLAPIENTRY -_mesa_DrawTexfvOES(const GLfloat *coords); - -extern void GLAPIENTRY -_mesa_DrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height); - -extern void GLAPIENTRY -_mesa_DrawTexivOES(const GLint *coords); - -extern void GLAPIENTRY -_mesa_DrawTexsOES(GLshort x, GLshort y, GLshort z, GLshort width, GLshort height); - -extern void GLAPIENTRY -_mesa_DrawTexsvOES(const GLshort *coords); - -extern void GLAPIENTRY -_mesa_DrawTexx(GLfixed x, GLfixed y, GLfixed z, GLfixed width, GLfixed height); - -extern void GLAPIENTRY -_mesa_DrawTexxv(const GLfixed *coords); - - -#endif /* DRAWTEX_H */ diff --git a/src/mesa/main/enable.c b/src/mesa/main/enable.c index 1f835fddd78..c864b9f689e 100644 --- a/src/mesa/main/enable.c +++ b/src/mesa/main/enable.c @@ -28,7 +28,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "arrayobj.h" #include "blend.h" #include "clip.h" @@ -43,7 +43,10 @@ #include "state.h" #include "texstate.h" #include "varray.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_context.h" void _mesa_update_derived_primitive_restart_state(struct gl_context *ctx) @@ -125,7 +128,9 @@ client_state(struct gl_context *ctx, struct gl_vertex_array_object* vao, case GL_POINT_SIZE_ARRAY_OES: if (ctx->VertexProgram.PointSizeEnabled != state) { - FLUSH_VERTICES(ctx, _NEW_PROGRAM, 0); + FLUSH_VERTICES(ctx, ctx->st->lower_point_size ? _NEW_PROGRAM : 0, + 0); + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->VertexProgram.PointSizeEnabled = state; } vao_state(ctx, vao, VERT_ATTRIB_POINT_SIZE, state); @@ -145,11 +150,6 @@ client_state(struct gl_context *ctx, struct gl_vertex_array_object* vao, default: goto invalid_enum_error; } - - if (ctx->Driver.Enable) { - ctx->Driver.Enable( ctx, cap, state ); - } - return; invalid_enum_error: @@ -353,8 +353,7 @@ _mesa_set_multisample(struct gl_context *ctx, GLboolean state) /* GL compatibility needs Multisample.Enable to determine program state * constants. */ - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES || - !ctx->DriverFlags.NewMultisampleEnable) { + if (_mesa_is_desktop_gl_compat(ctx) || _mesa_is_gles1(ctx)) { FLUSH_VERTICES(ctx, _NEW_MULTISAMPLE, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT); } else { FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT); @@ -362,10 +361,6 @@ _mesa_set_multisample(struct gl_context *ctx, GLboolean state) ctx->NewDriverState |= ctx->DriverFlags.NewMultisampleEnable; ctx->Multisample.Enabled = state; - - if (ctx->Driver.Enable) { - ctx->Driver.Enable(ctx, GL_MULTISAMPLE, state); - } } /** @@ -379,14 +374,10 @@ _mesa_set_framebuffer_srgb(struct gl_context *ctx, GLboolean state) return; /* TODO: Switch i965 to the new flag and remove the conditional */ - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewFramebufferSRGB ? 0 : _NEW_BUFFERS, + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewFramebufferSRGB; + ctx->NewDriverState |= ST_NEW_FB_STATE; ctx->Color.sRGBEnabled = state; - - if (ctx->Driver.Enable) { - ctx->Driver.Enable(ctx, GL_FRAMEBUFFER_SRGB, state); - } } /** @@ -466,8 +457,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) /* The compatibility profile needs _NEW_TRANSFORM to transform * clip planes according to the projection matrix. */ - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES || - !ctx->DriverFlags.NewClipPlaneEnable) { + if (_mesa_is_desktop_gl_compat(ctx) || _mesa_is_gles1(ctx)) { FLUSH_VERTICES(ctx, _NEW_TRANSFORM, GL_TRANSFORM_BIT | GL_ENABLE_BIT); } else { @@ -480,9 +470,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) /* The projection matrix transforms the clip plane. */ /* TODO: glEnable might not be the best place to do it. */ - if (ctx->API == API_OPENGL_COMPAT || ctx->API == API_OPENGLES) { + if (_mesa_is_desktop_gl_compat(ctx) || _mesa_is_gles1(ctx)) { _mesa_update_clip_plane(ctx, p); - ctx->NewDriverState |= ctx->DriverFlags.NewClipPlane; + ctx->NewDriverState |= ST_NEW_CLIP_STATE; } } else { @@ -507,31 +497,31 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) case GL_CULL_FACE: if (ctx->Polygon.CullFlag == state) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.CullFlag = state; break; case GL_DEPTH_TEST: if (ctx->Depth.Test == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH, + FLUSH_VERTICES(ctx, 0, GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepth; + ctx->NewDriverState |= ST_NEW_DSA; ctx->Depth.Test = state; _mesa_update_allow_draw_out_of_order(ctx); break; case GL_DEBUG_OUTPUT: case GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB: _mesa_set_debug_state_int(ctx, cap, state); + _mesa_update_debug_callback(ctx); break; case GL_DITHER: if (ctx->Color.DitherFlag == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR, + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.DitherFlag = state; break; case GL_FOG: @@ -581,9 +571,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Line.SmoothFlag == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLineState ? 0 : _NEW_LINE, + FLUSH_VERTICES(ctx, 0, GL_LINE_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLineState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Line.SmoothFlag = state; break; case GL_LINE_STIPPLE: @@ -591,9 +581,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Line.StippleFlag == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLineState ? 0 : _NEW_LINE, + FLUSH_VERTICES(ctx, 0, GL_LINE_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLineState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Line.StippleFlag = state; break; case GL_INDEX_LOGIC_OP: @@ -601,9 +591,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Color.IndexLogicOpEnabled == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLogicOp ? 0 : _NEW_COLOR, + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp; + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.IndexLogicOpEnabled = state; break; case GL_CONSERVATIVE_RASTERIZATION_INTEL: @@ -612,8 +602,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) if (ctx->IntelConservativeRasterization == state) return; FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= - ctx->DriverFlags.NewIntelConservativeRasterization; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->IntelConservativeRasterization = state; _mesa_update_valid_to_render_state(ctx); break; @@ -623,8 +612,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) if (ctx->ConservativeRasterization == state) return; FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT); - ctx->NewDriverState |= - ctx->DriverFlags.NewNvConservativeRasterization; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->ConservativeRasterization = state; break; case GL_COLOR_LOGIC_OP: @@ -632,9 +620,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Color.ColorLogicOpEnabled == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLogicOp ? 0 : _NEW_COLOR, + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLogicOp; + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.ColorLogicOpEnabled = state; _mesa_update_allow_draw_out_of_order(ctx); break; @@ -822,10 +810,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Polygon.SmoothFlag == state) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.SmoothFlag = state; break; case GL_POLYGON_STIPPLE: @@ -833,10 +820,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Polygon.StippleFlag == state) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.StippleFlag = state; break; case GL_POLYGON_OFFSET_POINT: @@ -844,10 +830,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Polygon.OffsetPoint == state) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.OffsetPoint = state; break; case GL_POLYGON_OFFSET_LINE: @@ -855,19 +840,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Polygon.OffsetLine == state) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.OffsetLine = state; break; case GL_POLYGON_OFFSET_FILL: if (ctx->Polygon.OffsetFill == state) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.OffsetFill = state; break; case GL_RESCALE_NORMAL_EXT: @@ -885,10 +868,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) GLbitfield newEnabled = state * ((1 << ctx->Const.MaxViewports) - 1); if (newEnabled != ctx->Scissor.EnableFlags) { - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewScissorTest ? 0 : - _NEW_SCISSOR, + FLUSH_VERTICES(ctx, 0, GL_SCISSOR_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewScissorTest; + ctx->NewDriverState |= ST_NEW_SCISSOR | ST_NEW_RASTERIZER; ctx->Scissor.EnableFlags = newEnabled; } } @@ -896,9 +878,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) case GL_STENCIL_TEST: if (ctx->Stencil.Enabled == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.Enabled = state; _mesa_update_allow_draw_out_of_order(ctx); break; @@ -995,8 +977,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) /* GL_ARB_texture_cube_map */ case GL_TEXTURE_CUBE_MAP: - if (!_mesa_has_ARB_texture_cube_map(ctx) && - !_mesa_has_OES_texture_cube_map(ctx)) + if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_enum_error; if (!enable_texture(ctx, state, TEXTURE_CUBE_BIT)) { return; @@ -1023,10 +1004,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) case GL_SAMPLE_ALPHA_TO_COVERAGE_ARB: if (ctx->Multisample.SampleAlphaToCoverage == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleAlphaToXEnable ? 0 : - _NEW_MULTISAMPLE, + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleAlphaToXEnable; + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Multisample.SampleAlphaToCoverage = state; break; case GL_SAMPLE_ALPHA_TO_ONE_ARB: @@ -1034,19 +1014,17 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Multisample.SampleAlphaToOne == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleAlphaToXEnable ? 0 : - _NEW_MULTISAMPLE, + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleAlphaToXEnable; + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Multisample.SampleAlphaToOne = state; break; case GL_SAMPLE_COVERAGE_ARB: if (ctx->Multisample.SampleCoverage == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 : - _NEW_MULTISAMPLE, + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask; + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; ctx->Multisample.SampleCoverage = state; break; case GL_SAMPLE_COVERAGE_INVERT_ARB: @@ -1054,10 +1032,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Multisample.SampleCoverageInvert == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 : - _NEW_MULTISAMPLE, - GL_MULTISAMPLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask; + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT); + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; ctx->Multisample.SampleCoverageInvert = state; break; @@ -1067,8 +1043,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Multisample.SampleShading == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleShading ? 0 : - _NEW_MULTISAMPLE, + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT | GL_ENABLE_BIT); ctx->NewDriverState |= ctx->DriverFlags.NewSampleShading; ctx->Multisample.SampleShading = state; @@ -1086,7 +1061,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) /* GL_ARB_point_sprite */ case GL_POINT_SPRITE: - if (!(ctx->API == API_OPENGL_COMPAT && + if (!(_mesa_is_desktop_gl_compat(ctx) && _mesa_has_ARB_point_sprite(ctx)) && !_mesa_has_OES_point_sprite(ctx)) goto invalid_enum_error; @@ -1116,7 +1091,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->VertexProgram.PointSizeEnabled == state) return; - FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT); + FLUSH_VERTICES(ctx, ctx->st->lower_point_size ? _NEW_PROGRAM : 0, + GL_ENABLE_BIT); + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->VertexProgram.PointSizeEnabled = state; break; case GL_VERTEX_PROGRAM_TWO_SIDE_ARB: @@ -1124,7 +1101,14 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->VertexProgram.TwoSideEnabled == state) return; - FLUSH_VERTICES(ctx, _NEW_PROGRAM, GL_ENABLE_BIT); + FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT); + if (ctx->st->lower_two_sided_color) { + /* TODO: this could be smaller, but most drivers don't get here */ + ctx->NewDriverState |= ST_NEW_VS_STATE | + ST_NEW_TES_STATE | + ST_NEW_GS_STATE; + } + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->VertexProgram.TwoSideEnabled = state; break; @@ -1143,9 +1127,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Stencil.TestTwoSide == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.TestTwoSide = state; if (state) { ctx->Stencil._BackFace = 2; @@ -1170,9 +1154,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Depth.BoundsTest == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepth ? 0 : _NEW_DEPTH, - GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepth; + FLUSH_VERTICES(ctx, 0, GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Depth.BoundsTest = state; break; @@ -1183,10 +1166,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) if (ctx->Transform.DepthClampNear == state && ctx->Transform.DepthClampFar == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 : - _NEW_TRANSFORM, + FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Transform.DepthClampNear = state; ctx->Transform.DepthClampFar = state; break; @@ -1196,10 +1178,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Transform.DepthClampNear == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 : - _NEW_TRANSFORM, + FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Transform.DepthClampNear = state; break; @@ -1208,10 +1189,9 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Transform.DepthClampFar == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewDepthClamp ? 0 : - _NEW_TRANSFORM, + FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewDepthClamp; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Transform.DepthClampFar = state; break; @@ -1238,7 +1218,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->RasterDiscard != state) { FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewRasterizerDiscard; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->RasterDiscard = state; } break; @@ -1248,7 +1228,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->TileRasterOrderFixed != state) { FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewTileRasterOrder; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->TileRasterOrderFixed = state; } break; @@ -1258,7 +1238,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->TileRasterOrderIncreasingX != state) { FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewTileRasterOrder; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->TileRasterOrderIncreasingX = state; } break; @@ -1268,7 +1248,7 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->TileRasterOrderIncreasingY != state) { FLUSH_VERTICES(ctx, 0, GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewTileRasterOrder; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->TileRasterOrderIncreasingY = state; } break; @@ -1318,9 +1298,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Multisample.SampleMask == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 : - _NEW_MULTISAMPLE, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask; + FLUSH_VERTICES(ctx, 0, 0); + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; ctx->Multisample.SampleMask = state; break; @@ -1329,9 +1308,8 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) goto invalid_enum_error; if (ctx->Color.BlendCoherent == state) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewBlend ? 0 : _NEW_COLOR, - GL_COLOR_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewBlend; + FLUSH_VERTICES(ctx, 0, GL_COLOR_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Color.BlendCoherent = state; break; @@ -1342,16 +1320,12 @@ _mesa_set_enable(struct gl_context *ctx, GLenum cap, GLboolean state) return; FLUSH_VERTICES(ctx, 0, 0); ctx->IntelBlackholeRender = state; + ctx->pipe->set_frontend_noop(ctx->pipe, state); break; default: goto invalid_enum_error; } - - if (ctx->Driver.Enable) { - ctx->Driver.Enable( ctx, cap, state ); - } - return; invalid_enum_error: @@ -1428,10 +1402,9 @@ _mesa_set_enablei(struct gl_context *ctx, GLenum cap, return; } if (((ctx->Scissor.EnableFlags >> index) & 1) != state) { - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewScissorTest ? 0 : _NEW_SCISSOR, + FLUSH_VERTICES(ctx, 0, GL_SCISSOR_BIT | GL_ENABLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewScissorTest; + ctx->NewDriverState |= ST_NEW_SCISSOR | ST_NEW_RASTERIZER; if (state) ctx->Scissor.EnableFlags |= (1 << index); else @@ -1837,8 +1810,7 @@ _mesa_IsEnabled( GLenum cap ) /* GL_ARB_texture_cube_map */ case GL_TEXTURE_CUBE_MAP: - if (!_mesa_has_ARB_texture_cube_map(ctx) && - !_mesa_has_OES_texture_cube_map(ctx)) + if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) goto invalid_enum_error; return is_texture_enabled(ctx, TEXTURE_CUBE_BIT); @@ -1874,7 +1846,7 @@ _mesa_IsEnabled( GLenum cap ) /* GL_ARB_point_sprite */ case GL_POINT_SPRITE: - if (!(ctx->API == API_OPENGL_COMPAT && + if (!(_mesa_is_desktop_gl_compat(ctx) && _mesa_has_ARB_point_sprite(ctx)) && !_mesa_has_OES_point_sprite(ctx)) goto invalid_enum_error; diff --git a/src/mesa/main/enable.h b/src/mesa/main/enable.h index 78e31700548..7a064acdde5 100644 --- a/src/mesa/main/enable.h +++ b/src/mesa/main/enable.h @@ -32,7 +32,7 @@ #define ENABLE_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; @@ -43,51 +43,13 @@ _mesa_update_derived_primitive_restart_state(struct gl_context *ctx); extern void _mesa_set_enable( struct gl_context* ctx, GLenum cap, GLboolean state ); -extern void GLAPIENTRY -_mesa_Disable( GLenum cap ); - -extern void GLAPIENTRY -_mesa_Enable( GLenum cap ); - -extern GLboolean GLAPIENTRY -_mesa_IsEnabled( GLenum cap ); - extern void _mesa_set_enablei(struct gl_context *ctx, GLenum cap, GLuint index, GLboolean state); -extern void GLAPIENTRY -_mesa_Disablei( GLenum cap, GLuint index ); - -extern void GLAPIENTRY -_mesa_Enablei( GLenum cap, GLuint index ); - -extern GLboolean GLAPIENTRY -_mesa_IsEnabledi( GLenum cap, GLuint index ); - -extern void GLAPIENTRY -_mesa_EnableClientState( GLenum cap ); - -extern void GLAPIENTRY -_mesa_EnableClientStateiEXT( GLenum cap, GLuint index ); - -extern void GLAPIENTRY -_mesa_EnableVertexArrayEXT( GLuint vaobj, GLenum cap ); - -extern void GLAPIENTRY -_mesa_DisableClientState( GLenum cap ); - -extern void GLAPIENTRY -_mesa_DisableClientStateiEXT( GLenum cap, GLuint index ); - -extern void GLAPIENTRY -_mesa_DisableVertexArrayEXT( GLuint vaobj, GLenum cap ); - extern void _mesa_set_multisample(struct gl_context *ctx, GLboolean state); extern void _mesa_set_framebuffer_srgb(struct gl_context *ctx, GLboolean state); - - #endif diff --git a/src/mesa/main/errors.c b/src/mesa/main/errors.c index a4029c0896c..c42696074b3 100644 --- a/src/mesa/main/errors.c +++ b/src/mesa/main/errors.c @@ -35,14 +35,12 @@ #include "context.h" #include "debug_output.h" - - -static FILE *LogFile = NULL; - +#include "util/detect_os.h" +#include "util/log.h" +#include "api_exec_decl.h" static void -output_if_debug(const char *prefixString, const char *outputString, - GLboolean newline) +output_if_debug(enum mesa_log_level level, const char *outputString) { static int debug = -1; @@ -51,14 +49,6 @@ output_if_debug(const char *prefixString, const char *outputString, * by now so MESA_DEBUG_FLAGS will be initialized. */ if (debug == -1) { - /* If MESA_LOG_FILE env var is set, log Mesa errors, warnings, - * etc to the named file. Otherwise, output to stderr. - */ - const char *logFile = getenv("MESA_LOG_FILE"); - if (logFile) - LogFile = fopen(logFile, "w"); - if (!LogFile) - LogFile = stderr; #ifndef NDEBUG /* in debug builds, print messages unless MESA_DEBUG="silent" */ if (MESA_DEBUG_FLAGS & DEBUG_SILENT) @@ -72,28 +62,8 @@ output_if_debug(const char *prefixString, const char *outputString, } /* Now only print the string if we're required to do so. */ - if (debug) { - if (prefixString) - fprintf(LogFile, "%s: %s", prefixString, outputString); - else - fprintf(LogFile, "%s", outputString); - if (newline) - fprintf(LogFile, "\n"); - fflush(LogFile); - -#if defined(_WIN32) - /* stderr from windows applications without console is not usually - * visible, so communicate with the debugger instead */ - { - char buf[4096]; - if (prefixString) - snprintf(buf, sizeof(buf), "%s: %s%s", prefixString, outputString, newline ? "\n" : ""); - else - snprintf(buf, sizeof(buf), "%s%s", outputString, newline ? "\n" : ""); - OutputDebugStringA(buf); - } -#endif - } + if (debug) + mesa_log(level, "Mesa", "%s", outputString); } @@ -104,8 +74,7 @@ output_if_debug(const char *prefixString, const char *outputString, FILE * _mesa_get_log_file(void) { - assert(LogFile); - return LogFile; + return mesa_log_get_file(); } @@ -123,7 +92,7 @@ flush_delayed_errors( struct gl_context *ctx ) ctx->ErrorDebugCount, _mesa_enum_to_string(ctx->ErrorValue)); - output_if_debug("Mesa", s, GL_TRUE); + output_if_debug(MESA_LOG_ERROR, s); ctx->ErrorDebugCount = 0; } @@ -132,7 +101,7 @@ flush_delayed_errors( struct gl_context *ctx ) /** * Report a warning (a recoverable error condition) to stderr if - * either DEBUG is defined or the MESA_DEBUG env var is set. + * either MESA_DEBUG is defined to 1 or the MESA_DEBUG env var is set. * * \param ctx GL context. * \param fmtString printf()-like format string. @@ -149,7 +118,7 @@ _mesa_warning( struct gl_context *ctx, const char *fmtString, ... ) if (ctx) flush_delayed_errors( ctx ); - output_if_debug("Mesa warning", str, GL_TRUE); + output_if_debug(MESA_LOG_WARN, str); } @@ -274,7 +243,7 @@ _mesa_gl_debug(struct gl_context *ctx, /* limit the message to fit within KHR_debug buffers */ char s[MAX_DEBUG_MESSAGE_LENGTH]; - strncpy(s, msg, MAX_DEBUG_MESSAGE_LENGTH); + strncpy(s, msg, MAX_DEBUG_MESSAGE_LENGTH - 1); s[MAX_DEBUG_MESSAGE_LENGTH - 1] = '\0'; len = MAX_DEBUG_MESSAGE_LENGTH - 1; _mesa_log_msg(ctx, source, type, *id, severity, len, s); @@ -288,7 +257,7 @@ _mesa_gl_debug(struct gl_context *ctx, * Record an OpenGL state error. These usually occur when the user * passes invalid parameters to a GL function. * - * If debugging is enabled (either at compile-time via the DEBUG macro, or + * If debugging is enabled (either at compile-time via the MESA_DEBUG macro, or * run-time via the MESA_DEBUG environment variable), report the error with * _mesa_debug(). * @@ -349,7 +318,7 @@ _mesa_error( struct gl_context *ctx, GLenum error, const char *fmtString, ... ) /* Print the error to stderr if needed. */ if (do_output) { - output_if_debug("Mesa: User error", s2, GL_TRUE); + output_if_debug(MESA_LOG_ERROR, s2); } /* Log the error via ARB_debug_output if needed.*/ @@ -372,8 +341,8 @@ _mesa_error_no_memory(const char *caller) } /** - * Report debug information. Print error message to stderr via fprintf(). - * No-op if DEBUG mode not enabled. + * Report debug information. Print error message to stderr via fprintf() + * when debug mode is enabled by NDEBUG; otherwise no-op. * * \param ctx GL context. * \param fmtString printf()-style format string, followed by optional args. @@ -387,8 +356,8 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) va_start(args, fmtString); vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); va_end(args); - output_if_debug("Mesa", s, GL_FALSE); -#endif /* DEBUG */ + output_if_debug(MESA_LOG_DEBUG, s); +#endif /* !NDEBUG */ (void) ctx; (void) fmtString; } @@ -402,9 +371,14 @@ _mesa_log(const char *fmtString, ...) va_start(args, fmtString); vsnprintf(s, MAX_DEBUG_MESSAGE_LENGTH, fmtString, args); va_end(args); - output_if_debug(NULL, s, GL_FALSE); + output_if_debug(MESA_LOG_INFO, s); } +void +_mesa_log_direct(const char *string) +{ + output_if_debug(MESA_LOG_INFO, string); +} /** * Report debug information from the shader compiler via GL_ARB_debug_output. diff --git a/src/mesa/main/errors.h b/src/mesa/main/errors.h index 9549093b090..3effdf39af4 100644 --- a/src/mesa/main/errors.h +++ b/src/mesa/main/errors.h @@ -38,7 +38,7 @@ #include <stdio.h> #include <stdarg.h> -#include "glheader.h" +#include "util/glheader.h" #include "menums.h" @@ -66,6 +66,10 @@ _mesa_debug( const struct gl_context *ctx, const char *fmtString, ... ) PRINTFLI extern void _mesa_log(const char *fmtString, ...) PRINTFLIKE(1, 2); +extern void +_mesa_log_direct(const char *string); + + extern FILE * _mesa_get_log_file(void); @@ -109,9 +113,6 @@ _mesa_gl_debug(struct gl_context *ctx, } \ } while (0) -void GLAPIENTRY -_mesa_InternalSetError(GLenum error); - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/es1_conversion.c b/src/mesa/main/es1_conversion.c index e6995a36eae..2d1362e0a6e 100644 --- a/src/mesa/main/es1_conversion.c +++ b/src/mesa/main/es1_conversion.c @@ -1,9 +1,8 @@ #include <stdbool.h> -#include "api_exec.h" +#include "context.h" #include "blend.h" -#include "clear.h" #include "clip.h" #include "context.h" #include "depth.h" @@ -17,16 +16,10 @@ #include "points.h" #include "polygon.h" #include "readpix.h" -#include "texenv.h" -#include "texgen.h" -#include "texobj.h" #include "texparam.h" -#include "mtypes.h" #include "viewport.h" -#include "main/drawtex.h" #include "vbo/vbo.h" - -#include "main/es1_conversion.h" +#include "api_exec_decl.h" void GL_APIENTRY _mesa_AlphaFuncx(GLenum func, GLclampx ref) @@ -76,15 +69,6 @@ _mesa_ClipPlanex(GLenum plane, const GLfixed *equation) } void GL_APIENTRY -_es_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) -{ - _es_Color4f((GLfloat) (red / 255.0f), - (GLfloat) (green / 255.0f), - (GLfloat) (blue / 255.0f), - (GLfloat) (alpha / 255.0f)); -} - -void GL_APIENTRY _mesa_Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha) { _es_Color4f((GLfloat) (red / 65536.0f), @@ -406,12 +390,6 @@ _mesa_GetTexEnvxv(GLenum target, GLenum pname, GLfixed *params) } void GL_APIENTRY -_check_GetTexGenivOES(GLenum coord, GLenum pname, GLint *params) -{ - _mesa_GetTexGeniv(coord, pname, params); -} - -void GL_APIENTRY _mesa_GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params) { _mesa_GetTexGeniv(coord, pname, (GLint *) params); @@ -856,16 +834,18 @@ _mesa_TexEnvxv(GLenum target, GLenum pname, const GLfixed *params) } } -void GL_APIENTRY -_check_TexGeniOES(GLenum coord, GLenum pname, GLint param) +static void +_es_TexGenf(GLenum coord, GLenum pname, GLfloat param) { - _es_TexGenf(coord, pname, (GLfloat) param); -} - -void GL_APIENTRY -_check_TexGenivOES(GLenum coord, GLenum pname, const GLint *params) -{ - _es_TexGenf(coord, pname, (GLfloat) params[0]); + if (coord != GL_TEXTURE_GEN_STR_OES) { + GET_CURRENT_CONTEXT(ctx); + _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx](pname)" ); + return; + } + /* set S, T, and R at the same time */ + _mesa_TexGenf(GL_S, pname, param); + _mesa_TexGenf(GL_T, pname, param); + _mesa_TexGenf(GL_R, pname, param); } void GL_APIENTRY diff --git a/src/mesa/main/es1_conversion.h b/src/mesa/main/es1_conversion.h deleted file mode 100644 index 40cac4197da..00000000000 --- a/src/mesa/main/es1_conversion.h +++ /dev/null @@ -1,188 +0,0 @@ -/* - * Copyright 2008 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * VMWARE BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF - * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE - * SOFTWARE. - */ - -#ifndef ES1_CONVERSION_H -#define ES1_CONVERSION_H - -#ifndef GL_APIENTRY -#define GL_APIENTRY GLAPIENTRY -#endif - -void GL_APIENTRY -_mesa_AlphaFuncx(GLenum func, GLclampx ref); - -void GL_APIENTRY -_mesa_ClearColorx(GLclampx red, GLclampx green, GLclampx blue, GLclampx alpha); - -void GL_APIENTRY -_mesa_ClearDepthx(GLclampx depth); - -void GL_APIENTRY -_mesa_ClipPlanef(GLenum plane, const GLfloat *equation); - -void GL_APIENTRY -_mesa_ClipPlanex(GLenum plane, const GLfixed *equation); - -void GL_APIENTRY -_es_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha); - -void GL_APIENTRY -_mesa_Color4x(GLfixed red, GLfixed green, GLfixed blue, GLfixed alpha); - -void GL_APIENTRY -_mesa_DepthRangex(GLclampx zNear, GLclampx zFar); - -void GL_APIENTRY -_mesa_DrawTexxOES(GLfixed x, GLfixed y, GLfixed z, GLfixed w, GLfixed h); - -void GL_APIENTRY -_mesa_DrawTexxvOES(const GLfixed *coords); - -void GL_APIENTRY -_mesa_Fogx(GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_Fogxv(GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_Frustumf(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar); - -void GL_APIENTRY -_mesa_Frustumx(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, - GLfixed zNear, GLfixed zFar); - -void GL_APIENTRY -_mesa_GetClipPlanef(GLenum plane, GLfloat *equation); - -void GL_APIENTRY -_mesa_GetClipPlanex(GLenum plane, GLfixed *equation); - -void GL_APIENTRY -_mesa_GetLightxv(GLenum light, GLenum pname, GLfixed *params); - -void GL_APIENTRY -_mesa_GetMaterialxv(GLenum face, GLenum pname, GLfixed *params); - -void GL_APIENTRY -_check_GetTexGenivOES(GLenum coord, GLenum pname, GLint *params); - -void GL_APIENTRY -_mesa_GetTexEnvxv(GLenum target, GLenum pname, GLfixed *params); - -void GL_APIENTRY -_mesa_GetTexGenxvOES(GLenum coord, GLenum pname, GLfixed *params); - -void GL_APIENTRY -_mesa_GetTexParameterxv(GLenum target, GLenum pname, GLfixed *params); - -void GL_APIENTRY -_mesa_LightModelx(GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_LightModelxv(GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_Lightx(GLenum light, GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_Lightxv(GLenum light, GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_LineWidthx(GLfixed width); - -void GL_APIENTRY -_mesa_LoadMatrixx(const GLfixed *m); - -void GL_APIENTRY -_mesa_Materialx(GLenum face, GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_Materialxv(GLenum face, GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_MultMatrixx(const GLfixed *m); - -void GL_APIENTRY -_mesa_MultiTexCoord4x(GLenum texture, GLfixed s, GLfixed t, GLfixed r, GLfixed q); - -void GL_APIENTRY -_mesa_Normal3x(GLfixed nx, GLfixed ny, GLfixed nz); - -void GL_APIENTRY -_mesa_Orthof(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top, - GLfloat zNear, GLfloat zFar); - -void GL_APIENTRY -_mesa_Orthox(GLfixed left, GLfixed right, GLfixed bottom, GLfixed top, - GLfixed zNear, GLfixed zFar); - -void GL_APIENTRY -_mesa_PointParameterx(GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_PointParameterxv(GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_PointSizex(GLfixed size); - -void GL_APIENTRY -_mesa_PolygonOffsetx(GLfixed factor, GLfixed units); - -void GL_APIENTRY -_mesa_Rotatex(GLfixed angle, GLfixed x, GLfixed y, GLfixed z); - -void GL_APIENTRY -_mesa_SampleCoveragex(GLclampx value, GLboolean invert); - -void GL_APIENTRY -_mesa_Scalex(GLfixed x, GLfixed y, GLfixed z); - -void GL_APIENTRY -_mesa_TexEnvx(GLenum target, GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_TexEnvxv(GLenum target, GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_check_TexGeniOES(GLenum coord, GLenum pname, GLint param); - -void GL_APIENTRY -_check_TexGenivOES(GLenum coord, GLenum pname, const GLint *params); - -void GL_APIENTRY -_mesa_TexGenxOES(GLenum coord, GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_TexGenxvOES(GLenum coord, GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_TexParameterx(GLenum target, GLenum pname, GLfixed param); - -void GL_APIENTRY -_mesa_TexParameterxv(GLenum target, GLenum pname, const GLfixed *params); - -void GL_APIENTRY -_mesa_Translatex(GLfixed x, GLfixed y, GLfixed z); - -#endif /* ES1_CONVERSION_H */ diff --git a/src/mesa/main/eval.c b/src/mesa/main/eval.c index 9db9934eaef..320e35bd6e9 100644 --- a/src/mesa/main/eval.c +++ b/src/mesa/main/eval.c @@ -37,12 +37,13 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "eval.h" #include "macros.h" #include "mtypes.h" #include "main/dispatch.h" +#include "api_exec_decl.h" /* @@ -823,19 +824,6 @@ _mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, } -void -_mesa_install_eval_vtxfmt(struct _glapi_table *disp, - const GLvertexformat *vfmt) -{ - SET_EvalCoord1f(disp, vfmt->EvalCoord1f); - SET_EvalCoord1fv(disp, vfmt->EvalCoord1fv); - SET_EvalCoord2f(disp, vfmt->EvalCoord2f); - SET_EvalCoord2fv(disp, vfmt->EvalCoord2fv); - SET_EvalPoint1(disp, vfmt->EvalPoint1); - SET_EvalPoint2(disp, vfmt->EvalPoint2); -} - - /**********************************************************************/ /***** Initialization *****/ /**********************************************************************/ diff --git a/src/mesa/main/eval.h b/src/mesa/main/eval.h index 938e3579b0e..2b317d7182d 100644 --- a/src/mesa/main/eval.h +++ b/src/mesa/main/eval.h @@ -62,51 +62,7 @@ extern GLfloat *_mesa_copy_map_points2d(GLenum target, GLint vstride, GLint vorder, const GLdouble *points ); -extern void -_mesa_install_eval_vtxfmt(struct _glapi_table *disp, - const GLvertexformat *vfmt); - extern void _mesa_init_eval( struct gl_context *ctx ); extern void _mesa_free_eval_data( struct gl_context *ctx ); -void GLAPIENTRY -_mesa_Map1f( GLenum target, GLfloat u1, GLfloat u2, GLint stride, - GLint order, const GLfloat *points ); -void GLAPIENTRY -_mesa_Map1d( GLenum target, GLdouble u1, GLdouble u2, GLint stride, - GLint order, const GLdouble *points ); -void GLAPIENTRY -_mesa_Map2f( GLenum target, - GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, - GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, - const GLfloat *points); -void GLAPIENTRY -_mesa_Map2d( GLenum target, - GLdouble u1, GLdouble u2, GLint ustride, GLint uorder, - GLdouble v1, GLdouble v2, GLint vstride, GLint vorder, - const GLdouble *points ); -void GLAPIENTRY -_mesa_GetnMapdvARB( GLenum target, GLenum query, GLsizei bufSize, - GLdouble *v ); -void GLAPIENTRY -_mesa_GetMapdv( GLenum target, GLenum query, GLdouble *v ); -void GLAPIENTRY -_mesa_GetnMapfvARB( GLenum target, GLenum query, GLsizei bufSize, GLfloat *v ); -void GLAPIENTRY -_mesa_GetMapfv( GLenum target, GLenum query, GLfloat *v ); -void GLAPIENTRY -_mesa_GetnMapivARB( GLenum target, GLenum query, GLsizei bufSize, GLint *v ); -void GLAPIENTRY -_mesa_GetMapiv( GLenum target, GLenum query, GLint *v ); -void GLAPIENTRY -_mesa_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ); -void GLAPIENTRY -_mesa_MapGrid1d( GLint un, GLdouble u1, GLdouble u2 ); -void GLAPIENTRY -_mesa_MapGrid2f( GLint un, GLfloat u1, GLfloat u2, - GLint vn, GLfloat v1, GLfloat v2 ); -void GLAPIENTRY -_mesa_MapGrid2d( GLint un, GLdouble u1, GLdouble u2, - GLint vn, GLdouble v1, GLdouble v2 ); - #endif /* EVAL_H */ diff --git a/src/mesa/main/execmem.c b/src/mesa/main/execmem.c deleted file mode 100644 index a3e76c5d0b0..00000000000 --- a/src/mesa/main/execmem.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file execmem.c - * Functions for allocating executable memory. - * - * \author Keith Whitwell - */ - - -#include <stdio.h> -#include "main/glheader.h" -#include "execmem.h" -#include "c11/threads.h" - - -#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(__sun) || defined(__HAIKU__) - -/* - * Allocate a large block of memory which can hold code then dole it out - * in pieces by means of the generic memory manager code. -*/ - -#include <unistd.h> -#include <sys/mman.h> -#include "util/u_mm.h" - -#ifdef MESA_SELINUX -#include <selinux/selinux.h> -#endif - - -#ifndef MAP_ANONYMOUS -#define MAP_ANONYMOUS MAP_ANON -#endif - - -#define EXEC_HEAP_SIZE (10*1024*1024) - -static mtx_t exec_mutex = _MTX_INITIALIZER_NP; - -static struct mem_block *exec_heap = NULL; -static unsigned char *exec_mem = NULL; - - -static int -init_heap(void) -{ -#ifdef MESA_SELINUX - if (is_selinux_enabled()) { - if (!security_get_boolean_active("allow_execmem") || - !security_get_boolean_pending("allow_execmem")) - return 0; - } -#endif - - if (!exec_heap) - exec_heap = u_mmInit( 0, EXEC_HEAP_SIZE ); - - if (!exec_mem) - exec_mem = mmap(NULL, EXEC_HEAP_SIZE, PROT_EXEC | PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); - - return (exec_mem != MAP_FAILED); -} - - -void * -_mesa_exec_malloc(unsigned size) -{ - struct mem_block *block = NULL; - void *addr = NULL; - - mtx_lock(&exec_mutex); - - if (!init_heap()) - goto bail; - - if (exec_heap) { - size = (size + 31) & ~31; - block = u_mmAllocMem(exec_heap, size, 5, 0); - } - - if (block) - addr = exec_mem + block->ofs; - else - printf("_mesa_exec_malloc failed\n"); - -bail: - mtx_unlock(&exec_mutex); - - return addr; -} - - -void -_mesa_exec_free(void *addr) -{ - mtx_lock(&exec_mutex); - - if (exec_heap) { - struct mem_block *block = u_mmFindBlock(exec_heap, (unsigned char *)addr - exec_mem); - - if (block) - u_mmFreeMem(block); - } - - mtx_unlock(&exec_mutex); -} - - -#else - -/* - * Just use regular memory. - */ - -void * -_mesa_exec_malloc(unsigned size) -{ - return malloc( size ); -} - - -void -_mesa_exec_free(void *addr) -{ - free(addr); -} - - -#endif diff --git a/src/mesa/main/execmem.h b/src/mesa/main/execmem.h deleted file mode 100644 index d98cad7135b..00000000000 --- a/src/mesa/main/execmem.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef EXECMEM_H -#define EXECMEM_H - -#include "glheader.h" - -extern void * -_mesa_exec_malloc(unsigned size); - -extern void -_mesa_exec_free(void *addr); - - -#endif /* EXECMEM_H */ diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index 99a17279073..e007fed65eb 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -31,7 +31,7 @@ #include "util/os_misc.h" -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "extensions.h" @@ -113,82 +113,6 @@ _mesa_override_extensions(struct gl_context *ctx) } } - -/** - * Enable all extensions suitable for a software-only renderer. - * This is a convenience function used by the mesa/swrast drivers. - */ -void -_mesa_enable_sw_extensions(struct gl_context *ctx) -{ - ctx->Extensions.ARB_depth_clamp = GL_TRUE; - ctx->Extensions.ARB_depth_texture = GL_TRUE; - ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE; - ctx->Extensions.ARB_draw_instanced = GL_TRUE; - ctx->Extensions.ARB_explicit_attrib_location = GL_TRUE; - ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; - ctx->Extensions.ARB_fragment_program = GL_TRUE; - ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE; - ctx->Extensions.ARB_fragment_shader = GL_TRUE; - ctx->Extensions.ARB_framebuffer_object = GL_TRUE; - ctx->Extensions.ARB_half_float_vertex = GL_TRUE; - ctx->Extensions.ARB_map_buffer_range = GL_TRUE; - ctx->Extensions.ARB_occlusion_query = GL_TRUE; - ctx->Extensions.ARB_occlusion_query2 = GL_TRUE; - ctx->Extensions.ARB_point_sprite = GL_TRUE; - ctx->Extensions.ARB_shadow = GL_TRUE; - ctx->Extensions.ARB_texture_border_clamp = GL_TRUE; - ctx->Extensions.ARB_texture_compression_bptc = GL_TRUE; - ctx->Extensions.ARB_texture_cube_map = GL_TRUE; - ctx->Extensions.ARB_texture_env_combine = GL_TRUE; - ctx->Extensions.ARB_texture_env_crossbar = GL_TRUE; - ctx->Extensions.ARB_texture_env_dot3 = GL_TRUE; - ctx->Extensions.ARB_texture_filter_anisotropic = GL_TRUE; - ctx->Extensions.ARB_texture_float = GL_TRUE; - ctx->Extensions.ARB_texture_mirror_clamp_to_edge = GL_TRUE; - ctx->Extensions.ARB_texture_non_power_of_two = GL_TRUE; - ctx->Extensions.ARB_texture_rg = GL_TRUE; - ctx->Extensions.ARB_texture_compression_rgtc = GL_TRUE; - ctx->Extensions.ARB_vertex_program = GL_TRUE; - ctx->Extensions.ARB_vertex_shader = GL_TRUE; - ctx->Extensions.ARB_sync = GL_TRUE; - ctx->Extensions.APPLE_object_purgeable = GL_TRUE; - ctx->Extensions.ATI_fragment_shader = GL_TRUE; - ctx->Extensions.ATI_texture_compression_3dc = GL_TRUE; - ctx->Extensions.ATI_texture_env_combine3 = GL_TRUE; - ctx->Extensions.ATI_texture_mirror_once = GL_TRUE; - ctx->Extensions.EXT_blend_color = GL_TRUE; - ctx->Extensions.EXT_blend_equation_separate = GL_TRUE; - ctx->Extensions.EXT_blend_func_separate = GL_TRUE; - ctx->Extensions.EXT_blend_minmax = GL_TRUE; - ctx->Extensions.EXT_depth_bounds_test = GL_TRUE; - ctx->Extensions.EXT_draw_buffers2 = GL_TRUE; - ctx->Extensions.EXT_pixel_buffer_object = GL_TRUE; - ctx->Extensions.EXT_point_parameters = GL_TRUE; - ctx->Extensions.EXT_provoking_vertex = GL_TRUE; - ctx->Extensions.EXT_stencil_two_side = GL_TRUE; - ctx->Extensions.EXT_texture_array = GL_TRUE; - ctx->Extensions.EXT_texture_compression_latc = GL_TRUE; - ctx->Extensions.EXT_texture_env_dot3 = GL_TRUE; - ctx->Extensions.EXT_texture_filter_anisotropic = GL_TRUE; - ctx->Extensions.EXT_texture_mirror_clamp = GL_TRUE; - ctx->Extensions.EXT_texture_shared_exponent = GL_TRUE; - ctx->Extensions.EXT_texture_sRGB = GL_TRUE; - ctx->Extensions.EXT_texture_sRGB_decode = GL_TRUE; - ctx->Extensions.EXT_texture_swizzle = GL_TRUE; - /*ctx->Extensions.EXT_transform_feedback = GL_TRUE;*/ - ctx->Extensions.EXT_vertex_array_bgra = GL_TRUE; - ctx->Extensions.MESA_ycbcr_texture = GL_TRUE; - ctx->Extensions.NV_conditional_render = GL_TRUE; - ctx->Extensions.NV_texture_env_combine4 = GL_TRUE; - ctx->Extensions.NV_texture_rectangle = GL_TRUE; - ctx->Extensions.EXT_gpu_program_parameters = GL_TRUE; - ctx->Extensions.OES_standard_derivatives = GL_TRUE; - ctx->Extensions.TDFX_texture_compression_FXT1 = GL_TRUE; - ctx->Extensions.ANGLE_texture_compression_dxt = GL_TRUE; - ctx->Extensions.EXT_texture_compression_s3tc = GL_TRUE; -} - /** * Either enable or disable the named extension. * \return offset of extensions withint `ext' or 0 if extension is not known @@ -223,11 +147,11 @@ free_unknown_extensions_strings(void) /** - * \brief Initialize extension override tables based on \c MESA_EXTENSION_OVERRIDE + * \brief Initialize extension override tables based on \c override * * This should be called one time early during first context initialization. - * \c MESA_EXTENSION_OVERRIDE is a space-separated list of extensions to + * \c override is a space-separated list of extensions to * enable or disable. The list is processed thus: * - Enable recognized extension names that are prefixed with '+'. * - Disable recognized extension names that are prefixed with '-'. @@ -235,9 +159,8 @@ free_unknown_extensions_strings(void) * - Collect unrecognized extension names in a new string. */ void -_mesa_one_time_init_extension_overrides(void) +_mesa_one_time_init_extension_overrides(const char *override) { - const char *env_const = os_get_option("MESA_EXTENSION_OVERRIDE"); char *env; char *ext; size_t offset; @@ -246,12 +169,12 @@ _mesa_one_time_init_extension_overrides(void) memset(&_mesa_extension_override_enables, 0, sizeof(struct gl_extensions)); memset(&_mesa_extension_override_disables, 0, sizeof(struct gl_extensions)); - if (env_const == NULL) { + if (override == NULL || override[0] == '\0') { return; } - /* Copy env_const because strtok() is destructive. */ - env = strdup(env_const); + /* Copy 'override' because strtok() is destructive. */ + env = strdup(override); if (env == NULL) return; @@ -282,6 +205,11 @@ _mesa_one_time_init_extension_overrides(void) else recognized = false; + if (!enable && recognized && offset <= 1) { + printf("Warning: extension '%s' cannot be disabled\n", ext); + offset = set_extension(&_mesa_extension_override_disables, i, 0); + } + if (!recognized && enable) { if (unknown_ext >= MAX_UNRECOGNIZED_EXTENSIONS) { static bool warned; @@ -328,6 +256,50 @@ _mesa_init_extensions(struct gl_extensions *extensions) /* Then, selectively turn default extensions on. */ extensions->dummy_true = GL_TRUE; + + /* Always enable these extensions for all drivers. + * We can't use dummy_true in extensions_table.h for these + * because this would make them non-disablable using + * _mesa_override_extensions. + */ + extensions->MESA_pack_invert = GL_TRUE; + extensions->MESA_window_pos = GL_TRUE; + + extensions->ARB_ES2_compatibility = GL_TRUE; + extensions->ARB_draw_elements_base_vertex = GL_TRUE; + extensions->ARB_explicit_attrib_location = GL_TRUE; + extensions->ARB_explicit_uniform_location = GL_TRUE; + extensions->ARB_fragment_coord_conventions = GL_TRUE; + extensions->ARB_fragment_program = GL_TRUE; + extensions->ARB_fragment_shader = GL_TRUE; + extensions->ARB_half_float_vertex = GL_TRUE; + extensions->ARB_internalformat_query = GL_TRUE; + extensions->ARB_internalformat_query2 = GL_TRUE; + extensions->ARB_map_buffer_range = GL_TRUE; + extensions->ARB_occlusion_query = GL_TRUE; + extensions->ARB_sync = GL_TRUE; + extensions->ARB_vertex_program = GL_TRUE; + extensions->ARB_vertex_shader = GL_TRUE; + + extensions->EXT_EGL_image_storage = GL_TRUE; + extensions->EXT_gpu_program_parameters = GL_TRUE; + extensions->EXT_provoking_vertex = GL_TRUE; + extensions->EXT_stencil_two_side = GL_TRUE; + extensions->EXT_texture_env_dot3 = GL_TRUE; + + extensions->ATI_fragment_shader = GL_TRUE; + extensions->ATI_texture_env_combine3 = GL_TRUE; + + extensions->MESA_framebuffer_flip_y = GL_TRUE; + + extensions->NV_copy_image = GL_TRUE; + extensions->NV_fog_distance = GL_TRUE; + extensions->NV_texture_env_combine4 = GL_TRUE; + extensions->NV_texture_rectangle = GL_TRUE; + + extensions->OES_EGL_image = GL_TRUE; + extensions->OES_EGL_image_external = GL_TRUE; + extensions->OES_draw_texture = GL_TRUE; } @@ -382,7 +354,7 @@ GLubyte* _mesa_make_extension_string(struct gl_context *ctx) { /* The extension string. */ - char *exts = 0; + char *exts = NULL; /* Length of extension string. */ size_t length = 0; /* Number of extensions */ @@ -418,7 +390,7 @@ _mesa_make_extension_string(struct gl_context *ctx) if (unrecognized_extensions.names[k]) length += 1 + strlen(unrecognized_extensions.names[k]); /* +1 for space */ - exts = calloc(ALIGN(length + 1, 4), sizeof(char)); + exts = calloc(align_uintptr(length + 1, 4), sizeof(char)); if (exts == NULL) { return NULL; } diff --git a/src/mesa/main/extensions.h b/src/mesa/main/extensions.h index 303929baabc..8f84891757e 100644 --- a/src/mesa/main/extensions.h +++ b/src/mesa/main/extensions.h @@ -45,9 +45,7 @@ extern "C" { struct gl_context; struct gl_extensions; -extern void _mesa_enable_sw_extensions(struct gl_context *ctx); - -extern void _mesa_one_time_init_extension_overrides(void); +extern void _mesa_one_time_init_extension_overrides(const char *override); extern void _mesa_init_extensions(struct gl_extensions *extentions); diff --git a/src/mesa/main/extensions_table.h b/src/mesa/main/extensions_table.h index a09b58afbb5..73ca6dbd561 100644 --- a/src/mesa/main/extensions_table.h +++ b/src/mesa/main/extensions_table.h @@ -13,6 +13,7 @@ EXT(AMD_conservative_depth , ARB_conservative_depth EXT(AMD_depth_clamp_separate , AMD_depth_clamp_separate , GLL, GLC, x , x , 2009) EXT(AMD_draw_buffers_blend , ARB_draw_buffers_blend , GLL, GLC, x , x , 2009) EXT(AMD_framebuffer_multisample_advanced , AMD_framebuffer_multisample_advanced , GLL, GLC, x , ES2, 2018) +EXT(AMD_gpu_shader_half_float , AMD_gpu_shader_half_float , 40, 40, x , x , 2016) EXT(AMD_gpu_shader_int64 , ARB_gpu_shader_int64 , x , GLC, x , x , 2015) EXT(AMD_multi_draw_indirect , ARB_draw_indirect , GLL, GLC, x , x , 2011) EXT(AMD_performance_monitor , AMD_performance_monitor , GLL, GLC, x , ES2, 2007) @@ -31,13 +32,13 @@ EXT(ANGLE_pack_reverse_row_order , dummy_true EXT(ANGLE_texture_compression_dxt3 , ANGLE_texture_compression_dxt , GLL, GLC, ES1, ES2, 2011) EXT(ANGLE_texture_compression_dxt5 , ANGLE_texture_compression_dxt , GLL, GLC, ES1, ES2, 2011) -EXT(APPLE_object_purgeable , APPLE_object_purgeable , GLL, GLC, x , x , 2006) EXT(APPLE_packed_pixels , dummy_true , GLL, x , x , x , 2002) +EXT(APPLE_sync , ARB_sync , x , x , ES1, ES2, 2012) EXT(APPLE_texture_max_level , dummy_true , x , x , ES1, ES2, 2009) EXT(ARB_ES2_compatibility , ARB_ES2_compatibility , GLL, GLC, x , x , 2009) EXT(ARB_ES3_1_compatibility , ARB_ES3_1_compatibility , GLL, GLC, x , x , 2014) -EXT(ARB_ES3_2_compatibility , ARB_ES3_2_compatibility , x , GLC, x , x , 2015) +EXT(ARB_ES3_2_compatibility , ARB_ES3_2_compatibility , GLL, GLC, x , x , 2015) EXT(ARB_ES3_compatibility , ARB_ES3_compatibility , GLL, GLC, x , x , 2012) EXT(ARB_arrays_of_arrays , ARB_arrays_of_arrays , GLL, GLC, x , x , 2012) EXT(ARB_base_instance , ARB_base_instance , GLL, GLC, x , x , 2011) @@ -45,7 +46,7 @@ EXT(ARB_bindless_texture , ARB_bindless_texture EXT(ARB_blend_func_extended , ARB_blend_func_extended , GLL, GLC, x , x , 2009) EXT(ARB_buffer_storage , ARB_buffer_storage , GLL, GLC, x , x , 2013) EXT(ARB_clear_buffer_object , dummy_true , GLL, GLC, x , x , 2012) -EXT(ARB_clear_texture , ARB_clear_texture , GLL, GLC, x , x , 2013) +EXT(ARB_clear_texture , dummy_true , GLL, GLC, x , x , 2013) EXT(ARB_clip_control , ARB_clip_control , GLL, GLC, x , x , 2014) EXT(ARB_color_buffer_float , ARB_color_buffer_float , GLL, GLC, x , x , 2004) EXT(ARB_compatibility , ARB_compatibility , GLL, x , x , x , 2009) @@ -60,7 +61,7 @@ EXT(ARB_cull_distance , ARB_cull_distance EXT(ARB_debug_output , dummy_true , GLL, GLC, x , x , 2009) EXT(ARB_depth_buffer_float , ARB_depth_buffer_float , GLL, GLC, x , x , 2008) EXT(ARB_depth_clamp , ARB_depth_clamp , GLL, GLC, x , x , 2003) -EXT(ARB_depth_texture , ARB_depth_texture , GLL, x , x , x , 2001) +EXT(ARB_depth_texture , dummy_true , GLL, x , x , x , 2001) EXT(ARB_derivative_control , ARB_derivative_control , GLL, GLC, x , x , 2014) EXT(ARB_direct_state_access , dummy_true , 31, GLC, x , x , 2014) EXT(ARB_draw_buffers , dummy_true , GLL, GLC, x , x , 2002) @@ -103,9 +104,9 @@ EXT(ARB_occlusion_query , ARB_occlusion_query EXT(ARB_occlusion_query2 , ARB_occlusion_query2 , GLL, GLC, x , x , 2003) EXT(ARB_parallel_shader_compile , dummy_true , GLL, GLC, x , x , 2015) EXT(ARB_pipeline_statistics_query , ARB_pipeline_statistics_query , GLL, GLC, x , x , 2014) -EXT(ARB_pixel_buffer_object , EXT_pixel_buffer_object , GLL, GLC, x , x , 2004) -EXT(ARB_point_parameters , EXT_point_parameters , GLL, x , x , x , 1997) -EXT(ARB_point_sprite , ARB_point_sprite , GLL, GLC, x , x , 2003) +EXT(ARB_pixel_buffer_object , dummy_true , GLL, GLC, x , x , 2004) +EXT(ARB_point_parameters , dummy_true , GLL, x , x , x , 1997) +EXT(ARB_point_sprite , dummy_true , GLL, GLC, x , x , 2003) EXT(ARB_polygon_offset_clamp , ARB_polygon_offset_clamp , GLL, GLC, x , x , 2017) EXT(ARB_post_depth_coverage , ARB_post_depth_coverage , GLL, GLC, x , x, 2015) EXT(ARB_program_interface_query , dummy_true , GLL, GLC, x , x , 2012) @@ -142,24 +143,27 @@ EXT(ARB_shading_language_include , dummy_true EXT(ARB_shading_language_packing , ARB_shading_language_packing , GLL, GLC, x , x , 2011) EXT(ARB_shadow , ARB_shadow , GLL, x , x , x , 2001) EXT(ARB_sparse_buffer , ARB_sparse_buffer , GLL, GLC, x , x , 2014) +EXT(ARB_sparse_texture , ARB_sparse_texture , GLL, GLC, x , x , 2013) +EXT(ARB_sparse_texture2 , ARB_sparse_texture2 , GLL, GLC, x , x , 2015) +EXT(ARB_sparse_texture_clamp , ARB_sparse_texture_clamp , GLL, GLC, x , x , 2015) EXT(ARB_spirv_extensions , ARB_spirv_extensions , GLL, GLC, x , x , 2016) EXT(ARB_stencil_texturing , ARB_stencil_texturing , GLL, GLC, x , x , 2012) EXT(ARB_sync , ARB_sync , GLL, GLC, x , x , 2003) EXT(ARB_tessellation_shader , ARB_tessellation_shader , GLL, GLC, x , x , 2009) EXT(ARB_texture_barrier , NV_texture_barrier , GLL, GLC, x , x , 2014) -EXT(ARB_texture_border_clamp , ARB_texture_border_clamp , GLL, x , x , x , 2000) +EXT(ARB_texture_border_clamp , dummy_true , GLL, GLC, x , x , 2000) EXT(ARB_texture_buffer_object , ARB_texture_buffer_object , GLL, GLC, x , x , 2008) EXT(ARB_texture_buffer_object_rgb32 , ARB_texture_buffer_object_rgb32 , GLL, GLC, x , x , 2009) EXT(ARB_texture_buffer_range , ARB_texture_buffer_range , GLL, GLC, x , x , 2012) EXT(ARB_texture_compression , dummy_true , GLL, x , x , x , 2000) EXT(ARB_texture_compression_bptc , ARB_texture_compression_bptc , GLL, GLC, x , x , 2010) EXT(ARB_texture_compression_rgtc , ARB_texture_compression_rgtc , GLL, GLC, x , x , 2004) -EXT(ARB_texture_cube_map , ARB_texture_cube_map , GLL, x , x , x , 1999) +EXT(ARB_texture_cube_map , dummy_true , GLL, x , x , x , 1999) EXT(ARB_texture_cube_map_array , ARB_texture_cube_map_array , GLL, GLC, x , x , 2009) EXT(ARB_texture_env_add , dummy_true , GLL, x , x , x , 1999) -EXT(ARB_texture_env_combine , ARB_texture_env_combine , GLL, x , x , x , 2001) -EXT(ARB_texture_env_crossbar , ARB_texture_env_crossbar , GLL, x , x , x , 2001) -EXT(ARB_texture_env_dot3 , ARB_texture_env_dot3 , GLL, x , x , x , 2001) +EXT(ARB_texture_env_combine , dummy_true , GLL, x , x , x , 2001) +EXT(ARB_texture_env_crossbar , dummy_true , GLL, x , x , x , 2001) +EXT(ARB_texture_env_dot3 , dummy_true , GLL, x , x , x , 2001) EXT(ARB_texture_filter_anisotropic , ARB_texture_filter_anisotropic , GLL, GLC, x , x , 2017) EXT(ARB_texture_filter_minmax , ARB_texture_filter_minmax , GLL, GLC, x , x , 2015) EXT(ARB_texture_float , ARB_texture_float , GLL, GLC, x , x , 2004) @@ -197,6 +201,8 @@ EXT(ARB_vertex_type_2_10_10_10_rev , ARB_vertex_type_2_10_10_10_rev EXT(ARB_viewport_array , ARB_viewport_array , GLL, GLC, x , x , 2010) EXT(ARB_window_pos , dummy_true , GLL, x , x , x , 2001) +EXT(ARM_shader_framebuffer_fetch_depth_stencil, ARM_shader_framebuffer_fetch_depth_stencil, GLL, GLC, x , ES2, 2014) + EXT(ATI_blend_equation_separate , EXT_blend_equation_separate , GLL, GLC, x , x , 2003) EXT(ATI_draw_buffers , dummy_true , GLL, x , x , x , 2002) EXT(ATI_fragment_shader , ATI_fragment_shader , GLL, x , x , x , 2001) @@ -212,21 +218,23 @@ EXT(EXT_EGL_sync , dummy_true EXT(EXT_abgr , dummy_true , GLL, GLC, x , x , 1995) EXT(EXT_base_instance , ARB_base_instance , x , x , x , 30, 2014) EXT(EXT_bgra , dummy_true , GLL, x , x , x , 1995) -EXT(EXT_blend_color , EXT_blend_color , GLL, x , x , x , 1995) +EXT(EXT_blend_color , dummy_true , GLL, x , x , x , 1995) EXT(EXT_blend_equation_separate , EXT_blend_equation_separate , GLL, GLC, x , x , 2003) EXT(EXT_blend_func_extended , ARB_blend_func_extended , x , x , x , ES2, 2015) -EXT(EXT_blend_func_separate , EXT_blend_func_separate , GLL, x , x , x , 1999) -EXT(EXT_blend_minmax , EXT_blend_minmax , GLL, x , ES1, ES2, 1995) +EXT(EXT_blend_func_separate , dummy_true , GLL, x , x , x , 1999) +EXT(EXT_blend_minmax , dummy_true , GLL, x , ES1, ES2, 1995) EXT(EXT_blend_subtract , dummy_true , GLL, x , x , x , 1995) EXT(EXT_buffer_storage , ARB_buffer_storage , x , x , x , 31, 2015) +EXT(EXT_clear_texture , dummy_true , x , x , x , 31, 2016) EXT(EXT_clip_control , ARB_clip_control , x , x , x , ES2, 2017) EXT(EXT_clip_cull_distance , ARB_cull_distance , x , x , x , 30, 2016) -EXT(EXT_color_buffer_float , dummy_true , x , x , x , 30, 2013) +EXT(EXT_color_buffer_float , EXT_color_buffer_float , x , x , x , 30, 2013) EXT(EXT_color_buffer_half_float , EXT_color_buffer_half_float , x , x , x , 20, 2017) EXT(EXT_compiled_vertex_array , dummy_true , GLL, x , x , x , 1996) EXT(EXT_compressed_ETC1_RGB8_sub_texture , OES_compressed_ETC1_RGB8_texture , x , x , ES1, ES2, 2014) EXT(EXT_copy_image , OES_copy_image , x , x , x , 30, 2014) EXT(EXT_copy_texture , dummy_true , GLL, x , x , x , 1995) +EXT(EXT_debug_label , dummy_true , GLL, GLC, 11, ES2, 2013) EXT(EXT_demote_to_helper_invocation , EXT_demote_to_helper_invocation , GLL, GLC, ES1, ES2, 2019) EXT(EXT_depth_bounds_test , EXT_depth_bounds_test , GLL, GLC, x , x , 2002) EXT(EXT_depth_clamp , ARB_depth_clamp , x , x , x , ES2, 2019) @@ -254,9 +262,11 @@ EXT(EXT_gpu_program_parameters , EXT_gpu_program_parameters * Additionally, EXT_gpu_shader4 would reintroduce functions that were removed in GLSL 1.40. */ EXT(EXT_gpu_shader4 , EXT_gpu_shader4 , GLL, x , x , x , 2006) EXT(EXT_gpu_shader5 , ARB_gpu_shader5 , x , x , x , 31, 2014) +EXT(EXT_instanced_arrays , ARB_instanced_arrays , x , x , x , ES2, 2012) EXT(EXT_map_buffer_range , ARB_map_buffer_range , x , x , ES1, ES2, 2012) EXT(EXT_memory_object , EXT_memory_object , GLL, GLC, x , ES2, 2017) EXT(EXT_memory_object_fd , EXT_memory_object_fd , GLL, GLC, x , ES2, 2017) +EXT(EXT_memory_object_win32 , EXT_memory_object_win32 , GLL, GLC, x , ES2, 2017) EXT(EXT_multi_draw_arrays , dummy_true , GLL, x , ES1, ES2, 1999) EXT(EXT_multisampled_render_to_texture , EXT_multisampled_render_to_texture , x , x , x , ES2, 2016) EXT(EXT_multisampled_render_to_texture2 , EXT_multisampled_render_to_texture , x , x , x , ES2, 2016) @@ -264,19 +274,20 @@ EXT(EXT_occlusion_query_boolean , ARB_occlusion_query2 EXT(EXT_packed_depth_stencil , dummy_true , GLL, GLC, x , x , 2005) EXT(EXT_packed_float , EXT_packed_float , GLL, GLC, x , x , 2004) EXT(EXT_packed_pixels , dummy_true , GLL, x , x , x , 1997) -EXT(EXT_pixel_buffer_object , EXT_pixel_buffer_object , GLL, GLC, x , x , 2004) -EXT(EXT_point_parameters , EXT_point_parameters , GLL, x , x , x , 1997) +EXT(EXT_pixel_buffer_object , dummy_true , GLL, GLC, x , x , 2004) +EXT(EXT_point_parameters , dummy_true , GLL, x , x , x , 1997) EXT(EXT_polygon_offset_clamp , ARB_polygon_offset_clamp , GLL, GLC, ES1, ES2, 2014) EXT(EXT_primitive_bounding_box , OES_primitive_bounding_box , x , x , x , 31, 2014) EXT(EXT_provoking_vertex , EXT_provoking_vertex , GLL, GLC, x , x , 2009) EXT(EXT_read_format_bgra , dummy_true , x , x , ES1, ES2, 2009) -EXT(EXT_render_snorm , EXT_render_snorm , x , x , x, 31, 2014) +EXT(EXT_render_snorm , EXT_render_snorm , x , x , x, 30, 2014) EXT(EXT_rescale_normal , dummy_true , GLL, x , x , x , 1997) EXT(EXT_robustness , KHR_robustness , x, x, x , ES2, 2011) EXT(EXT_sRGB_write_control , EXT_framebuffer_sRGB , x, x , x , 30, 2013) EXT(EXT_secondary_color , dummy_true , GLL, x , x , x , 1999) EXT(EXT_semaphore , EXT_semaphore , GLL, GLC, x , ES2, 2017) EXT(EXT_semaphore_fd , EXT_semaphore_fd , GLL, GLC, x , ES2, 2017) +EXT(EXT_semaphore_win32 , EXT_semaphore_win32 , GLL, GLC, x , ES2, 2017) EXT(EXT_separate_shader_objects , dummy_true , x , x , x , ES2, 2013) EXT(EXT_separate_specular_color , dummy_true , GLL, x , x , x , 1997) EXT(EXT_shader_framebuffer_fetch , EXT_shader_framebuffer_fetch , GLL, GLC, x , ES2, 2013) @@ -297,7 +308,7 @@ EXT(EXT_tessellation_shader , ARB_tessellation_shader EXT(EXT_texture , dummy_true , GLL, x , x , x , 1996) EXT(EXT_texture3D , dummy_true , GLL, x , x , x , 1996) EXT(EXT_texture_array , EXT_texture_array , GLL, GLC, x , x , 2006) -EXT(EXT_texture_border_clamp , ARB_texture_border_clamp , x , x , x , ES2, 2014) +EXT(EXT_texture_border_clamp , dummy_true , x , x , x , ES2, 2014) EXT(EXT_texture_buffer , OES_texture_buffer , x , x , x , 31, 2014) EXT(EXT_texture_buffer_object , EXT_texture_buffer_object , GLL, x , x , x , 2007) EXT(EXT_texture_compression_bptc , ARB_texture_compression_bptc , x , x , x , 30, 2017) @@ -306,7 +317,7 @@ EXT(EXT_texture_compression_latc , EXT_texture_compression_latc EXT(EXT_texture_compression_rgtc , ARB_texture_compression_rgtc , GLL, GLC, x , 30, 2004) EXT(EXT_texture_compression_s3tc , EXT_texture_compression_s3tc , GLL, GLC, x , ES2, 2000) EXT(EXT_texture_compression_s3tc_srgb , EXT_texture_compression_s3tc_srgb , x , x, x , ES2, 2016) -EXT(EXT_texture_cube_map , ARB_texture_cube_map , GLL, x , x , x , 2001) +EXT(EXT_texture_cube_map , dummy_true , GLL, x , x , x , 2001) EXT(EXT_texture_cube_map_array , OES_texture_cube_map_array , x , x , x , 31, 2014) EXT(EXT_texture_edge_clamp , dummy_true , GLL, x , x , x , 1997) EXT(EXT_texture_env_add , dummy_true , GLL, x , x , x , 1999) @@ -318,18 +329,20 @@ EXT(EXT_texture_format_BGRA8888 , dummy_true EXT(EXT_texture_integer , EXT_texture_integer , GLL, GLC, x , x , 2006) EXT(EXT_texture_lod_bias , dummy_true , GLL, x , ES1, x , 1999) EXT(EXT_texture_mirror_clamp , EXT_texture_mirror_clamp , GLL, GLC, x , x , 2004) +EXT(EXT_texture_mirror_clamp_to_edge , ARB_texture_mirror_clamp_to_edge , x , x , x , ES2, 2017) EXT(EXT_texture_norm16 , EXT_texture_norm16 , x , x , x , 31, 2014) EXT(EXT_texture_object , dummy_true , GLL, x , x , x , 1995) EXT(EXT_texture_query_lod , ARB_texture_query_lod , x , x , x , 30, 2019) EXT(EXT_texture_rectangle , NV_texture_rectangle , GLL, x , x , x , 2004) EXT(EXT_texture_rg , ARB_texture_rg , x , x , x , ES2, 2011) EXT(EXT_texture_sRGB , EXT_texture_sRGB , GLL, GLC, x , x , 2004) -EXT(EXT_texture_sRGB_R8 , EXT_texture_sRGB_R8 , GLL ,GLC, x , 30, 2015) -EXT(EXT_texture_sRGB_RG8 , EXT_texture_sRGB_RG8 , x , x , x , 30, 2015) +EXT(EXT_texture_sRGB_R8 , EXT_texture_sRGB_R8 , GLL, GLC, x , 30, 2015) +EXT(EXT_texture_sRGB_RG8 , EXT_texture_sRGB_RG8 , GLL, GLC, x , 30, 2015) EXT(EXT_texture_sRGB_decode , EXT_texture_sRGB_decode , GLL, GLC, x , 30, 2006) EXT(EXT_texture_shadow_lod , EXT_texture_shadow_lod , GLL, GLC, x , 30, 2018) EXT(EXT_texture_shared_exponent , EXT_texture_shared_exponent , GLL, GLC, x , x , 2004) EXT(EXT_texture_snorm , EXT_texture_snorm , GLL, GLC, x , x , 2009) +EXT(EXT_texture_storage , dummy_true , GLL, GLC, x , ES2, 2009) EXT(EXT_texture_swizzle , EXT_texture_swizzle , GLL, GLC, x , x , 2008) EXT(EXT_texture_type_2_10_10_10_REV , EXT_texture_type_2_10_10_10_REV , x , x , x , ES2, 2008) EXT(EXT_texture_view , OES_texture_view , x , x , x , 31, 2014) @@ -347,7 +360,7 @@ EXT(IBM_multimode_draw_arrays , dummy_true EXT(IBM_rasterpos_clip , dummy_true , GLL, x , x , x , 1996) EXT(IBM_texture_mirrored_repeat , dummy_true , GLL, x , x , x , 1998) -EXT(INGR_blend_func_separate , EXT_blend_func_separate , GLL, x , x , x , 1999) +EXT(INGR_blend_func_separate , dummy_true , GLL, x , x , x , 1999) EXT(INTEL_blackhole_render , INTEL_blackhole_render , 30, 30, x , ES2, 2018) EXT(INTEL_conservative_rasterization , INTEL_conservative_rasterization , x , GLC, x , 31, 2013) @@ -369,15 +382,18 @@ EXT(KHR_texture_compression_astc_sliced_3d , KHR_texture_compression_astc_slice EXT(MESA_bgra , dummy_true , x , x , x , ES2, 2021) EXT(MESA_framebuffer_flip_y , MESA_framebuffer_flip_y , 43, 43, x , 30, 2018) -EXT(MESA_pack_invert , dummy_true , GLL, GLC, x , x , 2002) +EXT(MESA_pack_invert , MESA_pack_invert , GLL, GLC, x , x , 2002) +EXT(MESA_sampler_objects , dummy_true , x , x , x , ES2, 2019) EXT(MESA_shader_integer_functions , MESA_shader_integer_functions , GLL, GLC, x , 30, 2016) +EXT(MESA_texture_const_bandwidth , MESA_texture_const_bandwidth , GLL, GLC, x , ES2, 2023) EXT(MESA_texture_signed_rgba , EXT_texture_snorm , GLL, GLC, x , x , 2009) EXT(MESA_tile_raster_order , MESA_tile_raster_order , GLL, GLC, x , ES2, 2017) -EXT(MESA_window_pos , dummy_true , GLL, x , x , x , 2000) +EXT(MESA_window_pos , MESA_window_pos , GLL, x , x , x , 2000) EXT(MESA_ycbcr_texture , MESA_ycbcr_texture , GLL, GLC, x , x , 2002) EXT(NVX_gpu_memory_info , NVX_gpu_memory_info , GLL, GLC, x , x , 2013) +EXT(NV_ES1_1_compatibility , dummy_true , GLL, x , x , x , 2022) EXT(NV_alpha_to_coverage_dither_control , NV_alpha_to_coverage_dither_control , GLL, GLC, x , ES2, 2017) EXT(NV_blend_square , dummy_true , GLL, x , x , x , 1999) EXT(NV_compute_shader_derivatives , NV_compute_shader_derivatives , GLL, GLC, x , 32, 2018) @@ -394,11 +410,13 @@ EXT(NV_fbo_color_attachments , dummy_true EXT(NV_fill_rectangle , NV_fill_rectangle , GLL, GLC, x , x , 2015) EXT(NV_fog_distance , NV_fog_distance , GLL, x , x , x , 2001) EXT(NV_fragment_shader_interlock , ARB_fragment_shader_interlock , GLL, GLC, x , 31, 2015) -EXT(NV_half_float , ARB_half_float_vertex , GLL, x, x , x, 2001) +EXT(NV_generate_mipmap_sRGB , EXT_framebuffer_sRGB , x , x , ES1, ES2, 2012) +EXT(NV_half_float , ARB_half_float_vertex , GLL, x , x , x , 2001) EXT(NV_image_formats , dummy_true , x , x , x , 31, 2014) EXT(NV_light_max_exponent , dummy_true , GLL, x , x , x , 1999) +EXT(NV_pack_subimage , dummy_true , x , x , x , ES2, 2009) EXT(NV_packed_depth_stencil , dummy_true , GLL, GLC, x , x , 2000) -EXT(NV_pixel_buffer_object , EXT_pixel_buffer_object , x , x , x , ES2, 2012) +EXT(NV_pixel_buffer_object , dummy_true , x , x , x , ES2, 2012) EXT(NV_primitive_restart , NV_primitive_restart , GLL, x , x , x , 2002) EXT(NV_read_buffer , dummy_true , x , x , x , ES2, 2011) EXT(NV_read_depth , dummy_true , x , x , x , ES2, 2011) @@ -407,8 +425,9 @@ EXT(NV_read_stencil , dummy_true EXT(NV_sample_locations , ARB_sample_locations , GLL, GLC, x , ES2, 2015) EXT(NV_shader_atomic_float , NV_shader_atomic_float , GLL, GLC, x , x , 2012) EXT(NV_shader_atomic_int64 , NV_shader_atomic_int64 , GLL, GLC, x , x , 2014) +EXT(NV_shader_noperspective_interpolation , EXT_gpu_shader4 , x , x , x , 30, 2014) EXT(NV_texgen_reflection , dummy_true , GLL, x , x , x , 1999) -EXT(NV_texture_barrier , NV_texture_barrier , GLL, GLC, x , x , 2009) +EXT(NV_texture_barrier , NV_texture_barrier , GLL, GLC, x , ES2, 2009) EXT(NV_texture_env_combine4 , NV_texture_env_combine4 , GLL, x , x , x , 1999) EXT(NV_texture_rectangle , NV_texture_rectangle , GLL, x , x , x , 2000) EXT(NV_vdpau_interop , NV_vdpau_interop , GLL, GLC, x , x , 2010) @@ -420,14 +439,14 @@ EXT(OES_EGL_image_external , OES_EGL_image_external EXT(OES_EGL_image_external_essl3 , OES_EGL_image_external , x , x , x , 30, 2015) EXT(OES_EGL_sync , dummy_true , x , x , ES1, ES2, 2010) EXT(OES_blend_equation_separate , EXT_blend_equation_separate , x , x , ES1, x , 2009) -EXT(OES_blend_func_separate , EXT_blend_func_separate , x , x , ES1, x , 2009) +EXT(OES_blend_func_separate , dummy_true , x , x , ES1, x , 2009) EXT(OES_blend_subtract , dummy_true , x , x , ES1, x , 2009) EXT(OES_byte_coordinates , dummy_true , x , x , ES1, x , 2002) EXT(OES_compressed_ETC1_RGB8_texture , OES_compressed_ETC1_RGB8_texture , x , x , ES1, ES2, 2005) EXT(OES_compressed_paletted_texture , dummy_true , x , x , ES1, x , 2003) EXT(OES_copy_image , OES_copy_image , x , x , x , 30, 2014) EXT(OES_depth24 , dummy_true , x , x , ES1, ES2, 2005) -EXT(OES_depth_texture , ARB_depth_texture , x , x , x , ES2, 2006) +EXT(OES_depth_texture , dummy_true , x , x , x , ES2, 2006) EXT(OES_depth_texture_cube_map , OES_depth_texture_cube_map , x , x , x , ES2, 2012) EXT(OES_draw_buffers_indexed , ARB_draw_buffers_blend , x , x , x , 30, 2014) EXT(OES_draw_elements_base_vertex , ARB_draw_elements_base_vertex , x , x , x , ES2, 2014) @@ -443,7 +462,7 @@ EXT(OES_gpu_shader5 , ARB_gpu_shader5 EXT(OES_mapbuffer , dummy_true , x , x , ES1, ES2, 2005) EXT(OES_packed_depth_stencil , dummy_true , x , x , ES1, ES2, 2007) EXT(OES_point_size_array , dummy_true , x , x , ES1, x , 2004) -EXT(OES_point_sprite , ARB_point_sprite , x , x , ES1, x , 2004) +EXT(OES_point_sprite , dummy_true , x , x , ES1, x , 2004) EXT(OES_primitive_bounding_box , OES_primitive_bounding_box , x , x , x , 31, 2014) EXT(OES_query_matrix , dummy_true , x , x , ES1, x , 2003) EXT(OES_read_format , dummy_true , GLL, x , ES1, x , 2003) @@ -461,13 +480,13 @@ EXT(OES_stencil_wrap , dummy_true EXT(OES_surfaceless_context , dummy_true , x , x , ES1, ES2, 2012) EXT(OES_tessellation_point_size , ARB_tessellation_shader , x , x , x , 31, 2014) EXT(OES_tessellation_shader , ARB_tessellation_shader , x , x , x , 31, 2014) -EXT(OES_texture_3D , dummy_true , x , x , x , ES2, 2005) -EXT(OES_texture_border_clamp , ARB_texture_border_clamp , x , x , x , ES2, 2014) +EXT(OES_texture_3D , OES_texture_3D , x , x , x , ES2, 2005) +EXT(OES_texture_border_clamp , dummy_true , x , x , x , ES2, 2014) EXT(OES_texture_buffer , OES_texture_buffer , x , x , x , 31, 2014) EXT(OES_texture_compression_astc , OES_texture_compression_astc , x , x , ES1, ES2, 2015) -EXT(OES_texture_cube_map , ARB_texture_cube_map , x , x , ES1, x , 2007) +EXT(OES_texture_cube_map , dummy_true , x , x , ES1, x , 2007) EXT(OES_texture_cube_map_array , OES_texture_cube_map_array , x , x , x , 31, 2014) -EXT(OES_texture_env_crossbar , ARB_texture_env_crossbar , x , x , ES1, x , 2005) +EXT(OES_texture_env_crossbar , dummy_true , x , x , ES1, x , 2005) EXT(OES_texture_float , OES_texture_float , x , x , x , ES2, 2005) EXT(OES_texture_float_linear , OES_texture_float_linear , x , x , x , ES2, 2005) EXT(OES_texture_half_float , OES_texture_half_float , x , x , x , ES2, 2005) @@ -484,7 +503,7 @@ EXT(OES_viewport_array , OES_viewport_array EXT(S3_s3tc , ANGLE_texture_compression_dxt , GLL, GLC, x , x , 1999) EXT(SGIS_generate_mipmap , dummy_true , GLL, x , x , x , 1997) -EXT(SGIS_texture_border_clamp , ARB_texture_border_clamp , GLL, x , x , x , 1997) +EXT(SGIS_texture_border_clamp , dummy_true , GLL, x , x , x , 1997) EXT(SGIS_texture_edge_clamp , dummy_true , GLL, x , x , x , 1997) EXT(SGIS_texture_lod , dummy_true , GLL, x , x , x , 1997) diff --git a/src/mesa/main/externalobjects.c b/src/mesa/main/externalobjects.c index 01c859f8301..6c119694fac 100644 --- a/src/mesa/main/externalobjects.c +++ b/src/mesa/main/externalobjects.c @@ -25,6 +25,7 @@ #include "mtypes.h" #include "bufferobj.h" #include "context.h" +#include "enums.h" #include "externalobjects.h" #include "teximage.h" #include "texobj.h" @@ -32,55 +33,95 @@ #include "texstorage.h" #include "util/u_memory.h" -/** - * Allocate and initialize a new memory object. But don't put it into the - * memory object hash table. - * - * Called via ctx->Driver.NewMemoryObject, unless overridden by a device - * driver. - * - * \return pointer to new memory object. - */ +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_texture.h" + +struct st_context; + +#include "frontend/drm_driver.h" +#ifdef HAVE_LIBDRM +#include "drm-uapi/drm_fourcc.h" +#endif + static struct gl_memory_object * -_mesa_new_memory_object(struct gl_context *ctx, GLuint name) +memoryobj_alloc(struct gl_context *ctx, GLuint name) { - struct gl_memory_object *obj = MALLOC_STRUCT(gl_memory_object); + struct gl_memory_object *obj = CALLOC_STRUCT(gl_memory_object); if (!obj) return NULL; - _mesa_initialize_memory_object(ctx, obj, name); + obj->Name = name; + obj->Dedicated = GL_FALSE; return obj; } -/** - * Delete a memory object. Called via ctx->Driver.DeleteMemory(). - * Not removed from hash table here. - */ -void -_mesa_delete_memory_object(struct gl_context *ctx, - struct gl_memory_object *memObj) +static void +import_memoryobj_fd(struct gl_context *ctx, + struct gl_memory_object *obj, + GLuint64 size, + int fd) { - free(memObj); +#if !defined(_WIN32) + struct pipe_screen *screen = ctx->pipe->screen; + struct winsys_handle whandle = { + .type = WINSYS_HANDLE_TYPE_FD, + .handle = fd, +#ifdef HAVE_LIBDRM + .modifier = DRM_FORMAT_MOD_INVALID, +#endif + }; + + obj->memory = screen->memobj_create_from_handle(screen, + &whandle, + obj->Dedicated); + + /* We own fd, but we no longer need it. So get rid of it */ + close(fd); +#endif } -void -_mesa_init_memory_object_functions(struct dd_function_table *driver) +static void +import_memoryobj_win32(struct gl_context *ctx, + struct gl_memory_object *obj, + GLuint64 size, + void *handle, + const void *name) { - driver->NewMemoryObject = _mesa_new_memory_object; - driver->DeleteMemoryObject = _mesa_delete_memory_object; + struct pipe_screen *screen = ctx->pipe->screen; + struct winsys_handle whandle = { + .type = handle ? WINSYS_HANDLE_TYPE_WIN32_HANDLE : WINSYS_HANDLE_TYPE_WIN32_NAME, +#ifdef _WIN32 + .handle = handle, +#else + .handle = 0, +#endif +#ifdef HAVE_LIBDRM + .modifier = DRM_FORMAT_MOD_INVALID, +#endif + .name = name, + }; + + obj->memory = screen->memobj_create_from_handle(screen, + &whandle, + obj->Dedicated); } /** - * Initialize a buffer object to default values. + * Delete a memory object. + * Not removed from hash table here. */ void -_mesa_initialize_memory_object(struct gl_context *ctx, - struct gl_memory_object *obj, - GLuint name) +_mesa_delete_memory_object(struct gl_context *ctx, + struct gl_memory_object *memObj) { - memset(obj, 0, sizeof(struct gl_memory_object)); - obj->Name = name; - obj->Dedicated = GL_FALSE; + struct pipe_screen *screen = ctx->pipe->screen; + if (memObj->memory) + screen->memobj_destroy(screen, memObj->memory); + FREE(memObj); } void GLAPIENTRY @@ -107,20 +148,20 @@ _mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects) if (!memoryObjects) return; - _mesa_HashLockMutex(ctx->Shared->MemoryObjects); + _mesa_HashLockMutex(&ctx->Shared->MemoryObjects); for (GLint i = 0; i < n; i++) { if (memoryObjects[i] > 0) { struct gl_memory_object *delObj = _mesa_lookup_memory_object_locked(ctx, memoryObjects[i]); if (delObj) { - _mesa_HashRemoveLocked(ctx->Shared->MemoryObjects, + _mesa_HashRemoveLocked(&ctx->Shared->MemoryObjects, memoryObjects[i]); - ctx->Driver.DeleteMemoryObject(ctx, delObj); + _mesa_delete_memory_object(ctx, delObj); } } } - _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects); + _mesa_HashUnlockMutex(&ctx->Shared->MemoryObjects); } GLboolean GLAPIENTRY @@ -148,7 +189,7 @@ _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects) const char *func = "glCreateMemoryObjectsEXT"; if (MESA_VERBOSE & (VERBOSE_API)) - _mesa_debug(ctx, "%s(%d, %p)", func, n, memoryObjects); + _mesa_debug(ctx, "%s(%d, %p)\n", func, n, memoryObjects); if (!ctx->Extensions.EXT_memory_object) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); @@ -163,27 +204,26 @@ _mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects) if (!memoryObjects) return; - _mesa_HashLockMutex(ctx->Shared->MemoryObjects); - if (_mesa_HashFindFreeKeys(ctx->Shared->MemoryObjects, memoryObjects, n)) { + _mesa_HashLockMutex(&ctx->Shared->MemoryObjects); + if (_mesa_HashFindFreeKeys(&ctx->Shared->MemoryObjects, memoryObjects, n)) { for (GLsizei i = 0; i < n; i++) { struct gl_memory_object *memObj; /* allocate memory object */ - memObj = ctx->Driver.NewMemoryObject(ctx, memoryObjects[i]); + memObj = memoryobj_alloc(ctx, memoryObjects[i]); if (!memObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s()", func); - _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects); + _mesa_HashUnlockMutex(&ctx->Shared->MemoryObjects); return; } /* insert into hash table */ - _mesa_HashInsertLocked(ctx->Shared->MemoryObjects, - memoryObjects[i], - memObj, true); + _mesa_HashInsertLocked(&ctx->Shared->MemoryObjects, memoryObjects[i], + memObj); } } - _mesa_HashUnlockMutex(ctx->Shared->MemoryObjects); + _mesa_HashUnlockMutex(&ctx->Shared->MemoryObjects); } void GLAPIENTRY @@ -302,6 +342,21 @@ texstorage_memory(GLuint dims, GLenum target, GLsizei levels, return; } + if (!_mesa_is_legal_tex_storage_target(ctx, dims, target)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(illegal target=%s)", + func, _mesa_enum_to_string(target)); + return; + } + + /* Check the format to make sure it is sized. */ + if (!_mesa_is_legal_tex_storage_format(ctx, internalFormat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(internalformat = %s)", func, + _mesa_enum_to_string(internalFormat)); + return; + } + texObj = _mesa_get_current_tex_object(ctx, target); if (!texObj) return; @@ -363,10 +418,25 @@ texturestorage_memory(GLuint dims, GLuint texture, GLsizei levels, return; } + /* Check the format to make sure it is sized. */ + if (!_mesa_is_legal_tex_storage_format(ctx, internalFormat)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "%s(internalformat = %s)", func, + _mesa_enum_to_string(internalFormat)); + return; + } + texObj = _mesa_lookup_texture(ctx, texture); if (!texObj) return; + if (!_mesa_is_legal_tex_storage_target(ctx, dims, texObj->Target)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(illegal target=%s)", func, + _mesa_enum_to_string(texObj->Target)); + return; + } + memObj = lookup_memory_object_err(ctx, memory, func); if (!memObj) return; @@ -545,6 +615,130 @@ _mesa_TextureStorageMem1DEXT(GLuint texture, memory, offset, "glTextureStorageMem1DEXT"); } +static struct gl_semaphore_object * +semaphoreobj_alloc(struct gl_context *ctx, GLuint name) +{ + struct gl_semaphore_object *obj = CALLOC_STRUCT(gl_semaphore_object); + if (!obj) + return NULL; + + obj->Name = name; + return obj; +} + +static void +import_semaphoreobj_fd(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + int fd) +{ + struct pipe_context *pipe = ctx->pipe; + + pipe->create_fence_fd(pipe, &semObj->fence, fd, PIPE_FD_TYPE_SYNCOBJ); + +#if !defined(_WIN32) + /* We own fd, but we no longer need it. So get rid of it */ + close(fd); +#endif +} + +static void +import_semaphoreobj_win32(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + void *handle, + const void *name, + enum pipe_fd_type type) +{ + struct pipe_context *pipe = ctx->pipe; + semObj->type = type; + + pipe->screen->create_fence_win32(pipe->screen, &semObj->fence, handle, name, type); +} + +static void +server_wait_semaphore(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *srcLayouts) +{ + struct st_context *st = ctx->st; + struct pipe_context *pipe = ctx->pipe; + struct gl_buffer_object *bufObj; + struct gl_texture_object *texObj; + + /* The driver is allowed to flush during fence_server_sync, be prepared */ + st_flush_bitmap_cache(st); + pipe->fence_server_sync(pipe, semObj->fence); + + /** + * According to the EXT_external_objects spec, the memory operations must + * follow the wait. This is to make sure the flush is executed after the + * other party is done modifying the memory. + * + * Relevant excerpt from section "4.2.3 Waiting for Semaphores": + * + * Following completion of the semaphore wait operation, memory will also be + * made visible in the specified buffer and texture objects. + * + */ + for (unsigned i = 0; i < numBufferBarriers; i++) { + if (!bufObjs[i]) + continue; + + bufObj = bufObjs[i]; + if (bufObj->buffer) + pipe->flush_resource(pipe, bufObj->buffer); + } + + for (unsigned i = 0; i < numTextureBarriers; i++) { + if (!texObjs[i]) + continue; + + texObj = texObjs[i]; + if (texObj->pt) + pipe->flush_resource(pipe, texObj->pt); + } +} + +static void +server_signal_semaphore(struct gl_context *ctx, + struct gl_semaphore_object *semObj, + GLuint numBufferBarriers, + struct gl_buffer_object **bufObjs, + GLuint numTextureBarriers, + struct gl_texture_object **texObjs, + const GLenum *dstLayouts) +{ + struct st_context *st = ctx->st; + struct pipe_context *pipe = ctx->pipe; + struct gl_buffer_object *bufObj; + struct gl_texture_object *texObj; + + for (unsigned i = 0; i < numBufferBarriers; i++) { + if (!bufObjs[i]) + continue; + + bufObj = bufObjs[i]; + if (bufObj->buffer) + pipe->flush_resource(pipe, bufObj->buffer); + } + + for (unsigned i = 0; i < numTextureBarriers; i++) { + if (!texObjs[i]) + continue; + + texObj = texObjs[i]; + if (texObj->pt) + pipe->flush_resource(pipe, texObj->pt); + } + + /* The driver must flush during fence_server_signal, be prepared */ + st_flush_bitmap_cache(st); + pipe->fence_server_signal(pipe, semObj->fence); +} + /** * Used as a placeholder for semaphore objects between glGenSemaphoresEXT() * and glImportSemaphoreFdEXT(), so that glIsSemaphoreEXT() can work correctly. @@ -552,27 +746,18 @@ _mesa_TextureStorageMem1DEXT(GLuint texture, static struct gl_semaphore_object DummySemaphoreObject; /** - * Delete a semaphore object. Called via ctx->Driver.DeleteSemaphore(). + * Delete a semaphore object. * Not removed from hash table here. */ void _mesa_delete_semaphore_object(struct gl_context *ctx, struct gl_semaphore_object *semObj) { - if (semObj != &DummySemaphoreObject) - free(semObj); -} - -/** - * Initialize a semaphore object to default values. - */ -void -_mesa_initialize_semaphore_object(struct gl_context *ctx, - struct gl_semaphore_object *obj, - GLuint name) -{ - memset(obj, 0, sizeof(struct gl_semaphore_object)); - obj->Name = name; + if (semObj != &DummySemaphoreObject) { + struct pipe_context *pipe = ctx->pipe; + pipe->screen->fence_reference(ctx->screen, &semObj->fence, NULL); + FREE(semObj); + } } void GLAPIENTRY @@ -583,7 +768,7 @@ _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores) const char *func = "glGenSemaphoresEXT"; if (MESA_VERBOSE & (VERBOSE_API)) - _mesa_debug(ctx, "%s(%d, %p)", func, n, semaphores); + _mesa_debug(ctx, "%s(%d, %p)\n", func, n, semaphores); if (!ctx->Extensions.EXT_semaphore) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); @@ -598,15 +783,15 @@ _mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores) if (!semaphores) return; - _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects); - if (_mesa_HashFindFreeKeys(ctx->Shared->SemaphoreObjects, semaphores, n)) { + _mesa_HashLockMutex(&ctx->Shared->SemaphoreObjects); + if (_mesa_HashFindFreeKeys(&ctx->Shared->SemaphoreObjects, semaphores, n)) { for (GLsizei i = 0; i < n; i++) { - _mesa_HashInsertLocked(ctx->Shared->SemaphoreObjects, - semaphores[i], &DummySemaphoreObject, true); + _mesa_HashInsertLocked(&ctx->Shared->SemaphoreObjects, semaphores[i], + &DummySemaphoreObject); } } - _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects); + _mesa_HashUnlockMutex(&ctx->Shared->SemaphoreObjects); } void GLAPIENTRY @@ -633,20 +818,20 @@ _mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores) if (!semaphores) return; - _mesa_HashLockMutex(ctx->Shared->SemaphoreObjects); + _mesa_HashLockMutex(&ctx->Shared->SemaphoreObjects); for (GLint i = 0; i < n; i++) { if (semaphores[i] > 0) { struct gl_semaphore_object *delObj = _mesa_lookup_semaphore_object_locked(ctx, semaphores[i]); if (delObj) { - _mesa_HashRemoveLocked(ctx->Shared->SemaphoreObjects, + _mesa_HashRemoveLocked(&ctx->Shared->SemaphoreObjects, semaphores[i]); - ctx->Driver.DeleteSemaphoreObject(ctx, delObj); + _mesa_delete_semaphore_object(ctx, delObj); } } } - _mesa_HashUnlockMutex(ctx->Shared->SemaphoreObjects); + _mesa_HashUnlockMutex(&ctx->Shared->SemaphoreObjects); } GLboolean GLAPIENTRY @@ -672,15 +857,6 @@ _mesa_IsSemaphoreEXT(GLuint semaphore) static void semaphore_parameter_stub(const char* func, GLenum pname) { - GET_CURRENT_CONTEXT(ctx); - - if (!ctx->Extensions.EXT_semaphore) { - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); - return; - } - - /* EXT_semaphore and EXT_semaphore_fd define no parameters */ - _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); } void GLAPIENTRY @@ -688,9 +864,31 @@ _mesa_SemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, const GLuint64 *params) { + GET_CURRENT_CONTEXT(ctx); const char *func = "glSemaphoreParameterui64vEXT"; - semaphore_parameter_stub(func, pname); + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (pname != GL_D3D12_FENCE_VALUE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); + return; + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj->type != PIPE_FD_TYPE_TIMELINE_SEMAPHORE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(Not a D3D12 fence)", func); + return; + } + + semObj->timeline_value = params[0]; + ctx->screen->set_fence_timeline_value(ctx->screen, semObj->fence, params[0]); } void GLAPIENTRY @@ -698,9 +896,30 @@ _mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore, GLenum pname, GLuint64 *params) { + GET_CURRENT_CONTEXT(ctx); const char *func = "glGetSemaphoreParameterui64vEXT"; - semaphore_parameter_stub(func, pname); + if (!ctx->Extensions.EXT_semaphore) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (pname != GL_D3D12_FENCE_VALUE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname); + return; + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj->type != PIPE_FD_TYPE_TIMELINE_SEMAPHORE) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(Not a D3D12 fence)", func); + return; + } + + params[0] = semObj->timeline_value; } void GLAPIENTRY @@ -753,10 +972,10 @@ _mesa_WaitSemaphoreEXT(GLuint semaphore, texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); } - ctx->Driver.ServerWaitSemaphoreObject(ctx, semObj, - numBufferBarriers, bufObjs, - numTextureBarriers, texObjs, - srcLayouts); + server_wait_semaphore(ctx, semObj, + numBufferBarriers, bufObjs, + numTextureBarriers, texObjs, + srcLayouts); end: free(bufObjs); @@ -813,10 +1032,10 @@ _mesa_SignalSemaphoreEXT(GLuint semaphore, texObjs[i] = _mesa_lookup_texture(ctx, textures[i]); } - ctx->Driver.ServerSignalSemaphoreObject(ctx, semObj, - numBufferBarriers, bufObjs, - numTextureBarriers, texObjs, - dstLayouts); + server_signal_semaphore(ctx, semObj, + numBufferBarriers, bufObjs, + numTextureBarriers, texObjs, + dstLayouts); end: free(bufObjs); @@ -847,7 +1066,69 @@ _mesa_ImportMemoryFdEXT(GLuint memory, if (!memObj) return; - ctx->Driver.ImportMemoryObjectFd(ctx, memObj, size, fd); + import_memoryobj_fd(ctx, memObj, size, fd); + memObj->Immutable = GL_TRUE; +} + +void GLAPIENTRY +_mesa_ImportMemoryWin32HandleEXT(GLuint memory, + GLuint64 size, + GLenum handleType, + void *handle) +{ + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glImportMemoryWin32HandleEXT"; + + if (!ctx->Extensions.EXT_memory_object_win32) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT && + handleType != GL_HANDLE_TYPE_D3D11_IMAGE_EXT && + handleType != GL_HANDLE_TYPE_D3D12_RESOURCE_EXT && + handleType != GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + return; + } + + struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory); + if (!memObj) + return; + + import_memoryobj_win32(ctx, memObj, size, handle, NULL); + memObj->Immutable = GL_TRUE; +} + +void GLAPIENTRY +_mesa_ImportMemoryWin32NameEXT(GLuint memory, + GLuint64 size, + GLenum handleType, + const void *name) +{ + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glImportMemoryWin32NameEXT"; + + if (!ctx->Extensions.EXT_memory_object_win32) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT && + handleType != GL_HANDLE_TYPE_D3D11_IMAGE_EXT && + handleType != GL_HANDLE_TYPE_D3D12_RESOURCE_EXT && + handleType != GL_HANDLE_TYPE_D3D12_TILEPOOL_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + return; + } + + struct gl_memory_object *memObj = _mesa_lookup_memory_object(ctx, memory); + if (!memObj) + return; + + import_memoryobj_win32(ctx, memObj, size, NULL, name); memObj->Immutable = GL_TRUE; } @@ -876,13 +1157,101 @@ _mesa_ImportSemaphoreFdEXT(GLuint semaphore, return; if (semObj == &DummySemaphoreObject) { - semObj = ctx->Driver.NewSemaphoreObject(ctx, semaphore); + semObj = semaphoreobj_alloc(ctx, semaphore); + if (!semObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); + return; + } + _mesa_HashInsert(&ctx->Shared->SemaphoreObjects, semaphore, semObj); + } + + import_semaphoreobj_fd(ctx, semObj, fd); +} + +void GLAPIENTRY +_mesa_ImportSemaphoreWin32HandleEXT(GLuint semaphore, + GLenum handleType, + void *handle) +{ + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glImportSemaphoreWin32HandleEXT"; + + if (!ctx->Extensions.EXT_semaphore_win32) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT && + handleType != GL_HANDLE_TYPE_D3D12_FENCE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + return; + } + + if (handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT && + !ctx->screen->get_param(ctx->screen, PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT)) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj == &DummySemaphoreObject) { + semObj = semaphoreobj_alloc(ctx, semaphore); + if (!semObj) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); + return; + } + _mesa_HashInsert(&ctx->Shared->SemaphoreObjects, semaphore, semObj); + } + + enum pipe_fd_type type = handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT ? + PIPE_FD_TYPE_TIMELINE_SEMAPHORE : PIPE_FD_TYPE_SYNCOBJ; + import_semaphoreobj_win32(ctx, semObj, handle, NULL, type); +} + +void GLAPIENTRY +_mesa_ImportSemaphoreWin32NameEXT(GLuint semaphore, + GLenum handleType, + const void *name) +{ + GET_CURRENT_CONTEXT(ctx); + + const char *func = "glImportSemaphoreWin32HandleEXT"; + + if (!ctx->Extensions.EXT_semaphore_win32) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported)", func); + return; + } + + if (handleType != GL_HANDLE_TYPE_OPAQUE_WIN32_EXT && + handleType != GL_HANDLE_TYPE_D3D12_FENCE_EXT) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + return; + } + + if (handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT && + !ctx->screen->get_param(ctx->screen, PIPE_CAP_TIMELINE_SEMAPHORE_IMPORT)) { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(handleType=%u)", func, handleType); + } + + struct gl_semaphore_object *semObj = _mesa_lookup_semaphore_object(ctx, + semaphore); + if (!semObj) + return; + + if (semObj == &DummySemaphoreObject) { + semObj = semaphoreobj_alloc(ctx, semaphore); if (!semObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; } - _mesa_HashInsert(ctx->Shared->SemaphoreObjects, semaphore, semObj, true); + _mesa_HashInsert(&ctx->Shared->SemaphoreObjects, semaphore, semObj); } - ctx->Driver.ImportSemaphoreFd(ctx, semObj, fd); + enum pipe_fd_type type = handleType == GL_HANDLE_TYPE_D3D12_FENCE_EXT ? + PIPE_FD_TYPE_TIMELINE_SEMAPHORE : PIPE_FD_TYPE_SYNCOBJ; + import_semaphoreobj_win32(ctx, semObj, NULL, name, type); } diff --git a/src/mesa/main/externalobjects.h b/src/mesa/main/externalobjects.h index 75b0bc2eddb..642c42dc97b 100644 --- a/src/mesa/main/externalobjects.h +++ b/src/mesa/main/externalobjects.h @@ -34,7 +34,7 @@ #ifndef EXTERNALOBJECTS_H #define EXTERNALOBJECTS_H -#include "glheader.h" +#include "util/glheader.h" #include "hash.h" static inline struct gl_memory_object * @@ -44,7 +44,7 @@ _mesa_lookup_memory_object(struct gl_context *ctx, GLuint memory) return NULL; return (struct gl_memory_object *) - _mesa_HashLookup(ctx->Shared->MemoryObjects, memory); + _mesa_HashLookup(&ctx->Shared->MemoryObjects, memory); } static inline struct gl_memory_object * @@ -54,7 +54,7 @@ _mesa_lookup_memory_object_locked(struct gl_context *ctx, GLuint memory) return NULL; return (struct gl_memory_object *) - _mesa_HashLookupLocked(ctx->Shared->MemoryObjects, memory); + _mesa_HashLookupLocked(&ctx->Shared->MemoryObjects, memory); } static inline struct gl_semaphore_object * @@ -64,7 +64,7 @@ _mesa_lookup_semaphore_object(struct gl_context *ctx, GLuint semaphore) return NULL; return (struct gl_semaphore_object *) - _mesa_HashLookup(ctx->Shared->SemaphoreObjects, semaphore); + _mesa_HashLookup(&ctx->Shared->SemaphoreObjects, semaphore); } static inline struct gl_semaphore_object * @@ -74,187 +74,15 @@ _mesa_lookup_semaphore_object_locked(struct gl_context *ctx, GLuint semaphore) return NULL; return (struct gl_semaphore_object *) - _mesa_HashLookupLocked(ctx->Shared->SemaphoreObjects, semaphore); + _mesa_HashLookupLocked(&ctx->Shared->SemaphoreObjects, semaphore); } extern void -_mesa_init_memory_object_functions(struct dd_function_table *driver); - -extern void -_mesa_initialize_memory_object(struct gl_context *ctx, - struct gl_memory_object *obj, - GLuint name); -extern void _mesa_delete_memory_object(struct gl_context *ctx, struct gl_memory_object *semObj); extern void -_mesa_initialize_semaphore_object(struct gl_context *ctx, - struct gl_semaphore_object *obj, - GLuint name); -extern void _mesa_delete_semaphore_object(struct gl_context *ctx, struct gl_semaphore_object *semObj); -extern void GLAPIENTRY -_mesa_DeleteMemoryObjectsEXT(GLsizei n, const GLuint *memoryObjects); - -extern GLboolean GLAPIENTRY -_mesa_IsMemoryObjectEXT(GLuint memoryObject); - -extern void GLAPIENTRY -_mesa_CreateMemoryObjectsEXT(GLsizei n, GLuint *memoryObjects); - -extern void GLAPIENTRY -_mesa_MemoryObjectParameterivEXT(GLuint memoryObject, - GLenum pname, - const GLint *params); - -extern void GLAPIENTRY -_mesa_GetMemoryObjectParameterivEXT(GLuint memoryObject, - GLenum pname, - GLint *params); - -extern void GLAPIENTRY -_mesa_TexStorageMem2DEXT(GLenum target, - GLsizei levels, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TexStorageMem2DMultisampleEXT(GLenum target, - GLsizei samples, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLboolean fixedSampleLocations, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TexStorageMem3DEXT(GLenum target, - GLsizei levels, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TexStorageMem3DMultisampleEXT(GLenum target, - GLsizei samples, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLboolean fixedSampleLocations, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TextureStorageMem2DEXT(GLuint texture, - GLsizei levels, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TextureStorageMem2DMultisampleEXT(GLuint texture, - GLsizei samples, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLboolean fixedSampleLocations, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TextureStorageMem3DEXT(GLuint texture, - GLsizei levels, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TextureStorageMem3DMultisampleEXT(GLuint texture, - GLsizei samples, - GLenum internalFormat, - GLsizei width, - GLsizei height, - GLsizei depth, - GLboolean fixedSampleLocations, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TexStorageMem1DEXT(GLenum target, - GLsizei levels, - GLenum internalFormat, - GLsizei width, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_TextureStorageMem1DEXT(GLuint texture, - GLsizei levels, - GLenum internalFormat, - GLsizei width, - GLuint memory, - GLuint64 offset); - -extern void GLAPIENTRY -_mesa_GenSemaphoresEXT(GLsizei n, GLuint *semaphores); - -extern void GLAPIENTRY -_mesa_DeleteSemaphoresEXT(GLsizei n, const GLuint *semaphores); - -extern GLboolean GLAPIENTRY -_mesa_IsSemaphoreEXT(GLuint semaphore); - -extern void GLAPIENTRY -_mesa_SemaphoreParameterui64vEXT(GLuint semaphore, - GLenum pname, - const GLuint64 *params); - -extern void GLAPIENTRY -_mesa_GetSemaphoreParameterui64vEXT(GLuint semaphore, - GLenum pname, - GLuint64 *params); - -extern void GLAPIENTRY -_mesa_WaitSemaphoreEXT(GLuint semaphore, - GLuint numBufferBarriers, - const GLuint *buffers, - GLuint numTextureBarriers, - const GLuint *textures, - const GLenum *srcLayouts); - -extern void GLAPIENTRY -_mesa_SignalSemaphoreEXT(GLuint semaphore, - GLuint numBufferBarriers, - const GLuint *buffers, - GLuint numTextureBarriers, - const GLuint *textures, - const GLenum *dstLayouts); - -extern void GLAPIENTRY -_mesa_ImportMemoryFdEXT(GLuint memory, - GLuint64 size, - GLenum handleType, - GLint fd); - -extern void GLAPIENTRY -_mesa_ImportSemaphoreFdEXT(GLuint semaphore, - GLenum handleType, - GLint fd); - #endif diff --git a/src/mesa/main/fbobject.c b/src/mesa/main/fbobject.c index 92375a9361b..da47ac15be1 100644 --- a/src/mesa/main/fbobject.c +++ b/src/mesa/main/fbobject.c @@ -50,7 +50,13 @@ #include "state.h" #include "teximage.h" #include "texobj.h" +#include "api_exec_decl.h" +#include "util/u_memory.h" +#include "state_tracker/st_cb_eglimage.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_format.h" +#include "state_tracker/st_util.h" /** * Notes: @@ -81,18 +87,17 @@ delete_dummy_framebuffer(struct gl_framebuffer *fb) * with the real frame/renderbuffer. */ static struct gl_framebuffer DummyFramebuffer = { - .Mutex = _SIMPLE_MTX_INITIALIZER_NP, + .Mutex = SIMPLE_MTX_INITIALIZER, .Delete = delete_dummy_framebuffer, }; static struct gl_renderbuffer DummyRenderbuffer = { - .Mutex = _SIMPLE_MTX_INITIALIZER_NP, .Delete = delete_dummy_renderbuffer, }; /* We bind this framebuffer when applications pass a NULL * drawable/surface in make current. */ static struct gl_framebuffer IncompleteFramebuffer = { - .Mutex = _SIMPLE_MTX_INITIALIZER_NP, + .Mutex = SIMPLE_MTX_INITIALIZER, .Delete = delete_dummy_framebuffer, }; @@ -115,7 +120,7 @@ _mesa_lookup_renderbuffer(struct gl_context *ctx, GLuint id) return NULL; rb = (struct gl_renderbuffer *) - _mesa_HashLookup(ctx->Shared->RenderBuffers, id); + _mesa_HashLookup(&ctx->Shared->RenderBuffers, id); return rb; } @@ -153,7 +158,7 @@ _mesa_lookup_framebuffer(struct gl_context *ctx, GLuint id) return NULL; fb = (struct gl_framebuffer *) - _mesa_HashLookup(ctx->Shared->FrameBuffers, id); + _mesa_HashLookup(&ctx->Shared->FrameBuffers, id); return fb; } @@ -172,17 +177,17 @@ _mesa_lookup_framebuffer_dsa(struct gl_context *ctx, GLuint id, /* Name exists but buffer is not initialized */ if (fb == &DummyFramebuffer) { - fb = ctx->Driver.NewFramebuffer(ctx, id); - _mesa_HashInsert(ctx->Shared->FrameBuffers, id, fb, true); + fb = _mesa_new_framebuffer(ctx, id); + _mesa_HashInsert(&ctx->Shared->FrameBuffers, id, fb); } /* Name doesn't exist */ else if (!fb) { - fb = ctx->Driver.NewFramebuffer(ctx, id); + fb = _mesa_new_framebuffer(ctx, id); if (!fb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return NULL; } - _mesa_HashInsert(ctx->Shared->FrameBuffers, id, fb, false); + _mesa_HashInsert(&ctx->Shared->FrameBuffers, id, fb); } return fb; } @@ -292,7 +297,7 @@ get_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, */ i = attachment - GL_COLOR_ATTACHMENT0_EXT; if (i >= ctx->Const.MaxColorAttachments - || (i > 0 && ctx->API == API_OPENGLES)) { + || (i > 0 && _mesa_is_gles1(ctx))) { return NULL; } assert(BUFFER_COLOR0 + i < ARRAY_SIZE(fb->Attachment)); @@ -409,7 +414,65 @@ get_fb0_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, } } +/** + * Return the pipe_resource which stores a particular texture image. + */ +static struct pipe_resource * +get_teximage_resource(struct gl_texture_object *texObj, + unsigned face, unsigned level) +{ + struct gl_texture_image *stImg = + texObj->Image[face][level]; + + return stImg->pt; +} + +static void +render_texture(struct gl_context *ctx, + struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct st_context *st = st_context(ctx); + struct gl_renderbuffer *rb = att->Renderbuffer; + struct pipe_resource *pt; + + pt = get_teximage_resource(att->Texture, + att->CubeMapFace, + att->TextureLevel); + assert(pt); + + /* point renderbuffer at texobject */ + rb->is_rtt = true; + rb->rtt_face = att->CubeMapFace; + rb->rtt_slice = att->Zoffset; + rb->rtt_layered = att->Layered; + rb->rtt_nr_samples = att->NumSamples; + pipe_resource_reference(&rb->texture, pt); + + _mesa_update_renderbuffer_surface(ctx, rb); + + /* Invalidate buffer state so that the pipe's framebuffer state + * gets updated. + * That's where the new renderbuffer (which we just created) gets + * passed to the pipe as a (color/depth) render target. + */ + st_invalidate_buffers(st); + + + /* Need to trigger a call to update_framebuffer() since we just + * attached a new renderbuffer. + */ + ctx->NewState |= _NEW_BUFFERS; +} +static void +finish_render_texture(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + rb->is_rtt = false; + + /* restore previous framebuffer state */ + st_invalidate_buffers(st_context(ctx)); +} /** * Remove any texture or renderbuffer attached to the given attachment @@ -422,8 +485,8 @@ remove_attachment(struct gl_context *ctx, struct gl_renderbuffer *rb = att->Renderbuffer; /* tell driver that we're done rendering to this texture. */ - if (rb && rb->NeedsFinishRenderTexture) - ctx->Driver.FinishRenderTexture(ctx, rb); + if (rb) + finish_render_texture(ctx, rb); if (att->Type == GL_TEXTURE) { assert(att->Texture); @@ -450,7 +513,8 @@ driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment *att) att->Texture->Image[att->CubeMapFace][att->TextureLevel]; if (!texImage || - texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) + !texImage->pt || + _mesa_is_zero_size_texture(texImage)) return false; if ((texImage->TexObject->Target == GL_TEXTURE_1D_ARRAY @@ -462,6 +526,18 @@ driver_RenderTexture_is_safe(const struct gl_renderbuffer_attachment *att) return true; } +static struct gl_renderbuffer * +new_renderbuffer(struct gl_context *ctx, GLuint name) +{ + struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); + if (rb) { + assert(name != 0); + _mesa_init_renderbuffer(rb, name); + return rb; + } + return NULL; +} + /** * Create a renderbuffer which will be set up by the driver to wrap the * texture image slice. @@ -486,7 +562,7 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, rb = att->Renderbuffer; if (!rb) { - rb = ctx->Driver.NewRenderbuffer(ctx, ~0); + rb = new_renderbuffer(ctx, ~0); if (!rb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glFramebufferTexture()"); return; @@ -497,8 +573,6 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, * for clarity compared to user renderbuffers. */ rb->AllocStorage = NULL; - - rb->NeedsFinishRenderTexture = ctx->Driver.FinishRenderTexture != NULL; } if (!texImage) @@ -515,7 +589,7 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, rb->TexImage = texImage; if (driver_RenderTexture_is_safe(att)) - ctx->Driver.RenderTexture(ctx, fb, att); + render_texture(ctx, fb, att); } /** @@ -532,8 +606,8 @@ set_texture_attachment(struct gl_context *ctx, { struct gl_renderbuffer *rb = att->Renderbuffer; - if (rb && rb->NeedsFinishRenderTexture) - ctx->Driver.FinishRenderTexture(ctx, rb); + if (rb) + finish_render_texture(ctx, rb); if (att->Texture == texObj) { /* re-attaching same texture */ @@ -583,7 +657,7 @@ set_renderbuffer_attachment(struct gl_context *ctx, * Fallback for ctx->Driver.FramebufferRenderbuffer() * Attach a renderbuffer object to a framebuffer object. */ -void +static void _mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx, struct gl_framebuffer *fb, GLenum attachment, @@ -620,45 +694,6 @@ _mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx, simple_mtx_unlock(&fb->Mutex); } - -/** - * Fallback for ctx->Driver.ValidateFramebuffer() - * Check if the renderbuffer's formats are supported by the software - * renderer. - * Drivers should probably override this. - */ -void -_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) -{ - gl_buffer_index buf; - for (buf = 0; buf < BUFFER_COUNT; buf++) { - const struct gl_renderbuffer *rb = fb->Attachment[buf].Renderbuffer; - if (rb) { - switch (rb->_BaseFormat) { - case GL_ALPHA: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE: - case GL_INTENSITY: - case GL_RED: - case GL_RG: - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; - return; - - default: - switch (rb->Format) { - /* XXX This list is likely incomplete. */ - case MESA_FORMAT_R9G9B9E5_FLOAT: - fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED; - return; - default:; - /* render buffer format is supported by software rendering */ - } - } - } - } -} - - /** * Return true if the framebuffer has a combined depth/stencil * renderbuffer attached. @@ -733,7 +768,7 @@ _mesa_is_legal_color_format(const struct gl_context *ctx, GLenum baseFormat) case GL_LUMINANCE_ALPHA: case GL_INTENSITY: case GL_ALPHA: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_framebuffer_object; case GL_RED: case GL_RG: @@ -803,6 +838,8 @@ is_format_color_renderable(const struct gl_context *ctx, mesa_format format, return _mesa_has_EXT_color_buffer_float(ctx); case GL_RGB16F: return _mesa_has_EXT_color_buffer_half_float(ctx); + case GL_RGB10_A2: + return _mesa_is_gles3(ctx); case GL_RGB32F: case GL_RGB32I: case GL_RGB32UI: @@ -996,14 +1033,8 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, } } else if (format == GL_DEPTH) { - if (baseFormat == GL_DEPTH_COMPONENT) { - /* OK */ - } - else if (ctx->Extensions.ARB_depth_texture && - baseFormat == GL_DEPTH_STENCIL) { - /* OK */ - } - else { + if (baseFormat != GL_DEPTH_COMPONENT && + baseFormat != GL_DEPTH_STENCIL) { att->Complete = GL_FALSE; att_incomplete("bad depth format"); return; @@ -1011,8 +1042,7 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, } else { assert(format == GL_STENCIL); - if (ctx->Extensions.ARB_depth_texture && - baseFormat == GL_DEPTH_STENCIL) { + if (baseFormat == GL_DEPTH_STENCIL) { /* OK */ } else if (ctx->Extensions.ARB_texture_stencil8 && baseFormat == GL_STENCIL_INDEX) { @@ -1076,6 +1106,149 @@ test_attachment_completeness(const struct gl_context *ctx, GLenum format, } } +/** Debug helper */ +static void +fbo_invalid(const char *reason) +{ + if (MESA_DEBUG_FLAGS & DEBUG_INCOMPLETE_FBO) { + _mesa_debug(NULL, "Invalid FBO: %s\n", reason); + } +} + + +/** + * Validate a renderbuffer attachment for a particular set of bindings. + */ +static GLboolean +do_validate_attachment(struct gl_context *ctx, + struct pipe_screen *screen, + const struct gl_renderbuffer_attachment *att, + unsigned bindings) +{ + const struct gl_texture_object *stObj = att->Texture; + enum pipe_format format; + mesa_format texFormat; + GLboolean valid; + + /* Sanity check: we must be binding the surface as a (color) render target + * or depth/stencil target. + */ + assert(bindings == PIPE_BIND_RENDER_TARGET || + bindings == PIPE_BIND_DEPTH_STENCIL); + + /* Only validate texture attachments for now, since + * st_renderbuffer_alloc_storage makes sure that + * the format is supported. + */ + if (att->Type != GL_TEXTURE) + return GL_TRUE; + + if (!stObj || !stObj->pt) + return GL_FALSE; + + format = stObj->pt->format; + texFormat = att->Renderbuffer->TexImage->TexFormat; + + /* If the encoding is sRGB and sRGB rendering cannot be enabled, + * check for linear format support instead. + * Later when we create a surface, we change the format to a linear one. */ + if (!ctx->Extensions.EXT_sRGB && _mesa_is_format_srgb(texFormat)) { + const mesa_format linearFormat = _mesa_get_srgb_format_linear(texFormat); + format = st_mesa_format_to_pipe_format(st_context(ctx), linearFormat); + } + + valid = screen->is_format_supported(screen, format, + PIPE_TEXTURE_2D, + stObj->pt->nr_samples, + stObj->pt->nr_storage_samples, + bindings); + if (!valid) { + fbo_invalid("Invalid format"); + } + + return valid; +} + + +/** + * Check that the framebuffer configuration is valid in terms of what + * the driver can support. + * + * For Gallium we only supports combined Z+stencil, not separate buffers. + */ +static void +do_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) +{ + struct pipe_screen *screen = ctx->screen; + const struct gl_renderbuffer_attachment *depth = + &fb->Attachment[BUFFER_DEPTH]; + const struct gl_renderbuffer_attachment *stencil = + &fb->Attachment[BUFFER_STENCIL]; + GLuint i; + enum pipe_format first_format = PIPE_FORMAT_NONE; + bool mixed_formats = + screen->get_param(screen, PIPE_CAP_MIXED_COLORBUFFER_FORMATS) != 0; + + if (depth->Type && stencil->Type && depth->Type != stencil->Type) { + fbo_invalid("Different Depth/Stencil buffer formats"); + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + if (depth->Type == GL_RENDERBUFFER_EXT && + stencil->Type == GL_RENDERBUFFER_EXT && + depth->Renderbuffer != stencil->Renderbuffer) { + fbo_invalid("Separate Depth/Stencil buffers"); + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + return; + } + if (depth->Type == GL_TEXTURE && + stencil->Type == GL_TEXTURE && + depth->Texture != stencil->Texture) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + fbo_invalid("Different Depth/Stencil textures"); + return; + } + + if (!do_validate_attachment(ctx, screen, depth, PIPE_BIND_DEPTH_STENCIL)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + fbo_invalid("Invalid depth attachment"); + return; + } + if (!do_validate_attachment(ctx, screen, stencil, PIPE_BIND_DEPTH_STENCIL)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + fbo_invalid("Invalid stencil attachment"); + return; + } + for (i = 0; i < ctx->Const.MaxColorAttachments; i++) { + struct gl_renderbuffer_attachment *att = + &fb->Attachment[BUFFER_COLOR0 + i]; + enum pipe_format format; + + if (!do_validate_attachment(ctx, screen, att, PIPE_BIND_RENDER_TARGET)) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + fbo_invalid("Invalid color attachment"); + return; + } + + if (!mixed_formats) { + /* Disallow mixed formats. */ + if (att->Type != GL_NONE) { + format = att->Renderbuffer->surface->format; + } else { + continue; + } + + if (first_format == PIPE_FORMAT_NONE) { + first_format = format; + } else if (format != first_format) { + fb->_Status = GL_FRAMEBUFFER_UNSUPPORTED_EXT; + fbo_invalid("Mixed color formats"); + return; + } + } + } +} + /** * Test if the given framebuffer object is complete and update its @@ -1118,7 +1291,8 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->_HasSNormOrFloatColorBuffer = GL_FALSE; fb->_HasAttachments = true; fb->_IntegerBuffers = 0; - fb->_RGBBuffers = 0; + fb->_BlendForceAlphaToOne = 0; + fb->_IsRGB = 0; fb->_FP32Buffers = 0; /* Start at -2 to more easily loop over all attachment points. @@ -1280,7 +1454,13 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, fb->_IntegerBuffers |= (1 << i); if (baseFormat == GL_RGB) - fb->_RGBBuffers |= (1 << i); + fb->_IsRGB |= (1 << i); + + if (ctx->st->has_indep_blend_func && + ((baseFormat == GL_RGB) || + (baseFormat == GL_LUMINANCE && !util_format_is_luminance(attFormat)) || + (baseFormat == GL_INTENSITY && !util_format_is_intensity(attFormat)))) + fb->_BlendForceAlphaToOne |= (1 << i); if (type == GL_FLOAT && _mesa_get_format_max_bits(attFormat) > 16) fb->_FP32Buffers |= (1 << i); @@ -1519,12 +1699,10 @@ _mesa_test_framebuffer_completeness(struct gl_context *ctx, * Drivers will most likely set the status to GL_FRAMEBUFFER_UNSUPPORTED * if anything. */ - if (ctx->Driver.ValidateFramebuffer) { - ctx->Driver.ValidateFramebuffer(ctx, fb); - if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { - fbo_incomplete(ctx, "driver marked FBO as incomplete", -1); - return; - } + do_validate_framebuffer(ctx, fb); + if (fb->_Status != GL_FRAMEBUFFER_COMPLETE_EXT) { + fbo_incomplete(ctx, "driver marked FBO as incomplete", -1); + return; } /* @@ -1558,20 +1736,19 @@ _mesa_IsRenderbuffer(GLuint renderbuffer) static struct gl_renderbuffer * allocate_renderbuffer_locked(struct gl_context *ctx, GLuint renderbuffer, - bool isGenName, const char *func) { struct gl_renderbuffer *newRb; /* create new renderbuffer object */ - newRb = ctx->Driver.NewRenderbuffer(ctx, renderbuffer); + newRb = new_renderbuffer(ctx, renderbuffer); if (!newRb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return NULL; } assert(newRb->AllocStorage); - _mesa_HashInsertLocked(ctx->Shared->RenderBuffers, renderbuffer, - newRb, isGenName); + _mesa_HashInsertLocked(&ctx->Shared->RenderBuffers, renderbuffer, + newRb); return newRb; } @@ -1593,14 +1770,12 @@ bind_renderbuffer(GLenum target, GLuint renderbuffer) */ if (renderbuffer) { - bool isGenName = false; newRb = _mesa_lookup_renderbuffer(ctx, renderbuffer); if (newRb == &DummyRenderbuffer) { /* ID was reserved, but no real renderbuffer object made yet */ newRb = NULL; - isGenName = true; } - else if (!newRb && ctx->API == API_OPENGL_CORE) { + else if (!newRb && _mesa_is_desktop_gl_core(ctx)) { /* All RB IDs must be Gen'd */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindRenderbuffer(non-gen name)"); @@ -1608,10 +1783,10 @@ bind_renderbuffer(GLenum target, GLuint renderbuffer) } if (!newRb) { - _mesa_HashLockMutex(ctx->Shared->RenderBuffers); + _mesa_HashLockMutex(&ctx->Shared->RenderBuffers); newRb = allocate_renderbuffer_locked(ctx, renderbuffer, - isGenName, "glBindRenderbufferEXT"); - _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); + "glBindRenderbufferEXT"); + _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers); } } else { @@ -1730,7 +1905,7 @@ framebuffer_parameteri(struct gl_context *ctx, struct gl_framebuffer *fb, case GL_FRAMEBUFFER_PROGRAMMABLE_SAMPLE_LOCATIONS_ARB: case GL_FRAMEBUFFER_SAMPLE_LOCATION_PIXEL_GRID_ARB: if (fb == ctx->DrawBuffer) - ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations; + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; break; default: invalidate_framebuffer(fb); @@ -2051,7 +2226,7 @@ _mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers) * But the object will not be freed until it's no longer * referenced anywhere else. */ - _mesa_HashRemove(ctx->Shared->RenderBuffers, renderbuffers[i]); + _mesa_HashRemove(&ctx->Shared->RenderBuffers, renderbuffers[i]); if (rb != &DummyRenderbuffer) { /* no longer referenced by hash table */ @@ -2072,21 +2247,21 @@ create_render_buffers(struct gl_context *ctx, GLsizei n, GLuint *renderbuffers, if (!renderbuffers) return; - _mesa_HashLockMutex(ctx->Shared->RenderBuffers); + _mesa_HashLockMutex(&ctx->Shared->RenderBuffers); - _mesa_HashFindFreeKeys(ctx->Shared->RenderBuffers, renderbuffers, n); + _mesa_HashFindFreeKeys(&ctx->Shared->RenderBuffers, renderbuffers, n); for (i = 0; i < n; i++) { if (dsa) { - allocate_renderbuffer_locked(ctx, renderbuffers[i], true, func); + allocate_renderbuffer_locked(ctx, renderbuffers[i], func); } else { /* insert a dummy renderbuffer into the hash table */ - _mesa_HashInsertLocked(ctx->Shared->RenderBuffers, renderbuffers[i], - &DummyRenderbuffer, true); + _mesa_HashInsertLocked(&ctx->Shared->RenderBuffers, renderbuffers[i], + &DummyRenderbuffer); } } - _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); + _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers); } @@ -2165,14 +2340,14 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_ALPHA8: case GL_ALPHA12: case GL_ALPHA16: - return (ctx->API == API_OPENGL_COMPAT && + return (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_framebuffer_object) ? GL_ALPHA : 0; case GL_LUMINANCE: case GL_LUMINANCE4: case GL_LUMINANCE8: case GL_LUMINANCE12: case GL_LUMINANCE16: - return (ctx->API == API_OPENGL_COMPAT && + return (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_framebuffer_object) ? GL_LUMINANCE : 0; case GL_LUMINANCE_ALPHA: case GL_LUMINANCE4_ALPHA4: @@ -2181,14 +2356,14 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_LUMINANCE12_ALPHA4: case GL_LUMINANCE12_ALPHA12: case GL_LUMINANCE16_ALPHA16: - return (ctx->API == API_OPENGL_COMPAT && + return (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_framebuffer_object) ? GL_LUMINANCE_ALPHA : 0; case GL_INTENSITY: case GL_INTENSITY4: case GL_INTENSITY8: case GL_INTENSITY12: case GL_INTENSITY16: - return (ctx->API == API_OPENGL_COMPAT && + return (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_framebuffer_object) ? GL_INTENSITY : 0; case GL_RGB8: return GL_RGB; @@ -2238,12 +2413,12 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) return GL_DEPTH_STENCIL; case GL_DEPTH_COMPONENT32F: return ctx->Version >= 30 - || (ctx->API == API_OPENGL_COMPAT && + || (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_depth_buffer_float) ? GL_DEPTH_COMPONENT : 0; case GL_DEPTH32F_STENCIL8: return ctx->Version >= 30 - || (ctx->API == API_OPENGL_COMPAT && + || (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_depth_buffer_float) ? GL_DEPTH_STENCIL : 0; case GL_RED: @@ -2301,7 +2476,7 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_ALPHA_SNORM: case GL_ALPHA8_SNORM: case GL_ALPHA16_SNORM: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_texture_snorm && ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; case GL_LUMINANCE_SNORM: @@ -2370,22 +2545,22 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) ? GL_RGB: 0; case GL_ALPHA16F_ARB: case GL_ALPHA32F_ARB: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_texture_float && ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; case GL_LUMINANCE16F_ARB: case GL_LUMINANCE32F_ARB: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_texture_float && ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0; case GL_LUMINANCE_ALPHA16F_ARB: case GL_LUMINANCE_ALPHA32F_ARB: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_texture_float && ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0; case GL_INTENSITY16F_ARB: case GL_INTENSITY32F_ARB: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_texture_float && ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0; case GL_R11F_G11F_B10F: @@ -2439,7 +2614,7 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_INTENSITY16UI_EXT: case GL_INTENSITY32I_EXT: case GL_INTENSITY32UI_EXT: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_texture_integer && ctx->Extensions.ARB_framebuffer_object ? GL_INTENSITY : 0; @@ -2449,7 +2624,7 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_LUMINANCE16UI_EXT: case GL_LUMINANCE32I_EXT: case GL_LUMINANCE32UI_EXT: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_texture_integer && ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE : 0; @@ -2459,7 +2634,7 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_LUMINANCE_ALPHA16UI_EXT: case GL_LUMINANCE_ALPHA32I_EXT: case GL_LUMINANCE_ALPHA32UI_EXT: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_texture_integer && ctx->Extensions.ARB_framebuffer_object ? GL_LUMINANCE_ALPHA : 0; @@ -2469,7 +2644,7 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_ALPHA16UI_EXT: case GL_ALPHA32I_EXT: case GL_ALPHA32UI_EXT: - return ctx->API == API_OPENGL_COMPAT && + return _mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_texture_integer && ctx->Extensions.ARB_framebuffer_object ? GL_ALPHA : 0; @@ -2481,6 +2656,16 @@ _mesa_base_fbo_format(const struct gl_context *ctx, GLenum internalFormat) case GL_RGB565: return _mesa_is_gles(ctx) || ctx->Extensions.ARB_ES2_compatibility ? GL_RGB : 0; + + case GL_BGRA: + /* EXT_texture_format_BGRA8888 only adds this as color-renderable for + * GLES 2 and later + */ + if (_mesa_has_EXT_texture_format_BGRA8888(ctx) && _mesa_is_gles2(ctx)) + return GL_RGBA; + else + return 0; + default: return 0; } @@ -2574,7 +2759,7 @@ _mesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, /* Invalidate the framebuffers the renderbuffer is attached in. */ if (rb->AttachedAnytime) { - _mesa_HashWalk(ctx->Shared->FrameBuffers, invalidate_rb, rb); + _mesa_HashWalk(&ctx->Shared->FrameBuffers, invalidate_rb, rb); } } @@ -2748,9 +2933,16 @@ _mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image) return; } + if (!image || (ctx->Driver.ValidateEGLImage && + !ctx->Driver.ValidateEGLImage(ctx, image))) { + _mesa_error(ctx, GL_INVALID_VALUE, + "EGLImageTargetRenderbufferStorageOES"); + return; + } + FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); - ctx->Driver.EGLImageTargetRenderbufferStorage(ctx, rb, image); + st_egl_image_target_renderbuffer_storage(ctx, rb, image); } @@ -2808,27 +3000,6 @@ _mesa_RenderbufferStorageMultisampleAdvancedAMD( } -/** - * OpenGL ES version of glRenderBufferStorage. - */ -void GLAPIENTRY -_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, - GLsizei width, GLsizei height) -{ - switch (internalFormat) { - case GL_RGB565: - /* XXX this confuses GL_RENDERBUFFER_INTERNAL_FORMAT_OES */ - /* choose a closest format */ - internalFormat = GL_RGB5; - break; - default: - break; - } - - renderbuffer_storage_target(target, internalFormat, width, height, 0, 0, - "glRenderbufferStorageEXT"); -} - void GLAPIENTRY _mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, GLsizei width, GLsizei height) @@ -2848,10 +3019,10 @@ _mesa_NamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, GET_CURRENT_CONTEXT(ctx); struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); if (!rb || rb == &DummyRenderbuffer) { - _mesa_HashLockMutex(ctx->Shared->RenderBuffers); - rb = allocate_renderbuffer_locked(ctx, renderbuffer, rb != NULL, + _mesa_HashLockMutex(&ctx->Shared->RenderBuffers); + rb = allocate_renderbuffer_locked(ctx, renderbuffer, "glNamedRenderbufferStorageEXT"); - _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); + _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers); } renderbuffer_storage(ctx, rb, internalformat, width, height, NO_SAMPLES, 0, "glNamedRenderbufferStorageEXT"); @@ -2877,10 +3048,10 @@ _mesa_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei sample GET_CURRENT_CONTEXT(ctx); struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); if (!rb || rb == &DummyRenderbuffer) { - _mesa_HashLockMutex(ctx->Shared->RenderBuffers); - rb = allocate_renderbuffer_locked(ctx, renderbuffer, rb != NULL, + _mesa_HashLockMutex(&ctx->Shared->RenderBuffers); + rb = allocate_renderbuffer_locked(ctx, renderbuffer, "glNamedRenderbufferStorageMultisampleEXT"); - _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); + _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers); } renderbuffer_storage(ctx, rb, internalformat, width, height, samples, samples, @@ -2995,10 +3166,10 @@ _mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, renderbuffer); if (!rb || rb == &DummyRenderbuffer) { - _mesa_HashLockMutex(ctx->Shared->RenderBuffers); - rb = allocate_renderbuffer_locked(ctx, renderbuffer, rb != NULL, + _mesa_HashLockMutex(&ctx->Shared->RenderBuffers); + rb = allocate_renderbuffer_locked(ctx, renderbuffer, "glGetNamedRenderbufferParameterivEXT"); - _mesa_HashUnlockMutex(ctx->Shared->RenderBuffers); + _mesa_HashUnlockMutex(&ctx->Shared->RenderBuffers); } get_render_buffer_parameteriv(ctx, rb, pname, params, @@ -3029,7 +3200,6 @@ static void check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) { GLuint i; - assert(ctx->Driver.RenderTexture); if (_mesa_is_winsys_fbo(fb)) return; /* can't render to texture with winsys framebuffers */ @@ -3038,7 +3208,7 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) struct gl_renderbuffer_attachment *att = fb->Attachment + i; if (att->Texture && att->Renderbuffer->TexImage && driver_RenderTexture_is_safe(att)) { - ctx->Driver.RenderTexture(ctx, fb, att); + render_texture(ctx, fb, att); } } } @@ -3052,18 +3222,15 @@ check_begin_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) static void check_end_texture_render(struct gl_context *ctx, struct gl_framebuffer *fb) { - /* Skip if we know NeedsFinishRenderTexture won't be set. */ - if (_mesa_is_winsys_fbo(fb) && !ctx->Driver.BindRenderbufferTexImage) + if (_mesa_is_winsys_fbo(fb)) return; - if (ctx->Driver.FinishRenderTexture) { - GLuint i; - for (i = 0; i < BUFFER_COUNT; i++) { - struct gl_renderbuffer_attachment *att = fb->Attachment + i; - struct gl_renderbuffer *rb = att->Renderbuffer; - if (rb && rb->NeedsFinishRenderTexture) { - ctx->Driver.FinishRenderTexture(ctx, rb); - } + GLuint i; + for (i = 0; i < BUFFER_COUNT; i++) { + struct gl_renderbuffer_attachment *att = fb->Attachment + i; + struct gl_renderbuffer *rb = att->Renderbuffer; + if (rb) { + finish_render_texture(ctx, rb); } } } @@ -3095,15 +3262,13 @@ bind_framebuffer(GLenum target, GLuint framebuffer) } if (framebuffer) { - bool isGenName = false; /* Binding a user-created framebuffer object */ newDrawFb = _mesa_lookup_framebuffer(ctx, framebuffer); if (newDrawFb == &DummyFramebuffer) { /* ID was reserved, but no real framebuffer object made yet */ newDrawFb = NULL; - isGenName = true; } - else if (!newDrawFb && ctx->API == API_OPENGL_CORE) { + else if (!newDrawFb && _mesa_is_desktop_gl_core(ctx)) { /* All FBO IDs must be Gen'd */ _mesa_error(ctx, GL_INVALID_OPERATION, "glBindFramebuffer(non-gen name)"); @@ -3112,12 +3277,12 @@ bind_framebuffer(GLenum target, GLuint framebuffer) if (!newDrawFb) { /* create new framebuffer object */ - newDrawFb = ctx->Driver.NewFramebuffer(ctx, framebuffer); + newDrawFb = _mesa_new_framebuffer(ctx, framebuffer); if (!newDrawFb) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBindFramebufferEXT"); return; } - _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, newDrawFb, isGenName); + _mesa_HashInsert(&ctx->Shared->FrameBuffers, framebuffer, newDrawFb); } newReadFb = newDrawFb; } @@ -3125,8 +3290,10 @@ bind_framebuffer(GLenum target, GLuint framebuffer) /* Binding the window system framebuffer (which was originally set * with MakeCurrent). */ - newDrawFb = ctx->WinSysDrawBuffer; - newReadFb = ctx->WinSysReadBuffer; + if (bindDrawBuf) + newDrawFb = ctx->WinSysDrawBuffer; + if (bindReadBuf) + newReadFb = ctx->WinSysReadBuffer; } _mesa_bind_framebuffers(ctx, @@ -3167,7 +3334,7 @@ _mesa_bind_framebuffers(struct gl_context *ctx, if (bindDrawBuf) { FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations; + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; /* check if old framebuffer had any texture attachments */ if (oldDrawFb) @@ -3180,15 +3347,6 @@ _mesa_bind_framebuffers(struct gl_context *ctx, _mesa_update_allow_draw_out_of_order(ctx); _mesa_update_valid_to_render_state(ctx); } - - if ((bindDrawBuf || bindReadBuf) && ctx->Driver.BindFramebuffer) { - /* The few classic drivers that actually hook this function really only - * want to know if the draw framebuffer changed. - */ - ctx->Driver.BindFramebuffer(ctx, - bindDrawBuf ? GL_FRAMEBUFFER : GL_READ_FRAMEBUFFER, - newDrawFb, newReadFb); - } } void GLAPIENTRY @@ -3241,7 +3399,7 @@ _mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers) } /* remove from hash table immediately, to free the ID */ - _mesa_HashRemove(ctx->Shared->FrameBuffers, framebuffers[i]); + _mesa_HashRemove(&ctx->Shared->FrameBuffers, framebuffers[i]); if (fb != &DummyFramebuffer) { /* But the object will not be freed until it's no longer @@ -3277,15 +3435,15 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa) if (!framebuffers) return; - _mesa_HashLockMutex(ctx->Shared->FrameBuffers); + _mesa_HashLockMutex(&ctx->Shared->FrameBuffers); - _mesa_HashFindFreeKeys(ctx->Shared->FrameBuffers, framebuffers, n); + _mesa_HashFindFreeKeys(&ctx->Shared->FrameBuffers, framebuffers, n); for (i = 0; i < n; i++) { if (dsa) { - fb = ctx->Driver.NewFramebuffer(ctx, framebuffers[i]); + fb = _mesa_new_framebuffer(ctx, framebuffers[i]); if (!fb) { - _mesa_HashUnlockMutex(ctx->Shared->FrameBuffers); + _mesa_HashUnlockMutex(&ctx->Shared->FrameBuffers); _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; } @@ -3293,11 +3451,10 @@ create_framebuffers(GLsizei n, GLuint *framebuffers, bool dsa) else fb = &DummyFramebuffer; - _mesa_HashInsertLocked(ctx->Shared->FrameBuffers, framebuffers[i], - fb, true); + _mesa_HashInsertLocked(&ctx->Shared->FrameBuffers, framebuffers[i], fb); } - _mesa_HashUnlockMutex(ctx->Shared->FrameBuffers); + _mesa_HashUnlockMutex(&ctx->Shared->FrameBuffers); } @@ -3652,10 +3809,11 @@ check_textarget(struct gl_context *ctx, int dims, GLenum target, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - err = dims != 2 || !ctx->Extensions.ARB_texture_cube_map; + err = dims != 2; break; case GL_TEXTURE_3D: - err = dims != 3; + err = dims != 3 || + (_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D); break; default: _mesa_error(ctx, GL_INVALID_ENUM, @@ -4216,8 +4374,7 @@ _mesa_framebuffer_renderbuffer(struct gl_context *ctx, FLUSH_VERTICES(ctx, _NEW_BUFFERS, 0); - assert(ctx->Driver.FramebufferRenderbuffer); - ctx->Driver.FramebufferRenderbuffer(ctx, fb, attachment, rb); + _mesa_FramebufferRenderbuffer_sw(ctx, fb, attachment, rb); /* Some subsequent GL commands may depend on the framebuffer's visual * after the binding is updated. Update visual info now. @@ -4430,7 +4587,7 @@ get_framebuffer_attachment_parameter(struct gl_context *ctx, * FRAMEBUFFER_ATTACHMENT_OBJECT_NAME will return zero, and all other * queries will generate an INVALID_OPERATION error." */ - err = ctx->API == API_OPENGLES2 && ctx->Version < 30 ? + err = _mesa_is_gles2(ctx) && ctx->Version < 30 ? GL_INVALID_ENUM : GL_INVALID_OPERATION; if (_mesa_is_winsys_fbo(buffer)) { @@ -4593,7 +4750,7 @@ get_framebuffer_attachment_parameter(struct gl_context *ctx, } return; case GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_3D_ZOFFSET_EXT: - if (ctx->API == API_OPENGLES) { + if (_mesa_is_gles1(ctx)) { goto invalid_pname_enum; } else if (att->Type == GL_NONE) { _mesa_error(ctx, err, "%s(invalid pname %s)", caller, @@ -4896,8 +5053,8 @@ lookup_named_framebuffer_ext_dsa(struct gl_context *ctx, GLuint framebuffer, con } /* Then, make sure it's initialized */ if (fb == &DummyFramebuffer) { - fb = ctx->Driver.NewFramebuffer(ctx, framebuffer); - _mesa_HashInsert(ctx->Shared->FrameBuffers, framebuffer, fb, true); + fb = _mesa_new_framebuffer(ctx, framebuffer); + _mesa_HashInsert(&ctx->Shared->FrameBuffers, framebuffer, fb); } } else @@ -5139,13 +5296,13 @@ invalid_enum: return; } -static struct gl_renderbuffer_attachment * -get_fb_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, - const GLenum attachment) +static gl_buffer_index +get_fb_attachment_index(struct gl_context *ctx, struct gl_framebuffer *fb, + const GLenum attachment) { switch (attachment) { case GL_COLOR: - return &fb->Attachment[BUFFER_BACK_LEFT]; + return BUFFER_BACK_LEFT; case GL_COLOR_ATTACHMENT0: case GL_COLOR_ATTACHMENT1: case GL_COLOR_ATTACHMENT2: @@ -5164,19 +5321,67 @@ get_fb_attachment(struct gl_context *ctx, struct gl_framebuffer *fb, case GL_COLOR_ATTACHMENT15: { const unsigned i = attachment - GL_COLOR_ATTACHMENT0; if (i >= ctx->Const.MaxColorAttachments) - return NULL; + return BUFFER_NONE; assert(BUFFER_COLOR0 + i < ARRAY_SIZE(fb->Attachment)); - return &fb->Attachment[BUFFER_COLOR0 + i]; + return BUFFER_COLOR0 + i; } case GL_DEPTH: case GL_DEPTH_ATTACHMENT: case GL_DEPTH_STENCIL_ATTACHMENT: - return &fb->Attachment[BUFFER_DEPTH]; + return BUFFER_DEPTH; case GL_STENCIL: case GL_STENCIL_ATTACHMENT: - return &fb->Attachment[BUFFER_STENCIL]; + return BUFFER_STENCIL; default: - return NULL; + return BUFFER_NONE; + } +} + +static void +do_discard_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, + struct gl_renderbuffer_attachment *att) +{ + struct pipe_resource *prsc; + + if (!att->Renderbuffer || !att->Complete) + return; + + prsc = att->Renderbuffer->surface->texture; + + /* using invalidate_resource will only work for simple 2D resources */ + if (prsc->depth0 != 1 || prsc->array_size != 1 || prsc->last_level != 0) + return; + + if (ctx->pipe->invalidate_resource) + ctx->pipe->invalidate_resource(ctx->pipe, prsc); +} + +static void +discard_attachments(struct gl_context *ctx, struct gl_framebuffer *fb, + uint32_t mask) +{ + const uint32_t zsmask = BITFIELD_BIT(BUFFER_DEPTH) | BITFIELD_BIT(BUFFER_STENCIL); + + /* If we're asked to invalidate just depth or just stencil, but the + * attachment is packed depth/stencil, then we can only use + * DiscardFramebuffer if the attachments list includes both depth + * and stencil and they both point at the same renderbuffer. + * + * Note EXT_discard_framebuffer says that discarding only one component + * of a packed z/s implicitly discards both. But glInvalidateFramebuffer + * does not appear to specify the behavior. So this may be overly + * conservative. + */ + if ((mask & zsmask) && ((mask & zsmask) != zsmask) && + (fb->Attachment[BUFFER_DEPTH].Renderbuffer == + fb->Attachment[BUFFER_STENCIL].Renderbuffer)) { + mask &= ~zsmask; + } + + u_foreach_bit (b, mask) { + struct gl_renderbuffer_attachment *att = &fb->Attachment[b]; + + do_discard_framebuffer(ctx, fb, att); } } @@ -5184,42 +5389,34 @@ static void discard_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb, GLsizei numAttachments, const GLenum *attachments) { - if (!ctx->Driver.DiscardFramebuffer) + uint32_t mask = 0; + + if (unlikely(ctx->st_opts->ignore_discard_framebuffer)) return; for (int i = 0; i < numAttachments; i++) { - struct gl_renderbuffer_attachment *att = - get_fb_attachment(ctx, fb, attachments[i]); - - if (!att) - continue; - - /* If we're asked to invalidate just depth or just stencil, but the - * attachment is packed depth/stencil, then we can only use - * Driver.DiscardFramebuffer if the attachments list includes both depth - * and stencil and they both point at the same renderbuffer. - */ - if ((attachments[i] == GL_DEPTH_ATTACHMENT || - attachments[i] == GL_STENCIL_ATTACHMENT) && - (!att->Renderbuffer || - att->Renderbuffer->_BaseFormat == GL_DEPTH_STENCIL)) { - GLenum other_format = (attachments[i] == GL_DEPTH_ATTACHMENT ? - GL_STENCIL_ATTACHMENT : GL_DEPTH_ATTACHMENT); - bool has_both = false; - for (int j = 0; j < numAttachments; j++) { - if (attachments[j] == other_format) { - has_both = true; - break; - } + GLenum att = attachments[i]; + + /* A couple enums need special handling, because gl.. */ + if (!_mesa_is_user_fbo(fb)) { + if (att == GL_DEPTH) { + att = GL_DEPTH_ATTACHMENT; + } else if (att == GL_STENCIL) { + att = GL_STENCIL_ATTACHMENT; } + } - if (fb->Attachment[BUFFER_DEPTH].Renderbuffer != - fb->Attachment[BUFFER_STENCIL].Renderbuffer || !has_both) - continue; + if (att == GL_DEPTH_STENCIL_ATTACHMENT) { + mask |= BITFIELD_BIT(BUFFER_DEPTH) | BITFIELD_BIT(BUFFER_STENCIL); + continue; } - ctx->Driver.DiscardFramebuffer(ctx, fb, att); + gl_buffer_index idx = get_fb_attachment_index(ctx, fb, att); + if (idx != BUFFER_NONE) + mask |= BITFIELD_BIT(idx); } + + discard_attachments(ctx, fb, mask); } void GLAPIENTRY @@ -5332,6 +5529,15 @@ _mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments, discard_framebuffer(ctx, fb, numAttachments, attachments); } +void GLAPIENTRY +_mesa_InternalInvalidateFramebufferAncillaryMESA(void) +{ + GET_CURRENT_CONTEXT(ctx); + + struct gl_framebuffer *fb = get_framebuffer_target(ctx, GL_FRAMEBUFFER); + discard_attachments(ctx, fb, BITFIELD_BIT(BUFFER_DEPTH) | BITFIELD_BIT(BUFFER_STENCIL)); +} + void GLAPIENTRY _mesa_InvalidateNamedFramebufferData(GLuint framebuffer, @@ -5485,7 +5691,7 @@ sample_locations(struct gl_context *ctx, struct gl_framebuffer *fb, } if (fb == ctx->DrawBuffer) - ctx->NewDriverState |= ctx->DriverFlags.NewSampleLocations; + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; } void GLAPIENTRY @@ -5560,6 +5766,7 @@ _mesa_EvaluateDepthValuesARB(void) return; } - if (ctx->Driver.EvaluateDepthValues) - ctx->Driver.EvaluateDepthValues(ctx); + st_validate_state(st_context(ctx), ST_PIPELINE_UPDATE_FB_STATE_MASK); + + ctx->pipe->evaluate_depth_buffer(ctx->pipe); } diff --git a/src/mesa/main/fbobject.h b/src/mesa/main/fbobject.h index 2a32c158e68..7dedf1006ea 100644 --- a/src/mesa/main/fbobject.h +++ b/src/mesa/main/fbobject.h @@ -26,7 +26,7 @@ #ifndef FBOBJECT_H #define FBOBJECT_H -#include "glheader.h" +#include "util/glheader.h" #include <stdbool.h> struct gl_context; @@ -82,12 +82,6 @@ _mesa_update_texture_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer_attachment *att); extern void -_mesa_FramebufferRenderbuffer_sw(struct gl_context *ctx, - struct gl_framebuffer *fb, - GLenum attachment, - struct gl_renderbuffer *rb); - -extern void _mesa_framebuffer_renderbuffer(struct gl_context *ctx, struct gl_framebuffer *fb, GLenum attachment, @@ -99,9 +93,6 @@ _mesa_renderbuffer_storage(struct gl_context *ctx, struct gl_renderbuffer *rb, GLsizei height, GLsizei samples, GLsizei storageSamples); -extern void -_mesa_validate_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb); - extern GLboolean _mesa_has_depthstencil_combined(const struct gl_framebuffer *fb); @@ -142,312 +133,7 @@ _mesa_bind_framebuffers(struct gl_context *ctx, struct gl_framebuffer *newDrawFb, struct gl_framebuffer *newReadFb); -extern GLboolean GLAPIENTRY -_mesa_IsRenderbuffer(GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_BindRenderbuffer(GLenum target, GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_BindRenderbufferEXT(GLenum target, GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_DeleteRenderbuffers(GLsizei n, const GLuint *renderbuffers); - -void GLAPIENTRY -_mesa_GenRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers); - -extern void GLAPIENTRY -_mesa_GenRenderbuffers(GLsizei n, GLuint *renderbuffers); - -void GLAPIENTRY -_mesa_CreateRenderbuffers_no_error(GLsizei n, GLuint *renderbuffers); - -extern void GLAPIENTRY -_mesa_CreateRenderbuffers(GLsizei n, GLuint *renderbuffers); - -extern void GLAPIENTRY -_mesa_RenderbufferStorage(GLenum target, GLenum internalformat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_RenderbufferStorageMultisample(GLenum target, GLsizei samples, - GLenum internalformat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_RenderbufferStorageMultisampleAdvancedAMD( - GLenum target, GLsizei samples, GLsizei storageSamples, - GLenum internalFormat, GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_es_RenderbufferStorageEXT(GLenum target, GLenum internalFormat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_NamedRenderbufferStorage(GLuint renderbuffer, GLenum internalformat, - GLsizei width, GLsizei height); -extern void GLAPIENTRY -_mesa_NamedRenderbufferStorageEXT(GLuint renderbuffer, GLenum internalformat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_NamedRenderbufferStorageMultisample(GLuint renderbuffer, GLsizei samples, - GLenum internalformat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_NamedRenderbufferStorageMultisampleEXT(GLuint renderbuffer, GLsizei samples, - GLenum internalformat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_NamedRenderbufferStorageMultisampleAdvancedAMD( - GLuint renderbuffer, GLsizei samples, GLsizei storageSamples, - GLenum internalformat, GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_EGLImageTargetRenderbufferStorageOES(GLenum target, GLeglImageOES image); - -extern void GLAPIENTRY -_mesa_GetRenderbufferParameteriv(GLenum target, GLenum pname, - GLint *params); - -void GLAPIENTRY -_mesa_GetNamedRenderbufferParameteriv(GLuint renderbuffer, GLenum pname, - GLint *params); - -extern GLboolean GLAPIENTRY -_mesa_IsFramebuffer(GLuint framebuffer); - -extern void GLAPIENTRY -_mesa_BindFramebuffer(GLenum target, GLuint framebuffer); - -extern void GLAPIENTRY -_mesa_BindFramebufferEXT(GLenum target, GLuint framebuffer); - -extern void GLAPIENTRY -_mesa_DeleteFramebuffers(GLsizei n, const GLuint *framebuffers); - -extern void GLAPIENTRY -_mesa_GenFramebuffers(GLsizei n, GLuint *framebuffers); - -extern void GLAPIENTRY -_mesa_CreateFramebuffers(GLsizei n, GLuint *framebuffers); - -GLenum GLAPIENTRY -_mesa_CheckFramebufferStatus_no_error(GLenum target); - -extern GLenum GLAPIENTRY -_mesa_CheckFramebufferStatus(GLenum target); - -extern GLenum GLAPIENTRY -_mesa_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target); - -extern GLenum GLAPIENTRY -_mesa_CheckNamedFramebufferStatusEXT(GLuint framebuffer, GLenum target); - -extern void GLAPIENTRY -_mesa_FramebufferTexture1D_no_error(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level); -extern void GLAPIENTRY -_mesa_FramebufferTexture1D(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level); - -extern void GLAPIENTRY -_mesa_FramebufferTexture2D_no_error(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level); -extern void GLAPIENTRY -_mesa_FramebufferTexture2D(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, GLint level); - void GLAPIENTRY -_mesa_FramebufferTexture2DMultisampleEXT(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level, GLsizei samples); - -extern void GLAPIENTRY -_mesa_FramebufferTexture3D_no_error(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level, GLint layer); -extern void GLAPIENTRY -_mesa_FramebufferTexture3D(GLenum target, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level, GLint layer); - -extern void GLAPIENTRY -_mesa_FramebufferTextureLayer_no_error(GLenum target, GLenum attachment, - GLuint texture, GLint level, - GLint layer); -extern void GLAPIENTRY -_mesa_FramebufferTextureLayer(GLenum target, GLenum attachment, - GLuint texture, GLint level, GLint layer); - -extern void GLAPIENTRY -_mesa_NamedFramebufferTextureLayer_no_error(GLuint framebuffer, - GLenum attachment, - GLuint texture, GLint level, - GLint layer); -extern void GLAPIENTRY -_mesa_NamedFramebufferTextureLayer(GLuint framebuffer, GLenum attachment, - GLuint texture, GLint level, GLint layer); - -extern void GLAPIENTRY -_mesa_FramebufferTexture_no_error(GLenum target, GLenum attachment, - GLuint texture, GLint level); -extern void GLAPIENTRY -_mesa_FramebufferTexture(GLenum target, GLenum attachment, - GLuint texture, GLint level); - -extern void GLAPIENTRY -_mesa_NamedFramebufferTexture_no_error(GLuint framebuffer, GLenum attachment, - GLuint texture, GLint level); -extern void GLAPIENTRY -_mesa_NamedFramebufferTexture(GLuint framebuffer, GLenum attachment, - GLuint texture, GLint level); - -extern void GLAPIENTRY -_mesa_NamedFramebufferRenderbufferEXT(GLuint framebuffer, GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_NamedFramebufferTexture1DEXT(GLuint framebuffer, GLenum attachment, - GLenum textarget, GLuint texture, GLint level); - -extern void GLAPIENTRY -_mesa_NamedFramebufferTexture2DEXT(GLuint framebuffer, GLenum attachment, - GLenum textarget, GLuint texture, GLint level); - -extern void GLAPIENTRY -_mesa_NamedFramebufferTexture3DEXT(GLuint framebuffer, GLenum attachment, - GLenum textarget, GLuint texture, - GLint level, GLint zoffset); - -void GLAPIENTRY -_mesa_FramebufferRenderbuffer_no_error(GLenum target, GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_FramebufferRenderbuffer(GLenum target, GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer); - -void GLAPIENTRY -_mesa_NamedFramebufferRenderbuffer_no_error(GLuint framebuffer, - GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_NamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment, - GLenum renderbuffertarget, - GLuint renderbuffer); - -extern void GLAPIENTRY -_mesa_GetFramebufferAttachmentParameteriv(GLenum target, GLenum attachment, - GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetNamedFramebufferAttachmentParameteriv(GLuint framebuffer, - GLenum attachment, - GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetNamedFramebufferAttachmentParameterivEXT(GLuint framebuffer, - GLenum attachment, - GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_NamedFramebufferParameteri(GLuint framebuffer, GLenum pname, - GLint param); - -extern void GLAPIENTRY -_mesa_NamedFramebufferParameteriEXT(GLuint framebuffer, GLenum pname, - GLint param); - -extern void GLAPIENTRY -_mesa_GetNamedRenderbufferParameterivEXT(GLuint renderbuffer, GLenum pname, - GLint *params); - -extern void GLAPIENTRY -_mesa_GetFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, - GLint *param); - -extern void GLAPIENTRY -_mesa_GetNamedFramebufferParameteriv(GLuint framebuffer, GLenum pname, - GLint *param); - -extern void GLAPIENTRY -_mesa_GetNamedFramebufferParameterivEXT(GLuint framebuffer, GLenum pname, - GLint *param); - -void GLAPIENTRY -_mesa_InvalidateSubFramebuffer_no_error(GLenum target, GLsizei numAttachments, - const GLenum *attachments, GLint x, - GLint y, GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_InvalidateSubFramebuffer(GLenum target, GLsizei numAttachments, - const GLenum *attachments, GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_InvalidateNamedFramebufferSubData(GLuint framebuffer, - GLsizei numAttachments, - const GLenum *attachments, - GLint x, GLint y, - GLsizei width, GLsizei height); -void GLAPIENTRY -_mesa_InvalidateFramebuffer_no_error(GLenum target, GLsizei numAttachments, - const GLenum *attachments); - -extern void GLAPIENTRY -_mesa_InvalidateFramebuffer(GLenum target, GLsizei numAttachments, - const GLenum *attachments); - -extern void GLAPIENTRY -_mesa_InvalidateNamedFramebufferData(GLuint framebuffer, - GLsizei numAttachments, - const GLenum *attachments); - -extern void GLAPIENTRY -_mesa_DiscardFramebufferEXT(GLenum target, GLsizei numAttachments, - const GLenum *attachments); - -extern void GLAPIENTRY -_mesa_FramebufferParameteri(GLenum target, GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_FramebufferParameteriMESA(GLenum target, GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_GetFramebufferParameteriv(GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetFramebufferParameterivMESA(GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_FramebufferSampleLocationsfvARB(GLenum target, GLuint start, - GLsizei count, const GLfloat *v); - -extern void GLAPIENTRY -_mesa_NamedFramebufferSampleLocationsfvARB(GLuint framebuffer, GLuint start, - GLsizei count, const GLfloat *v); - -extern void GLAPIENTRY -_mesa_FramebufferSampleLocationsfvARB_no_error(GLenum target, GLuint start, - GLsizei count, const GLfloat *v); - -extern void GLAPIENTRY -_mesa_NamedFramebufferSampleLocationsfvARB_no_error(GLuint framebuffer, - GLuint start, GLsizei count, - const GLfloat *v); - -extern void GLAPIENTRY -_mesa_EvaluateDepthValuesARB(void); +_mesa_InternalInvalidateFramebufferAncillaryMESA(void); #endif /* FBOBJECT_H */ diff --git a/src/mesa/main/feedback.c b/src/mesa/main/feedback.c index b6776a1acee..8d8d02206b2 100644 --- a/src/mesa/main/feedback.c +++ b/src/mesa/main/feedback.c @@ -29,13 +29,17 @@ */ -#include "glheader.h" +#include "util/glheader.h" +#include "c99_alloca.h" #include "context.h" #include "enums.h" #include "feedback.h" #include "macros.h" #include "mtypes.h" +#include "api_exec_decl.h" +#include "bufferobj.h" +#include "state_tracker/st_cb_feedback.h" #define FB_3D 0x01 #define FB_4D 0x02 @@ -219,68 +223,240 @@ _mesa_update_hitflag(struct gl_context *ctx, GLfloat z) } } - -/** - * Write the hit record. - * - * \param ctx GL context. - * - * Write the hit record, i.e., the number of names in the stack, the minimum and - * maximum depth values and the number of names in the name stack at the time - * of the event. Resets the hit flag. - * - * \sa gl_selection. - */ static void -write_hit_record(struct gl_context *ctx) +alloc_select_resource(struct gl_context *ctx) { - GLuint i; - GLuint zmin, zmax, zscale = (~0u); + struct gl_selection *s = &ctx->Select; + + if (!ctx->Const.HardwareAcceleratedSelect) + return; + + if (!ctx->Dispatch.HWSelectModeBeginEnd) { + ctx->Dispatch.HWSelectModeBeginEnd = _mesa_alloc_dispatch_table(false); + if (!ctx->Dispatch.HWSelectModeBeginEnd) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot allocate HWSelectModeBeginEnd"); + return; + } + vbo_init_dispatch_hw_select_begin_end(ctx); + } + + if (!s->SaveBuffer) { + s->SaveBuffer = malloc(NAME_STACK_BUFFER_SIZE); + if (!s->SaveBuffer) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot allocate name stack save buffer"); + return; + } + } - /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */ - /* 2^32-1 and round to nearest unsigned integer. */ + if (!s->Result) { + s->Result = _mesa_bufferobj_alloc(ctx, -1); + if (!s->Result) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot allocate select result buffer"); + return; + } - assert( ctx != NULL ); /* this line magically fixes a SunOS 5.x/gcc bug */ - zmin = (GLuint) ((GLfloat) zscale * ctx->Select.HitMinZ); - zmax = (GLuint) ((GLfloat) zscale * ctx->Select.HitMaxZ); + GLuint init_result[MAX_NAME_STACK_RESULT_NUM * 3]; + for (int i = 0; i < MAX_NAME_STACK_RESULT_NUM; i++) { + init_result[i * 3] = 0; /* hit */ + init_result[i * 3 + 1] = 0xffffffff; /* minz */ + init_result[i * 3 + 2] = 0; /* maxz */ + } - write_record( ctx, ctx->Select.NameStackDepth ); - write_record( ctx, zmin ); - write_record( ctx, zmax ); - for (i = 0; i < ctx->Select.NameStackDepth; i++) { - write_record( ctx, ctx->Select.NameStack[i] ); + bool success = _mesa_bufferobj_data(ctx, + GL_SHADER_STORAGE_BUFFER, + sizeof(init_result), + init_result, + GL_STATIC_DRAW, 0, + s->Result); + if (!success) { + _mesa_reference_buffer_object(ctx, &s->Result, NULL); + _mesa_error(ctx, GL_OUT_OF_MEMORY, "Cannot init result buffer"); + return; + } } +} - ctx->Select.Hits++; - ctx->Select.HitFlag = GL_FALSE; - ctx->Select.HitMinZ = 1.0; - ctx->Select.HitMaxZ = -1.0; +static bool +save_used_name_stack(struct gl_context *ctx) +{ + struct gl_selection *s = &ctx->Select; + + if (!ctx->Const.HardwareAcceleratedSelect) + return false; + + /* We have two kinds of name stack user: + * 1. glRasterPos (CPU based) will set HitFlag + * 2. draw call for GPU will set ResultUsed + */ + if (!s->ResultUsed && !s->HitFlag) + return false; + + void *save = (char *)s->SaveBuffer + s->SaveBufferTail; + + /* save meta data */ + uint8_t *metadata = save; + metadata[0] = s->HitFlag; + metadata[1] = s->ResultUsed; + metadata[2] = s->NameStackDepth; + metadata[3] = 0; + + /* save hit data */ + int index = 1; + if (s->HitFlag) { + float *hit = save; + hit[index++] = s->HitMinZ; + hit[index++] = s->HitMaxZ; + } + + /* save name stack */ + memcpy((uint32_t *)save + index, s->NameStack, s->NameStackDepth * sizeof(GLuint)); + index += s->NameStackDepth; + + s->SaveBufferTail += index * sizeof(GLuint); + s->SavedStackNum++; + + /* if current slot has been used, store result to next slot in result buffer */ + if (s->ResultUsed) + s->ResultOffset += 3 * sizeof(GLuint); + + /* reset fields */ + s->HitFlag = GL_FALSE; + s->HitMinZ = 1.0; + s->HitMaxZ = 0; + + s->ResultUsed = GL_FALSE; + + /* return true if we have no enough space for the next name stack data */ + return s->ResultOffset >= MAX_NAME_STACK_RESULT_NUM * 3 * sizeof(GLuint) || + s->SaveBufferTail >= NAME_STACK_BUFFER_SIZE - (MAX_NAME_STACK_DEPTH + 3) * sizeof(GLuint); +} + +static void +update_hit_record(struct gl_context *ctx) +{ + struct gl_selection *s = &ctx->Select; + + if (ctx->Const.HardwareAcceleratedSelect) { + if (!s->SavedStackNum) + return; + + unsigned size = s->ResultOffset; + GLuint *result = size ? alloca(size) : NULL; + _mesa_bufferobj_get_subdata(ctx, 0, size, result, s->Result); + + unsigned index = 0; + unsigned *save = s->SaveBuffer; + for (int i = 0; i < s->SavedStackNum; i++) { + uint8_t *metadata = (uint8_t *)(save++); + + unsigned zmin, zmax; + bool cpu_hit = !!metadata[0]; + if (cpu_hit) { + /* map [0, 1] to [0, UINT_MAX]*/ + zmin = (unsigned) ((float)(~0u) * *(float *)(save++)); + zmax = (unsigned) ((float)(~0u) * *(float *)(save++)); + } else { + zmin = ~0u; + zmax = 0; + } + + bool gpu_hit = false; + if (metadata[1]) { + gpu_hit = !!result[index]; + + if (gpu_hit) { + zmin = MIN2(zmin, result[index + 1]); + zmax = MAX2(zmax, result[index + 2]); + + /* reset data */ + result[index] = 0; /* hit */ + result[index + 1] = 0xffffffff; /* minz */ + result[index + 2] = 0; /* maxz */ + } + index += 3; + } + + int depth = metadata[2]; + if (cpu_hit || gpu_hit) { + /* hit */ + write_record(ctx, depth); + write_record(ctx, zmin); + write_record(ctx, zmax); + + for (int j = 0; j < depth; j++) + write_record(ctx, save[j]); + s->Hits++; + } + save += depth; + } + + /* reset result buffer */ + _mesa_bufferobj_subdata(ctx, 0, size, result, s->Result); + + s->SaveBufferTail = 0; + s->SavedStackNum = 0; + s->ResultOffset = 0; + } else { + if (!s->HitFlag) + return; + + /* HitMinZ and HitMaxZ are in [0,1]. Multiply these values by */ + /* 2^32-1 and round to nearest unsigned integer. */ + GLuint zscale = (~0u); + GLuint zmin = (GLuint) ((GLfloat) zscale * s->HitMinZ); + GLuint zmax = (GLuint) ((GLfloat) zscale * s->HitMaxZ); + + write_record(ctx, s->NameStackDepth); + write_record(ctx, zmin); + write_record(ctx, zmax); + for (int i = 0; i < s->NameStackDepth; i++) + write_record(ctx, s->NameStack[i]); + + s->HitFlag = GL_FALSE; + s->HitMinZ = 1.0; + s->HitMaxZ = -1.0; + + s->Hits++; + } } +static void +reset_name_stack_to_empty(struct gl_context *ctx) +{ + struct gl_selection *s = &ctx->Select; + + s->NameStackDepth = 0; + s->HitFlag = GL_FALSE; + s->HitMinZ = 1.0; + s->HitMaxZ = 0.0; + + if (ctx->Const.HardwareAcceleratedSelect) { + s->SaveBufferTail = 0; + s->SavedStackNum = 0; + s->ResultUsed = GL_FALSE; + s->ResultOffset = 0; + } +} /** * Initialize the name stack. - * - * Verifies we are in select mode and resets the name stack depth and resets - * the hit record data in gl_selection. Marks new render mode in - * __struct gl_contextRec::NewState. */ void GLAPIENTRY _mesa_InitNames( void ) { GET_CURRENT_CONTEXT(ctx); + + /* Calls to glInitNames while the render mode is not GL_SELECT are ignored. */ + if (ctx->RenderMode != GL_SELECT) + return; + FLUSH_VERTICES(ctx, 0, 0); - /* Record the hit before the HitFlag is wiped out again. */ - if (ctx->RenderMode == GL_SELECT) { - if (ctx->Select.HitFlag) { - write_hit_record( ctx ); - } - } - ctx->Select.NameStackDepth = 0; - ctx->Select.HitFlag = GL_FALSE; - ctx->Select.HitMinZ = 1.0; - ctx->Select.HitMaxZ = 0.0; + save_used_name_stack(ctx); + update_hit_record(ctx); + + reset_name_stack_to_empty(ctx); + ctx->NewState |= _NEW_RENDERMODE; } @@ -289,12 +465,6 @@ _mesa_InitNames( void ) * Load the top-most name of the name stack. * * \param name name. - * - * Verifies we are in selection mode and that the name stack is not empty. - * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), - * and replace the top-most name in the stack. - * - * sa __struct gl_contextRec::Select. */ void GLAPIENTRY _mesa_LoadName( GLuint name ) @@ -309,17 +479,13 @@ _mesa_LoadName( GLuint name ) return; } - FLUSH_VERTICES(ctx, _NEW_RENDERMODE, 0); - - if (ctx->Select.HitFlag) { - write_hit_record( ctx ); - } - if (ctx->Select.NameStackDepth < MAX_NAME_STACK_DEPTH) { - ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name; - } - else { - ctx->Select.NameStack[MAX_NAME_STACK_DEPTH-1] = name; + if (!ctx->Const.HardwareAcceleratedSelect || save_used_name_stack(ctx)) { + FLUSH_VERTICES(ctx, 0, 0); + update_hit_record(ctx); } + + ctx->Select.NameStack[ctx->Select.NameStackDepth-1] = name; + ctx->NewState |= _NEW_RENDERMODE; } @@ -327,12 +493,6 @@ _mesa_LoadName( GLuint name ) * Push a name into the name stack. * * \param name name. - * - * Verifies we are in selection mode and that the name stack is not full. - * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), - * and adds the name to the top of the name stack. - * - * sa __struct gl_contextRec::Select. */ void GLAPIENTRY _mesa_PushName( GLuint name ) @@ -343,26 +503,23 @@ _mesa_PushName( GLuint name ) return; } - FLUSH_VERTICES(ctx, _NEW_RENDERMODE, 0); - if (ctx->Select.HitFlag) { - write_hit_record( ctx ); - } if (ctx->Select.NameStackDepth >= MAX_NAME_STACK_DEPTH) { _mesa_error( ctx, GL_STACK_OVERFLOW, "glPushName" ); + return; } - else - ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name; + + if (!ctx->Const.HardwareAcceleratedSelect || save_used_name_stack(ctx)) { + FLUSH_VERTICES(ctx, 0, 0); + update_hit_record(ctx); + } + + ctx->Select.NameStack[ctx->Select.NameStackDepth++] = name; + ctx->NewState |= _NEW_RENDERMODE; } /** * Pop a name into the name stack. - * - * Verifies we are in selection mode and that the name stack is not empty. - * Flushes vertices. If there is a hit flag writes it (via write_hit_record()), - * and removes top-most name in the name stack. - * - * sa __struct gl_contextRec::Select. */ void GLAPIENTRY _mesa_PopName( void ) @@ -373,15 +530,18 @@ _mesa_PopName( void ) return; } - FLUSH_VERTICES(ctx, _NEW_RENDERMODE, 0); - if (ctx->Select.HitFlag) { - write_hit_record( ctx ); - } if (ctx->Select.NameStackDepth == 0) { _mesa_error( ctx, GL_STACK_UNDERFLOW, "glPopName" ); + return; + } + + if (!ctx->Const.HardwareAcceleratedSelect || save_used_name_stack(ctx)) { + FLUSH_VERTICES(ctx, 0, 0); + update_hit_record(ctx); } - else - ctx->Select.NameStackDepth--; + + ctx->Select.NameStackDepth--; + ctx->NewState |= _NEW_RENDERMODE; } /*@}*/ @@ -424,9 +584,9 @@ _mesa_RenderMode( GLenum mode ) result = 0; break; case GL_SELECT: - if (ctx->Select.HitFlag) { - write_hit_record( ctx ); - } + save_used_name_stack(ctx); + update_hit_record(ctx); + if (ctx->Select.BufferCount > ctx->Select.BufferSize) { /* overflow */ #ifndef NDEBUG @@ -439,7 +599,8 @@ _mesa_RenderMode( GLenum mode ) } ctx->Select.BufferCount = 0; ctx->Select.Hits = 0; - ctx->Select.NameStackDepth = 0; + /* name stack should be in empty state after exiting GL_SELECT mode */ + reset_name_stack_to_empty(ctx); break; case GL_FEEDBACK: if (ctx->Feedback.Count > ctx->Feedback.BufferSize) { @@ -464,6 +625,7 @@ _mesa_RenderMode( GLenum mode ) /* haven't called glSelectBuffer yet */ _mesa_error( ctx, GL_INVALID_OPERATION, "glRenderMode" ); } + alloc_select_resource(ctx); break; case GL_FEEDBACK: if (ctx->Feedback.BufferSize==0) { @@ -476,9 +638,10 @@ _mesa_RenderMode( GLenum mode ) return 0; } + st_RenderMode( ctx, mode ); + + /* finally update render mode to new one */ ctx->RenderMode = mode; - if (ctx->Driver.RenderMode) - ctx->Driver.RenderMode( ctx, mode ); return result; } @@ -512,4 +675,12 @@ void _mesa_init_feedback( struct gl_context * ctx ) ctx->RenderMode = GL_RENDER; } +void _mesa_free_feedback(struct gl_context * ctx) +{ + struct gl_selection *s = &ctx->Select; + + free(s->SaveBuffer); + _mesa_reference_buffer_object(ctx, &s->Result, NULL); +} + /*@}*/ diff --git a/src/mesa/main/feedback.h b/src/mesa/main/feedback.h index 08bc7620e1b..67b4dba00da 100644 --- a/src/mesa/main/feedback.h +++ b/src/mesa/main/feedback.h @@ -26,27 +26,8 @@ #ifndef FEEDBACK_H #define FEEDBACK_H - #include "main/mtypes.h" - -void GLAPIENTRY -_mesa_FeedbackBuffer( GLsizei size, GLenum type, GLfloat *buffer ); -void GLAPIENTRY -_mesa_PassThrough( GLfloat token ); -void GLAPIENTRY -_mesa_SelectBuffer( GLsizei size, GLuint *buffer ); -void GLAPIENTRY -_mesa_InitNames( void ); -void GLAPIENTRY -_mesa_LoadName( GLuint name ); -void GLAPIENTRY -_mesa_PushName( GLuint name ); -void GLAPIENTRY -_mesa_PopName( void ); -GLint GLAPIENTRY -_mesa_RenderMode( GLenum mode ); - extern void _mesa_feedback_vertex( struct gl_context *ctx, const GLfloat win[4], @@ -71,4 +52,7 @@ _mesa_update_hitflag( struct gl_context *ctx, GLfloat z ); extern void _mesa_init_feedback( struct gl_context *ctx ); +extern void +_mesa_free_feedback( struct gl_context *ctx ); + #endif /* FEEDBACK_H */ diff --git a/src/mesa/main/ff_fragment_shader.c b/src/mesa/main/ff_fragment_shader.c new file mode 100644 index 00000000000..e34a3ee5bcc --- /dev/null +++ b/src/mesa/main/ff_fragment_shader.c @@ -0,0 +1,1018 @@ +/************************************************************************** + * + * Copyright 2007 VMware, Inc. + * All Rights Reserved. + * Copyright 2009 VMware, Inc. All Rights Reserved. + * Copyright © 2010-2011 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +#include "util/glheader.h" +#include "main/context.h" + +#include "main/macros.h" +#include "main/state.h" +#include "main/texenvprogram.h" +#include "main/texobj.h" +#include "program/program.h" +#include "program/prog_cache.h" +#include "program/prog_statevars.h" +#include "program/prog_to_nir.h" +#include "util/bitscan.h" + +#include "state_tracker/st_context.h" +#include "state_tracker/st_program.h" +#include "state_tracker/st_nir.h" + +#include "compiler/nir/nir_builder.h" +#include "compiler/nir/nir_builtin_builder.h" + +/* + * Note on texture units: + * + * The number of texture units supported by fixed-function fragment + * processing is MAX_TEXTURE_COORD_UNITS, not MAX_TEXTURE_IMAGE_UNITS. + * That's because there's a one-to-one correspondence between texture + * coordinates and samplers in fixed-function processing. + * + * Since fixed-function vertex processing is limited to MAX_TEXTURE_COORD_UNITS + * sets of texcoords, so is fixed-function fragment processing. + * + * We can safely use ctx->Const.MaxTextureUnits for loop bounds. + */ + + +static GLboolean +texenv_doing_secondary_color(struct gl_context *ctx) +{ + if (ctx->Light.Enabled && + (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) + return GL_TRUE; + + if (ctx->Fog.ColorSumEnabled) + return GL_TRUE; + + return GL_FALSE; +} + +struct state_key { + GLuint nr_enabled_units:4; + GLuint separate_specular:1; + GLuint fog_mode:2; /**< FOG_x */ + GLuint inputs_available:12; + GLuint num_draw_buffers:4; + + /* NOTE: This array of structs must be last! (see "keySize" below) */ + struct { + GLuint enabled:1; + GLuint source_index:4; /**< TEXTURE_x_INDEX */ + GLuint shadow:1; + + /*** + * These are taken from struct gl_tex_env_combine_packed + * @{ + */ + GLuint ModeRGB:4; + GLuint ModeA:4; + GLuint ScaleShiftRGB:2; + GLuint ScaleShiftA:2; + GLuint NumArgsRGB:3; + GLuint NumArgsA:3; + struct gl_tex_env_argument ArgsRGB[MAX_COMBINER_TERMS]; + struct gl_tex_env_argument ArgsA[MAX_COMBINER_TERMS]; + /** @} */ + } unit[MAX_TEXTURE_COORD_UNITS]; +}; + + +/** + * Do we need to clamp the results of the given texture env/combine mode? + * If the inputs to the mode are in [0,1] we don't always have to clamp + * the results. + */ +static GLboolean +need_saturate( GLuint mode ) +{ + switch (mode) { + case TEXENV_MODE_REPLACE: + case TEXENV_MODE_MODULATE: + case TEXENV_MODE_INTERPOLATE: + return GL_FALSE; + case TEXENV_MODE_ADD: + case TEXENV_MODE_ADD_SIGNED: + case TEXENV_MODE_SUBTRACT: + case TEXENV_MODE_DOT3_RGB: + case TEXENV_MODE_DOT3_RGB_EXT: + case TEXENV_MODE_DOT3_RGBA: + case TEXENV_MODE_DOT3_RGBA_EXT: + case TEXENV_MODE_MODULATE_ADD_ATI: + case TEXENV_MODE_MODULATE_SIGNED_ADD_ATI: + case TEXENV_MODE_MODULATE_SUBTRACT_ATI: + case TEXENV_MODE_ADD_PRODUCTS_NV: + case TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV: + return GL_TRUE; + default: + assert(0); + return GL_FALSE; + } +} + +#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) + +/** + * Identify all possible varying inputs. The fragment program will + * never reference non-varying inputs, but will track them via state + * constants instead. + * + * This function figures out all the inputs that the fragment program + * has access to and filters input bitmask. + */ +static GLbitfield filter_fp_input_mask( GLbitfield fp_inputs, + struct gl_context *ctx ) +{ + if (ctx->VertexProgram._Overriden) { + /* Somebody's messing with the vertex program and we don't have + * a clue what's happening. Assume that it could be producing + * all possible outputs. + */ + return fp_inputs; + } + + if (ctx->RenderMode == GL_FEEDBACK) { + /* _NEW_RENDERMODE */ + return fp_inputs & (VARYING_BIT_COL0 | VARYING_BIT_TEX0); + } + + /* _NEW_PROGRAM */ + const GLboolean vertexShader = + ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] != NULL; + const GLboolean vertexProgram = _mesa_arb_vertex_program_enabled(ctx); + + if (!(vertexProgram || vertexShader)) { + /* Fixed function vertex logic */ + GLbitfield possible_inputs = 0; + + GLbitfield varying_inputs = ctx->VertexProgram._VaryingInputs; + /* We only update ctx->VertexProgram._VaryingInputs when in VP_MODE_FF _VPMode */ + assert(VP_MODE_FF == ctx->VertexProgram._VPMode); + + /* These get generated in the setup routine regardless of the + * vertex program: + */ + /* _NEW_POINT */ + if (ctx->Point.PointSprite) { + /* All texture varyings are possible to use */ + possible_inputs = VARYING_BITS_TEX_ANY; + } + else { + const GLbitfield possible_tex_inputs = + ctx->Texture._TexGenEnabled | + ctx->Texture._TexMatEnabled | + ((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0); + + possible_inputs = (possible_tex_inputs << VARYING_SLOT_TEX0); + } + + /* First look at what values may be computed by the generated + * vertex program: + */ + if (ctx->Light.Enabled) { + possible_inputs |= VARYING_BIT_COL0; + + if (texenv_doing_secondary_color(ctx)) + possible_inputs |= VARYING_BIT_COL1; + } + + /* Then look at what might be varying as a result of enabled + * arrays, etc: + */ + if (varying_inputs & VERT_BIT_COLOR0) + possible_inputs |= VARYING_BIT_COL0; + if (varying_inputs & VERT_BIT_COLOR1) + possible_inputs |= VARYING_BIT_COL1; + + return fp_inputs & possible_inputs; + } + + /* calculate from vp->outputs */ + struct gl_program *vprog; + + /* Choose GLSL vertex shader over ARB vertex program. Need this + * since vertex shader state validation comes after fragment state + * validation (see additional comments in state.c). + */ + if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY] != NULL) + vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; + else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL] != NULL) + vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; + else if (vertexShader) + vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; + else + vprog = ctx->VertexProgram.Current; + + GLbitfield possible_inputs = vprog->info.outputs_written; + + /* These get generated in the setup routine regardless of the + * vertex program: + */ + /* _NEW_POINT */ + if (ctx->Point.PointSprite) { + /* All texture varyings are possible to use */ + possible_inputs |= VARYING_BITS_TEX_ANY; + } + + return fp_inputs & possible_inputs; +} + + +/** + * Examine current texture environment state and generate a unique + * key to identify it. + */ +static GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) +{ + GLbitfield inputs_referenced = VARYING_BIT_COL0; + GLbitfield mask; + GLuint keySize; + + memset(key, 0, sizeof(*key)); + + /* _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE */ + mask = ctx->Texture._EnabledCoordUnits; + int i = -1; + while (mask) { + i = u_bit_scan(&mask); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; + const struct gl_texture_object *texObj = texUnit->_Current; + const struct gl_tex_env_combine_packed *comb = + &ctx->Texture.FixedFuncUnit[i]._CurrentCombinePacked; + + if (!texObj) + continue; + + key->unit[i].enabled = 1; + inputs_referenced |= VARYING_BIT_TEX(i); + + key->unit[i].source_index = texObj->TargetIndex; + + const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, i); + if (samp->Attrib.CompareMode == GL_COMPARE_R_TO_TEXTURE) { + const GLenum format = _mesa_texture_base_format(texObj); + key->unit[i].shadow = (format == GL_DEPTH_COMPONENT || + format == GL_DEPTH_STENCIL_EXT); + } + + key->unit[i].ModeRGB = comb->ModeRGB; + key->unit[i].ModeA = comb->ModeA; + key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB; + key->unit[i].ScaleShiftA = comb->ScaleShiftA; + key->unit[i].NumArgsRGB = comb->NumArgsRGB; + key->unit[i].NumArgsA = comb->NumArgsA; + + memcpy(key->unit[i].ArgsRGB, comb->ArgsRGB, sizeof comb->ArgsRGB); + memcpy(key->unit[i].ArgsA, comb->ArgsA, sizeof comb->ArgsA); + } + + key->nr_enabled_units = i + 1; + + /* _NEW_FOG */ + if (texenv_doing_secondary_color(ctx)) { + key->separate_specular = 1; + inputs_referenced |= VARYING_BIT_COL1; + } + + /* _NEW_FOG */ + key->fog_mode = ctx->Fog._PackedEnabledMode; + + /* _NEW_BUFFERS */ + key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; + + /* _NEW_COLOR */ + if (ctx->Color.AlphaEnabled && key->num_draw_buffers == 0) { + /* if alpha test is enabled we need to emit at least one color */ + key->num_draw_buffers = 1; + } + + key->inputs_available = filter_fp_input_mask(inputs_referenced, ctx); + + /* compute size of state key, ignoring unused texture units */ + keySize = sizeof(*key) - sizeof(key->unit) + + key->nr_enabled_units * sizeof(key->unit[0]); + + return keySize; +} + + +/** State used to build the fragment program: + */ +struct texenv_fragment_program { + nir_builder *b; + struct gl_program_parameter_list *state_params; + + struct state_key *state; + + nir_variable *sampler_vars[MAX_TEXTURE_COORD_UNITS]; + + nir_def *src_texture[MAX_TEXTURE_COORD_UNITS]; + /* ssa-def containing each texture unit's sampled texture color, + * else NULL. + */ + + nir_def *src_previous; /**< Color from previous stage */ +}; + +static nir_variable * +register_state_var(struct texenv_fragment_program *p, + gl_state_index s0, + gl_state_index s1, + gl_state_index s2, + gl_state_index s3, + const struct glsl_type *type) +{ + gl_state_index16 tokens[STATE_LENGTH]; + tokens[0] = s0; + tokens[1] = s1; + tokens[2] = s2; + tokens[3] = s3; + nir_variable *var = nir_find_state_variable(p->b->shader, tokens); + if (var) + return var; + + int loc = _mesa_add_state_reference(p->state_params, tokens); + + char *name = _mesa_program_state_string(tokens); + var = nir_variable_create(p->b->shader, nir_var_uniform, type, name); + free(name); + + var->num_state_slots = 1; + var->state_slots = ralloc_array(var, nir_state_slot, 1); + var->data.driver_location = loc; + memcpy(var->state_slots[0].tokens, tokens, + sizeof(var->state_slots[0].tokens)); + + p->b->shader->num_uniforms++; + return var; +} + +static nir_def * +load_state_var(struct texenv_fragment_program *p, + gl_state_index s0, + gl_state_index s1, + gl_state_index s2, + gl_state_index s3, + const struct glsl_type *type) +{ + nir_variable *var = register_state_var(p, s0, s1, s2, s3, type); + return nir_load_var(p->b, var); +} + +static nir_def * +load_input(struct texenv_fragment_program *p, gl_varying_slot slot, + const struct glsl_type *type) +{ + nir_variable *var = + nir_get_variable_with_location(p->b->shader, + nir_var_shader_in, + slot, + type); + var->data.interpolation = INTERP_MODE_NONE; + return nir_load_var(p->b, var); +} + +static nir_def * +get_current_attrib(struct texenv_fragment_program *p, GLuint attrib) +{ + return load_state_var(p, STATE_CURRENT_ATTRIB_MAYBE_VP_CLAMPED, + attrib, 0, 0, + glsl_vec4_type()); +} + +static nir_def * +get_gl_Color(struct texenv_fragment_program *p) +{ + if (p->state->inputs_available & VARYING_BIT_COL0) { + return load_input(p, VARYING_SLOT_COL0, glsl_vec4_type()); + } else { + return get_current_attrib(p, VERT_ATTRIB_COLOR0); + } +} + +static nir_def * +get_source(struct texenv_fragment_program *p, + GLuint src, GLuint unit) +{ + switch (src) { + case TEXENV_SRC_TEXTURE: + return p->src_texture[unit]; + + case TEXENV_SRC_TEXTURE0: + case TEXENV_SRC_TEXTURE1: + case TEXENV_SRC_TEXTURE2: + case TEXENV_SRC_TEXTURE3: + case TEXENV_SRC_TEXTURE4: + case TEXENV_SRC_TEXTURE5: + case TEXENV_SRC_TEXTURE6: + case TEXENV_SRC_TEXTURE7: + return p->src_texture[src - TEXENV_SRC_TEXTURE0]; + + case TEXENV_SRC_CONSTANT: + return load_state_var(p, STATE_TEXENV_COLOR, + unit, 0, 0, + glsl_vec4_type()); + + case TEXENV_SRC_PRIMARY_COLOR: + return get_gl_Color(p); + + case TEXENV_SRC_ZERO: + return nir_imm_zero(p->b, 4, 32); + + case TEXENV_SRC_ONE: + return nir_imm_vec4(p->b, 1.0f, 1.0f, 1.0f, 1.0f); + + case TEXENV_SRC_PREVIOUS: + if (!p->src_previous) { + return get_gl_Color(p); + } else { + return p->src_previous; + } + + default: + assert(0); + return NULL; + } +} + +static nir_def * +emit_combine_source(struct texenv_fragment_program *p, + GLuint unit, + GLuint source, + GLuint operand) +{ + nir_def *src; + + src = get_source(p, source, unit); + + switch (operand) { + case TEXENV_OPR_ONE_MINUS_COLOR: + return nir_fsub_imm(p->b, 1.0, src); + + case TEXENV_OPR_ALPHA: + return src->num_components == 1 ? src : nir_channel(p->b, src, 3); + + case TEXENV_OPR_ONE_MINUS_ALPHA: { + nir_def *scalar = + src->num_components == 1 ? src : nir_channel(p->b, src, 3); + + return nir_fsub_imm(p->b, 1.0, scalar); + } + + case TEXENV_OPR_COLOR: + return src; + + default: + assert(0); + return src; + } +} + +/** + * Check if the RGB and Alpha sources and operands match for the given + * texture unit's combinder state. When the RGB and A sources and + * operands match, we can emit fewer instructions. + */ +static GLboolean args_match( const struct state_key *key, GLuint unit ) +{ + GLuint i, numArgs = key->unit[unit].NumArgsRGB; + + for (i = 0; i < numArgs; i++) { + if (key->unit[unit].ArgsA[i].Source != key->unit[unit].ArgsRGB[i].Source) + return GL_FALSE; + + switch (key->unit[unit].ArgsA[i].Operand) { + case TEXENV_OPR_ALPHA: + switch (key->unit[unit].ArgsRGB[i].Operand) { + case TEXENV_OPR_COLOR: + case TEXENV_OPR_ALPHA: + break; + default: + return GL_FALSE; + } + break; + case TEXENV_OPR_ONE_MINUS_ALPHA: + switch (key->unit[unit].ArgsRGB[i].Operand) { + case TEXENV_OPR_ONE_MINUS_COLOR: + case TEXENV_OPR_ONE_MINUS_ALPHA: + break; + default: + return GL_FALSE; + } + break; + default: + return GL_FALSE; /* impossible */ + } + } + + return GL_TRUE; +} + +static nir_def * +smear(nir_builder *b, nir_def *val) +{ + if (val->num_components != 1) + return val; + + return nir_replicate(b, val, 4); +} + +static nir_def * +emit_combine(struct texenv_fragment_program *p, + GLuint unit, + GLuint nr, + GLuint mode, + const struct gl_tex_env_argument *opt) +{ + nir_def *src[MAX_COMBINER_TERMS]; + nir_def *tmp0, *tmp1; + GLuint i; + + assert(nr <= MAX_COMBINER_TERMS); + + for (i = 0; i < nr; i++) + src[i] = emit_combine_source( p, unit, opt[i].Source, opt[i].Operand ); + + switch (mode) { + case TEXENV_MODE_REPLACE: + return src[0]; + + case TEXENV_MODE_MODULATE: + return nir_fmul(p->b, src[0], src[1]); + + case TEXENV_MODE_ADD: + return nir_fadd(p->b, src[0], src[1]); + + case TEXENV_MODE_ADD_SIGNED: + return nir_fadd_imm(p->b, nir_fadd(p->b, src[0], src[1]), -0.5f); + + case TEXENV_MODE_INTERPOLATE: + return nir_flrp(p->b, src[1], src[0], src[2]); + + case TEXENV_MODE_SUBTRACT: + return nir_fsub(p->b, src[0], src[1]); + + case TEXENV_MODE_DOT3_RGBA: + case TEXENV_MODE_DOT3_RGBA_EXT: + case TEXENV_MODE_DOT3_RGB_EXT: + case TEXENV_MODE_DOT3_RGB: + tmp0 = nir_fadd_imm(p->b, nir_fmul_imm(p->b, src[0], 2.0f), -1.0f); + tmp1 = nir_fadd_imm(p->b, nir_fmul_imm(p->b, src[1], 2.0f), -1.0f); + return nir_fdot3(p->b, smear(p->b, tmp0), smear(p->b, tmp1)); + + case TEXENV_MODE_MODULATE_ADD_ATI: + return nir_fmad(p->b, src[0], src[2], src[1]); + + case TEXENV_MODE_MODULATE_SIGNED_ADD_ATI: + return nir_fadd_imm(p->b, + nir_fadd(p->b, + nir_fmul(p->b, src[0], src[2]), + src[1]), + -0.5f); + + case TEXENV_MODE_MODULATE_SUBTRACT_ATI: + return nir_fsub(p->b, nir_fmul(p->b, src[0], src[2]), src[1]); + + case TEXENV_MODE_ADD_PRODUCTS_NV: + return nir_fadd(p->b, nir_fmul(p->b, src[0], src[1]), + nir_fmul(p->b, src[2], src[3])); + + case TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV: + return nir_fadd_imm(p->b, + nir_fadd(p->b, + nir_fmul(p->b, src[0], src[1]), + nir_fmul(p->b, src[2], src[3])), + -0.5f); + default: + assert(0); + return src[0]; + } +} + +/** + * Generate instructions for one texture unit's env/combiner mode. + */ +static nir_def * +emit_texenv(struct texenv_fragment_program *p, GLuint unit) +{ + const struct state_key *key = p->state; + GLboolean rgb_saturate, alpha_saturate; + GLuint rgb_shift, alpha_shift; + + if (!key->unit[unit].enabled) { + return get_source(p, TEXENV_SRC_PREVIOUS, 0); + } + + switch (key->unit[unit].ModeRGB) { + case TEXENV_MODE_DOT3_RGB_EXT: + alpha_shift = key->unit[unit].ScaleShiftA; + rgb_shift = 0; + break; + case TEXENV_MODE_DOT3_RGBA_EXT: + alpha_shift = 0; + rgb_shift = 0; + break; + default: + rgb_shift = key->unit[unit].ScaleShiftRGB; + alpha_shift = key->unit[unit].ScaleShiftA; + break; + } + + /* If we'll do rgb/alpha shifting don't saturate in emit_combine(). + * We don't want to clamp twice. + */ + if (rgb_shift) + rgb_saturate = GL_FALSE; /* saturate after rgb shift */ + else if (need_saturate(key->unit[unit].ModeRGB)) + rgb_saturate = GL_TRUE; + else + rgb_saturate = GL_FALSE; + + if (alpha_shift) + alpha_saturate = GL_FALSE; /* saturate after alpha shift */ + else if (need_saturate(key->unit[unit].ModeA)) + alpha_saturate = GL_TRUE; + else + alpha_saturate = GL_FALSE; + + nir_def *val; + + /* Emit the RGB and A combine ops + */ + if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && + args_match(key, unit)) { + val = emit_combine(p, unit, + key->unit[unit].NumArgsRGB, + key->unit[unit].ModeRGB, + key->unit[unit].ArgsRGB); + val = smear(p->b, val); + if (rgb_saturate) + val = nir_fsat(p->b, val); + } + else if (key->unit[unit].ModeRGB == TEXENV_MODE_DOT3_RGBA_EXT || + key->unit[unit].ModeRGB == TEXENV_MODE_DOT3_RGBA) { + val = emit_combine(p, unit, + key->unit[unit].NumArgsRGB, + key->unit[unit].ModeRGB, + key->unit[unit].ArgsRGB); + val = smear(p->b, val); + if (rgb_saturate) + val = nir_fsat(p->b, val); + } + else { + /* Need to do something to stop from re-emitting identical + * argument calculations here: + */ + val = emit_combine(p, unit, + key->unit[unit].NumArgsRGB, + key->unit[unit].ModeRGB, + key->unit[unit].ArgsRGB); + val = smear(p->b, val); + if (rgb_saturate) + val = nir_fsat(p->b, val); + nir_def *rgb = val; + + val = emit_combine(p, unit, + key->unit[unit].NumArgsA, + key->unit[unit].ModeA, + key->unit[unit].ArgsA); + + if (val->num_components != 1) + val = nir_channel(p->b, val, 3); + + if (alpha_saturate) + val = nir_fsat(p->b, val); + nir_def *a = val; + + val = nir_vector_insert_imm(p->b, rgb, a, 3); + } + + /* Deal with the final shift: + */ + if (alpha_shift || rgb_shift) { + nir_def *shift; + + if (rgb_shift == alpha_shift) { + shift = nir_imm_float(p->b, (float)(1 << rgb_shift)); + } + else { + shift = nir_imm_vec4(p->b, + (float)(1 << rgb_shift), + (float)(1 << rgb_shift), + (float)(1 << rgb_shift), + (float)(1 << alpha_shift)); + } + + return nir_fsat(p->b, nir_fmul(p->b, val, shift)); + } + else + return val; +} + + +/** + * Generate instruction for getting a texture source term. + */ +static void +load_texture(struct texenv_fragment_program *p, GLuint unit) +{ + if (p->src_texture[unit]) + return; + + const GLuint texTarget = p->state->unit[unit].source_index; + nir_def *texcoord; + + if (!(p->state->inputs_available & (VARYING_BIT_TEX0 << unit))) { + texcoord = get_current_attrib(p, VERT_ATTRIB_TEX0 + unit); + } else { + texcoord = load_input(p, + VARYING_SLOT_TEX0 + unit, + glsl_vec4_type()); + } + + if (!p->state->unit[unit].enabled) { + p->src_texture[unit] = nir_imm_zero(p->b, 4, 32); + return ; + } + + unsigned num_srcs = 4; + if (p->state->unit[unit].shadow) + num_srcs++; + + nir_tex_instr *tex = nir_tex_instr_create(p->b->shader, num_srcs); + tex->op = nir_texop_tex; + tex->dest_type = nir_type_float32; + tex->texture_index = unit; + tex->sampler_index = unit; + + tex->sampler_dim = + _mesa_texture_index_to_sampler_dim(texTarget, + &tex->is_array); + + tex->coord_components = + glsl_get_sampler_dim_coordinate_components(tex->sampler_dim); + if (tex->is_array) + tex->coord_components++; + + nir_variable *var = p->sampler_vars[unit]; + if (!var) { + const struct glsl_type *sampler_type = + glsl_sampler_type(tex->sampler_dim, + p->state->unit[unit].shadow, + tex->is_array, GLSL_TYPE_FLOAT); + + var = nir_variable_create(p->b->shader, nir_var_uniform, + sampler_type, + ralloc_asprintf(p->b->shader, + "sampler_%d", unit)); + var->data.binding = unit; + var->data.explicit_binding = true; + + p->sampler_vars[unit] = var; + } + + nir_deref_instr *deref = nir_build_deref_var(p->b, var); + tex->src[0] = nir_tex_src_for_ssa(nir_tex_src_texture_deref, + &deref->def); + tex->src[1] = nir_tex_src_for_ssa(nir_tex_src_sampler_deref, + &deref->def); + + nir_def *src2 = + nir_channels(p->b, texcoord, + nir_component_mask(tex->coord_components)); + tex->src[2] = nir_tex_src_for_ssa(nir_tex_src_coord, src2); + + tex->src[3] = nir_tex_src_for_ssa(nir_tex_src_projector, + nir_channel(p->b, texcoord, 3)); + + if (p->state->unit[unit].shadow) { + tex->is_shadow = true; + nir_def *src4 = + nir_channel(p->b, texcoord, tex->coord_components); + tex->src[4] = nir_tex_src_for_ssa(nir_tex_src_comparator, src4); + } + + nir_def_init(&tex->instr, &tex->def, 4, 32); + p->src_texture[unit] = &tex->def; + + nir_builder_instr_insert(p->b, &tex->instr); + BITSET_SET(p->b->shader->info.textures_used, unit); + BITSET_SET(p->b->shader->info.samplers_used, unit); +} + +static void +load_texenv_source(struct texenv_fragment_program *p, + GLuint src, GLuint unit) +{ + switch (src) { + case TEXENV_SRC_TEXTURE: + load_texture(p, unit); + break; + + case TEXENV_SRC_TEXTURE0: + case TEXENV_SRC_TEXTURE1: + case TEXENV_SRC_TEXTURE2: + case TEXENV_SRC_TEXTURE3: + case TEXENV_SRC_TEXTURE4: + case TEXENV_SRC_TEXTURE5: + case TEXENV_SRC_TEXTURE6: + case TEXENV_SRC_TEXTURE7: + load_texture(p, src - TEXENV_SRC_TEXTURE0); + break; + + default: + /* not a texture src - do nothing */ + break; + } +} + + +/** + * Generate instructions for loading all texture source terms. + */ +static GLboolean +load_texunit_sources(struct texenv_fragment_program *p, GLuint unit) +{ + const struct state_key *key = p->state; + GLuint i; + + for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { + load_texenv_source( p, key->unit[unit].ArgsRGB[i].Source, unit ); + } + + for (i = 0; i < key->unit[unit].NumArgsA; i++) { + load_texenv_source( p, key->unit[unit].ArgsA[i].Source, unit ); + } + + return GL_TRUE; +} + +static void +emit_instructions(struct texenv_fragment_program *p) +{ + struct state_key *key = p->state; + GLuint unit; + + if (key->nr_enabled_units) { + /* First pass - to support texture_env_crossbar, first identify + * all referenced texture sources and emit texld instructions + * for each: + */ + for (unit = 0; unit < key->nr_enabled_units; unit++) + if (key->unit[unit].enabled) { + load_texunit_sources(p, unit); + } + + /* Second pass - emit combine instructions to build final color: + */ + for (unit = 0; unit < key->nr_enabled_units; unit++) { + if (key->unit[unit].enabled) { + p->src_previous = emit_texenv(p, unit); + } + } + } + + nir_def *cf = get_source(p, TEXENV_SRC_PREVIOUS, 0); + + if (key->separate_specular) { + nir_def *spec_result = cf; + + nir_def *secondary; + if (p->state->inputs_available & VARYING_BIT_COL1) + secondary = load_input(p, VARYING_SLOT_COL1, glsl_vec4_type()); + else + secondary = get_current_attrib(p, VERT_ATTRIB_COLOR1); + + secondary = nir_vector_insert_imm(p->b, secondary, + nir_imm_zero(p->b, 1, 32), 3); + cf = nir_fadd(p->b, spec_result, secondary); + } + + const char *name = + gl_frag_result_name(FRAG_RESULT_COLOR); + nir_variable *var = + nir_variable_create(p->b->shader, nir_var_shader_out, + glsl_vec4_type(), name); + + var->data.location = FRAG_RESULT_COLOR; + var->data.driver_location = p->b->shader->num_outputs++; + + p->b->shader->info.outputs_written |= BITFIELD64_BIT(FRAG_RESULT_COLOR); + + nir_store_var(p->b, var, cf, 0xf); +} + +/** + * Generate a new fragment program which implements the context's + * current texture env/combine mode. + */ +static nir_shader * +create_new_program(struct state_key *key, + struct gl_program *program, + const nir_shader_compiler_options *options) +{ + struct texenv_fragment_program p; + + memset(&p, 0, sizeof(p)); + p.state = key; + + program->Parameters = _mesa_new_parameter_list(); + p.state_params = _mesa_new_parameter_list(); + + nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_FRAGMENT, + options, + "ff-fs"); + + nir_shader *s = b.shader; + + s->info.separate_shader = true; + s->info.subgroup_size = SUBGROUP_SIZE_UNIFORM; + + p.b = &b; + + if (key->num_draw_buffers) + emit_instructions(&p); + + nir_validate_shader(b.shader, "after generating ff-vertex shader"); + + if (key->fog_mode) + NIR_PASS(_, b.shader, st_nir_lower_fog, key->fog_mode, p.state_params); + + _mesa_add_separate_state_parameters(program, p.state_params); + _mesa_free_parameter_list(p.state_params); + + return s; +} + +/** + * Return a fragment program which implements the current + * fixed-function texture, fog and color-sum operations. + */ +struct gl_program * +_mesa_get_fixed_func_fragment_program(struct gl_context *ctx) +{ + struct gl_program *prog; + struct state_key key; + GLuint keySize; + + keySize = make_state_key(ctx, &key); + + prog = (struct gl_program *) + _mesa_search_program_cache(ctx->FragmentProgram.Cache, + &key, keySize); + + if (!prog) { + prog = ctx->Driver.NewProgram(ctx, MESA_SHADER_FRAGMENT, 0, false); + if (!prog) + return NULL; + + const struct nir_shader_compiler_options *options = + st_get_nir_compiler_options(ctx->st, MESA_SHADER_FRAGMENT); + + nir_shader *s = + create_new_program(&key, prog, options); + + prog->state.type = PIPE_SHADER_IR_NIR; + prog->nir = s; + + prog->SamplersUsed = s->info.samplers_used[0]; + + /* default mapping from samplers to texture units */ + for (unsigned i = 0; i < MAX_SAMPLERS; i++) + prog->SamplerUnits[i] = i; + + st_program_string_notify(ctx, GL_FRAGMENT_PROGRAM_ARB, prog); + + _mesa_program_cache_insert(ctx, ctx->FragmentProgram.Cache, + &key, keySize, prog); + } + + return prog; +} diff --git a/src/mesa/main/ff_fragment_shader.cpp b/src/mesa/main/ff_fragment_shader.cpp deleted file mode 100644 index 302c3b1de9b..00000000000 --- a/src/mesa/main/ff_fragment_shader.cpp +++ /dev/null @@ -1,1157 +0,0 @@ -/************************************************************************** - * - * Copyright 2007 VMware, Inc. - * All Rights Reserved. - * Copyright 2009 VMware, Inc. All Rights Reserved. - * Copyright © 2010-2011 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -#include "main/glheader.h" -#include "main/context.h" - -#include "main/macros.h" -#include "main/samplerobj.h" -#include "main/shaderobj.h" -#include "main/state.h" -#include "main/texenvprogram.h" -#include "main/texobj.h" -#include "main/uniforms.h" -#include "compiler/glsl/ir_builder.h" -#include "compiler/glsl/ir_optimization.h" -#include "compiler/glsl/glsl_parser_extras.h" -#include "compiler/glsl/glsl_symbol_table.h" -#include "compiler/glsl_types.h" -#include "program/ir_to_mesa.h" -#include "program/program.h" -#include "program/programopt.h" -#include "program/prog_cache.h" -#include "program/prog_instruction.h" -#include "program/prog_parameter.h" -#include "program/prog_print.h" -#include "program/prog_statevars.h" -#include "util/bitscan.h" - -using namespace ir_builder; - -/* - * Note on texture units: - * - * The number of texture units supported by fixed-function fragment - * processing is MAX_TEXTURE_COORD_UNITS, not MAX_TEXTURE_IMAGE_UNITS. - * That's because there's a one-to-one correspondence between texture - * coordinates and samplers in fixed-function processing. - * - * Since fixed-function vertex processing is limited to MAX_TEXTURE_COORD_UNITS - * sets of texcoords, so is fixed-function fragment processing. - * - * We can safely use ctx->Const.MaxTextureUnits for loop bounds. - */ - - -static GLboolean -texenv_doing_secondary_color(struct gl_context *ctx) -{ - if (ctx->Light.Enabled && - (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) - return GL_TRUE; - - if (ctx->Fog.ColorSumEnabled) - return GL_TRUE; - - return GL_FALSE; -} - -struct state_key { - GLuint nr_enabled_units:4; - GLuint separate_specular:1; - GLuint fog_mode:2; /**< FOG_x */ - GLuint inputs_available:12; - GLuint num_draw_buffers:4; - - /* NOTE: This array of structs must be last! (see "keySize" below) */ - struct { - GLuint enabled:1; - GLuint source_index:4; /**< TEXTURE_x_INDEX */ - GLuint shadow:1; - - /*** - * These are taken from struct gl_tex_env_combine_packed - * @{ - */ - GLuint ModeRGB:4; - GLuint ModeA:4; - GLuint ScaleShiftRGB:2; - GLuint ScaleShiftA:2; - GLuint NumArgsRGB:3; - GLuint NumArgsA:3; - struct gl_tex_env_argument ArgsRGB[MAX_COMBINER_TERMS]; - struct gl_tex_env_argument ArgsA[MAX_COMBINER_TERMS]; - /** @} */ - } unit[MAX_TEXTURE_COORD_UNITS]; -}; - - -/** - * Do we need to clamp the results of the given texture env/combine mode? - * If the inputs to the mode are in [0,1] we don't always have to clamp - * the results. - */ -static GLboolean -need_saturate( GLuint mode ) -{ - switch (mode) { - case TEXENV_MODE_REPLACE: - case TEXENV_MODE_MODULATE: - case TEXENV_MODE_INTERPOLATE: - return GL_FALSE; - case TEXENV_MODE_ADD: - case TEXENV_MODE_ADD_SIGNED: - case TEXENV_MODE_SUBTRACT: - case TEXENV_MODE_DOT3_RGB: - case TEXENV_MODE_DOT3_RGB_EXT: - case TEXENV_MODE_DOT3_RGBA: - case TEXENV_MODE_DOT3_RGBA_EXT: - case TEXENV_MODE_MODULATE_ADD_ATI: - case TEXENV_MODE_MODULATE_SIGNED_ADD_ATI: - case TEXENV_MODE_MODULATE_SUBTRACT_ATI: - case TEXENV_MODE_ADD_PRODUCTS_NV: - case TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV: - return GL_TRUE; - default: - assert(0); - return GL_FALSE; - } -} - -#define VERT_BIT_TEX_ANY (0xff << VERT_ATTRIB_TEX0) - -/** - * Identify all possible varying inputs. The fragment program will - * never reference non-varying inputs, but will track them via state - * constants instead. - * - * This function figures out all the inputs that the fragment program - * has access to and filters input bitmask. - */ -static GLbitfield filter_fp_input_mask( GLbitfield fp_inputs, - struct gl_context *ctx ) -{ - if (ctx->VertexProgram._Overriden) { - /* Somebody's messing with the vertex program and we don't have - * a clue what's happening. Assume that it could be producing - * all possible outputs. - */ - return fp_inputs; - } - - if (ctx->RenderMode == GL_FEEDBACK) { - /* _NEW_RENDERMODE */ - return fp_inputs & (VARYING_BIT_COL0 | VARYING_BIT_TEX0); - } - - /* _NEW_PROGRAM */ - const GLboolean vertexShader = - ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] != NULL; - const GLboolean vertexProgram = _mesa_arb_vertex_program_enabled(ctx); - - if (!(vertexProgram || vertexShader)) { - /* Fixed function vertex logic */ - GLbitfield possible_inputs = 0; - - GLbitfield varying_inputs = ctx->VertexProgram._VaryingInputs; - /* We only update ctx->VertexProgram._VaryingInputs when in VP_MODE_FF _VPMode */ - assert(VP_MODE_FF == ctx->VertexProgram._VPMode); - - /* These get generated in the setup routine regardless of the - * vertex program: - */ - /* _NEW_POINT */ - if (ctx->Point.PointSprite) { - /* All texture varyings are possible to use */ - possible_inputs = VARYING_BITS_TEX_ANY; - } - else { - const GLbitfield possible_tex_inputs = - ctx->Texture._TexGenEnabled | - ctx->Texture._TexMatEnabled | - ((varying_inputs & VERT_BIT_TEX_ANY) >> VERT_ATTRIB_TEX0); - - possible_inputs = (possible_tex_inputs << VARYING_SLOT_TEX0); - } - - /* First look at what values may be computed by the generated - * vertex program: - */ - if (ctx->Light.Enabled) { - possible_inputs |= VARYING_BIT_COL0; - - if (texenv_doing_secondary_color(ctx)) - possible_inputs |= VARYING_BIT_COL1; - } - - /* Then look at what might be varying as a result of enabled - * arrays, etc: - */ - if (varying_inputs & VERT_BIT_COLOR0) - possible_inputs |= VARYING_BIT_COL0; - if (varying_inputs & VERT_BIT_COLOR1) - possible_inputs |= VARYING_BIT_COL1; - - return fp_inputs & possible_inputs; - } - - /* calculate from vp->outputs */ - struct gl_program *vprog; - - /* Choose GLSL vertex shader over ARB vertex program. Need this - * since vertex shader state validation comes after fragment state - * validation (see additional comments in state.c). - */ - if (ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY] != NULL) - vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; - else if (ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL] != NULL) - vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; - else if (vertexShader) - vprog = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; - else - vprog = ctx->VertexProgram.Current; - - GLbitfield possible_inputs = vprog->info.outputs_written; - - /* These get generated in the setup routine regardless of the - * vertex program: - */ - /* _NEW_POINT */ - if (ctx->Point.PointSprite) { - /* All texture varyings are possible to use */ - possible_inputs |= VARYING_BITS_TEX_ANY; - } - - return fp_inputs & possible_inputs; -} - - -/** - * Examine current texture environment state and generate a unique - * key to identify it. - */ -static GLuint make_state_key( struct gl_context *ctx, struct state_key *key ) -{ - GLbitfield inputs_referenced = VARYING_BIT_COL0; - GLbitfield mask; - GLuint keySize; - - memset(key, 0, sizeof(*key)); - - /* _NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE */ - mask = ctx->Texture._EnabledCoordUnits; - int i = -1; - while (mask) { - i = u_bit_scan(&mask); - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[i]; - const struct gl_texture_object *texObj = texUnit->_Current; - const struct gl_tex_env_combine_packed *comb = - &ctx->Texture.FixedFuncUnit[i]._CurrentCombinePacked; - - if (!texObj) - continue; - - key->unit[i].enabled = 1; - inputs_referenced |= VARYING_BIT_TEX(i); - - key->unit[i].source_index = texObj->TargetIndex; - - const struct gl_sampler_object *samp = _mesa_get_samplerobj(ctx, i); - if (samp->Attrib.CompareMode == GL_COMPARE_R_TO_TEXTURE) { - const GLenum format = _mesa_texture_base_format(texObj); - key->unit[i].shadow = (format == GL_DEPTH_COMPONENT || - format == GL_DEPTH_STENCIL_EXT); - } - - key->unit[i].ModeRGB = comb->ModeRGB; - key->unit[i].ModeA = comb->ModeA; - key->unit[i].ScaleShiftRGB = comb->ScaleShiftRGB; - key->unit[i].ScaleShiftA = comb->ScaleShiftA; - key->unit[i].NumArgsRGB = comb->NumArgsRGB; - key->unit[i].NumArgsA = comb->NumArgsA; - - memcpy(key->unit[i].ArgsRGB, comb->ArgsRGB, sizeof comb->ArgsRGB); - memcpy(key->unit[i].ArgsA, comb->ArgsA, sizeof comb->ArgsA); - } - - key->nr_enabled_units = i + 1; - - /* _NEW_FOG */ - if (texenv_doing_secondary_color(ctx)) { - key->separate_specular = 1; - inputs_referenced |= VARYING_BIT_COL1; - } - - /* _NEW_FOG */ - key->fog_mode = ctx->Fog._PackedEnabledMode; - - /* _NEW_BUFFERS */ - key->num_draw_buffers = ctx->DrawBuffer->_NumColorDrawBuffers; - - /* _NEW_COLOR */ - if (ctx->Color.AlphaEnabled && key->num_draw_buffers == 0) { - /* if alpha test is enabled we need to emit at least one color */ - key->num_draw_buffers = 1; - } - - key->inputs_available = filter_fp_input_mask(inputs_referenced, ctx); - - /* compute size of state key, ignoring unused texture units */ - keySize = sizeof(*key) - sizeof(key->unit) - + key->nr_enabled_units * sizeof(key->unit[0]); - - return keySize; -} - - -/** State used to build the fragment program: - */ -class texenv_fragment_program : public ir_factory { -public: - struct gl_shader_program *shader_program; - struct gl_shader *shader; - exec_list *top_instructions; - struct state_key *state; - - ir_variable *src_texture[MAX_TEXTURE_COORD_UNITS]; - /* Reg containing each texture unit's sampled texture color, - * else undef. - */ - - ir_rvalue *src_previous; /**< Reg containing color from previous - * stage. May need to be decl'd. - */ -}; - -static ir_rvalue * -get_current_attrib(texenv_fragment_program *p, GLuint attrib) -{ - ir_variable *current; - char name[128]; - - snprintf(name, sizeof(name), "gl_CurrentAttribFrag%uMESA", attrib); - - current = p->shader->symbols->get_variable(name); - assert(current); - return new(p->mem_ctx) ir_dereference_variable(current); -} - -static ir_rvalue * -get_gl_Color(texenv_fragment_program *p) -{ - if (p->state->inputs_available & VARYING_BIT_COL0) { - ir_variable *var = p->shader->symbols->get_variable("gl_Color"); - assert(var); - return new(p->mem_ctx) ir_dereference_variable(var); - } else { - return get_current_attrib(p, VERT_ATTRIB_COLOR0); - } -} - -static ir_rvalue * -get_source(texenv_fragment_program *p, - GLuint src, GLuint unit) -{ - ir_variable *var; - ir_dereference *deref; - - switch (src) { - case TEXENV_SRC_TEXTURE: - return new(p->mem_ctx) ir_dereference_variable(p->src_texture[unit]); - - case TEXENV_SRC_TEXTURE0: - case TEXENV_SRC_TEXTURE1: - case TEXENV_SRC_TEXTURE2: - case TEXENV_SRC_TEXTURE3: - case TEXENV_SRC_TEXTURE4: - case TEXENV_SRC_TEXTURE5: - case TEXENV_SRC_TEXTURE6: - case TEXENV_SRC_TEXTURE7: - return new(p->mem_ctx) - ir_dereference_variable(p->src_texture[src - TEXENV_SRC_TEXTURE0]); - - case TEXENV_SRC_CONSTANT: - var = p->shader->symbols->get_variable("gl_TextureEnvColor"); - assert(var); - deref = new(p->mem_ctx) ir_dereference_variable(var); - var->data.max_array_access = MAX2(var->data.max_array_access, (int)unit); - return new(p->mem_ctx) ir_dereference_array(deref, - new(p->mem_ctx) ir_constant(unit)); - - case TEXENV_SRC_PRIMARY_COLOR: - var = p->shader->symbols->get_variable("gl_Color"); - assert(var); - return new(p->mem_ctx) ir_dereference_variable(var); - - case TEXENV_SRC_ZERO: - return new(p->mem_ctx) ir_constant(0.0f); - - case TEXENV_SRC_ONE: - return new(p->mem_ctx) ir_constant(1.0f); - - case TEXENV_SRC_PREVIOUS: - if (!p->src_previous) { - return get_gl_Color(p); - } else { - return p->src_previous->clone(p->mem_ctx, NULL); - } - - default: - assert(0); - return NULL; - } -} - -static ir_rvalue * -emit_combine_source(texenv_fragment_program *p, - GLuint unit, - GLuint source, - GLuint operand) -{ - ir_rvalue *src; - - src = get_source(p, source, unit); - - switch (operand) { - case TEXENV_OPR_ONE_MINUS_COLOR: - return sub(new(p->mem_ctx) ir_constant(1.0f), src); - - case TEXENV_OPR_ALPHA: - return src->type->is_scalar() ? src : swizzle_w(src); - - case TEXENV_OPR_ONE_MINUS_ALPHA: { - ir_rvalue *const scalar = src->type->is_scalar() ? src : swizzle_w(src); - - return sub(new(p->mem_ctx) ir_constant(1.0f), scalar); - } - - case TEXENV_OPR_COLOR: - return src; - - default: - assert(0); - return src; - } -} - -/** - * Check if the RGB and Alpha sources and operands match for the given - * texture unit's combinder state. When the RGB and A sources and - * operands match, we can emit fewer instructions. - */ -static GLboolean args_match( const struct state_key *key, GLuint unit ) -{ - GLuint i, numArgs = key->unit[unit].NumArgsRGB; - - for (i = 0; i < numArgs; i++) { - if (key->unit[unit].ArgsA[i].Source != key->unit[unit].ArgsRGB[i].Source) - return GL_FALSE; - - switch (key->unit[unit].ArgsA[i].Operand) { - case TEXENV_OPR_ALPHA: - switch (key->unit[unit].ArgsRGB[i].Operand) { - case TEXENV_OPR_COLOR: - case TEXENV_OPR_ALPHA: - break; - default: - return GL_FALSE; - } - break; - case TEXENV_OPR_ONE_MINUS_ALPHA: - switch (key->unit[unit].ArgsRGB[i].Operand) { - case TEXENV_OPR_ONE_MINUS_COLOR: - case TEXENV_OPR_ONE_MINUS_ALPHA: - break; - default: - return GL_FALSE; - } - break; - default: - return GL_FALSE; /* impossible */ - } - } - - return GL_TRUE; -} - -static ir_rvalue * -smear(ir_rvalue *val) -{ - if (!val->type->is_scalar()) - return val; - - return swizzle_xxxx(val); -} - -static ir_rvalue * -emit_combine(texenv_fragment_program *p, - GLuint unit, - GLuint nr, - GLuint mode, - const struct gl_tex_env_argument *opt) -{ - ir_rvalue *src[MAX_COMBINER_TERMS]; - ir_rvalue *tmp0, *tmp1; - GLuint i; - - assert(nr <= MAX_COMBINER_TERMS); - - for (i = 0; i < nr; i++) - src[i] = emit_combine_source( p, unit, opt[i].Source, opt[i].Operand ); - - switch (mode) { - case TEXENV_MODE_REPLACE: - return src[0]; - - case TEXENV_MODE_MODULATE: - return mul(src[0], src[1]); - - case TEXENV_MODE_ADD: - return add(src[0], src[1]); - - case TEXENV_MODE_ADD_SIGNED: - return add(add(src[0], src[1]), new(p->mem_ctx) ir_constant(-0.5f)); - - case TEXENV_MODE_INTERPOLATE: - /* Arg0 * (Arg2) + Arg1 * (1-Arg2) */ - tmp0 = mul(src[0], src[2]); - tmp1 = mul(src[1], sub(new(p->mem_ctx) ir_constant(1.0f), - src[2]->clone(p->mem_ctx, NULL))); - return add(tmp0, tmp1); - - case TEXENV_MODE_SUBTRACT: - return sub(src[0], src[1]); - - case TEXENV_MODE_DOT3_RGBA: - case TEXENV_MODE_DOT3_RGBA_EXT: - case TEXENV_MODE_DOT3_RGB_EXT: - case TEXENV_MODE_DOT3_RGB: { - tmp0 = mul(src[0], new(p->mem_ctx) ir_constant(2.0f)); - tmp0 = add(tmp0, new(p->mem_ctx) ir_constant(-1.0f)); - - tmp1 = mul(src[1], new(p->mem_ctx) ir_constant(2.0f)); - tmp1 = add(tmp1, new(p->mem_ctx) ir_constant(-1.0f)); - - return dot(swizzle_xyz(smear(tmp0)), swizzle_xyz(smear(tmp1))); - } - case TEXENV_MODE_MODULATE_ADD_ATI: - return add(mul(src[0], src[2]), src[1]); - - case TEXENV_MODE_MODULATE_SIGNED_ADD_ATI: - return add(add(mul(src[0], src[2]), src[1]), - new(p->mem_ctx) ir_constant(-0.5f)); - - case TEXENV_MODE_MODULATE_SUBTRACT_ATI: - return sub(mul(src[0], src[2]), src[1]); - - case TEXENV_MODE_ADD_PRODUCTS_NV: - return add(mul(src[0], src[1]), mul(src[2], src[3])); - - case TEXENV_MODE_ADD_PRODUCTS_SIGNED_NV: - return add(add(mul(src[0], src[1]), mul(src[2], src[3])), - new(p->mem_ctx) ir_constant(-0.5f)); - default: - assert(0); - return src[0]; - } -} - -/** - * Generate instructions for one texture unit's env/combiner mode. - */ -static ir_rvalue * -emit_texenv(texenv_fragment_program *p, GLuint unit) -{ - const struct state_key *key = p->state; - GLboolean rgb_saturate, alpha_saturate; - GLuint rgb_shift, alpha_shift; - - if (!key->unit[unit].enabled) { - return get_source(p, TEXENV_SRC_PREVIOUS, 0); - } - - switch (key->unit[unit].ModeRGB) { - case TEXENV_MODE_DOT3_RGB_EXT: - alpha_shift = key->unit[unit].ScaleShiftA; - rgb_shift = 0; - break; - case TEXENV_MODE_DOT3_RGBA_EXT: - alpha_shift = 0; - rgb_shift = 0; - break; - default: - rgb_shift = key->unit[unit].ScaleShiftRGB; - alpha_shift = key->unit[unit].ScaleShiftA; - break; - } - - /* If we'll do rgb/alpha shifting don't saturate in emit_combine(). - * We don't want to clamp twice. - */ - if (rgb_shift) - rgb_saturate = GL_FALSE; /* saturate after rgb shift */ - else if (need_saturate(key->unit[unit].ModeRGB)) - rgb_saturate = GL_TRUE; - else - rgb_saturate = GL_FALSE; - - if (alpha_shift) - alpha_saturate = GL_FALSE; /* saturate after alpha shift */ - else if (need_saturate(key->unit[unit].ModeA)) - alpha_saturate = GL_TRUE; - else - alpha_saturate = GL_FALSE; - - ir_variable *temp_var = p->make_temp(glsl_type::vec4_type, "texenv_combine"); - ir_dereference *deref; - ir_rvalue *val; - - /* Emit the RGB and A combine ops - */ - if (key->unit[unit].ModeRGB == key->unit[unit].ModeA && - args_match(key, unit)) { - val = emit_combine(p, unit, - key->unit[unit].NumArgsRGB, - key->unit[unit].ModeRGB, - key->unit[unit].ArgsRGB); - val = smear(val); - if (rgb_saturate) - val = saturate(val); - - p->emit(assign(temp_var, val)); - } - else if (key->unit[unit].ModeRGB == TEXENV_MODE_DOT3_RGBA_EXT || - key->unit[unit].ModeRGB == TEXENV_MODE_DOT3_RGBA) { - ir_rvalue *val = emit_combine(p, unit, - key->unit[unit].NumArgsRGB, - key->unit[unit].ModeRGB, - key->unit[unit].ArgsRGB); - val = smear(val); - if (rgb_saturate) - val = saturate(val); - p->emit(assign(temp_var, val)); - } - else { - /* Need to do something to stop from re-emitting identical - * argument calculations here: - */ - val = emit_combine(p, unit, - key->unit[unit].NumArgsRGB, - key->unit[unit].ModeRGB, - key->unit[unit].ArgsRGB); - val = swizzle_xyz(smear(val)); - if (rgb_saturate) - val = saturate(val); - p->emit(assign(temp_var, val, WRITEMASK_XYZ)); - - val = emit_combine(p, unit, - key->unit[unit].NumArgsA, - key->unit[unit].ModeA, - key->unit[unit].ArgsA); - val = swizzle_w(smear(val)); - if (alpha_saturate) - val = saturate(val); - p->emit(assign(temp_var, val, WRITEMASK_W)); - } - - deref = new(p->mem_ctx) ir_dereference_variable(temp_var); - - /* Deal with the final shift: - */ - if (alpha_shift || rgb_shift) { - ir_constant *shift; - - if (rgb_shift == alpha_shift) { - shift = new(p->mem_ctx) ir_constant((float)(1 << rgb_shift)); - } - else { - ir_constant_data const_data; - - const_data.f[0] = float(1 << rgb_shift); - const_data.f[1] = float(1 << rgb_shift); - const_data.f[2] = float(1 << rgb_shift); - const_data.f[3] = float(1 << alpha_shift); - - shift = new(p->mem_ctx) ir_constant(glsl_type::vec4_type, - &const_data); - } - - return saturate(mul(deref, shift)); - } - else - return deref; -} - - -/** - * Generate instruction for getting a texture source term. - */ -static void load_texture( texenv_fragment_program *p, GLuint unit ) -{ - ir_dereference *deref; - - if (p->src_texture[unit]) - return; - - const GLuint texTarget = p->state->unit[unit].source_index; - ir_rvalue *texcoord; - - if (!(p->state->inputs_available & (VARYING_BIT_TEX0 << unit))) { - texcoord = get_current_attrib(p, VERT_ATTRIB_TEX0 + unit); - } else { - ir_variable *tc_array = p->shader->symbols->get_variable("gl_TexCoord"); - assert(tc_array); - texcoord = new(p->mem_ctx) ir_dereference_variable(tc_array); - ir_rvalue *index = new(p->mem_ctx) ir_constant(unit); - texcoord = new(p->mem_ctx) ir_dereference_array(texcoord, index); - tc_array->data.max_array_access = MAX2(tc_array->data.max_array_access, (int)unit); - } - - if (!p->state->unit[unit].enabled) { - p->src_texture[unit] = p->make_temp(glsl_type::vec4_type, - "dummy_tex"); - p->emit(p->src_texture[unit]); - - p->emit(assign(p->src_texture[unit], new(p->mem_ctx) ir_constant(0.0f))); - return ; - } - - const glsl_type *sampler_type = NULL; - int coords = 0; - - switch (texTarget) { - case TEXTURE_1D_INDEX: - if (p->state->unit[unit].shadow) - sampler_type = glsl_type::sampler1DShadow_type; - else - sampler_type = glsl_type::sampler1D_type; - coords = 1; - break; - case TEXTURE_1D_ARRAY_INDEX: - if (p->state->unit[unit].shadow) - sampler_type = glsl_type::sampler1DArrayShadow_type; - else - sampler_type = glsl_type::sampler1DArray_type; - coords = 2; - break; - case TEXTURE_2D_INDEX: - if (p->state->unit[unit].shadow) - sampler_type = glsl_type::sampler2DShadow_type; - else - sampler_type = glsl_type::sampler2D_type; - coords = 2; - break; - case TEXTURE_2D_ARRAY_INDEX: - if (p->state->unit[unit].shadow) - sampler_type = glsl_type::sampler2DArrayShadow_type; - else - sampler_type = glsl_type::sampler2DArray_type; - coords = 3; - break; - case TEXTURE_RECT_INDEX: - if (p->state->unit[unit].shadow) - sampler_type = glsl_type::sampler2DRectShadow_type; - else - sampler_type = glsl_type::sampler2DRect_type; - coords = 2; - break; - case TEXTURE_3D_INDEX: - assert(!p->state->unit[unit].shadow); - sampler_type = glsl_type::sampler3D_type; - coords = 3; - break; - case TEXTURE_CUBE_INDEX: - if (p->state->unit[unit].shadow) - sampler_type = glsl_type::samplerCubeShadow_type; - else - sampler_type = glsl_type::samplerCube_type; - coords = 3; - break; - case TEXTURE_EXTERNAL_INDEX: - assert(!p->state->unit[unit].shadow); - sampler_type = glsl_type::samplerExternalOES_type; - coords = 2; - break; - } - - p->src_texture[unit] = p->make_temp(glsl_type::vec4_type, - "tex"); - - ir_texture *tex = new(p->mem_ctx) ir_texture(ir_tex); - - - char *sampler_name = ralloc_asprintf(p->mem_ctx, "sampler_%d", unit); - ir_variable *sampler = new(p->mem_ctx) ir_variable(sampler_type, - sampler_name, - ir_var_uniform); - p->top_instructions->push_head(sampler); - - /* Set the texture unit for this sampler in the same way that - * layout(binding=X) would. - */ - sampler->data.explicit_binding = true; - sampler->data.binding = unit; - - deref = new(p->mem_ctx) ir_dereference_variable(sampler); - tex->set_sampler(deref, glsl_type::vec4_type); - - tex->coordinate = new(p->mem_ctx) ir_swizzle(texcoord, 0, 1, 2, 3, coords); - - if (p->state->unit[unit].shadow) { - texcoord = texcoord->clone(p->mem_ctx, NULL); - tex->shadow_comparator = new(p->mem_ctx) ir_swizzle(texcoord, - coords, 0, 0, 0, - 1); - coords++; - } - - texcoord = texcoord->clone(p->mem_ctx, NULL); - tex->projector = swizzle_w(texcoord); - - p->emit(assign(p->src_texture[unit], tex)); -} - -static void -load_texenv_source(texenv_fragment_program *p, - GLuint src, GLuint unit) -{ - switch (src) { - case TEXENV_SRC_TEXTURE: - load_texture(p, unit); - break; - - case TEXENV_SRC_TEXTURE0: - case TEXENV_SRC_TEXTURE1: - case TEXENV_SRC_TEXTURE2: - case TEXENV_SRC_TEXTURE3: - case TEXENV_SRC_TEXTURE4: - case TEXENV_SRC_TEXTURE5: - case TEXENV_SRC_TEXTURE6: - case TEXENV_SRC_TEXTURE7: - load_texture(p, src - TEXENV_SRC_TEXTURE0); - break; - - default: - /* not a texture src - do nothing */ - break; - } -} - - -/** - * Generate instructions for loading all texture source terms. - */ -static GLboolean -load_texunit_sources( texenv_fragment_program *p, GLuint unit ) -{ - const struct state_key *key = p->state; - GLuint i; - - for (i = 0; i < key->unit[unit].NumArgsRGB; i++) { - load_texenv_source( p, key->unit[unit].ArgsRGB[i].Source, unit ); - } - - for (i = 0; i < key->unit[unit].NumArgsA; i++) { - load_texenv_source( p, key->unit[unit].ArgsA[i].Source, unit ); - } - - return GL_TRUE; -} - -/** - * Applies the fog calculations. - * - * This is basically like the ARB_fragment_prorgam fog options. Note - * that ffvertex_prog.c produces fogcoord for us when - * GL_FOG_COORDINATE_EXT is set to GL_FRAGMENT_DEPTH_EXT. - */ -static ir_rvalue * -emit_fog_instructions(texenv_fragment_program *p, - ir_rvalue *fragcolor) -{ - struct state_key *key = p->state; - ir_rvalue *f, *temp; - ir_variable *params, *oparams; - ir_variable *fogcoord; - - /* Temporary storage for the whole fog result. Fog calculations - * only affect rgb so we're hanging on to the .a value of fragcolor - * this way. - */ - ir_variable *fog_result = p->make_temp(glsl_type::vec4_type, "fog_result"); - p->emit(assign(fog_result, fragcolor)); - - fragcolor = swizzle_xyz(fog_result); - - oparams = p->shader->symbols->get_variable("gl_FogParamsOptimizedMESA"); - assert(oparams); - fogcoord = p->shader->symbols->get_variable("gl_FogFragCoord"); - assert(fogcoord); - params = p->shader->symbols->get_variable("gl_Fog"); - assert(params); - f = new(p->mem_ctx) ir_dereference_variable(fogcoord); - - ir_variable *f_var = p->make_temp(glsl_type::float_type, "fog_factor"); - - switch (key->fog_mode) { - case FOG_LINEAR: - /* f = (end - z) / (end - start) - * - * gl_MesaFogParamsOptimized gives us (-1 / (end - start)) and - * (end / (end - start)) so we can generate a single MAD. - */ - f = add(mul(f, swizzle_x(oparams)), swizzle_y(oparams)); - break; - case FOG_EXP: - /* f = e^(-(density * fogcoord)) - * - * gl_MesaFogParamsOptimized gives us density/ln(2) so we can - * use EXP2 which is generally the native instruction without - * having to do any further math on the fog density uniform. - */ - f = mul(f, swizzle_z(oparams)); - f = new(p->mem_ctx) ir_expression(ir_unop_neg, f); - f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f); - break; - case FOG_EXP2: - /* f = e^(-(density * fogcoord)^2) - * - * gl_MesaFogParamsOptimized gives us density/sqrt(ln(2)) so we - * can do this like FOG_EXP but with a squaring after the - * multiply by density. - */ - ir_variable *temp_var = p->make_temp(glsl_type::float_type, "fog_temp"); - p->emit(assign(temp_var, mul(f, swizzle_w(oparams)))); - - f = mul(temp_var, temp_var); - f = new(p->mem_ctx) ir_expression(ir_unop_neg, f); - f = new(p->mem_ctx) ir_expression(ir_unop_exp2, f); - break; - } - - p->emit(assign(f_var, saturate(f))); - - f = sub(new(p->mem_ctx) ir_constant(1.0f), f_var); - temp = new(p->mem_ctx) ir_dereference_variable(params); - temp = new(p->mem_ctx) ir_dereference_record(temp, "color"); - temp = mul(swizzle_xyz(temp), f); - - p->emit(assign(fog_result, add(temp, mul(fragcolor, f_var)), WRITEMASK_XYZ)); - - return new(p->mem_ctx) ir_dereference_variable(fog_result); -} - -static void -emit_instructions(texenv_fragment_program *p) -{ - struct state_key *key = p->state; - GLuint unit; - - if (key->nr_enabled_units) { - /* First pass - to support texture_env_crossbar, first identify - * all referenced texture sources and emit texld instructions - * for each: - */ - for (unit = 0; unit < key->nr_enabled_units; unit++) - if (key->unit[unit].enabled) { - load_texunit_sources(p, unit); - } - - /* Second pass - emit combine instructions to build final color: - */ - for (unit = 0; unit < key->nr_enabled_units; unit++) { - if (key->unit[unit].enabled) { - p->src_previous = emit_texenv(p, unit); - } - } - } - - ir_rvalue *cf = get_source(p, TEXENV_SRC_PREVIOUS, 0); - - if (key->separate_specular) { - ir_variable *spec_result = p->make_temp(glsl_type::vec4_type, - "specular_add"); - p->emit(assign(spec_result, cf)); - - ir_rvalue *secondary; - if (p->state->inputs_available & VARYING_BIT_COL1) { - ir_variable *var = - p->shader->symbols->get_variable("gl_SecondaryColor"); - assert(var); - secondary = swizzle_xyz(var); - } else { - secondary = swizzle_xyz(get_current_attrib(p, VERT_ATTRIB_COLOR1)); - } - - p->emit(assign(spec_result, add(swizzle_xyz(spec_result), secondary), - WRITEMASK_XYZ)); - - cf = new(p->mem_ctx) ir_dereference_variable(spec_result); - } - - if (key->fog_mode) { - cf = emit_fog_instructions(p, cf); - } - - ir_variable *frag_color = p->shader->symbols->get_variable("gl_FragColor"); - assert(frag_color); - p->emit(assign(frag_color, cf)); -} - -/** - * Generate a new fragment program which implements the context's - * current texture env/combine mode. - */ -static struct gl_shader_program * -create_new_program(struct gl_context *ctx, struct state_key *key) -{ - texenv_fragment_program p; - unsigned int unit; - _mesa_glsl_parse_state *state; - - p.mem_ctx = ralloc_context(NULL); - p.shader = _mesa_new_shader(0, MESA_SHADER_FRAGMENT); -#ifdef DEBUG - p.shader->SourceChecksum = 0xf18ed; /* fixed */ -#endif - p.shader->ir = new(p.shader) exec_list; - state = new(p.shader) _mesa_glsl_parse_state(ctx, MESA_SHADER_FRAGMENT, - p.shader); - p.shader->symbols = state->symbols; - p.top_instructions = p.shader->ir; - p.instructions = p.shader->ir; - p.state = key; - p.shader_program = _mesa_new_shader_program(0); - - /* Tell the linker to ignore the fact that we're building a - * separate shader, in case we're in a GLES2 context that would - * normally reject that. The real problem is that we're building a - * fixed function program in a GLES2 context at all, but that's a - * big mess to clean up. - */ - p.shader_program->SeparateShader = GL_TRUE; - - /* The legacy GLSL shadow functions follow the depth texture - * mode and return vec4. The GLSL 1.30 shadow functions return float and - * ignore the depth texture mode. That's a shader and state dependency - * that's difficult to deal with. st/mesa uses a simple but not - * completely correct solution: if the shader declares GLSL >= 1.30 and - * the depth texture mode is GL_ALPHA (000X), it sets the XXXX swizzle - * instead. Thus, the GLSL 1.30 shadow function will get the result in .x - * and legacy shadow functions will get it in .w as expected. - * For the fixed-function fragment shader, use 120 to get correct behavior - * for GL_ALPHA. - */ - state->language_version = 120; - - state->es_shader = false; - if (_mesa_is_gles(ctx) && ctx->Extensions.OES_EGL_image_external) - state->OES_EGL_image_external_enable = true; - _mesa_glsl_initialize_types(state); - _mesa_glsl_initialize_variables(p.instructions, state); - - for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) - p.src_texture[unit] = NULL; - - p.src_previous = NULL; - - ir_function *main_f = new(p.mem_ctx) ir_function("main"); - p.emit(main_f); - state->symbols->add_function(main_f); - - ir_function_signature *main_sig = - new(p.mem_ctx) ir_function_signature(glsl_type::void_type); - main_sig->is_defined = true; - main_f->add_signature(main_sig); - - p.instructions = &main_sig->body; - if (key->num_draw_buffers) - emit_instructions(&p); - - validate_ir_tree(p.shader->ir); - - const struct gl_shader_compiler_options *options = - &ctx->Const.ShaderCompilerOptions[MESA_SHADER_FRAGMENT]; - - /* Conservative approach: Don't optimize here, the linker does it too. */ - if (!ctx->Const.GLSLOptimizeConservatively) { - while (do_common_optimization(p.shader->ir, false, false, options, - ctx->Const.NativeIntegers)) - ; - } - - reparent_ir(p.shader->ir, p.shader->ir); - - p.shader->CompileStatus = COMPILE_SUCCESS; - p.shader->Version = state->language_version; - p.shader_program->Shaders = - (gl_shader **)malloc(sizeof(*p.shader_program->Shaders)); - p.shader_program->Shaders[0] = p.shader; - p.shader_program->NumShaders = 1; - - _mesa_glsl_link_shader(ctx, p.shader_program); - - if (!p.shader_program->data->LinkStatus) - _mesa_problem(ctx, "Failed to link fixed function fragment shader: %s\n", - p.shader_program->data->InfoLog); - - ralloc_free(p.mem_ctx); - return p.shader_program; -} - -extern "C" { - -/** - * Return a fragment program which implements the current - * fixed-function texture, fog and color-sum operations. - */ -struct gl_shader_program * -_mesa_get_fixed_func_fragment_program(struct gl_context *ctx) -{ - struct gl_shader_program *shader_program; - struct state_key key; - GLuint keySize; - - keySize = make_state_key(ctx, &key); - - shader_program = (struct gl_shader_program *) - _mesa_search_program_cache(ctx->FragmentProgram.Cache, - &key, keySize); - - if (!shader_program) { - shader_program = create_new_program(ctx, &key); - - _mesa_shader_cache_insert(ctx, ctx->FragmentProgram.Cache, - &key, keySize, shader_program); - } - - return shader_program; -} - -} diff --git a/src/mesa/main/ffvertex_prog.c b/src/mesa/main/ffvertex_prog.c index ff5cf23beb2..bcd3fb8dc30 100644 --- a/src/mesa/main/ffvertex_prog.c +++ b/src/mesa/main/ffvertex_prog.c @@ -34,19 +34,22 @@ #include "main/errors.h" -#include "main/glheader.h" +#include "util/glheader.h" #include "main/mtypes.h" #include "main/macros.h" #include "main/enums.h" +#include "main/context.h" #include "main/ffvertex_prog.h" #include "program/program.h" #include "program/prog_cache.h" -#include "program/prog_instruction.h" -#include "program/prog_parameter.h" -#include "program/prog_print.h" #include "program/prog_statevars.h" #include "util/bitscan.h" +#include "state_tracker/st_program.h" +#include "state_tracker/st_nir.h" + +#include "compiler/nir/nir_builder.h" +#include "compiler/nir/nir_builtin_builder.h" /** Max of number of lights and texture coord units */ #define NUM_UNITS MAX2(MAX_TEXTURE_COORD_UNITS, MAX_LIGHTS) @@ -156,6 +159,16 @@ static void make_state_key( struct gl_context *ctx, struct state_key *key ) memset(key, 0, sizeof(struct state_key)); + if (_mesa_hw_select_enabled(ctx)) { + /* GL_SELECT mode only need position calculation. + * glBegin/End use VERT_BIT_SELECT_RESULT_OFFSET for multi name stack in one draw. + * glDrawArrays may also be called without user shader, fallback to FF one. + */ + key->varying_vp_inputs = ctx->VertexProgram._VaryingInputs & + (VERT_BIT_POS | VERT_BIT_SELECT_RESULT_OFFSET); + return; + } + /* This now relies on texenvprogram.c being active: */ assert(fp); @@ -174,16 +187,16 @@ static void make_state_key( struct gl_context *ctx, struct state_key *key ) key->light_global_enabled = 1; if (ctx->Light.Model.LocalViewer) - key->light_local_viewer = 1; + key->light_local_viewer = 1; if (ctx->Light.Model.TwoSide) - key->light_twoside = 1; + key->light_twoside = 1; if (ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) key->separate_specular = 1; if (ctx->Light.ColorMaterialEnabled) { - key->light_color_material_mask = ctx->Light._ColorMaterialBitmask; + key->light_color_material_mask = ctx->Light._ColorMaterialBitmask; } mask = ctx->Light._EnabledLights; @@ -240,596 +253,283 @@ static void make_state_key( struct gl_context *ctx, struct state_key *key ) &ctx->Texture.FixedFuncUnit[i]; if (ctx->Point.PointSprite) - if (ctx->Point.CoordReplace & (1u << i)) - key->unit[i].coord_replace = 1; + if (ctx->Point.CoordReplace & (1u << i)) + key->unit[i].coord_replace = 1; if (ctx->Texture._TexMatEnabled & ENABLE_TEXMAT(i)) - key->unit[i].texmat_enabled = 1; + key->unit[i].texmat_enabled = 1; if (texUnit->TexGenEnabled) { - key->unit[i].texgen_enabled = 1; - - key->unit[i].texgen_mode0 = - translate_texgen( texUnit->TexGenEnabled & (1<<0), - texUnit->GenS.Mode ); - key->unit[i].texgen_mode1 = - translate_texgen( texUnit->TexGenEnabled & (1<<1), - texUnit->GenT.Mode ); - key->unit[i].texgen_mode2 = - translate_texgen( texUnit->TexGenEnabled & (1<<2), - texUnit->GenR.Mode ); - key->unit[i].texgen_mode3 = - translate_texgen( texUnit->TexGenEnabled & (1<<3), - texUnit->GenQ.Mode ); + key->unit[i].texgen_enabled = 1; + + key->unit[i].texgen_mode0 = + translate_texgen( texUnit->TexGenEnabled & (1<<0), + texUnit->GenS.Mode ); + key->unit[i].texgen_mode1 = + translate_texgen( texUnit->TexGenEnabled & (1<<1), + texUnit->GenT.Mode ); + key->unit[i].texgen_mode2 = + translate_texgen( texUnit->TexGenEnabled & (1<<2), + texUnit->GenR.Mode ); + key->unit[i].texgen_mode3 = + translate_texgen( texUnit->TexGenEnabled & (1<<3), + texUnit->GenQ.Mode ); } } } - - -/* Very useful debugging tool - produces annotated listing of - * generated program with line/function references for each - * instruction back into this file: - */ -#define DISASSEM 0 - - -/* Use uregs to represent registers internally, translate to Mesa's - * expected formats on emit. - * - * NOTE: These are passed by value extensively in this file rather - * than as usual by pointer reference. If this disturbs you, try - * remembering they are just 32bits in size. - * - * GCC is smart enough to deal with these dword-sized structures in - * much the same way as if I had defined them as dwords and was using - * macros to access and set the fields. This is much nicer and easier - * to evolve. - */ -struct ureg { - GLuint file:4; - GLint idx:9; /* relative addressing may be negative */ - /* sizeof(idx) should == sizeof(prog_src_reg::Index) */ - GLuint negate:1; - GLuint swz:12; - GLuint pad:6; -}; - - struct tnl_program { const struct state_key *state; - struct gl_program *program; struct gl_program_parameter_list *state_params; - GLuint max_inst; /** number of instructions allocated for program */ GLboolean mvp_with_dp4; - GLuint temp_in_use; - GLuint temp_reserved; + nir_builder *b; - struct ureg eye_position; - struct ureg eye_position_z; - struct ureg eye_position_normalized; - struct ureg transformed_normal; - struct ureg identity; + nir_def *eye_position; + nir_def *eye_position_z; + nir_def *eye_position_normalized; + nir_def *transformed_normal; GLuint materials; GLuint color_materials; }; - -static const struct ureg undef = { - PROGRAM_UNDEFINED, - 0, - 0, - 0, - 0 -}; - -/* Local shorthand: - */ -#define X SWIZZLE_X -#define Y SWIZZLE_Y -#define Z SWIZZLE_Z -#define W SWIZZLE_W - - -/* Construct a ureg: - */ -static struct ureg make_ureg(GLuint file, GLint idx) -{ - struct ureg reg; - reg.file = file; - reg.idx = idx; - reg.negate = 0; - reg.swz = SWIZZLE_NOOP; - reg.pad = 0; - return reg; -} - - -static struct ureg negate( struct ureg reg ) -{ - reg.negate ^= 1; - return reg; -} - - -static struct ureg swizzle( struct ureg reg, int x, int y, int z, int w ) -{ - reg.swz = MAKE_SWIZZLE4(GET_SWZ(reg.swz, x), - GET_SWZ(reg.swz, y), - GET_SWZ(reg.swz, z), - GET_SWZ(reg.swz, w)); - return reg; -} - - -static struct ureg swizzle1( struct ureg reg, int x ) -{ - return swizzle(reg, x, x, x, x); -} - - -static struct ureg get_temp( struct tnl_program *p ) -{ - int bit = ffs( ~p->temp_in_use ); - if (!bit) { - _mesa_problem(NULL, "%s: out of temporaries\n", __FILE__); - exit(1); - } - - if ((GLuint) bit > p->program->arb.NumTemporaries) - p->program->arb.NumTemporaries = bit; - - p->temp_in_use |= 1<<(bit-1); - return make_ureg(PROGRAM_TEMPORARY, bit-1); -} - - -static struct ureg reserve_temp( struct tnl_program *p ) -{ - struct ureg temp = get_temp( p ); - p->temp_reserved |= 1<<temp.idx; - return temp; -} - - -static void release_temp( struct tnl_program *p, struct ureg reg ) -{ - if (reg.file == PROGRAM_TEMPORARY) { - p->temp_in_use &= ~(1<<reg.idx); - p->temp_in_use |= p->temp_reserved; /* can't release reserved temps */ - } -} - -static void release_temps( struct tnl_program *p ) -{ - p->temp_in_use = p->temp_reserved; -} - - -static struct ureg register_param4(struct tnl_program *p, - GLint s0, - GLint s1, - GLint s2, - GLint s3) +static nir_variable * +register_state_var(struct tnl_program *p, + gl_state_index16 s0, + gl_state_index16 s1, + gl_state_index16 s2, + gl_state_index16 s3, + const struct glsl_type *type) { gl_state_index16 tokens[STATE_LENGTH]; - GLint idx; tokens[0] = s0; tokens[1] = s1; tokens[2] = s2; tokens[3] = s3; - idx = _mesa_add_state_reference(p->state_params, tokens); - return make_ureg(PROGRAM_STATE_VAR, idx); -} - - -#define register_param1(p,s0) register_param4(p,s0,0,0,0) -#define register_param2(p,s0,s1) register_param4(p,s0,s1,0,0) -#define register_param3(p,s0,s1,s2) register_param4(p,s0,s1,s2,0) - - - -/** - * \param input one of VERT_ATTRIB_x tokens. - */ -static struct ureg register_input( struct tnl_program *p, GLuint input ) -{ - assert(input < VERT_ATTRIB_MAX); + nir_variable *var = nir_find_state_variable(p->b->shader, tokens); + if (var) + return var; - if (p->state->varying_vp_inputs & VERT_BIT(input)) { - p->program->info.inputs_read |= VERT_BIT(input); - return make_ureg(PROGRAM_INPUT, input); - } - else { - return register_param2(p, STATE_CURRENT_ATTRIB, input); - } -} + var = st_nir_state_variable_create(p->b->shader, type, tokens); + var->data.driver_location = _mesa_add_state_reference(p->state_params, tokens); - -/** - * \param input one of VARYING_SLOT_x tokens. - */ -static struct ureg register_output( struct tnl_program *p, GLuint output ) -{ - p->program->info.outputs_written |= BITFIELD64_BIT(output); - return make_ureg(PROGRAM_OUTPUT, output); + return var; } - -static struct ureg register_const4f( struct tnl_program *p, - GLfloat s0, - GLfloat s1, - GLfloat s2, - GLfloat s3) +static nir_def * +load_state_var(struct tnl_program *p, + gl_state_index16 s0, + gl_state_index16 s1, + gl_state_index16 s2, + gl_state_index16 s3, + const struct glsl_type *type) { - gl_constant_value values[4]; - GLint idx; - GLuint swizzle; - values[0].f = s0; - values[1].f = s1; - values[2].f = s2; - values[3].f = s3; - idx = _mesa_add_unnamed_constant(p->program->Parameters, values, 4, - &swizzle ); - assert(swizzle == SWIZZLE_NOOP); - return make_ureg(PROGRAM_CONSTANT, idx); + nir_variable *var = register_state_var(p, s0, s1, s2, s3, type); + return nir_load_var(p->b, var); } -#define register_const1f(p, s0) register_const4f(p, s0, 0, 0, 1) -#define register_scalar_const(p, s0) register_const4f(p, s0, s0, s0, s0) -#define register_const2f(p, s0, s1) register_const4f(p, s0, s1, 0, 1) -#define register_const3f(p, s0, s1, s2) register_const4f(p, s0, s1, s2, 1) - -static GLboolean is_undef( struct ureg reg ) +static nir_def * +load_state_vec4(struct tnl_program *p, + gl_state_index16 s0, + gl_state_index16 s1, + gl_state_index16 s2, + gl_state_index16 s3) { - return reg.file == PROGRAM_UNDEFINED; + return load_state_var(p, s0, s1, s2, s3, glsl_vec4_type()); } - -static struct ureg get_identity_param( struct tnl_program *p ) +static void +load_state_mat4(struct tnl_program *p, nir_def *out[4], + gl_state_index state_index, unsigned tex_index) { - if (is_undef(p->identity)) - p->identity = register_const4f(p, 0,0,0,1); - - return p->identity; + for (int i = 0; i < 4; ++i) + out[i] = load_state_vec4(p, state_index, tex_index, i, i); } -static void register_matrix_param5( struct tnl_program *p, - GLint s0, /* modelview, projection, etc */ - GLint s1, /* texture matrix number */ - GLint s2, /* first row */ - GLint s3, /* last row */ - struct ureg *matrix ) +static nir_def * +load_input(struct tnl_program *p, gl_vert_attrib attr, + const struct glsl_type *type) { - GLint i; - - /* This is a bit sad as the support is there to pull the whole - * matrix out in one go: - */ - for (i = 0; i <= s3 - s2; i++) - matrix[i] = register_param4(p, s0, s1, i, i); + if (p->state->varying_vp_inputs & VERT_BIT(attr)) { + nir_variable *var = nir_get_variable_with_location(p->b->shader, nir_var_shader_in, + attr, type); + p->b->shader->info.inputs_read |= (uint64_t)VERT_BIT(attr); + return nir_load_var(p->b, var); + } else + return load_state_var(p, STATE_CURRENT_ATTRIB, attr, 0, 0, type); } - -static void emit_arg( struct prog_src_register *src, - struct ureg reg ) +static nir_def * +load_input_vec4(struct tnl_program *p, gl_vert_attrib attr) { - src->File = reg.file; - src->Index = reg.idx; - src->Swizzle = reg.swz; - src->Negate = reg.negate ? NEGATE_XYZW : NEGATE_NONE; - src->RelAddr = 0; - /* Check that bitfield sizes aren't exceeded */ - assert(src->Index == reg.idx); + return load_input(p, attr, glsl_vec4_type()); } - -static void emit_dst( struct prog_dst_register *dst, - struct ureg reg, GLuint mask ) +static nir_variable * +register_output(struct tnl_program *p, gl_varying_slot slot, + const struct glsl_type *type) { - dst->File = reg.file; - dst->Index = reg.idx; - /* allow zero as a shorthand for xyzw */ - dst->WriteMask = mask ? mask : WRITEMASK_XYZW; - /* Check that bitfield sizes aren't exceeded */ - assert(dst->Index == reg.idx); + nir_variable *var = nir_get_variable_with_location(p->b->shader, nir_var_shader_out, + slot, type); + p->b->shader->info.outputs_written |= BITFIELD64_BIT(slot); + return var; } - -static void debug_insn( struct prog_instruction *inst, const char *fn, - GLuint line ) +static void +store_output_vec4_masked(struct tnl_program *p, gl_varying_slot slot, + nir_def *value, unsigned mask) { - if (DISASSEM) { - static const char *last_fn; - - if (fn != last_fn) { - last_fn = fn; - printf("%s:\n", fn); - } - - printf("%d:\t", line); - _mesa_print_instruction(inst); - } + assert(mask <= 0xf); + nir_variable *var = register_output(p, slot, glsl_vec4_type()); + nir_store_var(p->b, var, value, mask); } - -static void emit_op3fn(struct tnl_program *p, - enum prog_opcode op, - struct ureg dest, - GLuint mask, - struct ureg src0, - struct ureg src1, - struct ureg src2, - const char *fn, - GLuint line) +static void +store_output_vec4(struct tnl_program *p, gl_varying_slot slot, + nir_def *value) { - GLuint nr; - struct prog_instruction *inst; - - assert(p->program->arb.NumInstructions <= p->max_inst); - - if (p->program->arb.NumInstructions == p->max_inst) { - /* need to extend the program's instruction array */ - struct prog_instruction *newInst; - - /* double the size */ - p->max_inst *= 2; - - newInst = - rzalloc_array(p->program, struct prog_instruction, p->max_inst); - if (!newInst) { - _mesa_error(NULL, GL_OUT_OF_MEMORY, "vertex program build"); - return; - } - - _mesa_copy_instructions(newInst, p->program->arb.Instructions, - p->program->arb.NumInstructions); - - ralloc_free(p->program->arb.Instructions); - - p->program->arb.Instructions = newInst; - } - - nr = p->program->arb.NumInstructions++; - - inst = &p->program->arb.Instructions[nr]; - inst->Opcode = (enum prog_opcode) op; - - emit_arg( &inst->SrcReg[0], src0 ); - emit_arg( &inst->SrcReg[1], src1 ); - emit_arg( &inst->SrcReg[2], src2 ); - - emit_dst( &inst->DstReg, dest, mask ); - - debug_insn(inst, fn, line); + store_output_vec4_masked(p, slot, value, 0xf); } - -#define emit_op3(p, op, dst, mask, src0, src1, src2) \ - emit_op3fn(p, op, dst, mask, src0, src1, src2, __func__, __LINE__) - -#define emit_op2(p, op, dst, mask, src0, src1) \ - emit_op3fn(p, op, dst, mask, src0, src1, undef, __func__, __LINE__) - -#define emit_op1(p, op, dst, mask, src0) \ - emit_op3fn(p, op, dst, mask, src0, undef, undef, __func__, __LINE__) - - -static struct ureg make_temp( struct tnl_program *p, struct ureg reg ) +static void +store_output_float(struct tnl_program *p, gl_varying_slot slot, + nir_def *value) { - if (reg.file == PROGRAM_TEMPORARY && - !(p->temp_reserved & (1<<reg.idx))) - return reg; - else { - struct ureg temp = get_temp(p); - emit_op1(p, OPCODE_MOV, temp, 0, reg); - return temp; - } + nir_variable *var = register_output(p, slot, glsl_float_type()); + nir_store_var(p->b, var, value, 0x1); } -/* Currently no tracking performed of input/output/register size or - * active elements. Could be used to reduce these operations, as - * could the matrix type. - */ -static void emit_matrix_transform_vec4( struct tnl_program *p, - struct ureg dest, - const struct ureg *mat, - struct ureg src) +static nir_def * +emit_matrix_transform_vec4(nir_builder *b, + nir_def *mat[4], + nir_def *src) { - emit_op2(p, OPCODE_DP4, dest, WRITEMASK_X, src, mat[0]); - emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Y, src, mat[1]); - emit_op2(p, OPCODE_DP4, dest, WRITEMASK_Z, src, mat[2]); - emit_op2(p, OPCODE_DP4, dest, WRITEMASK_W, src, mat[3]); + return nir_vec4(b, + nir_fdot4(b, src, mat[0]), + nir_fdot4(b, src, mat[1]), + nir_fdot4(b, src, mat[2]), + nir_fdot4(b, src, mat[3])); } - -/* This version is much easier to implement if writemasks are not - * supported natively on the target or (like SSE), the target doesn't - * have a clean/obvious dotproduct implementation. - */ -static void emit_transpose_matrix_transform_vec4( struct tnl_program *p, - struct ureg dest, - const struct ureg *mat, - struct ureg src) +static nir_def * +emit_transpose_matrix_transform_vec4(nir_builder *b, + nir_def *mat[4], + nir_def *src) { - struct ureg tmp; - - if (dest.file != PROGRAM_TEMPORARY) - tmp = get_temp(p); - else - tmp = dest; - - emit_op2(p, OPCODE_MUL, tmp, 0, swizzle1(src,X), mat[0]); - emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Y), mat[1], tmp); - emit_op3(p, OPCODE_MAD, tmp, 0, swizzle1(src,Z), mat[2], tmp); - emit_op3(p, OPCODE_MAD, dest, 0, swizzle1(src,W), mat[3], tmp); - - if (dest.file != PROGRAM_TEMPORARY) - release_temp(p, tmp); + nir_def *result; + result = nir_fmul(b, nir_channel(b, src, 0), mat[0]); + result = nir_fmad(b, nir_channel(b, src, 1), mat[1], result); + result = nir_fmad(b, nir_channel(b, src, 2), mat[2], result); + result = nir_fmad(b, nir_channel(b, src, 3), mat[3], result); + return result; } - -static void emit_matrix_transform_vec3( struct tnl_program *p, - struct ureg dest, - const struct ureg *mat, - struct ureg src) +static nir_def * +emit_matrix_transform_vec3(nir_builder *b, + nir_def *mat[3], + nir_def *src) { - emit_op2(p, OPCODE_DP3, dest, WRITEMASK_X, src, mat[0]); - emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Y, src, mat[1]); - emit_op2(p, OPCODE_DP3, dest, WRITEMASK_Z, src, mat[2]); + return nir_vec3(b, + nir_fdot3(b, src, mat[0]), + nir_fdot3(b, src, mat[1]), + nir_fdot3(b, src, mat[2])); } - -static void emit_normalize_vec3( struct tnl_program *p, - struct ureg dest, - struct ureg src ) +static nir_def * +emit_normalize_vec3(nir_builder *b, nir_def *src) { - struct ureg tmp = get_temp(p); - emit_op2(p, OPCODE_DP3, tmp, WRITEMASK_X, src, src); - emit_op1(p, OPCODE_RSQ, tmp, WRITEMASK_X, tmp); - emit_op2(p, OPCODE_MUL, dest, 0, src, swizzle1(tmp, X)); - release_temp(p, tmp); + nir_def *tmp = nir_frsq(b, nir_fdot3(b, src, src)); + return nir_fmul(b, src, tmp); } - -static void emit_passthrough( struct tnl_program *p, - GLuint input, - GLuint output ) +static void +emit_passthrough(struct tnl_program *p, gl_vert_attrib attr, + gl_varying_slot varying) { - struct ureg out = register_output(p, output); - emit_op1(p, OPCODE_MOV, out, 0, register_input(p, input)); + nir_def *val = load_input_vec4(p, attr); + store_output_vec4(p, varying, val); } - -static struct ureg get_eye_position( struct tnl_program *p ) +static nir_def * +get_eye_position(struct tnl_program *p) { - if (is_undef(p->eye_position)) { - struct ureg pos = register_input( p, VERT_ATTRIB_POS ); - struct ureg modelview[4]; - - p->eye_position = reserve_temp(p); - + if (!p->eye_position) { + nir_def *pos = + load_input_vec4(p, VERT_ATTRIB_POS); if (p->mvp_with_dp4) { - register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, - modelview ); - - emit_matrix_transform_vec4(p, p->eye_position, modelview, pos); - } - else { - register_matrix_param5( p, STATE_MODELVIEW_MATRIX_TRANSPOSE, 0, 0, 3, - modelview ); - - emit_transpose_matrix_transform_vec4(p, p->eye_position, modelview, pos); + nir_def *modelview[4]; + load_state_mat4(p, modelview, STATE_MODELVIEW_MATRIX, 0); + p->eye_position = + emit_matrix_transform_vec4(p->b, modelview, pos); + } else { + nir_def *modelview[4]; + load_state_mat4(p, modelview, + STATE_MODELVIEW_MATRIX_TRANSPOSE, 0); + p->eye_position = + emit_transpose_matrix_transform_vec4(p->b, modelview, pos); } } return p->eye_position; } - -static struct ureg get_eye_position_z( struct tnl_program *p ) +static nir_def * +get_eye_position_z(struct tnl_program *p) { - if (!is_undef(p->eye_position)) - return swizzle1(p->eye_position, Z); - - if (is_undef(p->eye_position_z)) { - struct ureg pos = register_input( p, VERT_ATTRIB_POS ); - struct ureg modelview[4]; - - p->eye_position_z = reserve_temp(p); - - register_matrix_param5( p, STATE_MODELVIEW_MATRIX, 0, 0, 3, - modelview ); - - emit_op2(p, OPCODE_DP4, p->eye_position_z, 0, pos, modelview[2]); - } - - return p->eye_position_z; + return nir_channel(p->b, get_eye_position(p), 2); } - -static struct ureg get_eye_position_normalized( struct tnl_program *p ) +static nir_def * +get_eye_position_normalized(struct tnl_program *p) { - if (is_undef(p->eye_position_normalized)) { - struct ureg eye = get_eye_position(p); - p->eye_position_normalized = reserve_temp(p); - emit_normalize_vec3(p, p->eye_position_normalized, eye); + if (!p->eye_position_normalized) { + nir_def *eye = get_eye_position(p); + p->eye_position_normalized = emit_normalize_vec3(p->b, eye); } return p->eye_position_normalized; } - -static struct ureg get_transformed_normal( struct tnl_program *p ) +static nir_def * +get_transformed_normal(struct tnl_program *p) { - if (is_undef(p->transformed_normal) && + if (!p->transformed_normal && !p->state->need_eye_coords && !p->state->normalize && - !(p->state->need_eye_coords == p->state->rescale_normals)) - { - p->transformed_normal = register_input(p, VERT_ATTRIB_NORMAL ); - } - else if (is_undef(p->transformed_normal)) - { - struct ureg normal = register_input(p, VERT_ATTRIB_NORMAL ); - struct ureg mvinv[3]; - struct ureg transformed_normal = reserve_temp(p); + !(p->state->need_eye_coords == p->state->rescale_normals)) { + p->transformed_normal = + load_input(p, VERT_ATTRIB_NORMAL, + glsl_vector_type(GLSL_TYPE_FLOAT, 3)); + } else if (!p->transformed_normal) { + nir_def *normal = + load_input(p, VERT_ATTRIB_NORMAL, + glsl_vector_type(GLSL_TYPE_FLOAT, 3)); if (p->state->need_eye_coords) { - register_matrix_param5( p, STATE_MODELVIEW_MATRIX_INVTRANS, 0, 0, 2, - mvinv ); - - /* Transform to eye space: - */ - emit_matrix_transform_vec3( p, transformed_normal, mvinv, normal ); - normal = transformed_normal; + nir_def *mvinv[4]; + load_state_mat4(p, mvinv, STATE_MODELVIEW_MATRIX_INVTRANS, 0); + normal = emit_matrix_transform_vec3(p->b, mvinv, normal); } /* Normalize/Rescale: */ - if (p->state->normalize) { - emit_normalize_vec3( p, transformed_normal, normal ); - normal = transformed_normal; - } + if (p->state->normalize) + normal = emit_normalize_vec3(p->b, normal); else if (p->state->need_eye_coords == p->state->rescale_normals) { - /* This is already adjusted for eye/non-eye rendering: - */ - struct ureg rescale = register_param1(p, STATE_NORMAL_SCALE); - - emit_op2( p, OPCODE_MUL, transformed_normal, 0, normal, rescale ); - normal = transformed_normal; + nir_def *scale = + load_state_var(p, STATE_NORMAL_SCALE, 0, 0, 0, + glsl_float_type()); + normal = nir_fmul(p->b, normal, scale); } - assert(normal.file == PROGRAM_TEMPORARY); p->transformed_normal = normal; } return p->transformed_normal; } - -static void build_hpos( struct tnl_program *p ) -{ - struct ureg pos = register_input( p, VERT_ATTRIB_POS ); - struct ureg hpos = register_output( p, VARYING_SLOT_POS ); - struct ureg mvp[4]; - - if (p->mvp_with_dp4) { - register_matrix_param5( p, STATE_MVP_MATRIX, 0, 0, 3, - mvp ); - emit_matrix_transform_vec4( p, hpos, mvp, pos ); - } - else { - register_matrix_param5( p, STATE_MVP_MATRIX_TRANSPOSE, 0, 0, 3, - mvp ); - emit_transpose_matrix_transform_vec4( p, hpos, mvp, pos ); - } -} - - static GLuint material_attrib( GLuint side, GLuint property ) { switch (property) { @@ -859,7 +559,7 @@ static void set_material_flags( struct tnl_program *p ) if (p->state->varying_vp_inputs & VERT_BIT_COLOR0) { p->materials = - p->color_materials = p->state->light_color_material_mask; + p->color_materials = p->state->light_color_material_mask; } p->materials |= ((p->state->varying_vp_inputs & VERT_BIT_MAT_ALL) @@ -867,26 +567,27 @@ static void set_material_flags( struct tnl_program *p ) } -static struct ureg get_material( struct tnl_program *p, GLuint side, - GLuint property ) +static nir_def * +get_material(struct tnl_program *p, GLuint side, + GLuint property) { GLuint attrib = material_attrib(side, property); if (p->color_materials & (1<<attrib)) - return register_input(p, VERT_ATTRIB_COLOR0); + return load_input_vec4(p, VERT_ATTRIB_COLOR0); else if (p->materials & (1<<attrib)) { /* Put material values in the GENERIC slots -- they are not used * for anything in fixed function mode. */ - return register_input( p, VERT_ATTRIB_MAT(attrib) ); + return load_input_vec4(p, VERT_ATTRIB_MAT(attrib)); + } else { + return load_state_vec4(p, STATE_MATERIAL, attrib, 0, 0); } - else - return register_param2(p, STATE_MATERIAL, attrib); } #define SCENE_COLOR_BITS(side) (( MAT_BIT_FRONT_EMISSION | \ - MAT_BIT_FRONT_AMBIENT | \ - MAT_BIT_FRONT_DIFFUSE) << (side)) + MAT_BIT_FRONT_AMBIENT | \ + MAT_BIT_FRONT_DIFFUSE) << (side)) /** @@ -900,121 +601,150 @@ static struct ureg get_material( struct tnl_program *p, GLuint side, * lift it out of the main loop. That way the programs created here * would be independent of the vertex_buffer details. */ -static struct ureg get_scenecolor( struct tnl_program *p, GLuint side ) +static nir_def * +get_scenecolor(struct tnl_program *p, GLuint side) { if (p->materials & SCENE_COLOR_BITS(side)) { - struct ureg lm_ambient = register_param1(p, STATE_LIGHTMODEL_AMBIENT); - struct ureg material_emission = get_material(p, side, STATE_EMISSION); - struct ureg material_ambient = get_material(p, side, STATE_AMBIENT); - struct ureg material_diffuse = get_material(p, side, STATE_DIFFUSE); - struct ureg tmp = make_temp(p, material_diffuse); - emit_op3(p, OPCODE_MAD, tmp, WRITEMASK_XYZ, lm_ambient, - material_ambient, material_emission); - return tmp; + nir_def *lm_ambient = + load_state_vec4(p, STATE_LIGHTMODEL_AMBIENT, 0, 0, 0); + nir_def *material_emission = + get_material(p, side, STATE_EMISSION); + nir_def *material_ambient = + get_material(p, side, STATE_AMBIENT); + nir_def *material_diffuse = + get_material(p, side, STATE_DIFFUSE); + + // rgb: material_emission + material_ambient * lm_ambient + // alpha: material_diffuse.a + return nir_vector_insert_imm(p->b, nir_fmad(p->b, + lm_ambient, + material_ambient, + material_emission), + nir_channel(p->b, + material_diffuse, + 3), + 3); } else - return register_param2( p, STATE_LIGHTMODEL_SCENECOLOR, side ); + return load_state_vec4(p, STATE_LIGHTMODEL_SCENECOLOR, side, 0, 0); } - -static struct ureg get_lightprod( struct tnl_program *p, GLuint light, - GLuint side, GLuint property ) +static nir_def * +get_lightprod(struct tnl_program *p, GLuint light, + GLuint side, GLuint property, bool *is_state_light) { GLuint attrib = material_attrib(side, property); if (p->materials & (1<<attrib)) { - struct ureg light_value = - register_param3(p, STATE_LIGHT, light, property); - struct ureg material_value = get_material(p, side, property); - struct ureg tmp = get_temp(p); - emit_op2(p, OPCODE_MUL, tmp, 0, light_value, material_value); - return tmp; + *is_state_light = true; + return load_state_vec4(p, STATE_LIGHT, light, property, 0); + } else { + *is_state_light = false; + return load_state_vec4(p, STATE_LIGHTPROD, light, attrib, 0); } - else - return register_param3(p, STATE_LIGHTPROD, light, attrib); } -static struct ureg calculate_light_attenuation( struct tnl_program *p, - GLuint i, - struct ureg VPpli, - struct ureg dist ) +static nir_def * +calculate_light_attenuation(struct tnl_program *p, + GLuint i, + nir_def *VPpli, + nir_def *dist) { - struct ureg attenuation = register_param3(p, STATE_LIGHT, i, - STATE_ATTENUATION); - struct ureg att = undef; + nir_def *attenuation = NULL; + nir_def *att = NULL; /* Calculate spot attenuation: */ if (!p->state->unit[i].light_spotcutoff_is_180) { - struct ureg spot_dir_norm = register_param2(p, STATE_LIGHT_SPOT_DIR_NORMALIZED, i); - struct ureg spot = get_temp(p); - struct ureg slt = get_temp(p); - - att = get_temp(p); - - emit_op2(p, OPCODE_DP3, spot, 0, negate(VPpli), spot_dir_norm); - emit_op2(p, OPCODE_SLT, slt, 0, swizzle1(spot_dir_norm,W), spot); - emit_op1(p, OPCODE_ABS, spot, 0, spot); - emit_op2(p, OPCODE_POW, spot, 0, spot, swizzle1(attenuation, W)); - emit_op2(p, OPCODE_MUL, att, 0, slt, spot); - - release_temp(p, spot); - release_temp(p, slt); + nir_def *spot_dir_norm = + load_state_vec4(p, STATE_LIGHT_SPOT_DIR_NORMALIZED, i, 0, 0); + attenuation = + load_state_vec4(p, STATE_LIGHT, i, STATE_ATTENUATION, 0); + + nir_def *spot = nir_fdot3(p->b, nir_fneg(p->b, VPpli), + spot_dir_norm); + nir_def *cmp = nir_flt(p->b, nir_channel(p->b, spot_dir_norm, 3), + spot); + spot = nir_fpow(p->b, spot, nir_channel(p->b, attenuation, 3)); + att = nir_bcsel(p->b, cmp, spot, nir_imm_zero(p->b, 1, 32)); } /* Calculate distance attenuation(See formula (2.4) at glspec 2.1 page 62): * * Skip the calucation when _dist_ is undefined(light_eyepos3_is_zero) */ - if (p->state->unit[i].light_attenuated && !is_undef(dist)) { - if (is_undef(att)) - att = get_temp(p); - /* 1/d,d,d,1/d */ - emit_op1(p, OPCODE_RCP, dist, WRITEMASK_YZ, dist); - /* 1,d,d*d,1/d */ - emit_op2(p, OPCODE_MUL, dist, WRITEMASK_XZ, dist, swizzle1(dist,Y)); - /* 1/dist-atten */ - emit_op2(p, OPCODE_DP3, dist, 0, attenuation, dist); - - if (!p->state->unit[i].light_spotcutoff_is_180) { - /* dist-atten */ - emit_op1(p, OPCODE_RCP, dist, 0, dist); - /* spot-atten * dist-atten */ - emit_op2(p, OPCODE_MUL, att, 0, dist, att); - } - else { - /* dist-atten */ - emit_op1(p, OPCODE_RCP, att, 0, dist); + if (p->state->unit[i].light_attenuated && dist) { + if (!attenuation) { + attenuation = load_state_vec4(p, STATE_LIGHT, i, + STATE_ATTENUATION, 0); } + + /* dist is the reciprocal of ||VP|| used in the distance + * attenuation formula. So need to get the reciprocal of dist first + * before applying to the formula. + */ + dist = nir_frcp(p->b, dist); + + /* 1, d, d*d */ + nir_def *tmp = nir_vec3(p->b, + nir_imm_float(p->b, 1.0f), + dist, + nir_fmul(p->b, dist, dist) + ); + tmp = nir_frcp(p->b, nir_fdot3(p->b, tmp, attenuation)); + + if (!p->state->unit[i].light_spotcutoff_is_180) + return nir_fmul(p->b, tmp, att); + return tmp; } return att; } +static nir_def * +emit_lit(nir_builder *b, + nir_def *src) +{ + nir_def *zero = nir_imm_zero(b, 1, 32); + nir_def *one = nir_imm_float(b, 1.0f); + nir_def *src_x = nir_channel(b, src, 0); + nir_def *src_y = nir_channel(b, src, 1); + nir_def *src_w = nir_channel(b, src, 3); + + nir_def *wclamp = nir_fmax(b, nir_fmin(b, src_w, + nir_imm_float(b, 128.0f)), + nir_imm_float(b, -128.0f)); + nir_def *pow = nir_fpow(b, nir_fmax(b, src_y, zero), wclamp); + + return nir_vec4(b, + one, + nir_fmax(b, src_x, zero), + nir_bcsel(b, + nir_fge(b, zero, src_x), + zero, + pow), + one); +} /** * Compute: * lit.y = MAX(0, dots.x) * lit.z = SLT(0, dots.x) */ -static void emit_degenerate_lit( struct tnl_program *p, - struct ureg lit, - struct ureg dots ) +static nir_def * +emit_degenerate_lit(nir_builder *b, + nir_def *dots) { - struct ureg id = get_identity_param(p); /* id = {0,0,0,1} */ + nir_def *id = nir_imm_vec4(b, 0.0f, 0.0f, 0.0f, 1.0f); /* Note that lit.x & lit.w will not be examined. Note also that * dots.xyzw == dots.xxxx. */ - /* MAX lit, id, dots; - */ - emit_op2(p, OPCODE_MAX, lit, WRITEMASK_XYZW, id, dots); - - /* result[2] = (in > 0 ? 1 : 0) - * SLT lit.z, id.z, dots; # lit.z = (0 < dots.z) ? 1 : 0 - */ - emit_op2(p, OPCODE_SLT, lit, WRITEMASK_Z, swizzle1(id,Z), dots); + nir_def *zero = nir_imm_zero(b, 1, 32); + nir_def *dots_x = nir_channel(b, dots, 0); + nir_def *tmp = nir_fmax(b, id, dots); + return nir_vector_insert_imm(b, tmp, nir_slt(b, zero, dots_x), 2); } @@ -1026,12 +756,12 @@ static void build_lighting( struct tnl_program *p ) { const GLboolean twoside = p->state->light_twoside; const GLboolean separate = p->state->separate_specular; - GLuint nr_lights = 0, count = 0; - struct ureg normal = get_transformed_normal(p); - struct ureg lit = get_temp(p); - struct ureg dots = get_temp(p); - struct ureg _col0 = undef, _col1 = undef; - struct ureg _bfc0 = undef, _bfc1 = undef; + GLuint nr_lights = 0; + nir_def *lit = NULL; + nir_def *dots = nir_imm_zero(p->b, 4, 32); + nir_def *normal = get_transformed_normal(p); + nir_def *_col0 = NULL, *_col1 = NULL; + nir_def *_bfc0 = NULL, *_bfc1 = NULL; GLuint i; /* @@ -1044,22 +774,20 @@ static void build_lighting( struct tnl_program *p ) for (i = 0; i < MAX_LIGHTS; i++) if (p->state->unit[i].light_enabled) - nr_lights++; + nr_lights++; set_material_flags(p); { if (!p->state->material_shininess_is_zero) { - struct ureg shininess = get_material(p, 0, STATE_SHININESS); - emit_op1(p, OPCODE_MOV, dots, WRITEMASK_W, swizzle1(shininess,X)); - release_temp(p, shininess); + nir_def *shininess = get_material(p, 0, STATE_SHININESS); + nir_def *tmp = nir_channel(p->b, shininess, 0); + dots = nir_vector_insert_imm(p->b, dots, tmp, 3); } - _col0 = make_temp(p, get_scenecolor(p, 0)); + _col0 = get_scenecolor(p, 0); if (separate) - _col1 = make_temp(p, get_identity_param(p)); - else - _col1 = _col0; + _col1 = nir_imm_vec4(p->b, 0.0f, 0.0f, 0.0f, 1.0f); } if (twoside) { @@ -1067,65 +795,60 @@ static void build_lighting( struct tnl_program *p ) /* Note that we negate the back-face specular exponent here. * The negation will be un-done later in the back-face code below. */ - struct ureg shininess = get_material(p, 1, STATE_SHININESS); - emit_op1(p, OPCODE_MOV, dots, WRITEMASK_Z, - negate(swizzle1(shininess,X))); - release_temp(p, shininess); + nir_def *shininess = get_material(p, 1, STATE_SHININESS); + nir_def *tmp = nir_channel(p->b, shininess, 0); + tmp = nir_fneg(p->b, tmp); + dots = nir_vector_insert_imm(p->b, dots, tmp, 2); } - _bfc0 = make_temp(p, get_scenecolor(p, 1)); + _bfc0 = get_scenecolor(p, 1); if (separate) - _bfc1 = make_temp(p, get_identity_param(p)); - else - _bfc1 = _bfc0; + _bfc1 = nir_imm_vec4(p->b, 0.0f, 0.0f, 0.0f, 1.0f); } /* If no lights, still need to emit the scenecolor. */ - { - struct ureg res0 = register_output( p, VARYING_SLOT_COL0 ); - emit_op1(p, OPCODE_MOV, res0, 0, _col0); - } + store_output_vec4(p, VARYING_SLOT_COL0, _col0); - if (separate) { - struct ureg res1 = register_output( p, VARYING_SLOT_COL1 ); - emit_op1(p, OPCODE_MOV, res1, 0, _col1); - } + if (separate) + store_output_vec4(p, VARYING_SLOT_COL1, _col1); - if (twoside) { - struct ureg res0 = register_output( p, VARYING_SLOT_BFC0 ); - emit_op1(p, OPCODE_MOV, res0, 0, _bfc0); - } + if (twoside) + store_output_vec4(p, VARYING_SLOT_BFC0, _bfc0); - if (twoside && separate) { - struct ureg res1 = register_output( p, VARYING_SLOT_BFC1 ); - emit_op1(p, OPCODE_MOV, res1, 0, _bfc1); - } + if (twoside && separate) + store_output_vec4(p, VARYING_SLOT_BFC1, _bfc1); - if (nr_lights == 0) { - release_temps(p); + if (nr_lights == 0) return; - } /* Declare light products first to place them sequentially next to each * other for optimal constant uploads. */ - struct ureg lightprod_front[MAX_LIGHTS][3]; - struct ureg lightprod_back[MAX_LIGHTS][3]; + nir_def *lightprod_front[MAX_LIGHTS][3]; + nir_def *lightprod_back[MAX_LIGHTS][3]; + bool lightprod_front_is_state_light[MAX_LIGHTS][3]; + bool lightprod_back_is_state_light[MAX_LIGHTS][3]; for (i = 0; i < MAX_LIGHTS; i++) { if (p->state->unit[i].light_enabled) { - lightprod_front[i][0] = get_lightprod(p, i, 0, STATE_AMBIENT); + lightprod_front[i][0] = get_lightprod(p, i, 0, STATE_AMBIENT, + &lightprod_front_is_state_light[i][0]); if (twoside) - lightprod_back[i][0] = get_lightprod(p, i, 1, STATE_AMBIENT); + lightprod_back[i][0] = get_lightprod(p, i, 1, STATE_AMBIENT, + &lightprod_back_is_state_light[i][0]); - lightprod_front[i][1] = get_lightprod(p, i, 0, STATE_DIFFUSE); + lightprod_front[i][1] = get_lightprod(p, i, 0, STATE_DIFFUSE, + &lightprod_front_is_state_light[i][1]); if (twoside) - lightprod_back[i][1] = get_lightprod(p, i, 1, STATE_DIFFUSE); + lightprod_back[i][1] = get_lightprod(p, i, 1, STATE_DIFFUSE, + &lightprod_back_is_state_light[i][1]); - lightprod_front[i][2] = get_lightprod(p, i, 0, STATE_SPECULAR); + lightprod_front[i][2] = get_lightprod(p, i, 0, STATE_SPECULAR, + &lightprod_front_is_state_light[i][2]); if (twoside) - lightprod_back[i][2] = get_lightprod(p, i, 1, STATE_SPECULAR); + lightprod_back[i][2] = get_lightprod(p, i, 1, STATE_SPECULAR, + &lightprod_back_is_state_light[i][2]); } } @@ -1135,270 +858,239 @@ static void build_lighting( struct tnl_program *p ) for (i = 0; i < MAX_LIGHTS; i++) { if (p->state->unit[i].light_enabled) { if (p->state->unit[i].light_eyepos3_is_zero) - register_param2(p, STATE_LIGHT_POSITION_NORMALIZED, i); + register_state_var(p, STATE_LIGHT_POSITION_NORMALIZED, + i, 0, 0, + glsl_vector_type(GLSL_TYPE_FLOAT, 3)); else - register_param2(p, STATE_LIGHT_POSITION, i); + register_state_var(p, STATE_LIGHT_POSITION, i, 0, 0, + glsl_vec4_type()); } } for (i = 0; i < MAX_LIGHTS; i++) { - if (p->state->unit[i].light_enabled) - register_param3(p, STATE_LIGHT, i, STATE_ATTENUATION); + if (p->state->unit[i].light_enabled && + (!p->state->unit[i].light_spotcutoff_is_180 || + (p->state->unit[i].light_attenuated && + !p->state->unit[i].light_eyepos3_is_zero))) + register_state_var(p, STATE_LIGHT, i, STATE_ATTENUATION, 0, + glsl_vec4_type()); } for (i = 0; i < MAX_LIGHTS; i++) { if (p->state->unit[i].light_enabled) { - struct ureg half = undef; - struct ureg att = undef, VPpli = undef; - struct ureg dist = undef; + nir_def *half = NULL; + nir_def *att = NULL, *VPpli = NULL; + nir_def *dist = NULL; - count++; if (p->state->unit[i].light_eyepos3_is_zero) { - VPpli = register_param2(p, STATE_LIGHT_POSITION_NORMALIZED, i); + VPpli = load_state_var(p, STATE_LIGHT_POSITION_NORMALIZED, + i, 0, 0, + glsl_vector_type(GLSL_TYPE_FLOAT, 3)); } else { - struct ureg Ppli = register_param2(p, STATE_LIGHT_POSITION, i); - struct ureg V = get_eye_position(p); - - VPpli = get_temp(p); - dist = get_temp(p); + nir_def *Ppli = + load_state_vec4(p, STATE_LIGHT_POSITION, i, 0, 0); - /* Calculate VPpli vector - */ - emit_op2(p, OPCODE_SUB, VPpli, 0, Ppli, V); + nir_def *V = get_eye_position(p); + VPpli = nir_fsub(p->b, Ppli, V); /* Normalize VPpli. The dist value also used in * attenuation below. */ - emit_op2(p, OPCODE_DP3, dist, 0, VPpli, VPpli); - emit_op1(p, OPCODE_RSQ, dist, 0, dist); - emit_op2(p, OPCODE_MUL, VPpli, 0, VPpli, dist); + dist = nir_frsq(p->b, nir_fdot3(p->b, VPpli, VPpli)); + VPpli = nir_fmul(p->b, VPpli, dist); } /* Calculate attenuation: */ att = calculate_light_attenuation(p, i, VPpli, dist); - release_temp(p, dist); - /* Calculate viewer direction, or use infinite viewer: - */ + /* Calculate viewer direction, or use infinite viewer: + */ if (!p->state->material_shininess_is_zero) { if (p->state->light_local_viewer) { - struct ureg eye_hat = get_eye_position_normalized(p); - half = get_temp(p); - emit_op2(p, OPCODE_SUB, half, 0, VPpli, eye_hat); - emit_normalize_vec3(p, half, half); + nir_def *eye_hat = get_eye_position_normalized(p); + half = emit_normalize_vec3(p->b, + nir_fsub(p->b, VPpli, eye_hat)); } else if (p->state->unit[i].light_eyepos3_is_zero) { - half = register_param2(p, STATE_LIGHT_HALF_VECTOR, i); + half = + load_state_var(p, STATE_LIGHT_HALF_VECTOR, + i, 0, 0, + glsl_vector_type(GLSL_TYPE_FLOAT, 3)); } else { - struct ureg z_dir = swizzle(get_identity_param(p),X,Y,W,Z); - half = get_temp(p); - emit_op2(p, OPCODE_ADD, half, 0, VPpli, z_dir); - emit_normalize_vec3(p, half, half); + nir_def *tmp = + nir_fadd(p->b, + VPpli, + nir_imm_vec3(p->b, 0.0f, 0.0f, 1.0f)); + half = emit_normalize_vec3(p->b, tmp); } - } + } - /* Calculate dot products: - */ + /* Calculate dot products: + */ + nir_def *dot = nir_fdot3(p->b, normal, VPpli); if (p->state->material_shininess_is_zero) { - emit_op2(p, OPCODE_DP3, dots, 0, normal, VPpli); - } - else { - emit_op2(p, OPCODE_DP3, dots, WRITEMASK_X, normal, VPpli); - emit_op2(p, OPCODE_DP3, dots, WRITEMASK_Y, normal, half); + dots = nir_replicate(p->b, dot, 4); + } else { + dots = nir_vector_insert_imm(p->b, dots, dot, 0); + dot = nir_fdot3(p->b, normal, half); + dots = nir_vector_insert_imm(p->b, dots, dot, 1); } - /* Front face lighting: - */ - { - struct ureg ambient = lightprod_front[i][0]; - struct ureg diffuse = lightprod_front[i][1]; - struct ureg specular = lightprod_front[i][2]; - struct ureg res0, res1; - GLuint mask0, mask1; - - if (count == nr_lights) { - if (separate) { - mask0 = WRITEMASK_XYZ; - mask1 = WRITEMASK_XYZ; - res0 = register_output( p, VARYING_SLOT_COL0 ); - res1 = register_output( p, VARYING_SLOT_COL1 ); - } - else { - mask0 = 0; - mask1 = WRITEMASK_XYZ; - res0 = _col0; - res1 = register_output( p, VARYING_SLOT_COL0 ); - } - } - else { - mask0 = 0; - mask1 = 0; - res0 = _col0; - res1 = _col1; - } - - if (!is_undef(att)) { - /* light is attenuated by distance */ - emit_op1(p, OPCODE_LIT, lit, 0, dots); - emit_op2(p, OPCODE_MUL, lit, 0, lit, att); - emit_op3(p, OPCODE_MAD, _col0, 0, swizzle1(lit,X), ambient, _col0); + /* Front face lighting: + */ + { + /* Transform STATE_LIGHT into STATE_LIGHTPROD if needed. This isn't done in + * get_lightprod to avoid using too many temps. + */ + for (int j = 0; j < 3; j++) { + if (lightprod_front_is_state_light[i][j]) { + nir_def *material = + get_material(p, 0, STATE_AMBIENT + j); + lightprod_front[i][j] = + nir_fmul(p->b, lightprod_front[i][j], material); + } } - else if (!p->state->material_shininess_is_zero) { + + nir_def *ambient = lightprod_front[i][0]; + nir_def *diffuse = lightprod_front[i][1]; + nir_def *specular = lightprod_front[i][2]; + + if (att) { + /* light is attenuated by distance */ + lit = emit_lit(p->b, dots); + lit = nir_fmul(p->b, lit, att); + _col0 = nir_fmad(p->b, nir_channel(p->b, lit, 0), ambient, _col0); + } else if (!p->state->material_shininess_is_zero) { /* there's a non-zero specular term */ - emit_op1(p, OPCODE_LIT, lit, 0, dots); - emit_op2(p, OPCODE_ADD, _col0, 0, ambient, _col0); - } - else { + lit = emit_lit(p->b, dots); + _col0 = nir_fadd(p->b, ambient, _col0); + } else { /* no attenutation, no specular */ - emit_degenerate_lit(p, lit, dots); - emit_op2(p, OPCODE_ADD, _col0, 0, ambient, _col0); + lit = emit_degenerate_lit(p->b, dots); + _col0 = nir_fadd(p->b, ambient, _col0); + } + + _col0 = nir_fmad(p->b, nir_channel(p->b, lit, 1), + diffuse, _col0); + if (separate) + _col1 = nir_fmad(p->b, nir_channel(p->b, lit, 2), + specular, _col1); + else + _col0 = nir_fmad(p->b, nir_channel(p->b, lit, 2), + specular, _col0); + } + /* Back face lighting: + */ + nir_def *old_dots = dots; + if (twoside) { + /* Transform STATE_LIGHT into STATE_LIGHTPROD if needed. This isn't done in + * get_lightprod to avoid using too many temps. + */ + for (int j = 0; j < 3; j++) { + if (lightprod_back_is_state_light[i][j]) { + nir_def *material = + get_material(p, 1, STATE_AMBIENT + j); + lightprod_back[i][j] = + nir_fmul(p->b, lightprod_back[i][j], material); + } } - emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _col0); - emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _col1); - - release_temp(p, ambient); - release_temp(p, diffuse); - release_temp(p, specular); - } - - /* Back face lighting: - */ - if (twoside) { - struct ureg ambient = lightprod_back[i][0]; - struct ureg diffuse = lightprod_back[i][1]; - struct ureg specular = lightprod_back[i][2]; - struct ureg res0, res1; - GLuint mask0, mask1; - - if (count == nr_lights) { - if (separate) { - mask0 = WRITEMASK_XYZ; - mask1 = WRITEMASK_XYZ; - res0 = register_output( p, VARYING_SLOT_BFC0 ); - res1 = register_output( p, VARYING_SLOT_BFC1 ); - } - else { - mask0 = 0; - mask1 = WRITEMASK_XYZ; - res0 = _bfc0; - res1 = register_output( p, VARYING_SLOT_BFC0 ); - } - } - else { - res0 = _bfc0; - res1 = _bfc1; - mask0 = 0; - mask1 = 0; - } + nir_def *ambient = lightprod_back[i][0]; + nir_def *diffuse = lightprod_back[i][1]; + nir_def *specular = lightprod_back[i][2]; /* For the back face we need to negate the X and Y component * dot products. dots.Z has the negated back-face specular * exponent. We swizzle that into the W position. This * negation makes the back-face specular term positive again. */ - dots = negate(swizzle(dots,X,Y,W,Z)); + unsigned swiz_xywz[] = {0, 1, 3, 2}; + nir_def *dots = + nir_fneg(p->b, nir_swizzle(p->b, old_dots, swiz_xywz, 4)); - if (!is_undef(att)) { - emit_op1(p, OPCODE_LIT, lit, 0, dots); - emit_op2(p, OPCODE_MUL, lit, 0, lit, att); - emit_op3(p, OPCODE_MAD, _bfc0, 0, swizzle1(lit,X), ambient, _bfc0); - } - else if (!p->state->material_shininess_is_zero) { - emit_op1(p, OPCODE_LIT, lit, 0, dots); - emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); /**/ - } - else { - emit_degenerate_lit(p, lit, dots); - emit_op2(p, OPCODE_ADD, _bfc0, 0, ambient, _bfc0); + if (att) { + /* light is attenuated by distance */ + lit = emit_lit(p->b, dots); + lit = nir_fmul(p->b, lit, att); + _bfc0 = nir_fmad(p->b, nir_channel(p->b, lit, 0), ambient, _bfc0); + } else if (!p->state->material_shininess_is_zero) { + /* there's a non-zero specular term */ + lit = emit_lit(p->b, dots); + _bfc0 = nir_fadd(p->b, ambient, _bfc0); + } else { + /* no attenutation, no specular */ + lit = emit_degenerate_lit(p->b, dots); + _bfc0 = nir_fadd(p->b, ambient, _bfc0); } - emit_op3(p, OPCODE_MAD, res0, mask0, swizzle1(lit,Y), diffuse, _bfc0); - emit_op3(p, OPCODE_MAD, res1, mask1, swizzle1(lit,Z), specular, _bfc1); - /* restore dots to its original state for subsequent lights - * by negating and swizzling again. - */ - dots = negate(swizzle(dots,X,Y,W,Z)); - - release_temp(p, ambient); - release_temp(p, diffuse); - release_temp(p, specular); - } - - release_temp(p, half); - release_temp(p, VPpli); - release_temp(p, att); + _bfc0 = nir_fmad(p->b, nir_channel(p->b, lit, 1), + diffuse, _bfc0); + if (separate) + _bfc1 = nir_fmad(p->b, nir_channel(p->b, lit, 2), + specular, _bfc1); + else + _bfc0 = nir_fmad(p->b, nir_channel(p->b, lit, 2), + specular, _bfc0); + } } } - release_temps( p ); + store_output_vec4_masked(p, VARYING_SLOT_COL0, _col0, 0x7); + if (separate) + store_output_vec4_masked(p, VARYING_SLOT_COL1, _col1, 0x7); + + if (twoside) { + store_output_vec4_masked(p, VARYING_SLOT_BFC0, _bfc0, 0x7); + if (separate) + store_output_vec4_masked(p, VARYING_SLOT_BFC1, _bfc1, 0x7); + } } static void build_fog( struct tnl_program *p ) { - struct ureg fog = register_output(p, VARYING_SLOT_FOGC); - struct ureg input; - + nir_def *fog; switch (p->state->fog_distance_mode) { - case FDM_EYE_RADIAL: { /* Z = sqrt(Xe*Xe + Ye*Ye + Ze*Ze) */ - struct ureg tmp = get_temp(p); - input = get_eye_position(p); - emit_op2(p, OPCODE_DP3, tmp, WRITEMASK_X, input, input); - emit_op1(p, OPCODE_RSQ, tmp, WRITEMASK_X, tmp); - emit_op1(p, OPCODE_RCP, fog, WRITEMASK_X, tmp); + case FDM_EYE_RADIAL: + /* Z = sqrt(Xe*Xe + Ye*Ye + Ze*Ze) */ + fog = nir_fast_length(p->b, + nir_trim_vector(p->b, get_eye_position(p), 3)); break; - } case FDM_EYE_PLANE: /* Z = Ze */ - input = get_eye_position_z(p); - emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input); + fog = get_eye_position_z(p); break; case FDM_EYE_PLANE_ABS: /* Z = abs(Ze) */ - input = get_eye_position_z(p); - emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input); + fog = nir_fabs(p->b, get_eye_position_z(p)); break; case FDM_FROM_ARRAY: - input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); - emit_op1(p, OPCODE_ABS, fog, WRITEMASK_X, input); + fog = load_input(p, VERT_ATTRIB_FOG, glsl_float_type()); break; default: - assert(!"Bad fog mode in build_fog()"); - break; + unreachable("Bad fog mode in build_fog()"); } - emit_op1(p, OPCODE_MOV, fog, WRITEMASK_YZW, get_identity_param(p)); + store_output_float(p, VARYING_SLOT_FOGC, fog); } -static void build_reflect_texgen( struct tnl_program *p, - struct ureg dest, - GLuint writemask ) +static nir_def * +build_reflect_texgen(struct tnl_program *p) { - struct ureg normal = get_transformed_normal(p); - struct ureg eye_hat = get_eye_position_normalized(p); - struct ureg tmp = get_temp(p); - + nir_def *normal = get_transformed_normal(p); + nir_def *eye_hat = get_eye_position_normalized(p); /* n.u */ - emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); + nir_def *tmp = nir_fdot3(p->b, normal, eye_hat); /* 2n.u */ - emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); + tmp = nir_fadd(p->b, tmp, tmp); /* (-2n.u)n + u */ - emit_op3(p, OPCODE_MAD, dest, writemask, negate(tmp), normal, eye_hat); - - release_temp(p, tmp); + return nir_fmad(p->b, nir_fneg(p->b, tmp), normal, eye_hat); } -static void build_sphere_texgen( struct tnl_program *p, - struct ureg dest, - GLuint writemask ) +static nir_def * +build_sphere_texgen(struct tnl_program *p) { - struct ureg normal = get_transformed_normal(p); - struct ureg eye_hat = get_eye_position_normalized(p); - struct ureg tmp = get_temp(p); - struct ureg half = register_scalar_const(p, .5); - struct ureg r = get_temp(p); - struct ureg inv_m = get_temp(p); - struct ureg id = get_identity_param(p); + nir_def *normal = get_transformed_normal(p); + nir_def *eye_hat = get_eye_position_normalized(p); /* Could share the above calculations, but it would be * a fairly odd state for someone to set (both sphere and @@ -1409,28 +1101,23 @@ static void build_sphere_texgen( struct tnl_program *p, */ /* n.u */ - emit_op2(p, OPCODE_DP3, tmp, 0, normal, eye_hat); + nir_def *tmp = nir_fdot3(p->b, normal, eye_hat); /* 2n.u */ - emit_op2(p, OPCODE_ADD, tmp, 0, tmp, tmp); + tmp = nir_fadd(p->b, tmp, tmp); /* (-2n.u)n + u */ - emit_op3(p, OPCODE_MAD, r, 0, negate(tmp), normal, eye_hat); + nir_def *r = nir_fmad(p->b, nir_fneg(p->b, tmp), normal, eye_hat); /* r + 0,0,1 */ - emit_op2(p, OPCODE_ADD, tmp, 0, r, swizzle(id,X,Y,W,Z)); + tmp = nir_fadd(p->b, r, nir_imm_vec4(p->b, 0.0f, 0.0f, 1.0f, 0.0f)); /* rx^2 + ry^2 + (rz+1)^2 */ - emit_op2(p, OPCODE_DP3, tmp, 0, tmp, tmp); + tmp = nir_fdot3(p->b, tmp, tmp); /* 2/m */ - emit_op1(p, OPCODE_RSQ, tmp, 0, tmp); + tmp = nir_frsq(p->b, tmp); /* 1/m */ - emit_op2(p, OPCODE_MUL, inv_m, 0, tmp, half); + nir_def *inv_m = nir_fmul_imm(p->b, tmp, 0.5f); /* r/m + 1/2 */ - emit_op3(p, OPCODE_MAD, dest, writemask, r, inv_m, half); - - release_temp(p, tmp); - release_temp(p, r); - release_temp(p, inv_m); + return nir_fmad(p->b, r, inv_m, nir_imm_float(p->b, 0.5f)); } - static void build_texture_transform( struct tnl_program *p ) { GLuint i, j; @@ -1438,112 +1125,105 @@ static void build_texture_transform( struct tnl_program *p ) for (i = 0; i < MAX_TEXTURE_COORD_UNITS; i++) { if (!(p->state->fragprog_inputs_read & VARYING_BIT_TEX(i))) - continue; + continue; if (p->state->unit[i].coord_replace) - continue; - - if (p->state->unit[i].texgen_enabled || - p->state->unit[i].texmat_enabled) { - - GLuint texmat_enabled = p->state->unit[i].texmat_enabled; - struct ureg out = register_output(p, VARYING_SLOT_TEX0 + i); - struct ureg out_texgen = undef; - - if (p->state->unit[i].texgen_enabled) { - GLuint copy_mask = 0; - GLuint sphere_mask = 0; - GLuint reflect_mask = 0; - GLuint normal_mask = 0; - GLuint modes[4]; - - if (texmat_enabled) - out_texgen = get_temp(p); - else - out_texgen = out; - - modes[0] = p->state->unit[i].texgen_mode0; - modes[1] = p->state->unit[i].texgen_mode1; - modes[2] = p->state->unit[i].texgen_mode2; - modes[3] = p->state->unit[i].texgen_mode3; - - for (j = 0; j < 4; j++) { - switch (modes[j]) { - case TXG_OBJ_LINEAR: { - struct ureg obj = register_input(p, VERT_ATTRIB_POS); - struct ureg plane = - register_param3(p, STATE_TEXGEN, i, - STATE_TEXGEN_OBJECT_S + j); - - emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, - obj, plane ); - break; - } - case TXG_EYE_LINEAR: { - struct ureg eye = get_eye_position(p); - struct ureg plane = - register_param3(p, STATE_TEXGEN, i, - STATE_TEXGEN_EYE_S + j); - - emit_op2(p, OPCODE_DP4, out_texgen, WRITEMASK_X << j, - eye, plane ); - break; - } - case TXG_SPHERE_MAP: - sphere_mask |= WRITEMASK_X << j; - break; - case TXG_REFLECTION_MAP: - reflect_mask |= WRITEMASK_X << j; - break; - case TXG_NORMAL_MAP: - normal_mask |= WRITEMASK_X << j; - break; - case TXG_NONE: - copy_mask |= WRITEMASK_X << j; - } - } - - if (sphere_mask) { - build_sphere_texgen(p, out_texgen, sphere_mask); - } - - if (reflect_mask) { - build_reflect_texgen(p, out_texgen, reflect_mask); - } - - if (normal_mask) { - struct ureg normal = get_transformed_normal(p); - emit_op1(p, OPCODE_MOV, out_texgen, normal_mask, normal ); - } - - if (copy_mask) { - struct ureg in = register_input(p, VERT_ATTRIB_TEX0+i); - emit_op1(p, OPCODE_MOV, out_texgen, copy_mask, in ); - } - } - - if (texmat_enabled) { - struct ureg texmat[4]; - struct ureg in = (!is_undef(out_texgen) ? - out_texgen : - register_input(p, VERT_ATTRIB_TEX0+i)); - if (p->mvp_with_dp4) { - register_matrix_param5( p, STATE_TEXTURE_MATRIX, i, 0, 3, - texmat ); - emit_matrix_transform_vec4( p, out, texmat, in ); - } - else { - register_matrix_param5( p, STATE_TEXTURE_MATRIX_TRANSPOSE, i, 0, 3, - texmat ); - emit_transpose_matrix_transform_vec4( p, out, texmat, in ); - } - } - - release_temps(p); - } - else { - emit_passthrough(p, VERT_ATTRIB_TEX0+i, VARYING_SLOT_TEX0+i); + continue; + + nir_def *texcoord; + if (p->state->unit[i].texgen_enabled) { + GLuint copy_mask = 0; + GLuint sphere_mask = 0; + GLuint reflect_mask = 0; + GLuint normal_mask = 0; + GLuint modes[4]; + nir_def *comps[4]; + + modes[0] = p->state->unit[i].texgen_mode0; + modes[1] = p->state->unit[i].texgen_mode1; + modes[2] = p->state->unit[i].texgen_mode2; + modes[3] = p->state->unit[i].texgen_mode3; + + for (j = 0; j < 4; j++) { + switch (modes[j]) { + case TXG_OBJ_LINEAR: { + nir_def *obj = load_input_vec4(p, VERT_ATTRIB_POS); + nir_def *plane = + load_state_vec4(p, STATE_TEXGEN, i, + STATE_TEXGEN_OBJECT_S + j, 0); + comps[j] = nir_fdot4(p->b, obj, plane); + break; + } + case TXG_EYE_LINEAR: { + nir_def *eye = get_eye_position(p); + nir_def *plane = + load_state_vec4(p, STATE_TEXGEN, i, + STATE_TEXGEN_EYE_S + j, 0); + comps[j] = nir_fdot4(p->b, eye, plane); + break; + } + case TXG_SPHERE_MAP: + sphere_mask |= 1u << j; + break; + case TXG_REFLECTION_MAP: + reflect_mask |= 1u << j; + break; + case TXG_NORMAL_MAP: + normal_mask |= 1u << j; + break; + case TXG_NONE: + copy_mask |= 1u << j; + } + } + + if (sphere_mask) { + nir_def *sphere = build_sphere_texgen(p); + for (j = 0; j < 4; j++) + if (sphere_mask & (1 << j)) + comps[j] = nir_channel(p->b, sphere, j); + } + + if (reflect_mask) { + nir_def *reflect = build_reflect_texgen(p); + for (j = 0; j < 4; j++) + if (reflect_mask & (1 << j)) + comps[j] = nir_channel(p->b, reflect, j); + } + + if (normal_mask) { + nir_def *normal = get_transformed_normal(p); + for (j = 0; j < 4; j++) + if (normal_mask & (1 << j)) + comps[j] = nir_channel(p->b, normal, j); + } + + if (copy_mask) { + nir_def *in = load_input_vec4(p, VERT_ATTRIB_TEX0 + i); + for (j = 0; j < 4; j++) + if (copy_mask & (1 << j)) + comps[j] = nir_channel(p->b, in, j); + } + + texcoord = nir_vec(p->b, comps, 4); + } else + texcoord = load_input_vec4(p, VERT_ATTRIB_TEX0 + i); + + if (p->state->unit[i].texmat_enabled) { + nir_def *texmat[4]; + if (p->mvp_with_dp4) { + load_state_mat4(p, texmat, STATE_TEXTURE_MATRIX, i); + texcoord = + emit_matrix_transform_vec4(p->b, texmat, texcoord); + } else { + load_state_mat4(p, texmat, + STATE_TEXTURE_MATRIX_TRANSPOSE, i); + texcoord = + emit_transpose_matrix_transform_vec4(p->b, texmat, + texcoord); + } } + + store_output_vec4(p, VARYING_SLOT_TEX0 + i, texcoord); } } @@ -1553,36 +1233,36 @@ static void build_texture_transform( struct tnl_program *p ) */ static void build_atten_pointsize( struct tnl_program *p ) { - struct ureg eye = get_eye_position_z(p); - struct ureg state_size = register_param1(p, STATE_POINT_SIZE_CLAMPED); - struct ureg state_attenuation = register_param1(p, STATE_POINT_ATTENUATION); - struct ureg out = register_output(p, VARYING_SLOT_PSIZ); - struct ureg ut = get_temp(p); + nir_def *eye = get_eye_position_z(p); + nir_def *in_size = + load_state_vec4(p, STATE_POINT_SIZE_CLAMPED, 0, 0, 0); + nir_def *att = + load_state_vec4(p, STATE_POINT_ATTENUATION, 0, 0, 0); /* dist = |eyez| */ - emit_op1(p, OPCODE_ABS, ut, WRITEMASK_Y, swizzle1(eye, Z)); + nir_def *dist = nir_fabs(p->b, eye); + /* p1 + dist * (p2 + dist * p3); */ - emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), - swizzle1(state_attenuation, Z), swizzle1(state_attenuation, Y)); - emit_op3(p, OPCODE_MAD, ut, WRITEMASK_X, swizzle1(ut, Y), - ut, swizzle1(state_attenuation, X)); + nir_def *factor = nir_fmad(p->b, dist, nir_channel(p->b, att, 2), + nir_channel(p->b, att, 1)); + factor = nir_fmad(p->b, dist, factor, nir_channel(p->b, att, 0)); /* 1 / sqrt(factor) */ - emit_op1(p, OPCODE_RSQ, ut, WRITEMASK_X, ut ); + factor = nir_frsq(p->b, factor); + + /* pointSize / sqrt(factor) */ + nir_def *size = nir_fmul(p->b, factor, + nir_channel(p->b, in_size, 0)); -#if 0 - /* out = pointSize / sqrt(factor) */ - emit_op2(p, OPCODE_MUL, out, WRITEMASK_X, ut, state_size); -#else +#if 1 /* this is a good place to clamp the point size since there's likely * no hardware registers to clamp point size at rasterization time. */ - emit_op2(p, OPCODE_MUL, ut, WRITEMASK_X, ut, state_size); - emit_op2(p, OPCODE_MAX, ut, WRITEMASK_X, ut, swizzle1(state_size, Y)); - emit_op2(p, OPCODE_MIN, out, WRITEMASK_X, ut, swizzle1(state_size, Z)); + size = nir_fclamp(p->b, size, nir_channel(p->b, in_size, 1), + nir_channel(p->b, in_size, 2)); #endif - release_temp(p, ut); + store_output_float(p, VARYING_SLOT_PSIZ, size); } @@ -1591,29 +1271,28 @@ static void build_atten_pointsize( struct tnl_program *p ) */ static void build_array_pointsize( struct tnl_program *p ) { - struct ureg in = register_input(p, VERT_ATTRIB_POINT_SIZE); - struct ureg out = register_output(p, VARYING_SLOT_PSIZ); - emit_op1(p, OPCODE_MOV, out, WRITEMASK_X, in); + nir_def *val = load_input(p, VERT_ATTRIB_POINT_SIZE, + glsl_float_type()); + store_output_float(p, VARYING_SLOT_PSIZ, val); } static void build_tnl_program( struct tnl_program *p ) { - /* Emit the program, starting with the modelview, projection transforms: - */ - build_hpos(p); + /* Emit the program (except for the MVP transform, which is a separate pass) */ /* Lighting calculations: */ - if (p->state->fragprog_inputs_read & (VARYING_BIT_COL0|VARYING_BIT_COL1)) { + if (p->state->fragprog_inputs_read & + (VARYING_BIT_COL0 | VARYING_BIT_COL1)) { if (p->state->light_global_enabled) - build_lighting(p); + build_lighting(p); else { - if (p->state->fragprog_inputs_read & VARYING_BIT_COL0) - emit_passthrough(p, VERT_ATTRIB_COLOR0, VARYING_SLOT_COL0); + if (p->state->fragprog_inputs_read & VARYING_BIT_COL0) + emit_passthrough(p, VERT_ATTRIB_COLOR0, VARYING_SLOT_COL0); - if (p->state->fragprog_inputs_read & VARYING_BIT_COL1) - emit_passthrough(p, VERT_ATTRIB_COLOR1, VARYING_SLOT_COL1); + if (p->state->fragprog_inputs_read & VARYING_BIT_COL1) + emit_passthrough(p, VERT_ATTRIB_COLOR1, VARYING_SLOT_COL1); } } @@ -1628,62 +1307,48 @@ static void build_tnl_program( struct tnl_program *p ) else if (p->state->varying_vp_inputs & VERT_BIT_POINT_SIZE) build_array_pointsize(p); - /* Finish up: - */ - emit_op1(p, OPCODE_END, undef, 0, undef); - - /* Disassemble: - */ - if (DISASSEM) { - printf ("\n"); - } + if (p->state->varying_vp_inputs & VERT_BIT_SELECT_RESULT_OFFSET) + emit_passthrough(p, VERT_ATTRIB_SELECT_RESULT_OFFSET, + VARYING_SLOT_VAR0); } -static void +static nir_shader * create_new_program( const struct state_key *key, struct gl_program *program, GLboolean mvp_with_dp4, - GLuint max_temps) + const nir_shader_compiler_options *options) { struct tnl_program p; memset(&p, 0, sizeof(p)); p.state = key; - p.program = program; - p.eye_position = undef; - p.eye_position_z = undef; - p.eye_position_normalized = undef; - p.transformed_normal = undef; - p.identity = undef; - p.temp_in_use = 0; p.mvp_with_dp4 = mvp_with_dp4; - if (max_temps >= sizeof(int) * 8) - p.temp_reserved = 0; - else - p.temp_reserved = ~((1<<max_temps)-1); - - /* Start by allocating 32 instructions. - * If we need more, we'll grow the instruction array as needed. - */ - p.max_inst = 32; - p.program->arb.Instructions = - rzalloc_array(program, struct prog_instruction, p.max_inst); - p.program->String = NULL; - p.program->arb.NumInstructions = - p.program->arb.NumTemporaries = - p.program->arb.NumParameters = - p.program->arb.NumAttributes = p.program->arb.NumAddressRegs = 0; - p.program->Parameters = _mesa_new_parameter_list(); - p.program->info.inputs_read = 0; - p.program->info.outputs_written = 0; + program->Parameters = _mesa_new_parameter_list(); p.state_params = _mesa_new_parameter_list(); + nir_builder b = nir_builder_init_simple_shader(MESA_SHADER_VERTEX, + options, + "ff-vs"); + + nir_shader *s = b.shader; + + s->info.separate_shader = true; + + p.b = &b; + build_tnl_program( &p ); - _mesa_add_separate_state_parameters(p.program, p.state_params); + nir_validate_shader(b.shader, "after generating ff-vertex shader"); + + /* Emit the MVP position transformation */ + NIR_PASS(_, b.shader, st_nir_lower_position_invariant, mvp_with_dp4, p.state_params); + + _mesa_add_separate_state_parameters(program, p.state_params); _mesa_free_parameter_list(p.state_params); + + return s; } @@ -1714,16 +1379,22 @@ _mesa_get_fixed_func_vertex_program(struct gl_context *ctx) if (0) printf("Build new TNL program\n"); - prog = ctx->Driver.NewProgram(ctx, MESA_SHADER_VERTEX, 0, true); + prog = ctx->Driver.NewProgram(ctx, MESA_SHADER_VERTEX, 0, false); if (!prog) return NULL; - create_new_program( &key, prog, - ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS, - ctx->Const.Program[MESA_SHADER_VERTEX].MaxTemps ); + const struct nir_shader_compiler_options *options = + st_get_nir_compiler_options(ctx->st, MESA_SHADER_VERTEX); + + nir_shader *s = + create_new_program( &key, prog, + ctx->Const.ShaderCompilerOptions[MESA_SHADER_VERTEX].OptimizeForAOS, + options); + + prog->state.type = PIPE_SHADER_IR_NIR; + prog->nir = s; - if (ctx->Driver.ProgramStringNotify) - ctx->Driver.ProgramStringNotify(ctx, GL_VERTEX_PROGRAM_ARB, prog); + st_program_string_notify(ctx, GL_VERTEX_PROGRAM_ARB, prog); _mesa_program_cache_insert(ctx, ctx->VertexProgram.Cache, &key, sizeof(key), prog); diff --git a/src/mesa/main/fog.c b/src/mesa/main/fog.c index a2f9246d36f..5eb136fc880 100644 --- a/src/mesa/main/fog.c +++ b/src/mesa/main/fog.c @@ -23,12 +23,12 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "fog.h" #include "macros.h" #include "mtypes.h" - +#include "api_exec_decl.h" void GLAPIENTRY @@ -184,10 +184,6 @@ _mesa_Fogfv( GLenum pname, const GLfloat *params ) goto invalid_pname; } - if (ctx->Driver.Fogfv) { - ctx->Driver.Fogfv( ctx, pname, params ); - } - return; invalid_pname: diff --git a/src/mesa/main/fog.h b/src/mesa/main/fog.h index 1467663edcb..838175cee0f 100644 --- a/src/mesa/main/fog.h +++ b/src/mesa/main/fog.h @@ -37,23 +37,10 @@ #define FOG_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; - -extern void GLAPIENTRY -_mesa_Fogf(GLenum pname, GLfloat param); - -extern void GLAPIENTRY -_mesa_Fogi(GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_Fogfv(GLenum pname, const GLfloat *params ); - -extern void GLAPIENTRY -_mesa_Fogiv(GLenum pname, const GLint *params ); - extern void _mesa_init_fog( struct gl_context * ctx ); #endif diff --git a/src/mesa/main/format_fallback.py b/src/mesa/main/format_fallback.py index cc388274e75..748779cd709 100644 --- a/src/mesa/main/format_fallback.py +++ b/src/mesa/main/format_fallback.py @@ -66,25 +66,6 @@ def get_unorm_to_srgb_map(formats): # Every sRGB format MUST have a UNORM equivalent assert found_unorm_name -def get_rgbx_to_rgba_map(formats): - names = set(fmt.name for fmt in formats) - - for fmt in formats: - if not fmt.has_channel('r') or not fmt.has_channel('x'): - continue - - # The condition above will still let MESA_FORMAT_R9G9B9E5_FLOAT - # through. We need to ensure it actually has an X in the name. - if not 'X' in fmt.name: - continue - - rgbx_name = fmt.name - rgba_name = rgbx_name.replace("X", "A") - if rgba_name not in names: - continue; - - yield rgbx_name, rgba_name - def get_intensity_to_red_map(formats): names = set(fmt.name for fmt in formats) @@ -121,28 +102,6 @@ _mesa_get_srgb_format_linear(mesa_format format) } /** - * For a linear format, return the corresponding sRGB color space format. - * For an sRGB format, return the format as-is. - * Assert-fails if the format is not sRGB and does not have an sRGB equivalent. - */ -mesa_format -_mesa_get_linear_format_srgb(mesa_format format) -{ - switch (format) { -%for unorm, srgb in unorm_to_srgb_map: - case ${unorm}: - return ${srgb}; -%endfor -%for unorm, srgb in unorm_to_srgb_map: - case ${srgb}: -%endfor - return format; - default: - unreachable("Given format does not have an sRGB equivalent"); - } -} - -/** * For an intensity format, return the corresponding red format. For other * formats, return the format as-is. */ @@ -158,33 +117,6 @@ _mesa_get_intensity_format_red(mesa_format format) return format; } } - -/** - * If the format has an alpha channel, and there exists a non-alpha - * variant of the format with an identical bit layout, then return - * the non-alpha format. Otherwise return the original format. - * - * Examples: - * Fallback exists: - * MESA_FORMAT_R8G8B8X8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM - * MESA_FORMAT_RGBX_UNORM16 -> MESA_FORMAT_RGBA_UNORM16 - * - * No fallback: - * MESA_FORMAT_R8G8B8A8_UNORM -> MESA_FORMAT_R8G8B8A8_UNORM - * MESA_FORMAT_Z_FLOAT32 -> MESA_FORMAT_Z_FLOAT32 - */ -mesa_format -_mesa_format_fallback_rgbx_to_rgba(mesa_format format) -{ - switch (format) { -%for rgbx, rgba in rgbx_to_rgba_map: - case ${rgbx}: - return ${rgba}; -%endfor - default: - return format; - } -} """); def main(): @@ -194,11 +126,10 @@ def main(): template_env = { 'unorm_to_srgb_map': list(get_unorm_to_srgb_map(formats)), - 'rgbx_to_rgba_map': list(get_rgbx_to_rgba_map(formats)), 'intensity_to_red_map': list(get_intensity_to_red_map(formats)), } - with open(pargs.out, 'w') as f: + with open(pargs.out, 'w', encoding='utf-8') as f: f.write(TEMPLATE.render(**template_env)) if __name__ == "__main__": diff --git a/src/mesa/main/format_info.py b/src/mesa/main/format_info.py index edc0324e60b..c88b905f72b 100644 --- a/src/mesa/main/format_info.py +++ b/src/mesa/main/format_info.py @@ -21,8 +21,6 @@ # TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE # SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -from __future__ import division, print_function - import format_parser as parser import sys @@ -128,7 +126,7 @@ def get_channel_bits(fmat, chan_name): return bits if fmat.has_channel(chan_name) else 0 elif fmat.layout == 'atc': return 8 if fmat.has_channel(chan_name) else 0 - elif fmat.layout == 'other' and ('RG_RB' in fmat.name or 'GR_BR' in fmat.name): + elif fmat.layout == 'other' and any(s in fmat.name for s in {'RG_RB', 'GR_BR', 'RB_RG', 'BR_GR'}): return 8 if fmat.has_channel(chan_name) else 0 else: assert False diff --git a/src/mesa/main/format_utils.c b/src/mesa/main/format_utils.c index 75f6b67ec53..ca9d91932ac 100644 --- a/src/mesa/main/format_utils.c +++ b/src/mesa/main/format_utils.c @@ -356,11 +356,13 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, dst += dst_stride; } return; +#if UTIL_ARCH_LITTLE_ENDIAN } else if (dst_array_format == BGRA8_UBYTE && src_format == MESA_FORMAT_R8G8B8A8_UNORM) { convert_ubyte_rgba_to_bgra(width, height, src, src_stride, dst, dst_stride); return; +#endif } else if (dst_array_format == RGBA32_UINT && _mesa_is_format_unsigned(src_format)) { assert(_mesa_is_format_integer_color(src_format)); @@ -387,11 +389,14 @@ _mesa_format_convert(void *void_dst, uint32_t dst_format, size_t dst_stride, } else if (src_array_format == RGBA8_UBYTE) { assert(!_mesa_is_format_integer_color(dst_format)); +#if UTIL_ARCH_LITTLE_ENDIAN if (dst_format == MESA_FORMAT_B8G8R8A8_UNORM) { convert_ubyte_rgba_to_bgra(width, height, src, src_stride, dst, dst_stride); } - else { + else +#endif + { for (row = 0; row < height; ++row) { _mesa_pack_ubyte_rgba_row(dst_format, width, src, dst); src += src_stride; diff --git a/src/mesa/main/formatquery.c b/src/mesa/main/formatquery.c index 8fec6b213a9..3e8635f2644 100644 --- a/src/mesa/main/formatquery.c +++ b/src/mesa/main/formatquery.c @@ -36,6 +36,9 @@ #include "shaderimage.h" #include "texcompress.h" #include "textureview.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_format.h" static bool _is_renderable(struct gl_context *ctx, GLenum internalformat) @@ -140,6 +143,27 @@ _legal_parameters(struct gl_context *ctx, GLenum target, GLenum internalformat, } break; + case GL_NUM_VIRTUAL_PAGE_SIZES_ARB: + case GL_VIRTUAL_PAGE_SIZE_X_ARB: + case GL_VIRTUAL_PAGE_SIZE_Y_ARB: + case GL_VIRTUAL_PAGE_SIZE_Z_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetInternalformativ(pname=%s)", + _mesa_enum_to_string(pname)); + return false; + } + break; + + case GL_CLEAR_TEXTURE: + if (!_mesa_has_ARB_clear_texture(ctx)) { + _mesa_error(ctx, GL_INVALID_ENUM, + "glGetInternalformativ(pname=%s)", + _mesa_enum_to_string(pname)); + return false; + } + break; + case GL_SRGB_DECODE_ARB: /* The ARB_internalformat_query2 spec says: * @@ -322,6 +346,10 @@ _set_default_response(GLenum pname, GLint buffer[16]) case GL_TEXTURE_COMPRESSED_BLOCK_HEIGHT: case GL_TEXTURE_COMPRESSED_BLOCK_SIZE: case GL_NUM_TILING_TYPES_EXT: + case GL_NUM_VIRTUAL_PAGE_SIZES_ARB: + case GL_VIRTUAL_PAGE_SIZE_X_ARB: + case GL_VIRTUAL_PAGE_SIZE_Y_ARB: + case GL_VIRTUAL_PAGE_SIZE_Z_ARB: buffer[0] = 0; break; @@ -370,6 +398,7 @@ _set_default_response(GLenum pname, GLint buffer[16]) case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: case GL_CLEAR_BUFFER: + case GL_CLEAR_TEXTURE: case GL_TEXTURE_VIEW: case GL_VIEW_COMPATIBILITY_CLASS: buffer[0] = GL_NONE; @@ -421,7 +450,7 @@ _is_target_supported(struct gl_context *ctx, GLenum target) break; case GL_TEXTURE_CUBE_MAP: - if (ctx->API != API_OPENGL_CORE && !_mesa_has_ARB_texture_cube_map(ctx)) + if (!_mesa_is_desktop_gl(ctx)) return false; break; @@ -506,7 +535,8 @@ _is_resource_supported(struct gl_context *ctx, GLenum target, return false; /* additional checks for depth textures */ - if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat)) + if (!_mesa_legal_texture_base_format_for_target(ctx, target, internalformat) && + !(pname == GL_CLEAR_TEXTURE && _mesa_is_depth_or_stencil_format(internalformat))) return false; /* additional checks for compressed textures */ @@ -592,8 +622,8 @@ _is_internalformat_supported(struct gl_context *ctx, GLenum target, } /* Let the driver have the final word */ - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, - GL_INTERNALFORMAT_SUPPORTED, buffer); + st_QueryInternalFormat(ctx, target, internalformat, + GL_INTERNALFORMAT_SUPPORTED, buffer); return (buffer[0] == GL_TRUE); } @@ -715,6 +745,7 @@ _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target, case GL_SIMULTANEOUS_TEXTURE_AND_DEPTH_WRITE: case GL_SIMULTANEOUS_TEXTURE_AND_STENCIL_WRITE: case GL_CLEAR_BUFFER: + case GL_CLEAR_TEXTURE: case GL_TEXTURE_VIEW: case GL_TEXTURE_SHADOW: case GL_TEXTURE_GATHER: @@ -733,10 +764,14 @@ _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target, break; case GL_NUM_TILING_TYPES_EXT: params[0] = 2; + if (_mesa_has_MESA_texture_const_bandwidth(ctx)) + params[0]++; break; case GL_TILING_TYPES_EXT: params[0] = GL_OPTIMAL_TILING_EXT; params[1] = GL_LINEAR_TILING_EXT; + if (_mesa_has_MESA_texture_const_bandwidth(ctx)) + params[2] = GL_CONST_BW_TILING_MESA; break; default: @@ -840,12 +875,35 @@ _get_min_dimensions(GLenum pname) } } +static bool +_is_generic_compressed_format(const struct gl_context *ctx, + GLenum intFormat) +{ + switch (intFormat) { + case GL_COMPRESSED_SRGB: + case GL_COMPRESSED_SRGB_ALPHA: + case GL_COMPRESSED_SLUMINANCE: + case GL_COMPRESSED_SLUMINANCE_ALPHA: + return _mesa_has_EXT_texture_sRGB(ctx); + case GL_COMPRESSED_RG: + case GL_COMPRESSED_RED: + return _mesa_is_gles(ctx) ? + _mesa_has_EXT_texture_rg(ctx) : + _mesa_has_ARB_texture_rg(ctx); + case GL_COMPRESSED_RGB: + case GL_COMPRESSED_RGBA: + return true; + default: + return false; + } +} + /* * Similar to teximage.c:check_multisample_target, but independent of the * dimensions. */ -static bool -_is_multisample_target(GLenum target) +bool +_mesa_is_multisample_target(GLenum target) { switch(target) { case GL_TEXTURE_2D_MULTISAMPLE: @@ -873,8 +931,6 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, return; } - assert(ctx->Driver.QueryInternalFormat != NULL); - if (!_legal_parameters(ctx, target, internalformat, pname, bufSize, params)) return; @@ -919,13 +975,13 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * Since OpenGL ES 3.1 adds support for multisampled integer formats, we * have to check the version for 30 exactly. */ - if (pname == GL_NUM_SAMPLE_COUNTS && ctx->API == API_OPENGLES2 && + if (pname == GL_NUM_SAMPLE_COUNTS && _mesa_is_gles2(ctx) && ctx->Version == 30 && _mesa_is_enum_format_integer(internalformat)) { goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_INTERNALFORMAT_SUPPORTED: @@ -948,8 +1004,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * is called just to try to get a preferred format. If not supported, * GL_NONE was already returned and the driver is not called. */ - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_INTERNALFORMAT_RED_SIZE: @@ -974,13 +1030,21 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, baseformat = _mesa_base_fbo_format(ctx, internalformat); } + /* If the internal format is unsupported, or if a particular component + * is not present in the format, 0 is written to params. + */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = GL_NONE; + break; + } + /* Let the driver choose the texture format. * * Disclaimer: I am considering that drivers use for renderbuffers the * same format-choice logic as for textures. */ - texformat = ctx->Driver.ChooseTextureFormat(ctx, target, internalformat, - GL_NONE /*format */, GL_NONE /* type */); + texformat = st_ChooseTextureFormat(ctx, target, internalformat, + GL_NONE /*format */, GL_NONE /* type */); if (texformat == MESA_FORMAT_NONE || baseformat <= 0) goto end; @@ -1000,8 +1064,7 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, switch (pname) { case GL_INTERNALFORMAT_DEPTH_SIZE: - if (ctx->API != API_OPENGL_CORE && - !_mesa_has_ARB_depth_texture(ctx) && + if (!_mesa_is_desktop_gl(ctx) && target != GL_RENDERBUFFER && target != GL_TEXTURE_BUFFER) goto end; @@ -1057,6 +1120,12 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (get_pname == 0) goto end; + /* if the resource is unsupported, zero is returned */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = 0; + break; + } + _mesa_GetIntegerv(get_pname, buffer); break; } @@ -1068,6 +1137,12 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (!_mesa_is_array_texture(target)) goto end; + /* if the resource is unsupported, zero is returned */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = 0; + break; + } + _mesa_GetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, buffer); break; @@ -1082,12 +1157,18 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, unsigned i; GLint current_value; + /* if the resource is unsupported, zero is returned */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = 0; + break; + } + /* Combining the dimensions. Note that for array targets, this would * automatically include the value of MAX_LAYERS, as that value is * returned as MAX_HEIGHT or MAX_DEPTH */ for (i = 0; i < 4; i++) { if (max_dimensions_pnames[i] == GL_SAMPLES && - !_is_multisample_target(target)) + !_mesa_is_multisample_target(target)) continue; _mesa_GetInternalformativ(target, internalformat, @@ -1179,23 +1260,23 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, !_is_renderable(ctx, internalformat)) goto end; - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_READ_PIXELS: case GL_READ_PIXELS_FORMAT: case GL_READ_PIXELS_TYPE: - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_TEXTURE_IMAGE_FORMAT: case GL_GET_TEXTURE_IMAGE_FORMAT: case GL_TEXTURE_IMAGE_TYPE: case GL_GET_TEXTURE_IMAGE_TYPE: - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_MIPMAP: @@ -1226,8 +1307,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_COLOR_ENCODING: @@ -1246,8 +1327,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_SRGB_WRITE: @@ -1256,8 +1337,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_SRGB_DECODE_ARB: @@ -1268,8 +1349,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_FILTER: @@ -1289,8 +1370,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, * need to call the driver to know if it is CAVEAT_SUPPORT or * FULL_SUPPORT. */ - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_VERTEX_TEXTURE: @@ -1313,8 +1394,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (pname == GL_COMPUTE_TEXTURE && !_mesa_has_compute_shaders(ctx)) goto end; - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_TEXTURE_GATHER: @@ -1351,8 +1432,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_SHADER_IMAGE_LOAD: @@ -1370,16 +1451,16 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, !_mesa_is_shader_image_format_supported(ctx, internalformat)) goto end; - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_SHADER_IMAGE_ATOMIC: if (!_mesa_has_ARB_shader_image_load_store(ctx)) goto end; - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_IMAGE_TEXEL_SIZE: { @@ -1460,6 +1541,14 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (targetIndex < 0 || targetIndex == TEXTURE_BUFFER_INDEX) goto end; + /* If the resource is not supported for image textures, + * or if image textures are not supported, NONE is returned. + */ + if (!st_QueryTextureFormatSupport(ctx, target, internalformat)) { + buffer[0] = GL_NONE; + break; + } + /* From spec: "Equivalent to calling GetTexParameter with <value> set * to IMAGE_FORMAT_COMPATIBILITY_TYPE." * @@ -1491,8 +1580,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; } - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_TEXTURE_COMPRESSED: @@ -1533,9 +1622,22 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, if (target != GL_TEXTURE_BUFFER) goto end; - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, + st_QueryInternalFormat(ctx, target, internalformat, pname, buffer); break; + case GL_CLEAR_TEXTURE: { + if (target == GL_TEXTURE_BUFFER || + target == GL_RENDERBUFFER) + goto end; + + if (_mesa_is_compressed_format(ctx, internalformat) || + _is_generic_compressed_format(ctx, internalformat)) + goto end; + + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); + break; + } case GL_TEXTURE_VIEW: case GL_VIEW_COMPATIBILITY_CLASS: @@ -1545,8 +1647,8 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, goto end; if (pname == GL_TEXTURE_VIEW) { - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); } else { GLenum view_class = _mesa_texture_view_lookup_view_class(ctx, internalformat); @@ -1559,20 +1661,27 @@ _mesa_GetInternalformativ(GLenum target, GLenum internalformat, GLenum pname, case GL_NUM_TILING_TYPES_EXT: case GL_TILING_TYPES_EXT: - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); break; case GL_TEXTURE_REDUCTION_MODE_ARB: if (ctx->Extensions.EXT_texture_filter_minmax) buffer[0] = (GLint)1; else if (ctx->Extensions.ARB_texture_filter_minmax) - ctx->Driver.QueryInternalFormat(ctx, target, internalformat, pname, - buffer); + st_QueryInternalFormat(ctx, target, internalformat, pname, + buffer); else buffer[0] = (GLint)0; break; + case GL_NUM_VIRTUAL_PAGE_SIZES_ARB: + case GL_VIRTUAL_PAGE_SIZE_X_ARB: + case GL_VIRTUAL_PAGE_SIZE_Y_ARB: + case GL_VIRTUAL_PAGE_SIZE_Z_ARB: + st_QueryInternalFormat(ctx, target, internalformat, pname, buffer); + break; + default: unreachable("bad param"); } diff --git a/src/mesa/main/formatquery.h b/src/mesa/main/formatquery.h index f23fafd8fb0..55c79b88bdc 100644 --- a/src/mesa/main/formatquery.h +++ b/src/mesa/main/formatquery.h @@ -24,7 +24,7 @@ #ifndef FORMATQUERY_H #define FORMATQUERY_H -#include "glheader.h" +#include "util/glheader.h" size_t _mesa_query_samples_for_format(struct gl_context *ctx, GLenum target, @@ -35,12 +35,7 @@ _mesa_query_internal_format_default(struct gl_context *ctx, GLenum target, GLenum internalFormat, GLenum pname, GLint *params); -extern void GLAPIENTRY -_mesa_GetInternalformativ(GLenum target, GLenum internalformat, - GLenum pname, GLsizei bufSize, GLint *params); - -extern void GLAPIENTRY -_mesa_GetInternalformati64v(GLenum target, GLenum internalformat, - GLenum pname, GLsizei bufSize, GLint64 *params); +bool +_mesa_is_multisample_target(GLenum target); #endif /* FORMATQUERY_H */ diff --git a/src/mesa/main/formats.c b/src/mesa/main/formats.c index 9cd026f7507..de9e7da037e 100644 --- a/src/mesa/main/formats.c +++ b/src/mesa/main/formats.c @@ -412,7 +412,7 @@ _mesa_array_format_flip_channels(mesa_array_format format) for (unsigned i = 0; i < 4; i++) assert(swizzle[i] != 2 && swizzle[i] != 3); - static const uint8_t flip_xy[6] = { 1, 0, 2, 3, 4, 5 }; + static const uint8_t flip_xy[7] = { 1, 0, 2, 3, 4, 5, 6 }; _mesa_array_format_set_swizzle(&format, flip_xy[swizzle[0]], flip_xy[swizzle[1]], flip_xy[swizzle[2]], flip_xy[swizzle[3]]); @@ -420,7 +420,7 @@ _mesa_array_format_flip_channels(mesa_array_format format) } if (num_channels == 4) { - static const uint8_t flip[6] = { 3, 2, 1, 0, 4, 5 }; + static const uint8_t flip[7] = { 3, 2, 1, 0, 4, 5, 6 }; _mesa_array_format_set_swizzle(&format, flip[swizzle[0]], flip[swizzle[1]], flip[swizzle[2]], flip[swizzle[3]]); @@ -630,21 +630,7 @@ _mesa_is_format_srgb(mesa_format format) bool _mesa_is_format_etc2(mesa_format format) { - switch (format) { - case MESA_FORMAT_ETC2_RGB8: - case MESA_FORMAT_ETC2_SRGB8: - case MESA_FORMAT_ETC2_RGBA8_EAC: - case MESA_FORMAT_ETC2_SRGB8_ALPHA8_EAC: - case MESA_FORMAT_ETC2_R11_EAC: - case MESA_FORMAT_ETC2_RG11_EAC: - case MESA_FORMAT_ETC2_SIGNED_R11_EAC: - case MESA_FORMAT_ETC2_SIGNED_RG11_EAC: - case MESA_FORMAT_ETC2_RGB8_PUNCHTHROUGH_ALPHA1: - case MESA_FORMAT_ETC2_SRGB8_PUNCHTHROUGH_ALPHA1: - return true; - default: - return false; - } + return _mesa_get_format_layout(format) == MESA_FORMAT_LAYOUT_ETC2; } @@ -654,39 +640,48 @@ _mesa_is_format_etc2(mesa_format format) bool _mesa_is_format_astc_2d(mesa_format format) { - switch (format) { - case MESA_FORMAT_RGBA_ASTC_4x4: - case MESA_FORMAT_RGBA_ASTC_5x4: - case MESA_FORMAT_RGBA_ASTC_5x5: - case MESA_FORMAT_RGBA_ASTC_6x5: - case MESA_FORMAT_RGBA_ASTC_6x6: - case MESA_FORMAT_RGBA_ASTC_8x5: - case MESA_FORMAT_RGBA_ASTC_8x6: - case MESA_FORMAT_RGBA_ASTC_8x8: - case MESA_FORMAT_RGBA_ASTC_10x5: - case MESA_FORMAT_RGBA_ASTC_10x6: - case MESA_FORMAT_RGBA_ASTC_10x8: - case MESA_FORMAT_RGBA_ASTC_10x10: - case MESA_FORMAT_RGBA_ASTC_12x10: - case MESA_FORMAT_RGBA_ASTC_12x12: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_4x4: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x4: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_5x5: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x5: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_6x6: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x5: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x6: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_8x8: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x5: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x6: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x8: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_10x10: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x10: - case MESA_FORMAT_SRGB8_ALPHA8_ASTC_12x12: - return true; - default: - return false; - } + const struct mesa_format_info *info = _mesa_get_format_info(format); + return info->Layout == MESA_FORMAT_LAYOUT_ASTC && info->BlockDepth == 1; +} + + +/** + * Return TRUE if format is an S3TC compressed format. + */ +bool +_mesa_is_format_s3tc(mesa_format format) +{ + return _mesa_get_format_layout(format) == MESA_FORMAT_LAYOUT_S3TC; +} + + +/** + * Return TRUE if format is an RGTC compressed format. + */ +bool +_mesa_is_format_rgtc(mesa_format format) +{ + return _mesa_get_format_layout(format) == MESA_FORMAT_LAYOUT_RGTC; +} + + +/** + * Return TRUE if format is an LATC compressed format. + */ +bool +_mesa_is_format_latc(mesa_format format) +{ + return _mesa_get_format_layout(format) == MESA_FORMAT_LAYOUT_LATC; +} + + +/** + * Return TRUE if format is an BPTC compressed format. + */ +bool +_mesa_is_format_bptc(mesa_format format) +{ + return _mesa_get_format_layout(format) == MESA_FORMAT_LAYOUT_BPTC; } @@ -1025,7 +1020,9 @@ _mesa_uncompressed_format_to_type_and_comps(mesa_format format, case MESA_FORMAT_YCBCR: case MESA_FORMAT_YCBCR_REV: case MESA_FORMAT_RG_RB_UNORM8: + case MESA_FORMAT_RB_RG_UNORM8: case MESA_FORMAT_GR_BR_UNORM8: + case MESA_FORMAT_BR_GR_UNORM8: *datatype = GL_UNSIGNED_SHORT; *comps = 2; return; diff --git a/src/mesa/main/formats.csv b/src/mesa/main/formats.csv index 21cdea26e08..1b9ee62f8a7 100644 --- a/src/mesa/main/formats.csv +++ b/src/mesa/main/formats.csv @@ -94,7 +94,9 @@ MESA_FORMAT_YCBCR , other , 1, 1, 1, x16 , , , MESA_FORMAT_YCBCR_REV , other , 1, 1, 1, x16 , , , , xyzw, yuv MESA_FORMAT_RG_RB_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb +MESA_FORMAT_RB_RG_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb MESA_FORMAT_GR_BR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb +MESA_FORMAT_BR_GR_UNORM8 , other , 2, 1, 1, x16 , , , , xyz1, rgb # Array normalized formats MESA_FORMAT_A_UNORM8 , array , 1, 1, 1, un8 , , , , 000x, rgb diff --git a/src/mesa/main/formats.h b/src/mesa/main/formats.h index 508c9c342d2..8fce8f6930f 100644 --- a/src/mesa/main/formats.h +++ b/src/mesa/main/formats.h @@ -33,10 +33,11 @@ #define FORMATS_H -#include <GL/gl.h> #include <stdbool.h> #include <stdint.h> -#include "gallium/include/pipe/p_format.h" + +#include "util/glheader.h" +#include "util/format/u_formats.h" #include "util/u_endian.h" #ifdef __cplusplus @@ -239,7 +240,7 @@ _mesa_format_is_mesa_array_format(uint32_t f) /** * Mesa texture/renderbuffer image formats. These are just other names of the - * gallium p_format.h formats. + * util/format/u_formats.h formats. */ typedef enum pipe_format mesa_format; @@ -386,7 +387,9 @@ typedef enum pipe_format mesa_format; #define MESA_FORMAT_YCBCR PIPE_FORMAT_UYVY #define MESA_FORMAT_YCBCR_REV PIPE_FORMAT_YUYV #define MESA_FORMAT_RG_RB_UNORM8 PIPE_FORMAT_R8G8_R8B8_UNORM +#define MESA_FORMAT_RB_RG_UNORM8 PIPE_FORMAT_R8B8_R8G8_UNORM #define MESA_FORMAT_GR_BR_UNORM8 PIPE_FORMAT_G8R8_B8R8_UNORM +#define MESA_FORMAT_BR_GR_UNORM8 PIPE_FORMAT_B8R8_G8R8_UNORM #define MESA_FORMAT_A_UNORM8 PIPE_FORMAT_A8_UNORM #define MESA_FORMAT_A_UNORM16 PIPE_FORMAT_A16_UNORM #define MESA_FORMAT_L_UNORM8 PIPE_FORMAT_L8_UNORM @@ -696,6 +699,18 @@ bool _mesa_is_format_astc_2d(mesa_format format); bool +_mesa_is_format_s3tc(mesa_format format); + +bool +_mesa_is_format_rgtc(mesa_format format); + +bool +_mesa_is_format_latc(mesa_format format); + +bool +_mesa_is_format_bptc(mesa_format format); + +bool _mesa_is_format_color_format(mesa_format format); bool @@ -723,9 +738,6 @@ extern mesa_format _mesa_get_srgb_format_linear(mesa_format format); extern mesa_format -_mesa_get_linear_format_srgb(mesa_format format); - -extern mesa_format _mesa_get_intensity_format_red(mesa_format format); extern mesa_format @@ -742,9 +754,6 @@ _mesa_format_matches_format_and_type(mesa_format mesa_format, GLenum format, GLenum type, bool swapBytes, GLenum *error); -mesa_format -_mesa_format_fallback_rgbx_to_rgba(mesa_format format); - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/framebuffer.c b/src/mesa/main/framebuffer.c index de79ae0d85a..baa66fc4ee5 100644 --- a/src/mesa/main/framebuffer.c +++ b/src/mesa/main/framebuffer.c @@ -30,7 +30,7 @@ */ #include <stdio.h> -#include "glheader.h" +#include "util/glheader.h" #include "blend.h" #include "buffers.h" @@ -48,7 +48,7 @@ #include "state.h" #include "util/u_memory.h" - +#include "state_tracker/st_manager.h" /** * Compute/set the _DepthMax field for the given framebuffer. @@ -188,7 +188,7 @@ _mesa_destroy_framebuffer(struct gl_framebuffer *fb) if (fb) { _mesa_free_framebuffer_data(fb); free(fb->Label); - free(fb); + FREE(fb); } } @@ -203,6 +203,8 @@ _mesa_free_framebuffer_data(struct gl_framebuffer *fb) assert(fb); assert(fb->RefCount == 0); + pipe_resource_reference(&fb->resolve, NULL); + simple_mtx_destroy(&fb->Mutex); for (unsigned i = 0; i < BUFFER_COUNT; i++) { @@ -421,15 +423,36 @@ _mesa_update_framebuffer_visual(struct gl_context *ctx, /* find first RGB renderbuffer */ for (unsigned i = 0; i < BUFFER_COUNT; i++) { if (fb->Attachment[i].Renderbuffer) { - const struct gl_renderbuffer *rb = fb->Attachment[i].Renderbuffer; + const struct gl_renderbuffer_attachment *att = &fb->Attachment[i]; + const struct gl_renderbuffer *rb = att->Renderbuffer; const GLenum baseFormat = _mesa_get_format_base_format(rb->Format); const mesa_format fmt = rb->Format; /* Grab samples and sampleBuffers from any attachment point (assuming * the framebuffer is complete, we'll get the same answer from all - * attachments). + * attachments). If using EXT_multisampled_render_to_texture, the + * number of samples will be on fb->Attachment[i].NumSamples instead + * of the usual rb->NumSamples, but it's still guarantted to be the + * same for every attachment. + * + * From EXT_multisampled_render_to_texture: + * + * Also, FBOs cannot combine attachments that have associated + * multisample data specified by the mechanisms described in this + * extension with attachments allocated using the core OpenGL ES + * 3.1 mechanisms, such as TexStorage2DMultisample. Add to section + * 9.4.2 "Whole Framebuffer Completeness": + * + * "* If the value of RENDERBUFFER_SAMPLES is non-zero, all or + * none of the attached renderbuffers have been allocated + * using RenderbufferStorage- MultisampleEXT; if the value of + * TEXTURES_SAMPLES is non-zero, all or none of the attached + * textures have been attached using Framebuffer- + * Texture2DMultisampleEXT. + * { GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT }" */ - fb->Visual.samples = rb->NumSamples; + fb->Visual.samples = + att->NumSamples ? att->NumSamples : rb->NumSamples; if (_mesa_is_legal_color_format(ctx, baseFormat)) { fb->Visual.redBits = _mesa_get_format_bits(fmt, GL_RED_BITS); @@ -581,6 +604,29 @@ update_color_read_buffer(struct gl_framebuffer *fb) } } +/** + * Called via glDrawBuffer. We only provide this driver function so that we + * can check if we need to allocate a new renderbuffer. Specifically, we + * don't usually allocate a front color buffer when using a double-buffered + * visual. But if the app calls glDrawBuffer(GL_FRONT) we need to allocate + * that buffer. Note, this is only for window system buffers, not user- + * created FBOs. + */ +void +_mesa_draw_buffer_allocate(struct gl_context *ctx) +{ + struct gl_framebuffer *fb = ctx->DrawBuffer; + assert(_mesa_is_winsys_fbo(fb)); + GLuint i; + /* add the renderbuffers on demand */ + for (i = 0; i < fb->_NumColorDrawBuffers; i++) { + gl_buffer_index idx = fb->_ColorDrawBufferIndexes[i]; + + if (idx != BUFFER_NONE) { + st_manager_add_color_renderbuffer(ctx, fb, idx); + } + } +} /** * Update a gl_framebuffer's derived state. @@ -611,8 +657,7 @@ update_framebuffer(struct gl_context *ctx, struct gl_framebuffer *fb) /* Call device driver function if fb is the bound draw buffer. */ if (fb == ctx->DrawBuffer) { - if (ctx->Driver.DrawBufferAllocate) - ctx->Driver.DrawBufferAllocate(ctx); + _mesa_draw_buffer_allocate(ctx); } } else { @@ -783,6 +828,22 @@ _mesa_dest_buffer_exists(struct gl_context *ctx, GLenum format) return renderbuffer_exists(ctx, ctx->DrawBuffer, format, GL_FALSE); } +extern bool +_mesa_has_rtt_samples(const struct gl_framebuffer *fb) +{ + /* If there are multiple attachments, all of them are guaranteed + * to have the same sample count. */ + if (fb->_ColorReadBufferIndex) { + assert(fb->Attachment[fb->_ColorReadBufferIndex].Type != GL_NONE); + return fb->Attachment[fb->_ColorReadBufferIndex].NumSamples > 0; + } else if (fb->Attachment[BUFFER_DEPTH].Type != GL_NONE) { + return fb->Attachment[BUFFER_DEPTH].NumSamples > 0; + } else if (fb->Attachment[BUFFER_STENCIL].Type != GL_NONE) { + return fb->Attachment[BUFFER_STENCIL].NumSamples > 0; + } + + return true; +} /** * Used to answer the GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES queries (using @@ -844,6 +905,7 @@ _mesa_get_color_read_format(struct gl_context *ctx, return GL_RGB; case MESA_FORMAT_RG_FLOAT32: case MESA_FORMAT_RG_FLOAT16: + case MESA_FORMAT_RG_SNORM8: case MESA_FORMAT_RG_UNORM8: return GL_RG; case MESA_FORMAT_RG_SINT32: @@ -974,25 +1036,6 @@ _mesa_print_framebuffer(const struct gl_framebuffer *fb) } } -bool -_mesa_is_front_buffer_reading(const struct gl_framebuffer *fb) -{ - if (!fb || _mesa_is_user_fbo(fb)) - return false; - - return fb->_ColorReadBufferIndex == BUFFER_FRONT_LEFT; -} - -bool -_mesa_is_front_buffer_drawing(const struct gl_framebuffer *fb) -{ - if (!fb || _mesa_is_user_fbo(fb)) - return false; - - return (fb->_NumColorDrawBuffers >= 1 && - fb->_ColorDrawBufferIndexes[0] == BUFFER_FRONT_LEFT); -} - static inline GLuint _mesa_geometric_nonvalidated_samples(const struct gl_framebuffer *buffer) { @@ -1023,16 +1066,3 @@ _mesa_is_alpha_test_enabled(const struct gl_context *ctx) bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; return (ctx->Color.AlphaEnabled && !buffer0_is_integer); } - -/** - * Is alpha to coverage enabled and applicable to the currently bound - * framebuffer? - */ -bool -_mesa_is_alpha_to_coverage_enabled(const struct gl_context *ctx) -{ - bool buffer0_is_integer = ctx->DrawBuffer->_IntegerBuffers & 0x1; - return (ctx->Multisample.SampleAlphaToCoverage && - _mesa_is_multisample_enabled(ctx) && - !buffer0_is_integer); -} diff --git a/src/mesa/main/framebuffer.h b/src/mesa/main/framebuffer.h index 10952d38ef0..60c53e6af21 100644 --- a/src/mesa/main/framebuffer.h +++ b/src/mesa/main/framebuffer.h @@ -101,6 +101,33 @@ _mesa_geometric_layers(const struct gl_framebuffer *buffer) buffer->MaxNumLayers : buffer->DefaultGeometry.Layers; } +#define Y_0_TOP 1 +#define Y_0_BOTTOM 2 + +static inline GLuint +_mesa_fb_orientation(const struct gl_framebuffer *fb) +{ + if (fb && fb->FlipY) { + /* Drawing into a window (on-screen buffer). + * + * Negate Y scale to flip image vertically. + * The NDC Y coords prior to viewport transformation are in the range + * [y=-1=bottom, y=1=top] + * Hardware window coords are in the range [y=0=top, y=H-1=bottom] where + * H is the window height. + * Use the viewport transformation to invert Y. + */ + return Y_0_TOP; + } + else { + /* Drawing into user-created FBO (very likely a texture). + * + * For textures, T=0=Bottom, so by extension Y=0=Bottom for rendering. + */ + return Y_0_BOTTOM; + } +} + extern void _mesa_update_draw_buffer_bounds(struct gl_context *ctx, struct gl_framebuffer *drawFb); @@ -134,14 +161,11 @@ extern struct gl_renderbuffer * _mesa_get_read_renderbuffer_for_format(const struct gl_context *ctx, GLenum format); -extern void -_mesa_print_framebuffer(const struct gl_framebuffer *fb); - extern bool -_mesa_is_front_buffer_reading(const struct gl_framebuffer *fb); +_mesa_has_rtt_samples(const struct gl_framebuffer *fb); -extern bool -_mesa_is_front_buffer_drawing(const struct gl_framebuffer *fb); +extern void +_mesa_print_framebuffer(const struct gl_framebuffer *fb); extern bool _mesa_is_multisample_enabled(const struct gl_context *ctx); @@ -149,7 +173,7 @@ _mesa_is_multisample_enabled(const struct gl_context *ctx); extern bool _mesa_is_alpha_test_enabled(const struct gl_context *ctx); -extern bool -_mesa_is_alpha_to_coverage_enabled(const struct gl_context *ctx); +void +_mesa_draw_buffer_allocate(struct gl_context *ctx); #endif /* FRAMEBUFFER_H */ diff --git a/src/mesa/main/genmipmap.c b/src/mesa/main/genmipmap.c index 36727bb7060..3d3b896a16c 100644 --- a/src/mesa/main/genmipmap.c +++ b/src/mesa/main/genmipmap.c @@ -37,6 +37,9 @@ #include "teximage.h" #include "texobj.h" #include "hash.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_gen_mipmap.h" bool _mesa_is_valid_generate_texture_mipmap_target(struct gl_context *ctx, @@ -52,10 +55,10 @@ _mesa_is_valid_generate_texture_mipmap_target(struct gl_context *ctx, error = false; break; case GL_TEXTURE_3D: - error = ctx->API == API_OPENGLES; + error = _mesa_is_gles1(ctx); break; case GL_TEXTURE_CUBE_MAP: - error = !ctx->Extensions.ARB_texture_cube_map; + error = false; break; case GL_TEXTURE_1D_ARRAY: error = _mesa_is_gles(ctx) || !ctx->Extensions.EXT_texture_array; @@ -84,15 +87,10 @@ _mesa_is_valid_generate_texture_mipmap_internalformat(struct gl_context *ctx, * not specified with an unsized internal format from table 8.3 or a * sized internal format that is both color-renderable and * texture-filterable according to table 8.10." - * - * GL_EXT_texture_format_BGRA8888 adds a GL_BGRA_EXT unsized internal - * format, and includes it in a very similar looking table. So we - * include it here as well. */ return internalformat == GL_RGBA || internalformat == GL_RGB || internalformat == GL_LUMINANCE_ALPHA || internalformat == GL_LUMINANCE || internalformat == GL_ALPHA || - internalformat == GL_BGRA_EXT || (_mesa_is_es3_color_renderable(ctx, internalformat) && _mesa_is_es3_texture_filterable(ctx, internalformat)); } @@ -131,6 +129,8 @@ generate_texture_mipmap(struct gl_context *ctx, _mesa_lock_texture(ctx, texObj); + texObj->External = GL_FALSE; + srcImage = _mesa_select_tex_image(texObj, target, texObj->Attrib.BaseLevel); if (caller) { if (!srcImage) { @@ -148,6 +148,20 @@ generate_texture_mipmap(struct gl_context *ctx, _mesa_enum_to_string(srcImage->InternalFormat)); return; } + + /* The GLES 2.0 spec says: + * + * "If the level zero array is stored in a compressed internal format, + * the error INVALID_OPERATION is generated." + * + * and this text is gone from the GLES 3.0 spec. + */ + if (_mesa_is_gles2(ctx) && ctx->Version < 30 && + _mesa_is_format_compressed(srcImage->TexFormat)) { + _mesa_unlock_texture(ctx, texObj); + _mesa_error(ctx, GL_INVALID_OPERATION, "generate mipmaps on compressed texture"); + return; + } } if (srcImage->Width == 0 || srcImage->Height == 0) { @@ -158,12 +172,12 @@ generate_texture_mipmap(struct gl_context *ctx, if (target == GL_TEXTURE_CUBE_MAP) { GLuint face; for (face = 0; face < 6; face++) { - ctx->Driver.GenerateMipmap(ctx, - GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texObj); + st_generate_mipmap(ctx, + GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, texObj); } } else { - ctx->Driver.GenerateMipmap(ctx, target, texObj); + st_generate_mipmap(ctx, target, texObj); } _mesa_unlock_texture(ctx, texObj); } diff --git a/src/mesa/main/genmipmap.h b/src/mesa/main/genmipmap.h index c661f2184c7..09ae054ea48 100644 --- a/src/mesa/main/genmipmap.h +++ b/src/mesa/main/genmipmap.h @@ -26,7 +26,7 @@ #ifndef GENMIPMAP_H #define GENMIPMAP_H -#include "glheader.h" +#include "util/glheader.h" bool _mesa_is_valid_generate_texture_mipmap_target(struct gl_context *ctx, @@ -35,22 +35,4 @@ bool _mesa_is_valid_generate_texture_mipmap_internalformat(struct gl_context *ctx, GLenum internalformat); -void GLAPIENTRY -_mesa_GenerateMipmap_no_error(GLenum target); - -extern void GLAPIENTRY -_mesa_GenerateMipmap(GLenum target); - -void GLAPIENTRY -_mesa_GenerateTextureMipmap_no_error(GLuint texture); - -extern void GLAPIENTRY -_mesa_GenerateTextureMipmap(GLuint texture); - -extern void GLAPIENTRY -_mesa_GenerateTextureMipmapEXT(GLuint texture, GLenum target); - -extern void GLAPIENTRY -_mesa_GenerateMultiTexMipmapEXT(GLenum texunit, GLenum target); - #endif /* GENMIPMAP_H */ diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index f1c0d042baf..67d9b855c0f 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -23,7 +23,7 @@ * Author: Kristian Høgsberg <krh@bitplanet.net> */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "blend.h" #include "debug_output.h" @@ -33,7 +33,9 @@ #include "extensions.h" #include "get.h" #include "macros.h" +#include "multisample.h" #include "mtypes.h" +#include "queryobj.h" #include "spirv_extensions.h" #include "state.h" #include "texcompress.h" @@ -43,6 +45,9 @@ #include "stencil.h" #include "version.h" +#include "state_tracker/st_context.h" +#include "api_exec_decl.h" + /* This is a table driven implemetation of the glGet*v() functions. * The basic idea is that most getters just look up an int somewhere * in struct gl_context and then convert it to a bool or float according to @@ -78,8 +83,8 @@ FLOAT_TO_BOOLEAN(GLfloat X) static inline GLint FLOAT_TO_FIXED(GLfloat F) { - return ( ((F) * 65536.0f > INT_MAX) ? INT_MAX : - ((F) * 65536.0f < INT_MIN) ? INT_MIN : + return ( ((F) * 65536.0f > (float)INT32_MAX) ? INT32_MAX : + ((F) * 65536.0f < (float)INT32_MIN) ? INT32_MIN : (GLint) ((F) * 65536.0f) ); } @@ -187,6 +192,8 @@ enum value_extra { EXTRA_VERSION_43, EXTRA_API_GL, EXTRA_API_GL_CORE, + EXTRA_API_GL_COMPAT, + EXTRA_API_ES, EXTRA_API_ES2, EXTRA_API_ES3, EXTRA_API_ES31, @@ -225,6 +232,7 @@ union value { GLdouble value_double_2[2]; GLmatrix *value_matrix; GLint value_int; + GLint value_int_2[2]; GLint value_int_4[4]; GLint64 value_int64; GLenum value_enum; @@ -312,6 +320,13 @@ union value { * behavior, you would need to make a custom EXTRA_ enum. */ +static const int extra_new_buffers_compat_es[] = { + EXTRA_API_GL_COMPAT, + EXTRA_API_ES, + EXTRA_NEW_BUFFERS, + EXTRA_END +}; + static const int extra_new_buffers[] = { EXTRA_NEW_BUFFERS, EXTRA_END @@ -506,7 +521,19 @@ static const int extra_INTEL_conservative_rasterization[] = { EXTRA_END }; -EXTRA_EXT(ARB_texture_cube_map); +static const int extra_ARB_timer_query_or_EXT_disjoint_timer_query[] = { + EXT(ARB_timer_query), + EXT(EXT_disjoint_timer_query), + EXTRA_END +}; + +static const int extra_ARB_framebuffer_object_or_EXT_framebuffer_multisample_or_EXT_multisampled_render_to_texture[] = { + EXT(ARB_framebuffer_object), + EXT(EXT_framebuffer_multisample), + EXT(EXT_multisampled_render_to_texture), + EXTRA_END +}; + EXTRA_EXT(EXT_texture_array); EXTRA_EXT(NV_fog_distance); EXTRA_EXT(EXT_texture_filter_anisotropic); @@ -519,22 +546,18 @@ EXTRA_EXT(ATI_fragment_shader); EXTRA_EXT(EXT_provoking_vertex); EXTRA_EXT(ARB_fragment_shader); EXTRA_EXT(ARB_fragment_program); -EXTRA_EXT2(ARB_framebuffer_object, EXT_framebuffer_multisample); EXTRA_EXT(ARB_seamless_cube_map); EXTRA_EXT(ARB_sync); EXTRA_EXT(ARB_vertex_shader); EXTRA_EXT(EXT_transform_feedback); EXTRA_EXT(ARB_transform_feedback3); -EXTRA_EXT(EXT_pixel_buffer_object); EXTRA_EXT(ARB_vertex_program); -EXTRA_EXT(ARB_point_sprite); EXTRA_EXT2(ARB_vertex_program, ARB_fragment_program); EXTRA_EXT(ARB_color_buffer_float); EXTRA_EXT(EXT_framebuffer_sRGB); EXTRA_EXT(OES_EGL_image_external); EXTRA_EXT(ARB_blend_func_extended); EXTRA_EXT(ARB_uniform_buffer_object); -EXTRA_EXT(ARB_timer_query); EXTRA_EXT2(ARB_texture_cube_map_array, OES_texture_cube_map_array); EXTRA_EXT(ARB_texture_buffer_range); EXTRA_EXT(ARB_texture_multisample); @@ -567,6 +590,14 @@ EXTRA_EXT(ARB_sample_locations); EXTRA_EXT(AMD_framebuffer_multisample_advanced); EXTRA_EXT(ARB_spirv_extensions); EXTRA_EXT(NV_viewport_swizzle); +EXTRA_EXT(ARB_sparse_texture); + +static const int extra_ARB_gl_spirv_or_es2_compat[] = { + EXT(ARB_gl_spirv), + EXT(ARB_ES2_compatibility), + EXTRA_API_ES2, + EXTRA_END +}; static const int extra_ARB_color_buffer_float_or_glcore[] = { @@ -810,12 +841,12 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_TEXTURE_COORD_ARRAY_SIZE: array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)]; - v->value_int = array->Format.Size; + v->value_int = array->Format.User.Size; break; case GL_VERTEX_ARRAY_SIZE: array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_POS]; - v->value_int = array->Format.Size; + v->value_int = array->Format.User.Size; break; case GL_ACTIVE_TEXTURE_ARB: @@ -963,6 +994,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu _mesa_get_device_uuid(ctx, v->value_int_4); break; + /* GL_EXT_memory_object_win32 */ + case GL_DEVICE_LUID_EXT: + _mesa_get_device_luid(ctx, v->value_int_2); + break; + case GL_DEVICE_NODE_MASK_EXT: + v->value_int = ctx->pipe->screen->get_device_node_mask(ctx->pipe->screen); + break; + /* GL_EXT_packed_float */ case GL_RGBA_SIGNED_COMPONENTS_EXT: { @@ -1030,11 +1069,11 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu /* ARB_vertex_array_bgra */ case GL_COLOR_ARRAY_SIZE: array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR0]; - v->value_int = array->Format.Format == GL_BGRA ? GL_BGRA : array->Format.Size; + v->value_int = array->Format.User.Bgra ? GL_BGRA : array->Format.User.Size; break; case GL_SECONDARY_COLOR_ARRAY_SIZE: array = &ctx->Array.VAO->VertexAttrib[VERT_ATTRIB_COLOR1]; - v->value_int = array->Format.Format == GL_BGRA ? GL_BGRA : array->Format.Size; + v->value_int = array->Format.User.Bgra ? GL_BGRA : array->Format.User.Size; break; /* ARB_copy_buffer */ @@ -1171,12 +1210,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu break; /* GL_ARB_timer_query */ case GL_TIMESTAMP: - if (ctx->Driver.GetTimestamp) { - v->value_int64 = ctx->Driver.GetTimestamp(ctx); - } - else { - _mesa_problem(ctx, "driver doesn't implement GetTimestamp"); - } + v->value_int64 = _mesa_get_timestamp(ctx); break; /* GL_KHR_DEBUG */ case GL_DEBUG_OUTPUT: @@ -1236,9 +1270,11 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu case GL_GPU_MEMORY_INFO_EVICTION_COUNT_NVX: case GL_GPU_MEMORY_INFO_EVICTED_MEMORY_NVX: { - struct gl_memory_info info; + struct pipe_memory_info info; + struct pipe_screen *screen = ctx->pipe->screen; - ctx->Driver.QueryMemoryInfo(ctx, &info); + assert(screen->query_memory_info); + screen->query_memory_info(screen, &info); if (d->pname == GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX) v->value_int = info.total_device_memory; @@ -1282,6 +1318,14 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu v->value_int_n.ints[0] = GL_PROGRAM_BINARY_FORMAT_MESA; } break; + /* GL_ARB_gl_spirv */ + case GL_SHADER_BINARY_FORMATS: + assert(ctx->Const.NumShaderBinaryFormats <= 1); + v->value_int_n.n = MIN2(ctx->Const.NumShaderBinaryFormats, 1); + if (ctx->Const.NumShaderBinaryFormats > 0) { + v->value_int_n.ints[0] = GL_SHADER_BINARY_FORMAT_SPIR_V; + } + break; /* ARB_spirv_extensions */ case GL_NUM_SPIR_V_EXTENSIONS: v->value_int = _mesa_get_spirv_extension_count(ctx); @@ -1289,11 +1333,7 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu /* GL_EXT_disjoint_timer_query */ case GL_GPU_DISJOINT_EXT: { - simple_mtx_lock(&ctx->Shared->Mutex); - v->value_int = ctx->Shared->DisjointOperation; - /* Reset state as expected by the spec. */ - ctx->Shared->DisjointOperation = false; - simple_mtx_unlock(&ctx->Shared->Mutex); + v->value_int = 0; } break; /* GL_ARB_sample_locations */ @@ -1311,8 +1351,8 @@ find_custom_value(struct gl_context *ctx, const struct value_desc *d, union valu break; } - ctx->Driver.GetProgrammableSampleCaps(ctx, ctx->DrawBuffer, - &bits, &width, &height); + _mesa_GetProgrammableSampleCaps(ctx, ctx->DrawBuffer, + &bits, &width, &height); if (d->pname == GL_SAMPLE_LOCATION_PIXEL_GRID_WIDTH_ARB) v->value_uint = width; @@ -1399,9 +1439,14 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d if (_mesa_is_desktop_gl(ctx) && version >= 43) api_found = GL_TRUE; break; + case EXTRA_API_ES: + api_check = GL_TRUE; + if (_mesa_is_gles(ctx)) + api_found = GL_TRUE; + break; case EXTRA_API_ES2: api_check = GL_TRUE; - if (ctx->API == API_OPENGLES2) + if (_mesa_is_gles2(ctx)) api_found = GL_TRUE; break; case EXTRA_API_ES3: @@ -1426,7 +1471,12 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d break; case EXTRA_API_GL_CORE: api_check = GL_TRUE; - if (ctx->API == API_OPENGL_CORE) + if (_mesa_is_desktop_gl_core(ctx)) + api_found = GL_TRUE; + break; + case EXTRA_API_GL_COMPAT: + api_check = GL_TRUE; + if (_mesa_is_desktop_gl_compat(ctx)) api_found = GL_TRUE; break; case EXTRA_NEW_BUFFERS: @@ -1476,8 +1526,9 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d break; case EXTRA_EXT_SHADER_IMAGE_GS: api_check = GL_TRUE; - if (ctx->Extensions.ARB_shader_image_load_store && - _mesa_has_geometry_shaders(ctx)) + if ((ctx->Extensions.ARB_shader_image_load_store || + _mesa_is_gles31(ctx)) && + _mesa_has_geometry_shaders(ctx)) api_found = GL_TRUE; break; case EXTRA_EXT_ATOMICS_TESS: @@ -1510,7 +1561,7 @@ check_extra(struct gl_context *ctx, const char *func, const struct value_desc *d break; case EXTRA_EXT_PROVOKING_VERTEX_32: api_check = GL_TRUE; - if (ctx->API == API_OPENGL_COMPAT || version == 32) + if (_mesa_is_desktop_gl_compat(ctx) || version == 32) api_found = ctx->Extensions.EXT_provoking_vertex; break; case EXTRA_END: @@ -1574,7 +1625,7 @@ find_value(const char *func, GLenum pname, void **p, union value *v) * end. */ STATIC_ASSERT(ARRAY_SIZE(table_set) == API_OPENGL_LAST + 4); - if (ctx->API == API_OPENGLES2) { + if (_mesa_is_gles2(ctx)) { if (ctx->Version >= 32) api = API_OPENGL_LAST + 3; else if (ctx->Version >= 31) @@ -2019,24 +2070,33 @@ _mesa_GetIntegerv(GLenum pname, GLint *params) break; case TYPE_INT_4: - case TYPE_UINT_4: params[3] = ((GLint *) p)[3]; FALLTHROUGH; case TYPE_INT_3: - case TYPE_UINT_3: params[2] = ((GLint *) p)[2]; FALLTHROUGH; case TYPE_INT_2: - case TYPE_UINT_2: case TYPE_ENUM_2: params[1] = ((GLint *) p)[1]; FALLTHROUGH; case TYPE_INT: - case TYPE_UINT: case TYPE_ENUM: params[0] = ((GLint *) p)[0]; break; + case TYPE_UINT_4: + params[3] = MIN2(((GLuint *) p)[3], INT_MAX); + FALLTHROUGH; + case TYPE_UINT_3: + params[2] = MIN2(((GLuint *) p)[2], INT_MAX); + FALLTHROUGH; + case TYPE_UINT_2: + params[1] = MIN2(((GLuint *) p)[1], INT_MAX); + FALLTHROUGH; + case TYPE_UINT: + params[0] = MIN2(((GLuint *) p)[0], INT_MAX); + break; + case TYPE_ENUM16: params[0] = ((GLenum16 *) p)[0]; break; @@ -2432,10 +2492,11 @@ tex_binding_to_index(const struct gl_context *ctx, GLenum binding) case GL_TEXTURE_BINDING_2D: return TEXTURE_2D_INDEX; case GL_TEXTURE_BINDING_3D: - return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1; + return (ctx->API != API_OPENGLES && + !(_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D)) + ? TEXTURE_3D_INDEX : -1; case GL_TEXTURE_BINDING_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map - ? TEXTURE_CUBE_INDEX : -1; + return TEXTURE_CUBE_INDEX; case GL_TEXTURE_BINDING_RECTANGLE: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle ? TEXTURE_RECT_INDEX : -1; @@ -2716,7 +2777,7 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) return TYPE_INT; case GL_VERTEX_BINDING_BUFFER: - if (ctx->API == API_OPENGLES2 && ctx->Version < 31) + if (_mesa_is_gles2(ctx) && ctx->Version < 31) goto invalid_enum; if (index >= ctx->Const.Program[MESA_SHADER_VERTEX].MaxAttribs) goto invalid_value; @@ -2825,8 +2886,8 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) goto invalid_enum; if (index >= 3) goto invalid_value; - v->value_int = ctx->Const.MaxComputeWorkGroupCount[index]; - return TYPE_INT; + v->value_uint = ctx->Const.MaxComputeWorkGroupCount[index]; + return TYPE_UINT; case GL_MAX_COMPUTE_WORK_GROUP_SIZE: if (!_mesa_has_compute_shaders(ctx)) @@ -2859,6 +2920,17 @@ find_value_indexed(const char *func, GLenum pname, GLuint index, union value *v) goto invalid_value; _mesa_get_device_uuid(ctx, v->value_int_4); return TYPE_INT_4; + /* GL_EXT_memory_object_win32 */ + case GL_DEVICE_LUID_EXT: + if (index >= 1) + goto invalid_value; + _mesa_get_device_luid(ctx, v->value_int_2); + return TYPE_INT_2; + case GL_DEVICE_NODE_MASK_EXT: + if (index >= 1) + goto invalid_value; + v->value_int = ctx->pipe->screen->get_device_node_mask(ctx->pipe->screen); + return TYPE_INT; /* GL_EXT_direct_state_access */ case GL_TEXTURE_1D: case GL_TEXTURE_2D: @@ -2999,16 +3071,23 @@ _mesa_GetIntegeri_v( GLenum pname, GLuint index, GLint *params ) break; case TYPE_INT: - case TYPE_UINT: params[0] = v.value_int; break; + case TYPE_UINT: + params[0] = MIN2(v.value_uint, INT_MAX); + break; case TYPE_INT_4: - case TYPE_UINT_4: params[0] = v.value_int_4[0]; params[1] = v.value_int_4[1]; params[2] = v.value_int_4[2]; params[3] = v.value_int_4[3]; break; + case TYPE_UINT_4: + params[0] = MIN2((GLuint)v.value_int_4[0], INT_MAX); + params[1] = MIN2((GLuint)v.value_int_4[1], INT_MAX); + params[2] = MIN2((GLuint)v.value_int_4[2], INT_MAX); + params[3] = MIN2((GLuint)v.value_int_4[3], INT_MAX); + break; case TYPE_INT64: params[0] = INT64_TO_INT(v.value_int64); break; @@ -3035,7 +3114,7 @@ _mesa_GetInteger64i_v( GLenum pname, GLuint index, GLint64 *params ) params[3] = v.value_int_4[3]; break; case TYPE_UINT: - params[0] = (GLuint) v.value_int; + params[0] = v.value_uint; break; case TYPE_UINT_4: params[0] = (GLuint) v.value_int_4[0]; @@ -3352,24 +3431,33 @@ _mesa_GetFixedv(GLenum pname, GLfixed *params) break; case TYPE_INT_4: - case TYPE_UINT_4: params[3] = INT_TO_FIXED(((GLint *) p)[3]); FALLTHROUGH; case TYPE_INT_3: - case TYPE_UINT_3: params[2] = INT_TO_FIXED(((GLint *) p)[2]); FALLTHROUGH; case TYPE_INT_2: - case TYPE_UINT_2: case TYPE_ENUM_2: params[1] = INT_TO_FIXED(((GLint *) p)[1]); FALLTHROUGH; case TYPE_INT: - case TYPE_UINT: case TYPE_ENUM: params[0] = INT_TO_FIXED(((GLint *) p)[0]); break; + case TYPE_UINT_4: + params[3] = INT_TO_FIXED(((GLuint *) p)[3]); + FALLTHROUGH; + case TYPE_UINT_3: + params[2] = INT_TO_FIXED(((GLuint *) p)[2]); + FALLTHROUGH; + case TYPE_UINT_2: + params[1] = INT_TO_FIXED(((GLuint *) p)[1]); + FALLTHROUGH; + case TYPE_UINT: + params[0] = INT_TO_FIXED(((GLuint *) p)[0]); + break; + case TYPE_ENUM16: params[0] = INT_TO_FIXED((GLint)(((GLenum16 *) p)[0])); break; diff --git a/src/mesa/main/get.h b/src/mesa/main/get.h index de9b2a27e72..c7399b9bc84 100644 --- a/src/mesa/main/get.h +++ b/src/mesa/main/get.h @@ -32,66 +32,7 @@ #define GET_H -#include "glheader.h" - - -extern void GLAPIENTRY -_mesa_GetBooleanv( GLenum pname, GLboolean *params ); - -extern void GLAPIENTRY -_mesa_GetDoublev( GLenum pname, GLdouble *params ); - -extern void GLAPIENTRY -_mesa_GetFloatv( GLenum pname, GLfloat *params ); - -extern void GLAPIENTRY -_mesa_GetIntegerv( GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_mesa_GetInteger64v( GLenum pname, GLint64 *params ); - -extern void GLAPIENTRY -_mesa_GetFixedv(GLenum pname, GLfixed *params); - -extern void GLAPIENTRY -_mesa_GetUnsignedBytevEXT(GLenum pname, GLubyte *data); - -extern void GLAPIENTRY -_mesa_GetBooleani_v( GLenum pname, GLuint index, GLboolean *params ); - -extern void GLAPIENTRY -_mesa_GetIntegeri_v( GLenum pname, GLuint index, GLint *params ); - -extern void GLAPIENTRY -_mesa_GetInteger64i_v( GLenum pname, GLuint index, GLint64 *params ); - -extern void GLAPIENTRY -_mesa_GetPointerv( GLenum pname, GLvoid **params ); - -extern void GLAPIENTRY -_mesa_GetPointerIndexedvEXT( GLenum pname, GLuint index, GLvoid **params ); - -extern void GLAPIENTRY -_mesa_GetFloati_v(GLenum target, GLuint index, GLfloat *data); - -extern void GLAPIENTRY -_mesa_GetDoublei_v(GLenum target, GLuint index, GLdouble *data); - -extern void GLAPIENTRY -_mesa_GetUnsignedBytei_vEXT(GLenum target, GLuint index, GLubyte *data); - -extern const GLubyte * GLAPIENTRY -_mesa_GetString( GLenum name ); - -extern const GLubyte * GLAPIENTRY -_mesa_GetStringi(GLenum name, GLuint index); - -extern GLenum GLAPIENTRY -_mesa_GetError( void ); - -/* GL_ARB_robustness */ -extern GLenum GLAPIENTRY -_mesa_GetGraphicsResetStatusARB( void ); +#include "util/glheader.h" struct gl_vertex_array_object; diff --git a/src/mesa/main/get_hash_generator.py b/src/mesa/main/get_hash_generator.py index 3e9032bd4c8..fb006ad82d6 100644 --- a/src/mesa/main/get_hash_generator.py +++ b/src/mesa/main/get_hash_generator.py @@ -28,8 +28,6 @@ # Generate a C header file containing hash tables of glGet parameter # names for each GL API. The generated file is to be included by glGet.c -from __future__ import print_function - import os, sys, getopt from collections import defaultdict import get_hash_params diff --git a/src/mesa/main/get_hash_params.py b/src/mesa/main/get_hash_params.py index 318b639014d..267efa5b3be 100644 --- a/src/mesa/main/get_hash_params.py +++ b/src/mesa/main/get_hash_params.py @@ -3,12 +3,10 @@ descriptor=[ [ "ALPHA_BITS", "BUFFER_INT(Visual.alphaBits), extra_new_buffers" ], [ "BLEND", "CONTEXT_BIT0(Color.BlendEnabled), NO_EXTRA" ], [ "BLEND_SRC", "CONTEXT_ENUM16(Color.Blend[0].SrcRGB), NO_EXTRA" ], - [ "BLUE_BITS", "BUFFER_INT(Visual.blueBits), extra_new_buffers" ], [ "COLOR_CLEAR_VALUE", "LOC_CUSTOM, TYPE_FLOATN_4, 0, NO_EXTRA" ], [ "COLOR_WRITEMASK", "LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA" ], [ "CULL_FACE", "CONTEXT_BOOL(Polygon.CullFlag), NO_EXTRA" ], [ "CULL_FACE_MODE", "CONTEXT_ENUM16(Polygon.CullFaceMode), NO_EXTRA" ], - [ "DEPTH_BITS", "BUFFER_INT(Visual.depthBits), extra_new_buffers" ], [ "DEPTH_CLEAR_VALUE", "CONTEXT_FIELD(Depth.Clear, TYPE_DOUBLEN), NO_EXTRA" ], [ "DEPTH_FUNC", "CONTEXT_ENUM16(Depth.Func), NO_EXTRA" ], [ "DEPTH_RANGE", "LOC_CUSTOM, TYPE_DOUBLEN_2, 0, NO_EXTRA" ], @@ -16,7 +14,6 @@ descriptor=[ [ "DEPTH_WRITEMASK", "CONTEXT_BOOL(Depth.Mask), NO_EXTRA" ], [ "DITHER", "CONTEXT_BOOL(Color.DitherFlag), NO_EXTRA" ], [ "FRONT_FACE", "CONTEXT_ENUM16(Polygon.FrontFace), NO_EXTRA" ], - [ "GREEN_BITS", "BUFFER_INT(Visual.greenBits), extra_new_buffers" ], [ "LINE_WIDTH", "CONTEXT_FLOAT(Line.Width), NO_EXTRA" ], [ "ALIASED_LINE_WIDTH_RANGE", "CONTEXT_FLOAT2(Const.MinLineWidth), NO_EXTRA" ], [ "MAX_ELEMENTS_VERTICES", "CONTEXT_INT(Const.MaxArrayLockSize), NO_EXTRA" ], @@ -28,10 +25,8 @@ descriptor=[ [ "POLYGON_OFFSET_FACTOR", "CONTEXT_FLOAT(Polygon.OffsetFactor ), NO_EXTRA" ], [ "POLYGON_OFFSET_UNITS", "CONTEXT_FLOAT(Polygon.OffsetUnits ), NO_EXTRA" ], [ "POLYGON_OFFSET_FILL", "CONTEXT_BOOL(Polygon.OffsetFill), NO_EXTRA" ], - [ "RED_BITS", "BUFFER_INT(Visual.redBits), extra_new_buffers" ], [ "SCISSOR_BOX", "LOC_CUSTOM, TYPE_INT_4, 0, NO_EXTRA" ], [ "SCISSOR_TEST", "LOC_CUSTOM, TYPE_BOOLEAN, NO_OFFSET, NO_EXTRA" ], - [ "STENCIL_BITS", "BUFFER_INT(Visual.stencilBits), extra_new_buffers" ], [ "STENCIL_CLEAR_VALUE", "CONTEXT_INT(Stencil.Clear), NO_EXTRA" ], [ "STENCIL_FAIL", "LOC_CUSTOM, TYPE_ENUM16, NO_OFFSET, NO_EXTRA" ], [ "STENCIL_FUNC", "LOC_CUSTOM, TYPE_ENUM16, NO_OFFSET, NO_EXTRA" ], @@ -56,9 +51,9 @@ descriptor=[ # extensions below should mark the dependency. # GL_ARB_texture_cube_map - [ "TEXTURE_BINDING_CUBE_MAP_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_CUBE_INDEX, extra_ARB_texture_cube_map" ], + [ "TEXTURE_BINDING_CUBE_MAP_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_CUBE_INDEX, NO_EXTRA" ], # XXX: OES_texture_cube_map - [ "MAX_CUBE_MAP_TEXTURE_SIZE_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_context, Const.MaxCubeTextureLevels), extra_ARB_texture_cube_map" ], + [ "MAX_CUBE_MAP_TEXTURE_SIZE_ARB", "LOC_CUSTOM, TYPE_INT, offsetof(struct gl_context, Const.MaxCubeTextureLevels), NO_EXTRA" ], # XXX: OES_blend_subtract [ "BLEND_SRC_RGB", "CONTEXT_ENUM16(Color.Blend[0].SrcRGB), NO_EXTRA" ], @@ -143,6 +138,10 @@ descriptor=[ [ "NUM_DEVICE_UUIDS_EXT", "LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA" ], [ "DRIVER_UUID_EXT", "LOC_CUSTOM, TYPE_INT_4, NO_OFFSET, NO_EXTRA" ], [ "DEVICE_UUID_EXT", "LOC_CUSTOM, TYPE_INT_4, NO_OFFSET, NO_EXTRA" ], + +# GL_EXT_memory_object_win32 + [ "DEVICE_LUID_EXT", "LOC_CUSTOM, TYPE_INT_2, NO_OFFSET, NO_EXTRA" ], + [ "DEVICE_NODE_MASK_EXT", "LOC_CUSTOM, TYPE_INT_4, NO_OFFSET, NO_EXTRA" ], ]}, # Enums in OpenGL and GLES1 @@ -213,18 +212,18 @@ descriptor=[ [ "TEXTURE_STACK_DEPTH", "LOC_CUSTOM, TYPE_INT, 0, extra_valid_texture_unit" ], [ "VERTEX_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], [ "VERTEX_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], - [ "VERTEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_POS].Format.Type), NO_EXTRA" ], + [ "VERTEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_POS].Format.User.Type), NO_EXTRA" ], [ "VERTEX_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_POS].Stride), NO_EXTRA" ], [ "NORMAL_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], - [ "NORMAL_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_NORMAL].Format.Type), NO_EXTRA" ], + [ "NORMAL_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_NORMAL].Format.User.Type), NO_EXTRA" ], [ "NORMAL_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_NORMAL].Stride), NO_EXTRA" ], [ "COLOR_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], [ "COLOR_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], - [ "COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR0].Format.Type), NO_EXTRA" ], + [ "COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR0].Format.User.Type), NO_EXTRA" ], [ "COLOR_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_COLOR0].Stride), NO_EXTRA" ], [ "TEXTURE_COORD_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], [ "TEXTURE_COORD_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], - [ "TEXTURE_COORD_ARRAY_TYPE", "LOC_CUSTOM, TYPE_ENUM16, offsetof(struct gl_array_attributes, Format.Type), NO_EXTRA" ], + [ "TEXTURE_COORD_ARRAY_TYPE", "LOC_CUSTOM, TYPE_ENUM16, offsetof(struct gl_array_attributes, Format.User.Type), NO_EXTRA" ], [ "TEXTURE_COORD_ARRAY_STRIDE", "LOC_CUSTOM, TYPE_SHORT, offsetof(struct gl_array_attributes, Stride), NO_EXTRA" ], # GL_ARB_multitexture @@ -247,18 +246,27 @@ descriptor=[ [ "TEXTURE_COORD_ARRAY_BUFFER_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, NO_OFFSET, NO_EXTRA" ], # GL_OES_point_sprite - [ "POINT_SPRITE", "CONTEXT_BOOL(Point.PointSprite), extra_ARB_point_sprite" ], + [ "POINT_SPRITE", "CONTEXT_BOOL(Point.PointSprite), NO_EXTRA" ], ]}, { "apis": ["GLES"], "params": [ # OES_point_size_array [ "POINT_SIZE_ARRAY_OES", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], - [ "POINT_SIZE_ARRAY_TYPE_OES", "ARRAY_FIELD(VertexAttrib[VERT_ATTRIB_POINT_SIZE].Format.Type, TYPE_ENUM16), NO_EXTRA" ], + [ "POINT_SIZE_ARRAY_TYPE_OES", "ARRAY_FIELD(VertexAttrib[VERT_ATTRIB_POINT_SIZE].Format.User.Type, TYPE_ENUM16), NO_EXTRA" ], [ "POINT_SIZE_ARRAY_STRIDE_OES", "ARRAY_FIELD(VertexAttrib[VERT_ATTRIB_POINT_SIZE].Stride, TYPE_SHORT), NO_EXTRA" ], [ "POINT_SIZE_ARRAY_BUFFER_BINDING_OES", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], ]}, +# Enums in legacy OpenGL and GLES +{ "apis": ["GL", "GLES", "GLES2", "GLES3"], "params": [ + [ "RED_BITS", "BUFFER_INT(Visual.redBits), extra_new_buffers_compat_es" ], + [ "GREEN_BITS", "BUFFER_INT(Visual.greenBits), extra_new_buffers_compat_es" ], + [ "BLUE_BITS", "BUFFER_INT(Visual.blueBits), extra_new_buffers_compat_es" ], + [ "DEPTH_BITS", "BUFFER_INT(Visual.depthBits), extra_new_buffers_compat_es" ], + [ "STENCIL_BITS", "BUFFER_INT(Visual.stencilBits), extra_new_buffers_compat_es" ], +]}, + # Enums in GLES2, GLES3 { "apis": ["GLES2", "GLES3"], "params": [ [ "GPU_DISJOINT_EXT", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_disjoint_timer_query" ], @@ -339,8 +347,10 @@ descriptor=[ [ "MAX_VARYING_VECTORS", "CONTEXT_INT(Const.MaxVarying), extra_ARB_ES2_compatibility_api_es2" ], [ "MAX_VERTEX_UNIFORM_VECTORS", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_ES2_compatibility_api_es2" ], [ "MAX_FRAGMENT_UNIFORM_VECTORS", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_ES2_compatibility_api_es2" ], - [ "NUM_SHADER_BINARY_FORMATS", "CONST(0), extra_ARB_ES2_compatibility_api_es2" ], - [ "SHADER_BINARY_FORMATS", "LOC_CUSTOM, TYPE_INVALID, 0, extra_ARB_ES2_compatibility_api_es2" ], + +# GL_ARB_ES2_compatibility / GL_ARB_gl_spirv + [ "NUM_SHADER_BINARY_FORMATS", "CONTEXT_UINT(Const.NumShaderBinaryFormats), extra_ARB_gl_spirv_or_es2_compat" ], + [ "SHADER_BINARY_FORMATS", "LOC_CUSTOM, TYPE_INT_N, 0, extra_ARB_gl_spirv_or_es2_compat" ], # GL_ARB_get_program_binary / GL_OES_get_program_binary [ "NUM_PROGRAM_BINARY_FORMATS", "CONTEXT_UINT(Const.NumProgramBinaryFormats), NO_EXTRA" ], @@ -387,12 +397,22 @@ descriptor=[ # GL_NV_alpha_to_coverage_dither_control [ "ALPHA_TO_COVERAGE_DITHER_MODE_NV", "CONTEXT_ENUM(Multisample.SampleAlphaToCoverageDitherControl ), NO_EXTRA" ], + +# GL_EXT_pixel_buffer_object + [ "PIXEL_PACK_BUFFER_BINDING_EXT", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], + [ "PIXEL_UNPACK_BUFFER_BINDING_EXT", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], + +# GL_ARB_framebuffer_object or GL_EXT_framebuffer_multisample or GL_EXT_multisampled_render_to_texture + [ "MAX_SAMPLES", "CONTEXT_INT(Const.MaxSamples), extra_ARB_framebuffer_object_or_EXT_framebuffer_multisample_or_EXT_multisampled_render_to_texture" ], ]}, # GLES3 is not a typo. { "apis": ["GL", "GLES", "GLES3", "GL_CORE"], "params": [ # GL_EXT_texture_lod_bias [ "MAX_TEXTURE_LOD_BIAS_EXT", "CONTEXT_FLOAT(Const.MaxTextureLodBias), NO_EXTRA" ], + +# GL_ARB_timer_query, GL_EXT_disjoint_timer_query + [ "TIMESTAMP", "LOC_CUSTOM, TYPE_INT64, 0, extra_ARB_timer_query_or_EXT_disjoint_timer_query" ], ]}, @@ -414,9 +434,6 @@ descriptor=[ # GL_ARB_fragment_shader [ "MAX_FRAGMENT_UNIFORM_COMPONENTS_ARB", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxUniformComponents), extra_ARB_fragment_shader" ], -# GL_ARB_framebuffer_object - [ "MAX_SAMPLES", "CONTEXT_INT(Const.MaxSamples), extra_ARB_framebuffer_object_EXT_framebuffer_multisample" ], - # GL_ARB_sampler_objects / GL 3.3 / GLES 3.0 [ "SAMPLER_BINDING", "LOC_CUSTOM, TYPE_INT, GL_SAMPLER_BINDING, NO_EXTRA" ], @@ -435,7 +452,7 @@ descriptor=[ [ "MAX_VERTEX_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_VERTEX].MaxUniformBlocks), extra_ARB_uniform_buffer_object" ], [ "MAX_FRAGMENT_UNIFORM_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxUniformBlocks), extra_ARB_uniform_buffer_object" ], [ "MAX_COMBINED_UNIFORM_BLOCKS", "CONTEXT_INT(Const.MaxCombinedUniformBlocks), extra_ARB_uniform_buffer_object" ], - [ "MAX_UNIFORM_BLOCK_SIZE", "CONTEXT_INT(Const.MaxUniformBlockSize), extra_ARB_uniform_buffer_object" ], + [ "MAX_UNIFORM_BLOCK_SIZE", "CONTEXT_UINT(Const.MaxUniformBlockSize), extra_ARB_uniform_buffer_object" ], [ "MAX_UNIFORM_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxUniformBufferBindings), extra_ARB_uniform_buffer_object" ], [ "MAX_COMBINED_VERTEX_UNIFORM_COMPONENTS", "CONTEXT_INT64(Const.Program[MESA_SHADER_VERTEX].MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object" ], [ "MAX_COMBINED_FRAGMENT_UNIFORM_COMPONENTS", "CONTEXT_INT64(Const.Program[MESA_SHADER_FRAGMENT].MaxCombinedUniformComponents), extra_ARB_uniform_buffer_object" ], @@ -454,10 +471,6 @@ descriptor=[ [ "MIN_PROGRAM_TEXEL_OFFSET", "CONTEXT_INT(Const.MinProgramTexelOffset), extra_GLSL_130_es3_gpushader4" ], [ "MAX_PROGRAM_TEXEL_OFFSET", "CONTEXT_INT(Const.MaxProgramTexelOffset), extra_GLSL_130_es3_gpushader4" ], -# GL_EXT_pixel_buffer_object - [ "PIXEL_PACK_BUFFER_BINDING_EXT", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_pixel_buffer_object" ], - [ "PIXEL_UNPACK_BUFFER_BINDING_EXT", "LOC_CUSTOM, TYPE_INT, 0, extra_EXT_pixel_buffer_object" ], - # GL_EXT_texture_array [ "TEXTURE_BINDING_2D_ARRAY", "LOC_CUSTOM, TYPE_INT, TEXTURE_2D_ARRAY_INDEX, extra_EXT_texture_array_es3" ], [ "MAX_ARRAY_TEXTURE_LAYERS_EXT", "CONTEXT_INT(Const.MaxArrayTextureLayers), extra_EXT_texture_array_es3" ], @@ -481,6 +494,10 @@ descriptor=[ # GL_EXT_framebuffer_EXT / GLES 3.0 + EXT_sRGB_write_control [ "FRAMEBUFFER_SRGB_EXT", "CONTEXT_BOOL(Color.sRGBEnabled), extra_EXT_framebuffer_sRGB" ], + +# GL_ARB_cull_distance, GL_EXT_clip_cull_distance + [ "MAX_CULL_DISTANCES", "CONTEXT_INT(Const.MaxClipPlanes), extra_ARB_cull_distance" ], + [ "MAX_COMBINED_CLIP_AND_CULL_DISTANCES", "CONTEXT_INT(Const.MaxClipPlanes), extra_ARB_cull_distance" ], ]}, { "apis": ["GLES", "GLES2"], "params": [ @@ -495,7 +512,7 @@ descriptor=[ # Enums in OpenGL and ES 3.1 { "apis": ["GL", "GL_CORE", "GLES31"], "params": [ # GL_ARB_texture_buffer_object / GL_OES_texture_buffer - [ "MAX_TEXTURE_BUFFER_SIZE_ARB", "CONTEXT_INT(Const.MaxTextureBufferSize), extra_texture_buffer_object" ], + [ "MAX_TEXTURE_BUFFER_SIZE_ARB", "CONTEXT_UINT(Const.MaxTextureBufferSize), extra_texture_buffer_object" ], [ "TEXTURE_BINDING_BUFFER_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ], [ "TEXTURE_BUFFER_DATA_STORE_BINDING_ARB", "LOC_CUSTOM, TYPE_INT, TEXTURE_BUFFER_INDEX, extra_texture_buffer_object" ], [ "TEXTURE_BUFFER_FORMAT_ARB", "LOC_CUSTOM, TYPE_INT, 0, extra_texture_buffer_object" ], @@ -574,7 +591,7 @@ descriptor=[ [ "MAX_FRAGMENT_SHADER_STORAGE_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_FRAGMENT].MaxShaderStorageBlocks), extra_ARB_shader_storage_buffer_object_es31" ], [ "MAX_COMPUTE_SHADER_STORAGE_BLOCKS", "CONTEXT_INT(Const.Program[MESA_SHADER_COMPUTE].MaxShaderStorageBlocks), extra_ARB_shader_storage_buffer_object_es31" ], [ "MAX_COMBINED_SHADER_STORAGE_BLOCKS", "CONTEXT_INT(Const.MaxCombinedShaderStorageBlocks), extra_ARB_shader_storage_buffer_object_es31" ], - [ "MAX_SHADER_STORAGE_BLOCK_SIZE", "CONTEXT_INT(Const.MaxShaderStorageBlockSize), extra_ARB_shader_storage_buffer_object_es31" ], + [ "MAX_SHADER_STORAGE_BLOCK_SIZE", "CONTEXT_UINT(Const.MaxShaderStorageBlockSize), extra_ARB_shader_storage_buffer_object_es31" ], [ "MAX_SHADER_STORAGE_BUFFER_BINDINGS", "CONTEXT_INT(Const.MaxShaderStorageBufferBindings), extra_ARB_shader_storage_buffer_object_es31" ], [ "SHADER_STORAGE_BUFFER_OFFSET_ALIGNMENT", "CONTEXT_INT(Const.ShaderStorageBufferOffsetAlignment), extra_ARB_shader_storage_buffer_object_es31" ], [ "SHADER_STORAGE_BUFFER_BINDING", "LOC_CUSTOM, TYPE_INT, 0, extra_ARB_shader_storage_buffer_object_es31" ], @@ -816,7 +833,7 @@ descriptor=[ [ "NORMAL_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ], [ "COLOR_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ], [ "INDEX_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], - [ "INDEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.Type), NO_EXTRA" ], + [ "INDEX_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.User.Type), NO_EXTRA" ], [ "INDEX_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Stride), NO_EXTRA" ], [ "INDEX_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ], [ "TEXTURE_COORD_ARRAY_COUNT_EXT", "CONST(0), NO_EXTRA" ], @@ -850,14 +867,14 @@ descriptor=[ [ "COLOR_SUM", "CONTEXT_BOOL(Fog.ColorSumEnabled), NO_EXTRA" ], [ "CURRENT_SECONDARY_COLOR", "CONTEXT_FIELD(Current.Attrib[VERT_ATTRIB_COLOR1][0], TYPE_FLOATN_4), extra_flush_current" ], [ "SECONDARY_COLOR_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], - [ "SECONDARY_COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR1].Format.Type), NO_EXTRA" ], + [ "SECONDARY_COLOR_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_COLOR1].Format.User.Type), NO_EXTRA" ], [ "SECONDARY_COLOR_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_COLOR1].Stride), NO_EXTRA" ], [ "SECONDARY_COLOR_ARRAY_SIZE", "LOC_CUSTOM, TYPE_INT, 0, NO_EXTRA" ], # GL_EXT_fog_coord [ "CURRENT_FOG_COORDINATE", "CONTEXT_FLOAT(Current.Attrib[VERT_ATTRIB_FOG][0]), extra_flush_current" ], [ "FOG_COORDINATE_ARRAY", "LOC_CUSTOM, TYPE_BOOLEAN, 0, NO_EXTRA" ], - [ "FOG_COORDINATE_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_FOG].Format.Type), NO_EXTRA" ], + [ "FOG_COORDINATE_ARRAY_TYPE", "ARRAY_ENUM16(VertexAttrib[VERT_ATTRIB_FOG].Format.User.Type), NO_EXTRA" ], [ "FOG_COORDINATE_ARRAY_STRIDE", "ARRAY_SHORT(VertexAttrib[VERT_ATTRIB_FOG].Stride), NO_EXTRA" ], [ "FOG_COORDINATE_SOURCE", "CONTEXT_ENUM16(Fog.FogCoordinateSource), NO_EXTRA" ], @@ -868,7 +885,7 @@ descriptor=[ [ "RASTER_POSITION_UNCLIPPED_IBM", "CONTEXT_BOOL(Transform.RasterPositionUnclipped), NO_EXTRA" ], # GL_ARB_point_sprite - [ "POINT_SPRITE_COORD_ORIGIN", "CONTEXT_ENUM16(Point.SpriteOrigin), extra_ARB_point_sprite" ], + [ "POINT_SPRITE_COORD_ORIGIN", "CONTEXT_ENUM16(Point.SpriteOrigin), NO_EXTRA" ], # GL_NV_texture_rectangle [ "TEXTURE_RECTANGLE_NV", "LOC_CUSTOM, TYPE_BOOLEAN, 0, extra_NV_texture_rectangle" ], @@ -954,6 +971,12 @@ descriptor=[ # GL_ARB_color_buffer_float [ "RGBA_FLOAT_MODE_ARB", "BUFFER_FIELD(Visual.floatMode, TYPE_BOOLEAN), extra_core_ARB_color_buffer_float_and_new_buffers" ], +# GL_ARB_sparse_texture + [ "MAX_SPARSE_TEXTURE_SIZE_ARB", "CONTEXT_INT(Const.MaxSparseTextureSize), extra_ARB_sparse_texture" ], + [ "MAX_SPARSE_3D_TEXTURE_SIZE_ARB", "CONTEXT_INT(Const.MaxSparse3DTextureSize), extra_ARB_sparse_texture" ], + [ "MAX_SPARSE_ARRAY_TEXTURE_LAYERS_ARB", "CONTEXT_INT(Const.MaxSparseArrayTextureLayers), extra_ARB_sparse_texture" ], + [ "SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB", "CONTEXT_BOOL(Const.SparseTextureFullArrayCubeMipmaps), extra_ARB_sparse_texture" ], + # GL3.0 / GL_EXT_framebuffer_sRGB [ "FRAMEBUFFER_SRGB_CAPABLE_EXT", "BUFFER_INT(Visual.sRGBCapable), extra_EXT_framebuffer_sRGB_and_new_buffers" ], @@ -966,9 +989,6 @@ descriptor=[ # GL 3.2 [ "CONTEXT_PROFILE_MASK", "CONTEXT_INT(Const.ProfileMask), extra_version_32" ], -# GL_ARB_timer_query - [ "TIMESTAMP", "LOC_CUSTOM, TYPE_INT64, 0, extra_ARB_timer_query" ], - # GL_ARB_map_buffer_alignment [ "MIN_MAP_BUFFER_ALIGNMENT", "CONTEXT_INT(Const.MinMapBufferAlignment), NO_EXTRA" ], @@ -993,10 +1013,6 @@ descriptor=[ [ "GPU_MEMORY_INFO_EVICTION_COUNT_NVX", "LOC_CUSTOM, TYPE_INT, NO_OFFSET, extra_NVX_gpu_memory_info" ], [ "GPU_MEMORY_INFO_EVICTED_MEMORY_NVX", "LOC_CUSTOM, TYPE_INT, NO_OFFSET, extra_NVX_gpu_memory_info" ], -# GL_ARB_cull_distance - [ "MAX_CULL_DISTANCES", "CONTEXT_INT(Const.MaxClipPlanes), extra_ARB_cull_distance" ], - [ "MAX_COMBINED_CLIP_AND_CULL_DISTANCES", "CONTEXT_INT(Const.MaxClipPlanes), extra_ARB_cull_distance" ], - # GL_ARB_compute_variable_group_size [ "MAX_COMPUTE_VARIABLE_GROUP_INVOCATIONS_ARB", "CONTEXT_INT(Const.MaxComputeVariableGroupInvocations), extra_ARB_compute_variable_group_size" ], diff --git a/src/mesa/main/getstring.c b/src/mesa/main/getstring.c index 7ad147cbca9..45987488b84 100644 --- a/src/mesa/main/getstring.c +++ b/src/mesa/main/getstring.c @@ -24,7 +24,7 @@ #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "debug_output.h" #include "get.h" @@ -34,6 +34,10 @@ #include "macros.h" #include "version.h" #include "spirv_extensions.h" +#include "api_exec_decl.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" /** * Return the string for a glGetString(GL_SHADING_LANGUAGE_VERSION) query. @@ -128,24 +132,29 @@ _mesa_GetString( GLenum name ) return (const GLubyte *) ctx->Const.VendorOverride; } - /* this is a required driver function */ - assert(ctx->Driver.GetString); - { - /* Give the driver the chance to handle this query */ - const GLubyte *str = ctx->Driver.GetString(ctx, name); - if (str) - return str; + if (ctx->Const.RendererOverride && name == GL_RENDERER) { + return (const GLubyte *) ctx->Const.RendererOverride; } + struct pipe_screen *screen = ctx->pipe->screen; + switch (name) { - case GL_VENDOR: + case GL_VENDOR: { + const GLubyte *str = (const GLubyte *)screen->get_vendor(screen); + if (str) + return str; return (const GLubyte *) vendor; - case GL_RENDERER: + } + case GL_RENDERER: { + const GLubyte *str = (const GLubyte *)screen->get_name(screen); + if (str) + return str; return (const GLubyte *) renderer; + } case GL_VERSION: return (const GLubyte *) ctx->VersionString; case GL_EXTENSIONS: - if (ctx->API == API_OPENGL_CORE) { + if (_mesa_is_desktop_gl_core(ctx)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetString(GL_EXTENSIONS)"); return (const GLubyte *) 0; } @@ -153,11 +162,11 @@ _mesa_GetString( GLenum name ) ctx->Extensions.String = _mesa_make_extension_string(ctx); return (const GLubyte *) ctx->Extensions.String; case GL_SHADING_LANGUAGE_VERSION: - if (ctx->API == API_OPENGLES) + if (_mesa_is_gles1(ctx)) break; return shading_language_version(ctx); case GL_PROGRAM_ERROR_STRING_ARB: - if (ctx->API == API_OPENGL_COMPAT && + if (_mesa_is_desktop_gl_compat(ctx) && (ctx->Extensions.ARB_fragment_program || ctx->Extensions.ARB_vertex_program)) { return (const GLubyte *) ctx->Program.ErrorString; diff --git a/src/mesa/main/glconfig.h b/src/mesa/main/glconfig.h new file mode 100644 index 00000000000..099d7cee906 --- /dev/null +++ b/src/mesa/main/glconfig.h @@ -0,0 +1,42 @@ +#ifndef __GL_CONFIG_H__ +#define __GL_CONFIG_H__ + +#include "util/glheader.h" +#include "util/format/u_format.h" + +/** + * Framebuffer configuration (aka visual / pixelformat) + * Note: some of these fields should be boolean, but it appears that + * code in drivers/dri/common/util.c requires int-sized fields. + */ +struct gl_config +{ + /* if color_format is not PIPE_FORMAT_NONE, then all the properties of the + * gl_config must match the pipe_formats; if it is PIPE_FORMAT_NONE then + * the config properties are the only ones which can be trusted */ + enum pipe_format color_format; + enum pipe_format zs_format; + enum pipe_format accum_format; + + GLboolean floatMode; + GLuint doubleBufferMode; + GLuint stereoMode; + + GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ + GLuint redMask, greenMask, blueMask, alphaMask; + GLint redShift, greenShift, blueShift, alphaShift; + GLint rgbBits; /* total bits for rgb */ + + GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; + GLint depthBits; + GLint stencilBits; + + /* ARB_multisample / SGIS_multisample */ + GLuint samples; + + /* EXT_framebuffer_sRGB */ + GLint sRGBCapable; +}; + + +#endif diff --git a/src/mesa/main/glformats.c b/src/mesa/main/glformats.c index 641b103a914..f5a871388fa 100644 --- a/src/mesa/main/glformats.c +++ b/src/mesa/main/glformats.c @@ -522,55 +522,6 @@ _mesa_bytes_per_pixel(GLenum format, GLenum type) /** - * Get the number of bytes for a vertex attrib with the given number of - * components and type. - * - * \param comps number of components. - * \param type data type. - * - * \return bytes per attribute, or -1 if a bad comps/type combination was given. - */ -GLint -_mesa_bytes_per_vertex_attrib(GLint comps, GLenum type) -{ - switch (type) { - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return comps * sizeof(GLubyte); - case GL_SHORT: - case GL_UNSIGNED_SHORT: - return comps * sizeof(GLshort); - case GL_INT: - case GL_UNSIGNED_INT: - return comps * sizeof(GLint); - case GL_FLOAT: - return comps * sizeof(GLfloat); - case GL_HALF_FLOAT_ARB: - case GL_HALF_FLOAT_OES: - return comps * sizeof(GLhalfARB); - case GL_DOUBLE: - return comps * sizeof(GLdouble); - case GL_FIXED: - return comps * sizeof(GLfixed); - case GL_INT_2_10_10_10_REV: - case GL_UNSIGNED_INT_2_10_10_10_REV: - if (comps == 4) - return sizeof(GLuint); - else - return -1; - case GL_UNSIGNED_INT_10F_11F_11F_REV: - if (comps == 3) - return sizeof(GLuint); - else - return -1; - case GL_UNSIGNED_INT64_ARB: - return comps * 8; - default: - return -1; - } -} - -/** * Test if the given format is unsized. */ GLboolean @@ -1379,7 +1330,7 @@ _mesa_is_compressed_format(const struct gl_context *ctx, GLenum format) case GL_PALETTE8_R5_G6_B5_OES: case GL_PALETTE8_RGBA4_OES: case GL_PALETTE8_RGB5_A1_OES: - return ctx->API == API_OPENGLES; + return _mesa_is_gles1(ctx); } switch (_mesa_get_format_layout(m_format)) { @@ -1854,14 +1805,14 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, break; /* OK */ } if (type == GL_UNSIGNED_INT_2_10_10_10_REV && format == GL_RGB && - ctx->API == API_OPENGLES2) { + _mesa_is_gles2(ctx)) { break; /* OK by GL_EXT_texture_type_2_10_10_10_REV */ } return GL_INVALID_OPERATION; case GL_UNSIGNED_INT_24_8: /* Depth buffer OK to read in OpenGL ES (NV_read_depth). */ - if (ctx->API == API_OPENGLES2 && format == GL_DEPTH_COMPONENT) + if (_mesa_is_gles2(ctx) && format == GL_DEPTH_COMPONENT) return GL_NO_ERROR; if (format != GL_DEPTH_STENCIL) { @@ -1985,7 +1936,7 @@ _mesa_error_check_format_and_type(const struct gl_context *ctx, return GL_NO_ERROR; case GL_UNSIGNED_INT_2_10_10_10_REV: /* OK by GL_EXT_texture_type_2_10_10_10_REV */ - return (ctx->API == API_OPENGLES2) + return _mesa_is_gles2(ctx) ? GL_NO_ERROR : GL_INVALID_ENUM; case GL_UNSIGNED_INT_5_9_9_9_REV: return _mesa_has_texture_shared_exponent(ctx) @@ -2319,24 +2270,16 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) case GL_RGBA12: case GL_RGBA16: return GL_RGBA; + case GL_BGRA: + case GL_BGRA8_EXT: + return GL_RGBA; default: ; /* fallthrough */ } - /* GL_BGRA can be an internal format *only* in OpenGL ES (1.x or 2.0). - */ - if (_mesa_is_gles(ctx)) { - switch (internalFormat) { - case GL_BGRA: - return GL_RGBA; - default: - ; /* fallthrough */ - } - } - if (_mesa_has_ARB_ES2_compatibility(ctx) || _mesa_has_OES_framebuffer_object(ctx) || - ctx->API == API_OPENGLES2) { + _mesa_is_gles2(ctx)) { switch (internalFormat) { case GL_RGB565: return GL_RGB; @@ -2345,8 +2288,7 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) } } - if (_mesa_has_ARB_depth_texture(ctx) || _mesa_has_OES_depth_texture(ctx) || - ctx->API == API_OPENGL_CORE) { + if (ctx->API != API_OPENGLES) { switch (internalFormat) { case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16: @@ -2377,13 +2319,13 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) switch (internalFormat) { case GL_COMPRESSED_ALPHA: - return GL_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; case GL_COMPRESSED_LUMINANCE: - return GL_LUMINANCE; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; case GL_COMPRESSED_LUMINANCE_ALPHA: - return GL_LUMINANCE_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; case GL_COMPRESSED_INTENSITY: - return GL_INTENSITY; + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; case GL_COMPRESSED_RGB: return GL_RGB; case GL_COMPRESSED_RGBA: @@ -2413,34 +2355,34 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) if (_mesa_has_half_float_textures(ctx)) { switch (internalFormat) { case GL_ALPHA16F_ARB: - return GL_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; case GL_RGBA16F_ARB: return GL_RGBA; case GL_RGB16F_ARB: return GL_RGB; case GL_INTENSITY16F_ARB: - return GL_INTENSITY; + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; case GL_LUMINANCE16F_ARB: - return GL_LUMINANCE; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; case GL_LUMINANCE_ALPHA16F_ARB: - return GL_LUMINANCE_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; } } if (_mesa_has_float_textures(ctx)) { switch (internalFormat) { case GL_ALPHA32F_ARB: - return GL_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; case GL_RGBA32F_ARB: return GL_RGBA; case GL_RGB32F_ARB: return GL_RGB; case GL_INTENSITY32F_ARB: - return GL_INTENSITY; + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; case GL_LUMINANCE32F_ARB: - return GL_LUMINANCE; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; case GL_LUMINANCE_ALPHA32F_ARB: - return GL_LUMINANCE_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; } } @@ -2465,19 +2407,19 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) case GL_ALPHA_SNORM: case GL_ALPHA8_SNORM: case GL_ALPHA16_SNORM: - return GL_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; case GL_LUMINANCE_SNORM: case GL_LUMINANCE8_SNORM: case GL_LUMINANCE16_SNORM: - return GL_LUMINANCE; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; case GL_LUMINANCE_ALPHA_SNORM: case GL_LUMINANCE8_ALPHA8_SNORM: case GL_LUMINANCE16_ALPHA16_SNORM: - return GL_LUMINANCE_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; case GL_INTENSITY_SNORM: case GL_INTENSITY8_SNORM: case GL_INTENSITY16_SNORM: - return GL_INTENSITY; + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; default: ; /* fallthrough */ } @@ -2496,11 +2438,11 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) case GL_SLUMINANCE_ALPHA_EXT: case GL_SLUMINANCE8_ALPHA8_EXT: case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - return GL_LUMINANCE_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; case GL_SLUMINANCE_EXT: case GL_SLUMINANCE8_EXT: case GL_COMPRESSED_SLUMINANCE_EXT: - return GL_LUMINANCE; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; default: ; /* fallthrough */ } @@ -2558,28 +2500,28 @@ _mesa_base_tex_format(const struct gl_context *ctx, GLint internalFormat) case GL_ALPHA8I_EXT: case GL_ALPHA16I_EXT: case GL_ALPHA32I_EXT: - return GL_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_ALPHA : -1; case GL_INTENSITY8UI_EXT: case GL_INTENSITY16UI_EXT: case GL_INTENSITY32UI_EXT: case GL_INTENSITY8I_EXT: case GL_INTENSITY16I_EXT: case GL_INTENSITY32I_EXT: - return GL_INTENSITY; + return (ctx->API != API_OPENGL_CORE) ? GL_INTENSITY : -1; case GL_LUMINANCE8UI_EXT: case GL_LUMINANCE16UI_EXT: case GL_LUMINANCE32UI_EXT: case GL_LUMINANCE8I_EXT: case GL_LUMINANCE16I_EXT: case GL_LUMINANCE32I_EXT: - return GL_LUMINANCE; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE : -1; case GL_LUMINANCE_ALPHA8UI_EXT: case GL_LUMINANCE_ALPHA16UI_EXT: case GL_LUMINANCE_ALPHA32UI_EXT: case GL_LUMINANCE_ALPHA8I_EXT: case GL_LUMINANCE_ALPHA16I_EXT: case GL_LUMINANCE_ALPHA32I_EXT: - return GL_LUMINANCE_ALPHA; + return (ctx->API != API_OPENGL_CORE) ? GL_LUMINANCE_ALPHA : -1; default: ; /* fallthrough */ } @@ -2796,12 +2738,196 @@ gles_effective_internal_format_for_format_and_type(GLenum format, } /** + * Error checking if internalformat for glTex[Sub]Image is valid + * within OpenGL ES 3.2 (or introduced by an ES extension). + * + * Note, further checks in _mesa_gles_error_check_format_and_type + * are required for complete checking between format and type. + */ +static GLenum +_mesa_gles_check_internalformat(struct gl_context *ctx, + GLenum internalFormat) +{ + switch (internalFormat) { + /* OpenGL ES 2.0 */ + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_RGB: + case GL_RGBA: + + /* GL_OES_depth_texture */ + case GL_DEPTH_COMPONENT: + + /* GL_EXT_texture_format_BGRA8888 */ + case GL_BGRA: + + /* GL_OES_required_internalformat */ + case GL_RGB565: + case GL_RGB8: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_DEPTH24_STENCIL8: + case GL_RGB10_EXT: + case GL_RGB10_A2_EXT: + case GL_ALPHA8: + case GL_LUMINANCE8: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE4_ALPHA4: + return GL_NO_ERROR; + + case GL_R8: + case GL_RG8: + case GL_RED: + case GL_RG: + if (!_mesa_has_rg_textures(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + /* GL_OES_texture_stencil8 */ + case GL_STENCIL_INDEX8: + if (!_mesa_has_OES_texture_stencil8(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_COMPRESSED_RGBA_BPTC_UNORM: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: + if (!_mesa_has_EXT_texture_compression_bptc(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + case GL_COMPRESSED_RED_GREEN_RGTC2_EXT: + case GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT: + if (!_mesa_has_EXT_texture_compression_rgtc(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + if (!_mesa_has_EXT_texture_compression_s3tc(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + if (!_mesa_has_EXT_texture_compression_s3tc_srgb(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_R16: + case GL_RG16: + case GL_RGB16: + case GL_RGBA16: + if (!_mesa_has_EXT_texture_norm16(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_R16_SNORM: + case GL_RG16_SNORM: + case GL_RGB16_SNORM: + case GL_RGBA16_SNORM: + if (!_mesa_has_EXT_texture_norm16(ctx) && + !_mesa_has_EXT_texture_snorm(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_SR8_EXT: + if (!_mesa_has_EXT_texture_sRGB_R8(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_SRG8_EXT: + if (!_mesa_has_EXT_texture_sRGB_RG8(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + /* OpenGL ES 3.0 */ + case GL_SRGB8_ALPHA8: + case GL_RGBA8_SNORM: + case GL_RGBA16F: + case GL_RGBA32F: + case GL_RGBA8UI: + case GL_RGBA8I: + case GL_RGBA16UI: + case GL_RGBA16I: + case GL_RGBA32UI: + case GL_RGBA32I: + case GL_RGB10_A2UI: + case GL_SRGB8: + case GL_RGB8_SNORM: + case GL_R11F_G11F_B10F: + case GL_RGB9_E5: + case GL_RGB16F: + case GL_RGB32F: + case GL_RGB8UI: + case GL_RGB8I: + case GL_RGB16UI: + case GL_RGB16I: + case GL_RGB32UI: + case GL_RGB32I: + case GL_RG8_SNORM: + case GL_RG16F: + case GL_RG32F: + case GL_RG8UI: + case GL_RG8I: + case GL_RG16UI: + case GL_RG16I: + case GL_RG32UI: + case GL_RG32I: + case GL_R8_SNORM: + case GL_R16F: + case GL_R32F: + case GL_R8UI: + case GL_R8I: + case GL_R16UI: + case GL_R16I: + case GL_R32UI: + case GL_R32I: + case GL_DEPTH_COMPONENT32F: + case GL_DEPTH32F_STENCIL8: + if (!_mesa_is_gles3(ctx)) + return GL_INVALID_VALUE; + return GL_NO_ERROR; + + case GL_BGRA8_EXT: { + /* This is technically speaking out-of-spec. But too many + * applications seems to depend on it, so let's allow it + * together with a small complaint */ + static bool warned = false; + if (!warned) { + _mesa_warning(ctx, + "internalformat = GL_BGRA8_EXT invalid by spec, but too many " + "applications depend on it to error. Please fix the software " + "that causes this problem."); + warned = true; + } + return GL_NO_ERROR; + } + + default: + return GL_INVALID_VALUE; + } +} + +/** * Do error checking of format/type combinations for OpenGL ES 3 * glTex[Sub]Image, or ES1/ES2 with GL_OES_required_internalformat. * \return error code, or GL_NO_ERROR. */ GLenum -_mesa_gles_error_check_format_and_type(const struct gl_context *ctx, +_mesa_gles_error_check_format_and_type(struct gl_context *ctx, GLenum format, GLenum type, GLenum internalFormat) { @@ -2849,19 +2975,28 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, /* The GLES variant of EXT_texture_compression_s3tc is very vague and * doesn't list valid types. Just do exactly what the spec says. */ - if (_mesa_has_EXT_texture_compression_s3tc(ctx) && - (internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || - internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || - internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || - internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)) + if (internalFormat == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || + internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || + internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT3_EXT || + internalFormat == GL_COMPRESSED_RGBA_S3TC_DXT5_EXT) return format == GL_RGB || format == GL_RGBA ? GL_NO_ERROR : GL_INVALID_OPERATION; + /* Before checking for the combination, verify that + * given internalformat is legal for OpenGL ES. + */ + GLenum internal_format_error = + _mesa_gles_check_internalformat(ctx, internalFormat); + + if (internal_format_error != GL_NO_ERROR) + return internal_format_error; + switch (format) { case GL_BGRA_EXT: if (type != GL_UNSIGNED_BYTE || (internalFormat != GL_BGRA && internalFormat != GL_RGBA8 && + internalFormat != GL_BGRA8_EXT && internalFormat != GL_SRGB8_ALPHA8)) return GL_INVALID_OPERATION; break; @@ -2888,8 +3023,6 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, break; case GL_COMPRESSED_RGBA_BPTC_UNORM: case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM: - if (!_mesa_has_EXT_texture_compression_bptc(ctx)) - return GL_INVALID_OPERATION; break; default: return GL_INVALID_OPERATION; @@ -2902,13 +3035,12 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, break; case GL_UNSIGNED_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_RGBA16) + if (internalFormat != GL_RGBA16) return GL_INVALID_OPERATION; break; case GL_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || - internalFormat != GL_RGBA16_SNORM) + if (internalFormat != GL_RGBA16_SNORM) return GL_INVALID_OPERATION; break; @@ -3042,13 +3174,12 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, break; case GL_UNSIGNED_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_RGB16) + if (internalFormat != GL_RGB16) return GL_INVALID_OPERATION; break; case GL_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || - internalFormat != GL_RGB16_SNORM) + if (internalFormat != GL_RGB16_SNORM) return GL_INVALID_OPERATION; break; @@ -3096,8 +3227,6 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, break; case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT: case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT: - if (!_mesa_has_EXT_texture_compression_bptc(ctx)) - return GL_INVALID_OPERATION; break; case GL_RGB: if (!_mesa_has_OES_texture_float(ctx) || internalFormat != format) @@ -3180,29 +3309,25 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, return GL_INVALID_OPERATION; switch (type) { case GL_UNSIGNED_BYTE: - if (internalFormat == GL_RG8 || - (_mesa_has_EXT_texture_compression_rgtc(ctx) && - internalFormat == GL_COMPRESSED_RED_GREEN_RGTC2_EXT) || - (_mesa_has_EXT_texture_sRGB_RG8(ctx) && - internalFormat == GL_SRG8_EXT)) - break; - return GL_INVALID_OPERATION; + if (internalFormat != GL_RG8 && + internalFormat != GL_COMPRESSED_RED_GREEN_RGTC2_EXT && + internalFormat != GL_SRG8_EXT) + return GL_INVALID_OPERATION; + break; case GL_BYTE: if (internalFormat != GL_RG8_SNORM && - (!_mesa_has_EXT_texture_compression_rgtc(ctx) || - internalFormat != GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT)) + internalFormat != GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT) return GL_INVALID_OPERATION; break; case GL_UNSIGNED_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_RG16) + if (internalFormat != GL_RG16) return GL_INVALID_OPERATION; break; case GL_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || - internalFormat != GL_RG16_SNORM) + if (internalFormat != GL_RG16_SNORM) return GL_INVALID_OPERATION; break; @@ -3214,8 +3339,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, return GL_INVALID_OPERATION; break; case GL_RG: - if (!_mesa_has_rg_textures(ctx) || - !_mesa_has_OES_texture_half_float(ctx)) + if (!_mesa_has_OES_texture_half_float(ctx)) return GL_INVALID_OPERATION; break; default: @@ -3229,8 +3353,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, case GL_RG32F: break; case GL_RG: - if (!_mesa_has_rg_textures(ctx) || - !_mesa_has_OES_texture_float(ctx)) + if (!_mesa_has_OES_texture_float(ctx)) return GL_INVALID_OPERATION; break; default: @@ -3287,29 +3410,26 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, return GL_INVALID_OPERATION; switch (type) { case GL_UNSIGNED_BYTE: - if (internalFormat == GL_R8 || - ((internalFormat == GL_SR8_EXT) && - _mesa_has_EXT_texture_sRGB_R8(ctx)) || - (internalFormat == GL_COMPRESSED_RED_RGTC1_EXT && - _mesa_has_EXT_texture_compression_rgtc(ctx))) - break; - return GL_INVALID_OPERATION; + if (internalFormat != GL_R8 && + internalFormat != GL_SR8_EXT && + internalFormat != GL_COMPRESSED_RED_RGTC1_EXT) { + return GL_INVALID_OPERATION; + } + break; case GL_BYTE: if (internalFormat != GL_R8_SNORM && - (!_mesa_has_EXT_texture_compression_rgtc(ctx) || - internalFormat != GL_COMPRESSED_SIGNED_RED_RGTC1_EXT)) + internalFormat != GL_COMPRESSED_SIGNED_RED_RGTC1_EXT) return GL_INVALID_OPERATION; break; case GL_UNSIGNED_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || internalFormat != GL_R16) + if (internalFormat != GL_R16) return GL_INVALID_OPERATION; break; case GL_SHORT: - if (!_mesa_has_EXT_texture_norm16(ctx) || - internalFormat != GL_R16_SNORM) + if (internalFormat != GL_R16_SNORM) return GL_INVALID_OPERATION; break; @@ -3322,8 +3442,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, break; case GL_RG: case GL_RED: - if (!_mesa_has_rg_textures(ctx) || - !_mesa_has_OES_texture_half_float(ctx)) + if (!_mesa_has_OES_texture_half_float(ctx)) return GL_INVALID_OPERATION; break; default: @@ -3337,8 +3456,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, case GL_R32F: break; case GL_RED: - if (!_mesa_has_rg_textures(ctx) || - !_mesa_has_OES_texture_float(ctx)) + if (!_mesa_has_OES_texture_float(ctx)) return GL_INVALID_OPERATION; break; default: @@ -3393,8 +3511,8 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, case GL_DEPTH_COMPONENT: switch (type) { case GL_UNSIGNED_SHORT: - if (internalFormat != GL_DEPTH_COMPONENT - && internalFormat != GL_DEPTH_COMPONENT16) + if (internalFormat != GL_DEPTH_COMPONENT && + internalFormat != GL_DEPTH_COMPONENT16) return GL_INVALID_OPERATION; break; @@ -3422,8 +3540,8 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, case GL_DEPTH_STENCIL: switch (type) { case GL_UNSIGNED_INT_24_8: - if (internalFormat != GL_DEPTH_STENCIL - && internalFormat != GL_DEPTH24_STENCIL8) + if (internalFormat != GL_DEPTH_STENCIL && + internalFormat != GL_DEPTH24_STENCIL8) return GL_INVALID_OPERATION; break; @@ -3438,8 +3556,7 @@ _mesa_gles_error_check_format_and_type(const struct gl_context *ctx, break; case GL_STENCIL_INDEX: - if (!_mesa_has_OES_texture_stencil8(ctx) || - type != GL_UNSIGNED_BYTE || + if (type != GL_UNSIGNED_BYTE || internalFormat != GL_STENCIL_INDEX8) { return GL_INVALID_OPERATION; } @@ -3885,12 +4002,6 @@ _mesa_is_es3_color_renderable(const struct gl_context *ctx, case GL_RGB10_A2: case GL_RGB10_A2UI: case GL_SRGB8_ALPHA8: - case GL_R16F: - case GL_RG16F: - case GL_RGBA16F: - case GL_R32F: - case GL_RG32F: - case GL_RGBA32F: case GL_R11F_G11F_B10F: case GL_R8I: case GL_R8UI: @@ -3911,6 +4022,15 @@ _mesa_is_es3_color_renderable(const struct gl_context *ctx, case GL_RGBA32I: case GL_RGBA32UI: return true; + case GL_R16F: + case GL_RG16F: + case GL_RGB16F: + case GL_RGBA16F: + return _mesa_has_EXT_color_buffer_half_float(ctx); + case GL_R32F: + case GL_RG32F: + case GL_RGBA32F: + return _mesa_has_EXT_color_buffer_float(ctx); case GL_R16: case GL_RG16: case GL_RGBA16: @@ -3924,6 +4044,13 @@ _mesa_is_es3_color_renderable(const struct gl_context *ctx, case GL_RGBA16_SNORM: return _mesa_has_EXT_texture_norm16(ctx) && _mesa_has_EXT_render_snorm(ctx); + case GL_BGRA: + assert(_mesa_has_EXT_texture_format_BGRA8888(ctx)); + return true; + case GL_BGRA8_EXT: + assert(_mesa_has_EXT_texture_format_BGRA8888(ctx) && + _mesa_has_EXT_texture_storage(ctx)); + return true; default: return false; } @@ -3982,6 +4109,13 @@ _mesa_is_es3_texture_filterable(const struct gl_context *ctx, * for the R32F, RG32F, RGB32F, and RGBA32F formats." */ return _mesa_has_OES_texture_float_linear(ctx); + case GL_BGRA: + assert(_mesa_has_EXT_texture_format_BGRA8888(ctx)); + return true; + case GL_BGRA8_EXT: + assert(_mesa_has_EXT_texture_format_BGRA8888(ctx) && + _mesa_has_EXT_texture_storage(ctx)); + return true; default: return false; } diff --git a/src/mesa/main/glformats.h b/src/mesa/main/glformats.h index 98987a15f4e..391898d64e7 100644 --- a/src/mesa/main/glformats.h +++ b/src/mesa/main/glformats.h @@ -30,8 +30,8 @@ #include <stdbool.h> #include <stdint.h> -#include <GL/gl.h> +#include "util/glheader.h" #ifdef __cplusplus extern "C" { @@ -57,9 +57,6 @@ _mesa_components_in_format( GLenum format ); extern GLint _mesa_bytes_per_pixel( GLenum format, GLenum type ); -extern GLint -_mesa_bytes_per_vertex_attrib(GLint comps, GLenum type); - extern GLboolean _mesa_is_astc_format(GLenum internalFormat); @@ -142,7 +139,7 @@ _mesa_es_error_check_format_and_type(const struct gl_context *ctx, unsigned dimensions); extern GLenum -_mesa_gles_error_check_format_and_type(const struct gl_context *ctx, +_mesa_gles_error_check_format_and_type(struct gl_context *ctx, GLenum format, GLenum type, GLenum internalFormat); extern GLint diff --git a/src/mesa/main/glheader.h b/src/mesa/main/glheader.h deleted file mode 100644 index 12c9b949433..00000000000 --- a/src/mesa/main/glheader.h +++ /dev/null @@ -1,172 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file glheader.h - * Wrapper for GL/gl.h and GL/glext.h - */ - - -#ifndef GLHEADER_H -#define GLHEADER_H - - -#define GL_GLEXT_PROTOTYPES -#include "GL/gl.h" -#include "GL/glext.h" - - -#ifdef __cplusplus -extern "C" { -#endif - - -/* Custom Mesa types to save space. */ -typedef unsigned short GLenum16; -typedef unsigned char GLbitfield8; -typedef unsigned short GLbitfield16; -typedef GLuint64 GLbitfield64; - -/* Common GLES 1.0 and 2.0 tokens */ - -#ifndef GL_OES_EGL_image_external -#define GL_TEXTURE_EXTERNAL_OES 0x8D65 -#define GL_SAMPLER_EXTERNAL_OES 0x8D66 -#define GL_TEXTURE_BINDING_EXTERNAL_OES 0x8D67 -#define GL_REQUIRED_TEXTURE_IMAGE_UNITS_OES 0x8D68 -#endif - -#ifndef GL_OES_compressed_ETC1_RGB8_texture -#define GL_ETC1_RGB8_OES 0x8D64 -#endif - - -/* GLES 1.0 only tokens */ - -typedef int GLclampx; - -#ifndef GL_OES_point_size_array -#define GL_POINT_SIZE_ARRAY_OES 0x8B9C -#define GL_POINT_SIZE_ARRAY_TYPE_OES 0x898A -#define GL_POINT_SIZE_ARRAY_STRIDE_OES 0x898B -#define GL_POINT_SIZE_ARRAY_POINTER_OES 0x898C -#define GL_POINT_SIZE_ARRAY_BUFFER_BINDING_OES 0x8B9F -#endif - - -#ifndef GL_OES_draw_texture -#define GL_TEXTURE_CROP_RECT_OES 0x8B9D -#endif - -#ifndef GL_TEXTURE_GEN_STR_OES -#define GL_TEXTURE_GEN_STR_OES 0x8D60 -#endif - - -/* GLES 2.0 only tokens */ - -#ifndef GL_PROGRAM_BINARY_LENGTH_OES -#define GL_PROGRAM_BINARY_LENGTH_OES 0x8741 -#endif - -#ifndef GL_OES_texture_compression_astc -#define GL_COMPRESSED_RGBA_ASTC_3x3x3_OES 0x93C0 -#define GL_COMPRESSED_RGBA_ASTC_4x3x3_OES 0x93C1 -#define GL_COMPRESSED_RGBA_ASTC_4x4x3_OES 0x93C2 -#define GL_COMPRESSED_RGBA_ASTC_4x4x4_OES 0x93C3 -#define GL_COMPRESSED_RGBA_ASTC_5x4x4_OES 0x93C4 -#define GL_COMPRESSED_RGBA_ASTC_5x5x4_OES 0x93C5 -#define GL_COMPRESSED_RGBA_ASTC_5x5x5_OES 0x93C6 -#define GL_COMPRESSED_RGBA_ASTC_6x5x5_OES 0x93C7 -#define GL_COMPRESSED_RGBA_ASTC_6x6x5_OES 0x93C8 -#define GL_COMPRESSED_RGBA_ASTC_6x6x6_OES 0x93C9 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_3x3x3_OES 0x93E0 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x3x3_OES 0x93E1 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x3_OES 0x93E2 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_4x4x4_OES 0x93E3 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x4x4_OES 0x93E4 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x4_OES 0x93E5 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_5x5x5_OES 0x93E6 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x5x5_OES 0x93E7 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x5_OES 0x93E8 -#define GL_COMPRESSED_SRGB8_ALPHA8_ASTC_6x6x6_OES 0x93E9 -#endif - -#ifndef GL_EXT_shader_framebuffer_fetch -#define GL_FRAGMENT_SHADER_DISCARDS_SAMPLES_EXT 0x8A52 -#endif - -#ifndef GL_EXT_disjoint_timer_query -#define GL_GPU_DISJOINT_EXT 0x8FBB -#endif - -/* Inexplicably, GL_HALF_FLOAT_OES has a different value than GL_HALF_FLOAT. - */ -#ifndef GL_HALF_FLOAT_OES -#define GL_HALF_FLOAT_OES 0x8D61 -#endif - -/* There is no formal spec for the following extension. */ -#ifndef GL_ATI_texture_compression_3dc -#define GL_ATI_texture_compression_3dc 1 -#define GL_COMPRESSED_LUMINANCE_ALPHA_3DC_ATI 0x8837 -#endif - -#ifndef GL_EXT_texture_sRGB_R8 -#define GL_SR8_EXT 0x8FBD -#endif - -#ifndef GL_EXT_texture_sRGB_RG8 -#define GL_SRG8_EXT 0x8FBE -#endif - -#ifndef GL_AMD_compressed_ATC_texture -#define GL_ATC_RGB_AMD 0x8C92 -#define GL_ATC_RGBA_EXPLICIT_ALPHA_AMD 0x8C93 -#define GL_ATC_RGBA_INTERPOLATED_ALPHA_AMD 0x87EE -#endif - -/** - * Internal token to represent a GLSL shader program (a collection of - * one or more shaders that get linked together). Note that GLSL - * shaders and shader programs share one name space (one hash table) - * so we need a value that's different from any of the - * GL_VERTEX/FRAGMENT/GEOMETRY_PROGRAM tokens. - */ -#define GL_SHADER_PROGRAM_MESA 0x9999 - -#ifndef GL_EXT_multisampled_render_to_texture -#define GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_SAMPLES_EXT 0x8D6C -#endif - -#ifndef GL_ANGLE_pack_reverse_row_order -#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 -#endif - -#ifdef __cplusplus -} -#endif - -#endif /* GLHEADER_H */ diff --git a/src/mesa/main/glspirv.c b/src/mesa/main/glspirv.c index 1668be08d95..cf5c030a795 100644 --- a/src/mesa/main/glspirv.c +++ b/src/mesa/main/glspirv.c @@ -32,6 +32,7 @@ #include "program/program.h" #include "util/u_atomic.h" +#include "api_exec_decl.h" void _mesa_spirv_module_reference(struct gl_spirv_module **dest, @@ -73,6 +74,25 @@ _mesa_spirv_shader_binary(struct gl_context *ctx, struct gl_spirv_module *module; struct gl_shader_spirv_data *spirv_data; + /* From OpenGL 4.6 Core spec, "7.2 Shader Binaries" : + * + * "An INVALID_VALUE error is generated if the data pointed to by binary + * does not match the specified binaryformat." + * + * However, the ARB_gl_spirv spec, under issue #16 says: + * + * "ShaderBinary is expected to form an association between the SPIR-V + * module and likely would not parse the module as would be required to + * detect unsupported capabilities or other validation failures." + * + * Which specifies little to no validation requirements. Nevertheless, the + * two small checks below seem reasonable. + */ + if (!binary || (length % 4) != 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "glShaderBinary"); + return; + } + module = malloc(sizeof(*module) + length); if (!module) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glShaderBinary"); @@ -155,8 +175,7 @@ _mesa_spirv_link_shaders(struct gl_context *ctx, struct gl_shader_program *prog) return; } - _mesa_reference_shader_program_data(ctx, - &gl_prog->sh.data, + _mesa_reference_shader_program_data(&gl_prog->sh.data, prog->data); /* Don't use _mesa_reference_program() just take ownership */ @@ -243,8 +262,7 @@ _mesa_spirv_to_nir(struct gl_context *ctx, const struct spirv_to_nir_options spirv_options = { .environment = NIR_SPIRV_OPENGL, - .frag_coord_is_sysval = ctx->Const.GLSLFragCoordIsSysVal, - .use_deref_buffer_array_length = true, + .subgroup_size = SUBGROUP_SIZE_UNIFORM, .caps = ctx->Const.SpirVCapabilities, .ubo_addr_format = nir_address_format_32bit_index_offset, .ssbo_addr_format = nir_address_format_32bit_index_offset, @@ -279,40 +297,46 @@ _mesa_spirv_to_nir(struct gl_context *ctx, nir->info.separate_shader = linked_shader->Program->info.separate_shader; + /* Convert some sysvals to input varyings. */ + const struct nir_lower_sysvals_to_varyings_options sysvals_to_varyings = { + .frag_coord = !ctx->Const.GLSLFragCoordIsSysVal, + .point_coord = !ctx->Const.GLSLPointCoordIsSysVal, + .front_face = !ctx->Const.GLSLFrontFacingIsSysVal, + }; + NIR_PASS(_, nir, nir_lower_sysvals_to_varyings, &sysvals_to_varyings); + /* We have to lower away local constant initializers right before we * inline functions. That way they get properly initialized at the top * of the function and not at the top of its caller. */ - NIR_PASS_V(nir, nir_lower_variable_initializers, nir_var_function_temp); - NIR_PASS_V(nir, nir_lower_returns); - NIR_PASS_V(nir, nir_inline_functions); - NIR_PASS_V(nir, nir_copy_prop); - NIR_PASS_V(nir, nir_opt_deref); + NIR_PASS(_, nir, nir_lower_variable_initializers, nir_var_function_temp); + NIR_PASS(_, nir, nir_lower_returns); + NIR_PASS(_, nir, nir_inline_functions); + NIR_PASS(_, nir, nir_copy_prop); + NIR_PASS(_, nir, nir_opt_deref); /* Pick off the single entrypoint that we want */ - foreach_list_typed_safe(nir_function, func, node, &nir->functions) { - if (!func->is_entrypoint) - exec_node_remove(&func->node); - } - assert(exec_list_length(&nir->functions) == 1); + nir_remove_non_entrypoints(nir); /* Now that we've deleted all but the main function, we can go ahead and * lower the rest of the constant initializers. We do this here so that * nir_remove_dead_variables and split_per_member_structs below see the * corresponding stores. */ - NIR_PASS_V(nir, nir_lower_variable_initializers, ~0); + NIR_PASS(_, nir, nir_lower_variable_initializers, ~0); /* Split member structs. We do this before lower_io_to_temporaries so that * it doesn't lower system values to temporaries by accident. */ - NIR_PASS_V(nir, nir_split_var_copies); - NIR_PASS_V(nir, nir_split_per_member_structs); + NIR_PASS(_, nir, nir_split_var_copies); + NIR_PASS(_, nir, nir_split_per_member_structs); - if (nir->info.stage == MESA_SHADER_VERTEX) + if (nir->info.stage == MESA_SHADER_VERTEX && + (!(nir->options->io_options & nir_io_glsl_lower_derefs) || + !(nir->options->io_options & nir_io_glsl_opt_varyings))) nir_remap_dual_slot_attributes(nir, &linked_shader->Program->DualSlotInputs); - NIR_PASS_V(nir, nir_lower_frexp); + NIR_PASS(_, nir, nir_lower_frexp); return nir; } @@ -326,7 +350,6 @@ _mesa_SpecializeShaderARB(GLuint shader, { GET_CURRENT_CONTEXT(ctx); struct gl_shader *sh; - bool has_entry_point; struct nir_spirv_specialization *spec_entries = NULL; if (!ctx->Extensions.ARB_gl_spirv) { @@ -381,27 +404,35 @@ _mesa_SpecializeShaderARB(GLuint shader, spec_entries[i].defined_on_module = false; } - has_entry_point = - gl_spirv_validation((uint32_t *)&spirv_data->SpirVModule->Binary[0], - spirv_data->SpirVModule->Length / 4, - spec_entries, numSpecializationConstants, - sh->Stage, pEntryPoint); + enum spirv_verify_result r = spirv_verify_gl_specialization_constants( + (uint32_t *)&spirv_data->SpirVModule->Binary[0], + spirv_data->SpirVModule->Length / 4, + spec_entries, numSpecializationConstants, + sh->Stage, pEntryPoint); - /* See previous spec comment */ - if (!has_entry_point) { + switch (r) { + case SPIRV_VERIFY_OK: + break; + case SPIRV_VERIFY_PARSER_ERROR: _mesa_error(ctx, GL_INVALID_VALUE, - "glSpecializeShaderARB(\"%s\" is not a valid entry point" + "glSpecializeShaderARB(failed to parse entry point \"%s\"" " for shader)", pEntryPoint); goto end; - } - - for (unsigned i = 0; i < numSpecializationConstants; ++i) { - if (spec_entries[i].defined_on_module == false) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glSpecializeShaderARB(constant \"%i\" does not exist " - "in shader)", spec_entries[i].id); - goto end; + case SPIRV_VERIFY_ENTRY_POINT_NOT_FOUND: + _mesa_error(ctx, GL_INVALID_VALUE, + "glSpecializeShaderARB(could not find entry point \"%s\"" + " for shader)", pEntryPoint); + goto end; + case SPIRV_VERIFY_UNKNOWN_SPEC_INDEX: + for (unsigned i = 0; i < numSpecializationConstants; ++i) { + if (spec_entries[i].defined_on_module == false) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glSpecializeShaderARB(constant \"%i\" does not exist " + "in shader)", spec_entries[i].id); + break; + } } + goto end; } spirv_data->SpirVEntryPoint = ralloc_strdup(spirv_data, pEntryPoint); diff --git a/src/mesa/main/glspirv.h b/src/mesa/main/glspirv.h index 8025c17c099..58248dc7661 100644 --- a/src/mesa/main/glspirv.h +++ b/src/mesa/main/glspirv.h @@ -25,6 +25,7 @@ #define GLSPIRV_H #include "compiler/nir/nir.h" +#include "util/glheader.h" #ifdef __cplusplus extern "C" { @@ -90,20 +91,6 @@ _mesa_spirv_to_nir(struct gl_context *ctx, gl_shader_stage stage, const nir_shader_compiler_options *options); -/** - * \name API functions - */ -/*@{*/ - -void GLAPIENTRY -_mesa_SpecializeShaderARB(GLuint shader, - const GLchar *pEntryPoint, - GLuint numSpecializationConstants, - const GLuint *pConstantIndex, - const GLuint *pConstantValue); - -/*@}*/ - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/glthread.c b/src/mesa/main/glthread.c index ed619f5806c..45ad84a1eb8 100644 --- a/src/mesa/main/glthread.c +++ b/src/mesa/main/glthread.c @@ -36,110 +36,219 @@ #include "main/glthread.h" #include "main/glthread_marshal.h" #include "main/hash.h" +#include "main/pixelstore.h" #include "util/u_atomic.h" #include "util/u_thread.h" #include "util/u_cpu_detect.h" +#include "util/thread_sched.h" +#include "state_tracker/st_context.h" static void -glthread_unmarshal_batch(void *job, int thread_index) +glthread_update_global_locking(struct gl_context *ctx) +{ + struct gl_shared_state *shared = ctx->Shared; + + /* Determine if we should lock the global mutexes. */ + simple_mtx_lock(&shared->Mutex); + int64_t current_time = os_time_get_nano(); + + /* We can only lock the mutexes after NoLockDuration nanoseconds have + * passed since multiple contexts were active. + */ + bool lock_mutexes = shared->GLThread.LastContextSwitchTime + + shared->GLThread.NoLockDuration < current_time; + + /* Check if multiple contexts are active (the last executing context is + * different). + */ + if (ctx != shared->GLThread.LastExecutingCtx) { + if (lock_mutexes) { + /* If we get here, we've been locking the global mutexes for a while + * and now we are switching contexts. */ + if (shared->GLThread.LastContextSwitchTime + + 120 * ONE_SECOND_IN_NS < current_time) { + /* If it's been more than 2 minutes of only one active context, + * indicating that there was no other active context for a long + * time, reset the no-lock time to its initial state of only 1 + * second. This is most likely an infrequent situation of + * multi-context loading of game content and shaders. + * (this is a heuristic) + */ + shared->GLThread.NoLockDuration = ONE_SECOND_IN_NS; + } else if (shared->GLThread.NoLockDuration < 32 * ONE_SECOND_IN_NS) { + /* Double the no-lock duration if we are transitioning from only + * one active context to multiple active contexts after a short + * time, up to a maximum of 32 seconds, indicating that multiple + * contexts are frequently executing. (this is a heuristic) + */ + shared->GLThread.NoLockDuration *= 2; + } + + lock_mutexes = false; + } + + /* There are multiple active contexts. Update the last executing context + * and the last context switch time. We only start locking global mutexes + * after LastContextSwitchTime + NoLockDuration passes, so this + * effectively resets the non-locking stopwatch to 0, so that multiple + * contexts can execute simultaneously as long as they are not idle. + */ + shared->GLThread.LastExecutingCtx = ctx; + shared->GLThread.LastContextSwitchTime = current_time; + } + simple_mtx_unlock(&shared->Mutex); + + ctx->GLThread.LockGlobalMutexes = lock_mutexes; +} + +static void +glthread_unmarshal_batch(void *job, void *gdata, int thread_index) { struct glthread_batch *batch = (struct glthread_batch*)job; struct gl_context *ctx = batch->ctx; unsigned pos = 0; unsigned used = batch->used; uint64_t *buffer = batch->buffer; + struct gl_shared_state *shared = ctx->Shared; - _glapi_set_dispatch(ctx->CurrentServerDispatch); + /* Determine once every 64 batches whether shared mutexes should be locked. + * We have to do this less frequently because os_time_get_nano() is very + * expensive if the clock source is not TSC. See: + * https://gitlab.freedesktop.org/mesa/mesa/-/issues/8910 + */ + if (ctx->GLThread.GlobalLockUpdateBatchCounter++ % 64 == 0) + glthread_update_global_locking(ctx); - _mesa_HashLockMutex(ctx->Shared->BufferObjects); - ctx->BufferObjectsLocked = true; - mtx_lock(&ctx->Shared->TexMutex); - ctx->TexturesLocked = true; + /* Execute the GL calls. */ + _glapi_set_dispatch(ctx->Dispatch.Current); + + /* Here we lock the mutexes once globally if possible. If not, we just + * fallback to the individual API calls doing it. + */ + bool lock_mutexes = ctx->GLThread.LockGlobalMutexes; + if (lock_mutexes) { + _mesa_HashLockMutex(&shared->BufferObjects); + ctx->BufferObjectsLocked = true; + simple_mtx_lock(&shared->TexMutex); + ctx->TexturesLocked = true; + } while (pos < used) { const struct marshal_cmd_base *cmd = (const struct marshal_cmd_base *)&buffer[pos]; - _mesa_unmarshal_dispatch[cmd->cmd_id](ctx, cmd); - pos += cmd->cmd_size; + pos += _mesa_unmarshal_dispatch[cmd->cmd_id](ctx, cmd); } - ctx->TexturesLocked = false; - mtx_unlock(&ctx->Shared->TexMutex); - ctx->BufferObjectsLocked = false; - _mesa_HashUnlockMutex(ctx->Shared->BufferObjects); + if (lock_mutexes) { + ctx->TexturesLocked = false; + simple_mtx_unlock(&shared->TexMutex); + ctx->BufferObjectsLocked = false; + _mesa_HashUnlockMutex(&shared->BufferObjects); + } assert(pos == used); batch->used = 0; unsigned batch_index = batch - ctx->GLThread.batches; - /* Atomically set this to -1 if it's equal to batch_index. */ - p_atomic_cmpxchg(&ctx->GLThread.LastProgramChangeBatch, batch_index, -1); - p_atomic_cmpxchg(&ctx->GLThread.LastDListChangeBatchIndex, batch_index, -1); + _mesa_glthread_signal_call(&ctx->GLThread.LastProgramChangeBatch, batch_index); + _mesa_glthread_signal_call(&ctx->GLThread.LastDListChangeBatchIndex, batch_index); + + p_atomic_inc(&ctx->GLThread.stats.num_batches); +} + +static void +glthread_apply_thread_sched_policy(struct gl_context *ctx, bool initialization) +{ + struct glthread_state *glthread = &ctx->GLThread; + + if (!glthread->thread_sched_enabled) + return; + + /* Apply our thread scheduling policy for better multithreading + * performance. + */ + if (initialization || ++glthread->pin_thread_counter % 128 == 0) { + int cpu = util_get_current_cpu(); + + if (cpu >= 0 && + util_thread_sched_apply_policy(glthread->queue.threads[0], + UTIL_THREAD_GLTHREAD, cpu, + &glthread->thread_sched_state)) { + /* If it's successful, apply the policy to the driver threads too. */ + ctx->pipe->set_context_param(ctx->pipe, + PIPE_CONTEXT_PARAM_UPDATE_THREAD_SCHEDULING, + cpu); + } + } } static void -glthread_thread_initialization(void *job, int thread_index) +glthread_thread_initialization(void *job, void *gdata, int thread_index) { struct gl_context *ctx = (struct gl_context*)job; - ctx->Driver.SetBackgroundContext(ctx, &ctx->GLThread.stats); + st_set_background_context(ctx, &ctx->GLThread.stats); _glapi_set_context(ctx); } +static void +_mesa_glthread_init_dispatch(struct gl_context *ctx, + struct _glapi_table *table) +{ + _mesa_glthread_init_dispatch0(ctx, table); + _mesa_glthread_init_dispatch1(ctx, table); + _mesa_glthread_init_dispatch2(ctx, table); + _mesa_glthread_init_dispatch3(ctx, table); + _mesa_glthread_init_dispatch4(ctx, table); + _mesa_glthread_init_dispatch5(ctx, table); + _mesa_glthread_init_dispatch6(ctx, table); + _mesa_glthread_init_dispatch7(ctx, table); +} + void _mesa_glthread_init(struct gl_context *ctx) { + struct pipe_screen *screen = ctx->screen; struct glthread_state *glthread = &ctx->GLThread; - assert(!glthread->enabled); - if (!util_queue_init(&glthread->queue, "gl", MARSHAL_MAX_BATCHES - 2, - 1, 0)) { + if (!screen->get_param(screen, PIPE_CAP_MAP_UNSYNCHRONIZED_THREAD_SAFE) || + !screen->get_param(screen, PIPE_CAP_ALLOW_MAPPED_BUFFERS_DURING_EXECUTION)) return; - } - glthread->VAOs = _mesa_NewHashTable(); - if (!glthread->VAOs) { - util_queue_destroy(&glthread->queue); + if (!util_queue_init(&glthread->queue, "gl", MARSHAL_MAX_BATCHES - 2, + 1, 0, NULL)) { return; } + _mesa_InitHashTable(&glthread->VAOs); _mesa_glthread_reset_vao(&glthread->DefaultVAO); glthread->CurrentVAO = &glthread->DefaultVAO; - ctx->MarshalExec = _mesa_create_marshal_table(ctx); + ctx->MarshalExec = _mesa_alloc_dispatch_table(true); if (!ctx->MarshalExec) { - _mesa_DeleteHashTable(glthread->VAOs); + _mesa_DeinitHashTable(&glthread->VAOs, NULL, NULL); util_queue_destroy(&glthread->queue); return; } + _mesa_glthread_init_dispatch(ctx, ctx->MarshalExec); + _mesa_init_pixelstore_attrib(ctx, &glthread->Unpack); + for (unsigned i = 0; i < MARSHAL_MAX_BATCHES; i++) { glthread->batches[i].ctx = ctx; util_queue_fence_init(&glthread->batches[i].fence); } glthread->next_batch = &glthread->batches[glthread->next]; glthread->used = 0; - - glthread->enabled = true; glthread->stats.queue = &glthread->queue; - glthread->SupportsBufferUploads = - ctx->Const.BufferCreateMapUnsynchronizedThreadSafe && - ctx->Const.AllowMappedBuffersDuringExecution; - - /* If the draw start index is non-zero, glthread can upload to offset 0, - * which means the attrib offset has to be -(first * stride). - * So require signed vertex buffer offsets. - */ - glthread->SupportsNonVBOUploads = glthread->SupportsBufferUploads && - ctx->Const.VertexBufferOffsetIsInt32; + _mesa_glthread_init_call_fence(&glthread->LastProgramChangeBatch); + _mesa_glthread_init_call_fence(&glthread->LastDListChangeBatchIndex); - ctx->CurrentClientDispatch = ctx->MarshalExec; - - glthread->LastDListChangeBatchIndex = -1; + _mesa_glthread_enable(ctx); /* Execute the thread initialization function in the thread. */ struct util_queue_fence fence; @@ -148,6 +257,11 @@ _mesa_glthread_init(struct gl_context *ctx) glthread_thread_initialization, NULL, 0); util_queue_fence_wait(&fence); util_queue_fence_destroy(&fence); + + glthread->thread_sched_enabled = ctx->pipe->set_context_param && + util_thread_scheduler_enabled(); + util_thread_scheduler_init_state(&glthread->thread_sched_state); + glthread_apply_thread_sched_policy(ctx, true); } static void @@ -161,46 +275,82 @@ _mesa_glthread_destroy(struct gl_context *ctx) { struct glthread_state *glthread = &ctx->GLThread; - if (!glthread->enabled) - return; + _mesa_glthread_disable(ctx); - _mesa_glthread_finish(ctx); - util_queue_destroy(&glthread->queue); + if (util_queue_is_initialized(&glthread->queue)) { + util_queue_destroy(&glthread->queue); - for (unsigned i = 0; i < MARSHAL_MAX_BATCHES; i++) - util_queue_fence_destroy(&glthread->batches[i].fence); + for (unsigned i = 0; i < MARSHAL_MAX_BATCHES; i++) + util_queue_fence_destroy(&glthread->batches[i].fence); - _mesa_HashDeleteAll(glthread->VAOs, free_vao, NULL); - _mesa_DeleteHashTable(glthread->VAOs); + _mesa_DeinitHashTable(&glthread->VAOs, free_vao, NULL); + _mesa_glthread_release_upload_buffer(ctx); + } +} - ctx->GLThread.enabled = false; +void _mesa_glthread_enable(struct gl_context *ctx) +{ + if (ctx->GLThread.enabled || + ctx->Dispatch.Current == ctx->Dispatch.ContextLost || + ctx->GLThread.DebugOutputSynchronous) + return; + + ctx->GLThread.enabled = true; + ctx->GLApi = ctx->MarshalExec; + + /* glthread takes over all thread scheduling. */ + ctx->st->pin_thread_counter = ST_THREAD_SCHEDULER_DISABLED; - _mesa_glthread_restore_dispatch(ctx, "destroy"); + /* Update the dispatch only if the dispatch is current. */ + if (_glapi_get_dispatch() == ctx->Dispatch.Current) { + _glapi_set_dispatch(ctx->GLApi); + } } -void -_mesa_glthread_restore_dispatch(struct gl_context *ctx, const char *func) +void _mesa_glthread_disable(struct gl_context *ctx) { - /* Remove ourselves from the dispatch table except if another ctx/thread - * already installed a new dispatch table. - * - * Typically glxMakeCurrent will bind a new context (install new table) then - * old context might be deleted. - */ + if (!ctx->GLThread.enabled) + return; + + _mesa_glthread_finish(ctx); + + ctx->GLThread.enabled = false; + ctx->GLApi = ctx->Dispatch.Current; + + /* Re-enable thread scheduling in st/mesa when glthread is disabled. */ + if (ctx->pipe->set_context_param && util_thread_scheduler_enabled()) + ctx->st->pin_thread_counter = 0; + + /* Update the dispatch only if the dispatch is current. */ if (_glapi_get_dispatch() == ctx->MarshalExec) { - ctx->CurrentClientDispatch = ctx->CurrentServerDispatch; - _glapi_set_dispatch(ctx->CurrentClientDispatch); -#if 0 - printf("glthread disabled: %s\n", func); -#endif + _glapi_set_dispatch(ctx->GLApi); } + + /* Unbind VBOs in all VAOs that glthread bound for non-VBO vertex uploads + * to restore original states. + */ + if (ctx->API != API_OPENGL_CORE) + _mesa_glthread_unbind_uploaded_vbos(ctx); } -void -_mesa_glthread_disable(struct gl_context *ctx, const char *func) +static void +glthread_finalize_batch(struct glthread_state *glthread, + unsigned *num_items_counter) { - _mesa_glthread_finish_before(ctx, func); - _mesa_glthread_restore_dispatch(ctx, func); + struct glthread_batch *next = glthread->next_batch; + + /* Mark the end of the batch, but don't increment "used". */ + struct marshal_cmd_base *last = + (struct marshal_cmd_base *)&next->buffer[glthread->used]; + last->cmd_id = NUM_DISPATCH_CMD; + + p_atomic_add(num_items_counter, glthread->used); + next->used = glthread->used; + glthread->used = 0; + + glthread->LastCallList = NULL; + glthread->LastBindBuffer1 = NULL; + glthread->LastBindBuffer2 = NULL; } void @@ -210,51 +360,24 @@ _mesa_glthread_flush_batch(struct gl_context *ctx) if (!glthread->enabled) return; - if (!glthread->used) + if (ctx->Dispatch.Current == ctx->Dispatch.ContextLost) { + _mesa_glthread_disable(ctx); return; - - /* Pin threads regularly to the same Zen CCX that the main thread is - * running on. The main thread can move between CCXs. - */ - if (util_get_cpu_caps()->num_L3_caches > 1 && - /* driver support */ - ctx->Driver.PinDriverToL3Cache && - ++glthread->pin_thread_counter % 128 == 0) { - int cpu = util_get_current_cpu(); - - if (cpu >= 0) { - uint16_t L3_cache = util_get_cpu_caps()->cpu_to_L3[cpu]; - if (L3_cache != U_CPU_INVALID_L3) { - util_set_thread_affinity(glthread->queue.threads[0], - util_get_cpu_caps()->L3_affinity_mask[L3_cache], - NULL, util_get_cpu_caps()->num_cpu_mask_bits); - ctx->Driver.PinDriverToL3Cache(ctx, L3_cache); - } - } } - struct glthread_batch *next = glthread->next_batch; + if (!glthread->used) + return; /* the batch is empty */ - /* Debug: execute the batch immediately from this thread. - * - * Note that glthread_unmarshal_batch() changes the dispatch table so we'll - * need to restore it when it returns. - */ - if (false) { - glthread_unmarshal_batch(next, 0); - _glapi_set_dispatch(ctx->CurrentClientDispatch); - return; - } + glthread_apply_thread_sched_policy(ctx, false); + glthread_finalize_batch(glthread, &glthread->stats.num_offloaded_items); - p_atomic_add(&glthread->stats.num_offloaded_items, glthread->used); - next->used = glthread->used; + struct glthread_batch *next = glthread->next_batch; util_queue_add_job(&glthread->queue, next, &next->fence, glthread_unmarshal_batch, NULL, 0); glthread->last = glthread->next; glthread->next = (glthread->next + 1) % MARSHAL_MAX_BATCHES; glthread->next_batch = &glthread->batches[glthread->next]; - glthread->used = 0; } /** @@ -287,16 +410,16 @@ _mesa_glthread_finish(struct gl_context *ctx) synced = true; } + glthread_apply_thread_sched_policy(ctx, false); + if (glthread->used) { - p_atomic_add(&glthread->stats.num_direct_items, glthread->used); - next->used = glthread->used; - glthread->used = 0; + glthread_finalize_batch(glthread, &glthread->stats.num_direct_items); /* Since glthread_unmarshal_batch changes the dispatch to direct, * restore it after it's done. */ struct _glapi_table *dispatch = _glapi_get_dispatch(); - glthread_unmarshal_batch(next, 0); + glthread_unmarshal_batch(next, NULL, 0); _glapi_set_dispatch(dispatch); /* It's not a sync because we don't enqueue partial batches, but @@ -338,3 +461,66 @@ _mesa_error_glthread_safe(struct gl_context *ctx, GLenum error, bool glthread, _mesa_error(ctx, error, "%s", s); } } + +bool +_mesa_glthread_invalidate_zsbuf(struct gl_context *ctx) +{ + struct glthread_state *glthread = &ctx->GLThread; + if (!glthread->enabled) + return false; + _mesa_marshal_InternalInvalidateFramebufferAncillaryMESA(); + return true; +} + +void +_mesa_glthread_PixelStorei(struct gl_context *ctx, GLenum pname, GLint param) +{ + switch (pname) { + case GL_UNPACK_SWAP_BYTES: + ctx->GLThread.Unpack.SwapBytes = !!param; + break; + case GL_UNPACK_LSB_FIRST: + ctx->GLThread.Unpack.LsbFirst = !!param; + break; + case GL_UNPACK_ROW_LENGTH: + if (param >= 0) + ctx->GLThread.Unpack.RowLength = param; + break; + case GL_UNPACK_IMAGE_HEIGHT: + if (param >= 0) + ctx->GLThread.Unpack.ImageHeight = param; + break; + case GL_UNPACK_SKIP_PIXELS: + if (param >= 0) + ctx->GLThread.Unpack.SkipPixels = param; + break; + case GL_UNPACK_SKIP_ROWS: + if (param >= 0) + ctx->GLThread.Unpack.SkipRows = param; + break; + case GL_UNPACK_SKIP_IMAGES: + if (param >= 0) + ctx->GLThread.Unpack.SkipImages = param; + break; + case GL_UNPACK_ALIGNMENT: + if (param >= 1 && param <= 8 && util_is_power_of_two_nonzero(param)) + ctx->GLThread.Unpack.Alignment = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_WIDTH: + if (param >= 0) + ctx->GLThread.Unpack.CompressedBlockWidth = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT: + if (param >= 0) + ctx->GLThread.Unpack.CompressedBlockHeight = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_DEPTH: + if (param >= 0) + ctx->GLThread.Unpack.CompressedBlockDepth = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_SIZE: + if (param >= 0) + ctx->GLThread.Unpack.CompressedBlockSize = param; + break; + } +} diff --git a/src/mesa/main/glthread.h b/src/mesa/main/glthread.h index 6388baeaf61..39594b368e7 100644 --- a/src/mesa/main/glthread.h +++ b/src/mesa/main/glthread.h @@ -33,7 +33,12 @@ * chance of experiencing CPU cache thrashing * but it should be high enough so that u_queue overhead remains negligible. */ -#define MARSHAL_MAX_CMD_SIZE (8 * 1024) +#define MARSHAL_MAX_CMD_BUFFER_SIZE (8 * 1024) + +/* We need to leave 1 slot at the end to insert the END marker for unmarshal + * calls that look ahead to know where the batch ends. + */ +#define MARSHAL_MAX_CMD_SIZE (MARSHAL_MAX_CMD_BUFFER_SIZE - 8) /* The number of batch slots in memory. * @@ -49,9 +54,10 @@ #include <inttypes.h> #include <stdbool.h> #include "util/u_queue.h" -#include "GL/gl.h" #include "compiler/shader_enums.h" #include "main/config.h" +#include "main/hash.h" +#include "util/glheader.h" #ifdef __cplusplus extern "C" { @@ -59,12 +65,64 @@ extern "C" { struct gl_context; struct gl_buffer_object; -struct _mesa_HashTable; +struct _glapi_table; + +/** + * Client pixel packing/unpacking attributes + */ +struct gl_pixelstore_attrib +{ + GLint Alignment; + GLint RowLength; + GLint SkipPixels; + GLint SkipRows; + GLint ImageHeight; + GLint SkipImages; + GLboolean SwapBytes; + GLboolean LsbFirst; + GLboolean Invert; /**< GL_MESA_pack_invert */ + GLint CompressedBlockWidth; /**< GL_ARB_compressed_texture_pixel_storage */ + GLint CompressedBlockHeight; + GLint CompressedBlockDepth; + GLint CompressedBlockSize; + struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */ +}; + +/* Used by both glthread and gl_context. */ +union gl_vertex_format_user { + struct { + GLenum16 Type; /**< datatype: GL_FLOAT, GL_INT, etc */ + bool Bgra; /**< true if GL_BGRA, else GL_RGBA */ + uint8_t Size:5; /**< components per element (1,2,3,4) */ + bool Normalized:1; /**< GL_ARB_vertex_program */ + bool Integer:1; /**< Integer-valued? */ + bool Doubles:1; /**< double values are not converted to floats */ + }; + uint32_t All; +}; -struct glthread_attrib_binding { - struct gl_buffer_object *buffer; /**< where non-VBO data was uploaded */ - int offset; /**< offset to uploaded non-VBO data */ - const void *original_pointer; /**< restore this pointer after the draw */ +#define MESA_PACK_VFORMAT(type, size, normalized, integer, doubles) \ + (union gl_vertex_format_user){{ \ + .Type = MIN2(type, 0xffff), /* 0xffff means invalid value */ \ + .Bgra = size == GL_BGRA, \ + .Size = size == GL_BGRA ? 4 : MIN2(size, 5), /* 5 means invalid value */ \ + .Normalized = normalized, \ + .Integer = integer, \ + .Doubles = doubles \ + }} + +struct glthread_attrib { + /* Per attrib: */ + uint8_t ElementSize; /**< max 32 */ + uint8_t BufferIndex; /**< Referring to Attrib[BufferIndex]. */ + uint16_t RelativeOffset; /**< max 0xffff in Mesa */ + union gl_vertex_format_user Format; + + /* Per buffer binding: */ + GLuint Divisor; + int16_t Stride; /**< max 2048 */ + int8_t EnabledAttribCount; /**< Number of enabled attribs using this buffer. */ + const void *Pointer; }; struct glthread_vao { @@ -75,20 +133,10 @@ struct glthread_vao { GLbitfield BufferEnabled; /**< "Enabled" converted to buffer bindings. */ GLbitfield BufferInterleaved; /**< Bitmask of buffers used by multiple attribs. */ GLbitfield UserPointerMask; /**< Bitmask of buffer bindings. */ + GLbitfield NonNullPointerMask; /**< Bitmask of buffer bindings with non-NULL user pointers. */ GLbitfield NonZeroDivisorMask; /**< Bitmask of buffer bindings. */ - struct { - /* Per attrib: */ - GLuint ElementSize; - GLuint RelativeOffset; - GLuint BufferIndex; /**< Referring to Attrib[BufferIndex]. */ - - /* Per buffer binding: */ - GLsizei Stride; - GLuint Divisor; - int EnabledAttribCount; /**< Number of enabled attribs using this buffer. */ - const void *Pointer; - } Attrib[VERT_ATTRIB_MAX]; + struct glthread_attrib Attrib[VERT_ATTRIB_MAX]; }; /** A single batch of commands queued up for execution. */ @@ -109,7 +157,7 @@ struct glthread_batch unsigned used; /** Data contained in the command buffer. */ - uint64_t buffer[MARSHAL_MAX_CMD_SIZE / 8]; + uint64_t buffer[MARSHAL_MAX_CMD_BUFFER_SIZE / 8]; }; struct glthread_client_attrib { @@ -128,7 +176,12 @@ struct glthread_client_attrib { struct glthread_attrib_node { GLbitfield Mask; int ActiveTexture; - GLenum MatrixMode; + GLenum16 MatrixMode; + bool Blend; + bool CullFace; + bool DepthTest; + bool Lighting; + bool PolygonStipple; }; typedef enum { @@ -152,14 +205,17 @@ struct glthread_state /** Whether GLThread is enabled. */ bool enabled; + bool inside_begin_end; + bool thread_sched_enabled; /** Display lists. */ - GLenum ListMode; /**< Zero if not inside display list, else list mode. */ + GLenum16 ListMode; /**< Zero if not inside display list, else list mode. */ unsigned ListBase; unsigned ListCallDepth; /** For L3 cache pinning. */ unsigned pin_thread_counter; + unsigned thread_sched_state; /** The ring of batches in memory. */ struct glthread_batch batches[MARSHAL_MAX_BATCHES]; @@ -182,10 +238,6 @@ struct glthread_state unsigned upload_offset; int upload_buffer_private_refcount; - /** Caps. */ - GLboolean SupportsBufferUploads; - GLboolean SupportsNonVBOUploads; - /** Primitive restart state. */ bool PrimitiveRestart; bool PrimitiveRestartFixedIndex; @@ -194,7 +246,7 @@ struct glthread_state GLuint _RestartIndex[4]; /**< Restart index for index_size = 1,2,4. */ /** Vertex Array objects tracked by glthread independently of Mesa. */ - struct _mesa_HashTable *VAOs; + struct _mesa_HashTable VAOs; struct glthread_vao *CurrentVAO; struct glthread_vao *LastLookedUpVAO; struct glthread_vao DefaultVAO; @@ -207,6 +259,7 @@ struct glthread_state GLuint CurrentDrawIndirectBufferName; GLuint CurrentPixelPackBufferName; GLuint CurrentPixelUnpackBufferName; + GLuint CurrentQueryBufferName; /** * The batch index of the last occurence of glLinkProgram or @@ -222,32 +275,73 @@ struct glthread_state /** Basic matrix state tracking. */ int ActiveTexture; - GLenum MatrixMode; + GLenum16 MatrixMode; gl_matrix_index MatrixIndex; struct glthread_attrib_node AttribStack[MAX_ATTRIB_STACK_DEPTH]; int AttribStackDepth; int MatrixStackDepth[M_NUM_MATRIX_STACKS]; + + /** Enable states. */ + bool Blend; + bool DepthTest; + bool CullFace; + bool DebugOutputSynchronous; + bool Lighting; + bool PolygonStipple; + + GLuint CurrentDrawFramebuffer; + GLuint CurrentReadFramebuffer; + GLuint CurrentProgram; + + /** The last added call of the given function. */ + struct marshal_cmd_CallList *LastCallList; + struct marshal_cmd_BindBuffer *LastBindBuffer1; + struct marshal_cmd_BindBuffer *LastBindBuffer2; + + /** Global mutex update info. */ + unsigned GlobalLockUpdateBatchCounter; + bool LockGlobalMutexes; + + struct gl_pixelstore_attrib Unpack; }; void _mesa_glthread_init(struct gl_context *ctx); void _mesa_glthread_destroy(struct gl_context *ctx); -void _mesa_glthread_restore_dispatch(struct gl_context *ctx, const char *func); -void _mesa_glthread_disable(struct gl_context *ctx, const char *func); +void _mesa_glthread_init_dispatch0(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch1(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch2(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch3(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch4(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch5(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch6(struct gl_context *ctx, + struct _glapi_table *table); +void _mesa_glthread_init_dispatch7(struct gl_context *ctx, + struct _glapi_table *table); + +void _mesa_glthread_enable(struct gl_context *ctx); +void _mesa_glthread_disable(struct gl_context *ctx); void _mesa_glthread_flush_batch(struct gl_context *ctx); void _mesa_glthread_finish(struct gl_context *ctx); void _mesa_glthread_finish_before(struct gl_context *ctx, const char *func); +bool _mesa_glthread_invalidate_zsbuf(struct gl_context *ctx); +void _mesa_glthread_release_upload_buffer(struct gl_context *ctx); void _mesa_glthread_upload(struct gl_context *ctx, const void *data, GLsizeiptr size, unsigned *out_offset, struct gl_buffer_object **out_buffer, - uint8_t **out_ptr); + uint8_t **out_ptr, + unsigned start_offset); void _mesa_glthread_reset_vao(struct glthread_vao *vao); void _mesa_error_glthread_safe(struct gl_context *ctx, GLenum error, bool glthread, const char *format, ...); void _mesa_glthread_execute_list(struct gl_context *ctx, GLuint list); -void _mesa_glthread_BindBuffer(struct gl_context *ctx, GLenum target, - GLuint buffer); void _mesa_glthread_DeleteBuffers(struct gl_context *ctx, GLsizei n, const GLuint *buffers); @@ -264,16 +358,18 @@ void _mesa_glthread_ClientState(struct gl_context *ctx, GLuint *vaobj, void _mesa_glthread_AttribDivisor(struct gl_context *ctx, const GLuint *vaobj, gl_vert_attrib attrib, GLuint divisor); void _mesa_glthread_AttribPointer(struct gl_context *ctx, gl_vert_attrib attrib, - GLint size, GLenum type, GLsizei stride, - const void *pointer); + union gl_vertex_format_user format, + GLsizei stride, const void *pointer); void _mesa_glthread_DSAAttribPointer(struct gl_context *ctx, GLuint vao, GLuint buffer, gl_vert_attrib attrib, - GLint size, GLenum type, GLsizei stride, - GLintptr offset); + union gl_vertex_format_user format, + GLsizei stride, GLintptr offset); void _mesa_glthread_AttribFormat(struct gl_context *ctx, GLuint attribindex, - GLint size, GLenum type, GLuint relativeoffset); + union gl_vertex_format_user format, + GLuint relativeoffset); void _mesa_glthread_DSAAttribFormat(struct gl_context *ctx, GLuint vaobj, - GLuint attribindex, GLint size, GLenum type, + GLuint attribindex, + union gl_vertex_format_user format, GLuint relativeoffset); void _mesa_glthread_VertexBuffer(struct gl_context *ctx, GLuint bindingindex, GLuint buffer, GLintptr offset, GLsizei stride); @@ -302,6 +398,12 @@ void _mesa_glthread_ClientAttribDefault(struct gl_context *ctx, GLbitfield mask) void _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format, GLsizei stride, const GLvoid *pointer); void _mesa_glthread_ProgramChanged(struct gl_context *ctx); +void _mesa_glthread_UnrollDrawElements(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex); +void _mesa_glthread_unbind_uploaded_vbos(struct gl_context *ctx); +void _mesa_glthread_PixelStorei(struct gl_context *ctx, GLenum pname, + GLint param); #ifdef __cplusplus } diff --git a/src/mesa/main/glthread_bufferobj.c b/src/mesa/main/glthread_bufferobj.c index 6413780a8a5..499a480a339 100644 --- a/src/mesa/main/glthread_bufferobj.c +++ b/src/mesa/main/glthread_bufferobj.c @@ -32,29 +32,30 @@ static struct gl_buffer_object * new_upload_buffer(struct gl_context *ctx, GLsizeiptr size, uint8_t **ptr) { - assert(ctx->GLThread.SupportsBufferUploads); - - struct gl_buffer_object *obj = ctx->Driver.NewBufferObject(ctx, -1); + /* id 0 is used to avoid returning invalid binding values to apps */ + struct gl_buffer_object *obj = + _mesa_bufferobj_alloc(ctx, 0); if (!obj) return NULL; obj->Immutable = true; + obj->GLThreadInternal = true; - if (!ctx->Driver.BufferData(ctx, GL_ARRAY_BUFFER, size, NULL, - GL_WRITE_ONLY, - GL_CLIENT_STORAGE_BIT | GL_MAP_WRITE_BIT, - obj)) { - ctx->Driver.DeleteBuffer(ctx, obj); + if (!_mesa_bufferobj_data(ctx, GL_ARRAY_BUFFER, size, NULL, + GL_WRITE_ONLY, + GL_CLIENT_STORAGE_BIT | GL_MAP_WRITE_BIT, + obj)) { + _mesa_delete_buffer_object(ctx, obj); return NULL; } - *ptr = ctx->Driver.MapBufferRange(ctx, 0, size, - GL_MAP_WRITE_BIT | - GL_MAP_UNSYNCHRONIZED_BIT | - MESA_MAP_THREAD_SAFE_BIT, - obj, MAP_GLTHREAD); + *ptr = _mesa_bufferobj_map_range(ctx, 0, size, + GL_MAP_WRITE_BIT | + GL_MAP_UNSYNCHRONIZED_BIT | + MESA_MAP_THREAD_SAFE_BIT, + obj, MAP_GLTHREAD); if (!*ptr) { - ctx->Driver.DeleteBuffer(ctx, obj); + _mesa_delete_buffer_object(ctx, obj); return NULL; } @@ -62,10 +63,24 @@ new_upload_buffer(struct gl_context *ctx, GLsizeiptr size, uint8_t **ptr) } void +_mesa_glthread_release_upload_buffer(struct gl_context *ctx) +{ + struct glthread_state *glthread = &ctx->GLThread; + + if (glthread->upload_buffer_private_refcount > 0) { + p_atomic_add(&glthread->upload_buffer->RefCount, + -glthread->upload_buffer_private_refcount); + glthread->upload_buffer_private_refcount = 0; + } + _mesa_reference_buffer_object(ctx, &glthread->upload_buffer, NULL); +} + +void _mesa_glthread_upload(struct gl_context *ctx, const void *data, GLsizeiptr size, unsigned *out_offset, struct gl_buffer_object **out_buffer, - uint8_t **out_ptr) + uint8_t **out_ptr, + unsigned start_offset) { struct glthread_state *glthread = &ctx->GLThread; const unsigned default_size = 1024 * 1024; @@ -74,22 +89,23 @@ _mesa_glthread_upload(struct gl_context *ctx, const void *data, return; /* The alignment was chosen arbitrarily. */ - unsigned offset = align(glthread->upload_offset, 8); + unsigned offset = align(glthread->upload_offset, size <= 4 ? 4 : 8) + start_offset; /* Allocate a new buffer if needed. */ if (unlikely(!glthread->upload_buffer || offset + size > default_size)) { /* If the size is greater than the buffer size, allocate a separate buffer * just for this upload. */ - if (unlikely(size > default_size)) { + if (unlikely(start_offset + size > default_size)) { uint8_t *ptr; assert(*out_buffer == NULL); - *out_buffer = new_upload_buffer(ctx, size, &ptr); + *out_buffer = new_upload_buffer(ctx, size + start_offset, &ptr); if (!*out_buffer) return; - *out_offset = 0; + ptr += start_offset; + *out_offset = start_offset; if (data) memcpy(ptr, data, size); else @@ -97,16 +113,12 @@ _mesa_glthread_upload(struct gl_context *ctx, const void *data, return; } - if (glthread->upload_buffer_private_refcount > 0) { - p_atomic_add(&glthread->upload_buffer->RefCount, - -glthread->upload_buffer_private_refcount); - glthread->upload_buffer_private_refcount = 0; - } - _mesa_reference_buffer_object(ctx, &glthread->upload_buffer, NULL); + _mesa_glthread_release_upload_buffer(ctx); + glthread->upload_buffer = new_upload_buffer(ctx, default_size, &glthread->upload_ptr); glthread->upload_offset = 0; - offset = 0; + offset = start_offset; /* Since atomic operations are very very slow when 2 threads are not * sharing one L3 cache (which can happen on AMD Zen), prevent using @@ -170,7 +182,7 @@ _mesa_glthread_upload(struct gl_context *ctx, const void *data, * feature that if you pass a bad name, it just gens a buffer object for you, * so we escape without having to know if things are valid or not. */ -void +static void _mesa_glthread_BindBuffer(struct gl_context *ctx, GLenum target, GLuint buffer) { struct glthread_state *glthread = &ctx->GLThread; @@ -195,7 +207,78 @@ _mesa_glthread_BindBuffer(struct gl_context *ctx, GLenum target, GLuint buffer) case GL_PIXEL_UNPACK_BUFFER: glthread->CurrentPixelUnpackBufferName = buffer; break; + case GL_QUERY_BUFFER: + glthread->CurrentQueryBufferName = buffer; + break; + } +} + +struct marshal_cmd_BindBuffer +{ + struct marshal_cmd_base cmd_base; + GLenum16 target; + GLuint buffer; +}; + +uint32_t +_mesa_unmarshal_BindBuffer(struct gl_context *ctx, + const struct marshal_cmd_BindBuffer *restrict cmd) +{ + CALL_BindBuffer(ctx->Dispatch.Current, (cmd->target, cmd->buffer)); + return align(sizeof(struct marshal_cmd_BindBuffer), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_BindBuffer(GLenum target, GLuint buffer) +{ + GET_CURRENT_CONTEXT(ctx); + _mesa_glthread_BindBuffer(ctx, target, buffer); + + struct glthread_state *glthread = &ctx->GLThread; + struct marshal_cmd_BindBuffer *last1 = glthread->LastBindBuffer1; + struct marshal_cmd_BindBuffer *last2 = glthread->LastBindBuffer2; + int cmd_size = sizeof(struct marshal_cmd_BindBuffer); + + /* Eliminate duplicated BindBuffer calls, which are plentiful + * in viewperf2020/catia. In this example, the first 2 calls are eliminated + * by glthread by keeping track of the last 2 BindBuffer calls and + * overwriting them if the target matches. + * + * glBindBuffer(GL_ARRAY_BUFFER, 0); + * glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + * glBindBuffer(GL_ARRAY_BUFFER, 6); + * glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 7); + * + * If the last call is BindBuffer... + * last2 is more recent. last1 is before last2. + */ + if (_mesa_glthread_call_is_last(glthread, &last2->cmd_base, + align(cmd_size, 8) / 8)) { + /* If the target is in the last call and unbinding the buffer, overwrite + * the buffer ID there. + */ + if (target == last2->target) { + /* We can't overwrite binding non-zero buffers because binding also + * creates the GL objects (like glCreateBuffers), which can't be skipped. + */ + if (!last2->buffer) { + last2->buffer = buffer; + return; + } + } else if (last1 + 1 == last2 && target == last1->target && + !last1->buffer) { + last1->buffer = buffer; + return; + } } + + struct marshal_cmd_BindBuffer *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BindBuffer, cmd_size); + cmd->target = MIN2(target, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->buffer = buffer; + + glthread->LastBindBuffer1 = last2; + glthread->LastBindBuffer2 = cmd; } void @@ -204,7 +287,7 @@ _mesa_glthread_DeleteBuffers(struct gl_context *ctx, GLsizei n, { struct glthread_state *glthread = &ctx->GLThread; - if (!buffers) + if (!buffers || n < 0) return; for (unsigned i = 0; i < n; i++) { @@ -227,6 +310,7 @@ _mesa_glthread_DeleteBuffers(struct gl_context *ctx, GLsizei n, struct marshal_cmd_BufferData { struct marshal_cmd_base cmd_base; + uint16_t num_slots; GLuint target_or_name; GLsizeiptr size; GLenum usage; @@ -237,9 +321,9 @@ struct marshal_cmd_BufferData /* Next size bytes are GLubyte data[size] */ }; -void +uint32_t _mesa_unmarshal_BufferData(struct gl_context *ctx, - const struct marshal_cmd_BufferData *cmd) + const struct marshal_cmd_BufferData *restrict cmd) { const GLuint target_or_name = cmd->target_or_name; const GLsizei size = cmd->size; @@ -254,29 +338,32 @@ _mesa_unmarshal_BufferData(struct gl_context *ctx, data = (const void *) (cmd + 1); if (cmd->ext_dsa) { - CALL_NamedBufferDataEXT(ctx->CurrentServerDispatch, + CALL_NamedBufferDataEXT(ctx->Dispatch.Current, (target_or_name, size, data, usage)); } else if (cmd->named) { - CALL_NamedBufferData(ctx->CurrentServerDispatch, + CALL_NamedBufferData(ctx->Dispatch.Current, (target_or_name, size, data, usage)); } else { - CALL_BufferData(ctx->CurrentServerDispatch, + CALL_BufferData(ctx->Dispatch.Current, (target_or_name, size, data, usage)); } + return cmd->num_slots; } -void +uint32_t _mesa_unmarshal_NamedBufferData(struct gl_context *ctx, - const struct marshal_cmd_NamedBufferData *cmd) + const struct marshal_cmd_NamedBufferData *restrict cmd) { unreachable("never used - all BufferData variants use DISPATCH_CMD_BufferData"); + return 0; } -void +uint32_t _mesa_unmarshal_NamedBufferDataEXT(struct gl_context *ctx, - const struct marshal_cmd_NamedBufferDataEXT *cmd) + const struct marshal_cmd_NamedBufferDataEXT *restrict cmd) { unreachable("never used - all BufferData variants use DISPATCH_CMD_BufferData"); + return 0; } static void @@ -294,10 +381,10 @@ _mesa_marshal_BufferData_merged(GLuint target_or_name, GLsizeiptr size, (named && target_or_name == 0))) { _mesa_glthread_finish_before(ctx, func); if (named) { - CALL_NamedBufferData(ctx->CurrentServerDispatch, + CALL_NamedBufferData(ctx->Dispatch.Current, (target_or_name, size, data, usage)); } else { - CALL_BufferData(ctx->CurrentServerDispatch, + CALL_BufferData(ctx->Dispatch.Current, (target_or_name, size, data, usage)); } return; @@ -306,7 +393,7 @@ _mesa_marshal_BufferData_merged(GLuint target_or_name, GLsizeiptr size, struct marshal_cmd_BufferData *cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BufferData, cmd_size); - + cmd->num_slots = align(cmd_size, 8) / 8; cmd->target_or_name = target_or_name; cmd->size = size; cmd->usage = usage; @@ -350,6 +437,7 @@ _mesa_marshal_NamedBufferDataEXT(GLuint buffer, GLsizeiptr size, struct marshal_cmd_BufferSubData { struct marshal_cmd_base cmd_base; + uint16_t num_slots; GLenum target_or_name; GLintptr offset; GLsizeiptr size; @@ -358,9 +446,9 @@ struct marshal_cmd_BufferSubData /* Next size bytes are GLubyte data[size] */ }; -void +uint32_t _mesa_unmarshal_BufferSubData(struct gl_context *ctx, - const struct marshal_cmd_BufferSubData *cmd) + const struct marshal_cmd_BufferSubData *restrict cmd) { const GLenum target_or_name = cmd->target_or_name; const GLintptr offset = cmd->offset; @@ -368,29 +456,32 @@ _mesa_unmarshal_BufferSubData(struct gl_context *ctx, const void *data = (const void *) (cmd + 1); if (cmd->ext_dsa) { - CALL_NamedBufferSubDataEXT(ctx->CurrentServerDispatch, + CALL_NamedBufferSubDataEXT(ctx->Dispatch.Current, (target_or_name, offset, size, data)); } else if (cmd->named) { - CALL_NamedBufferSubData(ctx->CurrentServerDispatch, + CALL_NamedBufferSubData(ctx->Dispatch.Current, (target_or_name, offset, size, data)); } else { - CALL_BufferSubData(ctx->CurrentServerDispatch, + CALL_BufferSubData(ctx->Dispatch.Current, (target_or_name, offset, size, data)); } + return cmd->num_slots; } -void +uint32_t _mesa_unmarshal_NamedBufferSubData(struct gl_context *ctx, - const struct marshal_cmd_NamedBufferSubData *cmd) + const struct marshal_cmd_NamedBufferSubData *restrict cmd) { unreachable("never used - all BufferSubData variants use DISPATCH_CMD_BufferSubData"); + return 0; } -void +uint32_t _mesa_unmarshal_NamedBufferSubDataEXT(struct gl_context *ctx, - const struct marshal_cmd_NamedBufferSubDataEXT *cmd) + const struct marshal_cmd_NamedBufferSubDataEXT *restrict cmd) { unreachable("never used - all BufferSubData variants use DISPATCH_CMD_BufferSubData"); + return 0; } static void @@ -408,13 +499,14 @@ _mesa_marshal_BufferSubData_merged(GLuint target_or_name, GLintptr offset, * If offset == 0 and size == buffer_size, it's better to discard * the buffer storage, but we don't know the buffer size in glthread. */ - if (ctx->GLThread.SupportsBufferUploads && + if (ctx->Const.AllowGLThreadBufferSubDataOpt && + ctx->Dispatch.Current != ctx->Dispatch.ContextLost && data && offset > 0 && size > 0) { struct gl_buffer_object *upload_buffer = NULL; unsigned upload_offset = 0; _mesa_glthread_upload(ctx, data, size, &upload_offset, &upload_buffer, - NULL); + NULL, 0); if (upload_buffer) { _mesa_marshal_InternalBufferSubDataCopyMESA((GLintptr)upload_buffer, @@ -431,10 +523,10 @@ _mesa_marshal_BufferSubData_merged(GLuint target_or_name, GLintptr offset, (named && target_or_name == 0))) { _mesa_glthread_finish_before(ctx, func); if (named) { - CALL_NamedBufferSubData(ctx->CurrentServerDispatch, + CALL_NamedBufferSubData(ctx->Dispatch.Current, (target_or_name, offset, size, data)); } else { - CALL_BufferSubData(ctx->CurrentServerDispatch, + CALL_BufferSubData(ctx->Dispatch.Current, (target_or_name, offset, size, data)); } return; @@ -443,6 +535,7 @@ _mesa_marshal_BufferSubData_merged(GLuint target_or_name, GLintptr offset, struct marshal_cmd_BufferSubData *cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_BufferSubData, cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; cmd->target_or_name = target_or_name; cmd->offset = offset; cmd->size = size; diff --git a/src/mesa/main/glthread_draw.c b/src/mesa/main/glthread_draw.c index a534c51ab84..1bef35b0d71 100644 --- a/src/mesa/main/glthread_draw.c +++ b/src/mesa/main/glthread_draw.c @@ -29,6 +29,7 @@ #include "c99_alloca.h" +#include "api_exec_decl.h" #include "main/glthread_marshal.h" #include "main/dispatch.h" #include "main/varray.h" @@ -36,27 +37,26 @@ static inline unsigned get_index_size(GLenum type) { - /* GL_UNSIGNED_BYTE - GL_UNSIGNED_BYTE = 0 - * GL_UNSIGNED_SHORT - GL_UNSIGNED_BYTE = 2 - * GL_UNSIGNED_INT - GL_UNSIGNED_BYTE = 4 - * - * Divide by 2 to get n=0,1,2, then the index size is: 1 << n - */ - return 1 << ((type - GL_UNSIGNED_BYTE) >> 1); + return 1 << _mesa_get_index_size_shift(type); } -static inline bool -is_index_type_valid(GLenum type) +static inline GLindextype +encode_index_type(GLenum type) { - /* GL_UNSIGNED_BYTE = 0x1401 - * GL_UNSIGNED_SHORT = 0x1403 - * GL_UNSIGNED_INT = 0x1405 - * - * The trick is that bit 1 and bit 2 mean USHORT and UINT, respectively. - * After clearing those two bits (with ~6), we should get UBYTE. - * Both bits can't be set, because the enum would be greater than UINT. + /* Map invalid values less than GL_UNSIGNED_BYTE to GL_UNSIGNED_BYTE - 1, + * and invalid values greater than GL_UNSIGNED_INT to GL_UNSIGNED_INT + 1, + * Then subtract GL_UNSIGNED_BYTE - 1. Final encoding: + * 0 = invalid value + * 1 = GL_UNSIGNED_BYTE + * 2 = invalid value + * 3 = GL_UNSIGNED_SHORT + * 4 = invalid value + * 5 = GL_UNSIGNED_INT + * 6 = invalid value */ - return type <= GL_UNSIGNED_INT && (type & ~6) == GL_UNSIGNED_BYTE; + const unsigned min = GL_UNSIGNED_BYTE - 1; + const unsigned max = GL_UNSIGNED_INT + 1; + return (GLindextype){CLAMP(type, min, max) - min}; } static ALWAYS_INLINE struct gl_buffer_object * @@ -69,10 +69,12 @@ upload_indices(struct gl_context *ctx, unsigned count, unsigned index_size, assert(count); _mesa_glthread_upload(ctx, *indices, index_size * count, - &upload_offset, &upload_buffer, NULL); - assert(upload_buffer); + &upload_offset, &upload_buffer, NULL, 0); *indices = (const GLvoid*)(intptr_t)upload_offset; + if (!upload_buffer) + _mesa_marshal_InternalSetError(GL_OUT_OF_MEMORY); + return upload_buffer; } @@ -89,12 +91,18 @@ upload_multi_indices(struct gl_context *ctx, unsigned total_count, assert(total_count); _mesa_glthread_upload(ctx, NULL, index_size * total_count, - &upload_offset, &upload_buffer, &upload_ptr); - assert(upload_buffer); + &upload_offset, &upload_buffer, &upload_ptr, 0); + if (!upload_buffer) { + _mesa_marshal_InternalSetError(GL_OUT_OF_MEMORY); + return NULL; + } for (unsigned i = 0, offset = 0; i < draw_count; i++) { - if (count[i] == 0) + if (!count[i]) { + /* Set some valid value so as not to leave it uninitialized. */ + out_indices[i] = (const GLvoid*)(intptr_t)upload_offset; continue; + } unsigned size = count[i] * index_size; @@ -110,7 +118,7 @@ static ALWAYS_INLINE bool upload_vertices(struct gl_context *ctx, unsigned user_buffer_mask, unsigned start_vertex, unsigned num_vertices, unsigned start_instance, unsigned num_instances, - struct glthread_attrib_binding *buffers) + struct gl_buffer_object **buffers, int *offsets) { struct glthread_vao *vao = ctx->GLThread.CurrentVAO; unsigned attrib_mask_iter = vao->Enabled; @@ -188,15 +196,24 @@ upload_vertices(struct gl_context *ctx, unsigned user_buffer_mask, end = end_offset[binding_index]; assert(start < end); + /* If the draw start index is non-zero, glthread can upload to offset 0, + * which means the attrib offset has to be -(first * stride). + * So use signed vertex buffer offsets when possible to save memory. + */ const void *ptr = vao->Attrib[binding_index].Pointer; _mesa_glthread_upload(ctx, (uint8_t*)ptr + start, end - start, &upload_offset, - &upload_buffer, NULL); - assert(upload_buffer); + &upload_buffer, NULL, ctx->Const.VertexBufferOffsetIsInt32 ? 0 : start); + if (!upload_buffer) { + for (unsigned i = 0; i < num_buffers; i++) + _mesa_reference_buffer_object(ctx, &buffers[i], NULL); - buffers[num_buffers].buffer = upload_buffer; - buffers[num_buffers].offset = upload_offset - start; - buffers[num_buffers].original_pointer = ptr; + _mesa_marshal_InternalSetError(GL_OUT_OF_MEMORY); + return false; + } + + buffers[num_buffers] = upload_buffer; + offsets[num_buffers] = upload_offset - start; num_buffers++; } @@ -239,248 +256,266 @@ upload_vertices(struct gl_context *ctx, unsigned user_buffer_mask, size = stride * (num_vertices - 1) + element_size; } + /* If the draw start index is non-zero, glthread can upload to offset 0, + * which means the attrib offset has to be -(first * stride). + * So use signed vertex buffer offsets when possible to save memory. + */ const void *ptr = vao->Attrib[binding_index].Pointer; _mesa_glthread_upload(ctx, (uint8_t*)ptr + offset, - size, &upload_offset, &upload_buffer, NULL); - assert(upload_buffer); + size, &upload_offset, &upload_buffer, NULL, + ctx->Const.VertexBufferOffsetIsInt32 ? 0 : offset); + if (!upload_buffer) { + for (unsigned i = 0; i < num_buffers; i++) + _mesa_reference_buffer_object(ctx, &buffers[i], NULL); + + _mesa_marshal_InternalSetError(GL_OUT_OF_MEMORY); + return false; + } - buffers[num_buffers].buffer = upload_buffer; - buffers[num_buffers].offset = upload_offset - offset; - buffers[num_buffers].original_pointer = ptr; + buffers[num_buffers] = upload_buffer; + offsets[num_buffers] = upload_offset - offset; num_buffers++; } return true; } -/* Generic DrawArrays structure NOT supporting user buffers. Ignore the name. */ -struct marshal_cmd_DrawArrays +/* DrawArraysInstanced without user buffers. */ +uint32_t +_mesa_unmarshal_DrawArraysInstanced(struct gl_context *ctx, + const struct marshal_cmd_DrawArraysInstanced *restrict cmd) +{ + const GLenum mode = cmd->mode; + const GLint first = cmd->first; + const GLsizei count = cmd->count; + const GLsizei instance_count = cmd->primcount; + + CALL_DrawArraysInstanced(ctx->Dispatch.Current, (mode, first, count, instance_count)); + return align(sizeof(*cmd), 8) / 8; +} + +struct marshal_cmd_DrawArraysInstancedBaseInstanceDrawID { struct marshal_cmd_base cmd_base; - GLenum mode; + GLenum8 mode; GLint first; GLsizei count; GLsizei instance_count; GLuint baseinstance; + GLuint drawid; }; -void -_mesa_unmarshal_DrawArrays(struct gl_context *ctx, - const struct marshal_cmd_DrawArrays *cmd) +uint32_t +_mesa_unmarshal_DrawArraysInstancedBaseInstanceDrawID(struct gl_context *ctx, + const struct marshal_cmd_DrawArraysInstancedBaseInstanceDrawID *cmd) { - /* Ignore the function name. We use DISPATCH_CMD_DrawArrays - * for all DrawArrays variants without user buffers, and - * DISPATCH_CMD_DrawArraysInstancedBaseInstance for all DrawArrays - * variants with user buffrs. - */ const GLenum mode = cmd->mode; const GLint first = cmd->first; const GLsizei count = cmd->count; const GLsizei instance_count = cmd->instance_count; const GLuint baseinstance = cmd->baseinstance; - CALL_DrawArraysInstancedBaseInstance(ctx->CurrentServerDispatch, + ctx->DrawID = cmd->drawid; + CALL_DrawArraysInstancedBaseInstance(ctx->Dispatch.Current, (mode, first, count, instance_count, baseinstance)); + ctx->DrawID = 0; + return align(sizeof(*cmd), 8) / 8; } -static ALWAYS_INLINE void -draw_arrays_async(struct gl_context *ctx, GLenum mode, GLint first, - GLsizei count, GLsizei instance_count, GLuint baseinstance) -{ - int cmd_size = sizeof(struct marshal_cmd_DrawArrays); - struct marshal_cmd_DrawArrays *cmd = - _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArrays, cmd_size); - - cmd->mode = mode; - cmd->first = first; - cmd->count = count; - cmd->instance_count = instance_count; - cmd->baseinstance = baseinstance; -} - -/* Generic DrawArrays structure supporting user buffers. Ignore the name. */ -struct marshal_cmd_DrawArraysInstancedBaseInstance +/* DrawArraysInstancedBaseInstance with user buffers. */ +struct marshal_cmd_DrawArraysUserBuf { struct marshal_cmd_base cmd_base; - GLenum mode; + GLenum8 mode; + uint16_t num_slots; GLint first; GLsizei count; GLsizei instance_count; GLuint baseinstance; + GLuint drawid; GLuint user_buffer_mask; }; -void -_mesa_unmarshal_DrawArraysInstancedBaseInstance(struct gl_context *ctx, - const struct marshal_cmd_DrawArraysInstancedBaseInstance *cmd) +uint32_t +_mesa_unmarshal_DrawArraysUserBuf(struct gl_context *ctx, + const struct marshal_cmd_DrawArraysUserBuf *restrict cmd) { - /* Ignore the function name. We use DISPATCH_CMD_DrawArrays - * for all DrawArrays variants without user buffers, and - * DISPATCH_CMD_DrawArraysInstancedBaseInstance for all DrawArrays - * variants with user buffrs. - */ - const GLenum mode = cmd->mode; - const GLint first = cmd->first; - const GLsizei count = cmd->count; - const GLsizei instance_count = cmd->instance_count; - const GLuint baseinstance = cmd->baseinstance; const GLuint user_buffer_mask = cmd->user_buffer_mask; - const struct glthread_attrib_binding *buffers = - (const struct glthread_attrib_binding *)(cmd + 1); /* Bind uploaded buffers if needed. */ if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - false); + struct gl_buffer_object **buffers = (struct gl_buffer_object **)(cmd + 1); + const int *offsets = (const int *)(buffers + util_bitcount(user_buffer_mask)); + + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, user_buffer_mask); } - CALL_DrawArraysInstancedBaseInstance(ctx->CurrentServerDispatch, + const GLenum mode = cmd->mode; + const GLint first = cmd->first; + const GLsizei count = cmd->count; + const GLsizei instance_count = cmd->instance_count; + const GLuint baseinstance = cmd->baseinstance; + + ctx->DrawID = cmd->drawid; + CALL_DrawArraysInstancedBaseInstance(ctx->Dispatch.Current, (mode, first, count, instance_count, baseinstance)); - - /* Restore states. */ - if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - true); - } + ctx->DrawID = 0; + return cmd->num_slots; } -static ALWAYS_INLINE void -draw_arrays_async_user(struct gl_context *ctx, GLenum mode, GLint first, - GLsizei count, GLsizei instance_count, GLuint baseinstance, - unsigned user_buffer_mask, - const struct glthread_attrib_binding *buffers) +static inline unsigned +get_user_buffer_mask(struct gl_context *ctx) { - int buffers_size = util_bitcount(user_buffer_mask) * sizeof(buffers[0]); - int cmd_size = sizeof(struct marshal_cmd_DrawArraysInstancedBaseInstance) + - buffers_size; - struct marshal_cmd_DrawArraysInstancedBaseInstance *cmd; - - cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArraysInstancedBaseInstance, - cmd_size); - cmd->mode = mode; - cmd->first = first; - cmd->count = count; - cmd->instance_count = instance_count; - cmd->baseinstance = baseinstance; - cmd->user_buffer_mask = user_buffer_mask; + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; - if (user_buffer_mask) - memcpy(cmd + 1, buffers, buffers_size); + /* BufferEnabled means which attribs are enabled in terms of buffer + * binding slots (not attrib slots). + * + * UserPointerMask means which buffer bindings don't have a buffer bound. + * + * NonNullPointerMask means which buffer bindings have a NULL pointer. + * Those are not uploaded. This can happen when an attrib is enabled, but + * the shader doesn't use it, so it's ignored by mesa/state_tracker. + */ + return vao->BufferEnabled & vao->UserPointerMask & vao->NonNullPointerMask; } static ALWAYS_INLINE void -draw_arrays(GLenum mode, GLint first, GLsizei count, GLsizei instance_count, - GLuint baseinstance, bool compiled_into_dlist) +draw_arrays(GLuint drawid, GLenum mode, GLint first, GLsizei count, + GLsizei instance_count, GLuint baseinstance, + bool compiled_into_dlist, bool no_error) { GET_CURRENT_CONTEXT(ctx); - struct glthread_vao *vao = ctx->GLThread.CurrentVAO; - unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled; + /* The main benefit of no_error is that we can discard no-op draws + * immediately. + */ + if (no_error && (count <= 0 || instance_count <= 0)) + return; - if (compiled_into_dlist && ctx->GLThread.ListMode) { + if (unlikely(compiled_into_dlist && ctx->GLThread.ListMode)) { _mesa_glthread_finish_before(ctx, "DrawArrays"); /* Use the function that's compiled into a display list. */ - CALL_DrawArrays(ctx->CurrentServerDispatch, (mode, first, count)); + CALL_DrawArrays(ctx->Dispatch.Current, (mode, first, count)); return; } + unsigned user_buffer_mask = + _mesa_is_desktop_gl_core(ctx) ? 0 : get_user_buffer_mask(ctx); + /* Fast path when nothing needs to be done. * * This is also an error path. Zero counts should still call the driver * for possible GL errors. */ - if (ctx->API == API_OPENGL_CORE || !user_buffer_mask || - count <= 0 || instance_count <= 0) { - draw_arrays_async(ctx, mode, first, count, instance_count, baseinstance); + if (!user_buffer_mask || + (!no_error && + (count <= 0 || instance_count <= 0 || /* GL_INVALID_VALUE / no-op */ + ctx->GLThread.inside_begin_end || /* GL_INVALID_OPERATION */ + ctx->Dispatch.Current == ctx->Dispatch.ContextLost || /* GL_INVALID_OPERATION */ + ctx->GLThread.ListMode))) { /* GL_INVALID_OPERATION */ + if (baseinstance == 0 && drawid == 0) { + int cmd_size = sizeof(struct marshal_cmd_DrawArraysInstanced); + struct marshal_cmd_DrawArraysInstanced *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArraysInstanced, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->first = first; + cmd->count = count; + cmd->primcount = instance_count; + } else { + int cmd_size = sizeof(struct marshal_cmd_DrawArraysInstancedBaseInstanceDrawID); + struct marshal_cmd_DrawArraysInstancedBaseInstanceDrawID *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArraysInstancedBaseInstanceDrawID, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->first = first; + cmd->count = count; + cmd->instance_count = instance_count; + cmd->baseinstance = baseinstance; + cmd->drawid = drawid; + } return; } /* Upload and draw. */ - struct glthread_attrib_binding buffers[VERT_ATTRIB_MAX]; - if (!ctx->GLThread.SupportsNonVBOUploads || - !upload_vertices(ctx, user_buffer_mask, first, count, baseinstance, - instance_count, buffers)) { - _mesa_glthread_finish_before(ctx, "DrawArrays"); - CALL_DrawArraysInstancedBaseInstance(ctx->CurrentServerDispatch, - (mode, first, count, instance_count, - baseinstance)); - return; - } + struct gl_buffer_object *buffers[VERT_ATTRIB_MAX]; + int offsets[VERT_ATTRIB_MAX]; + + if (!upload_vertices(ctx, user_buffer_mask, first, count, baseinstance, + instance_count, buffers, offsets)) + return; /* the error is set by upload_vertices */ + + unsigned num_buffers = util_bitcount(user_buffer_mask); + int buffers_size = num_buffers * sizeof(buffers[0]); + int offsets_size = num_buffers * sizeof(int); + int cmd_size = sizeof(struct marshal_cmd_DrawArraysUserBuf) + + buffers_size + offsets_size; + struct marshal_cmd_DrawArraysUserBuf *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArraysUserBuf, + cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->first = first; + cmd->count = count; + cmd->instance_count = instance_count; + cmd->baseinstance = baseinstance; + cmd->drawid = drawid; + cmd->user_buffer_mask = user_buffer_mask; - draw_arrays_async_user(ctx, mode, first, count, instance_count, baseinstance, - user_buffer_mask, buffers); + if (user_buffer_mask) { + char *variable_data = (char*)(cmd + 1); + memcpy(variable_data, buffers, buffers_size); + variable_data += buffers_size; + memcpy(variable_data, offsets, offsets_size); + } } -struct marshal_cmd_MultiDrawArrays +/* MultiDrawArrays with user buffers. */ +struct marshal_cmd_MultiDrawArraysUserBuf { struct marshal_cmd_base cmd_base; - GLenum mode; + GLenum8 mode; + uint16_t num_slots; GLsizei draw_count; GLuint user_buffer_mask; }; -void -_mesa_unmarshal_MultiDrawArrays(struct gl_context *ctx, - const struct marshal_cmd_MultiDrawArrays *cmd) +uint32_t +_mesa_unmarshal_MultiDrawArraysUserBuf(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawArraysUserBuf *restrict cmd) { const GLenum mode = cmd->mode; const GLsizei draw_count = cmd->draw_count; + const GLsizei real_draw_count = MAX2(draw_count, 0); const GLuint user_buffer_mask = cmd->user_buffer_mask; const char *variable_data = (const char *)(cmd + 1); const GLint *first = (GLint *)variable_data; - variable_data += sizeof(GLint) * draw_count; + variable_data += sizeof(GLint) * real_draw_count; const GLsizei *count = (GLsizei *)variable_data; - variable_data += sizeof(GLsizei) * draw_count; - const struct glthread_attrib_binding *buffers = - (const struct glthread_attrib_binding *)variable_data; /* Bind uploaded buffers if needed. */ if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - false); - } + variable_data += sizeof(GLsizei) * real_draw_count; + const int *offsets = (const int *)variable_data; + variable_data += sizeof(int) * util_bitcount(user_buffer_mask); - CALL_MultiDrawArrays(ctx->CurrentServerDispatch, - (mode, first, count, draw_count)); + /* Align for pointers. */ + if ((uintptr_t)variable_data % sizeof(uintptr_t)) + variable_data += 4; - /* Restore states. */ - if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - true); - } -} + struct gl_buffer_object **buffers = (struct gl_buffer_object **)variable_data; -static ALWAYS_INLINE void -multi_draw_arrays_async(struct gl_context *ctx, GLenum mode, - const GLint *first, const GLsizei *count, - GLsizei draw_count, unsigned user_buffer_mask, - const struct glthread_attrib_binding *buffers) -{ - int first_size = sizeof(GLint) * draw_count; - int count_size = sizeof(GLsizei) * draw_count; - int buffers_size = util_bitcount(user_buffer_mask) * sizeof(buffers[0]); - int cmd_size = sizeof(struct marshal_cmd_MultiDrawArrays) + - first_size + count_size + buffers_size; - struct marshal_cmd_MultiDrawArrays *cmd; - - cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArrays, - cmd_size); - cmd->mode = mode; - cmd->draw_count = draw_count; - cmd->user_buffer_mask = user_buffer_mask; - - char *variable_data = (char*)(cmd + 1); - memcpy(variable_data, first, first_size); - variable_data += first_size; - memcpy(variable_data, count, count_size); - - if (user_buffer_mask) { - variable_data += count_size; - memcpy(variable_data, buffers, buffers_size); + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, user_buffer_mask); } + + CALL_MultiDrawArrays(ctx->Dispatch.Current, + (mode, first, count, draw_count)); + return cmd->num_slots; } void GLAPIENTRY @@ -489,479 +524,603 @@ _mesa_marshal_MultiDrawArrays(GLenum mode, const GLint *first, { GET_CURRENT_CONTEXT(ctx); - struct glthread_vao *vao = ctx->GLThread.CurrentVAO; - unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled; - - if (ctx->GLThread.ListMode) - goto sync; - - if (draw_count >= 0 && - (ctx->API == API_OPENGL_CORE || !user_buffer_mask)) { - multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL); + if (unlikely(ctx->GLThread.ListMode)) { + _mesa_glthread_finish_before(ctx, "MultiDrawArrays"); + CALL_MultiDrawArrays(ctx->Dispatch.Current, + (mode, first, count, draw_count)); return; } - /* If the draw count is too high or negative, the queue can't be used. */ - if (!ctx->GLThread.SupportsNonVBOUploads || - draw_count < 0 || draw_count > MARSHAL_MAX_CMD_SIZE / 16) - goto sync; + struct gl_buffer_object *buffers[VERT_ATTRIB_MAX]; + int offsets[VERT_ATTRIB_MAX]; + unsigned user_buffer_mask = + _mesa_is_desktop_gl_core(ctx) || draw_count <= 0 || + ctx->Dispatch.Current == ctx->Dispatch.ContextLost || + ctx->GLThread.inside_begin_end ? 0 : get_user_buffer_mask(ctx); - unsigned min_index = ~0; - unsigned max_index_exclusive = 0; + if (user_buffer_mask) { + unsigned min_index = ~0; + unsigned max_index_exclusive = 0; - for (unsigned i = 0; i < draw_count; i++) { - GLsizei vertex_count = count[i]; + for (int i = 0; i < draw_count; i++) { + GLsizei vertex_count = count[i]; - if (vertex_count < 0) { - /* Just call the driver to set the error. */ - multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL); - return; + if (vertex_count < 0) { + /* This will just call the driver to set the GL error. */ + min_index = ~0; + break; + } + if (vertex_count == 0) + continue; + + min_index = MIN2(min_index, first[i]); + max_index_exclusive = MAX2(max_index_exclusive, first[i] + vertex_count); } - if (vertex_count == 0) - continue; - min_index = MIN2(min_index, first[i]); - max_index_exclusive = MAX2(max_index_exclusive, first[i] + vertex_count); - } + if (min_index >= max_index_exclusive) { + /* Nothing to do, but call the driver to set possible GL errors. */ + user_buffer_mask = 0; + } else { + /* Upload. */ + unsigned num_vertices = max_index_exclusive - min_index; - unsigned num_vertices = max_index_exclusive - min_index; - if (num_vertices == 0) { - /* Nothing to do, but call the driver to set possible GL errors. */ - multi_draw_arrays_async(ctx, mode, first, count, draw_count, 0, NULL); - return; + if (!upload_vertices(ctx, user_buffer_mask, min_index, num_vertices, + 0, 1, buffers, offsets)) + return; /* the error is set by upload_vertices */ + } } - /* Upload and draw. */ - struct glthread_attrib_binding buffers[VERT_ATTRIB_MAX]; - if (!upload_vertices(ctx, user_buffer_mask, min_index, num_vertices, - 0, 1, buffers)) - goto sync; - - multi_draw_arrays_async(ctx, mode, first, count, draw_count, - user_buffer_mask, buffers); - return; - -sync: - _mesa_glthread_finish_before(ctx, "MultiDrawArrays"); - CALL_MultiDrawArrays(ctx->CurrentServerDispatch, - (mode, first, count, draw_count)); -} + /* Add the call into the batch buffer. */ + int real_draw_count = MAX2(draw_count, 0); + int first_size = sizeof(GLint) * real_draw_count; + int count_size = sizeof(GLsizei) * real_draw_count; + unsigned num_buffers = util_bitcount(user_buffer_mask); + int buffers_size = num_buffers * sizeof(buffers[0]); + int offsets_size = num_buffers * sizeof(int); + int cmd_size = sizeof(struct marshal_cmd_MultiDrawArraysUserBuf) + + first_size + count_size + buffers_size + offsets_size; + struct marshal_cmd_MultiDrawArraysUserBuf *cmd; + + /* Make sure cmd can fit in the batch buffer */ + if (cmd_size <= MARSHAL_MAX_CMD_SIZE) { + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArraysUserBuf, + cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->draw_count = draw_count; + cmd->user_buffer_mask = user_buffer_mask; + + char *variable_data = (char*)(cmd + 1); + memcpy(variable_data, first, first_size); + variable_data += first_size; + memcpy(variable_data, count, count_size); + + if (user_buffer_mask) { + variable_data += count_size; + memcpy(variable_data, offsets, offsets_size); + variable_data += offsets_size; + + /* Align for pointers. */ + if ((uintptr_t)variable_data % sizeof(uintptr_t)) + variable_data += 4; + + memcpy(variable_data, buffers, buffers_size); + } + } else { + /* The call is too large, so sync and execute the unmarshal code here. */ + _mesa_glthread_finish_before(ctx, "MultiDrawArrays"); -/* DrawElementsInstancedBaseVertexBaseInstance not supporting user buffers. - * Ignore the name. - */ -struct marshal_cmd_DrawElementsInstancedARB -{ - struct marshal_cmd_base cmd_base; - GLenum mode; - GLenum type; - GLsizei count; - GLsizei instance_count; - GLint basevertex; - GLuint baseinstance; - const GLvoid *indices; -}; + if (user_buffer_mask) { + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, + user_buffer_mask); + } -void -_mesa_unmarshal_DrawElementsInstancedARB(struct gl_context *ctx, - const struct marshal_cmd_DrawElementsInstancedARB *cmd) + CALL_MultiDrawArrays(ctx->Dispatch.Current, + (mode, first, count, draw_count)); + } +} + +uint32_t +_mesa_unmarshal_DrawElements(struct gl_context *ctx, + const struct marshal_cmd_DrawElements *restrict cmd) { - /* Ignore the function name. We use DISPATCH_CMD_DrawElementsInstanced- - * BaseVertexBaseInstance for all DrawElements variants with user buffers, - * and both DISPATCH_CMD_DrawElementsInstancedARB and DISPATCH_CMD_Draw- - * RangeElementsBaseVertex for all draw elements variants without user - * buffers. - */ const GLenum mode = cmd->mode; const GLsizei count = cmd->count; - const GLenum type = cmd->type; + const GLenum type = _mesa_decode_index_type(cmd->type); const GLvoid *indices = cmd->indices; - const GLsizei instance_count = cmd->instance_count; - const GLint basevertex = cmd->basevertex; - const GLuint baseinstance = cmd->baseinstance; - CALL_DrawElementsInstancedBaseVertexBaseInstance(ctx->CurrentServerDispatch, - (mode, count, type, indices, - instance_count, basevertex, - baseinstance)); + CALL_DrawElements(ctx->Dispatch.Current, (mode, count, type, indices)); + return align(sizeof(*cmd), 8) / 8; } -struct marshal_cmd_DrawRangeElementsBaseVertex +uint32_t +_mesa_unmarshal_DrawElementsPacked(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsPacked *restrict cmd) { - struct marshal_cmd_base cmd_base; - GLenum mode; - GLenum type; - GLsizei count; - GLint basevertex; - GLuint min_index; - GLuint max_index; - const GLvoid *indices; -}; + const GLenum mode = cmd->mode; + const GLsizei count = cmd->count; + const GLenum type = _mesa_decode_index_type(cmd->type); + const GLvoid *indices = (void*)(uintptr_t)cmd->indices; -void -_mesa_unmarshal_DrawRangeElementsBaseVertex(struct gl_context *ctx, - const struct marshal_cmd_DrawRangeElementsBaseVertex *cmd) + CALL_DrawElements(ctx->Dispatch.Current, (mode, count, type, indices)); + return align(sizeof(*cmd), 8) / 8; +} + +uint32_t +_mesa_unmarshal_DrawElementsInstancedBaseVertex(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsInstancedBaseVertex *restrict cmd) { const GLenum mode = cmd->mode; const GLsizei count = cmd->count; - const GLenum type = cmd->type; + const GLenum type = _mesa_decode_index_type(cmd->type); const GLvoid *indices = cmd->indices; + const GLsizei instance_count = cmd->primcount; const GLint basevertex = cmd->basevertex; - const GLuint min_index = cmd->min_index; - const GLuint max_index = cmd->max_index; - CALL_DrawRangeElementsBaseVertex(ctx->CurrentServerDispatch, - (mode, min_index, max_index, count, - type, indices, basevertex)); + CALL_DrawElementsInstancedBaseVertex(ctx->Dispatch.Current, + (mode, count, type, indices, + instance_count, basevertex)); + return align(sizeof(*cmd), 8) / 8; } -static ALWAYS_INLINE void -draw_elements_async(struct gl_context *ctx, GLenum mode, GLsizei count, - GLenum type, const GLvoid *indices, GLsizei instance_count, - GLint basevertex, GLuint baseinstance, - bool index_bounds_valid, GLuint min_index, GLuint max_index) +uint32_t +_mesa_unmarshal_DrawElementsInstancedBaseInstance(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsInstancedBaseInstance *restrict cmd) { - if (index_bounds_valid) { - int cmd_size = sizeof(struct marshal_cmd_DrawRangeElementsBaseVertex); - struct marshal_cmd_DrawRangeElementsBaseVertex *cmd = - _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawRangeElementsBaseVertex, cmd_size); - - cmd->mode = mode; - cmd->count = count; - cmd->type = type; - cmd->indices = indices; - cmd->basevertex = basevertex; - cmd->min_index = min_index; - cmd->max_index = max_index; - } else { - int cmd_size = sizeof(struct marshal_cmd_DrawElementsInstancedARB); - struct marshal_cmd_DrawElementsInstancedARB *cmd = - _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsInstancedARB, cmd_size); + const GLenum mode = cmd->mode; + const GLsizei count = cmd->count; + const GLenum type = _mesa_decode_index_type(cmd->type); + const GLvoid *indices = cmd->indices; + const GLsizei instance_count = cmd->primcount; + const GLint baseinstance = cmd->baseinstance; - cmd->mode = mode; - cmd->count = count; - cmd->type = type; - cmd->indices = indices; - cmd->instance_count = instance_count; - cmd->basevertex = basevertex; - cmd->baseinstance = baseinstance; - } + CALL_DrawElementsInstancedBaseInstance(ctx->Dispatch.Current, + (mode, count, type, indices, + instance_count, baseinstance)); + return align(sizeof(*cmd), 8) / 8; } -struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstance +uint32_t +_mesa_unmarshal_DrawElementsInstancedBaseVertexBaseInstanceDrawID(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstanceDrawID *restrict cmd) { - struct marshal_cmd_base cmd_base; - bool index_bounds_valid; - GLenum mode; - GLenum type; - GLsizei count; - GLsizei instance_count; - GLint basevertex; - GLuint baseinstance; - GLuint min_index; - GLuint max_index; - GLuint user_buffer_mask; - const GLvoid *indices; - struct gl_buffer_object *index_buffer; -}; - -void -_mesa_unmarshal_DrawElementsInstancedBaseVertexBaseInstance(struct gl_context *ctx, - const struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstance *cmd) -{ - /* Ignore the function name. We use DISPATCH_CMD_DrawElementsInstanced- - * BaseVertexBaseInstance for all DrawElements variants with user buffers, - * and both DISPATCH_CMD_DrawElementsInstancedARB and DISPATCH_CMD_Draw- - * RangeElementsBaseVertex for all draw elements variants without user - * buffers. - */ const GLenum mode = cmd->mode; const GLsizei count = cmd->count; - const GLenum type = cmd->type; + const GLenum type = _mesa_decode_index_type(cmd->type); const GLvoid *indices = cmd->indices; const GLsizei instance_count = cmd->instance_count; const GLint basevertex = cmd->basevertex; const GLuint baseinstance = cmd->baseinstance; - const GLuint min_index = cmd->min_index; - const GLuint max_index = cmd->max_index; + + ctx->DrawID = cmd->drawid; + CALL_DrawElementsInstancedBaseVertexBaseInstance(ctx->Dispatch.Current, + (mode, count, type, indices, + instance_count, basevertex, + baseinstance)); + ctx->DrawID = 0; + + return align(sizeof(*cmd), 8) / 8; +} + +uint32_t +_mesa_unmarshal_DrawElementsUserBuf(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsUserBuf *restrict cmd) +{ const GLuint user_buffer_mask = cmd->user_buffer_mask; - struct gl_buffer_object *index_buffer = cmd->index_buffer; - const struct glthread_attrib_binding *buffers = - (const struct glthread_attrib_binding *)(cmd + 1); /* Bind uploaded buffers if needed. */ if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - false); - } - if (index_buffer) { - _mesa_InternalBindElementBuffer(ctx, index_buffer); + struct gl_buffer_object **buffers = (struct gl_buffer_object **)(cmd + 1); + const int *offsets = (const int *)(buffers + util_bitcount(user_buffer_mask)); + + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, user_buffer_mask); } /* Draw. */ - if (cmd->index_bounds_valid && instance_count == 1 && baseinstance == 0) { - CALL_DrawRangeElementsBaseVertex(ctx->CurrentServerDispatch, - (mode, min_index, max_index, count, - type, indices, basevertex)); - } else { - CALL_DrawElementsInstancedBaseVertexBaseInstance(ctx->CurrentServerDispatch, - (mode, count, type, indices, - instance_count, basevertex, - baseinstance)); - } + CALL_DrawElementsUserBuf(ctx->Dispatch.Current, (cmd)); - /* Restore states. */ - if (index_buffer) { - _mesa_InternalBindElementBuffer(ctx, NULL); - } + struct gl_buffer_object *index_buffer = cmd->index_buffer; + _mesa_reference_buffer_object(ctx, &index_buffer, NULL); + return cmd->num_slots; +} + +uint32_t +_mesa_unmarshal_DrawElementsUserBufPacked(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsUserBufPacked *restrict cmd) +{ + const GLuint user_buffer_mask = cmd->user_buffer_mask; + + /* Bind uploaded buffers if needed. */ if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - true); + struct gl_buffer_object **buffers = (struct gl_buffer_object **)(cmd + 1); + const int *offsets = (const int *)(buffers + util_bitcount(user_buffer_mask)); + + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, user_buffer_mask); } -} -static ALWAYS_INLINE void -draw_elements_async_user(struct gl_context *ctx, GLenum mode, GLsizei count, - GLenum type, const GLvoid *indices, GLsizei instance_count, - GLint basevertex, GLuint baseinstance, - bool index_bounds_valid, GLuint min_index, GLuint max_index, - struct gl_buffer_object *index_buffer, - unsigned user_buffer_mask, - const struct glthread_attrib_binding *buffers) -{ - int buffers_size = util_bitcount(user_buffer_mask) * sizeof(buffers[0]); - int cmd_size = sizeof(struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstance) + - buffers_size; - struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstance *cmd; - - cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsInstancedBaseVertexBaseInstance, cmd_size); - cmd->mode = mode; - cmd->count = count; - cmd->type = type; - cmd->indices = indices; - cmd->instance_count = instance_count; - cmd->basevertex = basevertex; - cmd->baseinstance = baseinstance; - cmd->min_index = min_index; - cmd->max_index = max_index; - cmd->user_buffer_mask = user_buffer_mask; - cmd->index_bounds_valid = index_bounds_valid; - cmd->index_buffer = index_buffer; + /* Draw. */ + CALL_DrawElementsUserBufPacked(ctx->Dispatch.Current, (cmd)); - if (user_buffer_mask) - memcpy(cmd + 1, buffers, buffers_size); + struct gl_buffer_object *index_buffer = cmd->index_buffer; + _mesa_reference_buffer_object(ctx, &index_buffer, NULL); + return cmd->num_slots; } -static void -draw_elements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, - GLsizei instance_count, GLint basevertex, GLuint baseinstance, - bool index_bounds_valid, GLuint min_index, GLuint max_index, - bool compiled_into_dlist) +static inline bool +should_convert_to_begin_end(struct gl_context *ctx, unsigned count, + unsigned num_upload_vertices, + unsigned instance_count, struct glthread_vao *vao) +{ + /* Some of these are limitations of _mesa_glthread_UnrollDrawElements. + * Others prevent syncing, such as disallowing buffer objects because we + * can't map them without syncing. + */ + return ctx->API == API_OPENGL_COMPAT && + util_is_vbo_upload_ratio_too_large(count, num_upload_vertices) && + instance_count == 1 && /* no instancing */ + vao->CurrentElementBufferName == 0 && /* only user indices */ + !ctx->GLThread._PrimitiveRestart && /* no primitive restart */ + vao->UserPointerMask == vao->BufferEnabled && /* no VBOs */ + !(vao->NonZeroDivisorMask & vao->BufferEnabled); /* no instanced attribs */ +} + +static ALWAYS_INLINE void +draw_elements(GLuint drawid, GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instance_count, GLint basevertex, + GLuint baseinstance, bool index_bounds_valid, GLuint min_index, + GLuint max_index, bool compiled_into_dlist, bool no_error) { GET_CURRENT_CONTEXT(ctx); - struct glthread_vao *vao = ctx->GLThread.CurrentVAO; - unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled; - bool has_user_indices = vao->CurrentElementBufferName == 0; + /* The main benefit of no_error is that we can discard no-op draws + * immediately. These are plentiful in Viewperf2020/Catia1. + */ + if (no_error && (count <= 0 || instance_count <= 0)) + return; - if (compiled_into_dlist && ctx->GLThread.ListMode) - goto sync; + if (unlikely(compiled_into_dlist && ctx->GLThread.ListMode)) { + _mesa_glthread_finish_before(ctx, "DrawElements"); + + /* Only use the ones that are compiled into display lists. */ + if (basevertex) { + CALL_DrawElementsBaseVertex(ctx->Dispatch.Current, + (mode, count, type, indices, basevertex)); + } else if (index_bounds_valid) { + CALL_DrawRangeElements(ctx->Dispatch.Current, + (mode, min_index, max_index, count, type, indices)); + } else { + CALL_DrawElements(ctx->Dispatch.Current, (mode, count, type, indices)); + } + return; + } + + if (unlikely(!no_error && index_bounds_valid && max_index < min_index)) { + _mesa_marshal_InternalSetError(GL_INVALID_VALUE); + return; + } + + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_desktop_gl_core(ctx) ? 0 : get_user_buffer_mask(ctx); + bool has_user_indices = vao->CurrentElementBufferName == 0 && indices; /* Fast path when nothing needs to be done. * * This is also an error path. Zero counts should still call the driver * for possible GL errors. */ - if (ctx->API == API_OPENGL_CORE || - count <= 0 || instance_count <= 0 || max_index < min_index || - !is_index_type_valid(type) || - (!user_buffer_mask && !has_user_indices)) { - draw_elements_async(ctx, mode, count, type, indices, instance_count, - basevertex, baseinstance, index_bounds_valid, - min_index, max_index); + if ((!user_buffer_mask && !has_user_indices) || + (!no_error && + /* zeros are discarded for no_error at the beginning */ + (count <= 0 || instance_count <= 0 || /* GL_INVALID_VALUE / no-op */ + !_mesa_is_index_type_valid(type) || /* GL_INVALID_VALUE */ + ctx->Dispatch.Current == ctx->Dispatch.ContextLost || /* GL_INVALID_OPERATION */ + ctx->GLThread.inside_begin_end || /* GL_INVALID_OPERATION */ + ctx->GLThread.ListMode))) { /* GL_INVALID_OPERATION */ + if (drawid == 0 && baseinstance == 0) { + if (instance_count == 1 && basevertex == 0) { + if ((count & 0xffff) == count && (uintptr_t)indices <= UINT16_MAX) { + /* Packed version of DrawElements: 16-bit count and 16-bit index offset, + * reducing the call size by 8 bytes. + * This is the most common case in Viewperf2020/Catia1. + */ + int cmd_size = sizeof(struct marshal_cmd_DrawElementsPacked); + struct marshal_cmd_DrawElementsPacked *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsPacked, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; + cmd->indices = (uintptr_t)indices; + } else { + int cmd_size = sizeof(struct marshal_cmd_DrawElements); + struct marshal_cmd_DrawElements *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElements, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; + cmd->indices = indices; + } + } else { + int cmd_size = sizeof(struct marshal_cmd_DrawElementsInstancedBaseVertex); + struct marshal_cmd_DrawElementsInstancedBaseVertex *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsInstancedBaseVertex, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; + cmd->primcount = instance_count; + cmd->basevertex = basevertex; + cmd->indices = indices; + } + } else if (drawid == 0 && basevertex == 0) { + int cmd_size = sizeof(struct marshal_cmd_DrawElementsInstancedBaseInstance); + struct marshal_cmd_DrawElementsInstancedBaseInstance *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsInstancedBaseInstance, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; + cmd->primcount = instance_count; + cmd->baseinstance = baseinstance; + cmd->indices = indices; + } else { + int cmd_size = sizeof(struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstanceDrawID); + struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstanceDrawID *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsInstancedBaseVertexBaseInstanceDrawID, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; + cmd->instance_count = instance_count; + cmd->basevertex = basevertex; + cmd->baseinstance = baseinstance; + cmd->drawid = drawid; + cmd->indices = indices; + } return; } - if (!ctx->GLThread.SupportsNonVBOUploads) - goto sync; - bool need_index_bounds = user_buffer_mask & ~vao->NonZeroDivisorMask; unsigned index_size = get_index_size(type); if (need_index_bounds && !index_bounds_valid) { - /* Sync if indices come from a buffer and vertices come from memory - * and index bounds are not valid. - * - * We would have to map the indices to compute the index bounds, and - * for that we would have to sync anyway. - */ - if (!has_user_indices) - goto sync; - /* Compute the index bounds. */ - min_index = ~0; - max_index = 0; - vbo_get_minmax_index_mapped(count, index_size, - ctx->GLThread._RestartIndex[index_size - 1], - ctx->GLThread._PrimitiveRestart, indices, - &min_index, &max_index); + if (has_user_indices) { + min_index = ~0; + max_index = 0; + vbo_get_minmax_index_mapped(count, index_size, + ctx->GLThread._RestartIndex[index_size - 1], + ctx->GLThread._PrimitiveRestart, indices, + &min_index, &max_index); + } else { + /* Indices in a buffer. */ + _mesa_glthread_finish_before(ctx, "DrawElements - need index bounds"); + vbo_get_minmax_index(ctx, ctx->Array.VAO->IndexBufferObj, + NULL, (intptr_t)indices, count, index_size, + ctx->GLThread._PrimitiveRestart, + ctx->GLThread._RestartIndex[index_size - 1], + &min_index, &max_index); + } index_bounds_valid = true; } unsigned start_vertex = min_index + basevertex; unsigned num_vertices = max_index + 1 - min_index; - /* If there is too much data to upload, sync and let the driver unroll - * indices. */ - if (util_is_vbo_upload_ratio_too_large(count, num_vertices)) - goto sync; + /* If the vertex range to upload is much greater than the vertex count (e.g. + * only 3 vertices with indices 0, 1, 999999), uploading the whole range + * would take too much time. If all buffers are user buffers, have glthread + * fetch all indices and vertices and convert the draw into glBegin/glEnd. + * For such pathological cases, it's the fastest way. + * + * The game Cogs benefits from this - its FPS increases from 0 to 197. + */ + if (should_convert_to_begin_end(ctx, count, num_vertices, instance_count, + vao)) { + _mesa_glthread_UnrollDrawElements(ctx, mode, count, type, indices, + basevertex); + return; + } - struct glthread_attrib_binding buffers[VERT_ATTRIB_MAX]; - if (user_buffer_mask && - !upload_vertices(ctx, user_buffer_mask, start_vertex, num_vertices, - baseinstance, instance_count, buffers)) - goto sync; + struct gl_buffer_object *buffers[VERT_ATTRIB_MAX]; + int offsets[VERT_ATTRIB_MAX]; + + if (user_buffer_mask) { + if (!upload_vertices(ctx, user_buffer_mask, start_vertex, num_vertices, + baseinstance, instance_count, buffers, offsets)) + return; /* the error is set by upload_vertices */ + } /* Upload indices. */ struct gl_buffer_object *index_buffer = NULL; - if (has_user_indices) + if (has_user_indices) { index_buffer = upload_indices(ctx, count, index_size, &indices); + if (!index_buffer) + return; /* the error is set by upload_indices */ + } /* Draw asynchronously. */ - draw_elements_async_user(ctx, mode, count, type, indices, instance_count, - basevertex, baseinstance, index_bounds_valid, - min_index, max_index, index_buffer, - user_buffer_mask, buffers); - return; - -sync: - _mesa_glthread_finish_before(ctx, "DrawElements"); - - if (compiled_into_dlist && ctx->GLThread.ListMode) { - /* Only use the ones that are compiled into display lists. */ - if (basevertex) { - CALL_DrawElementsBaseVertex(ctx->CurrentServerDispatch, - (mode, count, type, indices, basevertex)); - } else if (index_bounds_valid) { - CALL_DrawRangeElements(ctx->CurrentServerDispatch, - (mode, min_index, max_index, count, type, indices)); - } else { - CALL_DrawElements(ctx->CurrentServerDispatch, (mode, count, type, indices)); - } - } else if (index_bounds_valid && instance_count == 1 && baseinstance == 0) { - CALL_DrawRangeElementsBaseVertex(ctx->CurrentServerDispatch, - (mode, min_index, max_index, count, - type, indices, basevertex)); + unsigned num_buffers = util_bitcount(user_buffer_mask); + int buffers_size = num_buffers * sizeof(buffers[0]); + int offsets_size = num_buffers * sizeof(int); + char *variable_data; + + if (instance_count == 1 && basevertex == 0 && baseinstance == 0 && + drawid == 0 && (count & 0xffff) == count && + (uintptr_t)indices <= UINT32_MAX) { + int cmd_size = sizeof(struct marshal_cmd_DrawElementsUserBufPacked) + + buffers_size + offsets_size; + struct marshal_cmd_DrawElementsUserBufPacked *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsUserBufPacked, cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; /* truncated */ + cmd->indices = (uintptr_t)indices; /* truncated */ + cmd->user_buffer_mask = user_buffer_mask; + cmd->index_buffer = index_buffer; + variable_data = (char*)(cmd + 1); } else { - CALL_DrawElementsInstancedBaseVertexBaseInstance(ctx->CurrentServerDispatch, - (mode, count, type, indices, - instance_count, basevertex, - baseinstance)); + int cmd_size = sizeof(struct marshal_cmd_DrawElementsUserBuf) + + buffers_size + offsets_size; + struct marshal_cmd_DrawElementsUserBuf *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsUserBuf, cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->count = count; + cmd->indices = indices; + cmd->instance_count = instance_count; + cmd->basevertex = basevertex; + cmd->baseinstance = baseinstance; + cmd->user_buffer_mask = user_buffer_mask; + cmd->index_buffer = index_buffer; + cmd->drawid = drawid; + variable_data = (char*)(cmd + 1); + } + + if (user_buffer_mask) { + memcpy(variable_data, buffers, buffers_size); + variable_data += buffers_size; + memcpy(variable_data, offsets, offsets_size); } } -struct marshal_cmd_MultiDrawElementsBaseVertex +struct marshal_cmd_MultiDrawElementsUserBuf { struct marshal_cmd_base cmd_base; bool has_base_vertex; - GLenum mode; - GLenum type; + GLenum8 mode; + GLindextype type; + uint16_t num_slots; GLsizei draw_count; GLuint user_buffer_mask; struct gl_buffer_object *index_buffer; }; -void -_mesa_unmarshal_MultiDrawElementsBaseVertex(struct gl_context *ctx, - const struct marshal_cmd_MultiDrawElementsBaseVertex *cmd) +uint32_t +_mesa_unmarshal_MultiDrawElementsUserBuf(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawElementsUserBuf *restrict cmd) { - const GLenum mode = cmd->mode; - const GLenum type = cmd->type; const GLsizei draw_count = cmd->draw_count; + const GLsizei real_draw_count = MAX2(draw_count, 0); const GLuint user_buffer_mask = cmd->user_buffer_mask; - struct gl_buffer_object *index_buffer = cmd->index_buffer; const bool has_base_vertex = cmd->has_base_vertex; const char *variable_data = (const char *)(cmd + 1); const GLsizei *count = (GLsizei *)variable_data; - variable_data += sizeof(GLsizei) * draw_count; - const GLvoid *const *indices = (const GLvoid *const *)variable_data; - variable_data += sizeof(const GLvoid *const *) * draw_count; + variable_data += sizeof(GLsizei) * real_draw_count; const GLsizei *basevertex = NULL; if (has_base_vertex) { basevertex = (GLsizei *)variable_data; - variable_data += sizeof(GLsizei) * draw_count; + variable_data += sizeof(GLsizei) * real_draw_count; + } + const int *offsets = NULL; + if (user_buffer_mask) { + offsets = (const int *)variable_data; + variable_data += sizeof(int) * util_bitcount(user_buffer_mask); } - const struct glthread_attrib_binding *buffers = - (const struct glthread_attrib_binding *)variable_data; + + /* Align for pointers. */ + if ((uintptr_t)variable_data % sizeof(uintptr_t)) + variable_data += 4; + + const GLvoid *const *indices = (const GLvoid *const *)variable_data; + variable_data += sizeof(const GLvoid *const *) * real_draw_count; /* Bind uploaded buffers if needed. */ if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - false); - } - if (index_buffer) { - _mesa_InternalBindElementBuffer(ctx, index_buffer); + struct gl_buffer_object **buffers = (struct gl_buffer_object **)variable_data; + + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, user_buffer_mask); } /* Draw. */ - if (has_base_vertex) { - CALL_MultiDrawElementsBaseVertex(ctx->CurrentServerDispatch, - (mode, count, type, indices, draw_count, - basevertex)); - } else { - CALL_MultiDrawElementsEXT(ctx->CurrentServerDispatch, - (mode, count, type, indices, draw_count)); - } + const GLenum mode = cmd->mode; + const GLenum type = _mesa_decode_index_type(cmd->type); + struct gl_buffer_object *index_buffer = cmd->index_buffer; - /* Restore states. */ - if (index_buffer) { - _mesa_InternalBindElementBuffer(ctx, NULL); - } - if (user_buffer_mask) { - _mesa_InternalBindVertexBuffers(ctx, buffers, user_buffer_mask, - true); - } + CALL_MultiDrawElementsUserBuf(ctx->Dispatch.Current, + ((GLintptr)index_buffer, mode, count, type, + indices, draw_count, basevertex)); + _mesa_reference_buffer_object(ctx, &index_buffer, NULL); + return cmd->num_slots; } -static ALWAYS_INLINE void +static void multi_draw_elements_async(struct gl_context *ctx, GLenum mode, const GLsizei *count, GLenum type, const GLvoid *const *indices, GLsizei draw_count, const GLsizei *basevertex, struct gl_buffer_object *index_buffer, unsigned user_buffer_mask, - const struct glthread_attrib_binding *buffers) -{ - int count_size = sizeof(GLsizei) * draw_count; - int indices_size = sizeof(indices[0]) * draw_count; - int basevertex_size = basevertex ? sizeof(GLsizei) * draw_count : 0; - int buffers_size = util_bitcount(user_buffer_mask) * sizeof(buffers[0]); - int cmd_size = sizeof(struct marshal_cmd_MultiDrawElementsBaseVertex) + - count_size + indices_size + basevertex_size + buffers_size; - struct marshal_cmd_MultiDrawElementsBaseVertex *cmd; - - cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsBaseVertex, cmd_size); - cmd->mode = mode; - cmd->type = type; - cmd->draw_count = draw_count; - cmd->user_buffer_mask = user_buffer_mask; - cmd->index_buffer = index_buffer; - cmd->has_base_vertex = basevertex != NULL; - - char *variable_data = (char*)(cmd + 1); - memcpy(variable_data, count, count_size); - variable_data += count_size; - memcpy(variable_data, indices, indices_size); - variable_data += indices_size; - - if (basevertex) { - memcpy(variable_data, basevertex, basevertex_size); - variable_data += basevertex_size; - } + struct gl_buffer_object **buffers, + const int *offsets) +{ + int real_draw_count = MAX2(draw_count, 0); + int count_size = sizeof(GLsizei) * real_draw_count; + int indices_size = sizeof(indices[0]) * real_draw_count; + int basevertex_size = basevertex ? sizeof(GLsizei) * real_draw_count : 0; + unsigned num_buffers = util_bitcount(user_buffer_mask); + int buffers_size = num_buffers * sizeof(buffers[0]); + int offsets_size = num_buffers * sizeof(int); + int cmd_size = sizeof(struct marshal_cmd_MultiDrawElementsUserBuf) + + count_size + indices_size + basevertex_size + buffers_size + + offsets_size; + struct marshal_cmd_MultiDrawElementsUserBuf *cmd; + + /* Make sure cmd can fit the queue buffer */ + if (cmd_size <= MARSHAL_MAX_CMD_SIZE) { + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsUserBuf, cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->mode = MIN2(mode, 0xff); /* primitive types go from 0 to 14 */ + cmd->type = encode_index_type(type); + cmd->draw_count = draw_count; + cmd->user_buffer_mask = user_buffer_mask; + cmd->index_buffer = index_buffer; + cmd->has_base_vertex = basevertex != NULL; + + char *variable_data = (char*)(cmd + 1); + memcpy(variable_data, count, count_size); + variable_data += count_size; + if (basevertex) { + memcpy(variable_data, basevertex, basevertex_size); + variable_data += basevertex_size; + } + if (user_buffer_mask) { + memcpy(variable_data, offsets, offsets_size); + variable_data += offsets_size; + } - if (user_buffer_mask) - memcpy(variable_data, buffers, buffers_size); + /* Align for pointers. */ + if ((uintptr_t)variable_data % sizeof(uintptr_t)) + variable_data += 4; + + memcpy(variable_data, indices, indices_size); + variable_data += indices_size; + + if (user_buffer_mask) + memcpy(variable_data, buffers, buffers_size); + } else { + /* The call is too large, so sync and execute the unmarshal code here. */ + _mesa_glthread_finish_before(ctx, "DrawElements"); + + /* Bind uploaded buffers if needed. */ + if (user_buffer_mask) { + _mesa_InternalBindVertexBuffers(ctx, buffers, offsets, + user_buffer_mask); + } + + /* Draw. */ + CALL_MultiDrawElementsUserBuf(ctx->Dispatch.Current, + ((GLintptr)index_buffer, mode, count, + type, indices, draw_count, basevertex)); + _mesa_reference_buffer_object(ctx, &index_buffer, NULL); + } } void GLAPIENTRY @@ -973,36 +1132,43 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, { GET_CURRENT_CONTEXT(ctx); - struct glthread_vao *vao = ctx->GLThread.CurrentVAO; - unsigned user_buffer_mask = vao->UserPointerMask & vao->BufferEnabled; - bool has_user_indices = vao->CurrentElementBufferName == 0; - - if (ctx->GLThread.ListMode) - goto sync; - - /* Fast path when nothing needs to be done. */ - if (draw_count >= 0 && - (ctx->API == API_OPENGL_CORE || - !is_index_type_valid(type) || - (!user_buffer_mask && !has_user_indices))) { - multi_draw_elements_async(ctx, mode, count, type, indices, draw_count, - basevertex, 0, 0, NULL); + if (unlikely(ctx->GLThread.ListMode)) { + _mesa_glthread_finish_before(ctx, "MultiDrawElements"); + + if (basevertex) { + CALL_MultiDrawElementsBaseVertex(ctx->Dispatch.Current, + (mode, count, type, indices, draw_count, + basevertex)); + } else { + CALL_MultiDrawElements(ctx->Dispatch.Current, + (mode, count, type, indices, draw_count)); + } return; } - bool need_index_bounds = user_buffer_mask & ~vao->NonZeroDivisorMask; + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = 0; + bool has_user_indices = false; - /* If the draw count is too high or negative, the queue can't be used. - * - * Sync if indices come from a buffer and vertices come from memory - * and index bounds are not valid. We would have to map the indices - * to compute the index bounds, and for that we would have to sync anyway. + /* Non-VBO vertex arrays are used only if this is true. + * When nothing needs to be uploaded or the draw is no-op or generates + * a GL error, we don't upload anything. */ - if (!ctx->GLThread.SupportsNonVBOUploads || - draw_count < 0 || draw_count > MARSHAL_MAX_CMD_SIZE / 32 || - (need_index_bounds && !has_user_indices)) - goto sync; + if (draw_count > 0 && _mesa_is_index_type_valid(type) && + ctx->Dispatch.Current != ctx->Dispatch.ContextLost && + !ctx->GLThread.inside_begin_end) { + user_buffer_mask = _mesa_is_desktop_gl_core(ctx) ? 0 : get_user_buffer_mask(ctx); + has_user_indices = vao->CurrentElementBufferName == 0; + } + /* Fast path when we don't need to upload anything. */ + if (!user_buffer_mask && !has_user_indices) { + multi_draw_elements_async(ctx, mode, count, type, indices, + draw_count, basevertex, NULL, 0, NULL, NULL); + return; + } + + bool need_index_bounds = user_buffer_mask & ~vao->NonZeroDivisorMask; unsigned index_size = get_index_size(type); unsigned min_index = ~0; unsigned max_index = 0; @@ -1013,6 +1179,8 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, * uploaded. */ if (need_index_bounds) { + bool synced = false; + /* Compute the index bounds. */ for (unsigned i = 0; i < draw_count; i++) { GLsizei vertex_count = count[i]; @@ -1020,17 +1188,30 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, if (vertex_count < 0) { /* Just call the driver to set the error. */ multi_draw_elements_async(ctx, mode, count, type, indices, draw_count, - basevertex, 0, 0, NULL); + basevertex, NULL, 0, NULL, NULL); return; } if (vertex_count == 0) continue; unsigned min = ~0, max = 0; - vbo_get_minmax_index_mapped(vertex_count, index_size, - ctx->GLThread._RestartIndex[index_size - 1], - ctx->GLThread._PrimitiveRestart, indices[i], - &min, &max); + if (has_user_indices) { + vbo_get_minmax_index_mapped(vertex_count, index_size, + ctx->GLThread._RestartIndex[index_size - 1], + ctx->GLThread._PrimitiveRestart, indices[i], + &min, &max); + } else { + if (!synced) { + _mesa_glthread_finish_before(ctx, "MultiDrawElements - need index bounds"); + synced = true; + } + vbo_get_minmax_index(ctx, ctx->Array.VAO->IndexBufferObj, + NULL, (intptr_t)indices[i], vertex_count, + index_size, ctx->GLThread._PrimitiveRestart, + ctx->GLThread._RestartIndex[index_size - 1], + &min, &max); + } + if (basevertex) { min += basevertex[i]; max += basevertex[i]; @@ -1045,14 +1226,9 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, if (total_count == 0 || num_vertices == 0) { /* Nothing to do, but call the driver to set possible GL errors. */ multi_draw_elements_async(ctx, mode, count, type, indices, draw_count, - basevertex, 0, 0, NULL); + basevertex, NULL, 0, NULL, NULL); return; } - - /* If there is too much data to upload, sync and let the driver unroll - * indices. */ - if (util_is_vbo_upload_ratio_too_large(total_count, num_vertices)) - goto sync; } else if (has_user_indices) { /* Only compute total_count for the upload of indices. */ for (unsigned i = 0; i < draw_count; i++) { @@ -1061,7 +1237,7 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, if (vertex_count < 0) { /* Just call the driver to set the error. */ multi_draw_elements_async(ctx, mode, count, type, indices, draw_count, - basevertex, 0, 0, NULL); + basevertex, NULL, 0, NULL, NULL); return; } if (vertex_count == 0) @@ -1073,17 +1249,20 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, if (total_count == 0) { /* Nothing to do, but call the driver to set possible GL errors. */ multi_draw_elements_async(ctx, mode, count, type, indices, draw_count, - basevertex, 0, 0, NULL); + basevertex, NULL, 0, NULL, NULL); return; } } /* Upload vertices. */ - struct glthread_attrib_binding buffers[VERT_ATTRIB_MAX]; - if (user_buffer_mask && - !upload_vertices(ctx, user_buffer_mask, min_index, num_vertices, - 0, 1, buffers)) - goto sync; + struct gl_buffer_object *buffers[VERT_ATTRIB_MAX]; + int offsets[VERT_ATTRIB_MAX]; + + if (user_buffer_mask) { + if (!upload_vertices(ctx, user_buffer_mask, min_index, num_vertices, + 0, 1, buffers, offsets)) + return; /* the error is set by upload_vertices */ + } /* Upload indices. */ struct gl_buffer_object *index_buffer = NULL; @@ -1093,39 +1272,426 @@ _mesa_marshal_MultiDrawElementsBaseVertex(GLenum mode, const GLsizei *count, index_buffer = upload_multi_indices(ctx, total_count, index_size, draw_count, count, indices, out_indices); + if (!index_buffer) + return; /* the error is set by upload_multi_indices */ + indices = out_indices; } /* Draw asynchronously. */ multi_draw_elements_async(ctx, mode, count, type, indices, draw_count, basevertex, index_buffer, user_buffer_mask, - buffers); - return; + buffers, offsets); +} + +void GLAPIENTRY +_mesa_marshal_MultiModeDrawArraysIBM(const GLenum *mode, const GLint *first, + const GLsizei *count, GLsizei primcount, + GLint modestride) +{ + for (int i = 0 ; i < primcount; i++) { + if (count[i] > 0) { + GLenum m = *((GLenum *)((GLubyte *)mode + i * modestride)); + _mesa_marshal_DrawArrays(m, first[i], count[i]); + } + } +} + +void GLAPIENTRY +_mesa_marshal_MultiModeDrawElementsIBM(const GLenum *mode, + const GLsizei *count, GLenum type, + const GLvoid * const *indices, + GLsizei primcount, GLint modestride) +{ + for (int i = 0 ; i < primcount; i++) { + if (count[i] > 0) { + GLenum m = *((GLenum *)((GLubyte *)mode + i * modestride)); + _mesa_marshal_DrawElements(m, count[i], type, indices[i]); + } + } +} -sync: - _mesa_glthread_finish_before(ctx, "DrawElements"); +static const void * +map_draw_indirect_params(struct gl_context *ctx, GLintptr offset, + unsigned count, unsigned stride) +{ + struct gl_buffer_object *obj = ctx->DrawIndirectBuffer; - if (basevertex) { - CALL_MultiDrawElementsBaseVertex(ctx->CurrentServerDispatch, - (mode, count, type, indices, draw_count, - basevertex)); - } else { - CALL_MultiDrawElementsEXT(ctx->CurrentServerDispatch, - (mode, count, type, indices, draw_count)); + if (!obj) + return (void*)offset; + + return _mesa_bufferobj_map_range(ctx, offset, + MIN2((size_t)count * stride, obj->Size), + GL_MAP_READ_BIT, obj, MAP_INTERNAL); +} + +static void +unmap_draw_indirect_params(struct gl_context *ctx) +{ + if (ctx->DrawIndirectBuffer) + _mesa_bufferobj_unmap(ctx, ctx->DrawIndirectBuffer, MAP_INTERNAL); +} + +static unsigned +read_draw_indirect_count(struct gl_context *ctx, GLintptr offset) +{ + unsigned result = 0; + + if (ctx->ParameterBuffer) { + _mesa_bufferobj_get_subdata(ctx, offset, sizeof(result), &result, + ctx->ParameterBuffer); + } + return result; +} + +static void +lower_draw_arrays_indirect(struct gl_context *ctx, GLenum mode, + GLintptr indirect, GLsizei stride, + unsigned draw_count) +{ + /* If <stride> is zero, the elements are tightly packed. */ + if (stride == 0) + stride = 4 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ + + const uint32_t *params = + map_draw_indirect_params(ctx, indirect, draw_count, stride); + + for (unsigned i = 0; i < draw_count; i++) { + draw_arrays(i, mode, + params[i * stride / 4 + 2], + params[i * stride / 4 + 0], + params[i * stride / 4 + 1], + params[i * stride / 4 + 3], false, false); + } + + unmap_draw_indirect_params(ctx); +} + +static void +lower_draw_elements_indirect(struct gl_context *ctx, GLenum mode, GLenum type, + GLintptr indirect, GLsizei stride, + unsigned draw_count) +{ + /* If <stride> is zero, the elements are tightly packed. */ + if (stride == 0) + stride = 5 * sizeof(GLuint); /* sizeof(DrawArraysIndirectCommand) */ + + const uint32_t *params = + map_draw_indirect_params(ctx, indirect, draw_count, stride); + + for (unsigned i = 0; i < draw_count; i++) { + draw_elements(i, mode, + params[i * stride / 4 + 0], + type, + (GLvoid*)((uintptr_t)params[i * stride / 4 + 2] * + get_index_size(type)), + params[i * stride / 4 + 1], + params[i * stride / 4 + 3], + params[i * stride / 4 + 4], + false, 0, 0, false, false); + } + unmap_draw_indirect_params(ctx); +} + +static inline bool +draw_indirect_async_allowed(struct gl_context *ctx, unsigned user_buffer_mask) +{ + return ctx->API != API_OPENGL_COMPAT || + /* This will just generate GL_INVALID_OPERATION, as it should. */ + ctx->GLThread.inside_begin_end || + ctx->GLThread.ListMode || + ctx->Dispatch.Current == ctx->Dispatch.ContextLost || + /* If the DrawIndirect buffer is bound, it behaves like profile != compat + * if there are no user VBOs. */ + (ctx->GLThread.CurrentDrawIndirectBufferName && !user_buffer_mask); +} + +uint32_t +_mesa_unmarshal_DrawArraysIndirect(struct gl_context *ctx, + const struct marshal_cmd_DrawArraysIndirect *cmd) +{ + GLenum mode = cmd->mode; + const GLvoid * indirect = cmd->indirect; + + CALL_DrawArraysIndirect(ctx->Dispatch.Current, (mode, indirect)); + + return align(sizeof(struct marshal_cmd_DrawArraysIndirect), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_DrawArraysIndirect(GLenum mode, const GLvoid *indirect) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled; + + if (draw_indirect_async_allowed(ctx, user_buffer_mask)) { + int cmd_size = sizeof(struct marshal_cmd_DrawArraysIndirect); + struct marshal_cmd_DrawArraysIndirect *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawArraysIndirect, cmd_size); + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->indirect = indirect; + return; + } + + _mesa_glthread_finish_before(ctx, "DrawArraysIndirect"); + lower_draw_arrays_indirect(ctx, mode, (GLintptr)indirect, 0, 1); +} + +uint32_t +_mesa_unmarshal_DrawElementsIndirect(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsIndirect *cmd) +{ + GLenum mode = cmd->mode; + const GLenum type = _mesa_decode_index_type(cmd->type); + const GLvoid * indirect = cmd->indirect; + + CALL_DrawElementsIndirect(ctx->Dispatch.Current, (mode, type, indirect)); + return align(sizeof(struct marshal_cmd_DrawElementsIndirect), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsIndirect(GLenum mode, GLenum type, const GLvoid *indirect) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled; + + if (draw_indirect_async_allowed(ctx, user_buffer_mask) || + !_mesa_is_index_type_valid(type)) { + int cmd_size = sizeof(struct marshal_cmd_DrawElementsIndirect); + struct marshal_cmd_DrawElementsIndirect *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawElementsIndirect, cmd_size); + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->indirect = indirect; + return; + } + + _mesa_glthread_finish_before(ctx, "DrawElementsIndirect"); + lower_draw_elements_indirect(ctx, mode, type, (GLintptr)indirect, 0, 1); +} + +uint32_t +_mesa_unmarshal_MultiDrawArraysIndirect(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawArraysIndirect *cmd) +{ + GLenum mode = cmd->mode; + const GLvoid * indirect = cmd->indirect; + GLsizei primcount = cmd->primcount; + GLsizei stride = cmd->stride; + + CALL_MultiDrawArraysIndirect(ctx->Dispatch.Current, + (mode, indirect, primcount, stride)); + return align(sizeof(struct marshal_cmd_MultiDrawArraysIndirect), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawArraysIndirect(GLenum mode, const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled; + + if (draw_indirect_async_allowed(ctx, user_buffer_mask) || + primcount <= 0) { + int cmd_size = sizeof(struct marshal_cmd_MultiDrawArraysIndirect); + struct marshal_cmd_MultiDrawArraysIndirect *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArraysIndirect, + cmd_size); + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->indirect = indirect; + cmd->primcount = primcount; + cmd->stride = stride; + return; } + + /* Lower the draw to direct due to non-VBO vertex arrays. */ + _mesa_glthread_finish_before(ctx, "MultiDrawArraysIndirect"); + lower_draw_arrays_indirect(ctx, mode, (GLintptr)indirect, stride, primcount); +} + +uint32_t +_mesa_unmarshal_MultiDrawElementsIndirect(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawElementsIndirect *cmd) +{ + GLenum mode = cmd->mode; + const GLenum type = _mesa_decode_index_type(cmd->type); + const GLvoid * indirect = cmd->indirect; + GLsizei primcount = cmd->primcount; + GLsizei stride = cmd->stride; + + CALL_MultiDrawElementsIndirect(ctx->Dispatch.Current, + (mode, type, indirect, primcount, stride)); + return align(sizeof(struct marshal_cmd_MultiDrawElementsIndirect), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawElementsIndirect(GLenum mode, GLenum type, + const GLvoid *indirect, + GLsizei primcount, GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled; + + if (draw_indirect_async_allowed(ctx, user_buffer_mask) || + primcount <= 0 || + !_mesa_is_index_type_valid(type)) { + int cmd_size = sizeof(struct marshal_cmd_MultiDrawElementsIndirect); + struct marshal_cmd_MultiDrawElementsIndirect *cmd; + + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsIndirect, + cmd_size); + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->indirect = indirect; + cmd->primcount = primcount; + cmd->stride = stride; + return; + } + + /* Lower the draw to direct due to non-VBO vertex arrays. */ + _mesa_glthread_finish_before(ctx, "MultiDrawElementsIndirect"); + lower_draw_elements_indirect(ctx, mode, type, (GLintptr)indirect, stride, + primcount); +} + +uint32_t +_mesa_unmarshal_MultiDrawArraysIndirectCountARB(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawArraysIndirectCountARB *cmd) +{ + GLenum mode = cmd->mode; + GLintptr indirect = cmd->indirect; + GLintptr drawcount = cmd->drawcount; + GLsizei maxdrawcount = cmd->maxdrawcount; + GLsizei stride = cmd->stride; + + CALL_MultiDrawArraysIndirectCountARB(ctx->Dispatch.Current, + (mode, indirect, drawcount, + maxdrawcount, stride)); + return align(sizeof(struct marshal_cmd_MultiDrawArraysIndirectCountARB), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawArraysIndirectCountARB(GLenum mode, GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled; + + if (draw_indirect_async_allowed(ctx, user_buffer_mask) || + /* This will just generate GL_INVALID_OPERATION because Draw*IndirectCount + * functions forbid a user indirect buffer in the Compat profile. */ + !ctx->GLThread.CurrentDrawIndirectBufferName) { + int cmd_size = + sizeof(struct marshal_cmd_MultiDrawArraysIndirectCountARB); + struct marshal_cmd_MultiDrawArraysIndirectCountARB *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawArraysIndirectCountARB, + cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->indirect = indirect; + cmd->drawcount = drawcount; + cmd->maxdrawcount = maxdrawcount; + cmd->stride = stride; + return; + } + + /* Lower the draw to direct due to non-VBO vertex arrays. */ + _mesa_glthread_finish_before(ctx, "MultiDrawArraysIndirectCountARB"); + lower_draw_arrays_indirect(ctx, mode, indirect, stride, + read_draw_indirect_count(ctx, drawcount)); +} + +uint32_t +_mesa_unmarshal_MultiDrawElementsIndirectCountARB(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawElementsIndirectCountARB *cmd) +{ + GLenum mode = cmd->mode; + const GLenum type = _mesa_decode_index_type(cmd->type); + GLintptr indirect = cmd->indirect; + GLintptr drawcount = cmd->drawcount; + GLsizei maxdrawcount = cmd->maxdrawcount; + GLsizei stride = cmd->stride; + + CALL_MultiDrawElementsIndirectCountARB(ctx->Dispatch.Current, (mode, type, indirect, drawcount, maxdrawcount, stride)); + + return align(sizeof(struct marshal_cmd_MultiDrawElementsIndirectCountARB), 8) / 8; +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawElementsIndirectCountARB(GLenum mode, GLenum type, + GLintptr indirect, + GLintptr drawcount, + GLsizei maxdrawcount, + GLsizei stride) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + unsigned user_buffer_mask = + _mesa_is_gles31(ctx) ? 0 : vao->UserPointerMask & vao->BufferEnabled; + + if (draw_indirect_async_allowed(ctx, user_buffer_mask) || + /* This will just generate GL_INVALID_OPERATION because Draw*IndirectCount + * functions forbid a user indirect buffer in the Compat profile. */ + !ctx->GLThread.CurrentDrawIndirectBufferName || + !_mesa_is_index_type_valid(type)) { + int cmd_size = sizeof(struct marshal_cmd_MultiDrawElementsIndirectCountARB); + struct marshal_cmd_MultiDrawElementsIndirectCountARB *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_MultiDrawElementsIndirectCountARB, cmd_size); + + cmd->mode = MIN2(mode, 0xff); /* clamped to 0xff (invalid enum) */ + cmd->type = encode_index_type(type); + cmd->indirect = indirect; + cmd->drawcount = drawcount; + cmd->maxdrawcount = maxdrawcount; + cmd->stride = stride; + return; + } + + /* Lower the draw to direct due to non-VBO vertex arrays. */ + _mesa_glthread_finish_before(ctx, "MultiDrawElementsIndirectCountARB"); + lower_draw_elements_indirect(ctx, mode, type, indirect, stride, + read_draw_indirect_count(ctx, drawcount)); } void GLAPIENTRY _mesa_marshal_DrawArrays(GLenum mode, GLint first, GLsizei count) { - draw_arrays(mode, first, count, 1, 0, true); + draw_arrays(0, mode, first, count, 1, 0, true, false); } void GLAPIENTRY -_mesa_marshal_DrawArraysInstancedARB(GLenum mode, GLint first, GLsizei count, - GLsizei instance_count) +_mesa_marshal_DrawArrays_no_error(GLenum mode, GLint first, GLsizei count) { - draw_arrays(mode, first, count, instance_count, 0, false); + draw_arrays(0, mode, first, count, 1, 0, true, true); +} + +void GLAPIENTRY +_mesa_marshal_DrawArraysInstanced(GLenum mode, GLint first, GLsizei count, + GLsizei instance_count) +{ + draw_arrays(0, mode, first, count, instance_count, 0, false, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawArraysInstanced_no_error(GLenum mode, GLint first, GLsizei count, + GLsizei instance_count) +{ + draw_arrays(0, mode, first, count, instance_count, 0, false, true); } void GLAPIENTRY @@ -1133,14 +1699,31 @@ _mesa_marshal_DrawArraysInstancedBaseInstance(GLenum mode, GLint first, GLsizei count, GLsizei instance_count, GLuint baseinstance) { - draw_arrays(mode, first, count, instance_count, baseinstance, false); + draw_arrays(0, mode, first, count, instance_count, baseinstance, false, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawArraysInstancedBaseInstance_no_error(GLenum mode, GLint first, + GLsizei count, GLsizei instance_count, + GLuint baseinstance) +{ + draw_arrays(0, mode, first, count, instance_count, baseinstance, false, true); } void GLAPIENTRY _mesa_marshal_DrawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices) { - draw_elements(mode, count, type, indices, 1, 0, 0, false, 0, 0, true); + draw_elements(0, mode, count, type, indices, 1, 0, + 0, false, 0, 0, true, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawElements_no_error(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices) +{ + draw_elements(0, mode, count, type, indices, 1, 0, + 0, false, 0, 0, true, true); } void GLAPIENTRY @@ -1148,21 +1731,51 @@ _mesa_marshal_DrawRangeElements(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices) { - draw_elements(mode, count, type, indices, 1, 0, 0, true, start, end, true); + draw_elements(0, mode, count, type, indices, 1, 0, + 0, true, start, end, true, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawRangeElements_no_error(GLenum mode, GLuint start, GLuint end, + GLsizei count, GLenum type, + const GLvoid *indices) +{ + draw_elements(0, mode, count, type, indices, 1, 0, + 0, true, start, end, true, true); } void GLAPIENTRY -_mesa_marshal_DrawElementsInstancedARB(GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, GLsizei instance_count) +_mesa_marshal_DrawElementsInstanced(GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLsizei instance_count) { - draw_elements(mode, count, type, indices, instance_count, 0, 0, false, 0, 0, false); + draw_elements(0, mode, count, type, indices, instance_count, 0, + 0, false, 0, 0, false, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsInstanced_no_error(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instance_count) +{ + draw_elements(0, mode, count, type, indices, instance_count, 0, + 0, false, 0, 0, false, true); } void GLAPIENTRY _mesa_marshal_DrawElementsBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) { - draw_elements(mode, count, type, indices, 1, basevertex, 0, false, 0, 0, true); + draw_elements(0, mode, count, type, indices, 1, basevertex, + 0, false, 0, 0, true, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsBaseVertex_no_error(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLint basevertex) +{ + draw_elements(0, mode, count, type, indices, 1, basevertex, + 0, false, 0, 0, true, true); } void GLAPIENTRY @@ -1170,7 +1783,17 @@ _mesa_marshal_DrawRangeElementsBaseVertex(GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices, GLint basevertex) { - draw_elements(mode, count, type, indices, 1, basevertex, 0, true, start, end, false); + draw_elements(0, mode, count, type, indices, 1, basevertex, + 0, true, start, end, true, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawRangeElementsBaseVertex_no_error(GLenum mode, GLuint start, + GLuint end, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex) +{ + draw_elements(0, mode, count, type, indices, 1, basevertex, + 0, true, start, end, true, true); } void GLAPIENTRY @@ -1178,7 +1801,17 @@ _mesa_marshal_DrawElementsInstancedBaseVertex(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instance_count, GLint basevertex) { - draw_elements(mode, count, type, indices, instance_count, basevertex, 0, false, 0, 0, false); + draw_elements(0, mode, count, type, indices, instance_count, basevertex, + 0, false, 0, 0, false, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsInstancedBaseVertex_no_error(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instance_count, GLint basevertex) +{ + draw_elements(0, mode, count, type, indices, instance_count, basevertex, + 0, false, 0, 0, false, true); } void GLAPIENTRY @@ -1186,7 +1819,17 @@ _mesa_marshal_DrawElementsInstancedBaseInstance(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, GLsizei instance_count, GLuint baseinstance) { - draw_elements(mode, count, type, indices, instance_count, 0, baseinstance, false, 0, 0, false); + draw_elements(0, mode, count, type, indices, instance_count, 0, + baseinstance, false, 0, 0, false, false); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsInstancedBaseInstance_no_error(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instance_count, GLuint baseinstance) +{ + draw_elements(0, mode, count, type, indices, instance_count, 0, + baseinstance, false, 0, 0, false, true); } void GLAPIENTRY @@ -1195,56 +1838,280 @@ _mesa_marshal_DrawElementsInstancedBaseVertexBaseInstance(GLenum mode, GLsizei c GLsizei instance_count, GLint basevertex, GLuint baseinstance) { - draw_elements(mode, count, type, indices, instance_count, basevertex, baseinstance, false, 0, 0, false); + draw_elements(0, mode, count, type, indices, instance_count, basevertex, + baseinstance, false, 0, 0, false, false); } void GLAPIENTRY -_mesa_marshal_MultiDrawElementsEXT(GLenum mode, const GLsizei *count, - GLenum type, const GLvoid *const *indices, - GLsizei draw_count) +_mesa_marshal_DrawElementsInstancedBaseVertexBaseInstance_no_error(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instance_count, + GLint basevertex, GLuint baseinstance) +{ + draw_elements(0, mode, count, type, indices, instance_count, basevertex, + baseinstance, false, 0, 0, false, true); +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawElements(GLenum mode, const GLsizei *count, + GLenum type, const GLvoid *const *indices, + GLsizei draw_count) { _mesa_marshal_MultiDrawElementsBaseVertex(mode, count, type, indices, draw_count, NULL); } -void -_mesa_unmarshal_DrawArraysInstancedARB(struct gl_context *ctx, const struct marshal_cmd_DrawArraysInstancedARB *cmd) +uint32_t +_mesa_unmarshal_DrawArrays(struct gl_context *ctx, + const struct marshal_cmd_DrawArrays *restrict cmd) { - unreachable("never used - DrawArraysInstancedBaseInstance is used instead"); + unreachable("should never end up here"); + return 0; } -void -_mesa_unmarshal_DrawElements(struct gl_context *ctx, const struct marshal_cmd_DrawElements *cmd) +uint32_t +_mesa_unmarshal_DrawArraysInstancedBaseInstance(struct gl_context *ctx, + const struct marshal_cmd_DrawArraysInstancedBaseInstance *restrict cmd) +{ + unreachable("should never end up here"); + return 0; +} + +uint32_t +_mesa_unmarshal_MultiDrawArrays(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawArrays *restrict cmd) +{ + unreachable("should never end up here"); + return 0; +} + +uint32_t +_mesa_unmarshal_DrawRangeElements(struct gl_context *ctx, + const struct marshal_cmd_DrawRangeElements *restrict cmd) +{ + unreachable("should never end up here"); + return 0; +} + +uint32_t +_mesa_unmarshal_DrawRangeElementsBaseVertex(struct gl_context *ctx, + const struct marshal_cmd_DrawRangeElementsBaseVertex *cmd) { - unreachable("never used - DrawElementsInstancedBaseVertexBaseInstance is used instead"); + unreachable("should never end up here"); + return 0; } -void -_mesa_unmarshal_DrawRangeElements(struct gl_context *ctx, const struct marshal_cmd_DrawRangeElements *cmd) +uint32_t +_mesa_unmarshal_DrawElementsInstanced(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsInstanced *restrict cmd) { - unreachable("never used - DrawElementsInstancedBaseVertexBaseInstance is used instead"); + unreachable("should never end up here"); + return 0; } -void -_mesa_unmarshal_DrawElementsBaseVertex(struct gl_context *ctx, const struct marshal_cmd_DrawElementsBaseVertex *cmd) +uint32_t +_mesa_unmarshal_DrawElementsBaseVertex(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsBaseVertex *restrict cmd) { - unreachable("never used - DrawElementsInstancedBaseVertexBaseInstance is used instead"); + unreachable("should never end up here"); + return 0; } -void -_mesa_unmarshal_DrawElementsInstancedBaseVertex(struct gl_context *ctx, const struct marshal_cmd_DrawElementsInstancedBaseVertex *cmd) +uint32_t +_mesa_unmarshal_DrawElementsInstancedBaseVertexBaseInstance(struct gl_context *ctx, + const struct marshal_cmd_DrawElementsInstancedBaseVertexBaseInstance *restrict cmd) { - unreachable("never used - DrawElementsInstancedBaseVertexBaseInstance is used instead"); + unreachable("should never end up here"); + return 0; } -void -_mesa_unmarshal_DrawElementsInstancedBaseInstance(struct gl_context *ctx, const struct marshal_cmd_DrawElementsInstancedBaseInstance *cmd) +uint32_t +_mesa_unmarshal_MultiDrawElements(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawElements *restrict cmd) +{ + unreachable("should never end up here"); + return 0; +} + +uint32_t +_mesa_unmarshal_MultiDrawElementsBaseVertex(struct gl_context *ctx, + const struct marshal_cmd_MultiDrawElementsBaseVertex *restrict cmd) { - unreachable("never used - DrawElementsInstancedBaseVertexBaseInstance is used instead"); + unreachable("should never end up here"); + return 0; } -void -_mesa_unmarshal_MultiDrawElementsEXT(struct gl_context *ctx, const struct marshal_cmd_MultiDrawElementsEXT *cmd) +uint32_t +_mesa_unmarshal_MultiModeDrawArraysIBM(struct gl_context *ctx, + const struct marshal_cmd_MultiModeDrawArraysIBM *cmd) { - unreachable("never used - MultiDrawElementsBaseVertex is used instead"); + unreachable("should never end up here"); + return 0; +} + +uint32_t +_mesa_unmarshal_MultiModeDrawElementsIBM(struct gl_context *ctx, + const struct marshal_cmd_MultiModeDrawElementsIBM *cmd) +{ + unreachable("should never end up here"); + return 0; +} + +void GLAPIENTRY +_mesa_marshal_DrawArraysUserBuf(void) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsUserBuf(const GLvoid *cmd) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsUserBufPacked(const GLvoid *cmd) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawArraysUserBuf(void) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_marshal_MultiDrawElementsUserBuf(GLintptr indexBuf, GLenum mode, + const GLsizei *count, GLenum type, + const GLvoid * const *indices, + GLsizei primcount, + const GLint *basevertex) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_marshal_DrawArraysInstancedBaseInstanceDrawID(void) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY _mesa_marshal_DrawElementsPacked(GLenum mode, GLenum type, + GLushort count, GLushort indices) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_marshal_DrawElementsInstancedBaseVertexBaseInstanceDrawID(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instance_count, GLint basevertex, + GLuint baseinstance, GLuint drawid) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_DrawArraysUserBuf(void) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_MultiDrawArraysUserBuf(void) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_DrawArraysInstancedBaseInstanceDrawID(void) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY _mesa_DrawElementsPacked(GLenum mode, GLenum type, + GLushort count, GLushort indices) +{ + unreachable("should never end up here"); +} + +void GLAPIENTRY +_mesa_DrawElementsInstancedBaseVertexBaseInstanceDrawID(GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices, + GLsizei instance_count, GLint basevertex, + GLuint baseinstance, GLuint drawid) +{ + unreachable("should never end up here"); +} + +uint32_t +_mesa_unmarshal_PushMatrix(struct gl_context *ctx, + const struct marshal_cmd_PushMatrix *restrict cmd) +{ + const unsigned push_matrix_size = 1; + const unsigned mult_matrixf_size = 9; + const unsigned draw_elements_size = + (align(sizeof(struct marshal_cmd_DrawElements), 8) / 8); + const unsigned draw_elements_packed_size = + (align(sizeof(struct marshal_cmd_DrawElementsPacked), 8) / 8); + const unsigned pop_matrix_size = 1; + uint64_t *next1 = _mesa_glthread_next_cmd((uint64_t *)cmd, push_matrix_size); + uint64_t *next2; + + /* Viewperf has these call patterns. */ + switch (_mesa_glthread_get_cmd(next1)->cmd_id) { + case DISPATCH_CMD_DrawElements: + /* Execute this sequence: + * glPushMatrix + * (glMultMatrixf with identity is eliminated by the marshal function) + * glDrawElements + * glPopMatrix + * as: + * glDrawElements + */ + next2 = _mesa_glthread_next_cmd(next1, draw_elements_size); + + if (_mesa_glthread_get_cmd(next2)->cmd_id == DISPATCH_CMD_PopMatrix) { + /* The beauty of this is that this is inlined. */ + _mesa_unmarshal_DrawElements(ctx, (void*)next1); + return push_matrix_size + draw_elements_size + pop_matrix_size; + } + break; + + case DISPATCH_CMD_DrawElementsPacked: + next2 = _mesa_glthread_next_cmd(next1, draw_elements_packed_size); + + if (_mesa_glthread_get_cmd(next2)->cmd_id == DISPATCH_CMD_PopMatrix) { + /* The beauty of this is that this is inlined. */ + _mesa_unmarshal_DrawElementsPacked(ctx, (void*)next1); + return push_matrix_size + draw_elements_packed_size + pop_matrix_size; + } + break; + + case DISPATCH_CMD_MultMatrixf: + /* Skip this sequence: + * glPushMatrix + * glMultMatrixf + * glPopMatrix + */ + next2 = _mesa_glthread_next_cmd(next1, mult_matrixf_size); + + if (_mesa_glthread_get_cmd(next2)->cmd_id == DISPATCH_CMD_PopMatrix) + return push_matrix_size + mult_matrixf_size + pop_matrix_size; + break; + } + + CALL_PushMatrix(ctx->Dispatch.Current, ()); + return push_matrix_size; +} + +void GLAPIENTRY +_mesa_marshal_PushMatrix(void) +{ + GET_CURRENT_CONTEXT(ctx); + + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_PushMatrix, + sizeof(struct marshal_cmd_PushMatrix)); + _mesa_glthread_PushMatrix(ctx); } diff --git a/src/mesa/main/glthread_draw_unroll.c b/src/mesa/main/glthread_draw_unroll.c new file mode 100644 index 00000000000..5611843d92a --- /dev/null +++ b/src/mesa/main/glthread_draw_unroll.c @@ -0,0 +1,949 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2022 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/* This lowers glDrawElementsBaseVertex into glBegin/glEnd draws. + * + * It's used by glthread when uploading non-VBO vertex arrays would take too + * much time due to small numbers of vertices per draw where indices have very + * large differences. (e.g. indices {0, 1000000} normally cause us to upload + * (1000000 * stride) bytes to draw 2 vertices) This helps performance for + * such pathological cases. + */ + +#include "context.h" +#include "glthread_marshal.h" +#include "vbo/vbo_util.h" +#include "util/half_float.h" + +#define FIXED_TO_FLOAT(x) \ + (int32_t)(CLAMP((x), -65536.0f, 65535.0f) * (double)0x10000) + +#define UNPACK_RGB10A2_USCALED(x) { \ + (x) & 0x3ff, \ + ((x) >> 10) & 0x3ff, \ + ((x) >> 20) & 0x3ff, \ + ((x) >> 30) & 0x3 \ +} + +#define UNPACK_RGB10A2_SSCALED(x) { \ + conv_i10_to_i((x) & 0x3ff), \ + conv_i10_to_i(((x) >> 10) & 0x3ff), \ + conv_i10_to_i(((x) >> 20) & 0x3ff), \ + conv_i2_to_i(((x) >> 30) & 0x3) \ +} + +#define UNPACK_RGB10A2_UNORM(x) { \ + conv_ui10_to_norm_float((x) & 0x3ff), \ + conv_ui10_to_norm_float(((x) >> 10) & 0x3ff), \ + conv_ui10_to_norm_float(((x) >> 20) & 0x3ff), \ + conv_ui2_to_norm_float(((x) >> 30) & 0x3) \ +} + +#define UNPACK_RGB10A2_SNORM(x) { \ + conv_i10_to_norm_float(ctx, (x) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((x) >> 10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((x) >> 20) & 0x3ff), \ + conv_i2_to_norm_float(ctx, ((x) >> 30) & 0x3) \ +} + +#define UNPACK_BGR10A2_USCALED(x) { \ + ((x) >> 20) & 0x3ff, \ + ((x) >> 10) & 0x3ff, \ + (x) & 0x3ff, \ + ((x) >> 30) & 0x3 \ +} + +#define UNPACK_BGR10A2_SSCALED(x) { \ + conv_i10_to_i(((x) >> 20) & 0x3ff), \ + conv_i10_to_i(((x) >> 10) & 0x3ff), \ + conv_i10_to_i((x) & 0x3ff), \ + conv_i2_to_i(((x) >> 30) & 0x3) \ +} + +#define UNPACK_BGR10A2_UNORM(x) { \ + conv_ui10_to_norm_float(((x) >> 20) & 0x3ff), \ + conv_ui10_to_norm_float(((x) >> 10) & 0x3ff), \ + conv_ui10_to_norm_float((x) & 0x3ff), \ + conv_ui2_to_norm_float(((x) >> 30) & 0x3) \ +} + +#define UNPACK_BGR10A2_SNORM(x) { \ + conv_i10_to_norm_float(ctx, ((x) >> 20) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((x) >> 10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, (x) & 0x3ff), \ + conv_i2_to_norm_float(ctx, ((x) >> 30) & 0x3) \ +} + +#define UNPACK_BGRA8_UNORM(x) { \ + UBYTE_TO_FLOAT(((x) >> 16) & 0xff), \ + UBYTE_TO_FLOAT(((x) >> 8) & 0xff), \ + UBYTE_TO_FLOAT((x) & 0xff), \ + UBYTE_TO_FLOAT(((x) >> 24) & 0xff) \ +} + +#define TEMPLATE_FUNC1(t, src, type, dst, conv) \ + static void _mesa_wrapped_VertexAttrib##t##1##src(GLuint index, type *v) \ + { \ + _mesa_marshal_VertexAttrib##t##1##dst(index, conv(v[0])); \ + } + +#define TEMPLATE_FUNC2(t, src, type, dst, conv) \ + static void _mesa_wrapped_VertexAttrib##t##2##src(GLuint index, type *v) \ + { \ + _mesa_marshal_VertexAttrib##t##2##dst(index, conv(v[0]), conv(v[1])); \ + } + +#define TEMPLATE_FUNC3(t, src, type, dst, conv) \ + static void _mesa_wrapped_VertexAttrib##t##3##src(GLuint index, type *v) \ + { \ + _mesa_marshal_VertexAttrib##t##3##dst(index, conv(v[0]), conv(v[1]), \ + conv(v[2])); \ + } + +#define TEMPLATE_FUNC4(t, src, type, dst, conv) \ + static void _mesa_wrapped_VertexAttrib##t##4##src(GLuint index, type *v) \ + { \ + _mesa_marshal_VertexAttrib##t##4##dst(index, conv(v[0]), conv(v[1]), \ + conv(v[2]), conv(v[3])); \ + } + +#define SCALED false +#define NORMALIZED true + +#define TEMPLATE_FUNCP(n, src, type, normalized) \ + static void _mesa_wrapped_VertexAttribP##n##src(GLuint index, GLuint *v) \ + { \ + _mesa_marshal_VertexAttribP##n##ui(index, type, normalized, v[0]); \ + } + +#define TEMPLATE_FUNCUP(n, src, dst, unpack) \ + static void _mesa_wrapped_VertexAttribP##n##src(GLuint index, GLuint *v) \ + { \ + float fv[n] = unpack(v[0]); \ + _mesa_marshal_VertexAttrib##n##dst(index, fv); \ + } + +#define TEMPLATE_FUNCUP_CTX(n, src, dst, unpack) \ + static void _mesa_wrapped_VertexAttribP##n##src(GLuint index, GLuint *v) \ + { \ + GET_CURRENT_CONTEXT(ctx); \ + float fv[n] = unpack(v[0]); \ + _mesa_marshal_VertexAttrib##n##dst(index, fv); \ + } + +#define TEMPLATE_FUNC_ALL3(t, src, type, dst, conv) \ + TEMPLATE_FUNC1(t, src, type, dst, conv) \ + TEMPLATE_FUNC2(t, src, type, dst, conv) \ + TEMPLATE_FUNC3(t, src, type, dst, conv) + +#define TEMPLATE_FUNC_ALL4(t, src, type, dst, conv) \ + TEMPLATE_FUNC_ALL3(t, src, type, dst, conv) \ + TEMPLATE_FUNC4(t, src, type, dst, conv) + +/* We use NV attributes because they can set all non-generic attributes. */ + +/* Define VertexAttrib wrappers using template macros. */ +TEMPLATE_FUNC_ALL4(, bvNV, GLbyte, sNV, ) +TEMPLATE_FUNC_ALL4(, NbvNV, GLbyte, fNV, BYTE_TO_FLOAT) +TEMPLATE_FUNC_ALL4(, ubvNV, GLubyte, sNV, ) +TEMPLATE_FUNC_ALL3(, NubvNV, GLubyte, fNV, UBYTE_TO_FLOAT) /* TODO: use VertexAttrib4ubNV */ + +TEMPLATE_FUNC_ALL3(, bv, GLbyte, s, ) /* TODO: use VertexAttrib4bv */ +TEMPLATE_FUNC_ALL3(, Nbv, GLbyte, fARB, BYTE_TO_FLOAT) /* TODO: use VertexAttrib4Nb */ +TEMPLATE_FUNC_ALL3(, ubv, GLubyte, s, ) /* TODO: use VertexAttrib4ubv */ +TEMPLATE_FUNC_ALL3(, Nubv, GLubyte, fARB, UBYTE_TO_FLOAT) /* TODO: use VertexAttrib4Nub */ +TEMPLATE_FUNC_ALL3(I, bv, GLbyte, iEXT, ) /* TODO: use VertexAttribI4bv */ +TEMPLATE_FUNC_ALL3(I, ubv, GLubyte, uiEXT, ) /* TODO: use VertexAttribI4ubv */ + +TEMPLATE_FUNC_ALL4(, NsvNV, GLshort, fNV, SHORT_TO_FLOAT) +TEMPLATE_FUNC_ALL4(, usvNV, GLushort, fNV, ) +TEMPLATE_FUNC_ALL4(, NusvNV, GLushort, fNV, USHORT_TO_FLOAT) + +TEMPLATE_FUNC_ALL3(, Nsv, GLshort, fARB, SHORT_TO_FLOAT) /* TODO: use VertexAttrib4Nsv */ +TEMPLATE_FUNC_ALL3(, usv, GLushort, fARB, ) /* TODO: use VertexAttrib4usv */ +TEMPLATE_FUNC_ALL3(, Nusv, GLushort, fARB, USHORT_TO_FLOAT) /* TODO: use VertexAttrib4Nusv */ +TEMPLATE_FUNC_ALL3(I, sv, GLshort, iEXT, ) /* TODO: use VertexAttribI4sv */ +TEMPLATE_FUNC_ALL3(I, usv, GLushort, uiEXT, ) /* TODO: use VertexAttribI4usv */ + +TEMPLATE_FUNC_ALL4(, ivNV, GLint, fNV, ) +TEMPLATE_FUNC_ALL4(, NivNV, GLint, fNV, INT_TO_FLOAT) +TEMPLATE_FUNC_ALL4(, uivNV, GLuint, fNV, ) +TEMPLATE_FUNC_ALL4(, NuivNV, GLuint, fNV, UINT_TO_FLOAT) + +TEMPLATE_FUNC_ALL3(, iv, GLint, fARB, ) +TEMPLATE_FUNC_ALL3(, Niv, GLint, fARB, INT_TO_FLOAT) +TEMPLATE_FUNC_ALL3(, uiv, GLuint, fARB, ) +TEMPLATE_FUNC_ALL3(, Nuiv, GLuint, fARB, UINT_TO_FLOAT) + +TEMPLATE_FUNC_ALL4(, xvNV, GLfixed, fNV, FIXED_TO_FLOAT) +TEMPLATE_FUNC_ALL4(, xv, GLfixed, fARB, FIXED_TO_FLOAT) + +TEMPLATE_FUNC_ALL4(, hv, GLhalf, fARB, _mesa_half_to_float) + +TEMPLATE_FUNC2(L, ui64v, GLuint64, d, UINT64_AS_DOUBLE) +TEMPLATE_FUNC3(L, ui64v, GLuint64, d, UINT64_AS_DOUBLE) +TEMPLATE_FUNC4(L, ui64v, GLuint64, d, UINT64_AS_DOUBLE) + +TEMPLATE_FUNCP(4, _rgb10a2_sscaled, GL_INT_2_10_10_10_REV, SCALED) +TEMPLATE_FUNCP(4, _rgb10a2_snorm, GL_INT_2_10_10_10_REV, NORMALIZED) +TEMPLATE_FUNCP(4, _rgb10a2_uscaled, GL_UNSIGNED_INT_2_10_10_10_REV, SCALED) +TEMPLATE_FUNCP(4, _rgb10a2_unorm, GL_UNSIGNED_INT_2_10_10_10_REV, NORMALIZED) +TEMPLATE_FUNCP(3, _rg11b10_float, GL_UNSIGNED_INT_10F_11F_11F_REV, SCALED) + +TEMPLATE_FUNCUP(4, NV_rgb10a2_uscaled, fvNV, UNPACK_RGB10A2_USCALED) +TEMPLATE_FUNCUP(4, NV_rgb10a2_sscaled, fvNV, UNPACK_RGB10A2_SSCALED) +TEMPLATE_FUNCUP(4, NV_rgb10a2_unorm, fvNV, UNPACK_RGB10A2_UNORM) +TEMPLATE_FUNCUP_CTX(4, NV_rgb10a2_snorm, fvNV, UNPACK_RGB10A2_SNORM) + +TEMPLATE_FUNCUP(4, NV_bgr10a2_uscaled, fvNV, UNPACK_BGR10A2_USCALED) +TEMPLATE_FUNCUP(4, NV_bgr10a2_sscaled, fvNV, UNPACK_BGR10A2_SSCALED) +TEMPLATE_FUNCUP(4, NV_bgr10a2_unorm, fvNV, UNPACK_BGR10A2_UNORM) +TEMPLATE_FUNCUP_CTX(4, NV_bgr10a2_snorm, fvNV, UNPACK_BGR10A2_SNORM) +TEMPLATE_FUNCUP(4, NV_bgra8_unorm, fvNV, UNPACK_BGRA8_UNORM) + +TEMPLATE_FUNCUP(4, _bgr10a2_uscaled, fvARB, UNPACK_BGR10A2_USCALED) +TEMPLATE_FUNCUP(4, _bgr10a2_sscaled, fvARB, UNPACK_BGR10A2_SSCALED) +TEMPLATE_FUNCUP(4, _bgr10a2_unorm, fvARB, UNPACK_BGR10A2_UNORM) +TEMPLATE_FUNCUP_CTX(4, _bgr10a2_snorm, fvARB, UNPACK_BGR10A2_SNORM) +TEMPLATE_FUNCUP(4, _bgra8_unorm, fvARB, UNPACK_BGRA8_UNORM) + +typedef void (GLAPIENTRY *attrib_func)(GLuint indx, const void *data); + +/* indexing: [gltype & 0x3f][normalized][size - 1] */ +static const attrib_func legacy_rgba_attrib_funcs[][2][4] = { + { /* GL_BYTE */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1bvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2bvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3bvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4bvNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1NbvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2NbvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3NbvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4NbvNV, + }, + }, + { /* GL_UNSIGNED_BYTE */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1ubvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2ubvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3ubvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4ubvNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1NubvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2NubvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3NubvNV, + (attrib_func)_mesa_marshal_VertexAttrib4ubvNV, /* always normalized */ + }, + }, + { /* GL_SHORT */ + { + (attrib_func)_mesa_marshal_VertexAttrib1svNV, + (attrib_func)_mesa_marshal_VertexAttrib2svNV, + (attrib_func)_mesa_marshal_VertexAttrib3svNV, + (attrib_func)_mesa_marshal_VertexAttrib4svNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1NsvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2NsvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3NsvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4NsvNV, + }, + }, + { /* GL_UNSIGNED_SHORT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1usvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2usvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3usvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4usvNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1NusvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2NusvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3NusvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4NusvNV, + }, + }, + { /* GL_INT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1ivNV, + (attrib_func)_mesa_wrapped_VertexAttrib2ivNV, + (attrib_func)_mesa_wrapped_VertexAttrib3ivNV, + (attrib_func)_mesa_wrapped_VertexAttrib4ivNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1NivNV, + (attrib_func)_mesa_wrapped_VertexAttrib2NivNV, + (attrib_func)_mesa_wrapped_VertexAttrib3NivNV, + (attrib_func)_mesa_wrapped_VertexAttrib4NivNV, + }, + }, + { /* GL_UNSIGNED_INT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1uivNV, + (attrib_func)_mesa_wrapped_VertexAttrib2uivNV, + (attrib_func)_mesa_wrapped_VertexAttrib3uivNV, + (attrib_func)_mesa_wrapped_VertexAttrib4uivNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1NuivNV, + (attrib_func)_mesa_wrapped_VertexAttrib2NuivNV, + (attrib_func)_mesa_wrapped_VertexAttrib3NuivNV, + (attrib_func)_mesa_wrapped_VertexAttrib4NuivNV, + }, + }, + { /* GL_FLOAT */ + { + (attrib_func)_mesa_marshal_VertexAttrib1fvNV, + (attrib_func)_mesa_marshal_VertexAttrib2fvNV, + (attrib_func)_mesa_marshal_VertexAttrib3fvNV, + (attrib_func)_mesa_marshal_VertexAttrib4fvNV, + }, + { + (attrib_func)_mesa_marshal_VertexAttrib1fvNV, + (attrib_func)_mesa_marshal_VertexAttrib2fvNV, + (attrib_func)_mesa_marshal_VertexAttrib3fvNV, + (attrib_func)_mesa_marshal_VertexAttrib4fvNV, + }, + }, + {{0}}, /* GL_2_BYTES */ + {{0}}, /* GL_3_BYTES */ + {{0}}, /* GL_4_BYTES */ + { /* GL_DOUBLE */ + { + (attrib_func)_mesa_marshal_VertexAttrib1dvNV, + (attrib_func)_mesa_marshal_VertexAttrib2dvNV, + (attrib_func)_mesa_marshal_VertexAttrib3dvNV, + (attrib_func)_mesa_marshal_VertexAttrib4dvNV, + }, + { + (attrib_func)_mesa_marshal_VertexAttrib1dvNV, + (attrib_func)_mesa_marshal_VertexAttrib2dvNV, + (attrib_func)_mesa_marshal_VertexAttrib3dvNV, + (attrib_func)_mesa_marshal_VertexAttrib4dvNV, + }, + }, + { /* GL_HALF_FLOAT */ + { + (attrib_func)_mesa_marshal_VertexAttrib1hvNV, + (attrib_func)_mesa_marshal_VertexAttrib2hvNV, + (attrib_func)_mesa_marshal_VertexAttrib3hvNV, + (attrib_func)_mesa_marshal_VertexAttrib4hvNV, + }, + { + (attrib_func)_mesa_marshal_VertexAttrib1hvNV, + (attrib_func)_mesa_marshal_VertexAttrib2hvNV, + (attrib_func)_mesa_marshal_VertexAttrib3hvNV, + (attrib_func)_mesa_marshal_VertexAttrib4hvNV, + }, + }, + { /* GL_FIXED */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1xvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2xvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3xvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4xvNV, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1xvNV, + (attrib_func)_mesa_wrapped_VertexAttrib2xvNV, + (attrib_func)_mesa_wrapped_VertexAttrib3xvNV, + (attrib_func)_mesa_wrapped_VertexAttrib4xvNV, + }, + }, + {{0}}, /* unused (13) */ + {{0}}, /* unused (14) */ + {{0}}, /* unused (15) */ + {{0}}, /* unused (16) */ + {{0}}, /* unused (17) */ + {{0}}, /* unused (18) */ + {{0}}, /* unused (19) */ + {{0}}, /* unused (20) */ + {{0}}, /* unused (21) */ + {{0}}, /* unused (22) */ + {{0}}, /* unused (23) */ + {{0}}, /* unused (24) */ + {{0}}, /* unused (25) */ + {{0}}, /* unused (26) */ + {{0}}, /* unused (27) */ + {{0}}, /* unused (28) */ + {{0}}, /* unused (29) */ + {{0}}, /* unused (30) */ + { /* GL_INT_2_10_10_10_REV */ + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_sscaled, + }, + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_snorm, + }, + }, + {{0}}, /* unused (32) */ + { /* GL_HALF_FLOAT_OES */ + { + (attrib_func)_mesa_marshal_VertexAttrib1hvNV, + (attrib_func)_mesa_marshal_VertexAttrib2hvNV, + (attrib_func)_mesa_marshal_VertexAttrib3hvNV, + (attrib_func)_mesa_marshal_VertexAttrib4hvNV, + }, + { + (attrib_func)_mesa_marshal_VertexAttrib1hvNV, + (attrib_func)_mesa_marshal_VertexAttrib2hvNV, + (attrib_func)_mesa_marshal_VertexAttrib3hvNV, + (attrib_func)_mesa_marshal_VertexAttrib4hvNV, + }, + }, + {{0}}, /* unused (34) */ + {{0}}, /* unused (35) */ + {{0}}, /* unused (36) */ + {{0}}, /* unused (37) */ + {{0}}, /* unused (38) */ + {{0}}, /* unused (39) */ + { /* GL_UNSIGNED_INT_2_10_10_10_REV */ + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_uscaled, + }, + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_rgb10a2_unorm, + }, + }, +}; + +/* indexing: [type & 0x3][normalized] */ +static const attrib_func legacy_bgra_attrib_funcs[4][2] = { + { /* GL_UNSIGNED_INT_2_10_10_10_REV */ + (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_uscaled, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_unorm, + }, + { /* GL_UNSIGNED_BYTE */ + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgra8_unorm, + }, + {0}, /* unused (2) */ + { /* GL_INT_2_10_10_10_REV */ + (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_sscaled, + (attrib_func)_mesa_wrapped_VertexAttribP4NV_bgr10a2_snorm, + } +}; + +/* indexing: [(gltype & 0x3f) | (double << 5)][integer*2 + normalized][size - 1] */ +static const attrib_func generic_rgba_attrib_funcs[][4][4] = { + { /* GL_BYTE */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1bv, + (attrib_func)_mesa_wrapped_VertexAttrib2bv, + (attrib_func)_mesa_wrapped_VertexAttrib3bv, + (attrib_func)_mesa_marshal_VertexAttrib4bv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1Nbv, + (attrib_func)_mesa_wrapped_VertexAttrib2Nbv, + (attrib_func)_mesa_wrapped_VertexAttrib3Nbv, + (attrib_func)_mesa_marshal_VertexAttrib4Nbv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttribI1bv, + (attrib_func)_mesa_wrapped_VertexAttribI2bv, + (attrib_func)_mesa_wrapped_VertexAttribI3bv, + (attrib_func)_mesa_marshal_VertexAttribI4bv, + }, + }, + { /* GL_UNSIGNED_BYTE */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1ubv, + (attrib_func)_mesa_wrapped_VertexAttrib2ubv, + (attrib_func)_mesa_wrapped_VertexAttrib3ubv, + (attrib_func)_mesa_marshal_VertexAttrib4ubv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1Nubv, + (attrib_func)_mesa_wrapped_VertexAttrib2Nubv, + (attrib_func)_mesa_wrapped_VertexAttrib3Nubv, + (attrib_func)_mesa_marshal_VertexAttrib4Nubv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttribI1ubv, + (attrib_func)_mesa_wrapped_VertexAttribI2ubv, + (attrib_func)_mesa_wrapped_VertexAttribI3ubv, + (attrib_func)_mesa_marshal_VertexAttribI4ubv, + }, + }, + { /* GL_SHORT */ + { + (attrib_func)_mesa_marshal_VertexAttrib1sv, + (attrib_func)_mesa_marshal_VertexAttrib2sv, + (attrib_func)_mesa_marshal_VertexAttrib3sv, + (attrib_func)_mesa_marshal_VertexAttrib4sv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1Nsv, + (attrib_func)_mesa_wrapped_VertexAttrib2Nsv, + (attrib_func)_mesa_wrapped_VertexAttrib3Nsv, + (attrib_func)_mesa_marshal_VertexAttrib4Nsv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttribI1sv, + (attrib_func)_mesa_wrapped_VertexAttribI2sv, + (attrib_func)_mesa_wrapped_VertexAttribI3sv, + (attrib_func)_mesa_marshal_VertexAttribI4sv, + }, + }, + { /* GL_UNSIGNED_SHORT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1usv, + (attrib_func)_mesa_wrapped_VertexAttrib2usv, + (attrib_func)_mesa_wrapped_VertexAttrib3usv, + (attrib_func)_mesa_marshal_VertexAttrib4usv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1Nusv, + (attrib_func)_mesa_wrapped_VertexAttrib2Nusv, + (attrib_func)_mesa_wrapped_VertexAttrib3Nusv, + (attrib_func)_mesa_marshal_VertexAttrib4Nusv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttribI1usv, + (attrib_func)_mesa_wrapped_VertexAttribI2usv, + (attrib_func)_mesa_wrapped_VertexAttribI3usv, + (attrib_func)_mesa_marshal_VertexAttribI4usv, + }, + }, + { /* GL_INT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1iv, + (attrib_func)_mesa_wrapped_VertexAttrib2iv, + (attrib_func)_mesa_wrapped_VertexAttrib3iv, + (attrib_func)_mesa_marshal_VertexAttrib4iv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1Niv, + (attrib_func)_mesa_wrapped_VertexAttrib2Niv, + (attrib_func)_mesa_wrapped_VertexAttrib3Niv, + (attrib_func)_mesa_marshal_VertexAttrib4Niv, + }, + { + (attrib_func)_mesa_marshal_VertexAttribI1iv, + (attrib_func)_mesa_marshal_VertexAttribI2ivEXT, + (attrib_func)_mesa_marshal_VertexAttribI3ivEXT, + (attrib_func)_mesa_marshal_VertexAttribI4ivEXT, + }, + }, + { /* GL_UNSIGNED_INT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1uiv, + (attrib_func)_mesa_wrapped_VertexAttrib2uiv, + (attrib_func)_mesa_wrapped_VertexAttrib3uiv, + (attrib_func)_mesa_marshal_VertexAttrib4uiv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1Nuiv, + (attrib_func)_mesa_wrapped_VertexAttrib2Nuiv, + (attrib_func)_mesa_wrapped_VertexAttrib3Nuiv, + (attrib_func)_mesa_marshal_VertexAttrib4Nuiv, + }, + { + (attrib_func)_mesa_marshal_VertexAttribI1uiv, + (attrib_func)_mesa_marshal_VertexAttribI2uivEXT, + (attrib_func)_mesa_marshal_VertexAttribI3uivEXT, + (attrib_func)_mesa_marshal_VertexAttribI4uivEXT, + }, + }, + { /* GL_FLOAT */ + { + (attrib_func)_mesa_marshal_VertexAttrib1fvARB, + (attrib_func)_mesa_marshal_VertexAttrib2fvARB, + (attrib_func)_mesa_marshal_VertexAttrib3fvARB, + (attrib_func)_mesa_marshal_VertexAttrib4fvARB, + }, + { + (attrib_func)_mesa_marshal_VertexAttrib1fvARB, + (attrib_func)_mesa_marshal_VertexAttrib2fvARB, + (attrib_func)_mesa_marshal_VertexAttrib3fvARB, + (attrib_func)_mesa_marshal_VertexAttrib4fvARB, + }, + }, + {{0}}, /* GL_2_BYTES */ + {{0}}, /* GL_3_BYTES */ + {{0}}, /* GL_4_BYTES */ + { /* GL_DOUBLE */ + { + (attrib_func)_mesa_marshal_VertexAttrib1dv, + (attrib_func)_mesa_marshal_VertexAttrib2dv, + (attrib_func)_mesa_marshal_VertexAttrib3dv, + (attrib_func)_mesa_marshal_VertexAttrib4dv, + }, + { + (attrib_func)_mesa_marshal_VertexAttrib1dv, + (attrib_func)_mesa_marshal_VertexAttrib2dv, + (attrib_func)_mesa_marshal_VertexAttrib3dv, + (attrib_func)_mesa_marshal_VertexAttrib4dv, + }, + }, + { /* GL_HALF_FLOAT */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1hv, + (attrib_func)_mesa_wrapped_VertexAttrib2hv, + (attrib_func)_mesa_wrapped_VertexAttrib3hv, + (attrib_func)_mesa_wrapped_VertexAttrib4hv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1hv, + (attrib_func)_mesa_wrapped_VertexAttrib2hv, + (attrib_func)_mesa_wrapped_VertexAttrib3hv, + (attrib_func)_mesa_wrapped_VertexAttrib4hv, + }, + }, + { /* GL_FIXED */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1xv, + (attrib_func)_mesa_wrapped_VertexAttrib2xv, + (attrib_func)_mesa_wrapped_VertexAttrib3xv, + (attrib_func)_mesa_wrapped_VertexAttrib4xv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1xv, + (attrib_func)_mesa_wrapped_VertexAttrib2xv, + (attrib_func)_mesa_wrapped_VertexAttrib3xv, + (attrib_func)_mesa_wrapped_VertexAttrib4xv, + }, + }, + {{0}}, /* unused (13) */ + {{0}}, /* unused (14) */ + {{0}}, /* unused (15) */ + {{0}}, /* unused (16) */ + {{0}}, /* unused (17) */ + {{0}}, /* unused (18) */ + {{0}}, /* unused (19) */ + {{0}}, /* unused (20) */ + {{0}}, /* unused (21) */ + {{0}}, /* unused (22) */ + {{0}}, /* unused (23) */ + {{0}}, /* unused (24) */ + {{0}}, /* unused (25) */ + {{0}}, /* unused (26) */ + {{0}}, /* unused (27) */ + {{0}}, /* unused (28) */ + {{0}}, /* unused (29) */ + {{0}}, /* unused (30) */ + { /* GL_INT_2_10_10_10_REV */ + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_sscaled, + }, + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_snorm, + }, + }, + {{0}}, /* unused (32) */ + { /* GL_HALF_FLOAT_OES */ + { + (attrib_func)_mesa_wrapped_VertexAttrib1hv, + (attrib_func)_mesa_wrapped_VertexAttrib2hv, + (attrib_func)_mesa_wrapped_VertexAttrib3hv, + (attrib_func)_mesa_wrapped_VertexAttrib4hv, + }, + { + (attrib_func)_mesa_wrapped_VertexAttrib1hv, + (attrib_func)_mesa_wrapped_VertexAttrib2hv, + (attrib_func)_mesa_wrapped_VertexAttrib3hv, + (attrib_func)_mesa_wrapped_VertexAttrib4hv, + }, + }, + {{0}}, /* unused (34) */ + {{0}}, /* unused (35) */ + {{0}}, /* unused (36) */ + {{0}}, /* unused (37) */ + {{0}}, /* unused (38) */ + {{0}}, /* unused (39) */ + { /* GL_UNSIGNED_INT_2_10_10_10_REV */ + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_uscaled, + }, + { + 0, + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4_rgb10a2_unorm, + }, + }, + {{0}}, /* unused (41) */ + { /* GL_DOUBLE | (doubles << 5) (real double) */ + { + (attrib_func)_mesa_marshal_VertexAttribL1dv, + (attrib_func)_mesa_marshal_VertexAttribL2dv, + (attrib_func)_mesa_marshal_VertexAttribL3dv, + (attrib_func)_mesa_marshal_VertexAttribL4dv, + }, + }, + {{0}}, /* unused (43) */ + {{0}}, /* unused (44) */ + {{0}}, /* unused (45) */ + {{0}}, /* unused (46) */ + { /* GL_UNSIGNED_INT64_ARB | (doubles << 5) (doubles is always true) */ + {0}, + {0}, + { + (attrib_func)_mesa_marshal_VertexAttribL1ui64vARB, + (attrib_func)_mesa_wrapped_VertexAttribL2ui64v, + (attrib_func)_mesa_wrapped_VertexAttribL3ui64v, + (attrib_func)_mesa_wrapped_VertexAttribL4ui64v, + }, + }, + {{0}}, /* unused (48) */ + {{0}}, /* unused (49) */ + {{0}}, /* unused (50) */ + {{0}}, /* unused (51) */ + {{0}}, /* unused (52) */ + {{0}}, /* unused (53) */ + {{0}}, /* unused (54) */ + {{0}}, /* unused (55) */ + {{0}}, /* unused (56) */ + {{0}}, /* unused (57) */ + {{0}}, /* unused (58) */ + { /* GL_UNSIGNED_INT_10F_11F_11F_REV */ + { + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP3_rg11b10_float, + 0 + }, + { + 0, + 0, + (attrib_func)_mesa_wrapped_VertexAttribP3_rg11b10_float, + 0 + }, + }, +}; + +/* indexing: [type & 0x3][normalized] */ +static const attrib_func generic_bgra_attrib_funcs[4][2] = { + { /* GL_UNSIGNED_INT_2_10_10_10_REV */ + (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_uscaled, + (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_unorm, + }, + { /* GL_UNSIGNED_BYTE */ + 0, + (attrib_func)_mesa_wrapped_VertexAttribP4_bgra8_unorm, + }, + {0}, /* unused (2) */ + { /* GL_INT_2_10_10_10_REV */ + (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_sscaled, + (attrib_func)_mesa_wrapped_VertexAttribP4_bgr10a2_snorm, + } +}; + +/* + * Return VertexAttrib*NV function pointer matching the provided vertex format. + */ +static inline attrib_func +get_legacy_func(union gl_vertex_format_user format) +{ + if (format.Bgra) + return legacy_bgra_attrib_funcs[format.Type & 0x3][format.Normalized]; + + int type = format.Type & 0x3f; + + assert(type < ARRAY_SIZE(legacy_rgba_attrib_funcs)); + return legacy_rgba_attrib_funcs[type][format.Normalized][format.Size - 1]; +} + +/* + * Return VertexAttrib*ARB function pointer matching the provided vertex format. + */ +static inline attrib_func +get_generic_func(union gl_vertex_format_user format) +{ + if (format.Bgra) + return generic_bgra_attrib_funcs[format.Type & 0x3][format.Normalized]; + + int type = (format.Type & 0x3f) | ((int)format.Doubles << 5); + int mod = format.Integer * 2 + format.Normalized; + + assert(type < ARRAY_SIZE(generic_rgba_attrib_funcs)); + return generic_rgba_attrib_funcs[type][mod][format.Size - 1]; +} + +static inline const uint8_t * +attrib_addr(const struct glthread_vao *vao, + const struct glthread_attrib *array) +{ + return (const uint8_t*)vao->Attrib[array->BufferIndex].Pointer + + array->RelativeOffset; +} + +static inline unsigned +attrib_stride(const struct glthread_vao *vao, + const struct glthread_attrib *array) +{ + return vao->Attrib[array->BufferIndex].Stride; +} + +struct attrib_info { + attrib_func marshal; /* glVertex4fv, etc. */ + const uint8_t *ptr; /* vertex array pointer at the first vertex */ + uint16_t stride; + uint8_t attrib; /* VERT_ATTRIB_* */ +}; + +/** + * Convert glDrawElements into glBegin/End. + * + * We use this when we need to upload non-VBO vertices and the vertex range + * to upload is much greater than the draw vertex count, which would cause + * the upload to take too much time. We can get better performance if we + * read each vertex from user memory and push it through glBegin/End. + * + * This assumes: No buffer objects, no instancing, no primitive restart. + */ +void +_mesa_glthread_UnrollDrawElements(struct gl_context *ctx, + GLenum mode, GLsizei count, GLenum type, + const GLvoid *indices, GLint basevertex) +{ + /* First gather all glVertex(Attrib) function pointers and attribute + * information, and then execute them between glBegin/End for every vertex. + */ + const struct glthread_vao *vao = ctx->GLThread.CurrentVAO; + struct attrib_info attribs[VERT_ATTRIB_MAX]; + unsigned num_attribs = 0; + + /* Gather glColor, glTexCoord etc. functions for non-generic attributes. */ + GLbitfield mask = (VERT_BIT_FF_ALL & ~VERT_BIT_POS) & vao->Enabled; + while (mask) { + const gl_vert_attrib attrib = u_bit_scan(&mask); + struct attrib_info *info = &attribs[num_attribs]; + const struct glthread_attrib *attr = &vao->Attrib[attrib]; + + info->marshal = get_legacy_func(attr->Format); + info->attrib = attrib; + info->ptr = attrib_addr(vao, attr); + info->stride = attrib_stride(vao, attr); + num_attribs++; + } + + /* Gather glVertexAttrib functions for generic attributes. */ + mask = (VERT_BIT_GENERIC_ALL & ~VERT_BIT_GENERIC0) & vao->Enabled; + while (mask) { + const gl_vert_attrib attrib = u_bit_scan(&mask); + struct attrib_info *info = &attribs[num_attribs]; + const struct glthread_attrib *attr = &vao->Attrib[attrib]; + + info->marshal = get_generic_func(attr->Format); + info->attrib = attrib - VERT_ATTRIB_GENERIC0; + info->ptr = attrib_addr(vao, attr); + info->stride = attrib_stride(vao, attr); + num_attribs++; + } + + /* Finally, vertex position. */ + if (vao->Enabled & VERT_BIT_GENERIC0) { + struct attrib_info *info = &attribs[num_attribs]; + const struct glthread_attrib *attr = + &vao->Attrib[VERT_ATTRIB_GENERIC0]; + + info->marshal = get_generic_func(attr->Format); + info->attrib = 0; + info->ptr = attrib_addr(vao, attr); + info->stride = attrib_stride(vao, attr); + num_attribs++; + } else if (vao->Enabled & VERT_BIT_POS) { + struct attrib_info *info = &attribs[num_attribs]; + const struct glthread_attrib *attr = + &vao->Attrib[VERT_ATTRIB_POS]; + + info->marshal = get_legacy_func(attr->Format); + info->attrib = VERT_ATTRIB_POS; + info->ptr = attrib_addr(vao, attr); + info->stride = attrib_stride(vao, attr); + num_attribs++; + } + + /* Convert the draw into glBegin/End. */ + _mesa_marshal_Begin(mode); + + switch (type) { + case GL_UNSIGNED_BYTE: { + const uint8_t *ub = indices; + for (int i = 0; i < count; i++) { + for (unsigned a = 0; a < num_attribs; a++) { + struct attrib_info *info = &attribs[a]; + unsigned index = ub[i] + basevertex; + + info->marshal(info->attrib, info->ptr + info->stride * index); + } + } + break; + } + case GL_UNSIGNED_SHORT: { + const uint16_t *us = indices; + for (int i = 0; i < count; i++) { + for (unsigned a = 0; a < num_attribs; a++) { + struct attrib_info *info = &attribs[a]; + unsigned index = us[i] + basevertex; + + info->marshal(info->attrib, info->ptr + info->stride * index); + } + } + break; + } + case GL_UNSIGNED_INT: { + const uint32_t *ui = indices; + for (int i = 0; i < count; i++) { + for (unsigned a = 0; a < num_attribs; a++) { + struct attrib_info *info = &attribs[a]; + unsigned index = ui[i] + basevertex; + + info->marshal(info->attrib, info->ptr + info->stride * index); + } + } + break; + } + } + + _mesa_marshal_End(); +} diff --git a/src/mesa/main/glthread_get.c b/src/mesa/main/glthread_get.c index 34627395173..51beaedc21a 100644 --- a/src/mesa/main/glthread_get.c +++ b/src/mesa/main/glthread_get.c @@ -24,11 +24,12 @@ #include "main/glthread_marshal.h" #include "main/dispatch.h" -void +uint32_t _mesa_unmarshal_GetIntegerv(struct gl_context *ctx, - const struct marshal_cmd_GetIntegerv *cmd) + const struct marshal_cmd_GetIntegerv *restrict cmd) { unreachable("never executed"); + return 0; } void GLAPIENTRY @@ -36,18 +37,15 @@ _mesa_marshal_GetIntegerv(GLenum pname, GLint *p) { GET_CURRENT_CONTEXT(ctx); + /* This will generate GL_INVALID_OPERATION, as it should. */ + if (ctx->GLThread.inside_begin_end) + goto sync; + /* TODO: Use get_hash_params.py to return values for items containing: * - CONST( * - CONTEXT_[A-Z]*(Const */ - if (ctx->API != API_OPENGL_COMPAT) { - /* glthread only tracks these states for the compatibility profile. */ - _mesa_glthread_finish_before(ctx, "GetIntegerv"); - CALL_GetIntegerv(ctx->CurrentServerDispatch, (pname, p)); - return; - } - switch (pname) { case GL_ACTIVE_TEXTURE: *p = GL_TEXTURE0 + ctx->GLThread.ActiveTexture; @@ -59,14 +57,32 @@ _mesa_marshal_GetIntegerv(GLenum pname, GLint *p) *p = ctx->GLThread.AttribStackDepth; return; case GL_CLIENT_ACTIVE_TEXTURE: - *p = ctx->GLThread.ClientActiveTexture; + *p = GL_TEXTURE0 + ctx->GLThread.ClientActiveTexture; return; case GL_CLIENT_ATTRIB_STACK_DEPTH: *p = ctx->GLThread.ClientAttribStackTop; return; + case GL_CURRENT_PROGRAM: + *p = ctx->GLThread.CurrentProgram; + return; case GL_DRAW_INDIRECT_BUFFER_BINDING: *p = ctx->GLThread.CurrentDrawIndirectBufferName; return; + case GL_DRAW_FRAMEBUFFER_BINDING: + *p = ctx->GLThread.CurrentDrawFramebuffer; + return; + case GL_READ_FRAMEBUFFER_BINDING: + *p = ctx->GLThread.CurrentReadFramebuffer; + return; + case GL_PIXEL_PACK_BUFFER_BINDING: + *p = ctx->GLThread.CurrentPixelPackBufferName; + return; + case GL_PIXEL_UNPACK_BUFFER_BINDING: + *p = ctx->GLThread.CurrentPixelUnpackBufferName; + return; + case GL_QUERY_BUFFER_BINDING: + *p = ctx->GLThread.CurrentQueryBufferName; + return; case GL_MATRIX_MODE: *p = ctx->GLThread.MatrixMode; @@ -114,8 +130,9 @@ _mesa_marshal_GetIntegerv(GLenum pname, GLint *p) return; } +sync: _mesa_glthread_finish_before(ctx, "GetIntegerv"); - CALL_GetIntegerv(ctx->CurrentServerDispatch, (pname, p)); + CALL_GetIntegerv(ctx->Dispatch.Current, (pname, p)); } /* TODO: Implement glGetBooleanv, glGetFloatv, etc. if needed */ diff --git a/src/mesa/main/glthread_list.c b/src/mesa/main/glthread_list.c new file mode 100644 index 00000000000..46d8ee46079 --- /dev/null +++ b/src/mesa/main/glthread_list.c @@ -0,0 +1,95 @@ +/* + * Copyright © 2020 Advanced Micro Devices, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS + * IN THE SOFTWARE. + */ + +#include "c99_alloca.h" + +#include "main/glthread_marshal.h" +#include "main/dispatch.h" + +struct marshal_cmd_CallList +{ + struct marshal_cmd_base cmd_base; + uint16_t num_slots; + GLuint num; + GLuint list[]; +}; + +uint32_t +_mesa_unmarshal_CallList(struct gl_context *ctx, + const struct marshal_cmd_CallList *restrict cmd) +{ + const GLuint num = cmd->num; + + if (cmd->num_slots == sizeof(*cmd) / 8) { + CALL_CallList(ctx->Dispatch.Current, (num)); + } else { + CALL_CallLists(ctx->Dispatch.Current, (num, GL_UNSIGNED_INT, cmd->list)); + } + + return cmd->num_slots; +} + +void GLAPIENTRY +_mesa_marshal_CallList(GLuint list) +{ + GET_CURRENT_CONTEXT(ctx); + struct glthread_state *glthread = &ctx->GLThread; + struct marshal_cmd_CallList *last = glthread->LastCallList; + + _mesa_glthread_CallList(ctx, list); + + /* If the last call is CallList and there is enough space to append another list... */ + if (last && + _mesa_glthread_call_is_last(glthread, &last->cmd_base, last->num_slots) && + glthread->used + 1 <= MARSHAL_MAX_CMD_SIZE / 8) { + STATIC_ASSERT(sizeof(*last) == 8); + + /* Add the list to the last call. */ + if (last->num_slots > sizeof(*last) / 8) { + last->list[last->num++] = list; + if (last->num % 2 == 1) { + last->num_slots++; + glthread->used++; + } + } else { + /* Initially, num contains the first list. After we increase cmd_size, + * num contains the number of lists and list[] contains the lists. + */ + last->list[0] = last->num; + last->list[1] = list; + last->num = 2; + last->num_slots++; + glthread->used++; + } + assert(align(sizeof(*last) + last->num * 4, 8) / 8 == last->num_slots); + return; + } + + int cmd_size = sizeof(struct marshal_cmd_CallList); + struct marshal_cmd_CallList *cmd; + cmd = _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_CallList, cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->num = list; + + glthread->LastCallList = cmd; +} diff --git a/src/mesa/main/glthread_marshal.h b/src/mesa/main/glthread_marshal.h index c3dbebb1773..b7dbfc35f4b 100644 --- a/src/mesa/main/glthread_marshal.h +++ b/src/mesa/main/glthread_marshal.h @@ -33,7 +33,16 @@ #include "main/glthread.h" #include "main/context.h" #include "main/macros.h" -#include "marshal_generated.h" +#include "main/matrix.h" + +/* 32-bit signed integer clamped to 0..UINT16_MAX to compress parameters + * for glthread. All values < 0 and >= UINT16_MAX are expected to throw + * GL_INVALID_VALUE. Negative values are mapped to UINT16_MAX. + */ +typedef uint16_t GLpacked16i; + +/* 32-bit signed integer clamped to 16 bits. */ +typedef int16_t GLclamped16i; struct marshal_cmd_base { @@ -41,15 +50,43 @@ struct marshal_cmd_base * Type of command. See enum marshal_dispatch_cmd_id. */ uint16_t cmd_id; - - /** - * Number of uint64_t elements used by the command. - */ - uint16_t cmd_size; }; -typedef void (*_mesa_unmarshal_func)(struct gl_context *ctx, const void *cmd); +/* This must be included after "struct marshal_cmd_base" because it uses it. */ +#include "marshal_generated.h" + +typedef uint32_t (*_mesa_unmarshal_func)(struct gl_context *ctx, + const void *restrict cmd); extern const _mesa_unmarshal_func _mesa_unmarshal_dispatch[NUM_DISPATCH_CMD]; +extern const char *_mesa_unmarshal_func_name[NUM_DISPATCH_CMD]; + +struct marshal_cmd_DrawElementsUserBuf +{ + struct marshal_cmd_base cmd_base; + GLenum8 mode; + GLindextype type; + uint16_t num_slots; + GLsizei count; + GLsizei instance_count; + GLint basevertex; + GLuint baseinstance; + GLuint drawid; + GLuint user_buffer_mask; + const GLvoid *indices; + struct gl_buffer_object *index_buffer; +}; + +struct marshal_cmd_DrawElementsUserBufPacked +{ + struct marshal_cmd_base cmd_base; + GLenum8 mode; + GLindextype type; + uint16_t num_slots; + GLushort count; + GLuint user_buffer_mask; + GLuint indices; + struct gl_buffer_object *index_buffer; +}; static inline void * _mesa_glthread_allocate_command(struct gl_context *ctx, @@ -59,6 +96,8 @@ _mesa_glthread_allocate_command(struct gl_context *ctx, struct glthread_state *glthread = &ctx->GLThread; const unsigned num_elements = align(size, 8) / 8; + assert (num_elements <= MARSHAL_MAX_CMD_SIZE / 8); + if (unlikely(glthread->used + num_elements > MARSHAL_MAX_CMD_SIZE / 8)) _mesa_glthread_flush_batch(ctx); @@ -67,74 +106,48 @@ _mesa_glthread_allocate_command(struct gl_context *ctx, (struct marshal_cmd_base *)&next->buffer[glthread->used]; glthread->used += num_elements; cmd_base->cmd_id = cmd_id; - cmd_base->cmd_size = num_elements; return cmd_base; } -static inline bool -_mesa_glthread_has_no_pack_buffer(const struct gl_context *ctx) +static inline GLenum +_mesa_decode_index_type(GLindextype type) { - return ctx->GLThread.CurrentPixelPackBufferName == 0; + return (GLenum)type.value + GL_UNSIGNED_BYTE - 1; } -static inline bool -_mesa_glthread_has_no_unpack_buffer(const struct gl_context *ctx) +static inline struct marshal_cmd_base * +_mesa_glthread_get_cmd(uint64_t *opaque_cmd) { - return ctx->GLThread.CurrentPixelUnpackBufferName == 0; + return (struct marshal_cmd_base*)opaque_cmd; } -/** - * Instead of conditionally handling marshaling immediate index data in draw - * calls (deprecated and removed in GL core), we just disable threading. - */ -static inline bool -_mesa_glthread_has_non_vbo_vertices_or_indices(const struct gl_context *ctx) +static inline uint64_t * +_mesa_glthread_next_cmd(uint64_t *opaque_cmd, unsigned cmd_size) { - const struct glthread_state *glthread = &ctx->GLThread; - struct glthread_vao *vao = glthread->CurrentVAO; - - return ctx->API != API_OPENGL_CORE && - (vao->CurrentElementBufferName == 0 || - (vao->UserPointerMask & vao->BufferEnabled)); + return opaque_cmd + cmd_size; } static inline bool -_mesa_glthread_has_non_vbo_vertices(const struct gl_context *ctx) +_mesa_glthread_call_is_last(struct glthread_state *glthread, + struct marshal_cmd_base *last, uint16_t num_slots) { - const struct glthread_state *glthread = &ctx->GLThread; - const struct glthread_vao *vao = glthread->CurrentVAO; - - return ctx->API != API_OPENGL_CORE && - (vao->UserPointerMask & vao->BufferEnabled); + return last && + (uint64_t*)last + num_slots == + &glthread->next_batch->buffer[glthread->used]; } static inline bool -_mesa_glthread_has_non_vbo_vertices_or_indirect(const struct gl_context *ctx) +_mesa_glthread_has_pack_buffer(const struct gl_context *ctx) { - const struct glthread_state *glthread = &ctx->GLThread; - const struct glthread_vao *vao = glthread->CurrentVAO; - - return ctx->API != API_OPENGL_CORE && - (glthread->CurrentDrawIndirectBufferName == 0 || - (vao->UserPointerMask & vao->BufferEnabled)); + return ctx->GLThread.CurrentPixelPackBufferName != 0; } static inline bool -_mesa_glthread_has_non_vbo_vertices_or_indices_or_indirect(const struct gl_context *ctx) +_mesa_glthread_has_unpack_buffer(const struct gl_context *ctx) { - const struct glthread_state *glthread = &ctx->GLThread; - struct glthread_vao *vao = glthread->CurrentVAO; - - return ctx->API != API_OPENGL_CORE && - (glthread->CurrentDrawIndirectBufferName == 0 || - vao->CurrentElementBufferName == 0 || - (vao->UserPointerMask & vao->BufferEnabled)); + return ctx->GLThread.CurrentPixelUnpackBufferName != 0; } - -struct _glapi_table * -_mesa_create_marshal_table(const struct gl_context *ctx); - static inline unsigned _mesa_buffer_enum_to_count(GLenum buffer) { @@ -180,6 +193,9 @@ _mesa_tex_param_enum_to_count(GLenum pname) case GL_TEXTURE_MAX_ANISOTROPY_EXT: case GL_TEXTURE_LOD_BIAS: case GL_TEXTURE_TILING_EXT: + case GL_TEXTURE_SPARSE_ARB: + case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB: + case GL_NUM_SPARSE_LEVELS_ARB: return 1; case GL_TEXTURE_CROP_RECT_OES: case GL_TEXTURE_SWIZZLE_RGBA: @@ -442,11 +458,43 @@ _mesa_glthread_Enable(struct gl_context *ctx, GLenum cap) if (ctx->GLThread.ListMode == GL_COMPILE) return; - if (cap == GL_PRIMITIVE_RESTART || - cap == GL_PRIMITIVE_RESTART_FIXED_INDEX) + switch (cap) { + case GL_PRIMITIVE_RESTART: + case GL_PRIMITIVE_RESTART_FIXED_INDEX: _mesa_glthread_set_prim_restart(ctx, cap, true); - else if (cap == GL_DEBUG_OUTPUT_SYNCHRONOUS_ARB) - _mesa_glthread_disable(ctx, "Enable(DEBUG_OUTPUT_SYNCHRONOUS)"); + break; + case GL_BLEND: + ctx->GLThread.Blend = true; + break; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + _mesa_glthread_disable(ctx); + ctx->GLThread.DebugOutputSynchronous = true; + break; + case GL_DEPTH_TEST: + ctx->GLThread.DepthTest = true; + break; + case GL_CULL_FACE: + ctx->GLThread.CullFace = true; + break; + case GL_LIGHTING: + ctx->GLThread.Lighting = true; + break; + case GL_POLYGON_STIPPLE: + ctx->GLThread.PolygonStipple = true; + break; + case GL_VERTEX_ARRAY: + case GL_NORMAL_ARRAY: + case GL_COLOR_ARRAY: + case GL_TEXTURE_COORD_ARRAY: + case GL_INDEX_ARRAY: + case GL_EDGE_FLAG_ARRAY: + case GL_FOG_COORDINATE_ARRAY: + case GL_SECONDARY_COLOR_ARRAY: + case GL_POINT_SIZE_ARRAY_OES: + _mesa_glthread_ClientState(ctx, NULL, _mesa_array_to_attrib(ctx, cap), + true); + break; + } } static inline void @@ -455,9 +503,77 @@ _mesa_glthread_Disable(struct gl_context *ctx, GLenum cap) if (ctx->GLThread.ListMode == GL_COMPILE) return; - if (cap == GL_PRIMITIVE_RESTART || - cap == GL_PRIMITIVE_RESTART_FIXED_INDEX) + switch (cap) { + case GL_PRIMITIVE_RESTART: + case GL_PRIMITIVE_RESTART_FIXED_INDEX: _mesa_glthread_set_prim_restart(ctx, cap, false); + break; + case GL_BLEND: + ctx->GLThread.Blend = false; + break; + case GL_CULL_FACE: + ctx->GLThread.CullFace = false; + break; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + ctx->GLThread.DebugOutputSynchronous = false; + _mesa_glthread_enable(ctx); + break; + case GL_DEPTH_TEST: + ctx->GLThread.DepthTest = false; + break; + case GL_LIGHTING: + ctx->GLThread.Lighting = false; + break; + case GL_POLYGON_STIPPLE: + ctx->GLThread.PolygonStipple = false; + break; + case GL_VERTEX_ARRAY: + case GL_NORMAL_ARRAY: + case GL_COLOR_ARRAY: + case GL_TEXTURE_COORD_ARRAY: + case GL_INDEX_ARRAY: + case GL_EDGE_FLAG_ARRAY: + case GL_FOG_COORDINATE_ARRAY: + case GL_SECONDARY_COLOR_ARRAY: + case GL_POINT_SIZE_ARRAY_OES: + _mesa_glthread_ClientState(ctx, NULL, _mesa_array_to_attrib(ctx, cap), + false); + break; + } +} + +static inline int +_mesa_glthread_IsEnabled(struct gl_context *ctx, GLenum cap) +{ + /* This will generate GL_INVALID_OPERATION, as it should. */ + if (ctx->GLThread.inside_begin_end) + return -1; + + switch (cap) { + case GL_BLEND: + return ctx->GLThread.Blend; + case GL_CULL_FACE: + return ctx->GLThread.CullFace; + case GL_DEBUG_OUTPUT_SYNCHRONOUS: + return ctx->GLThread.DebugOutputSynchronous; + case GL_DEPTH_TEST: + return ctx->GLThread.DepthTest; + case GL_LIGHTING: + return ctx->GLThread.Lighting; + case GL_POLYGON_STIPPLE: + return ctx->GLThread.PolygonStipple; + case GL_VERTEX_ARRAY: + return !!(ctx->GLThread.CurrentVAO->UserEnabled & VERT_BIT_POS); + case GL_NORMAL_ARRAY: + return !!(ctx->GLThread.CurrentVAO->UserEnabled & VERT_BIT_NORMAL); + case GL_COLOR_ARRAY: + return !!(ctx->GLThread.CurrentVAO->UserEnabled & VERT_BIT_COLOR0); + case GL_TEXTURE_COORD_ARRAY: + return !!(ctx->GLThread.CurrentVAO->UserEnabled & + (1 << VERT_ATTRIB_TEX(ctx->GLThread.ClientActiveTexture))); + default: + return -1; /* sync and call _mesa_IsEnabled. */ + } } static inline void @@ -466,11 +582,28 @@ _mesa_glthread_PushAttrib(struct gl_context *ctx, GLbitfield mask) if (ctx->GLThread.ListMode == GL_COMPILE) return; + if (ctx->GLThread.AttribStackDepth >= MAX_ATTRIB_STACK_DEPTH) + return; + struct glthread_attrib_node *attr = &ctx->GLThread.AttribStack[ctx->GLThread.AttribStackDepth++]; attr->Mask = mask; + if (mask & GL_ENABLE_BIT) + attr->Blend = ctx->GLThread.Blend; + + if (mask & (GL_POLYGON_BIT | GL_ENABLE_BIT)) { + attr->CullFace = ctx->GLThread.CullFace; + attr->PolygonStipple = ctx->GLThread.PolygonStipple; + } + + if (mask & (GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT)) + attr->DepthTest = ctx->GLThread.DepthTest; + + if (mask & (GL_LIGHTING_BIT | GL_ENABLE_BIT)) + attr->Lighting = ctx->GLThread.Lighting; + if (mask & GL_TEXTURE_BIT) attr->ActiveTexture = ctx->GLThread.ActiveTexture; @@ -484,10 +617,27 @@ _mesa_glthread_PopAttrib(struct gl_context *ctx) if (ctx->GLThread.ListMode == GL_COMPILE) return; + if (ctx->GLThread.AttribStackDepth == 0) + return; + struct glthread_attrib_node *attr = &ctx->GLThread.AttribStack[--ctx->GLThread.AttribStackDepth]; unsigned mask = attr->Mask; + if (mask & GL_ENABLE_BIT) + ctx->GLThread.Blend = attr->Blend; + + if (mask & (GL_POLYGON_BIT | GL_ENABLE_BIT)) { + ctx->GLThread.CullFace = attr->CullFace; + ctx->GLThread.PolygonStipple = attr->PolygonStipple; + } + + if (mask & (GL_DEPTH_BUFFER_BIT | GL_ENABLE_BIT)) + ctx->GLThread.DepthTest = attr->DepthTest; + + if (mask & (GL_LIGHTING_BIT | GL_ENABLE_BIT)) + ctx->GLThread.Lighting = attr->Lighting; + if (mask & GL_TEXTURE_BIT) ctx->GLThread.ActiveTexture = attr->ActiveTexture; @@ -497,12 +647,36 @@ _mesa_glthread_PopAttrib(struct gl_context *ctx) } } +static bool +is_matrix_stack_full(struct gl_context *ctx, gl_matrix_index idx) +{ + int max_stack_depth = 0; + if (M_MODELVIEW == ctx->GLThread.MatrixIndex) { + max_stack_depth = MAX_MODELVIEW_STACK_DEPTH; + } else if (M_PROJECTION == ctx->GLThread.MatrixIndex) { + max_stack_depth = MAX_PROJECTION_STACK_DEPTH; + } else if (M_PROGRAM_LAST >= ctx->GLThread.MatrixIndex) { + max_stack_depth = MAX_PROGRAM_MATRIX_STACK_DEPTH; + } else if (M_TEXTURE_LAST >= ctx->GLThread.MatrixIndex) { + max_stack_depth = MAX_TEXTURE_STACK_DEPTH; + } + assert(max_stack_depth); + + if (ctx->GLThread.MatrixStackDepth[idx] + 1 >= max_stack_depth) + return true; + + return false; +} + static inline void _mesa_glthread_MatrixPushEXT(struct gl_context *ctx, GLenum matrixMode) { if (ctx->GLThread.ListMode == GL_COMPILE) return; + if (is_matrix_stack_full(ctx, _mesa_get_matrix_index(ctx, matrixMode))) + return; + ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]++; } @@ -512,6 +686,9 @@ _mesa_glthread_MatrixPopEXT(struct gl_context *ctx, GLenum matrixMode) if (ctx->GLThread.ListMode == GL_COMPILE) return; + if (ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)] == 0) + return; + ctx->GLThread.MatrixStackDepth[_mesa_get_matrix_index(ctx, matrixMode)]--; } @@ -532,6 +709,9 @@ _mesa_glthread_PushMatrix(struct gl_context *ctx) if (ctx->GLThread.ListMode == GL_COMPILE) return; + if (is_matrix_stack_full(ctx, ctx->GLThread.MatrixIndex)) + return; + ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]++; } @@ -541,6 +721,9 @@ _mesa_glthread_PopMatrix(struct gl_context *ctx) if (ctx->GLThread.ListMode == GL_COMPILE) return; + if (ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex] == 0) + return; + ctx->GLThread.MatrixStackDepth[ctx->GLThread.MatrixIndex]--; } @@ -551,7 +734,7 @@ _mesa_glthread_MatrixMode(struct gl_context *ctx, GLenum mode) return; ctx->GLThread.MatrixIndex = _mesa_get_matrix_index(ctx, mode); - ctx->GLThread.MatrixMode = mode; + ctx->GLThread.MatrixMode = MIN2(mode, 0xffff); } static inline void @@ -564,6 +747,39 @@ _mesa_glthread_ListBase(struct gl_context *ctx, GLuint base) } static inline void +_mesa_glthread_init_call_fence(int *last_batch_index_where_called) +{ + *last_batch_index_where_called = -1; +} + +static inline void +_mesa_glthread_fence_call(struct gl_context *ctx, + int *last_batch_index_where_called) +{ + p_atomic_set(last_batch_index_where_called, ctx->GLThread.next); + /* Flush, so that the fenced call is last in the batch. */ + _mesa_glthread_flush_batch(ctx); +} + +static inline void +_mesa_glthread_signal_call(int *last_batch_index_where_called, int batch_index) +{ + /* Atomically set this to -1 if it's equal to batch_index. */ + p_atomic_cmpxchg(last_batch_index_where_called, batch_index, -1); +} + +static inline void +_mesa_glthread_wait_for_call(struct gl_context *ctx, + int *last_batch_index_where_called) +{ + int batch = p_atomic_read(last_batch_index_where_called); + if (batch != -1) { + util_queue_fence_wait(&ctx->GLThread.batches[batch].fence); + assert(p_atomic_read(last_batch_index_where_called) == -1); + } +} + +static inline void _mesa_glthread_CallList(struct gl_context *ctx, GLuint list) { if (ctx->GLThread.ListMode == GL_COMPILE) @@ -573,11 +789,10 @@ _mesa_glthread_CallList(struct gl_context *ctx, GLuint list) * all display lists are up to date and the driver thread is not * modifiying them. We will be executing them in the application thread. */ - int batch = p_atomic_read(&ctx->GLThread.LastDListChangeBatchIndex); - if (batch != -1) { - util_queue_fence_wait(&ctx->GLThread.batches[batch].fence); - p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, -1); - } + _mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex); + + if (!ctx->Shared->DisplayListsAffectGLThread) + return; /* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */ unsigned saved_mode = ctx->GLThread.ListMode; @@ -602,11 +817,7 @@ _mesa_glthread_CallLists(struct gl_context *ctx, GLsizei n, GLenum type, * all display lists are up to date and the driver thread is not * modifiying them. We will be executing them in the application thread. */ - int batch = p_atomic_read(&ctx->GLThread.LastDListChangeBatchIndex); - if (batch != -1) { - util_queue_fence_wait(&ctx->GLThread.batches[batch].fence); - p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, -1); - } + _mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex); /* Clear GL_COMPILE_AND_EXECUTE if needed. We only execute here. */ unsigned saved_mode = ctx->GLThread.ListMode; @@ -691,10 +902,10 @@ _mesa_glthread_CallLists(struct gl_context *ctx, GLsizei n, GLenum type, } static inline void -_mesa_glthread_NewList(struct gl_context *ctx, GLuint list, GLuint mode) +_mesa_glthread_NewList(struct gl_context *ctx, GLuint list, GLenum mode) { if (!ctx->GLThread.ListMode) - ctx->GLThread.ListMode = mode; + ctx->GLThread.ListMode = MIN2(mode, 0xffff); } static inline void @@ -706,8 +917,7 @@ _mesa_glthread_EndList(struct gl_context *ctx) ctx->GLThread.ListMode = 0; /* Track the last display list change. */ - p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next); - _mesa_glthread_flush_batch(ctx); + _mesa_glthread_fence_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex); } static inline void @@ -717,8 +927,38 @@ _mesa_glthread_DeleteLists(struct gl_context *ctx, GLsizei range) return; /* Track the last display list change. */ - p_atomic_set(&ctx->GLThread.LastDListChangeBatchIndex, ctx->GLThread.next); - _mesa_glthread_flush_batch(ctx); + _mesa_glthread_fence_call(ctx, &ctx->GLThread.LastDListChangeBatchIndex); +} + +static inline void +_mesa_glthread_BindFramebuffer(struct gl_context *ctx, GLenum target, GLuint id) +{ + switch (target) { + case GL_FRAMEBUFFER: + ctx->GLThread.CurrentDrawFramebuffer = id; + ctx->GLThread.CurrentReadFramebuffer = id; + break; + case GL_DRAW_FRAMEBUFFER: + ctx->GLThread.CurrentDrawFramebuffer = id; + break; + case GL_READ_FRAMEBUFFER: + ctx->GLThread.CurrentReadFramebuffer = id; + break; + } +} + +static inline void +_mesa_glthread_DeleteFramebuffers(struct gl_context *ctx, GLsizei n, + const GLuint *ids) +{ + if (ctx->GLThread.CurrentDrawFramebuffer) { + for (int i = 0; i < n; i++) { + if (ctx->GLThread.CurrentDrawFramebuffer == ids[i]) + ctx->GLThread.CurrentDrawFramebuffer = 0; + if (ctx->GLThread.CurrentReadFramebuffer == ids[i]) + ctx->GLThread.CurrentReadFramebuffer = 0; + } + } } #endif /* MARSHAL_H */ diff --git a/src/mesa/main/glthread_pixels.c b/src/mesa/main/glthread_pixels.c new file mode 100644 index 00000000000..5f4836b1cdb --- /dev/null +++ b/src/mesa/main/glthread_pixels.c @@ -0,0 +1,162 @@ +/* + * Copyright 2024 Advanced Micro Devices, Inc. + * + * SPDX-License-Identifier: MIT + */ + +#include "main/glthread_marshal.h" +#include "main/dispatch.h" +#include "main/image.h" + +#define MAX_BITMAP_BYTE_SIZE 4096 +#define MAX_DRAWPIX_BYTE_SIZE 4096 + +struct marshal_cmd_Bitmap +{ + struct marshal_cmd_base cmd_base; + uint16_t num_slots; + GLsizei width; + GLsizei height; + GLfloat xorig; + GLfloat yorig; + GLfloat xmove; + GLfloat ymove; + GLubyte *bitmap; +}; + +uint32_t +_mesa_unmarshal_Bitmap(struct gl_context *ctx, + const struct marshal_cmd_Bitmap *restrict cmd) +{ + CALL_Bitmap(ctx->Dispatch.Current, + (cmd->width, cmd->height, cmd->xorig, cmd->yorig, cmd->xmove, + cmd->ymove, cmd->bitmap)); + return cmd->num_slots; +} + +void GLAPIENTRY +_mesa_marshal_Bitmap(GLsizei width, GLsizei height, GLfloat xorig, + GLfloat yorig, GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap) +{ + GET_CURRENT_CONTEXT(ctx); + int cmd_size = sizeof(struct marshal_cmd_Bitmap); + + /* If not building a display list... */ + if (!ctx->GLThread.ListMode) { + /* PBO path or bitmap == NULL (which means xmove/ymove only move the raster + * pos. + */ + if (!bitmap || _mesa_glthread_has_unpack_buffer(ctx)) { + struct marshal_cmd_Bitmap *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Bitmap, + cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->width = width; + cmd->height = height; + cmd->xorig = xorig; + cmd->yorig = yorig; + cmd->xmove = xmove; + cmd->ymove = ymove; + cmd->bitmap = (GLubyte *)bitmap; + return; + } + + size_t bitmap_size = + (size_t)_mesa_image_row_stride(&ctx->GLThread.Unpack, width, + GL_COLOR_INDEX, GL_BITMAP) * height; + + /* If the bitmap is small enough, copy it into the batch. */ + if (bitmap_size <= MAX_BITMAP_BYTE_SIZE) { + struct marshal_cmd_Bitmap *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_Bitmap, + cmd_size + bitmap_size); + cmd->num_slots = align(cmd_size + bitmap_size, 8) / 8; + cmd->width = width; + cmd->height = height; + cmd->xorig = xorig; + cmd->yorig = yorig; + cmd->xmove = xmove; + cmd->ymove = ymove; + cmd->bitmap = (GLubyte *)(cmd + 1); + memcpy(cmd->bitmap, bitmap, bitmap_size); + return; + } + } + + _mesa_glthread_finish_before(ctx, "Bitmap"); + CALL_Bitmap(ctx->Dispatch.Current, + (width, height, xorig, yorig, xmove, ymove, bitmap)); +} + +struct marshal_cmd_DrawPixels +{ + struct marshal_cmd_base cmd_base; + uint16_t num_slots; + GLenum16 format; + GLenum16 type; + GLsizei width; + GLsizei height; + GLvoid *pixels; +}; + +uint32_t +_mesa_unmarshal_DrawPixels(struct gl_context *ctx, + const struct marshal_cmd_DrawPixels *restrict cmd) +{ + CALL_DrawPixels(ctx->Dispatch.Current, + (cmd->width, cmd->height, cmd->format, cmd->type, + cmd->pixels)); + return cmd->num_slots; +} + +void GLAPIENTRY +_mesa_marshal_DrawPixels(GLsizei width, GLsizei height, GLenum format, + GLenum type, const GLvoid *pixels) +{ + GET_CURRENT_CONTEXT(ctx); + int cmd_size = sizeof(struct marshal_cmd_DrawPixels); + + /* If not building a display list... */ + if (!ctx->GLThread.ListMode) { + /* PBO */ + if (_mesa_glthread_has_unpack_buffer(ctx)) { + struct marshal_cmd_DrawPixels *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawPixels, + cmd_size); + cmd->num_slots = align(cmd_size, 8) / 8; + cmd->format = MIN2(format, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->width = width; + cmd->height = height; + cmd->pixels = (void *)pixels; + return; + } + + /* A negative stride is unimplemented (it inverts the offset). */ + if (!ctx->Unpack.Invert) { + size_t image_size = + (size_t)_mesa_image_row_stride(&ctx->GLThread.Unpack, + width, format, type) * height; + + /* If the image is small enough, copy it into the batch. */ + if (image_size <= MAX_DRAWPIX_BYTE_SIZE) { + struct marshal_cmd_DrawPixels *cmd = + _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_DrawPixels, + cmd_size + image_size); + cmd->num_slots = align(cmd_size + image_size, 8) / 8; + cmd->format = MIN2(format, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->type = MIN2(type, 0xffff); /* clamped to 0xffff (invalid enum) */ + cmd->width = width; + cmd->height = height; + cmd->pixels = cmd + 1; + memcpy(cmd->pixels, pixels, image_size); + return; + } + } + } + + _mesa_glthread_finish_before(ctx, "DrawPixels"); + CALL_DrawPixels(ctx->Dispatch.Current, + (width, height, format, type, pixels)); +} diff --git a/src/mesa/main/glthread_shaderobj.c b/src/mesa/main/glthread_shaderobj.c index 7c47860390c..d994958d7d0 100644 --- a/src/mesa/main/glthread_shaderobj.c +++ b/src/mesa/main/glthread_shaderobj.c @@ -24,112 +24,30 @@ #include "glthread_marshal.h" #include "dispatch.h" #include "uniforms.h" - -struct marshal_cmd_ShaderSource -{ - struct marshal_cmd_base cmd_base; - GLuint shader; - GLsizei count; - /* Followed by GLint length[count], then the contents of all strings, - * concatenated. - */ -}; - - -void -_mesa_unmarshal_ShaderSource(struct gl_context *ctx, - const struct marshal_cmd_ShaderSource *cmd) -{ - const GLint *cmd_length = (const GLint *) (cmd + 1); - const GLchar *cmd_strings = (const GLchar *) (cmd_length + cmd->count); - /* TODO: how to deal with malloc failure? */ - const GLchar * *string = malloc(cmd->count * sizeof(const GLchar *)); - int i; - - for (i = 0; i < cmd->count; ++i) { - string[i] = cmd_strings; - cmd_strings += cmd_length[i]; - } - CALL_ShaderSource(ctx->CurrentServerDispatch, - (cmd->shader, cmd->count, string, cmd_length)); - free((void *)string); -} - - -static size_t -measure_ShaderSource_strings(GLsizei count, const GLchar * const *string, - const GLint *length_in, GLint *length_out) -{ - int i; - size_t total_string_length = 0; - - for (i = 0; i < count; ++i) { - if (length_in == NULL || length_in[i] < 0) { - if (string[i]) - length_out[i] = strlen(string[i]); - } else { - length_out[i] = length_in[i]; - } - total_string_length += length_out[i]; - } - return total_string_length; -} - - -void GLAPIENTRY -_mesa_marshal_ShaderSource(GLuint shader, GLsizei count, - const GLchar * const *string, const GLint *length) -{ - /* TODO: how to report an error if count < 0? */ - - GET_CURRENT_CONTEXT(ctx); - /* TODO: how to deal with malloc failure? */ - const size_t fixed_cmd_size = sizeof(struct marshal_cmd_ShaderSource); - STATIC_ASSERT(sizeof(struct marshal_cmd_ShaderSource) % sizeof(GLint) == 0); - size_t length_size = count * sizeof(GLint); - GLint *length_tmp = malloc(length_size); - size_t total_string_length = - measure_ShaderSource_strings(count, string, length, length_tmp); - size_t total_cmd_size = fixed_cmd_size + length_size + total_string_length; - - if (total_cmd_size <= MARSHAL_MAX_CMD_SIZE && count > 0) { - struct marshal_cmd_ShaderSource *cmd = - _mesa_glthread_allocate_command(ctx, DISPATCH_CMD_ShaderSource, - total_cmd_size); - GLint *cmd_length = (GLint *) (cmd + 1); - GLchar *cmd_strings = (GLchar *) (cmd_length + count); - int i; - - cmd->shader = shader; - cmd->count = count; - memcpy(cmd_length, length_tmp, length_size); - for (i = 0; i < count; ++i) { - memcpy(cmd_strings, string[i], cmd_length[i]); - cmd_strings += cmd_length[i]; - } - } else { - _mesa_glthread_finish(ctx); - CALL_ShaderSource(ctx->CurrentServerDispatch, - (shader, count, string, length_tmp)); - } - free(length_tmp); -} +#include "api_exec_decl.h" void _mesa_glthread_ProgramChanged(struct gl_context *ctx) { struct glthread_state *glthread = &ctx->GLThread; - /* Track the last change. */ - p_atomic_set(&glthread->LastProgramChangeBatch, glthread->next); - _mesa_glthread_flush_batch(ctx); + /* Track the last change to shader programs. */ + _mesa_glthread_fence_call(ctx, &glthread->LastProgramChangeBatch); } -void +uint32_t _mesa_unmarshal_GetActiveUniform(struct gl_context *ctx, - const struct marshal_cmd_GetActiveUniform *cmd) + const struct marshal_cmd_GetActiveUniform *restrict cmd) { unreachable("never executed"); + return 0; +} + +static void +wait_for_glLinkProgram(struct gl_context *ctx) +{ + /* Wait for the last glLinkProgram call. */ + _mesa_glthread_wait_for_call(ctx, &ctx->GLThread.LastProgramChangeBatch); } void GLAPIENTRY @@ -139,13 +57,17 @@ _mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, { GET_CURRENT_CONTEXT(ctx); - /* Wait for the last glLinkProgram call. */ - int batch = p_atomic_read(&ctx->GLThread.LastProgramChangeBatch); - if (batch != -1) { - util_queue_fence_wait(&ctx->GLThread.batches[batch].fence); - assert(p_atomic_read(&ctx->GLThread.LastProgramChangeBatch) == -1); + /* This will generate GL_INVALID_OPERATION, as it should. */ + if (ctx->GLThread.inside_begin_end) { + _mesa_glthread_finish_before(ctx, "GetActiveUniform"); + CALL_GetActiveUniform(ctx->Dispatch.Current, + (program, index, bufSize, length, size, type, + name)); + return; } + wait_for_glLinkProgram(ctx); + /* We can execute glGetActiveUniform without syncing if we are sync'd to * the last calls of glLinkProgram and glDeleteProgram because shader * object IDs and their contents are immutable after those calls and @@ -156,3 +78,28 @@ _mesa_marshal_GetActiveUniform(GLuint program, GLuint index, GLsizei bufSize, _mesa_GetActiveUniform_impl(program, index, bufSize, length, size, type, name, true); } + +uint32_t +_mesa_unmarshal_GetUniformLocation(struct gl_context *ctx, + const struct marshal_cmd_GetUniformLocation *restrict cmd) +{ + unreachable("never executed"); + return 0; +} + +GLint GLAPIENTRY +_mesa_marshal_GetUniformLocation(GLuint program, const GLchar *name) +{ + GET_CURRENT_CONTEXT(ctx); + + /* This will generate GL_INVALID_OPERATION, as it should. */ + if (ctx->GLThread.inside_begin_end) { + _mesa_glthread_finish_before(ctx, "GetUniformLocation"); + return CALL_GetUniformLocation(ctx->Dispatch.Current, (program, name)); + } + + wait_for_glLinkProgram(ctx); + + /* This is thread-safe. See the comment in _mesa_marshal_GetActiveUniform. */ + return _mesa_GetUniformLocation_impl(program, name, true); +} diff --git a/src/mesa/main/glthread_varray.c b/src/mesa/main/glthread_varray.c index f4f2bde2158..61ccfd202b1 100644 --- a/src/mesa/main/glthread_varray.c +++ b/src/mesa/main/glthread_varray.c @@ -33,38 +33,60 @@ #include "main/dispatch.h" #include "main/varray.h" +static unsigned +element_size(union gl_vertex_format_user format) +{ + return _mesa_bytes_per_vertex_attrib(format.Size, format.Type); +} + +static void +init_attrib(struct glthread_attrib *attrib, int index, int size, GLenum type) +{ + attrib->Format = MESA_PACK_VFORMAT(type, size, 0, 0, 0); + attrib->ElementSize = element_size(attrib->Format); + attrib->RelativeOffset = 0; + attrib->BufferIndex = index; + attrib->Stride = attrib->ElementSize; + attrib->Divisor = 0; + attrib->EnabledAttribCount = 0; + attrib->Pointer = NULL; +} void _mesa_glthread_reset_vao(struct glthread_vao *vao) { - static unsigned default_elem_size[VERT_ATTRIB_MAX] = { - [VERT_ATTRIB_NORMAL] = 12, - [VERT_ATTRIB_COLOR1] = 12, - [VERT_ATTRIB_FOG] = 4, - [VERT_ATTRIB_COLOR_INDEX] = 4, - [VERT_ATTRIB_EDGEFLAG] = 1, - [VERT_ATTRIB_POINT_SIZE] = 4, - }; - vao->CurrentElementBufferName = 0; vao->UserEnabled = 0; vao->Enabled = 0; vao->BufferEnabled = 0; vao->UserPointerMask = 0; + vao->NonNullPointerMask = 0; vao->NonZeroDivisorMask = 0; for (unsigned i = 0; i < ARRAY_SIZE(vao->Attrib); i++) { - unsigned elem_size = default_elem_size[i]; - if (!elem_size) - elem_size = 16; - - vao->Attrib[i].ElementSize = elem_size; - vao->Attrib[i].RelativeOffset = 0; - vao->Attrib[i].BufferIndex = i; - vao->Attrib[i].Stride = elem_size; - vao->Attrib[i].Divisor = 0; - vao->Attrib[i].EnabledAttribCount = 0; - vao->Attrib[i].Pointer = NULL; + switch (i) { + case VERT_ATTRIB_NORMAL: + init_attrib(&vao->Attrib[i], i, 3, GL_FLOAT); + break; + case VERT_ATTRIB_COLOR1: + init_attrib(&vao->Attrib[i], i, 3, GL_FLOAT); + break; + case VERT_ATTRIB_FOG: + init_attrib(&vao->Attrib[i], i, 1, GL_FLOAT); + break; + case VERT_ATTRIB_COLOR_INDEX: + init_attrib(&vao->Attrib[i], i, 1, GL_FLOAT); + break; + case VERT_ATTRIB_EDGEFLAG: + init_attrib(&vao->Attrib[i], i, 1, GL_UNSIGNED_BYTE); + break; + case VERT_ATTRIB_POINT_SIZE: + init_attrib(&vao->Attrib[i], i, 1, GL_FLOAT); + break; + default: + init_attrib(&vao->Attrib[i], i, 4, GL_FLOAT); + break; + } } } @@ -80,7 +102,7 @@ lookup_vao(struct gl_context *ctx, GLuint id) glthread->LastLookedUpVAO->Name == id) { vao = glthread->LastLookedUpVAO; } else { - vao = _mesa_HashLookupLocked(glthread->VAOs, id); + vao = _mesa_HashLookupLocked(&glthread->VAOs, id); if (!vao) return NULL; @@ -134,7 +156,7 @@ _mesa_glthread_DeleteVertexArrays(struct gl_context *ctx, glthread->LastLookedUpVAO = NULL; /* The ID is immediately freed for re-use */ - _mesa_HashRemoveLocked(glthread->VAOs, vao->Name); + _mesa_HashRemoveLocked(&glthread->VAOs, vao->Name); free(vao); } } @@ -159,7 +181,7 @@ _mesa_glthread_GenVertexArrays(struct gl_context *ctx, vao->Name = id; _mesa_glthread_reset_vao(vao); - _mesa_HashInsertLocked(glthread->VAOs, id, vao, true); + _mesa_HashInsertLocked(&glthread->VAOs, id, vao); } } @@ -332,26 +354,18 @@ void _mesa_glthread_AttribDivisor(struct gl_context *ctx, const GLuint *vaobj, vao->NonZeroDivisorMask &= ~(1u << attrib); } -static unsigned -element_size(GLint size, GLenum type) -{ - if (size == GL_BGRA) - size = 4; - - return _mesa_bytes_per_vertex_attrib(size, type); -} - static void attrib_pointer(struct glthread_state *glthread, struct glthread_vao *vao, GLuint buffer, gl_vert_attrib attrib, - GLint size, GLenum type, GLsizei stride, + union gl_vertex_format_user format, GLsizei stride, const void *pointer) { if (attrib >= VERT_ATTRIB_MAX) return; - unsigned elem_size = element_size(size, type); + unsigned elem_size = element_size(format); + vao->Attrib[attrib].Format = format; vao->Attrib[attrib].ElementSize = elem_size; vao->Attrib[attrib].Stride = stride ? stride : elem_size; vao->Attrib[attrib].Pointer = pointer; @@ -363,25 +377,30 @@ attrib_pointer(struct glthread_state *glthread, struct glthread_vao *vao, vao->UserPointerMask &= ~(1u << attrib); else vao->UserPointerMask |= 1u << attrib; + + if (pointer) + vao->NonNullPointerMask |= 1u << attrib; + else + vao->NonNullPointerMask &= ~(1u << attrib); } void _mesa_glthread_AttribPointer(struct gl_context *ctx, gl_vert_attrib attrib, - GLint size, GLenum type, GLsizei stride, - const void *pointer) + union gl_vertex_format_user format, + GLsizei stride, const void *pointer) { struct glthread_state *glthread = &ctx->GLThread; attrib_pointer(glthread, glthread->CurrentVAO, glthread->CurrentArrayBufferName, - attrib, size, type, stride, pointer); + attrib, format, stride, pointer); } void _mesa_glthread_DSAAttribPointer(struct gl_context *ctx, GLuint vaobj, GLuint buffer, gl_vert_attrib attrib, - GLint size, GLenum type, GLsizei stride, - GLintptr offset) + union gl_vertex_format_user format, + GLsizei stride, GLintptr offset) { struct glthread_state *glthread = &ctx->GLThread; struct glthread_vao *vao; @@ -390,45 +409,48 @@ _mesa_glthread_DSAAttribPointer(struct gl_context *ctx, GLuint vaobj, if (!vao) return; - attrib_pointer(glthread, vao, buffer, attrib, size, type, stride, + attrib_pointer(glthread, vao, buffer, attrib, format, stride, (const void*)offset); } static void attrib_format(struct glthread_state *glthread, struct glthread_vao *vao, - GLuint attribindex, GLint size, GLenum type, + GLuint attribindex, union gl_vertex_format_user format, GLuint relativeoffset) { if (attribindex >= VERT_ATTRIB_GENERIC_MAX) return; - unsigned elem_size = element_size(size, type); + unsigned elem_size = element_size(format); unsigned i = VERT_ATTRIB_GENERIC(attribindex); + vao->Attrib[i].Format = format; vao->Attrib[i].ElementSize = elem_size; vao->Attrib[i].RelativeOffset = relativeoffset; } void _mesa_glthread_AttribFormat(struct gl_context *ctx, GLuint attribindex, - GLint size, GLenum type, GLuint relativeoffset) + union gl_vertex_format_user format, + GLuint relativeoffset) { struct glthread_state *glthread = &ctx->GLThread; - attrib_format(glthread, glthread->CurrentVAO, attribindex, size, type, + attrib_format(glthread, glthread->CurrentVAO, attribindex, format, relativeoffset); } void _mesa_glthread_DSAAttribFormat(struct gl_context *ctx, GLuint vaobj, - GLuint attribindex, GLint size, GLenum type, + GLuint attribindex, + union gl_vertex_format_user format, GLuint relativeoffset) { struct glthread_state *glthread = &ctx->GLThread; struct glthread_vao *vao = lookup_vao(ctx, vaobj); if (vao) - attrib_format(glthread, vao, attribindex, size, type, relativeoffset); + attrib_format(glthread, vao, attribindex, format, relativeoffset); } static void @@ -447,6 +469,11 @@ bind_vertex_buffer(struct glthread_state *glthread, struct glthread_vao *vao, vao->UserPointerMask &= ~(1u << i); else vao->UserPointerMask |= 1u << i; + + if (offset) + vao->NonNullPointerMask |= 1u << i; + else + vao->NonNullPointerMask &= ~(1u << i); } void @@ -676,8 +703,10 @@ _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format, /* Texcoords */ if (layout.tflag) { _mesa_glthread_ClientState(ctx, NULL, tex, true); - _mesa_glthread_AttribPointer(ctx, tex, layout.tcomps, GL_FLOAT, stride, - (GLubyte *) pointer + layout.toffset); + _mesa_glthread_AttribPointer(ctx, tex, + MESA_PACK_VFORMAT(GL_FLOAT, layout.tcomps, + 0, 0, 0), + stride, (GLubyte *)pointer + layout.toffset); } else { _mesa_glthread_ClientState(ctx, NULL, tex, false); } @@ -685,9 +714,10 @@ _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format, /* Color */ if (layout.cflag) { _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_COLOR0, true); - _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_COLOR0, layout.ccomps, - layout.ctype, stride, - (GLubyte *) pointer + layout.coffset); + _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_COLOR0, + MESA_PACK_VFORMAT(layout.ctype, layout.ccomps, + 1, 0, 0), + stride, (GLubyte *)pointer + layout.coffset); } else { _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_COLOR0, false); } @@ -695,7 +725,8 @@ _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format, /* Normals */ if (layout.nflag) { _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_NORMAL, true); - _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_NORMAL, 3, GL_FLOAT, + _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_NORMAL, + MESA_PACK_VFORMAT(GL_FLOAT, 3, 1, 0, 0), stride, (GLubyte *) pointer + layout.noffset); } else { _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_NORMAL, false); @@ -703,6 +734,42 @@ _mesa_glthread_InterleavedArrays(struct gl_context *ctx, GLenum format, /* Vertices */ _mesa_glthread_ClientState(ctx, NULL, VERT_ATTRIB_POS, true); - _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_POS, layout.vcomps, GL_FLOAT, + _mesa_glthread_AttribPointer(ctx, VERT_ATTRIB_POS, + MESA_PACK_VFORMAT(GL_FLOAT, layout.vcomps, + 0, 0, 0), stride, (GLubyte *) pointer + layout.voffset); } + +static void +unbind_uploaded_vbos(void *_vao, void *_ctx) +{ + struct gl_context *ctx = _ctx; + struct gl_vertex_array_object *vao = _vao; + + assert(ctx->API != API_OPENGL_CORE); + + for (unsigned i = 0; i < ARRAY_SIZE(vao->BufferBinding); i++) { + if (vao->BufferBinding[i].BufferObj && + vao->BufferBinding[i].BufferObj->GLThreadInternal) { + /* We don't need to restore the user pointer because it's never + * overwritten. When we bind a VBO internally, the user pointer + * in gl_array_attribute::Ptr becomes ignored and unchanged. + */ + _mesa_bind_vertex_buffer(ctx, vao, i, NULL, 0, + vao->BufferBinding[i].Stride, false, false); + } + } +} + +/* Unbind VBOs in all VAOs that glthread bound for non-VBO vertex uploads + * to restore original states. + */ +void +_mesa_glthread_unbind_uploaded_vbos(struct gl_context *ctx) +{ + assert(ctx->API != API_OPENGL_CORE); + + /* Iterate over all VAOs. */ + _mesa_HashWalk(&ctx->Array.Objects, unbind_uploaded_vbos, ctx); + unbind_uploaded_vbos(ctx->Array.DefaultVAO, ctx); +} diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c index 8d2cef7c909..46b1ef7855b 100644 --- a/src/mesa/main/hash.c +++ b/src/mesa/main/hash.c @@ -1,19 +1,8 @@ -/** - * \file hash.c - * Generic hash table. - * - * Used for display lists, texture objects, vertex/fragment programs, - * buffer objects, etc. The hash functions are thread-safe. - * - * \note key=0 is illegal. - * - * \author Brian Paul - */ - /* * Mesa 3-D graphics library * * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 2024 Advanced Micro Devices, Inc. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -34,199 +23,101 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +/** + * \file hash.c + * Generic hash table. + * + * Used for display lists, texture objects, vertex/fragment programs, + * buffer objects, etc. The hash functions are thread-safe. + * + * \note key=0 is illegal. + * + * \author Brian Paul + */ + #include "errors.h" -#include "glheader.h" +#include "util/glheader.h" #include "hash.h" #include "util/hash_table.h" #include "util/u_memory.h" -#include "util/u_idalloc.h" - /** - * Create a new hash table. - * - * \return pointer to a new, empty hash table. + * Initialize a hash table. */ -struct _mesa_HashTable * -_mesa_NewHashTable(void) +void +_mesa_InitHashTable(struct _mesa_HashTable *table) { - struct _mesa_HashTable *table = CALLOC_STRUCT(_mesa_HashTable); - - if (table) { - table->ht = _mesa_hash_table_create(NULL, uint_key_hash, - uint_key_compare); - if (table->ht == NULL) { - free(table); - _mesa_error_no_memory(__func__); - return NULL; - } - - _mesa_hash_table_set_deleted_key(table->ht, uint_key(DELETED_KEY_VALUE)); - simple_mtx_init(&table->Mutex, mtx_plain); - } - else { - _mesa_error_no_memory(__func__); - } - - return table; + memset(table, 0, sizeof(*table)); + util_sparse_array_init(&table->array, sizeof(void*), 1024); + util_idalloc_init(&table->id_alloc, 8); + /* Mark ID = 0 as used, so that we don't return it. */ + util_idalloc_reserve(&table->id_alloc, 0); + simple_mtx_init(&table->Mutex, mtx_plain); } - - /** * Delete a hash table. * Frees each entry on the hash table and then the hash table structure itself. * Note that the caller should have already traversed the table and deleted * the objects in the table (i.e. We don't free the entries' data pointer). * + * Invoke the given callback function for each table entry if not NULL. + * * \param table the hash table to delete. + * \param table the hash table to delete + * \param free_callback the callback function + * \param userData arbitrary pointer to pass along to the callback + * (this is typically a struct gl_context pointer) */ void -_mesa_DeleteHashTable(struct _mesa_HashTable *table) -{ - assert(table); - - if (_mesa_hash_table_next_entry(table->ht, NULL) != NULL) { - _mesa_problem(NULL, "In _mesa_DeleteHashTable, found non-freed data"); - } - - _mesa_hash_table_destroy(table->ht, NULL); - if (table->id_alloc) { - util_idalloc_fini(table->id_alloc); - free(table->id_alloc); +_mesa_DeinitHashTable(struct _mesa_HashTable *table, + void (*free_callback)(void *data, void *userData), + void *userData) +{ + if (free_callback) { + util_idalloc_foreach_no_zero_safe(&table->id_alloc, id) { + free_callback(*(void**)util_sparse_array_get(&table->array, id), + userData); + } } + util_idalloc_fini(&table->id_alloc); + util_sparse_array_finish(&table->array); simple_mtx_destroy(&table->Mutex); - free(table); -} - -static void init_name_reuse(struct _mesa_HashTable *table) -{ - assert(_mesa_hash_table_num_entries(table->ht) == 0); - table->id_alloc = MALLOC_STRUCT(util_idalloc); - util_idalloc_init(table->id_alloc); - util_idalloc_resize(table->id_alloc, 8); - ASSERTED GLuint reserve0 = util_idalloc_alloc(table->id_alloc); - assert (reserve0 == 0); } void _mesa_HashEnableNameReuse(struct _mesa_HashTable *table) { _mesa_HashLockMutex(table); - init_name_reuse(table); - _mesa_HashUnlockMutex(table); -} - -/** - * Lookup an entry in the hash table, without locking. - * \sa _mesa_HashLookup - */ -static inline void * -_mesa_HashLookup_unlocked(struct _mesa_HashTable *table, GLuint key) -{ - const struct hash_entry *entry; - - assert(table); - assert(key); - - if (key == DELETED_KEY_VALUE) - return table->deleted_key_data; - - entry = _mesa_hash_table_search_pre_hashed(table->ht, - uint_hash(key), - uint_key(key)); - if (!entry) - return NULL; - - return entry->data; -} - - -/** - * Lookup an entry in the hash table. - * - * \param table the hash table. - * \param key the key. - * - * \return pointer to user's data or NULL if key not in table - */ -void * -_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key) -{ - void *res; - _mesa_HashLockMutex(table); - res = _mesa_HashLookup_unlocked(table, key); + table->alloc_via_idalloc = true; _mesa_HashUnlockMutex(table); - return res; } - /** - * Lookup an entry in the hash table without locking the mutex. + * Insert a key/pointer pair into the hash table without locking the mutex. + * If an entry with this key already exists we'll replace the existing entry. * * The hash table mutex must be locked manually by calling * _mesa_HashLockMutex() before calling this function. * * \param table the hash table. - * \param key the key. - * - * \return pointer to user's data or NULL if key not in table + * \param key the key (not zero). + * \param data pointer to user data. */ -void * -_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key) -{ - return _mesa_HashLookup_unlocked(table, key); -} - - -static inline void -_mesa_HashInsert_unlocked(struct _mesa_HashTable *table, GLuint key, void *data) +void +_mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data) { - uint32_t hash = uint_hash(key); - struct hash_entry *entry; - - assert(table); assert(key); if (key > table->MaxKey) table->MaxKey = key; - if (key == DELETED_KEY_VALUE) { - table->deleted_key_data = data; - } else { - entry = _mesa_hash_table_search_pre_hashed(table->ht, hash, uint_key(key)); - if (entry) { - entry->data = data; - } else { - _mesa_hash_table_insert_pre_hashed(table->ht, hash, uint_key(key), data); - } - } -} - + *(void**)util_sparse_array_get(&table->array, key) = data; -/** - * Insert a key/pointer pair into the hash table without locking the mutex. - * If an entry with this key already exists we'll replace the existing entry. - * - * The hash table mutex must be locked manually by calling - * _mesa_HashLockMutex() before calling this function. - * - * \param table the hash table. - * \param key the key (not zero). - * \param data pointer to user data. - * \param isGenName true if the key has been generated by a HashFindFreeKey* function - */ -void -_mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data, - GLboolean isGenName) -{ - _mesa_HashInsert_unlocked(table, key, data); - if (!isGenName && table->id_alloc) - util_idalloc_reserve(table->id_alloc, key); + util_idalloc_reserve(&table->id_alloc, key); } - /** * Insert a key/pointer pair into the hash table. * If an entry with this key already exists we'll replace the existing entry. @@ -234,20 +125,15 @@ _mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data, * \param table the hash table. * \param key the key (not zero). * \param data pointer to user data. - * \param isGenName true if the key has been generated by a HashFindFreeKey* function */ void -_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data, - GLboolean isGenName) +_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data) { _mesa_HashLockMutex(table); - _mesa_HashInsert_unlocked(table, key, data); - if (!isGenName && table->id_alloc) - util_idalloc_reserve(table->id_alloc, key); + _mesa_HashInsertLocked(table, key, data); _mesa_HashUnlockMutex(table); } - /** * Remove an entry from the hash table. * @@ -257,89 +143,23 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data, * While holding the hash table's lock, searches the entry with the matching * key and unlinks it. */ -static inline void -_mesa_HashRemove_unlocked(struct _mesa_HashTable *table, GLuint key) -{ - struct hash_entry *entry; - - assert(table); - assert(key); - - #ifndef NDEBUG - /* assert if _mesa_HashRemove illegally called from _mesa_HashDeleteAll - * callback function. Have to check this outside of mutex lock. - */ - assert(!table->InDeleteAll); - #endif - - if (key == DELETED_KEY_VALUE) { - table->deleted_key_data = NULL; - } else { - entry = _mesa_hash_table_search_pre_hashed(table->ht, - uint_hash(key), - uint_key(key)); - _mesa_hash_table_remove(table->ht, entry); - } - - if (table->id_alloc) - util_idalloc_free(table->id_alloc, key); -} - - void _mesa_HashRemoveLocked(struct _mesa_HashTable *table, GLuint key) { - _mesa_HashRemove_unlocked(table, key); -} + assert(key); + *(void**)util_sparse_array_get(&table->array, key) = NULL; -void -_mesa_HashRemove(struct _mesa_HashTable *table, GLuint key) -{ - _mesa_HashLockMutex(table); - _mesa_HashRemove_unlocked(table, key); - _mesa_HashUnlockMutex(table); + util_idalloc_free(&table->id_alloc, key); } -/** - * Delete all entries in a hash table, but don't delete the table itself. - * Invoke the given callback function for each table entry. - * - * \param table the hash table to delete - * \param callback the callback function - * \param userData arbitrary pointer to pass along to the callback - * (this is typically a struct gl_context pointer) - */ void -_mesa_HashDeleteAll(struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData) +_mesa_HashRemove(struct _mesa_HashTable *table, GLuint key) { - assert(callback); _mesa_HashLockMutex(table); - #ifndef NDEBUG - table->InDeleteAll = GL_TRUE; - #endif - hash_table_foreach(table->ht, entry) { - callback(entry->data, userData); - _mesa_hash_table_remove(table->ht, entry); - } - if (table->deleted_key_data) { - callback(table->deleted_key_data, userData); - table->deleted_key_data = NULL; - } - if (table->id_alloc) { - util_idalloc_fini(table->id_alloc); - free(table->id_alloc); - init_name_reuse(table); - } - #ifndef NDEBUG - table->InDeleteAll = GL_FALSE; - #endif - table->MaxKey = 0; + _mesa_HashRemoveLocked(table, key); _mesa_HashUnlockMutex(table); } - /** * Walk over all entries in a hash table, calling callback function for each. * \param table the hash table to walk @@ -347,61 +167,28 @@ _mesa_HashDeleteAll(struct _mesa_HashTable *table, * \param userData arbitrary pointer to pass along to the callback * (this is typically a struct gl_context pointer) */ -static void -hash_walk_unlocked(const struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData) +void +_mesa_HashWalkLocked(struct _mesa_HashTable *table, + void (*callback)(void *data, void *userData), + void *userData) { - assert(table); assert(callback); - hash_table_foreach(table->ht, entry) { - callback(entry->data, userData); + util_idalloc_foreach_no_zero_safe(&table->id_alloc, id) { + callback(*(void**)util_sparse_array_get(&table->array, id), userData); } - if (table->deleted_key_data) - callback(table->deleted_key_data, userData); -} - - -void -_mesa_HashWalk(const struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData) -{ - /* cast-away const */ - struct _mesa_HashTable *table2 = (struct _mesa_HashTable *) table; - - _mesa_HashLockMutex(table2); - hash_walk_unlocked(table, callback, userData); - _mesa_HashUnlockMutex(table2); } void -_mesa_HashWalkLocked(const struct _mesa_HashTable *table, +_mesa_HashWalk(struct _mesa_HashTable *table, void (*callback)(void *data, void *userData), void *userData) { - hash_walk_unlocked(table, callback, userData); -} - -/** - * Dump contents of hash table for debugging. - * - * \param table the hash table. - */ -void -_mesa_HashPrint(const struct _mesa_HashTable *table) -{ - if (table->deleted_key_data) - _mesa_debug(NULL, "%u %p\n", DELETED_KEY_VALUE, table->deleted_key_data); - - hash_table_foreach(table->ht, entry) { - _mesa_debug(NULL, "%u %p\n", (unsigned)(uintptr_t) entry->key, - entry->data); - } + _mesa_HashLockMutex(table); + _mesa_HashWalkLocked(table, callback, userData); + _mesa_HashUnlockMutex(table); } - /** * Find a block of adjacent unused hash keys. * @@ -419,8 +206,8 @@ GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) { const GLuint maxKey = ~((GLuint) 0) - 1; - if (table->id_alloc && numKeys == 1) { - return util_idalloc_alloc(table->id_alloc); + if (table->alloc_via_idalloc) { + return util_idalloc_alloc_range(&table->id_alloc, numKeys); } else if (maxKey - numKeys > table->MaxKey) { /* the quick solution */ return table->MaxKey + 1; @@ -431,7 +218,7 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) GLuint freeStart = 1; GLuint key; for (key = 1; key != maxKey; key++) { - if (_mesa_HashLookup_unlocked(table, key)) { + if (_mesa_HashLookupLocked(table, key)) { /* darn, this key is already in use */ freeCount = 0; freeStart = key+1; @@ -449,11 +236,10 @@ _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys) } } - bool _mesa_HashFindFreeKeys(struct _mesa_HashTable *table, GLuint* keys, GLuint numKeys) { - if (!table->id_alloc) { + if (!table->alloc_via_idalloc) { GLuint first = _mesa_HashFindFreeKeyBlock(table, numKeys); for (int i = 0; i < numKeys; i++) { keys[i] = first + i; @@ -462,25 +248,8 @@ _mesa_HashFindFreeKeys(struct _mesa_HashTable *table, GLuint* keys, GLuint numKe } for (int i = 0; i < numKeys; i++) { - keys[i] = util_idalloc_alloc(table->id_alloc); + keys[i] = util_idalloc_alloc(&table->id_alloc); } return true; } - - -/** - * Return the number of entries in the hash table. - */ -GLuint -_mesa_HashNumEntries(const struct _mesa_HashTable *table) -{ - GLuint count = 0; - - if (table->deleted_key_data) - count++; - - count += _mesa_hash_table_num_entries(table->ht); - - return count; -} diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h index 18612bd5c47..11fa528feec 100644 --- a/src/mesa/main/hash.h +++ b/src/mesa/main/hash.h @@ -1,8 +1,3 @@ -/** - * \file hash.h - * Generic hash table. - */ - /* * Mesa 3-D graphics library * @@ -27,104 +22,78 @@ * OTHER DEALINGS IN THE SOFTWARE. */ +/** + * \file hash.h + * A table managing OpenGL object IDs. + */ #ifndef HASH_H #define HASH_H - #include <stdbool.h> #include <stdint.h> -#include "glheader.h" +#include "util/glheader.h" #include "c11/threads.h" #include "util/simple_mtx.h" - -struct util_idalloc; +#include "util/sparse_array.h" +#include "util/u_idalloc.h" /** - * Magic GLuint object name that gets stored outside of the struct hash_table. - * - * The hash table needs a particular pointer to be the marker for a key that - * was deleted from the table, along with NULL for the "never allocated in the - * table" marker. Legacy GL allows any GLuint to be used as a GL object name, - * and we use a 1:1 mapping from GLuints to key pointers, so we need to be - * able to track a GLuint that happens to match the deleted key outside of - * struct hash_table. We tell the hash table to use "1" as the deleted key - * value, so that we test the deleted-key-in-the-table path as best we can. + * The not-really-hash-table data structure. It pretends to be a hash table, + * but it uses util_idalloc to keep track of GL object IDs and + * util_sparse_array for storing entries. Lookups only access the array. */ -#define DELETED_KEY_VALUE 1 +struct _mesa_HashTable { + struct util_sparse_array array; + /* Used when name reuse is enabled */ + struct util_idalloc id_alloc; + simple_mtx_t Mutex; + GLuint MaxKey; /**< highest key inserted so far */ + bool alloc_via_idalloc; +}; -/** @{ - * Mapping from our use of GLuint as both the key and the hash value to the - * hash_table.h API - * - * There exist many integer hash functions, designed to avoid collisions when - * the integers are spread across key space with some patterns. In GL, the - * pattern (in the case of glGen*()ed object IDs) is that the keys are unique - * contiguous integers starting from 1. Because of that, we just use the key - * as the hash value, to minimize the cost of the hash function. If objects - * are never deleted, we will never see a collision in the table, because the - * table resizes itself when it approaches full, and thus key % table_size == - * key. - * - * The case where we could have collisions for genned objects would be - * something like: glGenBuffers(&a, 100); glDeleteBuffers(&a + 50, 50); - * glGenBuffers(&b, 100), because objects 1-50 and 101-200 are allocated at - * the end of that sequence, instead of 1-150. So far it doesn't appear to be - * a problem. - */ -static inline bool -uint_key_compare(const void *a, const void *b) -{ - return a == b; -} +void +_mesa_InitHashTable(struct _mesa_HashTable *table); -static inline uint32_t -uint_hash(GLuint id) -{ - return id; -} +void +_mesa_DeinitHashTable(struct _mesa_HashTable *table, + void (*free_callback)(void *data, void *userData), + void *userData); -static inline uint32_t -uint_key_hash(const void *key) -{ - return uint_hash((uintptr_t)key); -} +void +_mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data); -static inline void * -uint_key(GLuint id) -{ - return (void *)(uintptr_t) id; -} -/** @} */ +void +_mesa_HashRemove(struct _mesa_HashTable *table, GLuint key); -/** - * The hash table data structure. - */ -struct _mesa_HashTable { - struct hash_table *ht; - GLuint MaxKey; /**< highest key inserted so far */ - simple_mtx_t Mutex; /**< mutual exclusion lock */ - /* Used when name reuse is enabled */ - struct util_idalloc* id_alloc; +void +_mesa_HashInsertLocked(struct _mesa_HashTable *table, GLuint key, void *data); - /** Value that would be in the table for DELETED_KEY_VALUE. */ - void *deleted_key_data; - #ifndef NDEBUG - GLboolean InDeleteAll; /**< Debug check */ - #endif -}; +void +_mesa_HashRemoveLocked(struct _mesa_HashTable *table, GLuint key); + +void +_mesa_HashWalk(struct _mesa_HashTable *table, + void (*callback)(void *data, void *userData), + void *userData); -extern struct _mesa_HashTable *_mesa_NewHashTable(void); +void +_mesa_HashWalkLocked(struct _mesa_HashTable *table, + void (*callback)(void *data, void *userData), + void *userData); -extern void _mesa_DeleteHashTable(struct _mesa_HashTable *table); +GLuint +_mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys); -extern void *_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key); +bool +_mesa_HashFindFreeKeys(struct _mesa_HashTable *table, GLuint* keys, + GLuint numKeys); -extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data, - GLboolean isGenName); +void +_mesa_HashEnableNameReuse(struct _mesa_HashTable *table); -extern void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key); +/* Inline functions. */ /** * Lock the hash table mutex. @@ -138,11 +107,9 @@ extern void _mesa_HashRemove(struct _mesa_HashTable *table, GLuint key); static inline void _mesa_HashLockMutex(struct _mesa_HashTable *table) { - assert(table); simple_mtx_lock(&table->Mutex); } - /** * Unlock the hash table mutex. * @@ -151,90 +118,60 @@ _mesa_HashLockMutex(struct _mesa_HashTable *table) static inline void _mesa_HashUnlockMutex(struct _mesa_HashTable *table) { - assert(table); simple_mtx_unlock(&table->Mutex); } -extern void *_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key); - -extern void _mesa_HashInsertLocked(struct _mesa_HashTable *table, - GLuint key, void *data, GLboolean isGenName); - -extern void _mesa_HashRemoveLocked(struct _mesa_HashTable *table, GLuint key); - -extern void -_mesa_HashDeleteAll(struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData); - -extern void -_mesa_HashWalk(const struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData); - -extern void -_mesa_HashWalkLocked(const struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData); - -extern void _mesa_HashPrint(const struct _mesa_HashTable *table); - -extern GLuint _mesa_HashFindFreeKeyBlock(struct _mesa_HashTable *table, GLuint numKeys); - -extern bool -_mesa_HashFindFreeKeys(struct _mesa_HashTable *table, GLuint* keys, GLuint numKeys); - -extern GLuint -_mesa_HashNumEntries(const struct _mesa_HashTable *table); - -extern void _mesa_test_hash_functions(void); - -extern void _mesa_HashEnableNameReuse(struct _mesa_HashTable *table); - static inline void -_mesa_HashWalkMaybeLocked(const struct _mesa_HashTable *table, - void (*callback)(void *data, void *userData), - void *userData, bool locked) +_mesa_HashLockMaybeLocked(struct _mesa_HashTable *table, bool locked) { - if (locked) - _mesa_HashWalkLocked(table, callback, userData); - else - _mesa_HashWalk(table, callback, userData); + if (!locked) + _mesa_HashLockMutex(table); } -static inline struct gl_buffer_object * -_mesa_HashLookupMaybeLocked(struct _mesa_HashTable *table, GLuint key, - bool locked) +static inline void +_mesa_HashUnlockMaybeLocked(struct _mesa_HashTable *table, bool locked) { - if (locked) - return _mesa_HashLookupLocked(table, key); - else - return _mesa_HashLookup(table, key); + if (!locked) + _mesa_HashUnlockMutex(table); } -static inline void -_mesa_HashInsertMaybeLocked(struct _mesa_HashTable *table, - GLuint key, void *data, GLboolean isGenName, - bool locked) +/** + * Lookup an entry in the hash table without locking the mutex. + * + * The hash table mutex must be locked manually by calling + * _mesa_HashLockMutex() before calling this function. + * + * \return pointer to user's data or NULL if key not in table + */ +static inline void * +_mesa_HashLookupLocked(struct _mesa_HashTable *table, GLuint key) { - if (locked) - _mesa_HashInsertLocked(table, key, data, isGenName); - else - _mesa_HashInsert(table, key, data, isGenName); + assert(key); + return *(void**)util_sparse_array_get(&table->array, key); } -static inline void -_mesa_HashLockMaybeLocked(struct _mesa_HashTable *table, bool locked) +/** + * Lookup an entry in the hash table. + * + * \return pointer to user's data or NULL if key not in table + */ +static inline void * +_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key) { - if (!locked) - _mesa_HashLockMutex(table); + _mesa_HashLockMutex(table); + void *res = _mesa_HashLookupLocked(table, key); + _mesa_HashUnlockMutex(table); + return res; } -static inline void -_mesa_HashUnlockMaybeLocked(struct _mesa_HashTable *table, bool locked) +static inline void * +_mesa_HashLookupMaybeLocked(struct _mesa_HashTable *table, GLuint key, + bool locked) { - if (!locked) - _mesa_HashUnlockMutex(table); + if (locked) + return _mesa_HashLookupLocked(table, key); + else + return _mesa_HashLookup(table, key); } #endif diff --git a/src/mesa/main/hint.c b/src/mesa/main/hint.c index 193a3621cbf..60be5358b22 100644 --- a/src/mesa/main/hint.c +++ b/src/mesa/main/hint.c @@ -24,14 +24,15 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "enums.h" #include "context.h" #include "hint.h" #include "mtypes.h" +#include "api_exec_decl.h" - +#include "pipe/p_screen.h" void GLAPIENTRY _mesa_Hint( GLenum target, GLenum mode ) @@ -102,7 +103,7 @@ _mesa_Hint( GLenum target, GLenum mode ) /* GL_SGIS_generate_mipmap */ case GL_GENERATE_MIPMAP_HINT_SGIS: - if (ctx->API == API_OPENGL_CORE) + if (_mesa_is_desktop_gl_core(ctx)) goto invalid_target; if (ctx->Hint.GenerateMipmap == mode) return; @@ -112,7 +113,7 @@ _mesa_Hint( GLenum target, GLenum mode ) /* GL_ARB_fragment_shader */ case GL_FRAGMENT_SHADER_DERIVATIVE_HINT_ARB: - if (ctx->API == API_OPENGLES || !ctx->Extensions.ARB_fragment_shader) + if (_mesa_is_gles1(ctx) || !ctx->Extensions.ARB_fragment_shader) goto invalid_target; if (ctx->Hint.FragmentShaderDerivative == mode) return; @@ -138,8 +139,9 @@ _mesa_MaxShaderCompilerThreadsKHR(GLuint count) ctx->Hint.MaxShaderCompilerThreads = count; - if (ctx->Driver.SetMaxShaderCompilerThreads) - ctx->Driver.SetMaxShaderCompilerThreads(ctx, count); + struct pipe_screen *screen = ctx->screen; + if (screen->set_max_shader_compiler_threads) + screen->set_max_shader_compiler_threads(screen, count); } /**********************************************************************/ diff --git a/src/mesa/main/hint.h b/src/mesa/main/hint.h index 2d7c710af26..705c667b44d 100644 --- a/src/mesa/main/hint.h +++ b/src/mesa/main/hint.h @@ -36,17 +36,10 @@ #ifndef HINT_H #define HINT_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -extern void GLAPIENTRY -_mesa_Hint( GLenum target, GLenum mode ); - -/* GL_KHR_parallel_shader_compile */ -extern void GLAPIENTRY -_mesa_MaxShaderCompilerThreadsKHR(GLuint count); - extern void _mesa_init_hint( struct gl_context * ctx ); diff --git a/src/mesa/main/histogram.c b/src/mesa/main/histogram.c deleted file mode 100644 index 5696f548c9b..00000000000 --- a/src/mesa/main/histogram.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#include "glheader.h" -#include "context.h" -#include "histogram.h" - - -/********************************************************************** - * API functions - */ - - -void GLAPIENTRY -_mesa_GetnMinmaxARB(GLenum target, GLboolean reset, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *values) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmax"); -} - - -void GLAPIENTRY -_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, - GLvoid *values) -{ - _mesa_GetnMinmaxARB(target, reset, format, type, INT_MAX, values); -} - - -void GLAPIENTRY -_mesa_GetnHistogramARB(GLenum target, GLboolean reset, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *values) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogram"); -} - - -void GLAPIENTRY -_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, - GLvoid *values) -{ - _mesa_GetnHistogramARB(target, reset, format, type, INT_MAX, values); -} - - -void GLAPIENTRY -_mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameterfv"); -} - - -void GLAPIENTRY -_mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetHistogramParameteriv"); -} - - -void GLAPIENTRY -_mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameterfv"); -} - - -void GLAPIENTRY -_mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glGetMinmaxParameteriv"); -} - - -void GLAPIENTRY -_mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, GLboolean sink) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glHistogram"); -} - - -void GLAPIENTRY -_mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glMinmax"); -} - - -void GLAPIENTRY -_mesa_ResetHistogram(GLenum target) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glResetHistogram"); -} - - -void GLAPIENTRY -_mesa_ResetMinmax(GLenum target) -{ - GET_CURRENT_CONTEXT(ctx); - - _mesa_error(ctx, GL_INVALID_OPERATION, "glResetMinmax"); -} diff --git a/src/mesa/main/histogram.h b/src/mesa/main/histogram.h deleted file mode 100644 index 47a2bf0e585..00000000000 --- a/src/mesa/main/histogram.h +++ /dev/null @@ -1,73 +0,0 @@ -/** - * \file histogram.h - * Histogram. - * - * \if subset - * (No-op) - * - * \endif - */ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2003 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef HISTOGRAM_H -#define HISTOGRAM_H - -#include "glheader.h" - - -void GLAPIENTRY -_mesa_GetnMinmaxARB(GLenum target, GLboolean reset, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *values); -void GLAPIENTRY -_mesa_GetMinmax(GLenum target, GLboolean reset, GLenum format, GLenum type, - GLvoid *values); -void GLAPIENTRY -_mesa_GetnHistogramARB(GLenum target, GLboolean reset, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *values); -void GLAPIENTRY -_mesa_GetHistogram(GLenum target, GLboolean reset, GLenum format, GLenum type, - GLvoid *values); -void GLAPIENTRY -_mesa_GetHistogramParameterfv(GLenum target, GLenum pname, GLfloat *params); -void GLAPIENTRY -_mesa_GetHistogramParameteriv(GLenum target, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetMinmaxParameterfv(GLenum target, GLenum pname, GLfloat *params); -void GLAPIENTRY -_mesa_GetMinmaxParameteriv(GLenum target, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_Histogram(GLenum target, GLsizei width, GLenum internalFormat, - GLboolean sink); -void GLAPIENTRY -_mesa_Minmax(GLenum target, GLenum internalFormat, GLboolean sink); -void GLAPIENTRY -_mesa_ResetHistogram(GLenum target); -void GLAPIENTRY -_mesa_ResetMinmax(GLenum target); - - -#endif /* HISTOGRAM_H */ diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 4358503e3ca..728f78aebc5 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -30,7 +30,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "colormac.h" #include "glformats.h" #include "image.h" @@ -338,12 +338,13 @@ _mesa_image_row_stride( const struct gl_pixelstore_attrib *packing, * Compute the stride between images in a 3D texture (in bytes) for the given * pixel packing parameters and image width, format and type. */ -GLint +intptr_t _mesa_image_image_stride( const struct gl_pixelstore_attrib *packing, GLint width, GLint height, GLenum format, GLenum type ) { - GLint bytesPerRow, bytesPerImage, remainder; + GLint bytesPerRow, remainder; + intptr_t bytesPerImage; assert(packing); @@ -373,9 +374,9 @@ _mesa_image_image_stride( const struct gl_pixelstore_attrib *packing, bytesPerRow += (packing->Alignment - remainder); if (packing->ImageHeight == 0) - bytesPerImage = bytesPerRow * height; + bytesPerImage = (intptr_t)bytesPerRow * height; else - bytesPerImage = bytesPerRow * packing->ImageHeight; + bytesPerImage = (intptr_t)bytesPerRow * packing->ImageHeight; return bytesPerImage; } @@ -467,130 +468,6 @@ _mesa_expand_bitmap(GLsizei width, GLsizei height, /** - * Convert an array of RGBA colors from one datatype to another. - * NOTE: src may equal dst. In that case, we use a temporary buffer. - */ -void -_mesa_convert_colors(GLenum srcType, const GLvoid *src, - GLenum dstType, GLvoid *dst, - GLuint count, const GLubyte mask[]) -{ - GLuint *tempBuffer; - const GLboolean useTemp = (src == dst); - - tempBuffer = malloc(count * MAX_PIXEL_BYTES); - if (!tempBuffer) - return; - - assert(srcType != dstType); - - switch (srcType) { - case GL_UNSIGNED_BYTE: - if (dstType == GL_UNSIGNED_SHORT) { - const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; - GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst); - GLuint i; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst2[i][RCOMP] = UBYTE_TO_USHORT(src1[i][RCOMP]); - dst2[i][GCOMP] = UBYTE_TO_USHORT(src1[i][GCOMP]); - dst2[i][BCOMP] = UBYTE_TO_USHORT(src1[i][BCOMP]); - dst2[i][ACOMP] = UBYTE_TO_USHORT(src1[i][ACOMP]); - } - } - if (useTemp) - memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); - } - else { - const GLubyte (*src1)[4] = (const GLubyte (*)[4]) src; - GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst); - GLuint i; - assert(dstType == GL_FLOAT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst4[i][RCOMP] = UBYTE_TO_FLOAT(src1[i][RCOMP]); - dst4[i][GCOMP] = UBYTE_TO_FLOAT(src1[i][GCOMP]); - dst4[i][BCOMP] = UBYTE_TO_FLOAT(src1[i][BCOMP]); - dst4[i][ACOMP] = UBYTE_TO_FLOAT(src1[i][ACOMP]); - } - } - if (useTemp) - memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); - } - break; - case GL_UNSIGNED_SHORT: - if (dstType == GL_UNSIGNED_BYTE) { - const GLushort (*src2)[4] = (const GLushort (*)[4]) src; - GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); - GLuint i; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst1[i][RCOMP] = USHORT_TO_UBYTE(src2[i][RCOMP]); - dst1[i][GCOMP] = USHORT_TO_UBYTE(src2[i][GCOMP]); - dst1[i][BCOMP] = USHORT_TO_UBYTE(src2[i][BCOMP]); - dst1[i][ACOMP] = USHORT_TO_UBYTE(src2[i][ACOMP]); - } - } - if (useTemp) - memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); - } - else { - const GLushort (*src2)[4] = (const GLushort (*)[4]) src; - GLfloat (*dst4)[4] = (GLfloat (*)[4]) (useTemp ? tempBuffer : dst); - GLuint i; - assert(dstType == GL_FLOAT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - dst4[i][RCOMP] = USHORT_TO_FLOAT(src2[i][RCOMP]); - dst4[i][GCOMP] = USHORT_TO_FLOAT(src2[i][GCOMP]); - dst4[i][BCOMP] = USHORT_TO_FLOAT(src2[i][BCOMP]); - dst4[i][ACOMP] = USHORT_TO_FLOAT(src2[i][ACOMP]); - } - } - if (useTemp) - memcpy(dst, tempBuffer, count * 4 * sizeof(GLfloat)); - } - break; - case GL_FLOAT: - if (dstType == GL_UNSIGNED_BYTE) { - const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; - GLubyte (*dst1)[4] = (GLubyte (*)[4]) (useTemp ? tempBuffer : dst); - GLuint i; - for (i = 0; i < count; i++) { - if (!mask || mask[i]) - _mesa_unclamped_float_rgba_to_ubyte(dst1[i], src4[i]); - } - if (useTemp) - memcpy(dst, tempBuffer, count * 4 * sizeof(GLubyte)); - } - else { - const GLfloat (*src4)[4] = (const GLfloat (*)[4]) src; - GLushort (*dst2)[4] = (GLushort (*)[4]) (useTemp ? tempBuffer : dst); - GLuint i; - assert(dstType == GL_UNSIGNED_SHORT); - for (i = 0; i < count; i++) { - if (!mask || mask[i]) { - UNCLAMPED_FLOAT_TO_USHORT(dst2[i][RCOMP], src4[i][RCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(dst2[i][GCOMP], src4[i][GCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(dst2[i][BCOMP], src4[i][BCOMP]); - UNCLAMPED_FLOAT_TO_USHORT(dst2[i][ACOMP], src4[i][ACOMP]); - } - } - if (useTemp) - memcpy(dst, tempBuffer, count * 4 * sizeof(GLushort)); - } - break; - default: - unreachable("Invalid datatype in _mesa_convert_colors"); - } - - free(tempBuffer); -} - - - - -/** * Perform basic clipping for glDrawPixels. The image's position and size * and the unpack SkipPixels and SkipRows are adjusted so that the image * region is entirely within the window and scissor bounds. diff --git a/src/mesa/main/image.h b/src/mesa/main/image.h index 7955bbb7ca6..7dd2e45691b 100644 --- a/src/mesa/main/image.h +++ b/src/mesa/main/image.h @@ -27,7 +27,7 @@ #define IMAGE_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_pixelstore_attrib; @@ -82,7 +82,7 @@ _mesa_image_row_stride( const struct gl_pixelstore_attrib *packing, GLint width, GLenum format, GLenum type ); -extern GLint +extern intptr_t _mesa_image_image_stride( const struct gl_pixelstore_attrib *packing, GLint width, GLint height, GLenum format, GLenum type ); @@ -96,12 +96,6 @@ _mesa_expand_bitmap(GLsizei width, GLsizei height, GLubyte onValue); -extern void -_mesa_convert_colors(GLenum srcType, const GLvoid *src, - GLenum dstType, GLvoid *dst, - GLuint count, const GLubyte mask[]); - - extern GLboolean _mesa_clip_drawpixels(const struct gl_context *ctx, GLint *destX, GLint *destY, diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index bb513f762ba..b1543f58f15 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -24,8 +24,7 @@ */ -#include "c99_math.h" -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" #include "light.h" @@ -33,7 +32,9 @@ #include "mtypes.h" #include "math/m_matrix.h" #include "util/bitscan.h" +#include "api_exec_decl.h" +#include <math.h> void GLAPIENTRY _mesa_ShadeModel( GLenum mode ) @@ -53,9 +54,6 @@ _mesa_ShadeModel( GLenum mode ) FLUSH_VERTICES(ctx, _NEW_LIGHT_STATE, GL_LIGHTING_BIT); ctx->Light.ShadeModel = mode; - - if (ctx->Driver.ShadeModel) - ctx->Driver.ShadeModel( ctx, mode ); } @@ -96,8 +94,8 @@ _mesa_ProvokingVertex(GLenum mode) * will have already been transformed by the modelview matrix! * Also, all error checking should have already been done. */ -void -_mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params) +static void +do_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params) { struct gl_light *light; @@ -247,11 +245,8 @@ _mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *pa break; } default: - unreachable("Unexpected pname in _mesa_light()"); + unreachable("Unexpected pname in do_light()"); } - - if (ctx->Driver.Lightfv) - ctx->Driver.Lightfv( ctx, GL_LIGHT0 + lnum, pname, params ); } @@ -322,7 +317,7 @@ _mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ) return; } - _mesa_light(ctx, i, pname, params); + do_light(ctx, i, pname, params); } @@ -550,9 +545,6 @@ _mesa_LightModelfv( GLenum pname, const GLfloat *params ) goto invalid_pname; } - if (ctx->Driver.LightModelfv) - ctx->Driver.LightModelfv( ctx, pname, params ); - return; invalid_pname: @@ -823,9 +815,6 @@ _mesa_ColorMaterial( GLenum face, GLenum mode ) FLUSH_CURRENT(ctx, _NEW_FF_VERT_PROGRAM); _mesa_update_color_material(ctx,ctx->Current.Attrib[VERT_ATTRIB_COLOR0]); } - - if (ctx->Driver.ColorMaterial) - ctx->Driver.ColorMaterial( ctx, face, mode ); } @@ -888,7 +877,7 @@ _mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ) GLuint f; GLfloat (*mat)[4] = ctx->Light.Material.Attrib; - assert(ctx->API == API_OPENGL_COMPAT); + assert(_mesa_is_desktop_gl_compat(ctx)); FLUSH_VERTICES(ctx, 0, 0); /* update materials */ FLUSH_CURRENT(ctx, 0); /* update ctx->Light.Material from vertex buffer */ @@ -1142,8 +1131,7 @@ _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state ) (void) new_state; ctx->_NeedEyeCoords = GL_FALSE; - if (ctx->_ForceEyeCoords || - (ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) || + if ((ctx->Texture._GenFlags & TEXGEN_NEED_EYE_COORD) || ctx->Point._Attenuated || ctx->Light._NeedEyeCoords) ctx->_NeedEyeCoords = GL_TRUE; @@ -1161,8 +1149,6 @@ _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state ) update_modelview_scale(ctx); compute_light_positions( ctx ); - if (ctx->Driver.LightingSpaceChange) - ctx->Driver.LightingSpaceChange( ctx ); return true; } else { @@ -1182,19 +1168,6 @@ _mesa_update_tnl_spaces( struct gl_context *ctx, GLuint new_state ) } -/** - * Drivers may need this if the hardware tnl unit doesn't support the - * light-in-modelspace optimization. It's also useful for debugging. - */ -void -_mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ) -{ - ctx->_ForceEyeCoords = !flag; - ctx->NewState |= _NEW_TNL_SPACES; -} - - - /**********************************************************************/ /***** Initialization *****/ /**********************************************************************/ @@ -1296,13 +1269,12 @@ _mesa_init_lighting( struct gl_context *ctx ) NULL ); ctx->Light.ColorMaterialEnabled = GL_FALSE; - ctx->Light.ClampVertexColor = ctx->API == API_OPENGL_COMPAT; - ctx->Light._ClampVertexColor = ctx->API == API_OPENGL_COMPAT; + ctx->Light.ClampVertexColor = _mesa_is_desktop_gl_compat(ctx); + ctx->Light._ClampVertexColor = _mesa_is_desktop_gl_compat(ctx); /* Miscellaneous */ ctx->Light._NeedEyeCoords = GL_FALSE; ctx->_NeedEyeCoords = GL_FALSE; - ctx->_ForceEyeCoords = GL_FALSE; ctx->_ModelViewInvScale = 1.0; ctx->_ModelViewInvScaleEyespace = 1.0; } diff --git a/src/mesa/main/light.h b/src/mesa/main/light.h index 855389e1876..00eb27d3aa1 100644 --- a/src/mesa/main/light.h +++ b/src/mesa/main/light.h @@ -29,63 +29,12 @@ #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_light; struct gl_material; -extern void GLAPIENTRY -_mesa_ShadeModel( GLenum mode ); - -extern void GLAPIENTRY -_mesa_ProvokingVertex(GLenum mode); - - -extern void GLAPIENTRY -_mesa_ColorMaterial( GLenum face, GLenum mode ); - -extern void GLAPIENTRY -_mesa_Lightf( GLenum light, GLenum pname, GLfloat param ); - -extern void GLAPIENTRY -_mesa_Lightfv( GLenum light, GLenum pname, const GLfloat *params ); - -extern void GLAPIENTRY -_mesa_Lightiv( GLenum light, GLenum pname, const GLint *params ); - -extern void GLAPIENTRY -_mesa_Lighti( GLenum light, GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_LightModelf( GLenum pname, GLfloat param ); - -extern void GLAPIENTRY -_mesa_LightModelfv( GLenum pname, const GLfloat *params ); - -extern void GLAPIENTRY -_mesa_LightModeli( GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_LightModeliv( GLenum pname, const GLint *params ); - -extern void GLAPIENTRY -_mesa_GetLightfv( GLenum light, GLenum pname, GLfloat *params ); - -extern void GLAPIENTRY -_mesa_GetLightiv( GLenum light, GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_mesa_GetMaterialfv( GLenum face, GLenum pname, GLfloat *params ); - -extern void GLAPIENTRY -_mesa_GetMaterialiv( GLenum face, GLenum pname, GLint *params ); - - -extern void -_mesa_light(struct gl_context *ctx, GLuint lnum, GLenum pname, const GLfloat *params); - - extern GLuint _mesa_material_bitmask( struct gl_context *ctx, GLenum face, GLenum pname, GLuint legal, @@ -103,6 +52,4 @@ extern void _mesa_update_color_material( struct gl_context *ctx, extern void _mesa_init_lighting( struct gl_context *ctx ); -extern void _mesa_allow_light_in_model( struct gl_context *ctx, GLboolean flag ); - #endif diff --git a/src/mesa/main/lines.c b/src/mesa/main/lines.c index 275e9a229b3..dc942f667d8 100644 --- a/src/mesa/main/lines.c +++ b/src/mesa/main/lines.c @@ -23,12 +23,14 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "lines.h" #include "macros.h" #include "mtypes.h" +#include "api_exec_decl.h" +#include "state_tracker/st_context.h" /** * Set the line width. @@ -59,7 +61,7 @@ line_width(struct gl_context *ctx, GLfloat width, bool no_error) * *NOT* removed in a later spec. Therefore, we only disallow this in a * forward compatible context. */ - if (!no_error && ctx->API == API_OPENGL_CORE + if (!no_error && _mesa_is_desktop_gl_core(ctx) && ((ctx->Const.ContextFlags & GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT) != 0) && width > 1.0F) { @@ -67,12 +69,9 @@ line_width(struct gl_context *ctx, GLfloat width, bool no_error) return; } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLineState ? 0 : _NEW_LINE, GL_LINE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLineState; + FLUSH_VERTICES(ctx, 0, GL_LINE_BIT); + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Line.Width = width; - - if (ctx->Driver.LineWidth) - ctx->Driver.LineWidth(ctx, width); } @@ -122,13 +121,10 @@ _mesa_LineStipple( GLint factor, GLushort pattern ) ctx->Line.StipplePattern == pattern) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewLineState ? 0 : _NEW_LINE, GL_LINE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewLineState; + FLUSH_VERTICES(ctx, 0, GL_LINE_BIT); + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Line.StippleFactor = factor; ctx->Line.StipplePattern = pattern; - - if (ctx->Driver.LineStipple) - ctx->Driver.LineStipple( ctx, factor, pattern ); } diff --git a/src/mesa/main/lines.h b/src/mesa/main/lines.h index 78a405cbac4..abe6528ffab 100644 --- a/src/mesa/main/lines.h +++ b/src/mesa/main/lines.h @@ -33,19 +33,10 @@ #define LINES_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -void GLAPIENTRY -_mesa_LineWidth_no_error(GLfloat width); - -extern void GLAPIENTRY -_mesa_LineWidth( GLfloat width ); - -extern void GLAPIENTRY -_mesa_LineStipple( GLint factor, GLushort pattern ); - extern void _mesa_init_line( struct gl_context * ctx ); diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index 920be481ed4..16268d4dd7c 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h @@ -35,7 +35,7 @@ #include "util/u_math.h" #include "util/rounding.h" #include "util/compiler.h" -#include "main/glheader.h" +#include "util/glheader.h" #include "mesa_private.h" @@ -145,7 +145,7 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; *** UNCLAMPED_FLOAT_TO_UBYTE: clamp float to [0,1] and map to ubyte in [0,255] *** CLAMPED_FLOAT_TO_UBYTE: map float known to be in [0,1] to ubyte in [0,255] ***/ -#ifndef DEBUG +#if !MESA_DEBUG /* This function/macro is sensitive to precision. Test very carefully * if you change it! */ @@ -689,13 +689,6 @@ INTERP_4F(GLfloat t, GLfloat dst[4], const GLfloat out[4], const GLfloat in[4]) -static inline unsigned -minify(unsigned value, unsigned levels) -{ - return MAX2(1, value >> levels); -} - - /** Cross product of two 3-element vectors */ static inline void CROSS3(GLfloat n[3], const GLfloat u[3], const GLfloat v[3]) diff --git a/src/mesa/main/matrix.c b/src/mesa/main/matrix.c index 41c504f8755..aefd7658ba5 100644 --- a/src/mesa/main/matrix.c +++ b/src/mesa/main/matrix.c @@ -35,7 +35,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" @@ -44,6 +44,7 @@ #include "mtypes.h" #include "math/m_matrix.h" #include "util/bitscan.h" +#include "api_exec_decl.h" static struct gl_matrix_stack * @@ -80,7 +81,7 @@ get_named_matrix_stack(struct gl_context *ctx, GLenum mode, const char* caller) case GL_MATRIX5_ARB: case GL_MATRIX6_ARB: case GL_MATRIX7_ARB: - if (ctx->API == API_OPENGL_COMPAT + if (_mesa_is_desktop_gl_compat(ctx) && (ctx->Extensions.ARB_vertex_program || ctx->Extensions.ARB_fragment_program)) { const GLuint m = mode - GL_MATRIX0_ARB; @@ -121,6 +122,7 @@ static void matrix_frustum(struct gl_matrix_stack* stack, (GLfloat) left, (GLfloat) right, (GLfloat) bottom, (GLfloat) top, (GLfloat) nearval, (GLfloat) farval); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } @@ -202,6 +204,7 @@ matrix_ortho(struct gl_matrix_stack* stack, (GLfloat) left, (GLfloat) right, (GLfloat) bottom, (GLfloat) top, (GLfloat) nearval, (GLfloat) farval ); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } @@ -327,6 +330,7 @@ push_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack, &stack->Stack[stack->Depth]); stack->Depth++; stack->Top = &(stack->Stack[stack->Depth]); + stack->ChangedSincePush = false; } @@ -376,13 +380,15 @@ pop_matrix( struct gl_context *ctx, struct gl_matrix_stack *stack ) /* If the popped matrix is the same as the current one, treat it as * a no-op change. */ - if (memcmp(stack->Top, &stack->Stack[stack->Depth], + if (stack->ChangedSincePush && + memcmp(stack->Top, &stack->Stack[stack->Depth], sizeof(GLmatrix))) { FLUSH_VERTICES(ctx, 0, 0); ctx->NewState |= stack->DirtyFlag; } stack->Top = &(stack->Stack[stack->Depth]); + stack->ChangedSincePush = true; return GL_TRUE; } @@ -449,6 +455,7 @@ _mesa_load_identity_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack FLUSH_VERTICES(ctx, 0, 0); _math_matrix_set_identity(stack->Top); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } @@ -494,6 +501,7 @@ _mesa_load_matrix(struct gl_context *ctx, struct gl_matrix_stack *stack, if (memcmp(m, stack->Top->m, 16 * sizeof(GLfloat)) != 0) { FLUSH_VERTICES(ctx, 0, 0); _math_matrix_loadf(stack->Top, m); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } } @@ -561,12 +569,11 @@ static void matrix_mult(struct gl_matrix_stack *stack, const GLfloat *m, const char* caller) { GET_CURRENT_CONTEXT(ctx); - if (!m || - (m[0] == 1 && m[1] == 0 && m[2] == 0 && m[3] == 0 && - m[4] == 0 && m[5] == 1 && m[6] == 0 && m[7] == 0 && - m[8] == 0 && m[9] == 0 && m[10] == 1 && m[11] == 0 && - m[12] == 0 && m[13] == 0 && m[14] == 0 && m[15] == 1)) + + /* glthread filters out identity matrices, so don't do it again. */ + if (!m || (!ctx->GLThread.enabled && _mesa_matrix_is_identity(m))) return; + if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "%s(%f %f %f %f, %f %f %f %f, %f %f %f %f, %f %f %f %f\n", @@ -578,6 +585,7 @@ matrix_mult(struct gl_matrix_stack *stack, const GLfloat *m, const char* caller) FLUSH_VERTICES(ctx, 0, 0); _math_matrix_mul_floats(stack->Top, m); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } @@ -623,6 +631,7 @@ matrix_rotate(struct gl_matrix_stack *stack, GLfloat angle, FLUSH_VERTICES(ctx, 0, 0); if (angle != 0.0F) { _math_matrix_rotate(stack->Top, angle, x, y, z); + stack->ChangedSincePush = true; ctx->NewState |=stack->DirtyFlag; } } @@ -683,6 +692,7 @@ _mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ) FLUSH_VERTICES(ctx, 0, 0); _math_matrix_scale( ctx->CurrentStack->Top, x, y, z); + ctx->CurrentStack->ChangedSincePush = true; ctx->NewState |= ctx->CurrentStack->DirtyFlag; } @@ -699,6 +709,7 @@ _mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) FLUSH_VERTICES(ctx, 0, 0); _math_matrix_scale(stack->Top, x, y, z); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } @@ -723,6 +734,7 @@ _mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ) FLUSH_VERTICES(ctx, 0, 0); _math_matrix_translate( ctx->CurrentStack->Top, x, y, z); + ctx->CurrentStack->ChangedSincePush = true; ctx->NewState |= ctx->CurrentStack->DirtyFlag; } @@ -738,6 +750,7 @@ _mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ) FLUSH_VERTICES(ctx, 0, 0); _math_matrix_translate(stack->Top, x, y, z); + stack->ChangedSincePush = true; ctx->NewState |= stack->DirtyFlag; } @@ -999,6 +1012,7 @@ init_matrix_stack(struct gl_matrix_stack *stack, stack->StackSize = 1; _math_matrix_ctr(&stack->Stack[0]); stack->Top = stack->Stack; + stack->ChangedSincePush = false; } /** diff --git a/src/mesa/main/matrix.h b/src/mesa/main/matrix.h index a09b08b1665..5a60a7cff9c 100644 --- a/src/mesa/main/matrix.h +++ b/src/mesa/main/matrix.h @@ -28,7 +28,7 @@ #define MATRIX_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_matrix_stack; @@ -40,129 +40,6 @@ extern void _mesa_load_matrix(struct gl_context *ctx, struct gl_matrix_stack *s, const GLfloat *m); -extern void GLAPIENTRY -_mesa_Frustum( GLdouble left, GLdouble right, - GLdouble bottom, GLdouble top, - GLdouble nearval, GLdouble farval ); - -extern void GLAPIENTRY -_mesa_Ortho( GLdouble left, GLdouble right, - GLdouble bottom, GLdouble top, - GLdouble nearval, GLdouble farval ); - -extern void GLAPIENTRY -_mesa_PushMatrix( void ); - -extern void GLAPIENTRY -_mesa_PopMatrix( void ); - -extern void GLAPIENTRY -_mesa_LoadIdentity( void ); - -extern void GLAPIENTRY -_mesa_LoadMatrixf( const GLfloat *m ); - -extern void GLAPIENTRY -_mesa_LoadMatrixd( const GLdouble *m ); - -extern void GLAPIENTRY -_mesa_MatrixMode( GLenum mode ); - -extern void GLAPIENTRY -_mesa_MultMatrixf( const GLfloat *m ); - -extern void GLAPIENTRY -_mesa_MultMatrixd( const GLdouble *m ); - -extern void GLAPIENTRY -_mesa_Rotatef( GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); - -extern void GLAPIENTRY -_mesa_Rotated( GLdouble angle, GLdouble x, GLdouble y, GLdouble z ); - -extern void GLAPIENTRY -_mesa_Scalef( GLfloat x, GLfloat y, GLfloat z ); - -extern void GLAPIENTRY -_mesa_Scaled( GLdouble x, GLdouble y, GLdouble z ); - -extern void GLAPIENTRY -_mesa_Translatef( GLfloat x, GLfloat y, GLfloat z ); - -extern void GLAPIENTRY -_mesa_Translated( GLdouble x, GLdouble y, GLdouble z ); - -extern void GLAPIENTRY -_mesa_LoadTransposeMatrixf( const GLfloat *m ); - -extern void GLAPIENTRY -_mesa_LoadTransposeMatrixd( const GLdouble *m ); - -extern void GLAPIENTRY -_mesa_MultTransposeMatrixf( const GLfloat *m ); - -extern void GLAPIENTRY -_mesa_MultTransposeMatrixd( const GLdouble *m ); - -extern void GLAPIENTRY -_mesa_MatrixLoadfEXT( GLenum matrixMode, const GLfloat *m ); - -extern void GLAPIENTRY -_mesa_MatrixLoaddEXT( GLenum matrixMode, const GLdouble *m ); - -extern void GLAPIENTRY -_mesa_MatrixMultfEXT( GLenum matrixMode, const GLfloat *m ); - -extern void GLAPIENTRY -_mesa_MatrixMultdEXT( GLenum matrixMode, const GLdouble *m ); - -extern void GLAPIENTRY -_mesa_MatrixLoadIdentityEXT( GLenum matrixMode ); - -extern void GLAPIENTRY -_mesa_MatrixRotatefEXT( GLenum matrixMode, GLfloat angle, GLfloat x, GLfloat y, GLfloat z ); - -extern void GLAPIENTRY -_mesa_MatrixRotatedEXT( GLenum matrixMode, GLdouble angle, GLdouble x, GLdouble y, GLdouble z ); - -extern void GLAPIENTRY -_mesa_MatrixScalefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ); - -extern void GLAPIENTRY -_mesa_MatrixScaledEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ); - -extern void GLAPIENTRY -_mesa_MatrixTranslatefEXT( GLenum matrixMode, GLfloat x, GLfloat y, GLfloat z ); - -extern void GLAPIENTRY -_mesa_MatrixTranslatedEXT( GLenum matrixMode, GLdouble x, GLdouble y, GLdouble z ); - -extern void GLAPIENTRY -_mesa_MatrixOrthoEXT( GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, - GLdouble n, GLdouble f ); - -extern void GLAPIENTRY -_mesa_MatrixFrustumEXT( GLenum matrixMode, GLdouble l, GLdouble r, GLdouble b, GLdouble t, - GLdouble n, GLdouble f ); - -extern void GLAPIENTRY -_mesa_MatrixPushEXT( GLenum matrixMode ); - -extern void GLAPIENTRY -_mesa_MatrixPopEXT( GLenum matrixMode ); - -extern void GLAPIENTRY -_mesa_MatrixLoadTransposefEXT( GLenum matrixMode, const GLfloat* m ); - -extern void GLAPIENTRY -_mesa_MatrixLoadTransposedEXT( GLenum matrixMode, const GLdouble* m ); - -extern void GLAPIENTRY -_mesa_MatrixMultTransposefEXT( GLenum matrixMode, const GLfloat* m ); - -extern void GLAPIENTRY -_mesa_MatrixMultTransposedEXT( GLenum matrixMode, const GLdouble* m ); - extern void _mesa_init_matrix( struct gl_context * ctx ); @@ -175,5 +52,20 @@ _mesa_free_matrix_data( struct gl_context *ctx ); extern void _mesa_update_modelview_project( struct gl_context *ctx, GLuint newstate ); +/* "m" must be a 4x4 matrix. Return true if it's the identity matrix. */ +static inline bool +_mesa_matrix_is_identity(const float *m) +{ + const uint32_t *u = (const uint32_t *)m; + const uint32_t one = IEEE_ONE; + + /* This is faster than memcmp with static identity matrix. Instead of + * comparing every non-diagonal element against zero, OR them and compare + * the result. Verified with Viewperf13/Sw/teslaTower_shaded. + */ + return u[0] == one && u[5] == one && u[10] == one && u[15] == one && + !(u[1] | u[2] | u[3] | u[4] | u[6] | u[7] | u[8] | u[9] | u[11] | + u[12] | u[13] | u[14]); +} #endif diff --git a/src/mesa/main/menums.h b/src/mesa/main/menums.h index b78fb2634b3..2a711ffee96 100644 --- a/src/mesa/main/menums.h +++ b/src/mesa/main/menums.h @@ -32,6 +32,7 @@ #ifndef MENUMS_H #define MENUMS_H +#include <stdbool.h> #include "util/macros.h" /** @@ -50,6 +51,19 @@ typedef enum } gl_api; /** + * Checks if the api is for GLES 2.0 or later + */ +static inline bool +_mesa_is_api_gles2(gl_api api) +{ +#if HAVE_OPENGL_ES_2 + return api == API_OPENGLES2; +#else + return false; +#endif +} + +/** * An index for each type of texture object. These correspond to the GL * texture target enums, such as GL_TEXTURE_2D, GL_TEXTURE_CUBE_MAP, etc. * Note: the order is from highest priority to lowest priority. @@ -90,7 +104,7 @@ typedef enum * * result_bit = logic_op & (1 << (2 * src_bit + dst_bit)) */ -enum PACKED gl_logicop_mode { +enum ENUM_PACKED gl_logicop_mode { COLOR_LOGICOP_CLEAR = 0, COLOR_LOGICOP_NOR = 1, COLOR_LOGICOP_AND_INVERTED = 2, diff --git a/src/mesa/main/mesa_private.h b/src/mesa/main/mesa_private.h index 229a746a809..0e2dc863c60 100644 --- a/src/mesa/main/mesa_private.h +++ b/src/mesa/main/mesa_private.h @@ -31,7 +31,7 @@ #ifndef MESA_PRIVATE_H #define MESA_PRIVATE_H -#include "glheader.h" +#include "util/glheader.h" #ifdef __cplusplus extern "C" { diff --git a/src/mesa/main/meson.build b/src/mesa/main/meson.build index a5f0e02c6cd..c8171e89ae5 100644 --- a/src/mesa/main/meson.build +++ b/src/mesa/main/meson.build @@ -31,7 +31,7 @@ main_marshal_generated_h = custom_target( 'marshal_generated.h', input : [files('../../mapi/glapi/gen/gl_marshal_h.py'), gl_and_es_api_files], output : 'marshal_generated.h', - command : [prog_python, '@INPUT0@', '-f', '@INPUT1@'], + command : [prog_python, '@INPUT0@', '@INPUT1@', sizeof_pointer], depend_files : files('../../mapi/glapi/gen/marshal_XML.py') + glapi_gen_depends, capture : true, ) @@ -44,3 +44,14 @@ main_remap_helper_h = custom_target( depend_files : glapi_gen_depends, capture : true, ) + +if _shader_replacement != '' + # shader replacement + shader_replacement_h = custom_target( + 'shader_replacement.h', + input: [files(_shader_replacement + '/process_shaders.py')], + output: 'shader_replacement.h', + command: [prog_python, '@INPUT0@', _shader_replacement, '@OUTPUT@'], + build_always: true, + ) +endif diff --git a/src/mesa/main/mipmap.c b/src/mesa/main/mipmap.c index 8f08396fe15..bfe67fc7f0d 100644 --- a/src/mesa/main/mipmap.c +++ b/src/mesa/main/mipmap.c @@ -42,6 +42,7 @@ #include "util/format_rgb9e5.h" #include "util/format_r11g11b10f.h" +#include "state_tracker/st_cb_texture.h" /** * Compute the expected number of mipmap levels in the texture given @@ -1720,7 +1721,7 @@ make_3d_mipmap(GLenum datatype, GLuint comps, GLint border, * \param srcRowStride stride between source rows, in bytes * \param dstRowStride stride between destination rows, in bytes */ -void +static void _mesa_generate_mipmap_level(GLenum target, GLenum datatype, GLuint comps, GLint border, @@ -1880,13 +1881,13 @@ prepare_mipmap_level(struct gl_context *ctx, dstImage->InternalFormat != intFormat || dstImage->TexFormat != format) { /* need to (re)allocate image */ - ctx->Driver.FreeTextureImageBuffer(ctx, dstImage); + st_FreeTextureImageBuffer(ctx, dstImage); _mesa_init_teximage_fields(ctx, dstImage, width, height, depth, border, intFormat, format); - ctx->Driver.AllocTextureImageBuffer(ctx, dstImage); + st_AllocTextureImageBuffer(ctx, dstImage); /* in case the mipmap level is part of an FBO: */ _mesa_update_fbo_texture(ctx, texObj, face, level); @@ -1913,6 +1914,10 @@ _mesa_prepare_mipmap_levels(struct gl_context *ctx, { const struct gl_texture_image *baseImage = _mesa_select_tex_image(texObj, texObj->Target, baseLevel); + + if (baseImage == NULL) + return; + const GLint border = 0; GLint width = baseImage->Width; GLint height = baseImage->Height; @@ -1994,10 +1999,10 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, srcMaps = calloc(srcDepth, sizeof(GLubyte *)); if (srcMaps) { for (slice = 0; slice < srcDepth; slice++) { - ctx->Driver.MapTextureImage(ctx, srcImage, slice, - 0, 0, srcWidth, srcHeight, - GL_MAP_READ_BIT, - &srcMaps[slice], &srcRowStride); + st_MapTextureImage(ctx, srcImage, slice, + 0, 0, srcWidth, srcHeight, + GL_MAP_READ_BIT, + &srcMaps[slice], &srcRowStride); if (!srcMaps[slice]) { success = GL_FALSE; break; @@ -2012,10 +2017,10 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, dstMaps = calloc(dstDepth, sizeof(GLubyte *)); if (dstMaps) { for (slice = 0; slice < dstDepth; slice++) { - ctx->Driver.MapTextureImage(ctx, dstImage, slice, - 0, 0, dstWidth, dstHeight, - GL_MAP_WRITE_BIT, - &dstMaps[slice], &dstRowStride); + st_MapTextureImage(ctx, dstImage, slice, + 0, 0, dstWidth, dstHeight, + GL_MAP_WRITE_BIT, + &dstMaps[slice], &dstRowStride); if (!dstMaps[slice]) { success = GL_FALSE; break; @@ -2039,7 +2044,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, if (srcMaps) { for (slice = 0; slice < srcDepth; slice++) { if (srcMaps[slice]) { - ctx->Driver.UnmapTextureImage(ctx, srcImage, slice); + st_UnmapTextureImage(ctx, srcImage, slice); } } free(srcMaps); @@ -2049,7 +2054,7 @@ generate_mipmap_uncompressed(struct gl_context *ctx, GLenum target, if (dstMaps) { for (slice = 0; slice < dstDepth; slice++) { if (dstMaps[slice]) { - ctx->Driver.UnmapTextureImage(ctx, dstImage, slice); + st_UnmapTextureImage(ctx, dstImage, slice); } } free(dstMaps); @@ -2132,12 +2137,12 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target, /* Get the uncompressed image */ assert(srcImage->Level == texObj->Attrib.BaseLevel); - ctx->Driver.GetTexSubImage(ctx, - 0, 0, 0, - srcImage->Width, srcImage->Height, - srcImage->Depth, - temp_base_format, temp_datatype, - temp_src, srcImage); + st_GetTexSubImage(ctx, + 0, 0, 0, + srcImage->Width, srcImage->Height, + srcImage->Depth, + temp_base_format, temp_datatype, + temp_src, srcImage); /* restore packing mode */ ctx->Pack = save; } @@ -2200,10 +2205,10 @@ generate_mipmap_compressed(struct gl_context *ctx, GLenum target, temp_dst_slices, temp_dst_row_stride); /* The image space was allocated above so use glTexSubImage now */ - ctx->Driver.TexSubImage(ctx, 2, dstImage, - 0, 0, 0, dstWidth, dstHeight, dstDepth, - temp_base_format, temp_datatype, - temp_dst, &ctx->DefaultPacking); + st_TexSubImage(ctx, 2, dstImage, + 0, 0, 0, dstWidth, dstHeight, dstDepth, + temp_base_format, temp_datatype, + temp_dst, &ctx->DefaultPacking); /* swap src and dest pointers */ { @@ -2224,7 +2229,7 @@ end: /** * Automatic mipmap generation. - * This is the fallback/default function for ctx->Driver.GenerateMipmap(). + * This is the fallback/default function for mipmap generation. * Generate a complete set of mipmaps from texObj's BaseLevel image. * Stop at texObj's MaxLevel or when we get to the 1x1 texture. * For cube maps, target will be one of diff --git a/src/mesa/main/mipmap.h b/src/mesa/main/mipmap.h index 3ec99721743..1dd29c46df3 100644 --- a/src/mesa/main/mipmap.h +++ b/src/mesa/main/mipmap.h @@ -26,7 +26,7 @@ #ifndef MIPMAP_H #define MIPMAP_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_texture_object; @@ -36,17 +36,6 @@ _mesa_compute_num_levels(struct gl_context *ctx, struct gl_texture_object *texObj, GLenum target); -extern void -_mesa_generate_mipmap_level(GLenum target, - GLenum datatype, GLuint comps, - GLint border, - GLint srcWidth, GLint srcHeight, GLint srcDepth, - const GLubyte **srcData, - GLint srcRowStride, - GLint dstWidth, GLint dstHeight, GLint dstDepth, - GLubyte **dstData, - GLint dstRowStride); - void _mesa_prepare_mipmap_levels(struct gl_context *ctx, struct gl_texture_object *texObj, diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index ee1c19df9a2..c023e443c9d 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -38,8 +38,11 @@ #include <stdbool.h> #include "c11/threads.h" -#include "main/glheader.h" +#include "util/glheader.h" #include "main/glthread.h" +#include "main/consts_exts.h" +#include "main/shader_types.h" +#include "main/glconfig.h" #include "main/menums.h" #include "main/config.h" #include "glapi/glapi.h" @@ -48,10 +51,16 @@ #include "compiler/shader_info.h" #include "main/formats.h" /* MESA_FORMAT_COUNT */ #include "compiler/glsl/list.h" +#include "compiler/glsl/ir_uniform.h" +#include "util/u_idalloc.h" #include "util/simple_mtx.h" #include "util/u_dynarray.h" +#include "util/mesa-sha1.h" #include "vbo/vbo.h" +#include "pipe/p_state.h" + +#include "frontend/api.h" #ifdef __cplusplus extern "C" { @@ -65,7 +74,6 @@ extern "C" { * \name Some forward type declarations */ /*@{*/ -struct _mesa_HashTable; struct gl_attrib_node; struct gl_list_extensions; struct gl_meta_state; @@ -89,30 +97,6 @@ struct shader_includes; #define PRIM_UNKNOWN (PRIM_MAX + 2) /** - * Determine if the given gl_varying_slot appears in the fragment shader. - */ -static inline GLboolean -_mesa_varying_slot_in_fs(gl_varying_slot slot) -{ - switch (slot) { - case VARYING_SLOT_PSIZ: - case VARYING_SLOT_BFC0: - case VARYING_SLOT_BFC1: - case VARYING_SLOT_EDGE: - case VARYING_SLOT_CLIP_VERTEX: - case VARYING_SLOT_LAYER: - case VARYING_SLOT_TESS_LEVEL_OUTER: - case VARYING_SLOT_TESS_LEVEL_INNER: - case VARYING_SLOT_BOUNDING_BOX0: - case VARYING_SLOT_BOUNDING_BOX1: - case VARYING_SLOT_VIEWPORT_MASK: - return GL_FALSE; - default: - return GL_TRUE; - } -} - -/** * Bit flags for all renderbuffers */ #define BUFFER_BIT_FRONT_LEFT (1 << BUFFER_FRONT_LEFT) @@ -150,75 +134,6 @@ _mesa_varying_slot_in_fs(gl_varying_slot slot) /* Mask of bits for depth+stencil buffers */ #define BUFFER_BITS_DEPTH_STENCIL (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL) -/** - * Framebuffer configuration (aka visual / pixelformat) - * Note: some of these fields should be boolean, but it appears that - * code in drivers/dri/common/util.c requires int-sized fields. - */ -struct gl_config -{ - GLboolean floatMode; - GLuint doubleBufferMode; - GLuint stereoMode; - - GLint redBits, greenBits, blueBits, alphaBits; /* bits per comp */ - GLuint redMask, greenMask, blueMask, alphaMask; - GLint redShift, greenShift, blueShift, alphaShift; - GLint rgbBits; /* total bits for rgb */ - - GLint accumRedBits, accumGreenBits, accumBlueBits, accumAlphaBits; - GLint depthBits; - GLint stencilBits; - - /* ARB_multisample / SGIS_multisample */ - GLuint samples; - - /* OML_swap_method */ - GLint swapMethod; - - /* EXT_framebuffer_sRGB */ - GLint sRGBCapable; -}; - - -/** - * \name Bit flags used for updating material values. - */ -/*@{*/ -#define MAT_ATTRIB_FRONT_AMBIENT 0 -#define MAT_ATTRIB_BACK_AMBIENT 1 -#define MAT_ATTRIB_FRONT_DIFFUSE 2 -#define MAT_ATTRIB_BACK_DIFFUSE 3 -#define MAT_ATTRIB_FRONT_SPECULAR 4 -#define MAT_ATTRIB_BACK_SPECULAR 5 -#define MAT_ATTRIB_FRONT_EMISSION 6 -#define MAT_ATTRIB_BACK_EMISSION 7 -#define MAT_ATTRIB_FRONT_SHININESS 8 -#define MAT_ATTRIB_BACK_SHININESS 9 -#define MAT_ATTRIB_FRONT_INDEXES 10 -#define MAT_ATTRIB_BACK_INDEXES 11 -#define MAT_ATTRIB_MAX 12 - -#define MAT_ATTRIB_AMBIENT(f) (MAT_ATTRIB_FRONT_AMBIENT+(f)) -#define MAT_ATTRIB_DIFFUSE(f) (MAT_ATTRIB_FRONT_DIFFUSE+(f)) -#define MAT_ATTRIB_SPECULAR(f) (MAT_ATTRIB_FRONT_SPECULAR+(f)) -#define MAT_ATTRIB_EMISSION(f) (MAT_ATTRIB_FRONT_EMISSION+(f)) -#define MAT_ATTRIB_SHININESS(f)(MAT_ATTRIB_FRONT_SHININESS+(f)) -#define MAT_ATTRIB_INDEXES(f) (MAT_ATTRIB_FRONT_INDEXES+(f)) - -#define MAT_BIT_FRONT_AMBIENT (1<<MAT_ATTRIB_FRONT_AMBIENT) -#define MAT_BIT_BACK_AMBIENT (1<<MAT_ATTRIB_BACK_AMBIENT) -#define MAT_BIT_FRONT_DIFFUSE (1<<MAT_ATTRIB_FRONT_DIFFUSE) -#define MAT_BIT_BACK_DIFFUSE (1<<MAT_ATTRIB_BACK_DIFFUSE) -#define MAT_BIT_FRONT_SPECULAR (1<<MAT_ATTRIB_FRONT_SPECULAR) -#define MAT_BIT_BACK_SPECULAR (1<<MAT_ATTRIB_BACK_SPECULAR) -#define MAT_BIT_FRONT_EMISSION (1<<MAT_ATTRIB_FRONT_EMISSION) -#define MAT_BIT_BACK_EMISSION (1<<MAT_ATTRIB_BACK_EMISSION) -#define MAT_BIT_FRONT_SHININESS (1<<MAT_ATTRIB_FRONT_SHININESS) -#define MAT_BIT_BACK_SHININESS (1<<MAT_ATTRIB_BACK_SHININESS) -#define MAT_BIT_FRONT_INDEXES (1<<MAT_ATTRIB_FRONT_INDEXES) -#define MAT_BIT_BACK_INDEXES (1<<MAT_ATTRIB_BACK_INDEXES) - #define FRONT_MATERIAL_BITS (MAT_BIT_FRONT_EMISSION | \ MAT_BIT_FRONT_AMBIENT | \ @@ -403,20 +318,14 @@ struct gl_colorbuffer_attrib GLboolean sRGBEnabled; /**< Framebuffer sRGB blending/updating requested */ }; - /** * Vertex format to describe a vertex element. */ struct gl_vertex_format { - GLenum16 Type; /**< datatype: GL_FLOAT, GL_INT, etc */ - GLenum16 Format; /**< default: GL_RGBA, but may be GL_BGRA */ + union gl_vertex_format_user User; enum pipe_format _PipeFormat:16; /**< pipe_format for Gallium */ - GLubyte Size:5; /**< components per element (1,2,3,4) */ - GLubyte Normalized:1; /**< GL_ARB_vertex_program */ - GLubyte Integer:1; /**< Integer-valued? */ - GLubyte Doubles:1; /**< double values are not converted to floats */ - GLubyte _ElementSize; /**< Size of each element in bytes */ + GLushort _ElementSize; /**< Size of each element in bytes */ }; @@ -856,15 +765,12 @@ struct gl_texture_image mesa_format TexFormat; /**< The actual texture memory format */ GLuint Border; /**< 0 or 1 */ - GLuint Width; /**< = 2^WidthLog2 + 2*Border */ - GLuint Height; /**< = 2^HeightLog2 + 2*Border */ - GLuint Depth; /**< = 2^DepthLog2 + 2*Border */ + GLuint Width; + GLuint Height; + GLuint Depth; GLuint Width2; /**< = Width - 2*Border */ GLuint Height2; /**< = Height - 2*Border */ GLuint Depth2; /**< = Depth - 2*Border */ - GLuint WidthLog2; /**< = log2(Width2) */ - GLuint HeightLog2; /**< = log2(Height2) */ - GLuint DepthLog2; /**< = log2(Depth2) */ GLuint MaxNumLevels; /**< = maximum possible number of mipmap levels, computed from the dimensions */ @@ -873,9 +779,29 @@ struct gl_texture_image /** Cube map face: index into gl_texture_object::Image[] array */ GLuint Face; + unsigned FormatSwizzle; + unsigned FormatSwizzleGLSL130; //for depth formats + /** GL_ARB_texture_multisample */ GLuint NumSamples; /**< Sample count, or 0 for non-multisample */ GLboolean FixedSampleLocations; /**< Same sample locations for all pixels? */ + + /* If stImage->pt != NULL, image data is stored here. + * Else there is no image data. + */ + struct pipe_resource *pt; + + /* List of transfers, allocated on demand. + * transfer[layer] is a mapping for that layer. + */ + struct st_texture_image_transfer *transfer; + unsigned num_transfers; + + /* For compressed images unsupported by the driver. Keep track of + * the original data. This is necessary for mapping/unmapping, + * as well as image copies. + */ + struct st_compressed_data* compressed_data; }; @@ -907,7 +833,6 @@ struct gl_sampler_attrib GLenum16 MinFilter; /**< minification filter */ GLenum16 MagFilter; /**< magnification filter */ GLenum16 sRGBDecode; /**< GL_DECODE_EXT or GL_SKIP_DECODE_EXT */ - union gl_color_union BorderColor; /**< Interpreted according to texture format */ GLfloat MinLod; /**< min lambda, OpenGL 1.2 */ GLfloat MaxLod; /**< max lambda, OpenGL 1.2 */ GLfloat LodBias; /**< OpenGL 1.4 */ @@ -915,7 +840,10 @@ struct gl_sampler_attrib GLenum16 CompareMode; /**< GL_ARB_shadow */ GLenum16 CompareFunc; /**< GL_ARB_shadow */ GLboolean CubeMapSeamless; /**< GL_AMD_seamless_cubemap_per_texture */ + GLboolean IsBorderColorNonZero; /**< Does the border color have any effect? */ GLenum16 ReductionMode; /**< GL_EXT_texture_filter_minmax */ + + struct pipe_sampler_state state; /**< Gallium representation */ }; /** @@ -941,24 +869,43 @@ struct gl_texture_object_attrib GLubyte NumLevels; /**< GL_ARB_texture_view */ }; + +typedef enum +{ + WRAP_S = (1<<0), + WRAP_T = (1<<1), + WRAP_R = (1<<2), +} gl_sampler_wrap; + /** * Sampler object state. These objects are new with GL_ARB_sampler_objects * and OpenGL 3.3. Legacy texture objects also contain a sampler object. */ struct gl_sampler_object { - simple_mtx_t Mutex; GLuint Name; GLchar *Label; /**< GL_KHR_debug */ GLint RefCount; struct gl_sampler_attrib Attrib; /**< State saved by glPushAttrib */ + uint8_t glclamp_mask; /**< mask of GL_CLAMP wraps active */ + /** GL_ARB_bindless_texture */ bool HandleAllocated; struct util_dynarray Handles; }; +/** + * YUV color space that should be used to sample textures backed by YUV + * images. + */ +enum gl_texture_yuv_color_space +{ + GL_TEXTURE_YUV_COLOR_SPACE_REC601, + GL_TEXTURE_YUV_COLOR_SPACE_REC709, + GL_TEXTURE_YUV_COLOR_SPACE_REC2020, +}; /** * Texture object state. Contains the array of mipmap images, border color, @@ -966,7 +913,6 @@ struct gl_sampler_object */ struct gl_texture_object { - simple_mtx_t Mutex; /**< for thread safety */ GLint RefCount; /**< reference count */ GLuint Name; /**< the user-visible texture object ID */ GLenum16 Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ @@ -984,8 +930,6 @@ struct gl_texture_object GLboolean _MipmapComplete; /**< Is the whole mipmap valid? */ GLboolean _IsIntegerFormat; /**< Does the texture store integer values? */ GLboolean _RenderToTexture; /**< Any rendering to this texture? */ - GLboolean Purgeable; /**< Is the buffer purgeable under memory - pressure? */ GLboolean Immutable; /**< GL_ARB_texture_storage */ GLboolean _IsFloat; /**< GL_OES_float_texture */ GLboolean _IsHalfFloat; /**< GL_OES_half_float_texture */ @@ -995,8 +939,11 @@ struct gl_texture_object bool StencilSampling; /**< Should we sample stencil instead of depth? */ /** GL_OES_EGL_image_external */ + GLboolean External; GLubyte RequiredTextureImageUnits; + GLboolean NullTexture; /**< this texture is incomplete and should be passed to the driver as NULL */ + /** GL_EXT_memory_object */ GLenum16 TextureTiling; @@ -1017,6 +964,96 @@ struct gl_texture_object /** GL_ARB_bindless_texture */ struct util_dynarray SamplerHandles; struct util_dynarray ImageHandles; + + /** GL_ARB_sparse_texture */ + GLboolean IsSparse; + GLint VirtualPageSizeIndex; + GLint NumSparseLevels; + + /* The texture must include at levels [0..lastLevel] once validated: + */ + GLuint lastLevel; + + unsigned Swizzle; + unsigned SwizzleGLSL130; + + unsigned int validated_first_level; + unsigned int validated_last_level; + + /* On validation any active images held in main memory or in other + * textures will be copied to this texture and the old storage freed. + */ + struct pipe_resource *pt; + + /* Protect modifications of the sampler_views array */ + simple_mtx_t validate_mutex; + + /* Container of sampler views (one per context) attached to this texture + * object. Created lazily on first binding in context. + * + * Purely read-only accesses to the current context's own sampler view + * require no locking. Another thread may simultaneously replace the + * container object in order to grow the array, but the old container will + * be kept alive. + * + * Writing to the container (even for modifying the current context's own + * sampler view) always requires taking the validate_mutex to protect against + * concurrent container switches. + * + * NULL'ing another context's sampler view is allowed only while + * implementing an API call that modifies the texture: an application which + * calls those while simultaneously reading the texture in another context + * invokes undefined behavior. (TODO: a dubious violation of this rule is + * st_finalize_texture, which is a lazy operation that corresponds to a + * texture modification.) + */ + struct st_sampler_views *sampler_views; + + /* Old sampler views container objects that have not been freed yet because + * other threads/contexts may still be reading from them. + */ + struct st_sampler_views *sampler_views_old; + + /* True if this texture comes from the window system. Such a texture + * cannot be reallocated and the format can only be changed with a sampler + * view or a surface. + */ + GLboolean surface_based; + + /* If surface_based is true, this format should be used for all sampler + * views and surfaces instead of pt->format. + */ + enum pipe_format surface_format; + + /* If surface_based is true and surface_format is a YUV format, these + * settings should be used to convert from YUV to RGB. + */ + enum gl_texture_yuv_color_space yuv_color_space; + bool yuv_full_range; + + /* When non-negative, samplers should use this level instead of the level + * range specified by the GL state. + * + * This is used for EGL images, which may correspond to a single level out + * of an imported pipe_resources with multiple mip levels. + */ + int level_override; + + /* When non-negative, samplers should use this layer instead of the one + * specified by the GL state. + * + * This is used for EGL images and VDPAU interop, where imported + * pipe_resources may be cube, 3D, or array textures (containing layers + * with different fields in the case of VDPAU) even though the GL state + * describes one non-array texture per field. + */ + int layer_override; + + /** + * Set when the texture images of this texture object might not all be in + * the pipe_resource *pt above. + */ + bool needs_validation; }; @@ -1181,6 +1218,7 @@ struct gl_texgen struct gl_texture_unit { GLfloat LodBias; /**< for biasing mipmap levels */ + float LodBiasQuantized; /**< to reduce pipe_sampler_state variants */ /** Texture targets that have a non-default texture bound */ GLbitfield _BoundTextures; @@ -1281,6 +1319,8 @@ struct gl_texture_attrib /** GL_ARB_seamless_cubemap */ GLboolean CubeMapSeamless; + GLshort NumSamplersWithClamp; + struct gl_texture_unit Unit[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; struct gl_fixedfunc_texture_unit FixedFuncUnit[MAX_TEXTURE_COORD_UNITS]; }; @@ -1351,7 +1391,6 @@ typedef enum USAGE_TRANSFORM_FEEDBACK_BUFFER = 0x10, USAGE_PIXEL_PACK_BUFFER = 0x20, USAGE_ARRAY_BUFFER = 0x40, - USAGE_ELEMENT_ARRAY_BUFFER = 0x80, USAGE_DISABLE_MINMAX_CACHE = 0x100, } gl_buffer_usage; @@ -1363,7 +1402,6 @@ struct gl_buffer_object { GLint RefCount; GLuint Name; - GLchar *Label; /**< GL_KHR_debug */ /** * The context that holds a global buffer reference for the lifetime of @@ -1393,52 +1431,49 @@ struct gl_buffer_object struct gl_context *Ctx; GLint CtxRefCount; /**< Non-atomic references held by Ctx. */ - GLenum16 Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */ - GLbitfield StorageFlags; /**< GL_MAP_PERSISTENT_BIT, etc. */ - GLsizeiptrARB Size; /**< Size of buffer storage in bytes */ - GLubyte *Data; /**< Location of storage either in RAM or VRAM. */ - GLboolean DeletePending; /**< true if buffer object is removed from the hash */ - GLboolean Written; /**< Ever written to? (for debugging) */ - GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ - GLboolean Immutable; /**< GL_ARB_buffer_storage */ gl_buffer_usage UsageHistory; /**< How has this buffer been used so far? */ - /** Counters used for buffer usage warnings */ - GLuint NumSubDataCalls; - GLuint NumMapBufferWriteCalls; + struct pipe_resource *buffer; + struct gl_context *private_refcount_ctx; + /* This mechanism allows passing buffer references to the driver without + * using atomics to increase the reference count. + * + * This private refcount can be decremented without atomics but only one + * context (ctx above) can use this counter to be thread-safe. + * + * This number is atomically added to buffer->reference.count at + * initialization. If it's never used, the same number is atomically + * subtracted from buffer->reference.count before destruction. If this + * number is decremented, we can pass that reference to the driver without + * touching reference.count. At buffer destruction we only subtract + * the number of references we did not return. This can possibly turn + * a million atomic increments into 1 add and 1 subtract atomic op. + */ + int private_refcount; - struct gl_buffer_mapping Mappings[MAP_COUNT]; + GLbitfield StorageFlags; /**< GL_MAP_PERSISTENT_BIT, etc. */ /** Memoization of min/max index computations for static index buffers */ - simple_mtx_t MinMaxCacheMutex; - struct hash_table *MinMaxCache; unsigned MinMaxCacheHitIndices; unsigned MinMaxCacheMissIndices; - bool MinMaxCacheDirty; + struct hash_table *MinMaxCache; + simple_mtx_t MinMaxCacheMutex; + bool MinMaxCacheDirty:1; - bool HandleAllocated; /**< GL_ARB_bindless_texture */ -}; + bool DeletePending:1; /**< true if buffer object is removed from the hash */ + bool Immutable:1; /**< GL_ARB_buffer_storage */ + bool HandleAllocated:1; /**< GL_ARB_bindless_texture */ + bool GLThreadInternal:1; /**< Created by glthread. */ + GLenum16 Usage; /**< GL_STREAM_DRAW_ARB, GL_STREAM_READ_ARB, etc. */ + GLchar *Label; /**< GL_KHR_debug */ + GLsizeiptrARB Size; /**< Size of buffer storage in bytes */ + /** Counters used for buffer usage warnings */ + GLuint NumSubDataCalls; + GLuint NumMapBufferWriteCalls; -/** - * Client pixel packing/unpacking attributes - */ -struct gl_pixelstore_attrib -{ - GLint Alignment; - GLint RowLength; - GLint SkipPixels; - GLint SkipRows; - GLint ImageHeight; - GLint SkipImages; - GLboolean SwapBytes; - GLboolean LsbFirst; - GLboolean Invert; /**< GL_MESA_pack_invert */ - GLint CompressedBlockWidth; /**< GL_ARB_compressed_texture_pixel_storage */ - GLint CompressedBlockHeight; - GLint CompressedBlockDepth; - GLint CompressedBlockSize; - struct gl_buffer_object *BufferObj; /**< GL_ARB_pixel_buffer_object */ + struct gl_buffer_mapping Mappings[MAP_COUNT]; + struct pipe_transfer *transfer[MAP_COUNT]; }; @@ -1574,26 +1609,12 @@ struct gl_vertex_array_object GLboolean EverBound; /** - * Whether the VAO is changed by the application so often that some of - * the derived fields are not updated at all to decrease overhead. - * Also, interleaved arrays are not detected, because it's too expensive - * to do that before every draw call. - */ - bool IsDynamic; - - /** * Marked to true if the object is shared between contexts and immutable. * Then reference counting is done using atomics and thread safe. * Is used for dlist VAOs. */ bool SharedAndImmutable; - /** - * Number of updates that were done by the application. This is used to - * decide whether the VAO is static or dynamic. - */ - unsigned NumUpdates; - /** Vertex attribute arrays */ struct gl_array_attributes VertexAttrib[VERT_ATTRIB_MAX]; @@ -1610,6 +1631,12 @@ struct gl_vertex_array_object GLbitfield Enabled; /** + * Mask of vertex attributes that have: + * VertexAttrib[i].BufferBindingIndex != i. + */ + GLbitfield NonIdentityBufferAttribMapping; + + /** * Mask indicating which VertexAttrib and BufferBinding structures have * been changed since the VAO creation. No bit is ever cleared to 0 by * state updates. Setting to the default state doesn't update this. @@ -1618,27 +1645,12 @@ struct gl_vertex_array_object */ GLbitfield NonDefaultStateMask; - /** - * Mask of VERT_BIT_* enabled arrays past position/generic0 mapping - * - * The value is valid past calling _mesa_update_vao_derived_arrays. - * Note that _mesa_update_vao_derived_arrays is called when binding - * the VAO to Array._DrawVAO. - */ - GLbitfield _EffEnabledVBO; - - /** Same as _EffEnabledVBO, but for instance divisors. */ - GLbitfield _EffEnabledNonZeroDivisor; - /** Denotes the way the position/generic0 attribute is mapped */ gl_attribute_map_mode _AttributeMapMode; /** "Enabled" with the position/generic0 attribute aliasing resolved */ GLbitfield _EnabledWithMapMode; - /** Mask of VERT_BIT_* values indicating changed/dirty arrays */ - GLbitfield NewArrays; - /** The index buffer (also known as the element array buffer in OpenGL). */ struct gl_buffer_object *IndexBufferObj; }; @@ -1662,7 +1674,7 @@ struct gl_array_attrib struct gl_vertex_array_object DefaultVAOState; /** Array objects (GL_ARB_vertex_array_object) */ - struct _mesa_HashTable *Objects; + struct _mesa_HashTable Objects; GLint ActiveTexture; /**< Client Active Texture */ GLuint LockFirst; /**< GL_EXT_compiled_vertex_array */ @@ -1692,20 +1704,28 @@ struct gl_array_attrib * mode or display list draws. */ struct gl_vertex_array_object *_DrawVAO; + + /** + * Whether per-vertex edge flags are enabled and should be processed by + * the vertex shader. + */ + bool _PerVertexEdgeFlagsEnabled; + /** - * The VERT_BIT_* bits effectively enabled from the current _DrawVAO. - * This is always a subset of _mesa_get_vao_vp_inputs(_DrawVAO) - * but may omit those arrays that shall not be referenced by the current - * gl_vertex_program_state::_VPMode. For example the generic attributes are - * maked out form the _DrawVAO's enabled arrays when a fixed function - * array draw is executed. - */ - GLbitfield _DrawVAOEnabledAttribs; + * Whether all edge flags are false, causing all points and lines generated + * by polygon mode to be not drawn. (i.e. culled) + */ + bool _PolygonModeAlwaysCulls; + /** - * Initially or if the VAO referenced by _DrawVAO is deleted the _DrawVAO - * pointer is set to the _EmptyVAO which is just an empty VAO all the time. + * If gallium vertex buffers are dirty, this flag indicates whether gallium + * vertex elements are dirty too. If this is false, GL states corresponding + * to vertex elements have not been changed. Thus, this affects what will + * happen when ST_NEW_VERTEX_ARRAYS is set. + * + * The driver should clear this when it's done. */ - struct gl_vertex_array_object *_EmptyVAO; + bool NewVertexElements; /** Legal array datatypes and the API for which they have been computed */ GLbitfield LegalTypesMask; @@ -1740,6 +1760,15 @@ struct gl_selection GLboolean HitFlag; /**< hit flag */ GLfloat HitMinZ; /**< minimum hit depth */ GLfloat HitMaxZ; /**< maximum hit depth */ + + /* HW GL_SELECT */ + void *SaveBuffer; /**< array holds multi stack data */ + GLuint SaveBufferTail; /**< offset to SaveBuffer's tail */ + GLuint SavedStackNum; /**< number of saved stacks */ + + GLboolean ResultUsed; /**< whether any draw used result buffer */ + GLuint ResultOffset; /**< offset into result buffer */ + struct gl_buffer_object *Result; /**< result buffer */ }; @@ -1804,79 +1833,6 @@ struct gl_evaluators }; -struct gl_transform_feedback_varying_info -{ - char *Name; - GLenum16 Type; - GLint BufferIndex; - GLint Size; - GLint Offset; -}; - - -/** - * Per-output info vertex shaders for transform feedback. - */ -struct gl_transform_feedback_output -{ - uint32_t OutputRegister; - uint32_t OutputBuffer; - uint32_t NumComponents; - uint32_t StreamId; - - /** offset (in DWORDs) of this output within the interleaved structure */ - uint32_t DstOffset; - - /** - * Offset into the output register of the data to output. For example, - * if NumComponents is 2 and ComponentOffset is 1, then the data to - * offset is in the y and z components of the output register. - */ - uint32_t ComponentOffset; -}; - - -struct gl_transform_feedback_buffer -{ - uint32_t Binding; - - uint32_t NumVaryings; - - /** - * Total number of components stored in each buffer. This may be used by - * hardware back-ends to determine the correct stride when interleaving - * multiple transform feedback outputs in the same buffer. - */ - uint32_t Stride; - - /** - * Which transform feedback stream this buffer binding is associated with. - */ - uint32_t Stream; -}; - - -/** Post-link transform feedback info. */ -struct gl_transform_feedback_info -{ - unsigned NumOutputs; - - /* Bitmask of active buffer indices. */ - unsigned ActiveBuffers; - - struct gl_transform_feedback_output *Outputs; - - /** Transform feedback varyings used for the linking of this shader program. - * - * Use for glGetTransformFeedbackVarying(). - */ - struct gl_transform_feedback_varying_info *Varyings; - GLint NumVarying; - - struct gl_transform_feedback_buffer Buffers[MAX_FEEDBACK_BUFFERS]; -}; - - /** * Transform feedback object state */ @@ -1929,6 +1885,14 @@ struct gl_transform_feedback_object * zero. */ GLsizeiptr RequestedSize[MAX_FEEDBACK_BUFFERS]; + + unsigned num_targets; + struct pipe_stream_output_target *targets[PIPE_MAX_SO_BUFFERS]; + + /* This encapsulates the count that can be used as a source for draw_vbo. + * It contains stream output targets from the last call of + * EndTransformFeedback for each stream. */ + struct pipe_stream_output_target *draw_count[MAX_VERTEX_STREAMS]; }; @@ -1943,7 +1907,7 @@ struct gl_transform_feedback_state struct gl_buffer_object *CurrentBuffer; /** The table of all transform feedback objects */ - struct _mesa_HashTable *Objects; + struct _mesa_HashTable Objects; /** The current xform-fb object (GL_TRANSFORM_FEEDBACK_BINDING) */ struct gl_transform_feedback_object *CurrentObject; @@ -1985,6 +1949,18 @@ struct gl_perf_monitor_object * BITSET_TEST(ActiveCounters[g], c) */ GLuint **ActiveCounters; + + unsigned num_active_counters; + + struct gl_perf_counter_object { + struct pipe_query *query; + int id; + int group_id; + unsigned batch_index; + } *active_counters; + + struct pipe_query *batch_query; + union pipe_query_result *batch_result; }; @@ -2012,6 +1988,9 @@ struct gl_perf_monitor_counter /** Maximum counter value. */ union gl_perf_monitor_counter_value Maximum; + + unsigned query_type; + unsigned flags; }; @@ -2029,8 +2008,9 @@ struct gl_perf_monitor_group /** Array of counters within this group. */ const struct gl_perf_monitor_counter *Counters; GLuint NumCounters; -}; + bool has_batch; +}; /** * A query object instance as described in INTEL_performance_query. @@ -2059,7 +2039,7 @@ struct gl_perf_monitor_state GLuint NumGroups; /** The table of all performance monitors. */ - struct _mesa_HashTable *Monitors; + struct _mesa_HashTable Monitors; }; @@ -2068,254 +2048,7 @@ struct gl_perf_monitor_state */ struct gl_perf_query_state { - struct _mesa_HashTable *Objects; /**< The table of all performance query objects */ -}; - - -/** - * A bindless sampler object. - */ -struct gl_bindless_sampler -{ - /** Texture unit (set by glUniform1()). */ - GLubyte unit; - - /** Whether this bindless sampler is bound to a unit. */ - GLboolean bound; - - /** Texture Target (TEXTURE_1D/2D/3D/etc_INDEX). */ - gl_texture_index target; - - /** Pointer to the base of the data. */ - GLvoid *data; -}; - - -/** - * A bindless image object. - */ -struct gl_bindless_image -{ - /** Image unit (set by glUniform1()). */ - GLubyte unit; - - /** Whether this bindless image is bound to a unit. */ - GLboolean bound; - - /** Access qualifier (GL_READ_WRITE, GL_READ_ONLY, GL_WRITE_ONLY, or - * GL_NONE to indicate both read-only and write-only) - */ - GLenum16 access; - - /** Pointer to the base of the data. */ - GLvoid *data; -}; - - -/** - * Base class for any kind of program object - */ -struct gl_program -{ - /** FIXME: This must be first until we split shader_info from nir_shader */ - struct shader_info info; - - GLuint Id; - GLint RefCount; - GLubyte *String; /**< Null-terminated program text */ - - /** GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV */ - GLenum16 Target; - GLenum16 Format; /**< String encoding format */ - - GLboolean _Used; /**< Ever used for drawing? Used for debugging */ - - struct nir_shader *nir; - - /* Saved and restored with metadata. Freed with ralloc. */ - void *driver_cache_blob; - size_t driver_cache_blob_size; - - bool is_arb_asm; /** Is this an ARB assembly-style program */ - - /** Is this program written to on disk shader cache */ - bool program_written_to_cache; - - /** A bitfield indicating which vertex shader inputs consume two slots - * - * This is used for mapping from single-slot input locations in the GL API - * to dual-slot double input locations in the shader. This field is set - * once as part of linking and never updated again to ensure the mapping - * remains consistent. - * - * Note: There may be dual-slot variables in the original shader source - * which do not appear in this bitfield due to having been eliminated by - * the compiler prior to DualSlotInputs being calculated. There may also - * be bits set in this bitfield which are set but which the shader never - * reads due to compiler optimizations eliminating such variables after - * DualSlotInputs is calculated. - */ - GLbitfield64 DualSlotInputs; - /** Subset of OutputsWritten outputs written with non-zero index. */ - GLbitfield64 SecondaryOutputsWritten; - /** TEXTURE_x_BIT bitmask */ - GLbitfield16 TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; - /** Bitfield of which samplers are used */ - GLbitfield SamplersUsed; - /** Texture units used for shadow sampling. */ - GLbitfield ShadowSamplers; - /** Texture units used for samplerExternalOES */ - GLbitfield ExternalSamplersUsed; - - /** Named parameters, constants, etc. from program text */ - struct gl_program_parameter_list *Parameters; - - /** Map from sampler unit to texture unit (set by glUniform1i()) */ - GLubyte SamplerUnits[MAX_SAMPLERS]; - - /* FIXME: We should be able to make this struct a union. However some - * drivers (i915/fragment_programs, swrast/prog_execute) mix the use of - * these fields, we should fix this. - */ - struct { - /** Fields used by GLSL programs */ - struct { - /** Data shared by gl_program and gl_shader_program */ - struct gl_shader_program_data *data; - - struct gl_active_atomic_buffer **AtomicBuffers; - - /** Post-link transform feedback info. */ - struct gl_transform_feedback_info *LinkedTransformFeedback; - - /** - * Number of types for subroutine uniforms. - */ - GLuint NumSubroutineUniformTypes; - - /** - * Subroutine uniform remap table - * based on the program level uniform remap table. - */ - GLuint NumSubroutineUniforms; /* non-sparse total */ - GLuint NumSubroutineUniformRemapTable; - struct gl_uniform_storage **SubroutineUniformRemapTable; - - /** - * Num of subroutine functions for this stage and storage for them. - */ - GLuint NumSubroutineFunctions; - GLuint MaxSubroutineFunctionIndex; - struct gl_subroutine_function *SubroutineFunctions; - - /** - * Map from image uniform index to image unit (set by glUniform1i()) - * - * An image uniform index is associated with each image uniform by - * the linker. The image index associated with each uniform is - * stored in the \c gl_uniform_storage::image field. - */ - GLubyte ImageUnits[MAX_IMAGE_UNIFORMS]; - - /** - * Access qualifier specified in the shader for each image uniform - * index. Either \c GL_READ_ONLY, \c GL_WRITE_ONLY, \c - * GL_READ_WRITE, or \c GL_NONE to indicate both read-only and - * write-only. - * - * It may be different, though only more strict than the value of - * \c gl_image_unit::Access for the corresponding image unit. - */ - GLenum16 ImageAccess[MAX_IMAGE_UNIFORMS]; - - GLuint NumUniformBlocks; - struct gl_uniform_block **UniformBlocks; - struct gl_uniform_block **ShaderStorageBlocks; - - /** - * Bitmask of shader storage blocks not declared as read-only. - */ - unsigned ShaderStorageBlocksWriteAccess; - - /** Which texture target is being sampled - * (TEXTURE_1D/2D/3D/etc_INDEX) - */ - GLubyte SamplerTargets[MAX_SAMPLERS]; - - /** - * Number of samplers declared with the bindless_sampler layout - * qualifier as specified by ARB_bindless_texture. - */ - GLuint NumBindlessSamplers; - GLboolean HasBoundBindlessSampler; - struct gl_bindless_sampler *BindlessSamplers; - - /** - * Number of images declared with the bindless_image layout qualifier - * as specified by ARB_bindless_texture. - */ - GLuint NumBindlessImages; - GLboolean HasBoundBindlessImage; - struct gl_bindless_image *BindlessImages; - - union { - struct { - /** - * A bitmask of gl_advanced_blend_mode values - */ - GLbitfield BlendSupport; - } fs; - }; - } sh; - - /** ARB assembly-style program fields */ - struct { - struct prog_instruction *Instructions; - - /** - * Local parameters used by the program. - * - * It's dynamically allocated because it is rarely used (just - * assembly-style programs), and MAX_PROGRAM_LOCAL_PARAMS entries - * once it's allocated. - */ - GLfloat (*LocalParams)[4]; - unsigned MaxLocalParams; - - /** Bitmask of which register files are read/written with indirect - * addressing. Mask of (1 << PROGRAM_x) bits. - */ - GLbitfield IndirectRegisterFiles; - - /** Logical counts */ - /*@{*/ - GLuint NumInstructions; - GLuint NumTemporaries; - GLuint NumParameters; - GLuint NumAttributes; - GLuint NumAddressRegs; - GLuint NumAluInstructions; - GLuint NumTexInstructions; - GLuint NumTexIndirections; - /*@}*/ - /** Native, actual h/w counts */ - /*@{*/ - GLuint NumNativeInstructions; - GLuint NumNativeTemporaries; - GLuint NumNativeParameters; - GLuint NumNativeAttributes; - GLuint NumNativeAddressRegs; - GLuint NumNativeAluInstructions; - GLuint NumNativeTexInstructions; - GLuint NumNativeTexIndirections; - /*@}*/ - - /** Used by ARB assembly-style programs. Can only be true for vertex - * programs. - */ - GLboolean IsPositionInvariant; - } arb; - }; + struct _mesa_HashTable Objects; /**< The table of all performance query objects */ }; @@ -2337,8 +2070,6 @@ struct gl_vertex_program_state GLboolean Enabled; /**< User-set GL_VERTEX_PROGRAM_ARB/NV flag */ GLboolean PointSizeEnabled; /**< GL_VERTEX_PROGRAM_POINT_SIZE_ARB/NV */ GLboolean TwoSideEnabled; /**< GL_VERTEX_PROGRAM_TWO_SIDE_ARB/NV */ - /** Should fixed-function T&L be implemented with a vertex prog? */ - GLboolean _MaintainTnlProgram; /** Whether the fixed-func program is being used right now. */ GLboolean _UsesTnlProgram; @@ -2417,8 +2148,6 @@ struct gl_geometry_program_state struct gl_fragment_program_state { GLboolean Enabled; /**< User-set fragment program enable flag */ - /** Should fixed-function texturing be implemented with a fragment prog? */ - GLboolean _MaintainTexEnvProgram; /** Whether the fixed-func program is being used right now. */ GLboolean _UsesTexEnvProgram; @@ -2501,675 +2230,6 @@ struct gl_ati_fragment_shader_state struct ati_fragment_shader *Current; }; -/** - * Shader subroutine function definition - */ -struct gl_subroutine_function -{ - char *name; - int index; - int num_compat_types; - const struct glsl_type **types; -}; - -/** - * Shader information needed by both gl_shader and gl_linked shader. - */ -struct gl_shader_info -{ - /** - * Tessellation Control shader state from layout qualifiers. - */ - struct { - /** - * 0 - vertices not declared in shader, or - * 1 .. GL_MAX_PATCH_VERTICES - */ - GLint VerticesOut; - } TessCtrl; - - /** - * Tessellation Evaluation shader state from layout qualifiers. - */ - struct { - /** - * GL_TRIANGLES, GL_QUADS, GL_ISOLINES or PRIM_UNKNOWN if it's not set - * in this shader. - */ - GLenum16 PrimitiveMode; - - enum gl_tess_spacing Spacing; - - /** - * GL_CW, GL_CCW, or 0 if it's not set in this shader. - */ - GLenum16 VertexOrder; - /** - * 1, 0, or -1 if it's not set in this shader. - */ - int PointMode; - } TessEval; - - /** - * Geometry shader state from GLSL 1.50 layout qualifiers. - */ - struct { - GLint VerticesOut; - /** - * 0 - Invocations count not declared in shader, or - * 1 .. Const.MaxGeometryShaderInvocations - */ - GLint Invocations; - /** - * GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or - * GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set in this - * shader. - */ - GLenum16 InputType; - /** - * GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP, or PRIM_UNKNOWN if - * it's not set in this shader. - */ - GLenum16 OutputType; - } Geom; - - /** - * Compute shader state from ARB_compute_shader and - * ARB_compute_variable_group_size layout qualifiers. - */ - struct { - /** - * Size specified using local_size_{x,y,z}, or all 0's to indicate that - * it's not set in this shader. - */ - unsigned LocalSize[3]; - - /** - * Whether a variable work group size has been specified as defined by - * ARB_compute_variable_group_size. - */ - bool LocalSizeVariable; - - /* - * Arrangement of invocations used to calculate derivatives in a compute - * shader. From NV_compute_shader_derivatives. - */ - enum gl_derivative_group DerivativeGroup; - } Comp; -}; - -/** - * A linked GLSL shader object. - */ -struct gl_linked_shader -{ - gl_shader_stage Stage; - -#ifdef DEBUG - unsigned SourceChecksum; -#endif - - struct gl_program *Program; /**< Post-compile assembly code */ - - /** - * \name Sampler tracking - * - * \note Each of these fields is only set post-linking. - */ - /*@{*/ - GLbitfield shadow_samplers; /**< Samplers used for shadow sampling. */ - /*@}*/ - - /** - * Number of default uniform block components used by this shader. - * - * This field is only set post-linking. - */ - unsigned num_uniform_components; - - /** - * Number of combined uniform components used by this shader. - * - * This field is only set post-linking. It is the sum of the uniform block - * sizes divided by sizeof(float), and num_uniform_compoennts. - */ - unsigned num_combined_uniform_components; - - struct exec_list *ir; - struct exec_list *packed_varyings; - struct exec_list *fragdata_arrays; - struct glsl_symbol_table *symbols; - - /** - * ARB_gl_spirv related data. - * - * This is actually a reference to the gl_shader::spirv_data, which - * stores information that is also needed during linking. - */ - struct gl_shader_spirv_data *spirv_data; -}; - - -/** - * Compile status enum. COMPILE_SKIPPED is used to indicate the compile - * was skipped due to the shader matching one that's been seen before by - * the on-disk cache. - */ -enum gl_compile_status -{ - COMPILE_FAILURE = 0, - COMPILE_SUCCESS, - COMPILE_SKIPPED -}; - -/** - * A GLSL shader object. - */ -struct gl_shader -{ - /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB || - * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER. - * Must be the first field. - */ - GLenum16 Type; - gl_shader_stage Stage; - GLuint Name; /**< AKA the handle */ - GLint RefCount; /**< Reference count */ - GLchar *Label; /**< GL_KHR_debug */ - unsigned char sha1[20]; /**< SHA1 hash of pre-processed source */ - GLboolean DeletePending; - bool IsES; /**< True if this shader uses GLSL ES */ - - enum gl_compile_status CompileStatus; - -#ifdef DEBUG - unsigned SourceChecksum; /**< for debug/logging purposes */ -#endif - const GLchar *Source; /**< Source code string */ - - const GLchar *FallbackSource; /**< Fallback string used by on-disk cache*/ - - GLchar *InfoLog; - - unsigned Version; /**< GLSL version used for linking */ - - /** - * A bitmask of gl_advanced_blend_mode values - */ - GLbitfield BlendSupport; - - struct exec_list *ir; - struct glsl_symbol_table *symbols; - - /** - * Whether early fragment tests are enabled as defined by - * ARB_shader_image_load_store. - */ - bool EarlyFragmentTests; - - bool ARB_fragment_coord_conventions_enable; - - bool redeclares_gl_fragcoord; - bool uses_gl_fragcoord; - - bool PostDepthCoverage; - bool PixelInterlockOrdered; - bool PixelInterlockUnordered; - bool SampleInterlockOrdered; - bool SampleInterlockUnordered; - bool InnerCoverage; - - /** - * Fragment shader state from GLSL 1.50 layout qualifiers. - */ - bool origin_upper_left; - bool pixel_center_integer; - - /** - * Whether bindless_sampler/bindless_image, and respectively - * bound_sampler/bound_image are declared at global scope as defined by - * ARB_bindless_texture. - */ - bool bindless_sampler; - bool bindless_image; - bool bound_sampler; - bool bound_image; - - /** - * Whether layer output is viewport-relative. - */ - bool redeclares_gl_layer; - bool layer_viewport_relative; - - /** Global xfb_stride out qualifier if any */ - GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS]; - - struct gl_shader_info info; - - /* ARB_gl_spirv related data */ - struct gl_shader_spirv_data *spirv_data; -}; - - -struct gl_uniform_buffer_variable -{ - char *Name; - - /** - * Name of the uniform as seen by glGetUniformIndices. - * - * glGetUniformIndices requires that the block instance index \b not be - * present in the name of queried uniforms. - * - * \note - * \c gl_uniform_buffer_variable::IndexName and - * \c gl_uniform_buffer_variable::Name may point to identical storage. - */ - char *IndexName; - - const struct glsl_type *Type; - unsigned int Offset; - GLboolean RowMajor; -}; - - -struct gl_uniform_block -{ - /** Declared name of the uniform block */ - char *Name; - - /** Array of supplemental information about UBO ir_variables. */ - struct gl_uniform_buffer_variable *Uniforms; - GLuint NumUniforms; - - /** - * Index (GL_UNIFORM_BLOCK_BINDING) into ctx->UniformBufferBindings[] to use - * with glBindBufferBase to bind a buffer object to this uniform block. - */ - GLuint Binding; - - /** - * Minimum size (in bytes) of a buffer object to back this uniform buffer - * (GL_UNIFORM_BLOCK_DATA_SIZE). - */ - GLuint UniformBufferSize; - - /** Stages that reference this block */ - uint8_t stageref; - - /** - * Linearized array index for uniform block instance arrays - * - * Given a uniform block instance array declared with size - * blk[s_0][s_1]..[s_m], the block referenced by blk[i_0][i_1]..[i_m] will - * have the linearized array index - * - * m-1 m - * i_m + ∑ i_j * ∏ s_k - * j=0 k=j+1 - * - * For a uniform block instance that is not an array, this is always 0. - */ - uint8_t linearized_array_index; - - /** - * Layout specified in the shader - * - * This isn't accessible through the API, but it is used while - * cross-validating uniform blocks. - */ - enum glsl_interface_packing _Packing; - GLboolean _RowMajor; -}; - -/** - * Structure that represents a reference to an atomic buffer from some - * shader program. - */ -struct gl_active_atomic_buffer -{ - /** Uniform indices of the atomic counters declared within it. */ - GLuint *Uniforms; - GLuint NumUniforms; - - /** Binding point index associated with it. */ - GLuint Binding; - - /** Minimum reasonable size it is expected to have. */ - GLuint MinimumSize; - - /** Shader stages making use of it. */ - GLboolean StageReferences[MESA_SHADER_STAGES]; -}; - -/** - * Data container for shader queries. This holds only the minimal - * amount of required information for resource queries to work. - */ -struct gl_shader_variable -{ - /** - * Declared type of the variable - */ - const struct glsl_type *type; - - /** - * If the variable is in an interface block, this is the type of the block. - */ - const struct glsl_type *interface_type; - - /** - * For variables inside structs (possibly recursively), this is the - * outermost struct type. - */ - const struct glsl_type *outermost_struct_type; - - /** - * Declared name of the variable - */ - char *name; - - /** - * Storage location of the base of this variable - * - * The precise meaning of this field depends on the nature of the variable. - * - * - Vertex shader input: one of the values from \c gl_vert_attrib. - * - Vertex shader output: one of the values from \c gl_varying_slot. - * - Geometry shader input: one of the values from \c gl_varying_slot. - * - Geometry shader output: one of the values from \c gl_varying_slot. - * - Fragment shader input: one of the values from \c gl_varying_slot. - * - Fragment shader output: one of the values from \c gl_frag_result. - * - Uniforms: Per-stage uniform slot number for default uniform block. - * - Uniforms: Index within the uniform block definition for UBO members. - * - Non-UBO Uniforms: explicit location until linking then reused to - * store uniform slot number. - * - Other: This field is not currently used. - * - * If the variable is a uniform, shader input, or shader output, and the - * slot has not been assigned, the value will be -1. - */ - int location; - - /** - * Specifies the first component the variable is stored in as per - * ARB_enhanced_layouts. - */ - unsigned component:2; - - /** - * Output index for dual source blending. - * - * \note - * The GLSL spec only allows the values 0 or 1 for the index in \b dual - * source blending. - */ - unsigned index:1; - - /** - * Specifies whether a shader input/output is per-patch in tessellation - * shader stages. - */ - unsigned patch:1; - - /** - * Storage class of the variable. - * - * \sa (n)ir_variable_mode - */ - unsigned mode:4; - - /** - * Interpolation mode for shader inputs / outputs - * - * \sa glsl_interp_mode - */ - unsigned interpolation:2; - - /** - * Was the location explicitly set in the shader? - * - * If the location is explicitly set in the shader, it \b cannot be changed - * by the linker or by the API (e.g., calls to \c glBindAttribLocation have - * no effect). - */ - unsigned explicit_location:1; - - /** - * Precision qualifier. - */ - unsigned precision:2; -}; - -/** - * Active resource in a gl_shader_program - */ -struct gl_program_resource -{ - GLenum16 Type; /** Program interface type. */ - const void *Data; /** Pointer to resource associated data structure. */ - uint8_t StageReferences; /** Bitmask of shader stage references. */ -}; - -/** - * Link status enum. LINKING_SKIPPED is used to indicate linking - * was skipped due to the shader being loaded from the on-disk cache. - */ -enum gl_link_status -{ - LINKING_FAILURE = 0, - LINKING_SUCCESS, - LINKING_SKIPPED -}; - -/** - * A data structure to be shared by gl_shader_program and gl_program. - */ -struct gl_shader_program_data -{ - GLint RefCount; /**< Reference count */ - - /** SHA1 hash of linked shader program */ - unsigned char sha1[20]; - - unsigned NumUniformStorage; - unsigned NumHiddenUniforms; - struct gl_uniform_storage *UniformStorage; - - unsigned NumUniformBlocks; - unsigned NumShaderStorageBlocks; - - struct gl_uniform_block *UniformBlocks; - struct gl_uniform_block *ShaderStorageBlocks; - - struct gl_active_atomic_buffer *AtomicBuffers; - unsigned NumAtomicBuffers; - - /* Shader cache variables used during restore */ - unsigned NumUniformDataSlots; - union gl_constant_value *UniformDataSlots; - - /* Used to hold initial uniform values for program binary restores. - * - * From the ARB_get_program_binary spec: - * - * "A successful call to ProgramBinary will reset all uniform - * variables to their initial values. The initial value is either - * the value of the variable's initializer as specified in the - * original shader source, or 0 if no initializer was present. - */ - union gl_constant_value *UniformDataDefaults; - - /** Hash for quick search by name. */ - struct hash_table_u64 *ProgramResourceHash; - - GLboolean Validated; - - /** List of all active resources after linking. */ - struct gl_program_resource *ProgramResourceList; - unsigned NumProgramResourceList; - - enum gl_link_status LinkStatus; /**< GL_LINK_STATUS */ - GLchar *InfoLog; - - unsigned Version; /**< GLSL version used for linking */ - - /* Mask of stages this program was linked against */ - unsigned linked_stages; - - /* Whether the shaders of this program are loaded from SPIR-V binaries - * (all have the SPIR_V_BINARY_ARB state). This was introduced by the - * ARB_gl_spirv extension. - */ - bool spirv; -}; - -/** - * A GLSL program object. - * Basically a linked collection of vertex and fragment shaders. - */ -struct gl_shader_program -{ - GLenum16 Type; /**< Always GL_SHADER_PROGRAM (internal token) */ - GLuint Name; /**< aka handle or ID */ - GLchar *Label; /**< GL_KHR_debug */ - GLint RefCount; /**< Reference count */ - GLboolean DeletePending; - - /** - * Is the application intending to glGetProgramBinary this program? - * - * BinaryRetrievableHint is the currently active hint that gets set - * during initialization and after linking and BinaryRetrievableHintPending - * is the hint set by the user to be active when program is linked next time. - */ - GLboolean BinaryRetrievableHint; - GLboolean BinaryRetrievableHintPending; - - /** - * Indicates whether program can be bound for individual pipeline stages - * using UseProgramStages after it is next linked. - */ - GLboolean SeparateShader; - - GLuint NumShaders; /**< number of attached shaders */ - struct gl_shader **Shaders; /**< List of attached the shaders */ - - /** - * User-defined attribute bindings - * - * These are set via \c glBindAttribLocation and are used to direct the - * GLSL linker. These are \b not the values used in the compiled shader, - * and they are \b not the values returned by \c glGetAttribLocation. - */ - struct string_to_uint_map *AttributeBindings; - - /** - * User-defined fragment data bindings - * - * These are set via \c glBindFragDataLocation and are used to direct the - * GLSL linker. These are \b not the values used in the compiled shader, - * and they are \b not the values returned by \c glGetFragDataLocation. - */ - struct string_to_uint_map *FragDataBindings; - struct string_to_uint_map *FragDataIndexBindings; - - /** - * Transform feedback varyings last specified by - * glTransformFeedbackVaryings(). - * - * For the current set of transform feedback varyings used for transform - * feedback output, see LinkedTransformFeedback. - */ - struct { - GLenum16 BufferMode; - /** Global xfb_stride out qualifier if any */ - GLuint BufferStride[MAX_FEEDBACK_BUFFERS]; - GLuint NumVarying; - GLchar **VaryingNames; /**< Array [NumVarying] of char * */ - } TransformFeedback; - - struct gl_program *last_vert_prog; - - /** Post-link gl_FragDepth layout for ARB_conservative_depth. */ - enum gl_frag_depth_layout FragDepthLayout; - - /** - * Geometry shader state - copied into gl_program by - * _mesa_copy_linked_program_data(). - */ - struct { - GLint VerticesIn; - - bool UsesEndPrimitive; - unsigned ActiveStreamMask; - } Geom; - - /** - * Compute shader state - copied into gl_program by - * _mesa_copy_linked_program_data(). - */ - struct { - /** - * Size of shared variables accessed by the compute shader. - */ - unsigned SharedSize; - } Comp; - - /** Data shared by gl_program and gl_shader_program */ - struct gl_shader_program_data *data; - - /** - * Mapping from GL uniform locations returned by \c glUniformLocation to - * UniformStorage entries. Arrays will have multiple contiguous slots - * in the UniformRemapTable, all pointing to the same UniformStorage entry. - */ - unsigned NumUniformRemapTable; - struct gl_uniform_storage **UniformRemapTable; - - /** - * Sometimes there are empty slots left over in UniformRemapTable after we - * allocate slots to explicit locations. This list stores the blocks of - * continuous empty slots inside UniformRemapTable. - */ - struct exec_list EmptyUniformLocations; - - /** - * Total number of explicit uniform location including inactive uniforms. - */ - unsigned NumExplicitUniformLocations; - - /** - * Map of active uniform names to locations - * - * Maps any active uniform that is not an array element to a location. - * Each active uniform, including individual structure members will appear - * in this map. This roughly corresponds to the set of names that would be - * enumerated by \c glGetActiveUniform. - */ - struct string_to_uint_map *UniformHash; - - GLboolean SamplersValidated; /**< Samplers validated against texture units? */ - - bool IsES; /**< True if this program uses GLSL ES */ - - /** - * Per-stage shaders resulting from the first stage of linking. - * - * Set of linked shaders for this program. The array is accessed using the - * \c MESA_SHADER_* defines. Entries for non-existent stages will be - * \c NULL. - */ - struct gl_linked_shader *_LinkedShaders[MESA_SHADER_STAGES]; - - /** - * True if any of the fragment shaders attached to this program use: - * #extension ARB_fragment_coord_conventions: enable - */ - GLboolean ARB_fragment_coord_conventions_enable; -}; - - #define GLSL_DUMP 0x1 /**< Dump shaders to stdout */ #define GLSL_LOG 0x2 /**< Write shaders to files */ #define GLSL_UNIFORMS 0x4 /**< Print glUniform calls */ @@ -3180,6 +2240,7 @@ struct gl_shader_program #define GLSL_DUMP_ON_ERROR 0x80 /**< Dump shaders to stderr on compile error */ #define GLSL_CACHE_INFO 0x100 /**< Print debug information about shader cache */ #define GLSL_CACHE_FALLBACK 0x200 /**< Force shader cache fallback paths */ +#define GLSL_SOURCE 0x400 /**< Only dump GLSL */ /** @@ -3233,81 +2294,10 @@ struct gl_pipeline_shader_state struct gl_pipeline_object *Default; /** Pipeline objects */ - struct _mesa_HashTable *Objects; + struct _mesa_HashTable Objects; }; /** - * Compiler options for a single GLSL shaders type - */ -struct gl_shader_compiler_options -{ - /** Driver-selectable options: */ - GLboolean EmitNoLoops; - GLboolean EmitNoCont; /**< Emit CONT opcode? */ - GLboolean EmitNoMainReturn; /**< Emit CONT/RET opcodes? */ - GLboolean EmitNoPow; /**< Emit POW opcodes? */ - GLboolean EmitNoSat; /**< Emit SAT opcodes? */ - GLboolean LowerCombinedClipCullDistance; /** Lower gl_ClipDistance and - * gl_CullDistance together from - * float[8] to vec4[2] - **/ - GLbitfield LowerBuiltinVariablesXfb; /**< Which builtin variables should - * be lowered for transform feedback - **/ - - /** - * If we can lower the precision of variables based on precision - * qualifiers - */ - GLboolean LowerPrecisionFloat16; - GLboolean LowerPrecisionInt16; - GLboolean LowerPrecisionDerivatives; - GLboolean LowerPrecisionFloat16Uniforms; - - /** - * This enables lowering of 16b constants. Some drivers may not - * to lower constants to 16b (ie. if the hw can do automatic - * narrowing on constant load) - */ - GLboolean LowerPrecisionConstants; - - /** - * \name Forms of indirect addressing the driver cannot do. - */ - /*@{*/ - GLboolean EmitNoIndirectInput; /**< No indirect addressing of inputs */ - GLboolean EmitNoIndirectOutput; /**< No indirect addressing of outputs */ - GLboolean EmitNoIndirectTemp; /**< No indirect addressing of temps */ - GLboolean EmitNoIndirectUniform; /**< No indirect addressing of constants */ - GLboolean EmitNoIndirectSampler; /**< No indirect addressing of samplers */ - /*@}*/ - - GLuint MaxIfDepth; /**< Maximum nested IF blocks */ - GLuint MaxUnrollIterations; - - /** - * Optimize code for array of structures backends. - * - * This is a proxy for: - * - preferring DP4 instructions (rather than MUL/MAD) for - * matrix * vector operations, such as position transformation. - */ - GLboolean OptimizeForAOS; - - /** Lower UBO and SSBO access to intrinsics. */ - GLboolean LowerBufferInterfaceBlocks; - - /** Clamp UBO and SSBO block indices so they don't go out-of-bounds. */ - GLboolean ClampBlockIndicesToArrayBounds; - - /** (driconf) Force gl_Position to be considered invariant */ - GLboolean PositionAlwaysInvariant; - - const struct nir_shader_compiler_options *NirOptions; -}; - - -/** * Occlusion/timer query object. */ struct gl_query_object @@ -3320,6 +2310,13 @@ struct gl_query_object GLboolean Ready; /**< result is ready? */ GLboolean EverBound;/**< has query object ever been bound */ GLuint Stream; /**< The stream */ + + struct pipe_query *pq; + + /* Begin TIMESTAMP query for GL_TIME_ELAPSED_EXT queries */ + struct pipe_query *pq_begin; + + unsigned type; /**< PIPE_QUERY_x */ }; @@ -3328,7 +2325,7 @@ struct gl_query_object */ struct gl_query_state { - struct _mesa_HashTable *QueryObjects; + struct _mesa_HashTable QueryObjects; struct gl_query_object *CurrentOcclusionObject; /* GL_ARB_occlusion_query */ struct gl_query_object *CurrentTimerObject; /* GL_EXT_timer_query */ @@ -3365,6 +2362,9 @@ struct gl_sync_object GLenum16 SyncCondition; GLbitfield Flags; /**< Flags passed to glFenceSync */ GLuint StatusFlag:1; /**< Has the sync object been signaled? */ + + struct pipe_fence_handle *fence; + simple_mtx_t mutex; /**< protects "fence" */ }; @@ -3375,15 +2375,16 @@ struct gl_shared_state { simple_mtx_t Mutex; /**< for thread safety */ GLint RefCount; /**< Reference count */ - struct _mesa_HashTable *DisplayList; /**< Display lists hash table */ - struct _mesa_HashTable *BitmapAtlas; /**< For optimized glBitmap text */ - struct _mesa_HashTable *TexObjects; /**< Texture objects hash table */ + bool DisplayListsAffectGLThread; + + struct _mesa_HashTable DisplayList; /**< Display lists hash table */ + struct _mesa_HashTable TexObjects; /**< Texture objects hash table */ /** Default texture objects (shared by all texture units) */ struct gl_texture_object *DefaultTex[NUM_TEXTURE_TARGETS]; /** Fallback texture used when a bound texture is incomplete */ - struct gl_texture_object *FallbackTex[NUM_TEXTURE_TARGETS]; + struct gl_texture_object *FallbackTex[NUM_TEXTURE_TARGETS][2]; /**< [color, depth] */ /** * \name Thread safety and statechange notification for texture @@ -3392,7 +2393,7 @@ struct gl_shared_state * \todo Improve the granularity of locking. */ /*@{*/ - mtx_t TexMutex; /**< texobj thread safety */ + simple_mtx_t TexMutex; /**< texobj thread safety */ GLuint TextureStateStamp; /**< state notification for shared tex */ /*@}*/ @@ -3400,16 +2401,16 @@ struct gl_shared_state * \name Vertex/geometry/fragment programs */ /*@{*/ - struct _mesa_HashTable *Programs; /**< All vertex/fragment programs */ + struct _mesa_HashTable Programs; /**< All vertex/fragment programs */ struct gl_program *DefaultVertexProgram; struct gl_program *DefaultFragmentProgram; /*@}*/ /* GL_ATI_fragment_shader */ - struct _mesa_HashTable *ATIShaders; + struct _mesa_HashTable ATIShaders; struct ati_fragment_shader *DefaultFragmentShader; - struct _mesa_HashTable *BufferObjects; + struct _mesa_HashTable BufferObjects; /* Buffer objects released by a different context than the one that * created them. Since the creating context holds one global buffer @@ -3425,17 +2426,17 @@ struct gl_shared_state struct set *ZombieBufferObjects; /** Table of both gl_shader and gl_shader_program objects */ - struct _mesa_HashTable *ShaderObjects; + struct _mesa_HashTable ShaderObjects; /* GL_EXT_framebuffer_object */ - struct _mesa_HashTable *RenderBuffers; - struct _mesa_HashTable *FrameBuffers; + struct _mesa_HashTable RenderBuffers; + struct _mesa_HashTable FrameBuffers; /* GL_ARB_sync */ struct set *SyncObjects; /** GL_ARB_sampler_objects */ - struct _mesa_HashTable *SamplerObjects; + struct _mesa_HashTable SamplerObjects; /* GL_ARB_bindless_texture */ struct hash_table_u64 *TextureHandles; @@ -3447,33 +2448,44 @@ struct gl_shared_state /* glCompileShaderInclude expects ShaderIncludes not to change while it is * in progress. */ - mtx_t ShaderIncludeMutex; - - /** - * Some context in this share group was affected by a GPU reset - * - * On the next call to \c glGetGraphicsResetStatus, contexts that have not - * been affected by a GPU reset must also return - * \c GL_INNOCENT_CONTEXT_RESET_ARB. - * - * Once this field becomes true, it is never reset to false. - */ - bool ShareGroupReset; + simple_mtx_t ShaderIncludeMutex; /** EXT_external_objects */ - struct _mesa_HashTable *MemoryObjects; + struct _mesa_HashTable MemoryObjects; /** EXT_semaphore */ - struct _mesa_HashTable *SemaphoreObjects; + struct _mesa_HashTable SemaphoreObjects; /** - * Some context in this share group was affected by a disjoint - * operation. This operation can be anything that has effects on - * values of timer queries in such manner that they become invalid for - * performance metrics. As example gpu reset, counter overflow or gpu - * frequency changes. + * Whether at least one image has been imported or exported, excluding + * the default framebuffer. If this is false, glFlush can be executed + * asynchronously because there is no invisible dependency on external + * users. */ - bool DisjointOperation; + bool HasExternallySharedImages; + + /* Small display list storage */ + struct { + union gl_dlist_node *ptr; + struct util_idalloc free_idx; + unsigned size; + } small_dlist_store; + + /* Global GLThread state. */ + struct { + /* The last context that locked global mutexes. */ + struct gl_context *LastExecutingCtx; + + /* The last time LastExecutingCtx started executing after a different + * context (the time of multiple active contexts). + */ + int64_t LastContextSwitchTime; + + /* The time for which no context can lock global mutexes since + * LastContextSwitchTime. + */ + int64_t NoLockDuration; + } GLThread; }; @@ -3485,24 +2497,12 @@ struct gl_shared_state */ struct gl_renderbuffer { - simple_mtx_t Mutex; /**< for thread safety */ - GLuint ClassID; /**< Useful for drivers */ GLuint Name; GLchar *Label; /**< GL_KHR_debug */ GLint RefCount; GLuint Width, Height; GLuint Depth; - GLboolean Purgeable; /**< Is the buffer purgeable under memory pressure? */ GLboolean AttachedAnytime; /**< TRUE if it was attached to a framebuffer */ - /** - * True for renderbuffers that wrap textures, giving the driver a chance to - * flush render caches through the FinishRenderTexture hook. - * - * Drivers may also set this on renderbuffers other than those generated by - * glFramebufferTexture(), though it means FinishRenderTexture() would be - * called without a rb->TexImage. - */ - GLboolean NeedsFinishRenderTexture; GLubyte NumSamples; /**< zero means not multisampled */ GLubyte NumStorageSamples; /**< for AMD_framebuffer_multisample_advanced */ GLenum16 InternalFormat; /**< The user-specified format */ @@ -3526,6 +2526,31 @@ struct gl_renderbuffer struct gl_renderbuffer *rb, GLenum internalFormat, GLuint width, GLuint height); + + struct pipe_resource *texture; + /* This points to either "surface_linear" or "surface_srgb". + * It doesn't hold the pipe_surface reference. The other two do. + */ + struct pipe_surface *surface; + struct pipe_surface *surface_linear; + struct pipe_surface *surface_srgb; + GLboolean defined; /**< defined contents? */ + + struct pipe_transfer *transfer; /**< only used when mapping the resource */ + + /** + * Used only when hardware accumulation buffers are not supported. + */ + bool software; + void *data; + + bool use_readpix_cache; + + /* Inputs from Driver.RenderTexture, don't use directly. */ + bool is_rtt; /**< whether Driver.RenderTexture was called */ + unsigned rtt_face, rtt_slice; + bool rtt_layered; /**< whether glFramebufferTexture was called */ + unsigned rtt_nr_samples; /**< from FramebufferTexture2DMultisampleEXT */ }; @@ -3642,7 +2667,8 @@ struct gl_framebuffer bool _HasAttachments; GLbitfield _IntegerBuffers; /**< Which color buffers are integer valued */ - GLbitfield _RGBBuffers; /**< Which color buffers have baseformat == RGB */ + GLbitfield _BlendForceAlphaToOne; /**< Which color buffers need blend factor adjustment */ + GLbitfield _IsRGB; /**< Which color buffers have an RGB base format? */ GLbitfield _FP32Buffers; /**< Which color buffers are FP32 */ /* ARB_color_buffer_float */ @@ -3660,6 +2686,7 @@ struct gl_framebuffer /** Array of all renderbuffer attachments, indexed by BUFFER_* tokens. */ struct gl_renderbuffer_attachment Attachment[BUFFER_COUNT]; + struct pipe_resource *resolve; /**< color resolve attachment */ /* In unextended OpenGL these vars are part of the GL_COLOR_BUFFER * attribute group and GL_PIXEL attribute group, respectively. @@ -3684,891 +2711,18 @@ struct gl_framebuffer /** Delete this framebuffer */ void (*Delete)(struct gl_framebuffer *fb); -}; - - -/** - * Precision info for shader datatypes. See glGetShaderPrecisionFormat(). - */ -struct gl_precision -{ - GLushort RangeMin; /**< min value exponent */ - GLushort RangeMax; /**< max value exponent */ - GLushort Precision; /**< number of mantissa bits */ -}; - - -/** - * Limits for vertex, geometry and fragment programs/shaders. - */ -struct gl_program_constants -{ - /* logical limits */ - GLuint MaxInstructions; - GLuint MaxAluInstructions; - GLuint MaxTexInstructions; - GLuint MaxTexIndirections; - GLuint MaxAttribs; - GLuint MaxTemps; - GLuint MaxAddressRegs; - GLuint MaxAddressOffset; /**< [-MaxAddressOffset, MaxAddressOffset-1] */ - GLuint MaxParameters; - GLuint MaxLocalParams; - GLuint MaxEnvParams; - /* native/hardware limits */ - GLuint MaxNativeInstructions; - GLuint MaxNativeAluInstructions; - GLuint MaxNativeTexInstructions; - GLuint MaxNativeTexIndirections; - GLuint MaxNativeAttribs; - GLuint MaxNativeTemps; - GLuint MaxNativeAddressRegs; - GLuint MaxNativeParameters; - /* For shaders */ - GLuint MaxUniformComponents; /**< Usually == MaxParameters * 4 */ - - /** - * \name Per-stage input / output limits - * - * Previous to OpenGL 3.2, the intrastage data limits were advertised with - * a single value: GL_MAX_VARYING_COMPONENTS (GL_MAX_VARYING_VECTORS in - * ES). This is stored as \c gl_constants::MaxVarying. - * - * Starting with OpenGL 3.2, the limits are advertised with per-stage - * variables. Each stage as a certain number of outputs that it can feed - * to the next stage and a certain number inputs that it can consume from - * the previous stage. - * - * Vertex shader inputs do not participate this in this accounting. - * These are tracked exclusively by \c gl_program_constants::MaxAttribs. - * - * Fragment shader outputs do not participate this in this accounting. - * These are tracked exclusively by \c gl_constants::MaxDrawBuffers. - */ - /*@{*/ - GLuint MaxInputComponents; - GLuint MaxOutputComponents; - /*@}*/ - - /* ES 2.0 and GL_ARB_ES2_compatibility */ - struct gl_precision LowFloat, MediumFloat, HighFloat; - struct gl_precision LowInt, MediumInt, HighInt; - /* GL_ARB_uniform_buffer_object */ - GLuint MaxUniformBlocks; - uint64_t MaxCombinedUniformComponents; - GLuint MaxTextureImageUnits; - - /* GL_ARB_shader_atomic_counters */ - GLuint MaxAtomicBuffers; - GLuint MaxAtomicCounters; - - /* GL_ARB_shader_image_load_store */ - GLuint MaxImageUniforms; - - /* GL_ARB_shader_storage_buffer_object */ - GLuint MaxShaderStorageBlocks; -}; - -/** - * Constants which may be overridden by device driver during context creation - * but are never changed after that. - */ -struct gl_constants -{ - GLuint MaxTextureMbytes; /**< Max memory per image, in MB */ - GLuint MaxTextureSize; /**< Max 1D/2D texture size, in pixels*/ - GLuint Max3DTextureLevels; /**< Max mipmap levels for 3D textures */ - GLuint MaxCubeTextureLevels; /**< Max mipmap levels for cube textures */ - GLuint MaxArrayTextureLayers; /**< Max layers in array textures */ - GLuint MaxTextureRectSize; /**< Max rectangle texture size, in pixes */ - GLuint MaxTextureCoordUnits; - GLuint MaxCombinedTextureImageUnits; - GLuint MaxTextureUnits; /**< = MIN(CoordUnits, FragmentProgram.ImageUnits) */ - GLfloat MaxTextureMaxAnisotropy; /**< GL_EXT_texture_filter_anisotropic */ - GLfloat MaxTextureLodBias; /**< GL_EXT_texture_lod_bias */ - GLuint MaxTextureBufferSize; /**< GL_ARB_texture_buffer_object */ - - GLuint TextureBufferOffsetAlignment; /**< GL_ARB_texture_buffer_range */ - - GLuint MaxArrayLockSize; - - GLint SubPixelBits; - - GLfloat MinPointSize, MaxPointSize; /**< aliased */ - GLfloat MinPointSizeAA, MaxPointSizeAA; /**< antialiased */ - GLfloat PointSizeGranularity; - GLfloat MinLineWidth, MaxLineWidth; /**< aliased */ - GLfloat MinLineWidthAA, MaxLineWidthAA; /**< antialiased */ - GLfloat LineWidthGranularity; - - GLuint MaxClipPlanes; - GLuint MaxLights; - GLfloat MaxShininess; /**< GL_NV_light_max_exponent */ - GLfloat MaxSpotExponent; /**< GL_NV_light_max_exponent */ - - GLuint MaxViewportWidth, MaxViewportHeight; - GLuint MaxViewports; /**< GL_ARB_viewport_array */ - GLuint ViewportSubpixelBits; /**< GL_ARB_viewport_array */ - struct { - GLfloat Min; - GLfloat Max; - } ViewportBounds; /**< GL_ARB_viewport_array */ - GLuint MaxWindowRectangles; /**< GL_EXT_window_rectangles */ - - struct gl_program_constants Program[MESA_SHADER_STAGES]; - GLuint MaxProgramMatrices; - GLuint MaxProgramMatrixStackDepth; - - struct { - GLuint SamplesPassed; - GLuint TimeElapsed; - GLuint Timestamp; - GLuint PrimitivesGenerated; - GLuint PrimitivesWritten; - GLuint VerticesSubmitted; - GLuint PrimitivesSubmitted; - GLuint VsInvocations; - GLuint TessPatches; - GLuint TessInvocations; - GLuint GsInvocations; - GLuint GsPrimitives; - GLuint FsInvocations; - GLuint ComputeInvocations; - GLuint ClInPrimitives; - GLuint ClOutPrimitives; - } QueryCounterBits; - - GLuint MaxDrawBuffers; /**< GL_ARB_draw_buffers */ - - GLuint MaxColorAttachments; /**< GL_EXT_framebuffer_object */ - GLuint MaxRenderbufferSize; /**< GL_EXT_framebuffer_object */ - GLuint MaxSamples; /**< GL_ARB_framebuffer_object */ - - /** - * GL_ARB_framebuffer_no_attachments - */ - GLuint MaxFramebufferWidth; - GLuint MaxFramebufferHeight; - GLuint MaxFramebufferLayers; - GLuint MaxFramebufferSamples; - - /** Number of varying vectors between any two shader stages. */ - GLuint MaxVarying; - - /** @{ - * GL_ARB_uniform_buffer_object - */ - GLuint MaxCombinedUniformBlocks; - GLuint MaxUniformBufferBindings; - GLuint MaxUniformBlockSize; - GLuint UniformBufferOffsetAlignment; - /** @} */ - - /** @{ - * GL_ARB_shader_storage_buffer_object - */ - GLuint MaxCombinedShaderStorageBlocks; - GLuint MaxShaderStorageBufferBindings; - GLuint MaxShaderStorageBlockSize; - GLuint ShaderStorageBufferOffsetAlignment; - /** @} */ - - /** - * GL_ARB_explicit_uniform_location - */ - GLuint MaxUserAssignableUniformLocations; - - /** geometry shader */ - GLuint MaxGeometryOutputVertices; - GLuint MaxGeometryTotalOutputComponents; - GLuint MaxGeometryShaderInvocations; - - GLuint GLSLVersion; /**< Desktop GLSL version supported (ex: 120 = 1.20) */ - GLuint GLSLVersionCompat; /**< Desktop compat GLSL version supported */ - - /** - * Changes default GLSL extension behavior from "error" to "warn". It's out - * of spec, but it can make some apps work that otherwise wouldn't. - */ - GLboolean ForceGLSLExtensionsWarn; - - /** - * If non-zero, forces GLSL shaders to behave as if they began - * with "#version ForceGLSLVersion". - */ - GLuint ForceGLSLVersion; - - /** - * Allow GLSL #extension directives in the middle of shaders. - */ - GLboolean AllowGLSLExtensionDirectiveMidShader; - - /** - * Allow a subset of GLSL 1.20 in GLSL 1.10 as needed by SPECviewperf13. - */ - GLboolean AllowGLSL120SubsetIn110; - - /** - * Allow builtins as part of constant expressions. This was not allowed - * until GLSL 1.20 this allows it everywhere. - */ - GLboolean AllowGLSLBuiltinConstantExpression; - - /** - * Allow some relaxation of GLSL ES shader restrictions. This encompasses - * a number of relaxations to the ES shader rules. - */ - GLboolean AllowGLSLRelaxedES; - - /** - * Allow GLSL built-in variables to be redeclared verbatim - */ - GLboolean AllowGLSLBuiltinVariableRedeclaration; - - /** - * Allow GLSL interpolation qualifier mismatch across shader stages. - */ - GLboolean AllowGLSLCrossStageInterpolationMismatch; - - /** - * Allow creating a higher compat profile (version 3.1+) for apps that - * request it. Be careful when adding that driconf option because some - * features are unimplemented and might not work correctly. - */ - GLboolean AllowHigherCompatVersion; - - /** - * Allow extra tokens at end of preprocessor directives. The CTS now tests - * to make sure these are not allowed. However, previously drivers would - * allow them to exist and just issue a warning so some old applications - * depend on this. - */ - GLboolean AllowExtraPPTokens; - - /** - * Force computing the absolute value for sqrt() and inversesqrt() to follow - * D3D9 when apps rely on this behaviour. - */ - GLboolean ForceGLSLAbsSqrt; - - /** - * Types of variable to default initialized to zero. Supported values are: - * - 0: no zero initialization - * - 1: all shader variables and gl_FragColor are initialiazed to 0 - * - 2: same as 1, but shader out variables are *not* initialized, while - * function out variables are now initialized. - */ - GLchar GLSLZeroInit; - - /** - * Force GL names reuse. Needed by SPECviewperf13. - */ - GLboolean ForceGLNamesReuse; - - /** - * Treat integer textures using GL_LINEAR filters as GL_NEAREST. - */ - GLboolean ForceIntegerTexNearest; - - /** - * Does the driver support real 32-bit integers? (Otherwise, integers are - * simulated via floats.) - */ - GLboolean NativeIntegers; - - /** - * Does VertexID count from zero or from base vertex? - * - * \note - * If desktop GLSL 1.30 or GLSL ES 3.00 are not supported, this field is - * ignored and need not be set. - */ - bool VertexID_is_zero_based; - - /** - * If the driver supports real 32-bit integers, what integer value should be - * used for boolean true in uniform uploads? (Usually 1 or ~0.) - */ - GLuint UniformBooleanTrue; - /** - * Maximum amount of time, measured in nanseconds, that the server can wait. - */ - GLuint64 MaxServerWaitTimeout; - - /** GL_EXT_provoking_vertex */ - GLboolean QuadsFollowProvokingVertexConvention; - - /** GL_ARB_viewport_array */ - GLenum16 LayerAndVPIndexProvokingVertex; - - /** OpenGL version 3.0 */ - GLbitfield ContextFlags; /**< Ex: GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT */ - - /** OpenGL version 3.2 */ - GLbitfield ProfileMask; /**< Mask of CONTEXT_x_PROFILE_BIT */ - - /** OpenGL version 4.4 */ - GLuint MaxVertexAttribStride; - - /** GL_EXT_transform_feedback */ - GLuint MaxTransformFeedbackBuffers; - GLuint MaxTransformFeedbackSeparateComponents; - GLuint MaxTransformFeedbackInterleavedComponents; - GLuint MaxVertexStreams; - - /** GL_EXT_gpu_shader4 */ - GLint MinProgramTexelOffset, MaxProgramTexelOffset; - - /** GL_ARB_texture_gather */ - GLuint MinProgramTextureGatherOffset; - GLuint MaxProgramTextureGatherOffset; - GLuint MaxProgramTextureGatherComponents; - - /* GL_ARB_robustness */ - GLenum16 ResetStrategy; - - /* GL_KHR_robustness */ - GLboolean RobustAccess; - - /* GL_ARB_blend_func_extended */ - GLuint MaxDualSourceDrawBuffers; - - /** - * Whether the implementation strips out and ignores texture borders. - * - * Many GPU hardware implementations don't support rendering with texture - * borders and mipmapped textures. (Note: not static border color, but the - * old 1-pixel border around each edge). Implementations then have to do - * slow fallbacks to be correct, or just ignore the border and be fast but - * wrong. Setting the flag strips the border off of TexImage calls, - * providing "fast but wrong" at significantly reduced driver complexity. - * - * Texture borders are deprecated in GL 3.0. - **/ - GLboolean StripTextureBorder; - - /** - * For drivers which can do a better job at eliminating unused uniforms - * than the GLSL compiler. - * - * XXX Remove these as soon as a better solution is available. - */ - GLboolean GLSLSkipStrictMaxUniformLimitCheck; - - /** - * Whether gl_FragCoord, gl_PointCoord and gl_FrontFacing - * are system values. - **/ - bool GLSLFragCoordIsSysVal; - bool GLSLPointCoordIsSysVal; - bool GLSLFrontFacingIsSysVal; - - /** - * Run the minimum amount of GLSL optimizations to be able to link - * shaders optimally (eliminate dead varyings and uniforms) and just do - * all the necessary lowering. - */ - bool GLSLOptimizeConservatively; - - /** - * Whether to call lower_const_arrays_to_uniforms() during linking. - */ - bool GLSLLowerConstArrays; - - /** - * True if gl_TessLevelInner/Outer[] in the TES should be inputs - * (otherwise, they're system values). - */ - bool GLSLTessLevelsAsInputs; - - /** - * Always use the GetTransformFeedbackVertexCount() driver hook, rather - * than passing the transform feedback object to the drawing function. - */ - GLboolean AlwaysUseGetTransformFeedbackVertexCount; - - /** GL_ARB_map_buffer_alignment */ - GLuint MinMapBufferAlignment; - - /** - * Disable varying packing. This is out of spec, but potentially useful - * for older platforms that supports a limited number of texture - * indirections--on these platforms, unpacking the varyings in the fragment - * shader increases the number of texture indirections by 1, which might - * make some shaders not executable at all. - * - * Drivers that support transform feedback must set this value to GL_FALSE. - */ - GLboolean DisableVaryingPacking; - - /** - * Disable varying packing if used for transform feedback. This is needed - * for some drivers (e.g. Panfrost) where transform feedback requires - * unpacked varyings. - * - * This variable is mutually exlusive with DisableVaryingPacking. - */ - GLboolean DisableTransformFeedbackPacking; - - /** - * UBOs and SSBOs can be packed tightly by the OpenGL implementation when - * layout is set as shared (the default) or packed. However most Mesa drivers - * just use STD140 for these layouts. This flag allows drivers to use STD430 - * for packed and shared layouts which allows arrays to be packed more - * tightly. - */ - bool UseSTD430AsDefaultPacking; - - /** - * Should meaningful names be generated for compiler temporary variables? - * - * Generally, it is not useful to have the compiler generate "meaningful" - * names for temporary variables that it creates. This can, however, be a - * useful debugging aid. In Mesa debug builds or release builds when - * MESA_GLSL is set at run-time, meaningful names will be generated. - * Drivers can also force names to be generated by setting this field. - * For example, the i965 driver may set it when INTEL_DEBUG=vs (to dump - * vertex shader assembly) is set at run-time. - */ - bool GenerateTemporaryNames; - - /* - * Maximum value supported for an index in DrawElements and friends. - * - * This must be at least (1ull<<24)-1. The default value is - * (1ull<<32)-1. - * - * \since ES 3.0 or GL_ARB_ES3_compatibility - * \sa _mesa_init_constants - */ - GLuint64 MaxElementIndex; - - /** - * Disable interpretation of line continuations (lines ending with a - * backslash character ('\') in GLSL source. - */ - GLboolean DisableGLSLLineContinuations; - - /** GL_ARB_texture_multisample */ - GLint MaxColorTextureSamples; - GLint MaxDepthTextureSamples; - GLint MaxIntegerSamples; - - /** GL_AMD_framebuffer_multisample_advanced */ - GLint MaxColorFramebufferSamples; - GLint MaxColorFramebufferStorageSamples; - GLint MaxDepthStencilFramebufferSamples; - - /* An array of supported MSAA modes allowing different sample - * counts per attachment type. - */ - struct { - GLint NumColorSamples; - GLint NumColorStorageSamples; - GLint NumDepthStencilSamples; - } SupportedMultisampleModes[40]; - GLint NumSupportedMultisampleModes; - - /** GL_ARB_shader_atomic_counters */ - GLuint MaxAtomicBufferBindings; - GLuint MaxAtomicBufferSize; - GLuint MaxCombinedAtomicBuffers; - GLuint MaxCombinedAtomicCounters; - - /** GL_ARB_vertex_attrib_binding */ - GLint MaxVertexAttribRelativeOffset; - GLint MaxVertexAttribBindings; - - /* GL_ARB_shader_image_load_store */ - GLuint MaxImageUnits; - GLuint MaxCombinedShaderOutputResources; - GLuint MaxImageSamples; - GLuint MaxCombinedImageUniforms; - - /** GL_ARB_compute_shader */ - GLuint MaxComputeWorkGroupCount[3]; /* Array of x, y, z dimensions */ - GLuint MaxComputeWorkGroupSize[3]; /* Array of x, y, z dimensions */ - GLuint MaxComputeWorkGroupInvocations; - GLuint MaxComputeSharedMemorySize; - - /** GL_ARB_compute_variable_group_size */ - GLuint MaxComputeVariableGroupSize[3]; /* Array of x, y, z dimensions */ - GLuint MaxComputeVariableGroupInvocations; - - /** GL_ARB_gpu_shader5 */ - GLfloat MinFragmentInterpolationOffset; - GLfloat MaxFragmentInterpolationOffset; - - GLboolean FakeSWMSAA; - - /** GL_KHR_context_flush_control */ - GLenum16 ContextReleaseBehavior; - - struct gl_shader_compiler_options ShaderCompilerOptions[MESA_SHADER_STAGES]; - - /** GL_ARB_tessellation_shader */ - GLuint MaxPatchVertices; - GLuint MaxTessGenLevel; - GLuint MaxTessPatchComponents; - GLuint MaxTessControlTotalOutputComponents; - bool LowerTessLevel; /**< Lower gl_TessLevel* from float[n] to vecn? */ - bool PrimitiveRestartForPatches; - bool LowerCsDerivedVariables; /**< Lower gl_GlobalInvocationID and - * gl_LocalInvocationIndex based on - * other builtin variables. */ - - /** GL_OES_primitive_bounding_box */ - bool NoPrimitiveBoundingBoxOutput; - - /** GL_ARB_sparse_buffer */ - GLuint SparseBufferPageSize; - - /** Used as an input for sha1 generation in the on-disk shader cache */ - unsigned char *dri_config_options_sha1; - - /** When drivers are OK with mapped buffers during draw and other calls. */ - bool AllowMappedBuffersDuringExecution; - - /** - * Whether buffer creation, unsynchronized mapping, unmapping, and - * deletion is thread-safe. - */ - bool BufferCreateMapUnsynchronizedThreadSafe; - - /** GL_ARB_get_program_binary */ - GLuint NumProgramBinaryFormats; - - /** GL_NV_conservative_raster */ - GLuint MaxSubpixelPrecisionBiasBits; - - /** GL_NV_conservative_raster_dilate */ - GLfloat ConservativeRasterDilateRange[2]; - GLfloat ConservativeRasterDilateGranularity; - - /** Is the drivers uniform storage packed or padded to 16 bytes. */ - bool PackedDriverUniformStorage; - - /** Does the driver make use of the NIR based GLSL linker */ - bool UseNIRGLSLLinker; - - /** Wether or not glBitmap uses red textures rather than alpha */ - bool BitmapUsesRed; - - /** Whether the vertex buffer offset is a signed 32-bit integer. */ - bool VertexBufferOffsetIsInt32; - - /** Whether the driver can handle MultiDrawElements with non-VBO indices. */ - bool MultiDrawWithUserIndices; - - /** Whether out-of-order draw (Begin/End) optimizations are allowed. */ - bool AllowDrawOutOfOrder; - - /** Whether draw merging optimizations are allowed (might cause - * incorrect results). */ - bool AllowIncorrectPrimitiveId; - - /** Whether to allow the fast path for frequently updated VAOs. */ - bool AllowDynamicVAOFastPath; - - /** Whether the driver can support primitive restart with a fixed index. - * This is essentially a subset of NV_primitive_restart with enough support - * to be able to enable GLES 3.1. Some hardware can support this but not the - * full NV extension with arbitrary restart indices. - */ - bool PrimitiveRestartFixedIndex; - - /** GL_ARB_gl_spirv */ - struct spirv_supported_capabilities SpirVCapabilities; - - /** GL_ARB_spirv_extensions */ - struct spirv_supported_extensions *SpirVExtensions; - - char *VendorOverride; - - /** Buffer size used to upload vertices from glBegin/glEnd. */ - unsigned glBeginEndBufferSize; + struct pipe_frontend_drawable *drawable; + enum st_attachment_type statts[ST_ATTACHMENT_COUNT]; + unsigned num_statts; + int32_t stamp; + int32_t drawable_stamp; + uint32_t drawable_ID; - /** Whether the driver doesn't want x/y/width/height clipped based on src size - * when doing a copy texture operation (eg: may want out-of-bounds reads that - * produce 0 instead of leaving the texture content undefined). - */ - bool NoClippingOnCopyTex; -}; - - -/** - * Enable flag for each OpenGL extension. Different device drivers will - * enable different extensions at runtime. - */ -struct gl_extensions -{ - GLboolean dummy; /* don't remove this! */ - GLboolean dummy_true; /* Set true by _mesa_init_extensions(). */ - GLboolean ANGLE_texture_compression_dxt; - GLboolean ARB_ES2_compatibility; - GLboolean ARB_ES3_compatibility; - GLboolean ARB_ES3_1_compatibility; - GLboolean ARB_ES3_2_compatibility; - GLboolean ARB_arrays_of_arrays; - GLboolean ARB_base_instance; - GLboolean ARB_bindless_texture; - GLboolean ARB_blend_func_extended; - GLboolean ARB_buffer_storage; - GLboolean ARB_clear_texture; - GLboolean ARB_clip_control; - GLboolean ARB_color_buffer_float; - GLboolean ARB_compatibility; - GLboolean ARB_compute_shader; - GLboolean ARB_compute_variable_group_size; - GLboolean ARB_conditional_render_inverted; - GLboolean ARB_conservative_depth; - GLboolean ARB_copy_image; - GLboolean ARB_cull_distance; - GLboolean EXT_color_buffer_half_float; - GLboolean ARB_depth_buffer_float; - GLboolean ARB_depth_clamp; - GLboolean ARB_depth_texture; - GLboolean ARB_derivative_control; - GLboolean ARB_draw_buffers_blend; - GLboolean ARB_draw_elements_base_vertex; - GLboolean ARB_draw_indirect; - GLboolean ARB_draw_instanced; - GLboolean ARB_fragment_coord_conventions; - GLboolean ARB_fragment_layer_viewport; - GLboolean ARB_fragment_program; - GLboolean ARB_fragment_program_shadow; - GLboolean ARB_fragment_shader; - GLboolean ARB_framebuffer_no_attachments; - GLboolean ARB_framebuffer_object; - GLboolean ARB_fragment_shader_interlock; - GLboolean ARB_enhanced_layouts; - GLboolean ARB_explicit_attrib_location; - GLboolean ARB_explicit_uniform_location; - GLboolean ARB_gl_spirv; - GLboolean ARB_gpu_shader5; - GLboolean ARB_gpu_shader_fp64; - GLboolean ARB_gpu_shader_int64; - GLboolean ARB_half_float_vertex; - GLboolean ARB_indirect_parameters; - GLboolean ARB_instanced_arrays; - GLboolean ARB_internalformat_query; - GLboolean ARB_internalformat_query2; - GLboolean ARB_map_buffer_range; - GLboolean ARB_occlusion_query; - GLboolean ARB_occlusion_query2; - GLboolean ARB_pipeline_statistics_query; - GLboolean ARB_point_sprite; - GLboolean ARB_polygon_offset_clamp; - GLboolean ARB_post_depth_coverage; - GLboolean ARB_query_buffer_object; - GLboolean ARB_robust_buffer_access_behavior; - GLboolean ARB_sample_locations; - GLboolean ARB_sample_shading; - GLboolean ARB_seamless_cube_map; - GLboolean ARB_shader_atomic_counter_ops; - GLboolean ARB_shader_atomic_counters; - GLboolean ARB_shader_ballot; - GLboolean ARB_shader_bit_encoding; - GLboolean ARB_shader_clock; - GLboolean ARB_shader_draw_parameters; - GLboolean ARB_shader_group_vote; - GLboolean ARB_shader_image_load_store; - GLboolean ARB_shader_image_size; - GLboolean ARB_shader_precision; - GLboolean ARB_shader_stencil_export; - GLboolean ARB_shader_storage_buffer_object; - GLboolean ARB_shader_texture_image_samples; - GLboolean ARB_shader_texture_lod; - GLboolean ARB_shader_viewport_layer_array; - GLboolean ARB_shading_language_packing; - GLboolean ARB_shading_language_420pack; - GLboolean ARB_shadow; - GLboolean ARB_sparse_buffer; - GLboolean ARB_stencil_texturing; - GLboolean ARB_spirv_extensions; - GLboolean ARB_sync; - GLboolean ARB_tessellation_shader; - GLboolean ARB_texture_border_clamp; - GLboolean ARB_texture_buffer_object; - GLboolean ARB_texture_buffer_object_rgb32; - GLboolean ARB_texture_buffer_range; - GLboolean ARB_texture_compression_bptc; - GLboolean ARB_texture_compression_rgtc; - GLboolean ARB_texture_cube_map; - GLboolean ARB_texture_cube_map_array; - GLboolean ARB_texture_env_combine; - GLboolean ARB_texture_env_crossbar; - GLboolean ARB_texture_env_dot3; - GLboolean ARB_texture_filter_anisotropic; - GLboolean ARB_texture_filter_minmax; - GLboolean ARB_texture_float; - GLboolean ARB_texture_gather; - GLboolean ARB_texture_mirror_clamp_to_edge; - GLboolean ARB_texture_multisample; - GLboolean ARB_texture_non_power_of_two; - GLboolean ARB_texture_stencil8; - GLboolean ARB_texture_query_levels; - GLboolean ARB_texture_query_lod; - GLboolean ARB_texture_rg; - GLboolean ARB_texture_rgb10_a2ui; - GLboolean ARB_texture_view; - GLboolean ARB_timer_query; - GLboolean ARB_transform_feedback2; - GLboolean ARB_transform_feedback3; - GLboolean ARB_transform_feedback_instanced; - GLboolean ARB_transform_feedback_overflow_query; - GLboolean ARB_uniform_buffer_object; - GLboolean ARB_vertex_attrib_64bit; - GLboolean ARB_vertex_program; - GLboolean ARB_vertex_shader; - GLboolean ARB_vertex_type_10f_11f_11f_rev; - GLboolean ARB_vertex_type_2_10_10_10_rev; - GLboolean ARB_viewport_array; - GLboolean EXT_blend_color; - GLboolean EXT_blend_equation_separate; - GLboolean EXT_blend_func_separate; - GLboolean EXT_blend_minmax; - GLboolean EXT_demote_to_helper_invocation; - GLboolean EXT_depth_bounds_test; - GLboolean EXT_disjoint_timer_query; - GLboolean EXT_draw_buffers2; - GLboolean EXT_EGL_image_storage; - GLboolean EXT_float_blend; - GLboolean EXT_framebuffer_multisample; - GLboolean EXT_framebuffer_multisample_blit_scaled; - GLboolean EXT_framebuffer_sRGB; - GLboolean EXT_gpu_program_parameters; - GLboolean EXT_gpu_shader4; - GLboolean EXT_memory_object; - GLboolean EXT_memory_object_fd; - GLboolean EXT_multisampled_render_to_texture; - GLboolean EXT_packed_float; - GLboolean EXT_pixel_buffer_object; - GLboolean EXT_point_parameters; - GLboolean EXT_provoking_vertex; - GLboolean EXT_render_snorm; - GLboolean EXT_semaphore; - GLboolean EXT_semaphore_fd; - GLboolean EXT_shader_image_load_formatted; - GLboolean EXT_shader_image_load_store; - GLboolean EXT_shader_integer_mix; - GLboolean EXT_shader_samples_identical; - GLboolean EXT_sRGB; - GLboolean EXT_stencil_two_side; - GLboolean EXT_texture_array; - GLboolean EXT_texture_buffer_object; - GLboolean EXT_texture_compression_latc; - GLboolean EXT_texture_compression_s3tc; - GLboolean EXT_texture_compression_s3tc_srgb; - GLboolean EXT_texture_env_dot3; - GLboolean EXT_texture_filter_anisotropic; - GLboolean EXT_texture_filter_minmax; - GLboolean EXT_texture_integer; - GLboolean EXT_texture_mirror_clamp; - GLboolean EXT_texture_norm16; - GLboolean EXT_texture_shadow_lod; - GLboolean EXT_texture_shared_exponent; - GLboolean EXT_texture_snorm; - GLboolean EXT_texture_sRGB; - GLboolean EXT_texture_sRGB_R8; - GLboolean EXT_texture_sRGB_RG8; - GLboolean EXT_texture_sRGB_decode; - GLboolean EXT_texture_swizzle; - GLboolean EXT_texture_type_2_10_10_10_REV; - GLboolean EXT_transform_feedback; - GLboolean EXT_timer_query; - GLboolean EXT_vertex_array_bgra; - GLboolean EXT_window_rectangles; - GLboolean OES_copy_image; - GLboolean OES_primitive_bounding_box; - GLboolean OES_sample_variables; - GLboolean OES_standard_derivatives; - GLboolean OES_texture_buffer; - GLboolean OES_texture_cube_map_array; - GLboolean OES_texture_view; - GLboolean OES_viewport_array; - /* vendor extensions */ - GLboolean AMD_compressed_ATC_texture; - GLboolean AMD_framebuffer_multisample_advanced; - GLboolean AMD_depth_clamp_separate; - GLboolean AMD_performance_monitor; - GLboolean AMD_pinned_memory; - GLboolean AMD_seamless_cubemap_per_texture; - GLboolean AMD_vertex_shader_layer; - GLboolean AMD_vertex_shader_viewport_index; - GLboolean ANDROID_extension_pack_es31a; - GLboolean APPLE_object_purgeable; - GLboolean ATI_meminfo; - GLboolean ATI_texture_compression_3dc; - GLboolean ATI_texture_mirror_once; - GLboolean ATI_texture_env_combine3; - GLboolean ATI_fragment_shader; - GLboolean GREMEDY_string_marker; - GLboolean INTEL_blackhole_render; - GLboolean INTEL_conservative_rasterization; - GLboolean INTEL_performance_query; - GLboolean INTEL_shader_atomic_float_minmax; - GLboolean INTEL_shader_integer_functions2; - GLboolean KHR_blend_equation_advanced; - GLboolean KHR_blend_equation_advanced_coherent; - GLboolean KHR_robustness; - GLboolean KHR_texture_compression_astc_hdr; - GLboolean KHR_texture_compression_astc_ldr; - GLboolean KHR_texture_compression_astc_sliced_3d; - GLboolean MESA_framebuffer_flip_y; - GLboolean MESA_tile_raster_order; - GLboolean EXT_shader_framebuffer_fetch; - GLboolean EXT_shader_framebuffer_fetch_non_coherent; - GLboolean MESA_shader_integer_functions; - GLboolean MESA_ycbcr_texture; - GLboolean NV_alpha_to_coverage_dither_control; - GLboolean NV_compute_shader_derivatives; - GLboolean NV_conditional_render; - GLboolean NV_copy_depth_to_color; - GLboolean NV_copy_image; - GLboolean NV_fill_rectangle; - GLboolean NV_fog_distance; - GLboolean NV_primitive_restart; - GLboolean NV_shader_atomic_float; - GLboolean NV_shader_atomic_int64; - GLboolean NV_texture_barrier; - GLboolean NV_texture_env_combine4; - GLboolean NV_texture_rectangle; - GLboolean NV_vdpau_interop; - GLboolean NV_conservative_raster; - GLboolean NV_conservative_raster_dilate; - GLboolean NV_conservative_raster_pre_snap_triangles; - GLboolean NV_conservative_raster_pre_snap; - GLboolean NV_viewport_array2; - GLboolean NV_viewport_swizzle; - GLboolean NVX_gpu_memory_info; - GLboolean TDFX_texture_compression_FXT1; - GLboolean OES_EGL_image; - GLboolean OES_draw_texture; - GLboolean OES_depth_texture_cube_map; - GLboolean OES_EGL_image_external; - GLboolean OES_texture_float; - GLboolean OES_texture_float_linear; - GLboolean OES_texture_half_float; - GLboolean OES_texture_half_float_linear; - GLboolean OES_compressed_ETC1_RGB8_texture; - GLboolean OES_geometry_shader; - GLboolean OES_texture_compression_astc; - GLboolean extension_sentinel; - /** The extension string */ - const GLubyte *String; - /** Number of supported extensions */ - GLuint Count; - /** - * The context version which extension helper functions compare against. - * By default, the value is equal to ctx->Version. This changes to ~0 - * while meta is in progress. - */ - GLubyte Version; + /* list of framebuffer objects */ + struct list_head head; }; - /** * A stack of matrices (projection, modelview, color, texture, etc). */ @@ -4580,6 +2734,7 @@ struct gl_matrix_stack GLuint Depth; /**< 0 <= Depth < MaxDepth */ GLuint MaxDepth; /**< size of Stack[] array */ GLuint DirtyFlag; /**< _NEW_MODELVIEW or _NEW_PROJECTION, for example */ + bool ChangedSincePush; }; @@ -4640,37 +2795,6 @@ struct gl_matrix_stack /*@}*/ -/** - * Composite state flags, deprecated and inefficient, do not use. - */ -/*@{*/ -#define _NEW_LIGHT (_NEW_LIGHT_CONSTANTS | /* state parameters */ \ - _NEW_LIGHT_STATE | /* rasterizer state */ \ - _NEW_MATERIAL | /* light materials */ \ - _NEW_FF_VERT_PROGRAM | \ - _NEW_FF_FRAG_PROGRAM) - -#define _NEW_TEXTURE (_NEW_TEXTURE_OBJECT | _NEW_TEXTURE_STATE | \ - _NEW_FF_VERT_PROGRAM | _NEW_FF_FRAG_PROGRAM) - -#define _MESA_NEW_NEED_EYE_COORDS (_NEW_FF_VERT_PROGRAM | \ - _NEW_FF_FRAG_PROGRAM | \ - _NEW_LIGHT_CONSTANTS | \ - _NEW_TEXTURE_STATE | \ - _NEW_POINT | \ - _NEW_PROGRAM | \ - _NEW_MODELVIEW) - -#define _MESA_NEW_SEPARATE_SPECULAR (_NEW_LIGHT | \ - _NEW_FOG | \ - _NEW_PROGRAM) - - -/*@}*/ - - - - /* This has to be included here. */ #include "dd.h" @@ -4685,10 +2809,19 @@ union gl_dlist_node; struct gl_display_list { GLuint Name; - GLbitfield Flags; /**< DLIST_x flags */ + bool execute_glthread; + bool small_list; GLchar *Label; /**< GL_KHR_debug */ /** The dlist commands are in a linked list of nodes */ - union gl_dlist_node *Head; + union { + /* Big lists allocate their own storage */ + union gl_dlist_node *Head; + /* Small lists use ctx->Shared->small_dlist_store */ + struct { + unsigned start; + unsigned count; + }; + }; }; @@ -4701,8 +2834,7 @@ struct gl_dlist_state union gl_dlist_node *CurrentBlock; /**< Pointer to current block of nodes */ GLuint CurrentPos; /**< Index into current block of nodes */ GLuint CallDepth; /**< Current recursion calling depth */ - - GLvertexformat ListVtxfmt; + GLuint LastInstSize; /**< Size of the last node. */ GLubyte ActiveAttribSize[VERT_ATTRIB_MAX]; uint32_t CurrentAttrib[VERT_ATTRIB_MAX][8]; @@ -4715,6 +2847,7 @@ struct gl_dlist_state * list. Used to eliminate some redundant state changes. */ GLenum16 ShadeModel; + bool UseLoopback; } Current; }; @@ -4727,146 +2860,29 @@ struct gl_dlist_state */ struct gl_driver_flags { - /** gl_context::Array::_DrawArrays (vertex array state) */ - uint64_t NewArray; - - /** gl_context::TransformFeedback::CurrentObject */ - uint64_t NewTransformFeedback; - - /** gl_context::TransformFeedback::CurrentObject::shader_program */ - uint64_t NewTransformFeedbackProg; - - /** gl_context::RasterDiscard */ - uint64_t NewRasterizerDiscard; - - /** gl_context::TileRasterOrder* */ - uint64_t NewTileRasterOrder; - - /** - * gl_context::UniformBufferBindings - * gl_shader_program::UniformBlocks - */ - uint64_t NewUniformBuffer; - - /** - * gl_context::ShaderStorageBufferBindings - * gl_shader_program::ShaderStorageBlocks - */ - uint64_t NewShaderStorageBuffer; - - uint64_t NewTextureBuffer; - /** * gl_context::AtomicBufferBindings */ uint64_t NewAtomicBuffer; - /** - * gl_context::ImageUnits - */ - uint64_t NewImageUnits; - - /** - * gl_context::TessCtrlProgram::patch_default_* - */ - uint64_t NewDefaultTessLevels; - - /** - * gl_context::IntelConservativeRasterization - */ - uint64_t NewIntelConservativeRasterization; - - /** - * gl_context::NvConservativeRasterization - */ - uint64_t NewNvConservativeRasterization; - - /** - * gl_context::ConservativeRasterMode/ConservativeRasterDilate - * gl_context::SubpixelPrecisionBias - */ - uint64_t NewNvConservativeRasterizationParams; - - /** - * gl_context::Scissor::WindowRects - */ - uint64_t NewWindowRectangles; - - /** gl_context::Color::sRGBEnabled */ - uint64_t NewFramebufferSRGB; - - /** gl_context::Scissor::EnableFlags */ - uint64_t NewScissorTest; - - /** gl_context::Scissor::ScissorArray */ - uint64_t NewScissorRect; - /** gl_context::Color::Alpha* */ uint64_t NewAlphaTest; - /** gl_context::Color::Blend/Dither */ - uint64_t NewBlend; - - /** gl_context::Color::BlendColor */ - uint64_t NewBlendColor; - - /** gl_context::Color::Color/Index */ - uint64_t NewColorMask; - - /** gl_context::Depth */ - uint64_t NewDepth; - - /** gl_context::Color::LogicOp/ColorLogicOp/IndexLogicOp */ - uint64_t NewLogicOp; - /** gl_context::Multisample::Enabled */ uint64_t NewMultisampleEnable; - /** gl_context::Multisample::SampleAlphaTo* */ - uint64_t NewSampleAlphaToXEnable; - - /** gl_context::Multisample::SampleCoverage/SampleMaskValue */ - uint64_t NewSampleMask; - /** gl_context::Multisample::(Min)SampleShading */ uint64_t NewSampleShading; - /** gl_context::Stencil */ - uint64_t NewStencil; - - /** gl_context::Transform::ClipOrigin/ClipDepthMode */ - uint64_t NewClipControl; - - /** gl_context::Transform::EyeUserPlane */ - uint64_t NewClipPlane; - /** gl_context::Transform::ClipPlanesEnabled */ uint64_t NewClipPlaneEnable; /** gl_context::Color::ClampFragmentColor */ uint64_t NewFragClamp; - /** gl_context::Transform::DepthClamp */ - uint64_t NewDepthClamp; - - /** gl_context::Line */ - uint64_t NewLineState; - - /** gl_context::Polygon */ - uint64_t NewPolygonState; - - /** gl_context::PolygonStipple */ - uint64_t NewPolygonStipple; - - /** gl_context::ViewportArray */ - uint64_t NewViewport; - /** Shader constants (uniforms, program parameters, state constants) */ uint64_t NewShaderConstants[MESA_SHADER_STAGES]; - /** Programmable sample location state for gl_context::DrawBuffer */ - uint64_t NewSampleLocations; - /** For GL_CLAMP emulation */ uint64_t NewSamplersWithClamp; }; @@ -4965,11 +2981,19 @@ struct gl_memory_object GLuint Name; /**< hash table ID/name */ GLboolean Immutable; /**< denotes mutability state of parameters */ GLboolean Dedicated; /**< import memory from a dedicated allocation */ + + struct pipe_memory_object *memory; + + /* TEXTURE_TILING_EXT param from gl_texture_object */ + GLuint TextureTiling; }; struct gl_semaphore_object { GLuint Name; /**< hash table ID/name */ + struct pipe_fence_handle *fence; + enum pipe_fd_type type; + uint64_t timeline_value; }; /** @@ -4988,7 +3012,6 @@ struct gl_client_attrib_node * The VBO module implemented in src/vbo. */ struct vbo_context { - struct gl_vertex_buffer_binding binding; struct gl_array_attributes current[VBO_ATTRIB_MAX]; struct gl_vertex_array_object *VAO; @@ -5088,6 +3111,7 @@ struct gl_texture_attrib_node GLuint NumTexSaved; struct gl_fixedfunc_texture_unit FixedFuncUnit[MAX_TEXTURE_COORD_UNITS]; GLfloat LodBias[MAX_TEXTURE_UNITS]; + float LodBiasQuantized[MAX_TEXTURE_UNITS]; /** Saved default texture object state. */ struct gl_texture_object SavedDefaultObj[NUM_TEXTURE_TARGETS]; @@ -5095,7 +3119,7 @@ struct gl_texture_attrib_node /* For saving per texture object state (wrap modes, filters, etc), * SavedObj[][].Target is unused, so the value is invalid. */ - struct gl_texture_object SavedObj[MAX_TEXTURE_UNITS][NUM_TEXTURE_TARGETS]; + struct gl_texture_object SavedObj[MAX_COMBINED_TEXTURE_IMAGE_UNITS][NUM_TEXTURE_TARGETS]; }; @@ -5135,6 +3159,57 @@ struct gl_attrib_node }; /** + * Dispatch tables. + */ +struct gl_dispatch +{ + /** + * For non-displaylist-saving, non-begin/end. + */ + struct _glapi_table *OutsideBeginEnd; + + /** + * The dispatch table used between glBegin() and glEnd() (outside of a + * display list). Only valid functions between those two are set. + */ + struct _glapi_table *BeginEnd; + + /** + * Same as BeginEnd except glVertex{Attrib} functions. Used when + * HW GL_SELECT mode instead of BeginEnd to insert extra code + * for GL_SELECT. + */ + struct _glapi_table *HWSelectModeBeginEnd; + + /** + * The dispatch table used between glNewList() and glEndList(). + */ + struct _glapi_table *Save; + + /** + * Dispatch table for when a graphics reset has happened. + */ + struct _glapi_table *ContextLost; + + /** + * The current dispatch table for non-displaylist-saving execution. + * It can be equal to one of these: + * - OutsideBeginEnd + * - BeginEnd + * - HWSelectModeBeginEnd + */ + struct _glapi_table *Exec; + + /** + * The current dispatch table overall. It can be equal to one of these: + * - Exec + * - Save + * - ContextLost + */ + struct _glapi_table *Current; +}; + +/** * Mesa rendering context. * * This is the central context data structure for Mesa. Almost all @@ -5157,44 +3232,23 @@ struct gl_context gl_api API; /** - * The current dispatch table for non-displaylist-saving execution, either - * BeginEnd or OutsideBeginEnd - */ - struct _glapi_table *Exec; - /** - * The normal dispatch table for non-displaylist-saving, non-begin/end - */ - struct _glapi_table *OutsideBeginEnd; - /** The dispatch table used between glNewList() and glEndList() */ - struct _glapi_table *Save; - /** - * The dispatch table used between glBegin() and glEnd() (outside of a - * display list). Only valid functions between those two are set, which is - * mostly just the set in a GLvertexformat struct. + * Dispatch tables implementing OpenGL functions. GLThread has no effect + * on this. */ - struct _glapi_table *BeginEnd; - /** - * Dispatch table for when a graphics reset has happened. - */ - struct _glapi_table *ContextLost; + struct gl_dispatch Dispatch; + /** - * Dispatch table used to marshal API calls from the client program to a - * separate server thread. NULL if API calls are not being marshalled to - * another thread. + * Dispatch table used by GLThread, a component used to marshal API + * calls from an application to a separate thread. */ struct _glapi_table *MarshalExec; + /** * Dispatch table currently in use for fielding API calls from the client * program. If API calls are being marshalled to another thread, this == - * MarshalExec. Otherwise it == CurrentServerDispatch. + * MarshalExec. Otherwise it == Dispatch.Current. */ - struct _glapi_table *CurrentClientDispatch; - - /** - * Dispatch table currently in use for performing API calls. == Save or - * Exec. - */ - struct _glapi_table *CurrentServerDispatch; + struct _glapi_table *GLApi; /*@}*/ @@ -5235,6 +3289,9 @@ struct gl_context */ GLbitfield ValidPrimMaskIndexed; + /** DrawID for the next non-multi non-indirect draw. Only set by glthread. */ + GLuint DrawID; + /** * Whether DrawPixels/CopyPixels/Bitmap are valid to render. */ @@ -5456,8 +3513,6 @@ struct gl_context GLboolean ViewportInitialized; /**< has viewport size been initialized? */ GLboolean _AllowDrawOutOfOrder; - /* Is gl_PrimitiveID unused by the current shaders? */ - bool _PrimitiveIDIsUnused; /** \name Derived state */ GLbitfield _ImageTransferState;/**< bitwise-or of IMAGE_*_BIT flags */ @@ -5465,10 +3520,11 @@ struct gl_context GLfloat _ModelViewInvScale; /* may be for model- or eyespace lighting */ GLfloat _ModelViewInvScaleEyespace; /* always factor defined in spec */ GLboolean _NeedEyeCoords; - GLboolean _ForceEyeCoords; GLuint TextureStateTimestamp; /**< detect changes to shared state */ + GLboolean PointSizeIsSet; /**< the glPointSize value in the shader is set */ + /** \name For debugging/development only */ /*@{*/ GLboolean FirstTimeCurrent; @@ -5508,11 +3564,19 @@ struct gl_context * These will eventually live in the driver or elsewhere. */ /*@{*/ - void *swrast_context; - void *swsetup_context; - void *swtnl_context; struct vbo_context vbo_context; struct st_context *st; + struct pipe_screen *screen; + struct pipe_context *pipe; + struct st_config_options *st_opts; + struct cso_context *cso_context; + bool has_invalidate_buffer; + bool has_string_marker; + /* On old libGL's for linux we need to invalidate the drawables + * on glViewpport calls, this is set via a option. + */ + bool invalidate_on_gl_viewport; + /*@}*/ /** @@ -5549,19 +3613,9 @@ struct gl_context /*@}*/ bool shader_builtin_ref; -}; -/** - * Information about memory usage. All sizes are in kilobytes. - */ -struct gl_memory_info -{ - unsigned total_device_memory; /**< size of device memory, e.g. VRAM */ - unsigned avail_device_memory; /**< free device memory at the moment */ - unsigned total_staging_memory; /**< size of staging memory, e.g. GART */ - unsigned avail_staging_memory; /**< free staging memory at the moment */ - unsigned device_memory_evicted; /**< size of memory evicted (monotonic counter) */ - unsigned nr_device_memory_evictions; /**< # of evictions (monotonic counter) */ + struct pipe_draw_start_count_bias *tmp_draws; + unsigned num_tmp_draws; }; #ifndef NDEBUG diff --git a/src/mesa/main/multisample.c b/src/mesa/main/multisample.c index 2d243eaac48..3a9aae44c37 100644 --- a/src/mesa/main/multisample.c +++ b/src/mesa/main/multisample.c @@ -23,7 +23,7 @@ */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/macros.h" #include "main/multisample.h" @@ -31,7 +31,12 @@ #include "main/fbobject.h" #include "main/glformats.h" #include "main/state.h" +#include "api_exec_decl.h" +#include "main/framebuffer.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_format.h" +#include "state_tracker/st_util.h" /** * Called via glSampleCoverageARB @@ -47,9 +52,8 @@ _mesa_SampleCoverage(GLclampf value, GLboolean invert) ctx->Multisample.SampleCoverageValue == value) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 : _NEW_MULTISAMPLE, - GL_MULTISAMPLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask; + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT); + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; ctx->Multisample.SampleCoverageValue = value; ctx->Multisample.SampleCoverageInvert = invert; } @@ -77,6 +81,23 @@ _mesa_init_multisample(struct gl_context *ctx) ctx->Multisample.SampleMaskValue = ~(GLbitfield)0; } +static void +get_sample_position(struct gl_context *ctx, + struct gl_framebuffer *fb, + GLuint index, + GLfloat *outPos) +{ + struct st_context *st = st_context(ctx); + + st_validate_state(st, ST_PIPELINE_UPDATE_FB_STATE_MASK); + + if (ctx->pipe->get_sample_position) + ctx->pipe->get_sample_position(ctx->pipe, + _mesa_geometric_samples(fb), + index, outPos); + else + outPos[0] = outPos[1] = 0.5f; +} void GLAPIENTRY _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val) @@ -94,7 +115,7 @@ _mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat * val) return; } - ctx->Driver.GetSamplePosition(ctx, ctx->DrawBuffer, index, val); + get_sample_position(ctx, ctx->DrawBuffer, index, val); /* FBOs can be upside down (winsys always are)*/ if (ctx->DrawBuffer->FlipY) @@ -133,8 +154,8 @@ sample_maski(struct gl_context *ctx, GLuint index, GLbitfield mask) if (ctx->Multisample.SampleMaskValue == mask) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleMask ? 0 : _NEW_MULTISAMPLE, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleMask; + FLUSH_VERTICES(ctx, 0, 0); + ctx->NewDriverState |= ST_NEW_SAMPLE_STATE; ctx->Multisample.SampleMaskValue = mask; } @@ -171,9 +192,7 @@ min_sample_shading(struct gl_context *ctx, GLclampf value) if (ctx->Multisample.MinSampleShadingValue == value) return; - FLUSH_VERTICES(ctx, - ctx->DriverFlags.NewSampleShading ? 0 : _NEW_MULTISAMPLE, - GL_MULTISAMPLE_BIT); + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT); ctx->NewDriverState |= ctx->DriverFlags.NewSampleShading; ctx->Multisample.MinSampleShadingValue = value; } @@ -223,7 +242,7 @@ _mesa_check_sample_count(struct gl_context *ctx, GLenum target, * * This restriction is relaxed for OpenGL ES 3.1. */ - if ((ctx->API == API_OPENGLES2 && ctx->Version == 30) && + if ((_mesa_is_gles2(ctx) && ctx->Version == 30) && _mesa_is_enum_format_integer(internalFormat) && samples > 0) { return GL_INVALID_OPERATION; @@ -294,8 +313,8 @@ _mesa_check_sample_count(struct gl_context *ctx, GLenum target, GLint buffer[16] = {-1}; GLint limit; - ctx->Driver.QueryInternalFormat(ctx, target, internalFormat, - GL_SAMPLES, buffer); + st_QueryInternalFormat(ctx, target, internalFormat, + GL_SAMPLES, buffer); /* since the query returns samples sorted in descending order, * the first element is the greatest supported sample value. */ @@ -360,10 +379,8 @@ _mesa_AlphaToCoverageDitherControlNV_no_error(GLenum mode) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleAlphaToXEnable ? 0 : - _NEW_MULTISAMPLE, - GL_MULTISAMPLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleAlphaToXEnable; + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; ctx->Multisample.SampleAlphaToCoverageDitherControl = mode; } @@ -372,10 +389,8 @@ _mesa_AlphaToCoverageDitherControlNV(GLenum mode) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewSampleAlphaToXEnable ? 0 : - _NEW_MULTISAMPLE, - GL_MULTISAMPLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewSampleAlphaToXEnable; + FLUSH_VERTICES(ctx, 0, GL_MULTISAMPLE_BIT); + ctx->NewDriverState |= ST_NEW_BLEND; switch (mode) { case GL_ALPHA_TO_COVERAGE_DITHER_DEFAULT_NV: case GL_ALPHA_TO_COVERAGE_DITHER_ENABLE_NV: @@ -386,3 +401,29 @@ _mesa_AlphaToCoverageDitherControlNV(GLenum mode) _mesa_error(ctx, GL_INVALID_ENUM, "glAlphaToCoverageDitherControlNV(invalid parameter)"); } } + +void +_mesa_GetProgrammableSampleCaps(struct gl_context *ctx, const struct gl_framebuffer *fb, + GLuint *outBits, GLuint *outWidth, GLuint *outHeight) +{ + struct st_context *st = st_context(ctx); + struct pipe_screen *screen = ctx->pipe->screen; + + st_validate_state(st, ST_PIPELINE_UPDATE_FB_STATE_MASK); + + *outBits = 4; + *outWidth = 1; + *outHeight = 1; + + if (ctx->Extensions.ARB_sample_locations) + screen->get_sample_pixel_grid(screen, st->state.fb_num_samples, + outWidth, outHeight); + + /* We could handle this better in some circumstances, + * but it's not really an issue */ + if (*outWidth > MAX_SAMPLE_LOCATION_GRID_SIZE || + *outHeight > MAX_SAMPLE_LOCATION_GRID_SIZE) { + *outWidth = 1; + *outHeight = 1; + } +} diff --git a/src/mesa/main/multisample.h b/src/mesa/main/multisample.h index 9cd4724947a..5bb4ed68697 100644 --- a/src/mesa/main/multisample.h +++ b/src/mesa/main/multisample.h @@ -26,42 +26,20 @@ #ifndef MULTISAMPLE_H #define MULTISAMPLE_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -extern void GLAPIENTRY -_mesa_SampleCoverage(GLclampf value, GLboolean invert); - +void +_mesa_GetProgrammableSampleCaps(struct gl_context *ctx, const struct gl_framebuffer *fb, + GLuint *outBits, GLuint *outWidth, GLuint *outHeight); extern void _mesa_init_multisample(struct gl_context *ctx); - -extern void GLAPIENTRY -_mesa_GetMultisamplefv(GLenum pname, GLuint index, GLfloat* val); - -void GLAPIENTRY -_mesa_SampleMaski_no_error(GLuint index, GLbitfield mask); - -extern void GLAPIENTRY -_mesa_SampleMaski(GLuint index, GLbitfield mask); - -void GLAPIENTRY -_mesa_MinSampleShading_no_error(GLclampf value); - -extern void GLAPIENTRY -_mesa_MinSampleShading(GLclampf value); - extern GLenum _mesa_check_sample_count(struct gl_context *ctx, GLenum target, GLenum internalFormat, GLsizei samples, GLsizei storageSamples); -extern void GLAPIENTRY -_mesa_AlphaToCoverageDitherControlNV_no_error(GLenum mode); - -extern void GLAPIENTRY -_mesa_AlphaToCoverageDitherControlNV(GLenum mode); - #endif diff --git a/src/mesa/main/objectlabel.c b/src/mesa/main/objectlabel.c index 1e3022ee547..5c82462e774 100644 --- a/src/mesa/main/objectlabel.c +++ b/src/mesa/main/objectlabel.c @@ -29,7 +29,6 @@ #include "dlist.h" #include "enums.h" #include "fbobject.h" -#include "objectlabel.h" #include "pipelineobj.h" #include "queryobj.h" #include "samplerobj.h" @@ -37,6 +36,7 @@ #include "syncobj.h" #include "texobj.h" #include "transformfeedback.h" +#include "api_exec_decl.h" /** @@ -44,14 +44,15 @@ */ static void set_label(struct gl_context *ctx, char **labelPtr, const char *label, - int length, const char *caller) + int length, const char *caller, bool ext_length) { free(*labelPtr); *labelPtr = NULL; /* set new label string */ if (label) { - if (length >= 0) { + if ((!ext_length && length >= 0) || + (ext_length && length > 0)) { if (length >= MAX_LABEL_LENGTH) _mesa_error(ctx, GL_INVALID_VALUE, "%s(length=%d, which is not less than " @@ -69,6 +70,13 @@ set_label(struct gl_context *ctx, char **labelPtr, const char *label, } } else { + if (ext_length && length < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, + "%s(label length=%d, is less than zero)", caller, + length); + return; + } + int len = strlen(label); if (len >= MAX_LABEL_LENGTH) _mesa_error(ctx, GL_INVALID_VALUE, @@ -133,12 +141,15 @@ copy_label(const GLchar *src, GLchar *dst, GLsizei *length, GLsizei bufSize) */ static char ** get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, - const char *caller) + const char *caller, bool ext_errors) { char **labelPtr = NULL; + GLenum no_match_error = + ext_errors ? GL_INVALID_OPERATION : GL_INVALID_VALUE; switch (identifier) { case GL_BUFFER: + case GL_BUFFER_OBJECT_EXT: { struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, name); if (bufObj) @@ -146,6 +157,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } break; case GL_SHADER: + case GL_SHADER_OBJECT_EXT: { struct gl_shader *shader = _mesa_lookup_shader(ctx, name); if (shader) @@ -153,6 +165,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } break; case GL_PROGRAM: + case GL_PROGRAM_OBJECT_EXT: { struct gl_shader_program *program = _mesa_lookup_shader_program(ctx, name); @@ -161,6 +174,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } break; case GL_VERTEX_ARRAY: + case GL_VERTEX_ARRAY_OBJECT_EXT: { struct gl_vertex_array_object *obj = _mesa_lookup_vao(ctx, name); if (obj) @@ -168,6 +182,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } break; case GL_QUERY: + case GL_QUERY_OBJECT_EXT: { struct gl_query_object *query = _mesa_lookup_query_object(ctx, name); if (query) @@ -215,8 +230,8 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } break; case GL_DISPLAY_LIST: - if (ctx->API == API_OPENGL_COMPAT) { - struct gl_display_list *list = _mesa_lookup_list(ctx, name); + if (_mesa_is_desktop_gl_compat(ctx)) { + struct gl_display_list *list = _mesa_lookup_list(ctx, name, false); if (list) labelPtr = &list->Label; } @@ -225,6 +240,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } break; case GL_PROGRAM_PIPELINE: + case GL_PROGRAM_PIPELINE_OBJECT_EXT: { struct gl_pipeline_object *pipe = _mesa_lookup_pipeline_object(ctx, name); @@ -237,7 +253,7 @@ get_label_pointer(struct gl_context *ctx, GLenum identifier, GLuint name, } if (NULL == labelPtr) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s(name = %u)", caller, name); + _mesa_error(ctx, no_match_error, "%s(name = %u)", caller, name); } return labelPtr; @@ -249,6 +265,42 @@ invalid_enum: } void GLAPIENTRY +_mesa_LabelObjectEXT(GLenum identifier, GLuint name, GLsizei length, + const GLchar *label) +{ + GET_CURRENT_CONTEXT(ctx); + const char *callerstr = "glLabelObjectEXT"; + char **labelPtr; + + labelPtr = get_label_pointer(ctx, identifier, name, callerstr, true); + if (!labelPtr) + return; + + set_label(ctx, labelPtr, label, length, callerstr, true); +} + +void GLAPIENTRY +_mesa_GetObjectLabelEXT(GLenum identifier, GLuint name, GLsizei bufSize, + GLsizei *length, GLchar *label) +{ + GET_CURRENT_CONTEXT(ctx); + const char *callerstr = "glGetObjectLabelEXT"; + char **labelPtr; + + if (bufSize < 0) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(bufSize = %d)", callerstr, + bufSize); + return; + } + + labelPtr = get_label_pointer(ctx, identifier, name, callerstr, true); + if (!labelPtr) + return; + + copy_label(*labelPtr, label, length, bufSize); +} + +void GLAPIENTRY _mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length, const GLchar *label) { @@ -261,11 +313,11 @@ _mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length, else callerstr = "glObjectLabelKHR"; - labelPtr = get_label_pointer(ctx, identifier, name, callerstr); + labelPtr = get_label_pointer(ctx, identifier, name, callerstr, false); if (!labelPtr) return; - set_label(ctx, labelPtr, label, length, callerstr); + set_label(ctx, labelPtr, label, length, callerstr, false); } void GLAPIENTRY @@ -287,7 +339,7 @@ _mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, return; } - labelPtr = get_label_pointer(ctx, identifier, name, callerstr); + labelPtr = get_label_pointer(ctx, identifier, name, callerstr, false); if (!labelPtr) return; @@ -317,7 +369,7 @@ _mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) labelPtr = &syncObj->Label; - set_label(ctx, labelPtr, label, length, callerstr); + set_label(ctx, labelPtr, label, length, callerstr, false); _mesa_unref_sync_object(ctx, syncObj, 1); } diff --git a/src/mesa/main/objectlabel.h b/src/mesa/main/objectlabel.h deleted file mode 100644 index f57d5f7b5d9..00000000000 --- a/src/mesa/main/objectlabel.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2013 Timothy Arceri All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file objectlabel.h - * Mesa object label functions. - * - * This file provides functions to assign and retrieve object labels. - */ - -#ifndef OBJECTLABEL_H -#define OBJECTLABEL_H - - -#include "glheader.h" - - -#ifdef __cplusplus -extern "C" { -#endif - -void GLAPIENTRY -_mesa_ObjectLabel(GLenum identifier, GLuint name, GLsizei length, - const GLchar *label); -void GLAPIENTRY -_mesa_GetObjectLabel(GLenum identifier, GLuint name, GLsizei bufSize, - GLsizei *length, GLchar *label); -void GLAPIENTRY -_mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label); -void GLAPIENTRY -_mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, - GLchar *label); - -#ifdef __cplusplus -} -#endif - - -#endif /* OBJECTLABEL_H */ diff --git a/src/mesa/main/objectpurge.c b/src/mesa/main/objectpurge.c deleted file mode 100644 index 78bc4487617..00000000000 --- a/src/mesa/main/objectpurge.c +++ /dev/null @@ -1,412 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -/** - * Code related to the GL_APPLE_object_purgeable extension. - */ - - -#include "glheader.h" -#include "enums.h" -#include "hash.h" - -#include "context.h" -#include "bufferobj.h" -#include "fbobject.h" -#include "mtypes.h" -#include "objectpurge.h" -#include "texobj.h" -#include "teximage.h" - - -static GLenum -buffer_object_purgeable(struct gl_context *ctx, GLuint name, GLenum option) -{ - struct gl_buffer_object *bufObj; - GLenum retval; - - bufObj = _mesa_lookup_bufferobj(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectPurgeable(name = 0x%x)", name); - return 0; - } - - if (bufObj->Purgeable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glObjectPurgeable(name = 0x%x) is already purgeable", name); - return GL_VOLATILE_APPLE; - } - - bufObj->Purgeable = GL_TRUE; - - retval = GL_VOLATILE_APPLE; - if (ctx->Driver.BufferObjectPurgeable) - retval = ctx->Driver.BufferObjectPurgeable(ctx, bufObj, option); - - return retval; -} - - -static GLenum -renderbuffer_purgeable(struct gl_context *ctx, GLuint name, GLenum option) -{ - struct gl_renderbuffer *bufObj; - GLenum retval; - - bufObj = _mesa_lookup_renderbuffer(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return 0; - } - - if (bufObj->Purgeable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glObjectPurgeable(name = 0x%x) is already purgeable", name); - return GL_VOLATILE_APPLE; - } - - bufObj->Purgeable = GL_TRUE; - - retval = GL_VOLATILE_APPLE; - if (ctx->Driver.RenderObjectPurgeable) - retval = ctx->Driver.RenderObjectPurgeable(ctx, bufObj, option); - - return retval; -} - - -static GLenum -texture_object_purgeable(struct gl_context *ctx, GLuint name, GLenum option) -{ - struct gl_texture_object *bufObj; - GLenum retval; - - bufObj = _mesa_lookup_texture(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectPurgeable(name = 0x%x)", name); - return 0; - } - - if (bufObj->Purgeable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glObjectPurgeable(name = 0x%x) is already purgeable", name); - return GL_VOLATILE_APPLE; - } - - bufObj->Purgeable = GL_TRUE; - - retval = GL_VOLATILE_APPLE; - if (ctx->Driver.TextureObjectPurgeable) - retval = ctx->Driver.TextureObjectPurgeable(ctx, bufObj, option); - - return retval; -} - - -GLenum GLAPIENTRY -_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option) -{ - GLenum retval; - - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); - - if (name == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectPurgeable(name = 0x%x)", name); - return 0; - } - - switch (option) { - case GL_VOLATILE_APPLE: - case GL_RELEASED_APPLE: - /* legal */ - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glObjectPurgeable(name = 0x%x) invalid option: %d", - name, option); - return 0; - } - - switch (objectType) { - case GL_TEXTURE: - retval = texture_object_purgeable(ctx, name, option); - break; - case GL_RENDERBUFFER_EXT: - retval = renderbuffer_purgeable(ctx, name, option); - break; - case GL_BUFFER_OBJECT_APPLE: - retval = buffer_object_purgeable(ctx, name, option); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glObjectPurgeable(name = 0x%x) invalid type: %d", - name, objectType); - return 0; - } - - /* In strict conformance to the spec, we must only return VOLATILE when - * when passed the VOLATILE option. Madness. - * - * XXX First fix the spec, then fix me. - */ - return option == GL_VOLATILE_APPLE ? GL_VOLATILE_APPLE : retval; -} - - -static GLenum -buffer_object_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option) -{ - struct gl_buffer_object *bufObj; - GLenum retval; - - bufObj = _mesa_lookup_bufferobj(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return 0; - } - - if (! bufObj->Purgeable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glObjectUnpurgeable(name = 0x%x) object is " - " already \"unpurged\"", name); - return 0; - } - - bufObj->Purgeable = GL_FALSE; - - retval = option; - if (ctx->Driver.BufferObjectUnpurgeable) - retval = ctx->Driver.BufferObjectUnpurgeable(ctx, bufObj, option); - - return retval; -} - - -static GLenum -renderbuffer_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option) -{ - struct gl_renderbuffer *bufObj; - GLenum retval; - - bufObj = _mesa_lookup_renderbuffer(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return 0; - } - - if (! bufObj->Purgeable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glObjectUnpurgeable(name = 0x%x) object is " - " already \"unpurged\"", name); - return 0; - } - - bufObj->Purgeable = GL_FALSE; - - retval = option; - if (ctx->Driver.RenderObjectUnpurgeable) - retval = ctx->Driver.RenderObjectUnpurgeable(ctx, bufObj, option); - - return retval; -} - - -static GLenum -texture_object_unpurgeable(struct gl_context *ctx, GLuint name, GLenum option) -{ - struct gl_texture_object *bufObj; - GLenum retval; - - bufObj = _mesa_lookup_texture(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return 0; - } - - if (! bufObj->Purgeable) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glObjectUnpurgeable(name = 0x%x) object is" - " already \"unpurged\"", name); - return 0; - } - - bufObj->Purgeable = GL_FALSE; - - retval = option; - if (ctx->Driver.TextureObjectUnpurgeable) - retval = ctx->Driver.TextureObjectUnpurgeable(ctx, bufObj, option); - - return retval; -} - - -GLenum GLAPIENTRY -_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option) -{ - GET_CURRENT_CONTEXT(ctx); - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, 0); - - if (name == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return 0; - } - - switch (option) { - case GL_RETAINED_APPLE: - case GL_UNDEFINED_APPLE: - /* legal */ - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glObjectUnpurgeable(name = 0x%x) invalid option: %d", - name, option); - return 0; - } - - switch (objectType) { - case GL_BUFFER_OBJECT_APPLE: - return buffer_object_unpurgeable(ctx, name, option); - case GL_TEXTURE: - return texture_object_unpurgeable(ctx, name, option); - case GL_RENDERBUFFER_EXT: - return renderbuffer_unpurgeable(ctx, name, option); - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glObjectUnpurgeable(name = 0x%x) invalid type: %d", - name, objectType); - return 0; - } -} - - -static void -get_buffer_object_parameteriv(struct gl_context *ctx, GLuint name, - GLenum pname, GLint *params) -{ - struct gl_buffer_object *bufObj = _mesa_lookup_bufferobj(ctx, name); - if (!bufObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetObjectParameteriv(name = 0x%x) invalid object", name); - return; - } - - switch (pname) { - case GL_PURGEABLE_APPLE: - *params = bufObj->Purgeable; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", - name, pname); - break; - } -} - - -static void -get_renderbuffer_parameteriv(struct gl_context *ctx, GLuint name, - GLenum pname, GLint *params) -{ - struct gl_renderbuffer *rb = _mesa_lookup_renderbuffer(ctx, name); - if (!rb) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return; - } - - switch (pname) { - case GL_PURGEABLE_APPLE: - *params = rb->Purgeable; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", - name, pname); - break; - } -} - - -static void -get_texture_object_parameteriv(struct gl_context *ctx, GLuint name, - GLenum pname, GLint *params) -{ - struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, name); - if (!texObj) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glObjectUnpurgeable(name = 0x%x)", name); - return; - } - - switch (pname) { - case GL_PURGEABLE_APPLE: - *params = texObj->Purgeable; - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetObjectParameteriv(name = 0x%x) invalid enum: %d", - name, pname); - break; - } -} - - -void GLAPIENTRY -_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, GLenum pname, - GLint *params) -{ - GET_CURRENT_CONTEXT(ctx); - - if (name == 0) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glGetObjectParameteriv(name = 0x%x)", name); - return; - } - - switch (objectType) { - case GL_TEXTURE: - get_texture_object_parameteriv(ctx, name, pname, params); - break; - case GL_BUFFER_OBJECT_APPLE: - get_buffer_object_parameteriv(ctx, name, pname, params); - break; - case GL_RENDERBUFFER_EXT: - get_renderbuffer_parameteriv(ctx, name, pname, params); - break; - default: - _mesa_error(ctx, GL_INVALID_ENUM, - "glGetObjectParameteriv(name = 0x%x) invalid type: %d", - name, objectType); - } -} diff --git a/src/mesa/main/objectpurge.h b/src/mesa/main/objectpurge.h deleted file mode 100644 index f0490121ef6..00000000000 --- a/src/mesa/main/objectpurge.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (C) 2009 VMware, Inc. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef OBJECTPURGE_H -#define OBJECTPURGE_H - - -GLenum GLAPIENTRY -_mesa_ObjectPurgeableAPPLE(GLenum objectType, GLuint name, GLenum option); - -GLenum GLAPIENTRY -_mesa_ObjectUnpurgeableAPPLE(GLenum objectType, GLuint name, GLenum option); - -void GLAPIENTRY -_mesa_GetObjectParameterivAPPLE(GLenum objectType, GLuint name, - GLenum pname, GLint* params); - - -#endif /* OBJECTPURGE_H */ diff --git a/src/mesa/main/pack.c b/src/mesa/main/pack.c index 257f9dd93e8..b1cf949530f 100644 --- a/src/mesa/main/pack.c +++ b/src/mesa/main/pack.c @@ -43,7 +43,7 @@ #include "errors.h" -#include "glheader.h" +#include "util/glheader.h" #include "enums.h" #include "image.h" diff --git a/src/mesa/main/pack.h b/src/mesa/main/pack.h index 8625a145fca..16a62608979 100644 --- a/src/mesa/main/pack.h +++ b/src/mesa/main/pack.h @@ -28,7 +28,7 @@ #define PACK_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_pixelstore_attrib; diff --git a/src/mesa/main/pbo.c b/src/mesa/main/pbo.c index 7cb463d93fc..e46333f340b 100644 --- a/src/mesa/main/pbo.c +++ b/src/mesa/main/pbo.c @@ -32,7 +32,7 @@ #include "errors.h" -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "glformats.h" #include "image.h" @@ -40,8 +40,6 @@ #include "macros.h" #include "pbo.h" - - /** * When we're about to read pixel data out of a PBO (via glDrawPixels, * glTexImage, etc) or write data into a PBO (via glReadPixels, @@ -153,11 +151,11 @@ _mesa_map_pbo_source(struct gl_context *ctx, if (unpack->BufferObj) { /* unpack from PBO */ - buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, - unpack->BufferObj->Size, - GL_MAP_READ_BIT, - unpack->BufferObj, - MAP_INTERNAL); + buf = (GLubyte *) _mesa_bufferobj_map_range(ctx, 0, + unpack->BufferObj->Size, + GL_MAP_READ_BIT, + unpack->BufferObj, + MAP_INTERNAL); if (!buf) return NULL; @@ -285,7 +283,7 @@ _mesa_unmap_pbo_source(struct gl_context *ctx, { assert(unpack != &ctx->Pack); /* catch pack/unpack mismatch */ if (unpack->BufferObj) { - ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, unpack->BufferObj, MAP_INTERNAL); } } @@ -307,11 +305,11 @@ _mesa_map_pbo_dest(struct gl_context *ctx, if (pack->BufferObj) { /* pack into PBO */ - buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, - pack->BufferObj->Size, - GL_MAP_WRITE_BIT, - pack->BufferObj, - MAP_INTERNAL); + buf = (GLubyte *) _mesa_bufferobj_map_range(ctx, 0, + pack->BufferObj->Size, + GL_MAP_WRITE_BIT, + pack->BufferObj, + MAP_INTERNAL); if (!buf) return NULL; @@ -382,7 +380,7 @@ _mesa_unmap_pbo_dest(struct gl_context *ctx, { assert(pack != &ctx->Unpack); /* catch pack/unpack mismatch */ if (pack->BufferObj) { - ctx->Driver.UnmapBuffer(ctx, pack->BufferObj, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, pack->BufferObj, MAP_INTERNAL); } } @@ -413,11 +411,11 @@ _mesa_validate_pbo_teximage(struct gl_context *ctx, GLuint dimensions, return NULL; } - buf = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, - unpack->BufferObj->Size, - GL_MAP_READ_BIT, - unpack->BufferObj, - MAP_INTERNAL); + buf = (GLubyte *) _mesa_bufferobj_map_range(ctx, 0, + unpack->BufferObj->Size, + GL_MAP_READ_BIT, + unpack->BufferObj, + MAP_INTERNAL); if (!buf) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s%uD(PBO is mapped)", funcName, dimensions); @@ -455,11 +453,11 @@ _mesa_validate_pbo_compressed_teximage(struct gl_context *ctx, return pixels; } - buf = (GLubyte*) ctx->Driver.MapBufferRange(ctx, 0, - packing->BufferObj->Size, - GL_MAP_READ_BIT, - packing->BufferObj, - MAP_INTERNAL); + buf = (GLubyte*) _mesa_bufferobj_map_range(ctx, 0, + packing->BufferObj->Size, + GL_MAP_READ_BIT, + packing->BufferObj, + MAP_INTERNAL); /* Validation above already checked that PBO is not mapped, so buffer * should not be null. @@ -479,6 +477,6 @@ _mesa_unmap_teximage_pbo(struct gl_context *ctx, const struct gl_pixelstore_attrib *unpack) { if (unpack->BufferObj) { - ctx->Driver.UnmapBuffer(ctx, unpack->BufferObj, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, unpack->BufferObj, MAP_INTERNAL); } } diff --git a/src/mesa/main/pbo.h b/src/mesa/main/pbo.h index bc764175ff4..e1911b19010 100644 --- a/src/mesa/main/pbo.h +++ b/src/mesa/main/pbo.h @@ -28,7 +28,7 @@ #define PBO_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_pixelstore_attrib; diff --git a/src/mesa/main/performance_monitor.c b/src/mesa/main/performance_monitor.c index e972b878268..cfb9db649b3 100644 --- a/src/mesa/main/performance_monitor.c +++ b/src/mesa/main/performance_monitor.c @@ -35,7 +35,7 @@ */ #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" #include "hash.h" @@ -44,27 +44,409 @@ #include "performance_monitor.h" #include "util/bitset.h" #include "util/ralloc.h" +#include "util/u_memory.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_debug.h" + +#include "pipe/p_context.h" +#include "pipe/p_screen.h" void _mesa_init_performance_monitors(struct gl_context *ctx) { - ctx->PerfMonitor.Monitors = _mesa_NewHashTable(); + _mesa_InitHashTable(&ctx->PerfMonitor.Monitors); ctx->PerfMonitor.NumGroups = 0; ctx->PerfMonitor.Groups = NULL; } + +static bool +init_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m) +{ + struct pipe_context *pipe = ctx->pipe; + unsigned *batch = NULL; + unsigned num_active_counters = 0; + unsigned max_batch_counters = 0; + unsigned num_batch_counters = 0; + int gid, cid; + + st_flush_bitmap_cache(st_context(ctx)); + + /* Determine the number of active counters. */ + for (gid = 0; gid < ctx->PerfMonitor.NumGroups; gid++) { + const struct gl_perf_monitor_group *g = &ctx->PerfMonitor.Groups[gid]; + + if (m->ActiveGroups[gid] > g->MaxActiveCounters) { + /* Maximum number of counters reached. Cannot start the session. */ + if (ST_DEBUG & DEBUG_MESA) { + debug_printf("Maximum number of counters reached. " + "Cannot start the session!\n"); + } + return false; + } + + num_active_counters += m->ActiveGroups[gid]; + if (g->has_batch) + max_batch_counters += m->ActiveGroups[gid]; + } + + if (!num_active_counters) + return true; + + m->active_counters = CALLOC(num_active_counters, + sizeof(*m->active_counters)); + if (!m->active_counters) + return false; + + if (max_batch_counters) { + batch = CALLOC(max_batch_counters, sizeof(*batch)); + if (!batch) + return false; + } + + /* Create a query for each active counter. */ + for (gid = 0; gid < ctx->PerfMonitor.NumGroups; gid++) { + const struct gl_perf_monitor_group *g = &ctx->PerfMonitor.Groups[gid]; + + BITSET_FOREACH_SET(cid, m->ActiveCounters[gid], g->NumCounters) { + const struct gl_perf_monitor_counter *c = &g->Counters[cid]; + struct gl_perf_counter_object *cntr = + &m->active_counters[m->num_active_counters]; + + cntr->id = cid; + cntr->group_id = gid; + if (c->flags & PIPE_DRIVER_QUERY_FLAG_BATCH) { + cntr->batch_index = num_batch_counters; + batch[num_batch_counters++] = c->query_type; + } else { + cntr->query = pipe->create_query(pipe, c->query_type, 0); + if (!cntr->query) + goto fail; + } + ++m->num_active_counters; + } + } + + /* Create the batch query. */ + if (num_batch_counters) { + m->batch_query = pipe->create_batch_query(pipe, num_batch_counters, + batch); + m->batch_result = CALLOC(num_batch_counters, sizeof(m->batch_result->batch[0])); + if (!m->batch_query || !m->batch_result) + goto fail; + } + + FREE(batch); + return true; + +fail: + FREE(batch); + return false; +} + +static void +do_reset_perf_monitor(struct gl_perf_monitor_object *m, + struct pipe_context *pipe) +{ + unsigned i; + + for (i = 0; i < m->num_active_counters; ++i) { + struct pipe_query *query = m->active_counters[i].query; + if (query) + pipe->destroy_query(pipe, query); + } + FREE(m->active_counters); + m->active_counters = NULL; + m->num_active_counters = 0; + + if (m->batch_query) { + pipe->destroy_query(pipe, m->batch_query); + m->batch_query = NULL; + } + FREE(m->batch_result); + m->batch_result = NULL; +} + +static void +delete_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + + do_reset_perf_monitor(m, pipe); + FREE(m); +} + +static GLboolean +begin_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + unsigned i; + + if (!m->num_active_counters) { + /* Create a query for each active counter before starting + * a new monitoring session. */ + if (!init_perf_monitor(ctx, m)) + goto fail; + } + + /* Start the query for each active counter. */ + for (i = 0; i < m->num_active_counters; ++i) { + struct pipe_query *query = m->active_counters[i].query; + if (query && !pipe->begin_query(pipe, query)) + goto fail; + } + + if (m->batch_query && !pipe->begin_query(pipe, m->batch_query)) + goto fail; + + return true; + +fail: + /* Failed to start the monitoring session. */ + do_reset_perf_monitor(m, pipe); + return false; +} + +static void +end_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + unsigned i; + + /* Stop the query for each active counter. */ + for (i = 0; i < m->num_active_counters; ++i) { + struct pipe_query *query = m->active_counters[i].query; + if (query) + pipe->end_query(pipe, query); + } + + if (m->batch_query) + pipe->end_query(pipe, m->batch_query); +} + +static void +reset_perf_monitor(struct gl_context *ctx, struct gl_perf_monitor_object *m) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + + if (!m->Ended) + end_perf_monitor(ctx, m); + + do_reset_perf_monitor(m, pipe); + + if (m->Active) + begin_perf_monitor(ctx, m); +} + +static GLboolean +is_perf_monitor_result_available(struct gl_context *ctx, + struct gl_perf_monitor_object *m) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + unsigned i; + + if (!m->num_active_counters) + return false; + + /* The result of a monitoring session is only available if the query of + * each active counter is idle. */ + for (i = 0; i < m->num_active_counters; ++i) { + struct pipe_query *query = m->active_counters[i].query; + union pipe_query_result result; + if (query && !pipe->get_query_result(pipe, query, false, &result)) { + /* The query is busy. */ + return false; + } + } + + if (m->batch_query && + !pipe->get_query_result(pipe, m->batch_query, false, m->batch_result)) + return false; + + return true; +} + +static void +get_perf_monitor_result(struct gl_context *ctx, + struct gl_perf_monitor_object *m, + GLsizei dataSize, + GLuint *data, + GLint *bytesWritten) +{ + struct pipe_context *pipe = st_context(ctx)->pipe; + unsigned i; + + /* Copy data to the supplied array (data). + * + * The output data format is: <group ID, counter ID, value> for each + * active counter. The API allows counters to appear in any order. + */ + GLsizei offset = 0; + bool have_batch_query = false; + + if (m->batch_query) + have_batch_query = pipe->get_query_result(pipe, m->batch_query, true, + m->batch_result); + + /* Read query results for each active counter. */ + for (i = 0; i < m->num_active_counters; ++i) { + struct gl_perf_counter_object *cntr = &m->active_counters[i]; + union pipe_query_result result = { 0 }; + int gid, cid; + GLenum type; + + cid = cntr->id; + gid = cntr->group_id; + type = ctx->PerfMonitor.Groups[gid].Counters[cid].Type; + + if (cntr->query) { + if (!pipe->get_query_result(pipe, cntr->query, true, &result)) + continue; + } else { + if (!have_batch_query) + continue; + result.batch[0] = m->batch_result->batch[cntr->batch_index]; + } + + data[offset++] = gid; + data[offset++] = cid; + switch (type) { + case GL_UNSIGNED_INT64_AMD: + memcpy(&data[offset], &result.u64, sizeof(uint64_t)); + offset += sizeof(uint64_t) / sizeof(GLuint); + break; + case GL_UNSIGNED_INT: + memcpy(&data[offset], &result.u32, sizeof(uint32_t)); + offset += sizeof(uint32_t) / sizeof(GLuint); + break; + case GL_FLOAT: + case GL_PERCENTAGE_AMD: + memcpy(&data[offset], &result.f, sizeof(GLfloat)); + offset += sizeof(GLfloat) / sizeof(GLuint); + break; + } + } + + if (bytesWritten) + *bytesWritten = offset * sizeof(GLuint); +} + +void +_mesa_free_perfomance_monitor_groups(struct gl_context *ctx) +{ + struct gl_perf_monitor_state *perfmon = &ctx->PerfMonitor; + int gid; + + for (gid = 0; gid < perfmon->NumGroups; gid++) { + FREE((void *)perfmon->Groups[gid].Counters); + } + FREE((void *)perfmon->Groups); +} + static inline void init_groups(struct gl_context *ctx) { - if (unlikely(!ctx->PerfMonitor.Groups)) - ctx->Driver.InitPerfMonitorGroups(ctx); + if (likely(ctx->PerfMonitor.Groups)) + return; + + struct gl_perf_monitor_state *perfmon = &ctx->PerfMonitor; + struct pipe_screen *screen = ctx->pipe->screen; + struct gl_perf_monitor_group *groups = NULL; + int num_counters, num_groups; + int gid, cid; + + /* Get the number of available queries. */ + num_counters = screen->get_driver_query_info(screen, 0, NULL); + + /* Get the number of available groups. */ + num_groups = screen->get_driver_query_group_info(screen, 0, NULL); + groups = CALLOC(num_groups, sizeof(*groups)); + if (!groups) + return; + + for (gid = 0; gid < num_groups; gid++) { + struct gl_perf_monitor_group *g = &groups[perfmon->NumGroups]; + struct pipe_driver_query_group_info group_info; + struct gl_perf_monitor_counter *counters = NULL; + + if (!screen->get_driver_query_group_info(screen, gid, &group_info)) + continue; + + g->Name = group_info.name; + g->MaxActiveCounters = group_info.max_active_queries; + + if (group_info.num_queries) + counters = CALLOC(group_info.num_queries, sizeof(*counters)); + if (!counters) + goto fail; + g->Counters = counters; + + for (cid = 0; cid < num_counters; cid++) { + struct gl_perf_monitor_counter *c = &counters[g->NumCounters]; + struct pipe_driver_query_info info; + + if (!screen->get_driver_query_info(screen, cid, &info)) + continue; + if (info.group_id != gid) + continue; + + c->Name = info.name; + switch (info.type) { + case PIPE_DRIVER_QUERY_TYPE_UINT64: + case PIPE_DRIVER_QUERY_TYPE_BYTES: + case PIPE_DRIVER_QUERY_TYPE_MICROSECONDS: + case PIPE_DRIVER_QUERY_TYPE_HZ: + c->Minimum.u64 = 0; + c->Maximum.u64 = info.max_value.u64 ? info.max_value.u64 : UINT64_MAX; + c->Type = GL_UNSIGNED_INT64_AMD; + break; + case PIPE_DRIVER_QUERY_TYPE_UINT: + c->Minimum.u32 = 0; + c->Maximum.u32 = info.max_value.u32 ? info.max_value.u32 : UINT32_MAX; + c->Type = GL_UNSIGNED_INT; + break; + case PIPE_DRIVER_QUERY_TYPE_FLOAT: + c->Minimum.f = 0.0; + c->Maximum.f = info.max_value.f ? info.max_value.f : FLT_MAX; + c->Type = GL_FLOAT; + break; + case PIPE_DRIVER_QUERY_TYPE_PERCENTAGE: + c->Minimum.f = 0.0f; + c->Maximum.f = 100.0f; + c->Type = GL_PERCENTAGE_AMD; + break; + default: + unreachable("Invalid driver query type!"); + } + + c->query_type = info.query_type; + c->flags = info.flags; + if (c->flags & PIPE_DRIVER_QUERY_FLAG_BATCH) + g->has_batch = true; + + g->NumCounters++; + } + perfmon->NumGroups++; + } + perfmon->Groups = groups; + + return; + +fail: + for (gid = 0; gid < num_groups; gid++) { + FREE((void *)groups[gid].Counters); + } + FREE(groups); } static struct gl_perf_monitor_object * new_performance_monitor(struct gl_context *ctx, GLuint index) { unsigned i; - struct gl_perf_monitor_object *m = ctx->Driver.NewPerfMonitor(ctx); + struct gl_perf_monitor_object *m = CALLOC_STRUCT(gl_perf_monitor_object); if (m == NULL) return NULL; @@ -96,7 +478,7 @@ new_performance_monitor(struct gl_context *ctx, GLuint index) fail: ralloc_free(m->ActiveGroups); ralloc_free(m->ActiveCounters); - ctx->Driver.DeletePerfMonitor(ctx, m); + delete_perf_monitor(ctx, m); return NULL; } @@ -108,22 +490,21 @@ free_performance_monitor(void *data, void *user) ralloc_free(m->ActiveGroups); ralloc_free(m->ActiveCounters); - ctx->Driver.DeletePerfMonitor(ctx, m); + delete_perf_monitor(ctx, m); } void _mesa_free_performance_monitors(struct gl_context *ctx) { - _mesa_HashDeleteAll(ctx->PerfMonitor.Monitors, - free_performance_monitor, ctx); - _mesa_DeleteHashTable(ctx->PerfMonitor.Monitors); + _mesa_DeinitHashTable(&ctx->PerfMonitor.Monitors, free_performance_monitor, + ctx); } static inline struct gl_perf_monitor_object * lookup_monitor(struct gl_context *ctx, GLuint id) { return (struct gl_perf_monitor_object *) - _mesa_HashLookup(ctx->PerfMonitor.Monitors, id); + _mesa_HashLookup(&ctx->PerfMonitor.Monitors, id); } static inline const struct gl_perf_monitor_group * @@ -353,7 +734,7 @@ _mesa_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors) if (monitors == NULL) return; - if (_mesa_HashFindFreeKeys(ctx->PerfMonitor.Monitors, monitors, n)) { + if (_mesa_HashFindFreeKeys(&ctx->PerfMonitor.Monitors, monitors, n)) { GLsizei i; for (i = 0; i < n; i++) { struct gl_perf_monitor_object *m = @@ -362,7 +743,7 @@ _mesa_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors) _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenPerfMonitorsAMD"); return; } - _mesa_HashInsert(ctx->PerfMonitor.Monitors, monitors[i], m, true); + _mesa_HashInsert(&ctx->PerfMonitor.Monitors, monitors[i], m); } } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenPerfMonitorsAMD"); @@ -393,14 +774,14 @@ _mesa_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors) if (m) { /* Give the driver a chance to stop the monitor if it's active. */ if (m->Active) { - ctx->Driver.ResetPerfMonitor(ctx, m); + reset_perf_monitor(ctx, m); m->Ended = false; } - _mesa_HashRemove(ctx->PerfMonitor.Monitors, monitors[i]); + _mesa_HashRemove(&ctx->PerfMonitor.Monitors, monitors[i]); ralloc_free(m->ActiveGroups); ralloc_free(m->ActiveCounters); - ctx->Driver.DeletePerfMonitor(ctx, m); + delete_perf_monitor(ctx, m); } else { /* "INVALID_VALUE error will be generated if any of the monitor IDs * in the <monitors> parameter to DeletePerfMonitorsAMD do not @@ -460,7 +841,7 @@ _mesa_SelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, * results for that monitor become invalidated and the result queries * PERFMON_RESULT_SIZE_AMD and PERFMON_RESULT_AVAILABLE_AMD are reset to 0." */ - ctx->Driver.ResetPerfMonitor(ctx, m); + reset_perf_monitor(ctx, m); /* Sanity check the counter ID list. */ for (i = 0; i < numCounters; i++) { @@ -515,7 +896,7 @@ _mesa_BeginPerfMonitorAMD(GLuint monitor) /* The driver is free to return false if it can't begin monitoring for * any reason. This translates into an INVALID_OPERATION error. */ - if (ctx->Driver.BeginPerfMonitor(ctx, m)) { + if (begin_perf_monitor(ctx, m)) { m->Active = true; m->Ended = false; } else { @@ -544,7 +925,7 @@ _mesa_EndPerfMonitorAMD(GLuint monitor) return; } - ctx->Driver.EndPerfMonitor(ctx, m); + end_perf_monitor(ctx, m); m->Active = false; m->Ended = true; @@ -606,7 +987,7 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, /* If the monitor has never ended, there is no result. */ result_available = m->Ended && - ctx->Driver.IsPerfMonitorResultAvailable(ctx, m); + is_perf_monitor_result_available(ctx, m); /* AMD appears to return 0 for all queries unless a result is available. */ if (!result_available) { @@ -628,7 +1009,7 @@ _mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, *bytesWritten = sizeof(GLuint); break; case GL_PERFMON_RESULT_AMD: - ctx->Driver.GetPerfMonitorResult(ctx, m, dataSize, data, bytesWritten); + get_perf_monitor_result(ctx, m, dataSize, data, bytesWritten); break; default: _mesa_error(ctx, GL_INVALID_ENUM, diff --git a/src/mesa/main/performance_monitor.h b/src/mesa/main/performance_monitor.h index 2ba703276b8..b2754a48708 100644 --- a/src/mesa/main/performance_monitor.h +++ b/src/mesa/main/performance_monitor.h @@ -30,7 +30,7 @@ #ifndef PERFORMANCE_MONITOR_H #define PERFORMANCE_MONITOR_H -#include "glheader.h" +#include "util/glheader.h" extern void _mesa_init_performance_monitors(struct gl_context *ctx); @@ -38,52 +38,9 @@ _mesa_init_performance_monitors(struct gl_context *ctx); extern void _mesa_free_performance_monitors(struct gl_context *ctx); -extern void GLAPIENTRY -_mesa_GetPerfMonitorGroupsAMD(GLint *numGroups, GLsizei groupsSize, - GLuint *groups); - -extern void GLAPIENTRY -_mesa_GetPerfMonitorCountersAMD(GLuint group, GLint *numCounters, - GLint *maxActiveCounters, - GLsizei countersSize, GLuint *counters); - -extern void GLAPIENTRY -_mesa_GetPerfMonitorGroupStringAMD(GLuint group, GLsizei bufSize, - GLsizei *length, GLchar *groupString); - -extern void GLAPIENTRY -_mesa_GetPerfMonitorCounterStringAMD(GLuint group, GLuint counter, - GLsizei bufSize, GLsizei *length, - GLchar *counterString); - -extern void GLAPIENTRY -_mesa_GetPerfMonitorCounterInfoAMD(GLuint group, GLuint counter, GLenum pname, - GLvoid *data); - -extern void GLAPIENTRY -_mesa_GenPerfMonitorsAMD(GLsizei n, GLuint *monitors); - -extern void GLAPIENTRY -_mesa_DeletePerfMonitorsAMD(GLsizei n, GLuint *monitors); - -extern void GLAPIENTRY -_mesa_SelectPerfMonitorCountersAMD(GLuint monitor, GLboolean enable, - GLuint group, GLint numCounters, - GLuint *counterList); - -extern void GLAPIENTRY -_mesa_BeginPerfMonitorAMD(GLuint monitor); - -extern void GLAPIENTRY -_mesa_EndPerfMonitorAMD(GLuint monitor); - -extern void GLAPIENTRY -_mesa_GetPerfMonitorCounterDataAMD(GLuint monitor, GLenum pname, - GLsizei dataSize, GLuint *data, - GLint *bytesWritten); - unsigned _mesa_perf_monitor_counter_size(const struct gl_perf_monitor_counter *); - +void +_mesa_free_perfomance_monitor_groups(struct gl_context *ctx); #endif diff --git a/src/mesa/main/performance_query.c b/src/mesa/main/performance_query.c index b3febdd57af..a5e2ef25f02 100644 --- a/src/mesa/main/performance_query.c +++ b/src/mesa/main/performance_query.c @@ -27,7 +27,7 @@ */ #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" #include "hash.h" @@ -35,11 +35,16 @@ #include "mtypes.h" #include "performance_query.h" #include "util/ralloc.h" +#include "api_exec_decl.h" + +#include "pipe/p_context.h" + +#include "state_tracker/st_cb_flush.h" void _mesa_init_performance_queries(struct gl_context *ctx) { - ctx->PerfQuery.Objects = _mesa_NewHashTable(); + _mesa_InitHashTable(&ctx->PerfQuery.Objects); } static void @@ -54,30 +59,25 @@ free_performance_query(void *data, void *user) */ m->Active = false; m->Used = false; - ctx->Driver.DeletePerfQuery(ctx, m); + ctx->pipe->delete_intel_perf_query(ctx->pipe, (struct pipe_query *)m); } void _mesa_free_performance_queries(struct gl_context *ctx) { - _mesa_HashDeleteAll(ctx->PerfQuery.Objects, - free_performance_query, ctx); - _mesa_DeleteHashTable(ctx->PerfQuery.Objects); + _mesa_DeinitHashTable(&ctx->PerfQuery.Objects, free_performance_query, ctx); } static inline struct gl_perf_query_object * lookup_object(struct gl_context *ctx, GLuint id) { - return _mesa_HashLookup(ctx->PerfQuery.Objects, id); + return _mesa_HashLookup(&ctx->PerfQuery.Objects, id); } static GLuint init_performance_query_info(struct gl_context *ctx) { - if (ctx->Driver.InitPerfQueryInfo) - return ctx->Driver.InitPerfQueryInfo(ctx); - else - return 0; + return ctx->pipe->init_intel_perf_query_info(ctx->pipe); } /* For INTEL_performance_query, query id 0 is reserved to be invalid. */ @@ -238,7 +238,8 @@ _mesa_GetPerfQueryIdByNameINTEL(char *queryName, GLuint *queryId) const GLchar *name; GLuint ignore; - ctx->Driver.GetPerfQueryInfo(ctx, i, &name, &ignore, &ignore, &ignore); + ctx->pipe->get_intel_perf_query_info(ctx->pipe, i, &name, + &ignore, &ignore, &ignore); if (strcmp(name, queryName) == 0) { *queryId = index_to_queryid(i); @@ -278,11 +279,9 @@ _mesa_GetPerfQueryInfoINTEL(GLuint queryId, return; } - ctx->Driver.GetPerfQueryInfo(ctx, queryIndex, - &queryName, - &queryDataSize, - &queryNumCounters, - &queryNumActive); + ctx->pipe->get_intel_perf_query_info(ctx->pipe, queryIndex, &queryName, + &queryDataSize, &queryNumCounters, + &queryNumActive); output_clipped_string(name, nameLength, queryName); @@ -309,6 +308,58 @@ _mesa_GetPerfQueryInfoINTEL(GLuint queryId, *capsMask = GL_PERFQUERY_SINGLE_CONTEXT_INTEL; } +static uint32_t +pipe_counter_type_enum_to_gl_type(enum pipe_perf_counter_type type) +{ + switch (type) { + case PIPE_PERF_COUNTER_TYPE_EVENT: return GL_PERFQUERY_COUNTER_EVENT_INTEL; + case PIPE_PERF_COUNTER_TYPE_DURATION_NORM: return GL_PERFQUERY_COUNTER_DURATION_NORM_INTEL; + case PIPE_PERF_COUNTER_TYPE_DURATION_RAW: return GL_PERFQUERY_COUNTER_DURATION_RAW_INTEL; + case PIPE_PERF_COUNTER_TYPE_THROUGHPUT: return GL_PERFQUERY_COUNTER_THROUGHPUT_INTEL; + case PIPE_PERF_COUNTER_TYPE_RAW: return GL_PERFQUERY_COUNTER_RAW_INTEL; + case PIPE_PERF_COUNTER_TYPE_TIMESTAMP: return GL_PERFQUERY_COUNTER_TIMESTAMP_INTEL; + default: + unreachable("Unknown counter type"); + } +} + +static uint32_t +pipe_counter_data_type_to_gl_type(enum pipe_perf_counter_data_type type) +{ + switch (type) { + case PIPE_PERF_COUNTER_DATA_TYPE_BOOL32: return GL_PERFQUERY_COUNTER_DATA_BOOL32_INTEL; + case PIPE_PERF_COUNTER_DATA_TYPE_UINT32: return GL_PERFQUERY_COUNTER_DATA_UINT32_INTEL; + case PIPE_PERF_COUNTER_DATA_TYPE_UINT64: return GL_PERFQUERY_COUNTER_DATA_UINT64_INTEL; + case PIPE_PERF_COUNTER_DATA_TYPE_FLOAT: return GL_PERFQUERY_COUNTER_DATA_FLOAT_INTEL; + case PIPE_PERF_COUNTER_DATA_TYPE_DOUBLE: return GL_PERFQUERY_COUNTER_DATA_DOUBLE_INTEL; + default: + unreachable("Unknown counter data type"); + } +} + +static void +get_perf_counter_info(struct gl_context *ctx, + unsigned query_index, + unsigned counter_index, + const char **name, + const char **desc, + GLuint *offset, + GLuint *data_size, + GLuint *type_enum, + GLuint *data_type_enum, + GLuint64 *raw_max) +{ + struct pipe_context *pipe = ctx->pipe; + uint32_t pipe_type_enum; + uint32_t pipe_data_type_enum; + + pipe->get_intel_perf_query_counter_info(pipe, query_index, counter_index, + name, desc, offset, data_size, + &pipe_type_enum, &pipe_data_type_enum, raw_max); + *type_enum = pipe_counter_type_enum_to_gl_type(pipe_type_enum); + *data_type_enum = pipe_counter_data_type_to_gl_type(pipe_data_type_enum); +} + extern void GLAPIENTRY _mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, GLuint nameLength, GLchar *name, @@ -347,11 +398,9 @@ _mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, return; } - ctx->Driver.GetPerfQueryInfo(ctx, queryIndex, - &queryName, - &queryDataSize, - &queryNumCounters, - &queryNumActive); + ctx->pipe->get_intel_perf_query_info(ctx->pipe, queryIndex, &queryName, + &queryDataSize, &queryNumCounters, + &queryNumActive); counterIndex = counterid_to_index(counterId); @@ -361,14 +410,14 @@ _mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, return; } - ctx->Driver.GetPerfCounterInfo(ctx, queryIndex, counterIndex, - &counterName, - &counterDesc, - &counterOffset, - &counterDataSize, - &counterTypeEnum, - &counterDataTypeEnum, - &counterRawMax); + get_perf_counter_info(ctx, queryIndex, counterIndex, + &counterName, + &counterDesc, + &counterOffset, + &counterDataSize, + &counterTypeEnum, + &counterDataTypeEnum, + &counterRawMax); output_clipped_string(name, nameLength, counterName); output_clipped_string(desc, descLength, counterDesc); @@ -439,7 +488,7 @@ _mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle) return; } - id = _mesa_HashFindFreeKeyBlock(ctx->PerfQuery.Objects, 1); + id = _mesa_HashFindFreeKeyBlock(&ctx->PerfQuery.Objects, 1); if (!id) { /* The GL_INTEL_performance_query spec says: * @@ -452,7 +501,8 @@ _mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle) return; } - obj = ctx->Driver.NewPerfQueryObject(ctx, queryid_to_index(queryId)); + obj = (struct gl_perf_query_object *)ctx->pipe->new_intel_perf_query_obj(ctx->pipe, + queryid_to_index(queryId)); if (obj == NULL) { _mesa_error_no_memory(__func__); return; @@ -462,7 +512,7 @@ _mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle) obj->Active = false; obj->Ready = false; - _mesa_HashInsert(ctx->PerfQuery.Objects, id, obj, true); + _mesa_HashInsert(&ctx->PerfQuery.Objects, id, obj); *queryHandle = id; } @@ -493,12 +543,12 @@ _mesa_DeletePerfQueryINTEL(GLuint queryHandle) _mesa_EndPerfQueryINTEL(queryHandle); if (obj->Used && !obj->Ready) { - ctx->Driver.WaitPerfQuery(ctx, obj); + ctx->pipe->wait_intel_perf_query(ctx->pipe, (struct pipe_query *)obj); obj->Ready = true; } - _mesa_HashRemove(ctx->PerfQuery.Objects, queryHandle); - ctx->Driver.DeletePerfQuery(ctx, obj); + _mesa_HashRemove(&ctx->PerfQuery.Objects, queryHandle); + ctx->pipe->delete_intel_perf_query(ctx->pipe, (struct pipe_query *)obj); } extern void GLAPIENTRY @@ -540,11 +590,11 @@ _mesa_BeginPerfQueryINTEL(GLuint queryHandle) * waiting for data on that object. */ if (obj->Used && !obj->Ready) { - ctx->Driver.WaitPerfQuery(ctx, obj); + ctx->pipe->wait_intel_perf_query(ctx->pipe, (struct pipe_query *)obj); obj->Ready = true; } - if (ctx->Driver.BeginPerfQuery(ctx, obj)) { + if (ctx->pipe->begin_intel_perf_query(ctx->pipe, (struct pipe_query *)obj)) { obj->Used = true; obj->Active = true; obj->Ready = false; @@ -580,7 +630,7 @@ _mesa_EndPerfQueryINTEL(GLuint queryHandle) return; } - ctx->Driver.EndPerfQuery(ctx, obj); + ctx->pipe->end_intel_perf_query(ctx->pipe, (struct pipe_query *)obj); obj->Active = false; obj->Ready = false; @@ -637,19 +687,22 @@ _mesa_GetPerfQueryDataINTEL(GLuint queryHandle, GLuint flags, return; } - obj->Ready = ctx->Driver.IsPerfQueryReady(ctx, obj); + if (!obj->Ready) + obj->Ready = ctx->pipe->is_intel_perf_query_ready(ctx->pipe, + (struct pipe_query *)obj); if (!obj->Ready) { if (flags == GL_PERFQUERY_FLUSH_INTEL) { - ctx->Driver.Flush(ctx); + st_glFlush(ctx, 0); } else if (flags == GL_PERFQUERY_WAIT_INTEL) { - ctx->Driver.WaitPerfQuery(ctx, obj); + ctx->pipe->wait_intel_perf_query(ctx->pipe, (struct pipe_query *)obj); obj->Ready = true; } } if (obj->Ready) { - if (!ctx->Driver.GetPerfQueryData(ctx, obj, dataSize, data, bytesWritten)) { + if (!ctx->pipe->get_intel_perf_query_data(ctx->pipe, (struct pipe_query *)obj, + dataSize, data, bytesWritten)) { memset(data, 0, dataSize); *bytesWritten = 0; diff --git a/src/mesa/main/performance_query.h b/src/mesa/main/performance_query.h index 784866402ba..64ede844d4f 100644 --- a/src/mesa/main/performance_query.h +++ b/src/mesa/main/performance_query.h @@ -29,7 +29,7 @@ #ifndef PERFORMANCE_QUERY_H #define PERFORMANCE_QUERY_H -#include "glheader.h" +#include "util/glheader.h" extern void _mesa_init_performance_queries(struct gl_context *ctx); @@ -37,43 +37,4 @@ _mesa_init_performance_queries(struct gl_context *ctx); extern void _mesa_free_performance_queries(struct gl_context *ctx); -extern void GLAPIENTRY -_mesa_GetFirstPerfQueryIdINTEL(GLuint *queryId); - -extern void GLAPIENTRY -_mesa_GetNextPerfQueryIdINTEL(GLuint queryId, GLuint *nextQueryId); - -extern void GLAPIENTRY -_mesa_GetPerfQueryIdByNameINTEL(char *queryName, GLuint *queryId); - -extern void GLAPIENTRY -_mesa_GetPerfQueryInfoINTEL(GLuint queryId, - GLuint queryNameLength, char *queryName, - GLuint *dataSize, GLuint *noCounters, - GLuint *noActiveInstances, - GLuint *capsMask); - -extern void GLAPIENTRY -_mesa_GetPerfCounterInfoINTEL(GLuint queryId, GLuint counterId, - GLuint counterNameLength, char *counterName, - GLuint counterDescLength, char *counterDesc, - GLuint *counterOffset, GLuint *counterDataSize, GLuint *counterTypeEnum, - GLuint *counterDataTypeEnum, GLuint64 *rawCounterMaxValue); - -extern void GLAPIENTRY -_mesa_CreatePerfQueryINTEL(GLuint queryId, GLuint *queryHandle); - -extern void GLAPIENTRY -_mesa_DeletePerfQueryINTEL(GLuint queryHandle); - -extern void GLAPIENTRY -_mesa_BeginPerfQueryINTEL(GLuint queryHandle); - -extern void GLAPIENTRY -_mesa_EndPerfQueryINTEL(GLuint queryHandle); - -extern void GLAPIENTRY -_mesa_GetPerfQueryDataINTEL(GLuint queryHandle, GLuint flags, - GLsizei dataSize, void *data, GLuint *bytesWritten); - #endif diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c index 58ea4cd8ba1..943c681d01c 100644 --- a/src/mesa/main/pipelineobj.c +++ b/src/mesa/main/pipelineobj.c @@ -32,7 +32,7 @@ */ #include <stdbool.h> -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/draw_validate.h" #include "main/enums.h" @@ -50,6 +50,7 @@ #include "program/prog_parameter.h" #include "util/ralloc.h" #include "util/bitscan.h" +#include "api_exec_decl.h" /** * Delete a pipeline object. @@ -93,7 +94,7 @@ _mesa_new_pipeline_object(struct gl_context *ctx, GLuint name) void _mesa_init_pipeline(struct gl_context *ctx) { - ctx->Pipeline.Objects = _mesa_NewHashTable(); + _mesa_InitHashTable(&ctx->Pipeline.Objects); ctx->Pipeline.Current = NULL; @@ -104,7 +105,7 @@ _mesa_init_pipeline(struct gl_context *ctx) /** - * Callback for deleting a pipeline object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a pipeline object. Called by _mesa_DeleteHashTable(). */ static void delete_pipelineobj_cb(void *data, void *userData) @@ -122,10 +123,7 @@ void _mesa_free_pipeline_data(struct gl_context *ctx) { _mesa_reference_pipeline_object(ctx, &ctx->_Shader, NULL); - - _mesa_HashDeleteAll(ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx); - _mesa_DeleteHashTable(ctx->Pipeline.Objects); - + _mesa_DeinitHashTable(&ctx->Pipeline.Objects, delete_pipelineobj_cb, ctx); _mesa_delete_pipeline_object(ctx, ctx->Pipeline.Default); } @@ -144,7 +142,7 @@ _mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id) return NULL; else return (struct gl_pipeline_object *) - _mesa_HashLookupLocked(ctx->Pipeline.Objects, id); + _mesa_HashLookupLocked(&ctx->Pipeline.Objects, id); } /** @@ -154,7 +152,7 @@ static void save_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj) { if (obj->Name > 0) { - _mesa_HashInsertLocked(ctx->Pipeline.Objects, obj->Name, obj, true); + _mesa_HashInsertLocked(&ctx->Pipeline.Objects, obj->Name, obj); } } @@ -166,7 +164,7 @@ static void remove_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj) { if (obj->Name > 0) { - _mesa_HashRemoveLocked(ctx->Pipeline.Objects, obj->Name); + _mesa_HashRemoveLocked(&ctx->Pipeline.Objects, obj->Name); } } @@ -542,7 +540,6 @@ _mesa_bind_pipeline(struct gl_context *ctx, _mesa_update_vertex_processing_mode(ctx); _mesa_update_allow_draw_out_of_order(ctx); - _mesa_update_primitive_id_is_unused(ctx); _mesa_update_valid_to_render_state(ctx); } } @@ -609,7 +606,7 @@ create_program_pipelines(struct gl_context *ctx, GLsizei n, GLuint *pipelines, if (!pipelines) return; - _mesa_HashFindFreeKeys(ctx->Pipeline.Objects, pipelines, n); + _mesa_HashFindFreeKeys(&ctx->Pipeline.Objects, pipelines, n); for (i = 0; i < n; i++) { struct gl_pipeline_object *obj; diff --git a/src/mesa/main/pipelineobj.h b/src/mesa/main/pipelineobj.h index 8cc5954eec7..c40d6656e29 100644 --- a/src/mesa/main/pipelineobj.h +++ b/src/mesa/main/pipelineobj.h @@ -26,7 +26,7 @@ #ifndef PIPELINEOBJ_H #define PIPELINEOBJ_H -#include "glheader.h" +#include "util/glheader.h" #ifdef __cplusplus extern "C" { @@ -70,51 +70,6 @@ extern GLboolean _mesa_validate_program_pipeline(struct gl_context * ctx, struct gl_pipeline_object *pipe); - -void GLAPIENTRY -_mesa_UseProgramStages_no_error(GLuint pipeline, GLbitfield stages, - GLuint prog); -extern void GLAPIENTRY -_mesa_UseProgramStages(GLuint pipeline, GLbitfield stages, GLuint program); - -void GLAPIENTRY -_mesa_ActiveShaderProgram_no_error(GLuint pipeline, GLuint program); -extern void GLAPIENTRY -_mesa_ActiveShaderProgram(GLuint pipeline, GLuint program); - -void GLAPIENTRY -_mesa_BindProgramPipeline_no_error(GLuint pipeline); -extern void GLAPIENTRY -_mesa_BindProgramPipeline(GLuint pipeline); - -extern void GLAPIENTRY -_mesa_DeleteProgramPipelines(GLsizei n, const GLuint *pipelines); - -void GLAPIENTRY -_mesa_GenProgramPipelines_no_error(GLsizei n, GLuint *pipelines); - -extern void GLAPIENTRY -_mesa_GenProgramPipelines(GLsizei n, GLuint *pipelines); - -void GLAPIENTRY -_mesa_CreateProgramPipelines_no_error(GLsizei n, GLuint *pipelines); - -void GLAPIENTRY -_mesa_CreateProgramPipelines(GLsizei n, GLuint *pipelines); - -extern GLboolean GLAPIENTRY -_mesa_IsProgramPipeline(GLuint pipeline); - -extern void GLAPIENTRY -_mesa_GetProgramPipelineiv(GLuint pipeline, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_ValidateProgramPipeline(GLuint pipeline); - -extern void GLAPIENTRY -_mesa_GetProgramPipelineInfoLog(GLuint pipeline, GLsizei bufSize, - GLsizei *length, GLchar *infoLog); - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/pixel.c b/src/mesa/main/pixel.c index ffa362f297d..ec75248ec1e 100644 --- a/src/mesa/main/pixel.c +++ b/src/mesa/main/pixel.c @@ -28,15 +28,16 @@ * Pixel transfer functions (glPixelZoom, glPixelMap, glPixelTransfer) */ -#include "c99_math.h" -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "context.h" #include "macros.h" #include "pixel.h" #include "pbo.h" #include "mtypes.h" +#include "api_exec_decl.h" +#include <math.h> /**********************************************************************/ /***** glPixelZoom *****/ @@ -343,6 +344,9 @@ _mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values ) return; } + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + values = (GLfloat *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); if (!values) { if (ctx->Pack.BufferObj) { @@ -392,6 +396,9 @@ _mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values ) return; } + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + values = (GLuint *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); if (!values) { if (ctx->Pack.BufferObj) { @@ -441,6 +448,9 @@ _mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values ) return; } + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + values = (GLushort *) _mesa_map_pbo_dest(ctx, &ctx->Pack, values); if (!values) { if (ctx->Pack.BufferObj) { diff --git a/src/mesa/main/pixel.h b/src/mesa/main/pixel.h index 17e7376281f..9ec720863af 100644 --- a/src/mesa/main/pixel.h +++ b/src/mesa/main/pixel.h @@ -33,36 +33,10 @@ #define PIXEL_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; - -void GLAPIENTRY -_mesa_PixelZoom( GLfloat xfactor, GLfloat yfactor ); -void GLAPIENTRY -_mesa_PixelMapfv( GLenum map, GLsizei mapsize, const GLfloat *values ); -void GLAPIENTRY -_mesa_PixelMapuiv(GLenum map, GLsizei mapsize, const GLuint *values ); -void GLAPIENTRY -_mesa_PixelMapusv(GLenum map, GLsizei mapsize, const GLushort *values ); -void GLAPIENTRY -_mesa_GetnPixelMapfvARB( GLenum map, GLsizei bufSize, GLfloat *values ); -void GLAPIENTRY -_mesa_GetPixelMapfv( GLenum map, GLfloat *values ); -void GLAPIENTRY -_mesa_GetnPixelMapuivARB( GLenum map, GLsizei bufSize, GLuint *values ); -void GLAPIENTRY -_mesa_GetPixelMapuiv( GLenum map, GLuint *values ); -void GLAPIENTRY -_mesa_GetnPixelMapusvARB( GLenum map, GLsizei bufSize, GLushort *values ); -void GLAPIENTRY -_mesa_GetPixelMapusv( GLenum map, GLushort *values ); -void GLAPIENTRY -_mesa_PixelTransferf(GLenum pname, GLfloat param); -void GLAPIENTRY -_mesa_PixelTransferi( GLenum pname, GLint param ); - extern void _mesa_update_pixel( struct gl_context *ctx ); diff --git a/src/mesa/main/pixelstore.c b/src/mesa/main/pixelstore.c index d1d1f038909..016181f624f 100644 --- a/src/mesa/main/pixelstore.c +++ b/src/mesa/main/pixelstore.c @@ -28,12 +28,13 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "context.h" #include "pixelstore.h" #include "mtypes.h" #include "util/rounding.h" +#include "api_exec_decl.h" static ALWAYS_INLINE void @@ -54,7 +55,7 @@ pixel_storei(GLenum pname, GLint param, bool no_error) ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE; break; case GL_PACK_ROW_LENGTH: - if (!no_error && !_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) + if (!no_error && _mesa_is_gles1(ctx)) goto invalid_enum_error; if (!no_error && param<0) goto invalid_value_error; @@ -68,14 +69,14 @@ pixel_storei(GLenum pname, GLint param, bool no_error) ctx->Pack.ImageHeight = param; break; case GL_PACK_SKIP_PIXELS: - if (!no_error && !_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) + if (!no_error && _mesa_is_gles1(ctx)) goto invalid_enum_error; if (!no_error && param<0) goto invalid_value_error; ctx->Pack.SkipPixels = param; break; case GL_PACK_SKIP_ROWS: - if (!no_error && !_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) + if (!no_error && _mesa_is_gles1(ctx)) goto invalid_enum_error; if (!no_error && param<0) goto invalid_value_error; @@ -143,7 +144,7 @@ pixel_storei(GLenum pname, GLint param, bool no_error) ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; break; case GL_UNPACK_ROW_LENGTH: - if (!no_error && ctx->API == API_OPENGLES) + if (!no_error && _mesa_is_gles1(ctx)) goto invalid_enum_error; if (!no_error && param<0) goto invalid_value_error; @@ -157,14 +158,14 @@ pixel_storei(GLenum pname, GLint param, bool no_error) ctx->Unpack.ImageHeight = param; break; case GL_UNPACK_SKIP_PIXELS: - if (!no_error && ctx->API == API_OPENGLES) + if (!no_error && _mesa_is_gles1(ctx)) goto invalid_enum_error; if (!no_error && param<0) goto invalid_value_error; ctx->Unpack.SkipPixels = param; break; case GL_UNPACK_SKIP_ROWS: - if (!no_error && ctx->API == API_OPENGLES) + if (!no_error && _mesa_is_gles1(ctx)) goto invalid_enum_error; if (!no_error && param<0) goto invalid_value_error; @@ -256,6 +257,25 @@ _mesa_PixelStoref_no_error(GLenum pname, GLfloat param) _mesa_PixelStorei_no_error(pname, lroundf(param)); } +void +_mesa_init_pixelstore_attrib(struct gl_context *ctx, + struct gl_pixelstore_attrib *pack) +{ + pack->Alignment = 4; + pack->RowLength = 0; + pack->ImageHeight = 0; + pack->SkipPixels = 0; + pack->SkipRows = 0; + pack->SkipImages = 0; + pack->SwapBytes = GL_FALSE; + pack->LsbFirst = GL_FALSE; + pack->Invert = GL_FALSE; + pack->CompressedBlockWidth = 0; + pack->CompressedBlockHeight = 0; + pack->CompressedBlockDepth = 0; + pack->CompressedBlockSize = 0; + _mesa_reference_buffer_object(ctx, &pack->BufferObj, NULL); +} /** * Initialize the context's pixel store state. @@ -264,34 +284,9 @@ void _mesa_init_pixelstore(struct gl_context *ctx) { /* Pixel transfer */ - ctx->Pack.Alignment = 4; - ctx->Pack.RowLength = 0; - ctx->Pack.ImageHeight = 0; - ctx->Pack.SkipPixels = 0; - ctx->Pack.SkipRows = 0; - ctx->Pack.SkipImages = 0; - ctx->Pack.SwapBytes = GL_FALSE; - ctx->Pack.LsbFirst = GL_FALSE; - ctx->Pack.Invert = GL_FALSE; - ctx->Pack.CompressedBlockWidth = 0; - ctx->Pack.CompressedBlockHeight = 0; - ctx->Pack.CompressedBlockDepth = 0; - ctx->Pack.CompressedBlockSize = 0; - _mesa_reference_buffer_object(ctx, &ctx->Pack.BufferObj, NULL); - ctx->Unpack.Alignment = 4; - ctx->Unpack.RowLength = 0; - ctx->Unpack.ImageHeight = 0; - ctx->Unpack.SkipPixels = 0; - ctx->Unpack.SkipRows = 0; - ctx->Unpack.SkipImages = 0; - ctx->Unpack.SwapBytes = GL_FALSE; - ctx->Unpack.LsbFirst = GL_FALSE; - ctx->Unpack.Invert = GL_FALSE; - ctx->Unpack.CompressedBlockWidth = 0; - ctx->Unpack.CompressedBlockHeight = 0; - ctx->Unpack.CompressedBlockDepth = 0; - ctx->Unpack.CompressedBlockSize = 0; - _mesa_reference_buffer_object(ctx, &ctx->Unpack.BufferObj, NULL); + _mesa_init_pixelstore_attrib(ctx, &ctx->Pack); + _mesa_init_pixelstore_attrib(ctx, &ctx->Unpack); + _mesa_init_pixelstore_attrib(ctx, &ctx->DefaultPacking); /* * _mesa_unpack_image() returns image data in this format. When we @@ -300,15 +295,6 @@ _mesa_init_pixelstore(struct gl_context *ctx) * unpacking parameters to these values! */ ctx->DefaultPacking.Alignment = 1; - ctx->DefaultPacking.RowLength = 0; - ctx->DefaultPacking.SkipPixels = 0; - ctx->DefaultPacking.SkipRows = 0; - ctx->DefaultPacking.ImageHeight = 0; - ctx->DefaultPacking.SkipImages = 0; - ctx->DefaultPacking.SwapBytes = GL_FALSE; - ctx->DefaultPacking.LsbFirst = GL_FALSE; - ctx->DefaultPacking.Invert = GL_FALSE; - _mesa_reference_buffer_object(ctx, &ctx->DefaultPacking.BufferObj, NULL); } diff --git a/src/mesa/main/pixelstore.h b/src/mesa/main/pixelstore.h index d21c6fe27f4..8ae885a3c53 100644 --- a/src/mesa/main/pixelstore.h +++ b/src/mesa/main/pixelstore.h @@ -32,26 +32,13 @@ #define PIXELSTORE_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; - -extern void GLAPIENTRY -_mesa_PixelStorei( GLenum pname, GLint param ); - - -extern void GLAPIENTRY -_mesa_PixelStoref( GLenum pname, GLfloat param ); - - -extern void GLAPIENTRY -_mesa_PixelStorei_no_error(GLenum pname, GLint param); - - -extern void GLAPIENTRY -_mesa_PixelStoref_no_error(GLenum pname, GLfloat param); - +extern void +_mesa_init_pixelstore_attrib(struct gl_context *ctx, + struct gl_pixelstore_attrib *pack); extern void _mesa_init_pixelstore( struct gl_context *ctx ); diff --git a/src/mesa/main/pixeltransfer.c b/src/mesa/main/pixeltransfer.c index b4dff56bdaa..9dbbb18ed3b 100644 --- a/src/mesa/main/pixeltransfer.c +++ b/src/mesa/main/pixeltransfer.c @@ -30,7 +30,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "macros.h" #include "pixeltransfer.h" @@ -221,29 +221,6 @@ _mesa_shift_and_offset_ci(const struct gl_context *ctx, /** - * Apply color index shift, offset and table lookup to an array - * of color indexes; - */ -void -_mesa_apply_ci_transfer_ops(const struct gl_context *ctx, - GLbitfield transferOps, - GLuint n, GLuint indexes[]) -{ - if (transferOps & IMAGE_SHIFT_OFFSET_BIT) { - _mesa_shift_and_offset_ci(ctx, n, indexes); - } - if (transferOps & IMAGE_MAP_COLOR_BIT) { - const GLuint mask = ctx->PixelMaps.ItoI.Size - 1; - GLuint i; - for (i = 0; i < n; i++) { - const GLuint j = indexes[i] & mask; - indexes[i] = _mesa_lroundevenf(ctx->PixelMaps.ItoI.Map[j]); - } - } -} - - -/** * Apply stencil index shift, offset and table lookup to an array * of stencil values. */ diff --git a/src/mesa/main/pixeltransfer.h b/src/mesa/main/pixeltransfer.h index caa2911fcf1..85197f9153a 100644 --- a/src/mesa/main/pixeltransfer.h +++ b/src/mesa/main/pixeltransfer.h @@ -28,7 +28,7 @@ #define PIXELTRANSFER_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; @@ -65,12 +65,6 @@ _mesa_shift_and_offset_ci(const struct gl_context *ctx, GLuint n, GLuint indexes[]); extern void -_mesa_apply_ci_transfer_ops(const struct gl_context *ctx, - GLbitfield transferOps, - GLuint n, GLuint indexes[]); - - -extern void _mesa_apply_stencil_transfer_ops(const struct gl_context *ctx, GLuint n, GLubyte stencil[]); diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index c336d887afb..29f2eb6f274 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -28,13 +28,21 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "macros.h" #include "points.h" #include "mtypes.h" +#include "api_exec_decl.h" +static void +update_point_size_set(struct gl_context *ctx) +{ + float size = CLAMP(ctx->Point.Size, ctx->Point.MinSize, ctx->Point.MaxSize); + ctx->PointSizeIsSet = (size == 1.0 && ctx->Point.Size == 1.0) || ctx->Point._Attenuated; +} + /** * Set current point size. * \param size point diameter in pixels @@ -53,9 +61,7 @@ point_size(struct gl_context *ctx, GLfloat size, bool no_error) FLUSH_VERTICES(ctx, _NEW_POINT, GL_POINT_BIT); ctx->Point.Size = size; - - if (ctx->Driver.PointSize) - ctx->Driver.PointSize(ctx, size); + update_point_size_set(ctx); } @@ -113,19 +119,6 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params) { GET_CURRENT_CONTEXT(ctx); - /* Drivers that support point sprites must also support point parameters. - * If point parameters aren't supported, then this function shouldn't even - * exist. - */ - assert(!ctx->Extensions.ARB_point_sprite || - ctx->Extensions.EXT_point_parameters); - - if (!ctx->Extensions.EXT_point_parameters) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "unsupported function called (unsupported extension)"); - return; - } - switch (pname) { case GL_DISTANCE_ATTENUATION_EXT: if (TEST_EQ_3V(ctx->Point.Params, params)) @@ -136,6 +129,7 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params) ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0F || ctx->Point.Params[1] != 0.0F || ctx->Point.Params[2] != 0.0F); + update_point_size_set(ctx); break; case GL_POINT_SIZE_MIN_EXT: if (params[0] < 0.0F) { @@ -174,8 +168,8 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params) /* GL_POINT_SPRITE_COORD_ORIGIN was added to point sprites when the * extension was merged into OpenGL 2.0. */ - if ((ctx->API == API_OPENGL_COMPAT && ctx->Version >= 20) - || ctx->API == API_OPENGL_CORE) { + if ((_mesa_is_desktop_gl_compat(ctx) && ctx->Version >= 20) + || _mesa_is_desktop_gl_core(ctx)) { GLenum value = (GLenum) params[0]; if (value != GL_LOWER_LEFT && value != GL_UPPER_LEFT) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -198,9 +192,6 @@ _mesa_PointParameterfv( GLenum pname, const GLfloat *params) "glPointParameterf[v]{EXT,ARB}(pname)" ); return; } - - if (ctx->Driver.PointParameterfv) - ctx->Driver.PointParameterfv(ctx, pname, params); } @@ -237,8 +228,8 @@ _mesa_init_point(struct gl_context *ctx) * In a core context, the state will default to true, and the setters and * getters are disabled. */ - ctx->Point.PointSprite = (ctx->API == API_OPENGL_CORE || - ctx->API == API_OPENGLES2); + ctx->Point.PointSprite = (_mesa_is_desktop_gl_core(ctx) || + _mesa_is_gles2(ctx)); ctx->Point.SpriteOrigin = GL_UPPER_LEFT; /* GL_ARB_point_sprite */ ctx->Point.CoordReplace = 0; /* GL_ARB_point_sprite */ diff --git a/src/mesa/main/points.h b/src/mesa/main/points.h index c2b67a371fd..b2b244efe07 100644 --- a/src/mesa/main/points.h +++ b/src/mesa/main/points.h @@ -32,29 +32,10 @@ #define POINTS_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; - -void GLAPIENTRY -_mesa_PointSize_no_error(GLfloat size); - -extern void GLAPIENTRY -_mesa_PointSize( GLfloat size ); - -extern void GLAPIENTRY -_mesa_PointParameteri( GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_PointParameteriv( GLenum pname, const GLint *params ); - -extern void GLAPIENTRY -_mesa_PointParameterf( GLenum pname, GLfloat param ); - -extern void GLAPIENTRY -_mesa_PointParameterfv( GLenum pname, const GLfloat *params ); - extern void _mesa_init_point( struct gl_context * ctx ); diff --git a/src/mesa/main/polygon.c b/src/mesa/main/polygon.c index bbba607ebe4..d5a6879c24c 100644 --- a/src/mesa/main/polygon.c +++ b/src/mesa/main/polygon.c @@ -28,7 +28,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "draw_validate.h" @@ -38,7 +38,10 @@ #include "pbo.h" #include "polygon.h" #include "mtypes.h" +#include "api_exec_decl.h" +#include "varray.h" +#include "state_tracker/st_context.h" /** * Specify whether to cull front- or back-facing facets. @@ -63,13 +66,10 @@ cull_face(struct gl_context *ctx, GLenum mode, bool no_error) return; } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.CullFaceMode = mode; - - if (ctx->Driver.CullFace) - ctx->Driver.CullFace(ctx, mode); } @@ -115,13 +115,10 @@ front_face(struct gl_context *ctx, GLenum mode, bool no_error) return; } - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.FrontFace = mode; - - if (ctx->Driver.FrontFace) - ctx->Driver.FrontFace(ctx, mode); } @@ -187,37 +184,40 @@ polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode, bool no_error) switch (face) { case GL_FRONT: - if (!no_error && ctx->API == API_OPENGL_CORE) { + if (!no_error && _mesa_is_desktop_gl_core(ctx)) { _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); return; } if (ctx->Polygon.FrontMode == mode) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.FrontMode = mode; + _mesa_update_edgeflag_state_vao(ctx); break; case GL_FRONT_AND_BACK: if (ctx->Polygon.FrontMode == mode && ctx->Polygon.BackMode == mode) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.FrontMode = mode; ctx->Polygon.BackMode = mode; + _mesa_update_edgeflag_state_vao(ctx); break; case GL_BACK: - if (!no_error && ctx->API == API_OPENGL_CORE) { + if (!no_error && _mesa_is_desktop_gl_core(ctx)) { _mesa_error( ctx, GL_INVALID_ENUM, "glPolygonMode(face)" ); return; } if (ctx->Polygon.BackMode == mode) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.BackMode = mode; + _mesa_update_edgeflag_state_vao(ctx); break; default: if (!no_error) @@ -225,9 +225,6 @@ polygon_mode(struct gl_context *ctx, GLenum face, GLenum mode, bool no_error) return; } - if (ctx->Driver.PolygonMode) - ctx->Driver.PolygonMode(ctx, face, mode); - if (ctx->Extensions.INTEL_conservative_rasterization || (mode == GL_FILL_RECTANGLE_NV || old_mode_has_fill_rectangle)) _mesa_update_valid_to_render_state(ctx); @@ -261,10 +258,8 @@ _mesa_PolygonStipple(const GLubyte *pattern) if (MESA_VERBOSE & VERBOSE_API) _mesa_debug(ctx, "glPolygonStipple\n"); - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonStipple ? 0 : - _NEW_POLYGONSTIPPLE, - GL_POLYGON_STIPPLE_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonStipple; + FLUSH_VERTICES(ctx, 0, GL_POLYGON_STIPPLE_BIT); + ctx->NewDriverState |= ST_NEW_POLY_STIPPLE; pattern = _mesa_map_validate_pbo_source(ctx, 2, &ctx->Unpack, 32, 32, 1, @@ -277,9 +272,6 @@ _mesa_PolygonStipple(const GLubyte *pattern) _mesa_unpack_polygon_stipple(pattern, ctx->PolygonStipple, &ctx->Unpack); _mesa_unmap_pbo_source(ctx, &ctx->Unpack); - - if (ctx->Driver.PolygonStipple) - ctx->Driver.PolygonStipple(ctx, pattern); } @@ -294,6 +286,9 @@ _mesa_GetnPolygonStippleARB( GLsizei bufSize, GLubyte *dest ) if (MESA_VERBOSE&VERBOSE_API) _mesa_debug(ctx, "glGetPolygonStipple\n"); + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + dest = _mesa_map_validate_pbo_dest(ctx, 2, &ctx->Pack, 32, 32, 1, GL_COLOR_INDEX, GL_BITMAP, @@ -322,15 +317,12 @@ _mesa_polygon_offset_clamp(struct gl_context *ctx, ctx->Polygon.OffsetClamp == clamp) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewPolygonState ? 0 : _NEW_POLYGON, + FLUSH_VERTICES(ctx, 0, GL_POLYGON_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; + ctx->NewDriverState |= ST_NEW_RASTERIZER; ctx->Polygon.OffsetFactor = factor; ctx->Polygon.OffsetUnits = units; ctx->Polygon.OffsetClamp = clamp; - - if (ctx->Driver.PolygonOffset) - ctx->Driver.PolygonOffset( ctx, factor, units, clamp ); } void GLAPIENTRY diff --git a/src/mesa/main/polygon.h b/src/mesa/main/polygon.h index a7e383da034..2d62fed7648 100644 --- a/src/mesa/main/polygon.h +++ b/src/mesa/main/polygon.h @@ -32,43 +32,10 @@ #define POLYGON_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -extern void GLAPIENTRY -_mesa_GetnPolygonStippleARB( GLsizei bufSize, GLubyte *dest ); - -void GLAPIENTRY -_mesa_CullFace_no_error(GLenum mode); - -extern void GLAPIENTRY -_mesa_CullFace(GLenum mode); - -void GLAPIENTRY -_mesa_FrontFace_no_error(GLenum mode); - -extern void GLAPIENTRY -_mesa_FrontFace(GLenum mode); - -void GLAPIENTRY -_mesa_PolygonMode_no_error(GLenum face, GLenum mode); - -extern void GLAPIENTRY -_mesa_PolygonMode( GLenum face, GLenum mode ); - -extern void GLAPIENTRY -_mesa_PolygonOffset( GLfloat factor, GLfloat units ); - -extern void GLAPIENTRY -_mesa_PolygonOffsetClampEXT( GLfloat factor, GLfloat units, GLfloat clamp ); - -extern void GLAPIENTRY -_mesa_PolygonStipple( const GLubyte *mask ); - -extern void GLAPIENTRY -_mesa_GetPolygonStipple( GLubyte *mask ); - extern void _mesa_polygon_offset_clamp(struct gl_context *ctx, GLfloat factor, GLfloat units, GLfloat clamp); diff --git a/src/mesa/main/program_binary.c b/src/mesa/main/program_binary.c index 536201694c3..6aaa2c5a80e 100644 --- a/src/mesa/main/program_binary.c +++ b/src/mesa/main/program_binary.c @@ -39,6 +39,8 @@ #include "program_binary.h" #include "program/prog_parameter.h" +#include "state_tracker/st_shader_cache.h" + /** * Mesa supports one binary format, but it must differentiate between formats * produced by different drivers and different Mesa versions. @@ -237,7 +239,7 @@ _mesa_get_program_binary(struct gl_context *ctx, uint8_t driver_sha1[20]; unsigned header_size = get_program_binary_header_size(); - ctx->Driver.GetProgramBinaryDriverSHA1(ctx, driver_sha1); + st_get_program_binary_driver_sha1(ctx, driver_sha1); blob_init(&blob); @@ -274,7 +276,7 @@ _mesa_program_binary(struct gl_context *ctx, struct gl_shader_program *sh_prog, uint8_t driver_sha1[20]; unsigned header_size = get_program_binary_header_size(); - ctx->Driver.GetProgramBinaryDriverSHA1(ctx, driver_sha1); + st_get_program_binary_driver_sha1(ctx, driver_sha1); const void *payload = get_program_binary_payload(binary_format, driver_sha1, binary, length); diff --git a/src/mesa/main/program_resource.c b/src/mesa/main/program_resource.c index fda59c561b3..16be056304a 100644 --- a/src/mesa/main/program_resource.c +++ b/src/mesa/main/program_resource.c @@ -29,8 +29,8 @@ #include "main/shaderapi.h" #include "main/shaderobj.h" #include "main/context.h" -#include "program_resource.h" #include "compiler/glsl/ir_uniform.h" +#include "api_exec_decl.h" static bool supported_interface_enum(struct gl_context *ctx, GLenum iface) @@ -97,7 +97,6 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, _mesa_enum_to_string(pname), params); } - unsigned i; struct gl_shader_program *shProg = _mesa_lookup_shader_program_err(ctx, program, "glGetProgramInterfaceiv"); @@ -117,125 +116,7 @@ _mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, return; } - /* Validate pname against interface. */ - switch(pname) { - case GL_ACTIVE_RESOURCES: - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) - if (shProg->data->ProgramResourceList[i].Type == programInterface) - (*params)++; - break; - case GL_MAX_NAME_LENGTH: - if (programInterface == GL_ATOMIC_COUNTER_BUFFER || - programInterface == GL_TRANSFORM_FEEDBACK_BUFFER) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramInterfaceiv(%s pname %s)", - _mesa_enum_to_string(programInterface), - _mesa_enum_to_string(pname)); - return; - } - /* Name length consists of base name, 3 additional chars '[0]' if - * resource is an array and finally 1 char for string terminator. - */ - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { - if (shProg->data->ProgramResourceList[i].Type != programInterface) - continue; - unsigned len = - _mesa_program_resource_name_len(&shProg->data->ProgramResourceList[i]); - *params = MAX2(*params, len + 1); - } - break; - case GL_MAX_NUM_ACTIVE_VARIABLES: - switch (programInterface) { - case GL_UNIFORM_BLOCK: - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { - if (shProg->data->ProgramResourceList[i].Type == programInterface) { - struct gl_uniform_block *block = - (struct gl_uniform_block *) - shProg->data->ProgramResourceList[i].Data; - *params = MAX2(*params, block->NumUniforms); - } - } - break; - case GL_SHADER_STORAGE_BLOCK: - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { - if (shProg->data->ProgramResourceList[i].Type == programInterface) { - struct gl_uniform_block *block = - (struct gl_uniform_block *) - shProg->data->ProgramResourceList[i].Data; - GLint block_params = 0; - for (unsigned j = 0; j < block->NumUniforms; j++) { - struct gl_program_resource *uni = - _mesa_program_resource_find_active_variable( - shProg, - GL_BUFFER_VARIABLE, - block, - j); - if (!uni) - continue; - block_params++; - } - *params = MAX2(*params, block_params); - } - } - break; - case GL_ATOMIC_COUNTER_BUFFER: - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { - if (shProg->data->ProgramResourceList[i].Type == programInterface) { - struct gl_active_atomic_buffer *buffer = - (struct gl_active_atomic_buffer *) - shProg->data->ProgramResourceList[i].Data; - *params = MAX2(*params, buffer->NumUniforms); - } - } - break; - case GL_TRANSFORM_FEEDBACK_BUFFER: - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { - if (shProg->data->ProgramResourceList[i].Type == programInterface) { - struct gl_transform_feedback_buffer *buffer = - (struct gl_transform_feedback_buffer *) - shProg->data->ProgramResourceList[i].Data; - *params = MAX2(*params, buffer->NumVaryings); - } - } - break; - default: - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramInterfaceiv(%s pname %s)", - _mesa_enum_to_string(programInterface), - _mesa_enum_to_string(pname)); - } - break; - case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: - switch (programInterface) { - case GL_VERTEX_SUBROUTINE_UNIFORM: - case GL_FRAGMENT_SUBROUTINE_UNIFORM: - case GL_GEOMETRY_SUBROUTINE_UNIFORM: - case GL_COMPUTE_SUBROUTINE_UNIFORM: - case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: - case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: { - for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { - if (shProg->data->ProgramResourceList[i].Type == programInterface) { - struct gl_uniform_storage *uni = - (struct gl_uniform_storage *) - shProg->data->ProgramResourceList[i].Data; - *params = MAX2(*params, uni->num_compatible_subroutines); - } - } - break; - } - - default: - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramInterfaceiv(%s pname %s)", - _mesa_enum_to_string(programInterface), - _mesa_enum_to_string(pname)); - } - break; - default: - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetProgramInterfaceiv(pname %s)", - _mesa_enum_to_string(pname)); - } + _mesa_get_program_interfaceiv(shProg, programInterface, pname, params); } static bool diff --git a/src/mesa/main/program_resource.h b/src/mesa/main/program_resource.h deleted file mode 100644 index 326ae1f936c..00000000000 --- a/src/mesa/main/program_resource.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 2015 Intel Corporation. All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - */ - -#ifndef PROGRAM_RESOURCE_H -#define PROGRAM_RESOURCE_H - -#include "glheader.h" - -extern void GLAPIENTRY -_mesa_GetProgramInterfaceiv(GLuint program, GLenum programInterface, - GLenum pname, GLint *params); - -extern GLuint GLAPIENTRY -_mesa_GetProgramResourceIndex(GLuint program, GLenum programInterface, - const GLchar *name); - -extern void GLAPIENTRY -_mesa_GetProgramResourceName(GLuint program, GLenum programInterface, - GLuint index, GLsizei bufSize, GLsizei *length, - GLchar *name); - -extern void GLAPIENTRY -_mesa_GetProgramResourceiv(GLuint program, GLenum programInterface, - GLuint index, GLsizei propCount, - const GLenum *props, GLsizei bufSize, - GLsizei *length, GLint *params); - -extern GLint GLAPIENTRY -_mesa_GetProgramResourceLocation(GLuint program, GLenum programInterface, - const GLchar *name); - -extern GLint GLAPIENTRY -_mesa_GetProgramResourceLocationIndex(GLuint program, GLenum programInterface, - const GLchar *name); - -#endif diff --git a/src/mesa/main/querymatrix.c b/src/mesa/main/querymatrix.c index b80bae6a6d2..8f2e78d5616 100644 --- a/src/mesa/main/querymatrix.c +++ b/src/mesa/main/querymatrix.c @@ -13,11 +13,12 @@ #include <stdlib.h> -#include "c99_math.h" -#include "glheader.h" -#include "querymatrix.h" +#include <math.h> + +#include "util/glheader.h" #include "main/get.h" #include "util/macros.h" +#include "api_exec_decl.h" /** @@ -40,7 +41,7 @@ GLbitfield GLAPIENTRY -_mesa_QueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]) +_mesa_QueryMatrixxOES(GLfixed *mantissa, GLint *exponent) { GLfloat matrix[16]; GLint tmp; diff --git a/src/mesa/main/querymatrix.h b/src/mesa/main/querymatrix.h deleted file mode 100644 index 64921891000..00000000000 --- a/src/mesa/main/querymatrix.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - */ - -#ifndef QUERYMATRIX_H -#define QUERYMATRIX_H - - -#include "glheader.h" - - -/* - * API functions - */ - -extern GLbitfield GLAPIENTRY -_mesa_QueryMatrixxOES(GLfixed mantissa[16], GLint exponent[16]); - -#endif diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c index d391bf0d3cb..31830cf5a70 100644 --- a/src/mesa/main/queryobj.c +++ b/src/mesa/main/queryobj.c @@ -24,128 +24,444 @@ #include "bufferobj.h" -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" #include "hash.h" #include "queryobj.h" #include "mtypes.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" #include "util/u_memory.h" +#include "api_exec_decl.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_bitmap.h" + -/** - * Allocate a new query object. This is a fallback routine called via - * ctx->Driver.NewQueryObject(). - * \param ctx - rendering context - * \param id - the new object's ID - * \return pointer to new query_object object or NULL if out of memory. - */ static struct gl_query_object * -_mesa_new_query_object(struct gl_context *ctx, GLuint id) +new_query_object(struct gl_context *ctx, GLuint id) { struct gl_query_object *q = CALLOC_STRUCT(gl_query_object); - (void) ctx; if (q) { q->Id = id; - q->Result = 0; - q->Active = GL_FALSE; - - /* This is to satisfy the language of the specification: "In the initial - * state of a query object, the result is available" (OpenGL 3.1 § - * 2.13). - */ q->Ready = GL_TRUE; - - /* OpenGL 3.1 § 2.13 says about GenQueries, "These names are marked as - * used, but no object is associated with them until the first time they - * are used by BeginQuery." Since our implementation actually does - * allocate an object at this point, use a flag to indicate that this - * object has not yet been bound so should not be considered a query. - */ - q->EverBound = GL_FALSE; + q->pq = NULL; + q->type = PIPE_QUERY_TYPES; /* an invalid value */ + return q; } - return q; + return NULL; } -/** - * Begin a query. Software driver fallback. - * Called via ctx->Driver.BeginQuery(). - */ static void -_mesa_begin_query(struct gl_context *ctx, struct gl_query_object *q) +free_queries(struct pipe_context *pipe, struct gl_query_object *q) { - ctx->NewState |= _NEW_DEPTH; /* for swrast */ + if (q->pq) { + pipe->destroy_query(pipe, q->pq); + q->pq = NULL; + } + + if (q->pq_begin) { + pipe->destroy_query(pipe, q->pq_begin); + q->pq_begin = NULL; + } } -/** - * End a query. Software driver fallback. - * Called via ctx->Driver.EndQuery(). - */ static void -_mesa_end_query(struct gl_context *ctx, struct gl_query_object *q) +delete_query(struct gl_context *ctx, struct gl_query_object *q) { - ctx->NewState |= _NEW_DEPTH; /* for swrast */ - q->Ready = GL_TRUE; + struct pipe_context *pipe = ctx->pipe; + + free_queries(pipe, q); + free(q->Label); + FREE(q); +} + +static int +target_to_index(const struct gl_query_object *q) +{ + if (q->Target == GL_PRIMITIVES_GENERATED || + q->Target == GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN || + q->Target == GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB) + return q->Stream; + + /* Drivers with PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE = 0 ignore the + * index param so it should be useless; but radeonsi needs it in some cases, + * so pass the correct value. + */ + switch (q->Target) { + case GL_VERTICES_SUBMITTED_ARB: + return PIPE_STAT_QUERY_IA_VERTICES; + case GL_PRIMITIVES_SUBMITTED_ARB: + return PIPE_STAT_QUERY_IA_PRIMITIVES; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_VS_INVOCATIONS; + case GL_GEOMETRY_SHADER_INVOCATIONS: + return PIPE_STAT_QUERY_GS_INVOCATIONS; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + return PIPE_STAT_QUERY_GS_PRIMITIVES; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + return PIPE_STAT_QUERY_C_INVOCATIONS; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + return PIPE_STAT_QUERY_C_PRIMITIVES; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_PS_INVOCATIONS; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + return PIPE_STAT_QUERY_HS_INVOCATIONS; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_DS_INVOCATIONS; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + return PIPE_STAT_QUERY_CS_INVOCATIONS; + default: + break; + } + + return 0; } +static bool +query_type_is_dummy(struct gl_context *ctx, unsigned type) +{ + struct st_context *st = st_context(ctx); + switch (type) { + case PIPE_QUERY_OCCLUSION_COUNTER: + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + return !st->has_occlusion_query; + case PIPE_QUERY_PIPELINE_STATISTICS: + return !st->has_pipeline_stat; + case PIPE_QUERY_PIPELINE_STATISTICS_SINGLE: + return !st->has_single_pipe_stat; + default: + break; + } + return false; +} -/** - * Wait for query to complete. Software driver fallback. - * Called via ctx->Driver.WaitQuery(). - */ static void -_mesa_wait_query(struct gl_context *ctx, struct gl_query_object *q) +begin_query(struct gl_context *ctx, struct gl_query_object *q) { - /* For software drivers, _mesa_end_query() should have completed the query. - * For real hardware, implement a proper WaitQuery() driver function, - * which may require issuing a flush. - */ - assert(q->Ready); + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = ctx->pipe; + unsigned type; + bool ret = false; + + st_flush_bitmap_cache(st_context(ctx)); + + /* convert GL query type to Gallium query type */ + switch (q->Target) { + case GL_ANY_SAMPLES_PASSED: + type = PIPE_QUERY_OCCLUSION_PREDICATE; + break; + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE: + type = PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE; + break; + case GL_SAMPLES_PASSED_ARB: + type = PIPE_QUERY_OCCLUSION_COUNTER; + break; + case GL_PRIMITIVES_GENERATED: + type = PIPE_QUERY_PRIMITIVES_GENERATED; + break; + case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN: + type = PIPE_QUERY_PRIMITIVES_EMITTED; + break; + case GL_TRANSFORM_FEEDBACK_STREAM_OVERFLOW_ARB: + type = PIPE_QUERY_SO_OVERFLOW_PREDICATE; + break; + case GL_TRANSFORM_FEEDBACK_OVERFLOW_ARB: + type = PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE; + break; + case GL_TIME_ELAPSED: + if (st->has_time_elapsed) + type = PIPE_QUERY_TIME_ELAPSED; + else + type = PIPE_QUERY_TIMESTAMP; + break; + case GL_VERTICES_SUBMITTED_ARB: + case GL_PRIMITIVES_SUBMITTED_ARB: + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + case GL_GEOMETRY_SHADER_INVOCATIONS: + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + type = st->has_single_pipe_stat ? PIPE_QUERY_PIPELINE_STATISTICS_SINGLE + : PIPE_QUERY_PIPELINE_STATISTICS; + break; + default: + assert(0 && "unexpected query target in st_BeginQuery()"); + return; + } + + if (q->type != type) { + /* free old query of different type */ + free_queries(pipe, q); + q->type = PIPE_QUERY_TYPES; /* an invalid value */ + } + + if (q->Target == GL_TIME_ELAPSED && + type == PIPE_QUERY_TIMESTAMP) { + /* Determine time elapsed by emitting two timestamp queries. */ + if (!q->pq_begin) { + q->pq_begin = pipe->create_query(pipe, type, 0); + q->type = type; + } + if (q->pq_begin) + ret = pipe->end_query(pipe, q->pq_begin); + } else { + if (query_type_is_dummy(ctx, type)) { + /* starting a dummy-query; ignore */ + assert(!q->pq); + q->type = type; + ret = true; + } else if (!q->pq) { + q->pq = pipe->create_query(pipe, type, target_to_index(q)); + q->type = type; + } + if (q->pq) + ret = pipe->begin_query(pipe, q->pq); + } + + if (!ret) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery"); + + free_queries(pipe, q); + q->Active = GL_FALSE; + return; + } + + if (q->type != PIPE_QUERY_TIMESTAMP) + st->active_queries++; + + assert(q->type == type); } -/** - * Check if a query results are ready. Software driver fallback. - * Called via ctx->Driver.CheckQuery(). - */ static void -_mesa_check_query(struct gl_context *ctx, struct gl_query_object *q) +end_query(struct gl_context *ctx, struct gl_query_object *q) { - /* No-op for sw rendering. - * HW drivers may need to flush at this time. - */ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = ctx->pipe; + bool ret = false; + + st_flush_bitmap_cache(st_context(ctx)); + + if ((q->Target == GL_TIMESTAMP || + q->Target == GL_TIME_ELAPSED) && + !q->pq) { + q->pq = pipe->create_query(pipe, PIPE_QUERY_TIMESTAMP, 0); + q->type = PIPE_QUERY_TIMESTAMP; + } + + if (query_type_is_dummy(ctx, q->type)) { + /* ending a dummy-query; ignore */ + ret = true; + } else if (q->pq) + ret = pipe->end_query(pipe, q->pq); + + if (!ret) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glEndQuery"); + return; + } + + if (q->type != PIPE_QUERY_TIMESTAMP) + st->active_queries--; +} + + +static bool +get_query_result(struct pipe_context *pipe, + struct gl_query_object *q, + bool wait) +{ + union pipe_query_result data; + + if (!q->pq) { + /* Needed in case we failed to allocate the gallium query earlier, or + * in the case of a dummy query. + * + * Return TRUE in either case so we don't spin on this forever. + */ + return true; + } + + if (!pipe->get_query_result(pipe, q->pq, wait, &data)) + return false; + + switch (q->type) { + case PIPE_QUERY_PIPELINE_STATISTICS: + switch (q->Target) { + case GL_VERTICES_SUBMITTED_ARB: + q->Result = data.pipeline_statistics.ia_vertices; + break; + case GL_PRIMITIVES_SUBMITTED_ARB: + q->Result = data.pipeline_statistics.ia_primitives; + break; + case GL_VERTEX_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.vs_invocations; + break; + case GL_TESS_CONTROL_SHADER_PATCHES_ARB: + q->Result = data.pipeline_statistics.hs_invocations; + break; + case GL_TESS_EVALUATION_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.ds_invocations; + break; + case GL_GEOMETRY_SHADER_INVOCATIONS: + q->Result = data.pipeline_statistics.gs_invocations; + break; + case GL_GEOMETRY_SHADER_PRIMITIVES_EMITTED_ARB: + q->Result = data.pipeline_statistics.gs_primitives; + break; + case GL_FRAGMENT_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.ps_invocations; + break; + case GL_COMPUTE_SHADER_INVOCATIONS_ARB: + q->Result = data.pipeline_statistics.cs_invocations; + break; + case GL_CLIPPING_INPUT_PRIMITIVES_ARB: + q->Result = data.pipeline_statistics.c_invocations; + break; + case GL_CLIPPING_OUTPUT_PRIMITIVES_ARB: + q->Result = data.pipeline_statistics.c_primitives; + break; + default: + unreachable("invalid pipeline statistics counter"); + } + break; + case PIPE_QUERY_OCCLUSION_PREDICATE: + case PIPE_QUERY_OCCLUSION_PREDICATE_CONSERVATIVE: + case PIPE_QUERY_SO_OVERFLOW_PREDICATE: + case PIPE_QUERY_SO_OVERFLOW_ANY_PREDICATE: + q->Result = !!data.b; + break; + default: + q->Result = data.u64; + break; + } + + if (q->Target == GL_TIME_ELAPSED && + q->type == PIPE_QUERY_TIMESTAMP) { + /* Calculate the elapsed time from the two timestamp queries */ + assert(q->pq_begin); + pipe->get_query_result(pipe, q->pq_begin, true, &data); + q->Result -= data.u64; + } else { + assert(!q->pq_begin); + } + + return true; } -/** - * Delete a query object. Called via ctx->Driver.DeleteQuery(), if not - * overwritten by driver. In the latter case, called from the driver - * after all driver-specific clean-up has been done. - * Not removed from hash table here. - * - * \param ctx GL context to wich query object belongs. - * \param q query object due to be deleted. - */ void -_mesa_delete_query(struct gl_context *ctx, struct gl_query_object *q) +_mesa_wait_query(struct gl_context *ctx, struct gl_query_object *q) { - free(q->Label); - free(q); + struct pipe_context *pipe = ctx->pipe; + + /* this function should only be called if we don't have a ready result */ + assert(!q->Ready); + + while (!q->Ready && + !get_query_result(pipe, q, true)) + { + /* nothing */ + } + + q->Ready = GL_TRUE; } void -_mesa_init_query_object_functions(struct dd_function_table *driver) +_mesa_check_query(struct gl_context *ctx, struct gl_query_object *q) { - driver->NewQueryObject = _mesa_new_query_object; - driver->DeleteQuery = _mesa_delete_query; - driver->BeginQuery = _mesa_begin_query; - driver->EndQuery = _mesa_end_query; - driver->WaitQuery = _mesa_wait_query; - driver->CheckQuery = _mesa_check_query; + struct pipe_context *pipe = ctx->pipe; + assert(!q->Ready); /* we should not get called if Ready is TRUE */ + q->Ready = get_query_result(pipe, q, false); +} + + +uint64_t +_mesa_get_timestamp(struct gl_context *ctx) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + + /* Prefer the per-screen function */ + if (screen->get_timestamp) { + return screen->get_timestamp(screen); + } + else { + /* Fall back to the per-context function */ + assert(pipe->get_timestamp); + return pipe->get_timestamp(pipe); + } +} + +static void +store_query_result(struct gl_context *ctx, struct gl_query_object *q, + struct gl_buffer_object *buf, intptr_t offset, + GLenum pname, GLenum ptype) +{ + struct pipe_context *pipe = ctx->pipe; + enum pipe_query_flags flags = 0; + enum pipe_query_value_type result_type; + int index; + + if (pname == GL_QUERY_RESULT) + flags |= PIPE_QUERY_WAIT; + + /* GL_QUERY_TARGET is a bit of an extension since it has nothing to + * do with the GPU end of the query. Write it in "by hand". + */ + if (pname == GL_QUERY_TARGET) { + /* Assume that the data must be LE. The endianness situation wrt CPU and + * GPU is incredibly confusing, but the vast majority of GPUs are + * LE. When a BE one comes along, this needs some form of resolution. + */ + unsigned data[2] = { CPU_TO_LE32(q->Target), 0 }; + pipe_buffer_write(pipe, buf->buffer, offset, + (ptype == GL_INT64_ARB || + ptype == GL_UNSIGNED_INT64_ARB) ? 8 : 4, + data); + return; + } + + switch (ptype) { + case GL_INT: + result_type = PIPE_QUERY_TYPE_I32; + break; + case GL_UNSIGNED_INT: + result_type = PIPE_QUERY_TYPE_U32; + break; + case GL_INT64_ARB: + result_type = PIPE_QUERY_TYPE_I64; + break; + case GL_UNSIGNED_INT64_ARB: + result_type = PIPE_QUERY_TYPE_U64; + break; + default: + unreachable("Unexpected result type"); + } + + if (pname == GL_QUERY_RESULT_AVAILABLE) { + index = -1; + } else if (q->type == PIPE_QUERY_PIPELINE_STATISTICS) { + index = target_to_index(q); + } else { + index = 0; + } + + if (q->pq) + pipe->get_query_result_resource(pipe, q->pq, flags, result_type, index, + buf->buffer, offset); } static struct gl_query_object ** @@ -155,7 +471,7 @@ get_pipe_stats_binding_point(struct gl_context *ctx, const int which = target - GL_VERTICES_SUBMITTED; assert(which < MAX_PIPELINE_STATISTICS); - if (!_mesa_has_ARB_pipeline_statistics_query(ctx)) + if (!_mesa_has_pipeline_statistics(ctx)) return NULL; return &ctx->Query.pipeline_stats[which]; @@ -171,14 +487,12 @@ get_query_binding_point(struct gl_context *ctx, GLenum target, GLuint index) { switch (target) { case GL_SAMPLES_PASSED: - if (_mesa_has_ARB_occlusion_query(ctx) || - _mesa_has_ARB_occlusion_query2(ctx)) + if (_mesa_has_occlusion_query(ctx)) return &ctx->Query.CurrentOcclusionObject; else return NULL; case GL_ANY_SAMPLES_PASSED: - if (_mesa_has_ARB_occlusion_query2(ctx) || - _mesa_has_EXT_occlusion_query_boolean(ctx)) + if (_mesa_has_occlusion_query_boolean(ctx)) return &ctx->Query.CurrentOcclusionObject; else return NULL; @@ -271,11 +585,11 @@ create_queries(struct gl_context *ctx, GLenum target, GLsizei n, GLuint *ids, return; } - if (_mesa_HashFindFreeKeys(ctx->Query.QueryObjects, ids, n)) { + if (_mesa_HashFindFreeKeys(&ctx->Query.QueryObjects, ids, n)) { GLsizei i; for (i = 0; i < n; i++) { struct gl_query_object *q - = ctx->Driver.NewQueryObject(ctx, ids[i]); + = new_query_object(ctx, ids[i]); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; @@ -284,7 +598,7 @@ create_queries(struct gl_context *ctx, GLenum target, GLsizei n, GLuint *ids, q->Target = target; q->EverBound = GL_TRUE; } - _mesa_HashInsertLocked(ctx->Query.QueryObjects, ids[i], q, true); + _mesa_HashInsertLocked(&ctx->Query.QueryObjects, ids[i], q); } } } @@ -349,10 +663,10 @@ _mesa_DeleteQueries(GLsizei n, const GLuint *ids) *bindpt = NULL; } q->Active = GL_FALSE; - ctx->Driver.EndQuery(ctx, q); + end_query(ctx, q); } - _mesa_HashRemoveLocked(ctx->Query.QueryObjects, ids[i]); - ctx->Driver.DeleteQuery(ctx, q); + _mesa_HashRemoveLocked(&ctx->Query.QueryObjects, ids[i]); + delete_query(ctx, q); } } } @@ -449,12 +763,12 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) return; } else { /* create new object */ - q = ctx->Driver.NewQueryObject(ctx, id); + q = new_query_object(ctx, id); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery{Indexed}"); return; } - _mesa_HashInsertLocked(ctx->Query.QueryObjects, id, q, false); + _mesa_HashInsertLocked(&ctx->Query.QueryObjects, id, q); } } else { @@ -504,7 +818,7 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id) /* XXX should probably refcount query objects */ *bindpt = q; - ctx->Driver.BeginQuery(ctx, q); + begin_query(ctx, q); } @@ -550,7 +864,7 @@ _mesa_EndQueryIndexed(GLenum target, GLuint index) } q->Active = GL_FALSE; - ctx->Driver.EndQuery(ctx, q); + end_query(ctx, q); } void GLAPIENTRY @@ -591,12 +905,12 @@ _mesa_QueryCounter(GLuint id, GLenum target) /* XXX the Core profile should throw INVALID_OPERATION here */ /* create new object */ - q = ctx->Driver.NewQueryObject(ctx, id); + q = new_query_object(ctx, id); if (!q) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glQueryCounter"); return; } - _mesa_HashInsertLocked(ctx->Query.QueryObjects, id, q, false); + _mesa_HashInsertLocked(&ctx->Query.QueryObjects, id, q); } else { if (q->Target && q->Target != GL_TIMESTAMP) { @@ -628,14 +942,10 @@ _mesa_QueryCounter(GLuint id, GLenum target) q->Ready = GL_FALSE; q->EverBound = GL_TRUE; - if (ctx->Driver.QueryCounter) { - ctx->Driver.QueryCounter(ctx, q); - } else { - /* QueryCounter is implemented using EndQuery without BeginQuery - * in drivers. This is actually Direct3D and Gallium convention. - */ - ctx->Driver.EndQuery(ctx, q); - } + /* QueryCounter is implemented using EndQuery without BeginQuery + * in drivers. This is actually Direct3D and Gallium convention. + */ + end_query(ctx, q); } @@ -845,7 +1155,7 @@ get_query_object(struct gl_context *ctx, const char *func, case GL_QUERY_RESULT_NO_WAIT: case GL_QUERY_RESULT_AVAILABLE: case GL_QUERY_TARGET: - ctx->Driver.StoreQueryResult(ctx, q, buf, offset, pname, ptype); + store_query_result(ctx, q, buf, offset, pname, ptype); return; } @@ -855,20 +1165,20 @@ get_query_object(struct gl_context *ctx, const char *func, switch (pname) { case GL_QUERY_RESULT: if (!q->Ready) - ctx->Driver.WaitQuery(ctx, q); + _mesa_wait_query(ctx, q); value = q->Result; break; case GL_QUERY_RESULT_NO_WAIT: if (!_mesa_has_ARB_query_buffer_object(ctx)) goto invalid_enum; - ctx->Driver.CheckQuery(ctx, q); + _mesa_check_query(ctx, q); if (!q->Ready) return; value = q->Result; break; case GL_QUERY_RESULT_AVAILABLE: if (!q->Ready) - ctx->Driver.CheckQuery(ctx, q); + _mesa_check_query(ctx, q); value = q->Ready; break; case GL_QUERY_TARGET: @@ -1030,38 +1340,59 @@ _mesa_GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, void _mesa_init_queryobj(struct gl_context *ctx) { - ctx->Query.QueryObjects = _mesa_NewHashTable(); + struct pipe_screen *screen = ctx->pipe->screen; + + _mesa_InitHashTable(&ctx->Query.QueryObjects); ctx->Query.CurrentOcclusionObject = NULL; - ctx->Const.QueryCounterBits.SamplesPassed = 64; + if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) + ctx->Const.QueryCounterBits.SamplesPassed = 64; + else + ctx->Const.QueryCounterBits.SamplesPassed = 0; + ctx->Const.QueryCounterBits.TimeElapsed = 64; ctx->Const.QueryCounterBits.Timestamp = 64; ctx->Const.QueryCounterBits.PrimitivesGenerated = 64; ctx->Const.QueryCounterBits.PrimitivesWritten = 64; - ctx->Const.QueryCounterBits.VerticesSubmitted = 64; - ctx->Const.QueryCounterBits.PrimitivesSubmitted = 64; - ctx->Const.QueryCounterBits.VsInvocations = 64; - ctx->Const.QueryCounterBits.TessPatches = 64; - ctx->Const.QueryCounterBits.TessInvocations = 64; - ctx->Const.QueryCounterBits.GsInvocations = 64; - ctx->Const.QueryCounterBits.GsPrimitives = 64; - ctx->Const.QueryCounterBits.FsInvocations = 64; - ctx->Const.QueryCounterBits.ComputeInvocations = 64; - ctx->Const.QueryCounterBits.ClInPrimitives = 64; - ctx->Const.QueryCounterBits.ClOutPrimitives = 64; + if (screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS) || + screen->get_param(screen, PIPE_CAP_QUERY_PIPELINE_STATISTICS_SINGLE)) { + ctx->Const.QueryCounterBits.VerticesSubmitted = 64; + ctx->Const.QueryCounterBits.PrimitivesSubmitted = 64; + ctx->Const.QueryCounterBits.VsInvocations = 64; + ctx->Const.QueryCounterBits.TessPatches = 64; + ctx->Const.QueryCounterBits.TessInvocations = 64; + ctx->Const.QueryCounterBits.GsInvocations = 64; + ctx->Const.QueryCounterBits.GsPrimitives = 64; + ctx->Const.QueryCounterBits.FsInvocations = 64; + ctx->Const.QueryCounterBits.ComputeInvocations = 64; + ctx->Const.QueryCounterBits.ClInPrimitives = 64; + ctx->Const.QueryCounterBits.ClOutPrimitives = 64; + } else { + ctx->Const.QueryCounterBits.VerticesSubmitted = 0; + ctx->Const.QueryCounterBits.PrimitivesSubmitted = 0; + ctx->Const.QueryCounterBits.VsInvocations = 0; + ctx->Const.QueryCounterBits.TessPatches = 0; + ctx->Const.QueryCounterBits.TessInvocations = 0; + ctx->Const.QueryCounterBits.GsInvocations = 0; + ctx->Const.QueryCounterBits.GsPrimitives = 0; + ctx->Const.QueryCounterBits.FsInvocations = 0; + ctx->Const.QueryCounterBits.ComputeInvocations = 0; + ctx->Const.QueryCounterBits.ClInPrimitives = 0; + ctx->Const.QueryCounterBits.ClOutPrimitives = 0; + } } /** - * Callback for deleting a query object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a query object. Called by _mesa_DeleteHashTable(). */ static void delete_queryobj_cb(void *data, void *userData) { struct gl_query_object *q= (struct gl_query_object *) data; struct gl_context *ctx = (struct gl_context *)userData; - ctx->Driver.DeleteQuery(ctx, q); + delete_query(ctx, q); } @@ -1071,6 +1402,5 @@ delete_queryobj_cb(void *data, void *userData) void _mesa_free_queryobj_data(struct gl_context *ctx) { - _mesa_HashDeleteAll(ctx->Query.QueryObjects, delete_queryobj_cb, ctx); - _mesa_DeleteHashTable(ctx->Query.QueryObjects); + _mesa_DeinitHashTable(&ctx->Query.QueryObjects, delete_queryobj_cb, ctx); } diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h index ba8336b525a..f343d00879a 100644 --- a/src/mesa/main/queryobj.h +++ b/src/mesa/main/queryobj.h @@ -35,64 +35,20 @@ static inline struct gl_query_object * _mesa_lookup_query_object(struct gl_context *ctx, GLuint id) { return (struct gl_query_object *) - _mesa_HashLookupLocked(ctx->Query.QueryObjects, id); + _mesa_HashLookupLocked(&ctx->Query.QueryObjects, id); } - -extern void -_mesa_init_query_object_functions(struct dd_function_table *driver); - extern void _mesa_init_queryobj(struct gl_context *ctx); extern void _mesa_free_queryobj_data(struct gl_context *ctx); -extern void -_mesa_delete_query(struct gl_context *ctx, struct gl_query_object *q); - -void GLAPIENTRY -_mesa_GenQueries(GLsizei n, GLuint *ids); -void GLAPIENTRY -_mesa_CreateQueries(GLenum target, GLsizei n, GLuint *ids); -void GLAPIENTRY -_mesa_DeleteQueries(GLsizei n, const GLuint *ids); -GLboolean GLAPIENTRY -_mesa_IsQuery(GLuint id); -void GLAPIENTRY -_mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id); -void GLAPIENTRY -_mesa_EndQueryIndexed(GLenum target, GLuint index); -void GLAPIENTRY -_mesa_BeginQuery(GLenum target, GLuint id); -void GLAPIENTRY -_mesa_EndQuery(GLenum target); -void GLAPIENTRY -_mesa_QueryCounter(GLuint id, GLenum target); -void GLAPIENTRY -_mesa_GetQueryIndexediv(GLenum target, GLuint index, GLenum pname, - GLint *params); -void GLAPIENTRY -_mesa_GetQueryiv(GLenum target, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetQueryObjectiv(GLuint id, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetQueryObjectuiv(GLuint id, GLenum pname, GLuint *params); -void GLAPIENTRY -_mesa_GetQueryObjecti64v(GLuint id, GLenum pname, GLint64EXT *params); -void GLAPIENTRY -_mesa_GetQueryObjectui64v(GLuint id, GLenum pname, GLuint64EXT *params); -void GLAPIENTRY -_mesa_GetQueryBufferObjectiv(GLuint id, GLuint buffer, GLenum pname, - GLintptr offset); -void GLAPIENTRY -_mesa_GetQueryBufferObjectuiv(GLuint id, GLuint buffer, GLenum pname, - GLintptr offset); -void GLAPIENTRY -_mesa_GetQueryBufferObjecti64v(GLuint id, GLuint buffer, GLenum pname, - GLintptr offset); -void GLAPIENTRY -_mesa_GetQueryBufferObjectui64v(GLuint id, GLuint buffer, GLenum pname, - GLintptr offset); +void +_mesa_wait_query(struct gl_context *ctx, struct gl_query_object *q); +void +_mesa_check_query(struct gl_context *ctx, struct gl_query_object *q); -#endif /* QUERYOBJ_H */ +uint64_t +_mesa_get_timestamp(struct gl_context *ctx); +#endif diff --git a/src/mesa/main/rastpos.c b/src/mesa/main/rastpos.c index 4fd16fac390..c8301e38b6a 100644 --- a/src/mesa/main/rastpos.c +++ b/src/mesa/main/rastpos.c @@ -28,7 +28,7 @@ * Raster position operations. */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "feedback.h" #include "macros.h" @@ -39,6 +39,8 @@ #include "main/viewport.h" #include "util/bitscan.h" +#include "state_tracker/st_cb_rasterpos.h" +#include "api_exec_decl.h" /** @@ -388,7 +390,7 @@ compute_texgen(struct gl_context *ctx, const GLfloat vObj[4], const GLfloat vEye /** - * glRasterPos transformation. Typically called via ctx->Driver.RasterPos(). + * glRasterPos transformation. * * \param vObj vertex position in object space */ @@ -544,7 +546,7 @@ rasterpos(GLfloat x, GLfloat y, GLfloat z, GLfloat w) if (ctx->NewState) _mesa_update_state( ctx ); - ctx->Driver.RasterPos(ctx, p); + st_RasterPos(ctx, p); } diff --git a/src/mesa/main/rastpos.h b/src/mesa/main/rastpos.h index 90b8f957b9f..0a9291a77f3 100644 --- a/src/mesa/main/rastpos.h +++ b/src/mesa/main/rastpos.h @@ -32,7 +32,7 @@ #define RASTPOS_H -#include "glheader.h" +#include "util/glheader.h" struct _glapi_table; @@ -44,104 +44,4 @@ _mesa_init_rastpos(struct gl_context *ctx); void _mesa_RasterPos(struct gl_context *ctx, const GLfloat vObj[4]); -void GLAPIENTRY -_mesa_RasterPos2d(GLdouble x, GLdouble y); -void GLAPIENTRY -_mesa_RasterPos2f(GLfloat x, GLfloat y); -void GLAPIENTRY -_mesa_RasterPos2i(GLint x, GLint y); -void GLAPIENTRY -_mesa_RasterPos2s(GLshort x, GLshort y); -void GLAPIENTRY -_mesa_RasterPos3d(GLdouble x, GLdouble y, GLdouble z); -void GLAPIENTRY -_mesa_RasterPos3f(GLfloat x, GLfloat y, GLfloat z); -void GLAPIENTRY -_mesa_RasterPos3i(GLint x, GLint y, GLint z); -void GLAPIENTRY -_mesa_RasterPos3s(GLshort x, GLshort y, GLshort z); -void GLAPIENTRY -_mesa_RasterPos4d(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -void GLAPIENTRY -_mesa_RasterPos4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -void GLAPIENTRY -_mesa_RasterPos4i(GLint x, GLint y, GLint z, GLint w); -void GLAPIENTRY -_mesa_RasterPos4s(GLshort x, GLshort y, GLshort z, GLshort w); -void GLAPIENTRY -_mesa_RasterPos2dv(const GLdouble *v); -void GLAPIENTRY -_mesa_RasterPos2fv(const GLfloat *v); -void GLAPIENTRY -_mesa_RasterPos2iv(const GLint *v); -void GLAPIENTRY -_mesa_RasterPos2sv(const GLshort *v); -void GLAPIENTRY -_mesa_RasterPos3dv(const GLdouble *v); -void GLAPIENTRY -_mesa_RasterPos3fv(const GLfloat *v); -void GLAPIENTRY -_mesa_RasterPos3iv(const GLint *v); -void GLAPIENTRY -_mesa_RasterPos3sv(const GLshort *v); -void GLAPIENTRY -_mesa_RasterPos4dv(const GLdouble *v); -void GLAPIENTRY -_mesa_RasterPos4fv(const GLfloat *v); -void GLAPIENTRY -_mesa_RasterPos4iv(const GLint *v); -void GLAPIENTRY -_mesa_RasterPos4sv(const GLshort *v); -void GLAPIENTRY -_mesa_WindowPos2d(GLdouble x, GLdouble y); -void GLAPIENTRY -_mesa_WindowPos2f(GLfloat x, GLfloat y); -void GLAPIENTRY -_mesa_WindowPos2i(GLint x, GLint y); -void GLAPIENTRY -_mesa_WindowPos2s(GLshort x, GLshort y); -void GLAPIENTRY -_mesa_WindowPos3d(GLdouble x, GLdouble y, GLdouble z); -void GLAPIENTRY -_mesa_WindowPos3f(GLfloat x, GLfloat y, GLfloat z); -void GLAPIENTRY -_mesa_WindowPos3i(GLint x, GLint y, GLint z); -void GLAPIENTRY -_mesa_WindowPos3s(GLshort x, GLshort y, GLshort z); -void GLAPIENTRY -_mesa_WindowPos4dMESA(GLdouble x, GLdouble y, GLdouble z, GLdouble w); -void GLAPIENTRY -_mesa_WindowPos4fMESA(GLfloat x, GLfloat y, GLfloat z, GLfloat w); -void GLAPIENTRY -_mesa_WindowPos4iMESA(GLint x, GLint y, GLint z, GLint w); -void GLAPIENTRY -_mesa_WindowPos4sMESA(GLshort x, GLshort y, GLshort z, GLshort w); -void GLAPIENTRY -_mesa_WindowPos2dv(const GLdouble *v); -void GLAPIENTRY -_mesa_WindowPos2fv(const GLfloat *v); -void GLAPIENTRY -_mesa_WindowPos2iv(const GLint *v); -void GLAPIENTRY -_mesa_WindowPos2sv(const GLshort *v); -void GLAPIENTRY -_mesa_WindowPos3dv(const GLdouble *v); -void GLAPIENTRY -_mesa_WindowPos3fv(const GLfloat *v); -void GLAPIENTRY -_mesa_WindowPos3iv(const GLint *v); -void GLAPIENTRY -_mesa_WindowPos3sv(const GLshort *v); -void GLAPIENTRY -_mesa_WindowPos4dvMESA(const GLdouble *v); -void GLAPIENTRY -_mesa_WindowPos4fvMESA(const GLfloat *v); -void GLAPIENTRY -_mesa_WindowPos4ivMESA(const GLint *v); -void GLAPIENTRY -_mesa_WindowPos4svMESA(const GLshort *v); - - -/*@}*/ - #endif /* RASTPOS_H */ diff --git a/src/mesa/main/readpix.c b/src/mesa/main/readpix.c index 6f4d49905a1..1ae2784fb20 100644 --- a/src/mesa/main/readpix.c +++ b/src/mesa/main/readpix.c @@ -22,7 +22,7 @@ * OTHER DEALINGS IN THE SOFTWARE. */ -#include "glheader.h" +#include "util/glheader.h" #include "blend.h" #include "bufferobj.h" @@ -37,12 +37,15 @@ #include "pack.h" #include "pbo.h" #include "pixel.h" +#include "renderbuffer.h" #include "state.h" #include "glformats.h" #include "fbobject.h" #include "format_utils.h" #include "pixeltransfer.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_readpixels.h" /** * Return true if the conversion L=R+G+B is needed. @@ -103,10 +106,19 @@ _mesa_get_readpixels_transfer_ops(const struct gl_context *ctx, return 0; } + /* If on OpenGL ES with GL_EXT_render_snorm, negative values should + * not be clamped. + */ + bool gles_snorm = + _mesa_has_EXT_render_snorm(ctx) && + _mesa_get_format_datatype(texFormat) == GL_SIGNED_NORMALIZED; + if (uses_blit) { /* For blit-based ReadPixels packing, the clamping is done automatically - * unless the type is float. */ + * unless the type is float. Disable clamping when on ES using snorm. + */ if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) && + !gles_snorm && (type == GL_FLOAT || type == GL_HALF_FLOAT || type == GL_UNSIGNED_INT_10F_11F_11F_REV)) { transferOps |= IMAGE_CLAMP_BIT; @@ -114,12 +126,23 @@ _mesa_get_readpixels_transfer_ops(const struct gl_context *ctx, } else { /* For CPU-based ReadPixels packing, the clamping must always be done - * for non-float types, */ - if (_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) || - (type != GL_FLOAT && type != GL_HALF_FLOAT && - type != GL_UNSIGNED_INT_10F_11F_11F_REV)) { + * for non-float types, except on ES when using snorm types. + */ + if ((_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) || + (type != GL_FLOAT && type != GL_HALF_FLOAT && + type != GL_UNSIGNED_INT_10F_11F_11F_REV)) && !gles_snorm) { transferOps |= IMAGE_CLAMP_BIT; } + + /* For SNORM formats we only clamp if `type` is signed and clamp is `true` + * and when not on ES using snorm types. + */ + if (!_mesa_get_clamp_read_color(ctx, ctx->ReadBuffer) && + !gles_snorm && + _mesa_get_format_datatype(texFormat) == GL_SIGNED_NORMALIZED && + (type == GL_BYTE || type == GL_SHORT || type == GL_INT)) { + transferOps &= ~IMAGE_CLAMP_BIT; + } } /* If the format is unsigned normalized, we can ignore clamping @@ -234,8 +257,8 @@ readpixels_memcpy(struct gl_context *ctx, dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, format, type, 0, 0); - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride, ctx->ReadBuffer->FlipY); + _mesa_map_renderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride, ctx->ReadBuffer->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return GL_TRUE; /* don't bother trying the slow path */ @@ -255,7 +278,7 @@ readpixels_memcpy(struct gl_context *ctx, } } - ctx->Driver.UnmapRenderbuffer(ctx, rb); + _mesa_unmap_renderbuffer(ctx, rb); return GL_TRUE; } @@ -285,8 +308,8 @@ read_uint_depth_pixels( struct gl_context *ctx, if (_mesa_get_format_datatype(rb->Format) != GL_UNSIGNED_NORMALIZED) return GL_FALSE; - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride, fb->FlipY); + _mesa_map_renderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride, fb->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); @@ -303,7 +326,7 @@ read_uint_depth_pixels( struct gl_context *ctx, map += stride; dst += dstStride; } - ctx->Driver.UnmapRenderbuffer(ctx, rb); + _mesa_unmap_renderbuffer(ctx, rb); return GL_TRUE; } @@ -343,8 +366,8 @@ read_depth_pixels( struct gl_context *ctx, dst = (GLubyte *) _mesa_image_address2d(packing, pixels, width, height, GL_DEPTH_COMPONENT, type, 0, 0); - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride, fb->FlipY); + _mesa_map_renderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride, fb->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; @@ -368,7 +391,7 @@ read_depth_pixels( struct gl_context *ctx, free(depthValues); - ctx->Driver.UnmapRenderbuffer(ctx, rb); + _mesa_unmap_renderbuffer(ctx, rb); } @@ -391,8 +414,8 @@ read_stencil_pixels( struct gl_context *ctx, if (!rb) return; - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride, fb->FlipY); + _mesa_map_renderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride, fb->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; @@ -420,7 +443,7 @@ read_stencil_pixels( struct gl_context *ctx, free(stencil); - ctx->Driver.UnmapRenderbuffer(ctx, rb); + _mesa_unmap_renderbuffer(ctx, rb); } /* @@ -462,8 +485,8 @@ read_rgba_pixels( struct gl_context *ctx, format, type, 0, 0); /* Map the source render buffer */ - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &rb_stride, fb->FlipY); + _mesa_map_renderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &rb_stride, fb->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; @@ -626,7 +649,7 @@ done_swap: } done_unmap: - ctx->Driver.UnmapRenderbuffer(ctx, rb); + _mesa_unmap_renderbuffer(ctx, rb); } /** @@ -652,8 +675,8 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx, rb->Format != MESA_FORMAT_Z24_UNORM_S8_UINT) return GL_FALSE; - ctx->Driver.MapRenderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, - &map, &stride, fb->FlipY); + _mesa_map_renderbuffer(ctx, rb, x, y, width, height, GL_MAP_READ_BIT, + &map, &stride, fb->FlipY); if (!map) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return GL_TRUE; /* don't bother trying the slow path */ @@ -666,7 +689,7 @@ fast_read_depth_stencil_pixels(struct gl_context *ctx, dst += dstStride; } - ctx->Driver.UnmapRenderbuffer(ctx, rb); + _mesa_unmap_renderbuffer(ctx, rb); return GL_TRUE; } @@ -692,17 +715,17 @@ fast_read_depth_stencil_pixels_separate(struct gl_context *ctx, if (_mesa_get_format_datatype(depthRb->Format) != GL_UNSIGNED_NORMALIZED) return GL_FALSE; - ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, - GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY); + _mesa_map_renderbuffer(ctx, depthRb, x, y, width, height, + GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY); if (!depthMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return GL_TRUE; /* don't bother trying the slow path */ } - ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height, - GL_MAP_READ_BIT, &stencilMap, &stencilStride, fb->FlipY); + _mesa_map_renderbuffer(ctx, stencilRb, x, y, width, height, + GL_MAP_READ_BIT, &stencilMap, &stencilStride, fb->FlipY); if (!stencilMap) { - ctx->Driver.UnmapRenderbuffer(ctx, depthRb); + _mesa_unmap_renderbuffer(ctx, depthRb); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return GL_TRUE; /* don't bother trying the slow path */ } @@ -730,8 +753,8 @@ fast_read_depth_stencil_pixels_separate(struct gl_context *ctx, free(stencilVals); - ctx->Driver.UnmapRenderbuffer(ctx, depthRb); - ctx->Driver.UnmapRenderbuffer(ctx, stencilRb); + _mesa_unmap_renderbuffer(ctx, depthRb); + _mesa_unmap_renderbuffer(ctx, stencilRb); return GL_TRUE; } @@ -756,19 +779,19 @@ slow_read_depth_stencil_pixels_separate(struct gl_context *ctx, /* The depth and stencil buffers might be separate, or a single buffer. * If one buffer, only map it once. */ - ctx->Driver.MapRenderbuffer(ctx, depthRb, x, y, width, height, - GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY); + _mesa_map_renderbuffer(ctx, depthRb, x, y, width, height, + GL_MAP_READ_BIT, &depthMap, &depthStride, fb->FlipY); if (!depthMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; } if (stencilRb != depthRb) { - ctx->Driver.MapRenderbuffer(ctx, stencilRb, x, y, width, height, - GL_MAP_READ_BIT, &stencilMap, - &stencilStride, fb->FlipY); + _mesa_map_renderbuffer(ctx, stencilRb, x, y, width, height, + GL_MAP_READ_BIT, &stencilMap, + &stencilStride, fb->FlipY); if (!stencilMap) { - ctx->Driver.UnmapRenderbuffer(ctx, depthRb); + _mesa_unmap_renderbuffer(ctx, depthRb); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels"); return; } @@ -802,9 +825,9 @@ slow_read_depth_stencil_pixels_separate(struct gl_context *ctx, free(stencilVals); free(depthVals); - ctx->Driver.UnmapRenderbuffer(ctx, depthRb); + _mesa_unmap_renderbuffer(ctx, depthRb); if (stencilRb != depthRb) { - ctx->Driver.UnmapRenderbuffer(ctx, stencilRb); + _mesa_unmap_renderbuffer(ctx, stencilRb); } } @@ -855,7 +878,7 @@ read_depth_stencil_pixels(struct gl_context *ctx, /** - * Software fallback routine for ctx->Driver.ReadPixels(). + * Software fallback routine. * By time we get here, all error checking will have been done. */ void @@ -958,15 +981,6 @@ read_pixels_es3_error_check(struct gl_context *ctx, GLenum format, GLenum type, return GL_NO_ERROR; } } - if (type == GL_UNSIGNED_BYTE) { - switch (internalFormat) { - case GL_R8_SNORM: - case GL_RG8_SNORM: - case GL_RGBA8_SNORM: - if (_mesa_has_EXT_render_snorm(ctx)) - return GL_NO_ERROR; - } - } break; case GL_BGRA: /* GL_EXT_read_format_bgra */ @@ -1049,8 +1063,7 @@ read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, return; } - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); if (ctx->NewState) _mesa_update_state(ctx); @@ -1078,7 +1091,7 @@ read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, * combination is, and Mesa can handle anything valid. Just work instead. */ if (_mesa_is_gles(ctx)) { - if (ctx->API == API_OPENGLES2 && + if (_mesa_is_gles2(ctx) && _mesa_is_color_format(format) && _mesa_get_color_read_format(ctx, NULL, "glReadPixels") == format && _mesa_get_color_read_type(ctx, NULL, "glReadPixels") == type) { @@ -1110,8 +1123,25 @@ read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, return; } + /** + * From the GL_EXT_multisampled_render_to_texture spec: + * + * Similarly, for ReadPixels: + * "An INVALID_OPERATION error is generated if the value of READ_- + * FRAMEBUFFER_BINDING (see section 9) is non-zero, the read framebuffer + * is framebuffer complete, and the value of SAMPLE_BUFFERS for the read + * framebuffer is one." + * + * These errors do not apply to textures and renderbuffers that have + * associated multisample data specified by the mechanisms described in + * this extension, i.e., the above operations are allowed even when + * SAMPLE_BUFFERS is non-zero for renderbuffers created via Renderbuffer- + * StorageMultisampleEXT or textures attached via FramebufferTexture2D- + * MultisampleEXT. + */ if (_mesa_is_user_fbo(ctx->ReadBuffer) && - ctx->ReadBuffer->Visual.samples > 0) { + ctx->ReadBuffer->Visual.samples > 0 && + !_mesa_has_rtt_samples(ctx->ReadBuffer)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(multisample FBO)"); return; } @@ -1163,8 +1193,11 @@ read_pixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, } } - ctx->Driver.ReadPixels(ctx, x, y, width, height, - format, type, &clippedPacking, pixels); + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + + st_ReadPixels(ctx, x, y, width, height, + format, type, &clippedPacking, pixels); } void GLAPIENTRY diff --git a/src/mesa/main/readpix.h b/src/mesa/main/readpix.h index eff8e029044..581632fa60c 100644 --- a/src/mesa/main/readpix.h +++ b/src/mesa/main/readpix.h @@ -27,7 +27,7 @@ #define READPIXELS_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_pixelstore_attrib; @@ -58,22 +58,4 @@ _mesa_readpixels(struct gl_context *ctx, const struct gl_pixelstore_attrib *packing, GLvoid *pixels); -void GLAPIENTRY -_mesa_ReadPixels_no_error(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_ReadPixels( GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLvoid *pixels ); - -void GLAPIENTRY -_mesa_ReadnPixelsARB_no_error(GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLsizei bufSize, - GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_ReadnPixelsARB( GLint x, GLint y, GLsizei width, GLsizei height, - GLenum format, GLenum type, GLsizei bufSize, - GLvoid *pixels ); - #endif diff --git a/src/mesa/main/remap.c b/src/mesa/main/remap.c index 2110140ab95..415f18e5295 100644 --- a/src/mesa/main/remap.c +++ b/src/mesa/main/remap.c @@ -52,48 +52,6 @@ int driDispatchRemapTable[driDispatchRemapTable_size]; -/** - * Map a function by its spec. The function will be added to glapi, - * and the dispatch offset will be returned. - * - * \param spec a '\0'-separated string array specifying a function. - * It begins with the parameter signature of the function, - * followed by the names of the entry points. An empty entry - * point name terminates the array. - * - * \return the offset of the (re-)mapped function in the dispatch - * table, or -1. - */ -static int -map_function_spec(const char *spec) -{ - const char *signature; - const char *names[MAX_ENTRY_POINTS + 1]; - int num_names = 0; - - if (!spec) - return -1; - - signature = spec; - spec += strlen(spec) + 1; - - /* spec is terminated by an empty string */ - while (*spec) { - names[num_names] = spec; - num_names++; - if (num_names >= MAX_ENTRY_POINTS) - break; - spec += strlen(spec) + 1; - } - if (!num_names) - return -1; - - names[num_names] = NULL; - - /* add the entry points to the dispatch table */ - return _glapi_add_dispatch(names, signature); -} - /** * Initialize the remap table. This is called in one_time_init(). @@ -110,20 +68,16 @@ _mesa_init_remap_table(void) return; initialized = true; - /* initialize the MESA_remap_table_functions table */ for (i = 0; i < driDispatchRemapTable_size; i++) { - int offset; - const char *spec; - /* sanity check */ assert(i == MESA_remap_table_functions[i].remap_index); - spec = _mesa_function_pool + MESA_remap_table_functions[i].pool_index; + const char *name = _mesa_function_pool + MESA_remap_table_functions[i].pool_index; - offset = map_function_spec(spec); - /* store the dispatch offset in the MESA_remap_table_functions table */ - driDispatchRemapTable[i] = offset; - if (offset < 0) { - const char *name = spec + strlen(spec) + 1; + /* store the dispatch offset in driDispatchRemapTable, for use by + * _gloffset_* macros. + */ + driDispatchRemapTable[i] = _glapi_add_dispatch(name); + if (driDispatchRemapTable[i] < 0) { _mesa_warning(NULL, "failed to remap %s", name); } } diff --git a/src/mesa/main/renderbuffer.c b/src/mesa/main/renderbuffer.c index 27c6d90fb9b..dd3d7da4af6 100644 --- a/src/mesa/main/renderbuffer.c +++ b/src/mesa/main/renderbuffer.c @@ -23,15 +23,275 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" +#include "bufferobj.h" #include "fbobject.h" #include "formats.h" +#include "glformats.h" #include "mtypes.h" #include "renderbuffer.h" #include "util/u_memory.h" +#include "util/u_inlines.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_format.h" + +/** + * Called by FBO code to choose a PIPE_FORMAT_ for drawing surfaces. + */ +static enum pipe_format +choose_renderbuffer_format(struct gl_context *ctx, + GLenum internalFormat, unsigned sample_count, + unsigned storage_sample_count) +{ + unsigned bindings; + if (_mesa_is_depth_or_stencil_format(internalFormat)) + bindings = PIPE_BIND_DEPTH_STENCIL; + else + bindings = PIPE_BIND_RENDER_TARGET; + return st_choose_format(st_context(ctx), internalFormat, GL_NONE, GL_NONE, + PIPE_TEXTURE_2D, sample_count, + storage_sample_count, bindings, + false, false); +} + + + +/** + * Delete a gl_framebuffer. + * This is the default function for renderbuffer->Delete(). + * Drivers which subclass gl_renderbuffer should probably implement their + * own delete function. But the driver might also call this function to + * free the object in the end. + */ +static void +delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) +{ + if (ctx) { + pipe_surface_release(ctx->pipe, &rb->surface_srgb); + pipe_surface_release(ctx->pipe, &rb->surface_linear); + } else { + pipe_surface_release_no_context(&rb->surface_srgb); + pipe_surface_release_no_context(&rb->surface_linear); + } + rb->surface = NULL; + pipe_resource_reference(&rb->texture, NULL); + free(rb->data); + free(rb->Label); + free(rb); +} + +static GLboolean +renderbuffer_alloc_sw_storage(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + enum pipe_format format; + size_t size; + + free(rb->data); + rb->data = NULL; + + if (internalFormat == GL_RGBA16_SNORM) { + /* Special case for software accum buffers. Otherwise, if the + * call to choose_renderbuffer_format() fails (because the + * driver doesn't support signed 16-bit/channel colors) we'd + * just return without allocating the software accum buffer. + */ + format = PIPE_FORMAT_R16G16B16A16_SNORM; + } + else { + format = choose_renderbuffer_format(ctx, internalFormat, 0, 0); + + /* Not setting gl_renderbuffer::Format here will cause + * FRAMEBUFFER_UNSUPPORTED and ValidateFramebuffer will not be called. + */ + if (format == PIPE_FORMAT_NONE) { + return GL_TRUE; + } + } + + rb->Format = st_pipe_format_to_mesa_format(format); + + size = _mesa_format_image_size(rb->Format, width, height, 1); + rb->data = malloc(size); + return rb->data != NULL; +} + + +/** + * gl_renderbuffer::AllocStorage() + * This is called to allocate the original drawing surface, and + * during window resize. + */ +static GLboolean +renderbuffer_alloc_storage(struct gl_context * ctx, + struct gl_renderbuffer *rb, + GLenum internalFormat, + GLuint width, GLuint height) +{ + struct st_context *st = st_context(ctx); + struct pipe_screen *screen = ctx->screen; + enum pipe_format format = PIPE_FORMAT_NONE; + struct pipe_resource templ; + + /* init renderbuffer fields */ + rb->Width = width; + rb->Height = height; + rb->_BaseFormat = _mesa_base_fbo_format(ctx, internalFormat); + rb->defined = GL_FALSE; /* undefined contents now */ + + if (rb->software) { + return renderbuffer_alloc_sw_storage(ctx, rb, internalFormat, + width, height); + } + + /* Free the old surface and texture + */ + pipe_surface_reference(&rb->surface_srgb, NULL); + pipe_surface_reference(&rb->surface_linear, NULL); + rb->surface = NULL; + pipe_resource_reference(&rb->texture, NULL); + + /* If an sRGB framebuffer is unsupported, sRGB formats behave like linear + * formats. + */ + if (!ctx->Extensions.EXT_sRGB) { + internalFormat = _mesa_get_linear_internalformat(internalFormat); + } + + /* Handle multisample renderbuffers first. + * + * From ARB_framebuffer_object: + * If <samples> is zero, then RENDERBUFFER_SAMPLES is set to zero. + * Otherwise <samples> represents a request for a desired minimum + * number of samples. Since different implementations may support + * different sample counts for multisampled rendering, the actual + * number of samples allocated for the renderbuffer image is + * implementation dependent. However, the resulting value for + * RENDERBUFFER_SAMPLES is guaranteed to be greater than or equal + * to <samples> and no more than the next larger sample count supported + * by the implementation. + * + * Find the supported number of samples >= rb->NumSamples + */ + if (rb->NumSamples > 0) { + unsigned start, start_storage; + + if (ctx->Const.MaxSamples > 1 && rb->NumSamples == 1) { + /* don't try num_samples = 1 with drivers that support real msaa */ + start = 2; + start_storage = 2; + } else { + start = rb->NumSamples; + start_storage = rb->NumStorageSamples; + } + + if (ctx->Extensions.AMD_framebuffer_multisample_advanced) { + if (rb->_BaseFormat == GL_DEPTH_COMPONENT || + rb->_BaseFormat == GL_DEPTH_STENCIL || + rb->_BaseFormat == GL_STENCIL_INDEX) { + /* Find a supported depth-stencil format. */ + for (unsigned samples = start; + samples <= ctx->Const.MaxDepthStencilFramebufferSamples; + samples++) { + format = choose_renderbuffer_format(ctx, internalFormat, + samples, samples); + + if (format != PIPE_FORMAT_NONE) { + rb->NumSamples = samples; + rb->NumStorageSamples = samples; + break; + } + } + } else { + /* Find a supported color format, samples >= storage_samples. */ + for (unsigned storage_samples = start_storage; + storage_samples <= ctx->Const.MaxColorFramebufferStorageSamples; + storage_samples++) { + for (unsigned samples = MAX2(start, storage_samples); + samples <= ctx->Const.MaxColorFramebufferSamples; + samples++) { + format = choose_renderbuffer_format(ctx, internalFormat, + samples, + storage_samples); + + if (format != PIPE_FORMAT_NONE) { + rb->NumSamples = samples; + rb->NumStorageSamples = storage_samples; + goto found; + } + } + } + found:; + } + } else { + for (unsigned samples = start; samples <= ctx->Const.MaxSamples; + samples++) { + format = choose_renderbuffer_format(ctx, internalFormat, + samples, samples); + + if (format != PIPE_FORMAT_NONE) { + rb->NumSamples = samples; + rb->NumStorageSamples = samples; + break; + } + } + } + } else { + format = choose_renderbuffer_format(ctx, internalFormat, 0, 0); + } + + /* Not setting gl_renderbuffer::Format here will cause + * FRAMEBUFFER_UNSUPPORTED and ValidateFramebuffer will not be called. + */ + if (format == PIPE_FORMAT_NONE) { + return GL_TRUE; + } + + rb->Format = st_pipe_format_to_mesa_format(format); + + if (width == 0 || height == 0) { + /* if size is zero, nothing to allocate */ + return GL_TRUE; + } + + /* Setup new texture template. + */ + memset(&templ, 0, sizeof(templ)); + templ.target = st->internal_target; + templ.format = format; + templ.width0 = width; + templ.height0 = height; + templ.depth0 = 1; + templ.array_size = 1; + templ.nr_samples = rb->NumSamples; + templ.nr_storage_samples = rb->NumStorageSamples; + + if (util_format_is_depth_or_stencil(format)) { + templ.bind = PIPE_BIND_DEPTH_STENCIL; + } + else if (rb->Name != 0) { + /* this is a user-created renderbuffer */ + templ.bind = PIPE_BIND_RENDER_TARGET; + } + else { + /* this is a window-system buffer */ + templ.bind = (PIPE_BIND_DISPLAY_TARGET | + PIPE_BIND_RENDER_TARGET); + } + + rb->texture = screen->resource_create(screen, &templ); + + if (!rb->texture) + return false; + + _mesa_update_renderbuffer_surface(ctx, rb); + return rb->surface != NULL; +} /** * Initialize the fields of a gl_renderbuffer to default values. @@ -41,12 +301,9 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) { GET_CURRENT_CONTEXT(ctx); - simple_mtx_init(&rb->Mutex, mtx_plain); - - rb->ClassID = 0; rb->Name = name; rb->RefCount = 1; - rb->Delete = _mesa_delete_renderbuffer; + rb->Delete = delete_renderbuffer; /* The rest of these should be set later by the caller of this function or * the AllocStorage method: @@ -74,37 +331,8 @@ _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name) } rb->Format = MESA_FORMAT_NONE; -} - -/** - * Allocate a new gl_renderbuffer object. This can be used for user-created - * renderbuffers or window-system renderbuffers. - */ -struct gl_renderbuffer * -_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name) -{ - struct gl_renderbuffer *rb = CALLOC_STRUCT(gl_renderbuffer); - if (rb) { - _mesa_init_renderbuffer(rb, name); - } - return rb; -} - - -/** - * Delete a gl_framebuffer. - * This is the default function for renderbuffer->Delete(). - * Drivers which subclass gl_renderbuffer should probably implement their - * own delete function. But the driver might also call this function to - * free the object in the end. - */ -void -_mesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb) -{ - simple_mtx_destroy(&rb->Mutex); - free(rb->Label); - free(rb); + rb->AllocStorage = renderbuffer_alloc_storage; } static void @@ -199,29 +427,234 @@ _mesa_reference_renderbuffer_(struct gl_renderbuffer **ptr, { if (*ptr) { /* Unreference the old renderbuffer */ - GLboolean deleteFlag = GL_FALSE; struct gl_renderbuffer *oldRb = *ptr; - simple_mtx_lock(&oldRb->Mutex); assert(oldRb->RefCount > 0); - oldRb->RefCount--; - deleteFlag = (oldRb->RefCount == 0); - simple_mtx_unlock(&oldRb->Mutex); - if (deleteFlag) { + if (p_atomic_dec_zero(&oldRb->RefCount)) { GET_CURRENT_CONTEXT(ctx); oldRb->Delete(ctx, oldRb); } - - *ptr = NULL; } - assert(!*ptr); if (rb) { /* reference new renderbuffer */ - simple_mtx_lock(&rb->Mutex); - rb->RefCount++; - simple_mtx_unlock(&rb->Mutex); - *ptr = rb; + p_atomic_inc(&rb->RefCount); + } + + *ptr = rb; +} + +void +_mesa_map_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **mapOut, GLint *rowStrideOut, + bool flip_y) +{ + struct pipe_context *pipe = ctx->pipe; + const GLboolean invert = flip_y; + GLuint y2; + GLubyte *map; + + if (rb->software) { + /* software-allocated renderbuffer (probably an accum buffer) */ + if (rb->data) { + GLint bpp = _mesa_get_format_bytes(rb->Format); + GLint stride = _mesa_format_row_stride(rb->Format, + rb->Width); + *mapOut = (GLubyte *) rb->data + y * stride + x * bpp; + *rowStrideOut = stride; + } + else { + *mapOut = NULL; + *rowStrideOut = 0; + } + return; + } + + /* Check for unexpected flags */ + assert((mode & ~(GL_MAP_READ_BIT | + GL_MAP_WRITE_BIT | + GL_MAP_INVALIDATE_RANGE_BIT)) == 0); + + const enum pipe_map_flags transfer_flags = + _mesa_access_flags_to_transfer_flags(mode, false); + + /* Note: y=0=bottom of buffer while y2=0=top of buffer. + * 'invert' will be true for window-system buffers and false for + * user-allocated renderbuffers and textures. + */ + if (invert) + y2 = rb->Height - y - h; + else + y2 = y; + + map = pipe_texture_map(pipe, + rb->texture, + rb->surface->u.tex.level, + rb->surface->u.tex.first_layer, + transfer_flags, x, y2, w, h, &rb->transfer); + if (map) { + if (invert) { + *rowStrideOut = -(int) rb->transfer->stride; + map += (h - 1) * rb->transfer->stride; + } + else { + *rowStrideOut = rb->transfer->stride; + } + *mapOut = map; + } + else { + *mapOut = NULL; + *rowStrideOut = 0; + } +} + +void +_mesa_unmap_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct pipe_context *pipe = ctx->pipe; + + if (rb->software) { + /* software-allocated renderbuffer (probably an accum buffer) */ + return; + } + + pipe_texture_unmap(pipe, rb->transfer); + rb->transfer = NULL; +} + +void +_mesa_regen_renderbuffer_surface(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_resource *resource = rb->texture; + + struct pipe_surface **psurf = + rb->surface_srgb ? &rb->surface_srgb : &rb->surface_linear; + struct pipe_surface *surf = *psurf; + /* create a new pipe_surface */ + struct pipe_surface surf_tmpl; + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + surf_tmpl.format = surf->format; + surf_tmpl.nr_samples = rb->rtt_nr_samples; + surf_tmpl.u.tex.level = surf->u.tex.level; + surf_tmpl.u.tex.first_layer = surf->u.tex.first_layer; + surf_tmpl.u.tex.last_layer = surf->u.tex.last_layer; + + /* create -> destroy to avoid blowing up cached surfaces */ + surf = pipe->create_surface(pipe, resource, &surf_tmpl); + pipe_surface_release(pipe, psurf); + *psurf = surf; + + rb->surface = *psurf; +} + +/** + * Create or update the pipe_surface of a FBO renderbuffer. + * This is usually called after st_finalize_texture. + */ +void +_mesa_update_renderbuffer_surface(struct gl_context *ctx, + struct gl_renderbuffer *rb) +{ + struct pipe_context *pipe = ctx->pipe; + struct pipe_resource *resource = rb->texture; + const struct gl_texture_object *stTexObj = NULL; + unsigned rtt_width = rb->Width; + unsigned rtt_height = rb->Height; + unsigned rtt_depth = rb->Depth; + + /* + * For winsys fbo, it is possible that the renderbuffer is sRGB-capable but + * the format of rb->texture is linear (because we have no control over + * the format). Check rb->Format instead of rb->texture->format + * to determine if the rb is sRGB-capable. + */ + bool enable_srgb = ctx->Color.sRGBEnabled && + _mesa_is_format_srgb(rb->Format); + enum pipe_format format = resource->format; + + if (rb->is_rtt) { + stTexObj = rb->TexImage->TexObject; + if (stTexObj->surface_based) + format = stTexObj->surface_format; + } + + format = enable_srgb ? util_format_srgb(format) : util_format_linear(format); + + if (resource->target == PIPE_TEXTURE_1D_ARRAY) { + rtt_depth = rtt_height; + rtt_height = 1; + } + + /* find matching mipmap level size */ + unsigned level; + for (level = 0; level <= resource->last_level; level++) { + if (u_minify(resource->width0, level) == rtt_width && + u_minify(resource->height0, level) == rtt_height && + (resource->target != PIPE_TEXTURE_3D || + u_minify(resource->depth0, level) == rtt_depth)) { + break; + } + } + assert(level <= resource->last_level); + + /* determine the layer bounds */ + unsigned first_layer, last_layer; + if (rb->rtt_layered) { + first_layer = 0; + last_layer = util_max_layer(rb->texture, level); + } + else { + first_layer = + last_layer = rb->rtt_face + rb->rtt_slice; + } + + /* Adjust for texture views */ + if (rb->is_rtt && resource->array_size > 1 && + stTexObj->Immutable) { + const struct gl_texture_object *tex = stTexObj; + first_layer += tex->Attrib.MinLayer; + if (!rb->rtt_layered) + last_layer += tex->Attrib.MinLayer; + else + last_layer = MIN2(first_layer + tex->Attrib.NumLayers - 1, + last_layer); + } + + struct pipe_surface **psurf = + enable_srgb ? &rb->surface_srgb : &rb->surface_linear; + struct pipe_surface *surf = *psurf; + + if (!surf || + surf->texture->nr_samples != rb->NumSamples || + surf->texture->nr_storage_samples != rb->NumStorageSamples || + surf->format != format || + surf->texture != resource || + surf->width != rtt_width || + surf->height != rtt_height || + surf->nr_samples != rb->rtt_nr_samples || + surf->u.tex.level != level || + surf->u.tex.first_layer != first_layer || + surf->u.tex.last_layer != last_layer) { + /* create a new pipe_surface */ + struct pipe_surface surf_tmpl; + memset(&surf_tmpl, 0, sizeof(surf_tmpl)); + surf_tmpl.format = format; + surf_tmpl.nr_samples = rb->rtt_nr_samples; + surf_tmpl.u.tex.level = level; + surf_tmpl.u.tex.first_layer = first_layer; + surf_tmpl.u.tex.last_layer = last_layer; + + /* create -> destroy to avoid blowing up cached surfaces */ + struct pipe_surface *surf = pipe->create_surface(pipe, resource, &surf_tmpl); + pipe_surface_release(pipe, psurf); + *psurf = surf; } + rb->surface = *psurf; } diff --git a/src/mesa/main/renderbuffer.h b/src/mesa/main/renderbuffer.h index 3f568e1e7f1..288ddb929bf 100644 --- a/src/mesa/main/renderbuffer.h +++ b/src/mesa/main/renderbuffer.h @@ -26,7 +26,7 @@ #ifndef RENDERBUFFER_H #define RENDERBUFFER_H -#include "glheader.h" +#include "util/glheader.h" #include "menums.h" #ifdef __cplusplus @@ -40,12 +40,6 @@ struct gl_renderbuffer; extern void _mesa_init_renderbuffer(struct gl_renderbuffer *rb, GLuint name); -extern struct gl_renderbuffer * -_mesa_new_renderbuffer(struct gl_context *ctx, GLuint name); - -extern void -_mesa_delete_renderbuffer(struct gl_context *ctx, struct gl_renderbuffer *rb); - extern void _mesa_attach_and_own_rb(struct gl_framebuffer *fb, gl_buffer_index bufferName, @@ -71,7 +65,25 @@ _mesa_reference_renderbuffer(struct gl_renderbuffer **ptr, if (*ptr != rb) _mesa_reference_renderbuffer_(ptr, rb); } - + +void +_mesa_map_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb, + GLuint x, GLuint y, GLuint w, GLuint h, + GLbitfield mode, + GLubyte **mapOut, GLint *rowStrideOut, + bool flip_y); + +void +_mesa_unmap_renderbuffer(struct gl_context *ctx, + struct gl_renderbuffer *rb); + +void +_mesa_regen_renderbuffer_surface(struct gl_context *ctx, + struct gl_renderbuffer *rb); +void +_mesa_update_renderbuffer_surface(struct gl_context *ctx, + struct gl_renderbuffer *rb); #ifdef __cplusplus } #endif diff --git a/src/mesa/main/robustness.c b/src/mesa/main/robustness.c index e7d7007da48..abe6d0f6afe 100644 --- a/src/mesa/main/robustness.c +++ b/src/mesa/main/robustness.c @@ -28,6 +28,8 @@ #include "mtypes.h" #include "macros.h" #include "main/dispatch.h" /* for _gloffset_COUNT */ +#include "api_exec_decl.h" +#include "glthread_marshal.h" static void GLAPIENTRY _context_lost_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, @@ -65,14 +67,14 @@ context_lost_nop_handler(void) void _mesa_set_context_lost_dispatch(struct gl_context *ctx) { - if (ctx->ContextLost == NULL) { + if (ctx->Dispatch.ContextLost == NULL) { int numEntries = MAX2(_glapi_get_dispatch_table_size(), _gloffset_COUNT); - ctx->ContextLost = malloc(numEntries * sizeof(_glapi_proc)); - if (!ctx->ContextLost) + ctx->Dispatch.ContextLost = malloc(numEntries * sizeof(_glapi_proc)); + if (!ctx->Dispatch.ContextLost) return; - _glapi_proc *entry = (_glapi_proc *) ctx->ContextLost; + _glapi_proc *entry = (_glapi_proc *) ctx->Dispatch.ContextLost; unsigned i; for (i = 0; i < numEntries; i++) entry[i] = (_glapi_proc) context_lost_nop_handler; @@ -95,14 +97,14 @@ _mesa_set_context_lost_dispatch(struct gl_context *ctx) * + GetQueryObjectuiv with <pname> QUERY_RESULT_AVAILABLE * ignores the other parameters and returns TRUE in <params>." */ - SET_GetError(ctx->ContextLost, _mesa_GetError); - SET_GetGraphicsResetStatusARB(ctx->ContextLost, _mesa_GetGraphicsResetStatusARB); - SET_GetSynciv(ctx->ContextLost, _context_lost_GetSynciv); - SET_GetQueryObjectuiv(ctx->ContextLost, _context_lost_GetQueryObjectuiv); + SET_GetError(ctx->Dispatch.ContextLost, _mesa_GetError); + SET_GetGraphicsResetStatusARB(ctx->Dispatch.ContextLost, _mesa_GetGraphicsResetStatusARB); + SET_GetSynciv(ctx->Dispatch.ContextLost, _context_lost_GetSynciv); + SET_GetQueryObjectuiv(ctx->Dispatch.ContextLost, _context_lost_GetQueryObjectuiv); } - ctx->CurrentServerDispatch = ctx->ContextLost; - _glapi_set_dispatch(ctx->CurrentServerDispatch); + ctx->Dispatch.Current = ctx->Dispatch.ContextLost; + _glapi_set_dispatch(ctx->Dispatch.Current); } /** @@ -131,29 +133,10 @@ _mesa_GetGraphicsResetStatusARB( void ) return GL_NO_ERROR; } - if (ctx->Driver.GetGraphicsResetStatus) { - /* Query the reset status of this context from the driver core. - */ + /* Query the reset status of this context from the driver core. */ + if (ctx->Driver.GetGraphicsResetStatus) status = ctx->Driver.GetGraphicsResetStatus(ctx); - simple_mtx_lock(&ctx->Shared->Mutex); - - /* If this context has not been affected by a GPU reset, check to see if - * some other context in the share group has been affected by a reset. - * If another context saw a reset but this context did not, assume that - * this context was not guilty. - */ - if (status != GL_NO_ERROR) { - ctx->Shared->ShareGroupReset = true; - ctx->Shared->DisjointOperation = true; - } else if (ctx->Shared->ShareGroupReset && !ctx->ShareGroupReset) { - status = GL_INNOCENT_CONTEXT_RESET_ARB; - } - - ctx->ShareGroupReset = ctx->Shared->ShareGroupReset; - simple_mtx_unlock(&ctx->Shared->Mutex); - } - if (status != GL_NO_ERROR) _mesa_set_context_lost_dispatch(ctx); diff --git a/src/mesa/main/samplerobj.c b/src/mesa/main/samplerobj.c index 841e07f8a4c..afb18f8c574 100644 --- a/src/mesa/main/samplerobj.c +++ b/src/mesa/main/samplerobj.c @@ -30,7 +30,7 @@ */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/enums.h" #include "main/hash.h" @@ -39,7 +39,19 @@ #include "main/samplerobj.h" #include "main/texturebindless.h" #include "util/u_memory.h" - +#include "api_exec_decl.h" + +/* Take advantage of how the enums are defined. */ +const enum pipe_tex_wrap wrap_to_gallium_table[32] = { + [GL_REPEAT & 0x1f] = PIPE_TEX_WRAP_REPEAT, + [GL_CLAMP & 0x1f] = PIPE_TEX_WRAP_CLAMP, + [GL_CLAMP_TO_EDGE & 0x1f] = PIPE_TEX_WRAP_CLAMP_TO_EDGE, + [GL_CLAMP_TO_BORDER & 0x1f] = PIPE_TEX_WRAP_CLAMP_TO_BORDER, + [GL_MIRRORED_REPEAT & 0x1f] = PIPE_TEX_WRAP_MIRROR_REPEAT, + [GL_MIRROR_CLAMP_EXT & 0x1f] = PIPE_TEX_WRAP_MIRROR_CLAMP, + [GL_MIRROR_CLAMP_TO_EDGE & 0x1f] = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE, + [GL_MIRROR_CLAMP_TO_BORDER_EXT & 0x1f] = PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER, +}; struct gl_sampler_object * _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) @@ -48,14 +60,14 @@ _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name) return NULL; else return (struct gl_sampler_object *) - _mesa_HashLookup(ctx->Shared->SamplerObjects, name); + _mesa_HashLookup(&ctx->Shared->SamplerObjects, name); } static inline struct gl_sampler_object * lookup_samplerobj_locked(struct gl_context *ctx, GLuint name) { return (struct gl_sampler_object *) - _mesa_HashLookupLocked(ctx->Shared->SamplerObjects, name); + _mesa_HashLookupLocked(&ctx->Shared->SamplerObjects, name); } static void @@ -63,9 +75,8 @@ delete_sampler_object(struct gl_context *ctx, struct gl_sampler_object *sampObj) { _mesa_delete_sampler_handles(ctx, sampObj); - simple_mtx_destroy(&sampObj->Mutex); free(sampObj->Label); - free(sampObj); + FREE(sampObj); } /** @@ -80,31 +91,22 @@ _mesa_reference_sampler_object_(struct gl_context *ctx, if (*ptr) { /* Unreference the old sampler */ - GLboolean deleteFlag = GL_FALSE; struct gl_sampler_object *oldSamp = *ptr; - simple_mtx_lock(&oldSamp->Mutex); assert(oldSamp->RefCount > 0); - oldSamp->RefCount--; - deleteFlag = (oldSamp->RefCount == 0); - simple_mtx_unlock(&oldSamp->Mutex); - if (deleteFlag) + if (p_atomic_dec_zero(&oldSamp->RefCount)) delete_sampler_object(ctx, oldSamp); - - *ptr = NULL; } - assert(!*ptr); if (samp) { /* reference new sampler */ - simple_mtx_lock(&samp->Mutex); assert(samp->RefCount > 0); - samp->RefCount++; - *ptr = samp; - simple_mtx_unlock(&samp->Mutex); + p_atomic_inc(&samp->RefCount); } + + *ptr = samp; } @@ -114,37 +116,48 @@ _mesa_reference_sampler_object_(struct gl_context *ctx, static void _mesa_init_sampler_object(struct gl_sampler_object *sampObj, GLuint name) { - simple_mtx_init(&sampObj->Mutex, mtx_plain); sampObj->Name = name; sampObj->RefCount = 1; sampObj->Attrib.WrapS = GL_REPEAT; sampObj->Attrib.WrapT = GL_REPEAT; sampObj->Attrib.WrapR = GL_REPEAT; + sampObj->Attrib.state.wrap_s = PIPE_TEX_WRAP_REPEAT; + sampObj->Attrib.state.wrap_t = PIPE_TEX_WRAP_REPEAT; + sampObj->Attrib.state.wrap_r = PIPE_TEX_WRAP_REPEAT; sampObj->Attrib.MinFilter = GL_NEAREST_MIPMAP_LINEAR; sampObj->Attrib.MagFilter = GL_LINEAR; - sampObj->Attrib.BorderColor.f[0] = 0.0; - sampObj->Attrib.BorderColor.f[1] = 0.0; - sampObj->Attrib.BorderColor.f[2] = 0.0; - sampObj->Attrib.BorderColor.f[3] = 0.0; + sampObj->Attrib.state.min_img_filter = PIPE_TEX_FILTER_NEAREST; + sampObj->Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; + sampObj->Attrib.state.mag_img_filter = PIPE_TEX_FILTER_LINEAR; + sampObj->Attrib.state.border_color.f[0] = 0; + sampObj->Attrib.state.border_color.f[1] = 0; + sampObj->Attrib.state.border_color.f[2] = 0; + sampObj->Attrib.state.border_color.f[3] = 0; + _mesa_update_is_border_color_nonzero(sampObj); sampObj->Attrib.MinLod = -1000.0F; sampObj->Attrib.MaxLod = 1000.0F; + sampObj->Attrib.state.min_lod = 0; /* Gallium doesn't allow negative numbers */ + sampObj->Attrib.state.max_lod = 1000; sampObj->Attrib.LodBias = 0.0F; + sampObj->Attrib.state.lod_bias = 0; sampObj->Attrib.MaxAnisotropy = 1.0F; + sampObj->Attrib.state.max_anisotropy = 0; /* Gallium uses 0 instead of 1. */ sampObj->Attrib.CompareMode = GL_NONE; sampObj->Attrib.CompareFunc = GL_LEQUAL; + sampObj->Attrib.state.compare_mode = PIPE_TEX_COMPARE_NONE; + sampObj->Attrib.state.compare_func = PIPE_FUNC_LEQUAL; sampObj->Attrib.sRGBDecode = GL_DECODE_EXT; sampObj->Attrib.CubeMapSeamless = GL_FALSE; + sampObj->Attrib.state.seamless_cube_map = false; sampObj->Attrib.ReductionMode = GL_WEIGHTED_AVERAGE_EXT; + sampObj->Attrib.state.reduction_mode = PIPE_TEX_REDUCTION_WEIGHTED_AVERAGE; sampObj->HandleAllocated = GL_FALSE; /* GL_ARB_bindless_texture */ _mesa_init_sampler_handles(sampObj); } -/** - * Fallback for ctx->Driver.NewSamplerObject(); - */ -struct gl_sampler_object * +static struct gl_sampler_object * _mesa_new_sampler_object(struct gl_context *ctx, GLuint name) { struct gl_sampler_object *sampObj = CALLOC_STRUCT(gl_sampler_object); @@ -163,26 +176,26 @@ create_samplers(struct gl_context *ctx, GLsizei count, GLuint *samplers, if (!samplers) return; - _mesa_HashLockMutex(ctx->Shared->SamplerObjects); + _mesa_HashLockMutex(&ctx->Shared->SamplerObjects); - _mesa_HashFindFreeKeys(ctx->Shared->SamplerObjects, samplers, count); + _mesa_HashFindFreeKeys(&ctx->Shared->SamplerObjects, samplers, count); /* Insert the ID and pointer to new sampler object into hash table */ for (i = 0; i < count; i++) { struct gl_sampler_object *sampObj; - sampObj = ctx->Driver.NewSamplerObject(ctx, samplers[i]); + sampObj = _mesa_new_sampler_object(ctx, samplers[i]); if (!sampObj) { - _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); + _mesa_HashUnlockMutex(&ctx->Shared->SamplerObjects); _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); return; } - _mesa_HashInsertLocked(ctx->Shared->SamplerObjects, samplers[i], - sampObj, true); + _mesa_HashInsertLocked(&ctx->Shared->SamplerObjects, samplers[i], + sampObj); } - _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); + _mesa_HashUnlockMutex(&ctx->Shared->SamplerObjects); } static void @@ -235,7 +248,7 @@ delete_samplers(struct gl_context *ctx, GLsizei count, const GLuint *samplers) { FLUSH_VERTICES(ctx, 0, 0); - _mesa_HashLockMutex(ctx->Shared->SamplerObjects); + _mesa_HashLockMutex(&ctx->Shared->SamplerObjects); for (GLsizei i = 0; i < count; i++) { if (samplers[i]) { @@ -253,14 +266,14 @@ delete_samplers(struct gl_context *ctx, GLsizei count, const GLuint *samplers) } /* The ID is immediately freed for re-use */ - _mesa_HashRemoveLocked(ctx->Shared->SamplerObjects, samplers[i]); + _mesa_HashRemoveLocked(&ctx->Shared->SamplerObjects, samplers[i]); /* But the object exists until its reference count goes to zero */ _mesa_reference_sampler_object(ctx, &sampObj, NULL); } } } - _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); + _mesa_HashUnlockMutex(&ctx->Shared->SamplerObjects); } @@ -380,7 +393,7 @@ bind_samplers(struct gl_context *ctx, GLuint first, GLsizei count, * their parameters are valid and no other error occurs." */ - _mesa_HashLockMutex(ctx->Shared->SamplerObjects); + _mesa_HashLockMutex(&ctx->Shared->SamplerObjects); for (i = 0; i < count; i++) { const GLuint unit = first + i; @@ -421,7 +434,7 @@ bind_samplers(struct gl_context *ctx, GLuint first, GLsizei count, } } - _mesa_HashUnlockMutex(ctx->Shared->SamplerObjects); + _mesa_HashUnlockMutex(&ctx->Shared->SamplerObjects); } else { /* Unbind all samplers in the range <first> through <first>+<count>-1 */ for (i = 0; i < count; i++) { @@ -479,6 +492,15 @@ validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap) { const struct gl_extensions * const e = &ctx->Extensions; + bool mirror_clamp = + _mesa_has_ATI_texture_mirror_once(ctx) || + _mesa_has_EXT_texture_mirror_clamp(ctx); + + bool mirror_clamp_to_edge = + _mesa_has_ARB_texture_mirror_clamp_to_edge(ctx) || + _mesa_has_EXT_texture_mirror_clamp_to_edge(ctx) || + mirror_clamp; + switch (wrap) { case GL_CLAMP: /* From GL 3.0 specification section E.1 "Profiles and Deprecated @@ -488,17 +510,16 @@ validate_texture_wrap_mode(struct gl_context *ctx, GLenum wrap) * texture parameters TEXTURE_WRAP_S, TEXTURE_WRAP_T, or * TEXTURE_WRAP_R. */ - return ctx->API == API_OPENGL_COMPAT; + return _mesa_is_desktop_gl_compat(ctx); case GL_CLAMP_TO_EDGE: case GL_REPEAT: case GL_MIRRORED_REPEAT: - return GL_TRUE; case GL_CLAMP_TO_BORDER: - return e->ARB_texture_border_clamp; + return GL_TRUE; case GL_MIRROR_CLAMP_EXT: - return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp; + return mirror_clamp; case GL_MIRROR_CLAMP_TO_EDGE_EXT: - return e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge; + return mirror_clamp_to_edge; case GL_MIRROR_CLAMP_TO_BORDER_EXT: return e->EXT_texture_mirror_clamp; default: @@ -516,33 +537,10 @@ flush(struct gl_context *ctx) FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); } -void -_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, - GLenum s, GLenum t, GLenum r) -{ - assert(validate_texture_wrap_mode(ctx, s)); - assert(validate_texture_wrap_mode(ctx, t)); - assert(validate_texture_wrap_mode(ctx, r)); - - if (samp->Attrib.WrapS == s && samp->Attrib.WrapT == t && samp->Attrib.WrapR == r) - return; - - flush(ctx); - samp->Attrib.WrapS = s; - samp->Attrib.WrapT = t; - samp->Attrib.WrapR = r; -} - #define INVALID_PARAM 0x100 #define INVALID_PNAME 0x101 #define INVALID_VALUE 0x102 -static inline GLboolean -is_wrap_gl_clamp(GLint param) -{ - return param == GL_CLAMP || param == GL_MIRROR_CLAMP_EXT; -} - static GLuint set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp, GLint param) @@ -551,9 +549,10 @@ set_sampler_wrap_s(struct gl_context *ctx, struct gl_sampler_object *samp, return GL_FALSE; if (validate_texture_wrap_mode(ctx, param)) { flush(ctx); - if (is_wrap_gl_clamp(samp->Attrib.WrapS) != is_wrap_gl_clamp(param)) - ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + update_sampler_gl_clamp(ctx, samp, is_wrap_gl_clamp(samp->Attrib.WrapS), is_wrap_gl_clamp(param), WRAP_S); samp->Attrib.WrapS = param; + samp->Attrib.state.wrap_s = wrap_to_gallium(param); + _mesa_lower_gl_clamp(ctx, samp); return GL_TRUE; } return INVALID_PARAM; @@ -568,9 +567,10 @@ set_sampler_wrap_t(struct gl_context *ctx, struct gl_sampler_object *samp, return GL_FALSE; if (validate_texture_wrap_mode(ctx, param)) { flush(ctx); - if (is_wrap_gl_clamp(samp->Attrib.WrapT) != is_wrap_gl_clamp(param)) - ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + update_sampler_gl_clamp(ctx, samp, is_wrap_gl_clamp(samp->Attrib.WrapT), is_wrap_gl_clamp(param), WRAP_T); samp->Attrib.WrapT = param; + samp->Attrib.state.wrap_t = wrap_to_gallium(param); + _mesa_lower_gl_clamp(ctx, samp); return GL_TRUE; } return INVALID_PARAM; @@ -585,36 +585,15 @@ set_sampler_wrap_r(struct gl_context *ctx, struct gl_sampler_object *samp, return GL_FALSE; if (validate_texture_wrap_mode(ctx, param)) { flush(ctx); - if (is_wrap_gl_clamp(samp->Attrib.WrapR) != is_wrap_gl_clamp(param)) - ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + update_sampler_gl_clamp(ctx, samp, is_wrap_gl_clamp(samp->Attrib.WrapR), is_wrap_gl_clamp(param), WRAP_R); samp->Attrib.WrapR = param; + samp->Attrib.state.wrap_r = wrap_to_gallium(param); + _mesa_lower_gl_clamp(ctx, samp); return GL_TRUE; } return INVALID_PARAM; } -void -_mesa_set_sampler_filters(struct gl_context *ctx, - struct gl_sampler_object *samp, - GLenum min_filter, GLenum mag_filter) -{ - assert(min_filter == GL_NEAREST || - min_filter == GL_LINEAR || - min_filter == GL_NEAREST_MIPMAP_NEAREST || - min_filter == GL_LINEAR_MIPMAP_NEAREST || - min_filter == GL_NEAREST_MIPMAP_LINEAR || - min_filter == GL_LINEAR_MIPMAP_LINEAR); - assert(mag_filter == GL_NEAREST || - mag_filter == GL_LINEAR); - - if (samp->Attrib.MinFilter == min_filter && samp->Attrib.MagFilter == mag_filter) - return; - - flush(ctx); - samp->Attrib.MinFilter = min_filter; - samp->Attrib.MagFilter = mag_filter; -} - static GLuint set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, GLint param) @@ -631,6 +610,9 @@ set_sampler_min_filter(struct gl_context *ctx, struct gl_sampler_object *samp, case GL_LINEAR_MIPMAP_LINEAR: flush(ctx); samp->Attrib.MinFilter = param; + samp->Attrib.state.min_img_filter = filter_to_gallium(param); + samp->Attrib.state.min_mip_filter = mipfilter_to_gallium(param); + _mesa_lower_gl_clamp(ctx, samp); return GL_TRUE; default: return INVALID_PARAM; @@ -650,6 +632,8 @@ set_sampler_mag_filter(struct gl_context *ctx, struct gl_sampler_object *samp, case GL_LINEAR: flush(ctx); samp->Attrib.MagFilter = param; + samp->Attrib.state.mag_img_filter = filter_to_gallium(param); + _mesa_lower_gl_clamp(ctx, samp); return GL_TRUE; default: return INVALID_PARAM; @@ -666,6 +650,7 @@ set_sampler_lod_bias(struct gl_context *ctx, struct gl_sampler_object *samp, flush(ctx); samp->Attrib.LodBias = param; + samp->Attrib.state.lod_bias = util_quantize_lod_bias(param); return GL_TRUE; } @@ -676,10 +661,8 @@ set_sampler_border_colorf(struct gl_context *ctx, const GLfloat params[4]) { flush(ctx); - samp->Attrib.BorderColor.f[RCOMP] = params[0]; - samp->Attrib.BorderColor.f[GCOMP] = params[1]; - samp->Attrib.BorderColor.f[BCOMP] = params[2]; - samp->Attrib.BorderColor.f[ACOMP] = params[3]; + memcpy(samp->Attrib.state.border_color.f, params, 4 * sizeof(float)); + _mesa_update_is_border_color_nonzero(samp); return GL_TRUE; } @@ -690,10 +673,8 @@ set_sampler_border_colori(struct gl_context *ctx, const GLint params[4]) { flush(ctx); - samp->Attrib.BorderColor.i[RCOMP] = params[0]; - samp->Attrib.BorderColor.i[GCOMP] = params[1]; - samp->Attrib.BorderColor.i[BCOMP] = params[2]; - samp->Attrib.BorderColor.i[ACOMP] = params[3]; + memcpy(samp->Attrib.state.border_color.i, params, 4 * sizeof(float)); + _mesa_update_is_border_color_nonzero(samp); return GL_TRUE; } @@ -704,10 +685,8 @@ set_sampler_border_colorui(struct gl_context *ctx, const GLuint params[4]) { flush(ctx); - samp->Attrib.BorderColor.ui[RCOMP] = params[0]; - samp->Attrib.BorderColor.ui[GCOMP] = params[1]; - samp->Attrib.BorderColor.ui[BCOMP] = params[2]; - samp->Attrib.BorderColor.ui[ACOMP] = params[3]; + memcpy(samp->Attrib.state.border_color.ui, params, 4 * sizeof(float)); + _mesa_update_is_border_color_nonzero(samp); return GL_TRUE; } @@ -721,6 +700,8 @@ set_sampler_min_lod(struct gl_context *ctx, struct gl_sampler_object *samp, flush(ctx); samp->Attrib.MinLod = param; + samp->Attrib.state.min_lod = MAX2(param, 0.0f); /* only positive */ + return GL_TRUE; } @@ -734,6 +715,7 @@ set_sampler_max_lod(struct gl_context *ctx, struct gl_sampler_object *samp, flush(ctx); samp->Attrib.MaxLod = param; + samp->Attrib.state.max_lod = param; return GL_TRUE; } @@ -788,6 +770,7 @@ set_sampler_compare_func(struct gl_context *ctx, case GL_NEVER: flush(ctx); samp->Attrib.CompareFunc = param; + samp->Attrib.state.compare_func = func_to_gallium(param); return GL_TRUE; default: return INVALID_PARAM; @@ -811,6 +794,9 @@ set_sampler_max_anisotropy(struct gl_context *ctx, flush(ctx); /* clamp to max, that's what NVIDIA does */ samp->Attrib.MaxAnisotropy = MIN2(param, ctx->Const.MaxTextureMaxAnisotropy); + /* gallium sets 0 for 1 */ + samp->Attrib.state.max_anisotropy = samp->Attrib.MaxAnisotropy == 1 ? + 0 : samp->Attrib.MaxAnisotropy; return GL_TRUE; } @@ -831,19 +817,10 @@ set_sampler_cube_map_seamless(struct gl_context *ctx, flush(ctx); samp->Attrib.CubeMapSeamless = param; + samp->Attrib.state.seamless_cube_map = param; return GL_TRUE; } -void -_mesa_set_sampler_srgb_decode(struct gl_context *ctx, - struct gl_sampler_object *samp, GLenum param) -{ - assert(param == GL_DECODE_EXT || param == GL_SKIP_DECODE_EXT); - - flush(ctx); - samp->Attrib.sRGBDecode = param; -} - static GLuint set_sampler_srgb_decode(struct gl_context *ctx, struct gl_sampler_object *samp, GLenum param) @@ -889,6 +866,7 @@ set_sampler_reduction_mode(struct gl_context *ctx, flush(ctx); samp->Attrib.ReductionMode = param; + samp->Attrib.state.reduction_mode = reduction_to_gallium(param); return GL_TRUE; } @@ -1513,12 +1491,10 @@ _mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params) *params = lroundf(sampObj->Attrib.MaxAnisotropy); break; case GL_TEXTURE_BORDER_COLOR: - if (!ctx->Extensions.ARB_texture_border_clamp) - goto invalid_pname; - params[0] = FLOAT_TO_INT(sampObj->Attrib.BorderColor.f[0]); - params[1] = FLOAT_TO_INT(sampObj->Attrib.BorderColor.f[1]); - params[2] = FLOAT_TO_INT(sampObj->Attrib.BorderColor.f[2]); - params[3] = FLOAT_TO_INT(sampObj->Attrib.BorderColor.f[3]); + params[0] = FLOAT_TO_INT(sampObj->Attrib.state.border_color.f[0]); + params[1] = FLOAT_TO_INT(sampObj->Attrib.state.border_color.f[1]); + params[2] = FLOAT_TO_INT(sampObj->Attrib.state.border_color.f[2]); + params[3] = FLOAT_TO_INT(sampObj->Attrib.state.border_color.f[3]); break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) @@ -1593,10 +1569,10 @@ _mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params) *params = sampObj->Attrib.MaxAnisotropy; break; case GL_TEXTURE_BORDER_COLOR: - params[0] = sampObj->Attrib.BorderColor.f[0]; - params[1] = sampObj->Attrib.BorderColor.f[1]; - params[2] = sampObj->Attrib.BorderColor.f[2]; - params[3] = sampObj->Attrib.BorderColor.f[3]; + params[0] = sampObj->Attrib.state.border_color.f[0]; + params[1] = sampObj->Attrib.state.border_color.f[1]; + params[2] = sampObj->Attrib.state.border_color.f[2]; + params[3] = sampObj->Attrib.state.border_color.f[3]; break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) @@ -1671,10 +1647,10 @@ _mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params) *params = (GLint) sampObj->Attrib.MaxAnisotropy; break; case GL_TEXTURE_BORDER_COLOR: - params[0] = sampObj->Attrib.BorderColor.i[0]; - params[1] = sampObj->Attrib.BorderColor.i[1]; - params[2] = sampObj->Attrib.BorderColor.i[2]; - params[3] = sampObj->Attrib.BorderColor.i[3]; + params[0] = sampObj->Attrib.state.border_color.i[0]; + params[1] = sampObj->Attrib.state.border_color.i[1]; + params[2] = sampObj->Attrib.state.border_color.i[2]; + params[3] = sampObj->Attrib.state.border_color.i[3]; break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) @@ -1749,10 +1725,10 @@ _mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params) *params = (GLuint) sampObj->Attrib.MaxAnisotropy; break; case GL_TEXTURE_BORDER_COLOR: - params[0] = sampObj->Attrib.BorderColor.ui[0]; - params[1] = sampObj->Attrib.BorderColor.ui[1]; - params[2] = sampObj->Attrib.BorderColor.ui[2]; - params[3] = sampObj->Attrib.BorderColor.ui[3]; + params[0] = sampObj->Attrib.state.border_color.ui[0]; + params[1] = sampObj->Attrib.state.border_color.ui[1]; + params[2] = sampObj->Attrib.state.border_color.ui[2]; + params[3] = sampObj->Attrib.state.border_color.ui[3]; break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: if (!ctx->Extensions.AMD_seamless_cubemap_per_texture) @@ -1779,10 +1755,3 @@ invalid_pname: _mesa_error(ctx, GL_INVALID_ENUM, "glGetSamplerParameterIuiv(pname=%s)", _mesa_enum_to_string(pname)); } - - -void -_mesa_init_sampler_object_functions(struct dd_function_table *driver) -{ - driver->NewSamplerObject = _mesa_new_sampler_object; -} diff --git a/src/mesa/main/samplerobj.h b/src/mesa/main/samplerobj.h index 2e9903352a2..eccde38e731 100644 --- a/src/mesa/main/samplerobj.h +++ b/src/mesa/main/samplerobj.h @@ -72,83 +72,140 @@ _mesa_reference_sampler_object(struct gl_context *ctx, extern struct gl_sampler_object * _mesa_lookup_samplerobj(struct gl_context *ctx, GLuint name); -extern struct gl_sampler_object * -_mesa_new_sampler_object(struct gl_context *ctx, GLuint name); - extern void -_mesa_init_sampler_object_functions(struct dd_function_table *driver); - -extern void -_mesa_set_sampler_wrap(struct gl_context *ctx, struct gl_sampler_object *samp, - GLenum s, GLenum t, GLenum r); +_mesa_bind_sampler(struct gl_context *ctx, GLuint unit, + struct gl_sampler_object *sampObj); -extern void -_mesa_set_sampler_filters(struct gl_context *ctx, - struct gl_sampler_object *samp, - GLenum min_filter, GLenum mag_filter); +extern const enum pipe_tex_wrap wrap_to_gallium_table[32]; -extern void -_mesa_set_sampler_srgb_decode(struct gl_context *ctx, - struct gl_sampler_object *samp, GLenum param); +/** + * Convert GLenum texcoord wrap tokens to pipe tokens. + */ +static inline enum pipe_tex_wrap +wrap_to_gallium(GLenum wrap) +{ + return wrap_to_gallium_table[wrap & 0x1f]; +} -extern void -_mesa_bind_sampler(struct gl_context *ctx, GLuint unit, - struct gl_sampler_object *sampObj); -void GLAPIENTRY -_mesa_GenSamplers_no_error(GLsizei count, GLuint *samplers); +static inline enum pipe_tex_mipfilter +mipfilter_to_gallium(GLenum filter) +{ + /* Take advantage of how the enums are defined. */ + if (filter <= GL_LINEAR) + return PIPE_TEX_MIPFILTER_NONE; + if (filter <= GL_LINEAR_MIPMAP_NEAREST) + return PIPE_TEX_MIPFILTER_NEAREST; -void GLAPIENTRY -_mesa_GenSamplers(GLsizei count, GLuint *samplers); + return PIPE_TEX_MIPFILTER_LINEAR; +} -void GLAPIENTRY -_mesa_CreateSamplers_no_error(GLsizei count, GLuint *samplers); -void GLAPIENTRY -_mesa_CreateSamplers(GLsizei count, GLuint *samplers); +static inline enum pipe_tex_filter +filter_to_gallium(GLenum filter) +{ + /* Take advantage of how the enums are defined. */ + if (filter & 1) + return PIPE_TEX_FILTER_LINEAR; -void GLAPIENTRY -_mesa_DeleteSamplers_no_error(GLsizei count, const GLuint *samplers); + return PIPE_TEX_FILTER_NEAREST; +} -void GLAPIENTRY -_mesa_DeleteSamplers(GLsizei count, const GLuint *samplers); +static inline enum pipe_tex_reduction_mode +reduction_to_gallium(GLenum reduction_mode) +{ + switch (reduction_mode) { + case GL_MIN: + return PIPE_TEX_REDUCTION_MIN; + case GL_MAX: + return PIPE_TEX_REDUCTION_MAX; + case GL_WEIGHTED_AVERAGE_EXT: + default: + return PIPE_TEX_REDUCTION_WEIGHTED_AVERAGE; + } +} -GLboolean GLAPIENTRY -_mesa_IsSampler(GLuint sampler); +/** + * Convert an OpenGL compare mode to a pipe tokens. + */ +static inline enum pipe_compare_func +func_to_gallium(GLenum func) +{ + /* Same values, just biased */ + STATIC_ASSERT(PIPE_FUNC_NEVER == GL_NEVER - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_LESS == GL_LESS - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_EQUAL == GL_EQUAL - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_LEQUAL == GL_LEQUAL - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_GREATER == GL_GREATER - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_NOTEQUAL == GL_NOTEQUAL - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_GEQUAL == GL_GEQUAL - GL_NEVER); + STATIC_ASSERT(PIPE_FUNC_ALWAYS == GL_ALWAYS - GL_NEVER); + assert(func >= GL_NEVER); + assert(func <= GL_ALWAYS); + return (enum pipe_compare_func)(func - GL_NEVER); +} -void GLAPIENTRY -_mesa_BindSampler_no_error(GLuint unit, GLuint sampler); +static inline void +_mesa_update_is_border_color_nonzero(struct gl_sampler_object *samp) +{ + samp->Attrib.IsBorderColorNonZero = samp->Attrib.state.border_color.ui[0] || + samp->Attrib.state.border_color.ui[1] || + samp->Attrib.state.border_color.ui[2] || + samp->Attrib.state.border_color.ui[3]; +} -void GLAPIENTRY -_mesa_BindSampler(GLuint unit, GLuint sampler); +static inline enum pipe_tex_wrap +lower_gl_clamp(enum pipe_tex_wrap old_wrap, GLenum wrap, bool clamp_to_border) +{ + if (wrap == GL_CLAMP) + return clamp_to_border ? PIPE_TEX_WRAP_CLAMP_TO_BORDER : + PIPE_TEX_WRAP_CLAMP_TO_EDGE; + else if (wrap == GL_MIRROR_CLAMP_EXT) + return clamp_to_border ? PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER : + PIPE_TEX_WRAP_MIRROR_CLAMP_TO_EDGE; + return old_wrap; +} -void GLAPIENTRY -_mesa_BindSamplers_no_error(GLuint first, GLsizei count, const GLuint *samplers); +static inline void +_mesa_lower_gl_clamp(struct gl_context *ctx, struct gl_sampler_object *samp) +{ + if (ctx->DriverFlags.NewSamplersWithClamp) { + struct pipe_sampler_state *s = &samp->Attrib.state; + bool clamp_to_border = s->min_img_filter != PIPE_TEX_FILTER_NEAREST && + s->mag_img_filter != PIPE_TEX_FILTER_NEAREST; + + s->wrap_s = lower_gl_clamp((enum pipe_tex_wrap)s->wrap_s, + samp->Attrib.WrapS, clamp_to_border); + s->wrap_t = lower_gl_clamp((enum pipe_tex_wrap)s->wrap_t, + samp->Attrib.WrapT, clamp_to_border); + s->wrap_r = lower_gl_clamp((enum pipe_tex_wrap)s->wrap_r, + samp->Attrib.WrapR, clamp_to_border); + } +} -void GLAPIENTRY -_mesa_BindSamplers(GLuint first, GLsizei count, const GLuint *samplers); +static inline GLboolean +is_wrap_gl_clamp(GLint param) +{ + return param == GL_CLAMP || param == GL_MIRROR_CLAMP_EXT; +} -void GLAPIENTRY -_mesa_SamplerParameteri(GLuint sampler, GLenum pname, GLint param); -void GLAPIENTRY -_mesa_SamplerParameterf(GLuint sampler, GLenum pname, GLfloat param); -void GLAPIENTRY -_mesa_SamplerParameteriv(GLuint sampler, GLenum pname, const GLint *params); -void GLAPIENTRY -_mesa_SamplerParameterfv(GLuint sampler, GLenum pname, const GLfloat *params); -void GLAPIENTRY -_mesa_SamplerParameterIiv(GLuint sampler, GLenum pname, const GLint *params); -void GLAPIENTRY -_mesa_SamplerParameterIuiv(GLuint sampler, GLenum pname, const GLuint *params); -void GLAPIENTRY -_mesa_GetSamplerParameteriv(GLuint sampler, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetSamplerParameterfv(GLuint sampler, GLenum pname, GLfloat *params); -void GLAPIENTRY -_mesa_GetSamplerParameterIiv(GLuint sampler, GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetSamplerParameterIuiv(GLuint sampler, GLenum pname, GLuint *params); +static inline void +update_sampler_gl_clamp(struct gl_context *ctx, struct gl_sampler_object *samp, bool cur_state, bool new_state, gl_sampler_wrap wrap) +{ + if (cur_state == new_state) + return; + ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + uint8_t old_mask = samp->glclamp_mask; + if (new_state) + samp->glclamp_mask |= wrap; + else + samp->glclamp_mask &= ~wrap; + if (old_mask && !samp->glclamp_mask) + ctx->Texture.NumSamplersWithClamp--; + else if (samp->glclamp_mask && !old_mask) + ctx->Texture.NumSamplersWithClamp++; +} #ifdef __cplusplus } #endif diff --git a/src/mesa/main/scissor.c b/src/mesa/main/scissor.c index df7b3363d20..a3bf2ae15ce 100644 --- a/src/mesa/main/scissor.c +++ b/src/mesa/main/scissor.c @@ -23,12 +23,15 @@ */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/enums.h" #include "main/mtypes.h" #include "main/scissor.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_bitmap.h" +#include "state_tracker/st_context.h" /** * Set scissor rectangle data directly in ScissorArray @@ -48,9 +51,8 @@ set_scissor_no_notify(struct gl_context *ctx, unsigned idx, height == ctx->Scissor.ScissorArray[idx].Height) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewScissorRect ? 0 : _NEW_SCISSOR, - GL_SCISSOR_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewScissorRect; + FLUSH_VERTICES(ctx, 0, GL_SCISSOR_BIT); + ctx->NewDriverState |= ST_NEW_SCISSOR; ctx->Scissor.ScissorArray[idx].X = x; ctx->Scissor.ScissorArray[idx].Y = y; @@ -77,9 +79,6 @@ scissor(struct gl_context *ctx, GLint x, GLint y, GLsizei width, GLsizei height) */ for (i = 0; i < ctx->Const.MaxViewports; i++) set_scissor_no_notify(ctx, i, x, y, width, height); - - if (ctx->Driver.Scissor) - ctx->Driver.Scissor(ctx); } /** @@ -127,9 +126,6 @@ _mesa_set_scissor(struct gl_context *ctx, unsigned idx, GLint x, GLint y, GLsizei width, GLsizei height) { set_scissor_no_notify(ctx, idx, x, y, width, height); - - if (ctx->Driver.Scissor) - ctx->Driver.Scissor(ctx); } static void @@ -140,9 +136,6 @@ scissor_array(struct gl_context *ctx, GLuint first, GLsizei count, set_scissor_no_notify(ctx, i + first, rect[i].X, rect[i].Y, rect[i].Width, rect[i].Height); } - - if (ctx->Driver.Scissor) - ctx->Driver.Scissor(ctx); } /** @@ -302,8 +295,10 @@ _mesa_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box) box += 4; } + st_flush_bitmap_cache(st_context(ctx)); + FLUSH_VERTICES(ctx, 0, GL_SCISSOR_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewWindowRectangles; + ctx->NewDriverState |= ST_NEW_WINDOW_RECTANGLES; memcpy(ctx->Scissor.WindowRects, newval, sizeof(struct gl_scissor_rect) * count); diff --git a/src/mesa/main/scissor.h b/src/mesa/main/scissor.h index 264873eaf1d..e590747d700 100644 --- a/src/mesa/main/scissor.h +++ b/src/mesa/main/scissor.h @@ -27,38 +27,10 @@ #define SCISSOR_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -void GLAPIENTRY -_mesa_Scissor_no_error(GLint x, GLint y, GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_Scissor( GLint x, GLint y, GLsizei width, GLsizei height ); - -void GLAPIENTRY -_mesa_ScissorArrayv_no_error(GLuint first, GLsizei count, const GLint * v); - -extern void GLAPIENTRY -_mesa_ScissorArrayv(GLuint first, GLsizei count, const GLint * v); - -void GLAPIENTRY -_mesa_ScissorIndexed_no_error(GLuint index, GLint left, GLint bottom, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_ScissorIndexed(GLuint index, GLint left, GLint bottom, GLsizei width, GLsizei height); - -void GLAPIENTRY -_mesa_ScissorIndexedv_no_error(GLuint index, const GLint * v); - -extern void GLAPIENTRY -_mesa_ScissorIndexedv(GLuint index, const GLint * v); - -extern void GLAPIENTRY -_mesa_WindowRectanglesEXT(GLenum mode, GLsizei count, const GLint *box); - extern void _mesa_set_scissor(struct gl_context *ctx, unsigned idx, GLint x, GLint y, GLsizei width, GLsizei height); diff --git a/src/mesa/main/shader_query.cpp b/src/mesa/main/shader_query.cpp index 8c44d3eaeba..aec39fb145c 100644 --- a/src/mesa/main/shader_query.cpp +++ b/src/mesa/main/shader_query.cpp @@ -35,9 +35,11 @@ #include "main/uniforms.h" #include "compiler/glsl/glsl_symbol_table.h" #include "compiler/glsl/ir.h" -#include "compiler/glsl/program.h" +#include "compiler/glsl/linker_util.h" #include "compiler/glsl/string_to_uint_map.h" #include "util/mesa-sha1.h" +#include "c99_alloca.h" +#include "api_exec_decl.h" static GLint program_resource_location(struct gl_program_resource *res, @@ -62,8 +64,11 @@ DECL_RESOURCE_FUNC(XFB, gl_transform_feedback_buffer); DECL_RESOURCE_FUNC(SUB, gl_subroutine_function); static GLenum -mediump_to_highp_type(GLenum type) +mediump_to_highp_type(struct gl_shader_program *shProg, GLenum type) { + if (!shProg->IsES) + return type; + switch (type) { case GL_FLOAT16_NV: return GL_FLOAT; @@ -195,7 +200,7 @@ _mesa_GetActiveAttrib(GLuint program, GLuint desired_index, const gl_shader_variable *const var = RESOURCE_VAR(res); - const char *var_name = var->name; + const char *var_name = var->name.string; _mesa_copy_string(name, maxLength, length, var_name); @@ -286,8 +291,7 @@ _mesa_longest_attribute_name_length(struct gl_shader_program *shProg) * returned. If no active attributes exist, zero is returned. If * no name reflection information is available, one is returned." */ - const size_t length = RESOURCE_VAR(res)->name != NULL ? - strlen(RESOURCE_VAR(res)->name) : 0; + const size_t length = RESOURCE_VAR(res)->name.length; if (length >= longest) longest = length + 1; @@ -409,12 +413,6 @@ _mesa_GetFragDataIndex(GLuint program, const GLchar *name) if (!name) return -1; - if (strncmp(name, "gl_", 3) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetFragDataIndex(illegal name)"); - return -1; - } - /* Not having a fragment shader is not an error. */ if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) @@ -444,12 +442,6 @@ _mesa_GetFragDataLocation(GLuint program, const GLchar *name) if (!name) return -1; - if (strncmp(name, "gl_", 3) == 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetFragDataLocation(illegal name)"); - return -1; - } - /* Not having a fragment shader is not an error. */ if (shProg->_LinkedShaders[MESA_SHADER_FRAGMENT] == NULL) @@ -472,35 +464,113 @@ _mesa_program_resource_name(struct gl_program_resource *res) switch (res->Type) { case GL_UNIFORM_BLOCK: case GL_SHADER_STORAGE_BLOCK: - return RESOURCE_UBO(res)->Name; + return RESOURCE_UBO(res)->name.string; case GL_TRANSFORM_FEEDBACK_VARYING: - return RESOURCE_XFV(res)->Name; + return RESOURCE_XFV(res)->name.string; case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: - return RESOURCE_VAR(res)->name; + return RESOURCE_VAR(res)->name.string; case GL_UNIFORM: case GL_BUFFER_VARIABLE: - return RESOURCE_UNI(res)->name; + return RESOURCE_UNI(res)->name.string; case GL_VERTEX_SUBROUTINE_UNIFORM: case GL_GEOMETRY_SUBROUTINE_UNIFORM: case GL_FRAGMENT_SUBROUTINE_UNIFORM: case GL_COMPUTE_SUBROUTINE_UNIFORM: case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: - return RESOURCE_UNI(res)->name + MESA_SUBROUTINE_PREFIX_LEN; + return RESOURCE_UNI(res)->name.string + MESA_SUBROUTINE_PREFIX_LEN; case GL_VERTEX_SUBROUTINE: case GL_GEOMETRY_SUBROUTINE: case GL_FRAGMENT_SUBROUTINE: case GL_COMPUTE_SUBROUTINE: case GL_TESS_CONTROL_SUBROUTINE: case GL_TESS_EVALUATION_SUBROUTINE: - return RESOURCE_SUB(res)->name; + return RESOURCE_SUB(res)->name.string; default: break; } return NULL; } +int +_mesa_program_resource_name_length(struct gl_program_resource *res) +{ + switch (res->Type) { + case GL_UNIFORM_BLOCK: + case GL_SHADER_STORAGE_BLOCK: + return RESOURCE_UBO(res)->name.length; + case GL_TRANSFORM_FEEDBACK_VARYING: + return RESOURCE_XFV(res)->name.length; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + return RESOURCE_VAR(res)->name.length; + case GL_UNIFORM: + case GL_BUFFER_VARIABLE: + return RESOURCE_UNI(res)->name.length; + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + return RESOURCE_UNI(res)->name.length - MESA_SUBROUTINE_PREFIX_LEN; + case GL_VERTEX_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + return RESOURCE_SUB(res)->name.length; + default: + break; + } + return 0; +} + +bool +_mesa_program_get_resource_name(struct gl_program_resource *res, + struct gl_resource_name *out) +{ + switch (res->Type) { + case GL_UNIFORM_BLOCK: + case GL_SHADER_STORAGE_BLOCK: + *out = RESOURCE_UBO(res)->name; + return out->string != NULL; + case GL_TRANSFORM_FEEDBACK_VARYING: + *out = RESOURCE_XFV(res)->name; + return out->string != NULL; + case GL_PROGRAM_INPUT: + case GL_PROGRAM_OUTPUT: + *out = RESOURCE_VAR(res)->name; + return out->string != NULL; + case GL_UNIFORM: + case GL_BUFFER_VARIABLE: + *out = RESOURCE_UNI(res)->name; + return out->string != NULL; + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: + *out = RESOURCE_UNI(res)->name; + out->string += MESA_SUBROUTINE_PREFIX_LEN; + out->length -= MESA_SUBROUTINE_PREFIX_LEN; + assert(out->string); /* always non-NULL */ + return true; + case GL_VERTEX_SUBROUTINE: + case GL_GEOMETRY_SUBROUTINE: + case GL_FRAGMENT_SUBROUTINE: + case GL_COMPUTE_SUBROUTINE: + case GL_TESS_CONTROL_SUBROUTINE: + case GL_TESS_EVALUATION_SUBROUTINE: + *out = RESOURCE_SUB(res)->name; + return out->string != NULL; + default: + return false; + } +} unsigned _mesa_program_resource_array_size(struct gl_program_resource *res) @@ -547,12 +617,12 @@ _mesa_program_resource_array_size(struct gl_program_resource *res) * Checks if array subscript is valid and if so sets array_index. */ static bool -valid_array_index(const GLchar *name, unsigned *array_index) +valid_array_index(const GLchar *name, int len, unsigned *array_index) { long idx = 0; const GLchar *out_base_name_end; - idx = parse_program_resource_name(name, strlen(name), &out_base_name_end); + idx = link_util_parse_program_resource_name(name, len, &out_base_name_end); if (idx < 0) return false; @@ -562,25 +632,24 @@ valid_array_index(const GLchar *name, unsigned *array_index) return true; } -static uint32_t -compute_resource_key(GLenum programInterface, const char *name, size_t len) -{ - return _mesa_hash_data_with_seed(name, len, programInterface + len); -} - static struct gl_program_resource * search_resource_hash(struct gl_shader_program *shProg, - GLenum programInterface, const char *name, + GLenum programInterface, const char *name, int len, unsigned *array_index) { + unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(programInterface); + assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash)); + + if (!shProg->data->ProgramResourceHash[type]) + return NULL; + const char *base_name_end; - size_t len = strlen(name); - long index = parse_program_resource_name(name, len, &base_name_end); + long index = link_util_parse_program_resource_name(name, len, &base_name_end); char *name_copy; /* If dealing with array, we need to get the basename. */ if (index >= 0) { - name_copy = (char *) malloc(base_name_end - name + 1); + name_copy = (char *) alloca(base_name_end - name + 1); memcpy(name_copy, name, base_name_end - name); name_copy[base_name_end - name] = '\0'; len = base_name_end - name; @@ -588,17 +657,17 @@ search_resource_hash(struct gl_shader_program *shProg, name_copy = (char*) name; } - uint32_t key = compute_resource_key(programInterface, name_copy, len); - struct gl_program_resource *res = (struct gl_program_resource *) - _mesa_hash_table_u64_search(shProg->data->ProgramResourceHash, key); - - if (name_copy != name) - free(name_copy); + uint32_t hash = _mesa_hash_string_with_length(name_copy, len); + struct hash_entry *entry = + _mesa_hash_table_search_pre_hashed(shProg->data->ProgramResourceHash[type], + hash, name_copy); + if (!entry) + return NULL; - if (res && array_index) + if (array_index) *array_index = index >= 0 ? index : 0; - return res; + return (struct gl_program_resource *)entry->data; } /* Find a program resource with specific name in given interface. @@ -608,14 +677,14 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, GLenum programInterface, const char *name, unsigned *array_index) { - struct gl_program_resource *res = NULL; - if (name == NULL) return NULL; + int len = strlen(name); + /* If we have a name, try the ProgramResourceHash first. */ - if (shProg->data->ProgramResourceHash) - res = search_resource_hash(shProg, programInterface, name, array_index); + struct gl_program_resource *res = + search_resource_hash(shProg, programInterface, name, len, array_index); if (res) return res; @@ -625,18 +694,14 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, if (res->Type != programInterface) continue; - /* Resource basename. */ - const char *rname = _mesa_program_resource_name(res); + struct gl_resource_name rname; /* Since ARB_gl_spirv lack of name reflections is a possibility */ - if (rname == NULL) + if (!_mesa_program_get_resource_name(res, &rname)) continue; - unsigned baselen = strlen(rname); - unsigned baselen_without_array_index = baselen; - const char *rname_last_square_bracket = strrchr(rname, '['); bool found = false; - bool rname_has_array_index_zero = false; + /* From ARB_program_interface_query spec: * * "uint GetProgramResourceIndex(uint program, enum programInterface, @@ -662,17 +727,15 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, * array's index is zero and the resulting string length is the same * than the provided name's length. */ - if (rname_last_square_bracket) { - baselen_without_array_index -= strlen(rname_last_square_bracket); - rname_has_array_index_zero = - (strcmp(rname_last_square_bracket, "[0]") == 0) && - (baselen_without_array_index == strlen(name)); - } + int length_without_array_index = + rname.last_square_bracket >= 0 ? rname.last_square_bracket : rname.length; + bool rname_has_array_index_zero = rname.suffix_is_zero_square_bracketed && + rname.last_square_bracket == len; - if (strncmp(rname, name, baselen) == 0) + if (len >= rname.length && strncmp(rname.string, name, rname.length) == 0) found = true; else if (rname_has_array_index_zero && - strncmp(rname, name, baselen_without_array_index) == 0) + strncmp(rname.string, name, length_without_array_index) == 0) found = true; if (found) { @@ -681,9 +744,9 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, case GL_SHADER_STORAGE_BLOCK: /* Basename match, check if array or struct. */ if (rname_has_array_index_zero || - name[baselen] == '\0' || - name[baselen] == '[' || - name[baselen] == '.') { + name[rname.length] == '\0' || + name[rname.length] == '[' || + name[rname.length] == '.') { return res; } break; @@ -702,16 +765,16 @@ _mesa_program_resource_find_name(struct gl_shader_program *shProg, case GL_COMPUTE_SUBROUTINE: case GL_TESS_CONTROL_SUBROUTINE: case GL_TESS_EVALUATION_SUBROUTINE: - if (name[baselen] == '.') { + if (name[rname.length] == '.') { return res; } FALLTHROUGH; case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: - if (name[baselen] == '\0') { + if (name[rname.length] == '\0') { return res; - } else if (name[baselen] == '[' && - valid_array_index(name, array_index)) { + } else if (name[rname.length] == '[' && + valid_array_index(name, len, array_index)) { return res; } break; @@ -974,17 +1037,16 @@ add_index_to_name(struct gl_program_resource *res) * base name + 3 for '[0]' if resource is an array. */ extern unsigned -_mesa_program_resource_name_len(struct gl_program_resource *res) +_mesa_program_resource_name_length_array(struct gl_program_resource *res) { - const char* name = _mesa_program_resource_name(res); + int length = _mesa_program_resource_name_length(res); /* For shaders constructed from SPIR-V binaries, variables may not * have names associated with them. */ - if (!name) + if (!length) return 0; - unsigned length = strlen(name); if (_mesa_program_resource_array_size(res) && add_index_to_name(res)) length += 3; return length; @@ -1063,7 +1125,7 @@ program_resource_location(struct gl_program_resource *res, unsigned array_index) return -1; } return var->location + - (array_index * var->type->without_array()->matrix_columns); + (array_index * glsl_without_array(var->type)->matrix_columns); } case GL_PROGRAM_OUTPUT: if (RESOURCE_VAR(res)->location == -1) @@ -1085,7 +1147,7 @@ program_resource_location(struct gl_program_resource *res, unsigned array_index) * "A valid name cannot be a structure, an array of structures, or any * portion of a single vector or a matrix." */ - if (RESOURCE_UNI(res)->type->without_array()->is_struct()) + if (glsl_type_is_struct(glsl_without_array(RESOURCE_UNI(res)->type))) return -1; /* From the GL_ARB_uniform_buffer_object spec: @@ -1399,7 +1461,7 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg, goto invalid_operation; default: /* Resource name length + terminator. */ - *val = _mesa_program_resource_name_len(res) + 1; + *val = _mesa_program_resource_name_length_array(res) + 1; } return 1; case GL_TYPE: @@ -1407,16 +1469,16 @@ _mesa_program_resource_prop(struct gl_shader_program *shProg, case GL_UNIFORM: case GL_BUFFER_VARIABLE: *val = RESOURCE_UNI(res)->type->gl_type; - *val = mediump_to_highp_type(*val); + *val = mediump_to_highp_type(shProg, *val); return 1; case GL_PROGRAM_INPUT: case GL_PROGRAM_OUTPUT: *val = RESOURCE_VAR(res)->type->gl_type; - *val = mediump_to_highp_type(*val); + *val = mediump_to_highp_type(shProg, *val); return 1; case GL_TRANSFORM_FEEDBACK_VARYING: *val = RESOURCE_XFV(res)->Type; - *val = mediump_to_highp_type(*val); + *val = mediump_to_highp_type(shProg, *val); return 1; default: goto invalid_operation; @@ -1680,6 +1742,135 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg, *length = amount; } +extern void +_mesa_get_program_interfaceiv(struct gl_shader_program *shProg, + GLenum programInterface, GLenum pname, + GLint *params) +{ + GET_CURRENT_CONTEXT(ctx); + unsigned i; + + /* Validate pname against interface. */ + switch(pname) { + case GL_ACTIVE_RESOURCES: + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) + if (shProg->data->ProgramResourceList[i].Type == programInterface) + (*params)++; + break; + case GL_MAX_NAME_LENGTH: + if (programInterface == GL_ATOMIC_COUNTER_BUFFER || + programInterface == GL_TRANSFORM_FEEDBACK_BUFFER) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_enum_to_string(programInterface), + _mesa_enum_to_string(pname)); + return; + } + /* Name length consists of base name, 3 additional chars '[0]' if + * resource is an array and finally 1 char for string terminator. + */ + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { + if (shProg->data->ProgramResourceList[i].Type != programInterface) + continue; + unsigned len = + _mesa_program_resource_name_length_array(&shProg->data->ProgramResourceList[i]); + *params = MAX2((unsigned)*params, len + 1); + } + break; + case GL_MAX_NUM_ACTIVE_VARIABLES: + switch (programInterface) { + case GL_UNIFORM_BLOCK: + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { + if (shProg->data->ProgramResourceList[i].Type == programInterface) { + struct gl_uniform_block *block = + (struct gl_uniform_block *) + shProg->data->ProgramResourceList[i].Data; + *params = MAX2((unsigned)*params, block->NumUniforms); + } + } + break; + case GL_SHADER_STORAGE_BLOCK: + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { + if (shProg->data->ProgramResourceList[i].Type == programInterface) { + struct gl_uniform_block *block = + (struct gl_uniform_block *) + shProg->data->ProgramResourceList[i].Data; + GLint block_params = 0; + for (unsigned j = 0; j < block->NumUniforms; j++) { + struct gl_program_resource *uni = + _mesa_program_resource_find_active_variable( + shProg, + GL_BUFFER_VARIABLE, + block, + j); + if (!uni) + continue; + block_params++; + } + *params = MAX2(*params, block_params); + } + } + break; + case GL_ATOMIC_COUNTER_BUFFER: + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { + if (shProg->data->ProgramResourceList[i].Type == programInterface) { + struct gl_active_atomic_buffer *buffer = + (struct gl_active_atomic_buffer *) + shProg->data->ProgramResourceList[i].Data; + *params = MAX2((unsigned)*params, buffer->NumUniforms); + } + } + break; + case GL_TRANSFORM_FEEDBACK_BUFFER: + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { + if (shProg->data->ProgramResourceList[i].Type == programInterface) { + struct gl_transform_feedback_buffer *buffer = + (struct gl_transform_feedback_buffer *) + shProg->data->ProgramResourceList[i].Data; + *params = MAX2((unsigned)*params, buffer->NumVaryings); + } + } + break; + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_enum_to_string(programInterface), + _mesa_enum_to_string(pname)); + } + break; + case GL_MAX_NUM_COMPATIBLE_SUBROUTINES: + switch (programInterface) { + case GL_VERTEX_SUBROUTINE_UNIFORM: + case GL_FRAGMENT_SUBROUTINE_UNIFORM: + case GL_GEOMETRY_SUBROUTINE_UNIFORM: + case GL_COMPUTE_SUBROUTINE_UNIFORM: + case GL_TESS_CONTROL_SUBROUTINE_UNIFORM: + case GL_TESS_EVALUATION_SUBROUTINE_UNIFORM: { + for (i = 0, *params = 0; i < shProg->data->NumProgramResourceList; i++) { + if (shProg->data->ProgramResourceList[i].Type == programInterface) { + struct gl_uniform_storage *uni = + (struct gl_uniform_storage *) + shProg->data->ProgramResourceList[i].Data; + *params = MAX2((unsigned)*params, uni->num_compatible_subroutines); + } + } + break; + } + + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(%s pname %s)", + _mesa_enum_to_string(programInterface), + _mesa_enum_to_string(pname)); + } + break; + default: + _mesa_error(ctx, GL_INVALID_OPERATION, + "glGetProgramInterfaceiv(pname %s)", + _mesa_enum_to_string(pname)); + } +} + static bool validate_io(struct gl_program *producer, struct gl_program *consumer) { @@ -1733,7 +1924,7 @@ validate_io(struct gl_program *producer, struct gl_program *consumer) * * Built-in inputs or outputs do not affect interface matching. */ - if (is_gl_identifier(var->name)) + if (is_gl_identifier(var->name.string)) continue; outputs[num_outputs++] = var; @@ -1750,7 +1941,7 @@ validate_io(struct gl_program *producer, struct gl_program *consumer) gl_shader_variable const *const consumer_var = RESOURCE_VAR(res); gl_shader_variable const *producer_var = NULL; - if (is_gl_identifier(consumer_var->name)) + if (is_gl_identifier(consumer_var->name.string)) continue; /* Inputs with explicit locations match other outputs with explicit @@ -1772,7 +1963,7 @@ validate_io(struct gl_program *producer, struct gl_program *consumer) const gl_shader_variable *const var = outputs[j]; if (!var->explicit_location && - strcmp(consumer_var->name, var->name) == 0) { + strcmp(consumer_var->name.string, var->name.string) == 0) { producer_var = var; match_index = j; break; @@ -1825,10 +2016,10 @@ validate_io(struct gl_program *producer, struct gl_program *consumer) if (consumer_is_array_stage) { if (consumer_interface_type) { /* the interface is the array; the underlying types should match */ - if (consumer_interface_type->is_array() && !consumer_var->patch) + if (glsl_type_is_array(consumer_interface_type) && !consumer_var->patch) consumer_interface_type = consumer_interface_type->fields.array; } else { - if (consumer_type->is_array() && !consumer_var->patch) + if (glsl_type_is_array(consumer_type) && !consumer_var->patch) consumer_type = consumer_type->fields.array; } } @@ -1836,10 +2027,10 @@ validate_io(struct gl_program *producer, struct gl_program *consumer) if (producer_is_array_stage) { if (producer_interface_type) { /* the interface is the array; the underlying types should match */ - if (producer_interface_type->is_array() && !producer_var->patch) + if (glsl_type_is_array(producer_interface_type) && !producer_var->patch) producer_interface_type = producer_interface_type->fields.array; } else { - if (producer_type->is_array() && !producer_var->patch) + if (glsl_type_is_array(producer_type) && !producer_var->patch) producer_type = producer_type->fields.array; } } @@ -1947,21 +2138,37 @@ _mesa_validate_pipeline_io(struct gl_pipeline_object *pipeline) } extern "C" void +_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg) +{ + for (unsigned i = 0; i < ARRAY_SIZE(shProg->data->ProgramResourceHash); i++) { + if (shProg->data->ProgramResourceHash[i]) { + _mesa_hash_table_destroy(shProg->data->ProgramResourceHash[i], NULL); + shProg->data->ProgramResourceHash[i] = NULL; + } + } +} + +extern "C" void _mesa_create_program_resource_hash(struct gl_shader_program *shProg) { /* Rebuild resource hash. */ - if (shProg->data->ProgramResourceHash) - _mesa_hash_table_u64_destroy(shProg->data->ProgramResourceHash); - - shProg->data->ProgramResourceHash = _mesa_hash_table_u64_create(shProg); + _mesa_program_resource_hash_destroy(shProg); struct gl_program_resource *res = shProg->data->ProgramResourceList; for (unsigned i = 0; i < shProg->data->NumProgramResourceList; i++, res++) { - const char *name = _mesa_program_resource_name(res); - if (name) { - uint32_t key = compute_resource_key(res->Type, name, strlen(name)); - _mesa_hash_table_u64_insert(shProg->data->ProgramResourceHash, key, - res); + struct gl_resource_name name; + if (_mesa_program_get_resource_name(res, &name)) { + unsigned type = GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(res->Type); + assert(type < ARRAY_SIZE(shProg->data->ProgramResourceHash)); + + if (!shProg->data->ProgramResourceHash[type]) { + shProg->data->ProgramResourceHash[type] = + _mesa_hash_table_create(shProg, _mesa_hash_string, + _mesa_key_string_equal); + } + + _mesa_hash_table_insert(shProg->data->ProgramResourceHash[type], + name.string, res); } } } diff --git a/src/mesa/main/shader_types.h b/src/mesa/main/shader_types.h new file mode 100644 index 00000000000..aa02f0dabfd --- /dev/null +++ b/src/mesa/main/shader_types.h @@ -0,0 +1,1009 @@ +/* + * Mesa 3-D graphics library + * + * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. + * Copyright (C) 2009 VMware, Inc. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/** + * \file shader_types.h + * All the GL shader/program types. + */ + +#ifndef SHADER_TYPES_H +#define SHADER_TYPES_H + +#include "main/config.h" /* for MAX_FEEDBACK_BUFFERS */ +#include "util/glheader.h" +#include "main/menums.h" +#include "util/mesa-sha1.h" +#include "compiler/shader_info.h" +#include "compiler/glsl/list.h" +#include "compiler/glsl/ir_uniform.h" + +#include "pipe/p_state.h" + +/** + * Shader information needed by both gl_shader and gl_linked shader. + */ +struct gl_shader_info +{ + /** + * Tessellation Control shader state from layout qualifiers. + */ + struct { + /** + * 0 - vertices not declared in shader, or + * 1 .. GL_MAX_PATCH_VERTICES + */ + GLint VerticesOut; + } TessCtrl; + + /** + * Tessellation Evaluation shader state from layout qualifiers. + */ + struct { + enum tess_primitive_mode _PrimitiveMode; + + enum gl_tess_spacing Spacing; + + /** + * GL_CW, GL_CCW, or 0 if it's not set in this shader. + */ + GLenum16 VertexOrder; + /** + * 1, 0, or -1 if it's not set in this shader. + */ + int PointMode; + } TessEval; + + /** + * Geometry shader state from GLSL 1.50 layout qualifiers. + */ + struct { + GLint VerticesOut; + /** + * 0 - Invocations count not declared in shader, or + * 1 .. Const.MaxGeometryShaderInvocations + */ + GLint Invocations; + /** + * GL_POINTS, GL_LINES, GL_LINES_ADJACENCY, GL_TRIANGLES, or + * GL_TRIANGLES_ADJACENCY, or PRIM_UNKNOWN if it's not set in this + * shader. + */ + enum mesa_prim InputType; + /** + * GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP, or PRIM_UNKNOWN if + * it's not set in this shader. + */ + enum mesa_prim OutputType; + } Geom; + + /** + * Compute shader state from ARB_compute_shader and + * ARB_compute_variable_group_size layout qualifiers. + */ + struct { + /** + * Size specified using local_size_{x,y,z}, or all 0's to indicate that + * it's not set in this shader. + */ + unsigned LocalSize[3]; + + /** + * Whether a variable work group size has been specified as defined by + * ARB_compute_variable_group_size. + */ + bool LocalSizeVariable; + + /* + * Arrangement of invocations used to calculate derivatives in a compute + * shader. From NV_compute_shader_derivatives. + */ + enum gl_derivative_group DerivativeGroup; + } Comp; +}; + +/** + * Compile status enum. COMPILE_SKIPPED is used to indicate the compile + * was skipped due to the shader matching one that's been seen before by + * the on-disk cache. + */ +enum gl_compile_status +{ + COMPILE_FAILURE = 0, + COMPILE_SUCCESS, + COMPILE_SKIPPED +}; + +/** + * A GLSL shader object. + */ +struct gl_shader +{ + /** GL_FRAGMENT_SHADER || GL_VERTEX_SHADER || GL_GEOMETRY_SHADER_ARB || + * GL_TESS_CONTROL_SHADER || GL_TESS_EVALUATION_SHADER. + * Must be the first field. + */ + GLenum16 Type; + gl_shader_stage Stage; + GLuint Name; /**< AKA the handle */ + GLint RefCount; /**< Reference count */ + GLchar *Label; /**< GL_KHR_debug */ + GLboolean DeletePending; + bool IsES; /**< True if this shader uses GLSL ES */ + + enum gl_compile_status CompileStatus; + + /** SHA1 of the pre-processed source used by the disk cache. */ + uint8_t disk_cache_sha1[SHA1_DIGEST_LENGTH]; + /** SHA1 of the original source before replacement, set by glShaderSource. */ + uint8_t source_sha1[SHA1_DIGEST_LENGTH]; + /** SHA1 of FallbackSource (a copy of some original source before replacement). */ + uint8_t fallback_source_sha1[SHA1_DIGEST_LENGTH]; + /** SHA1 of the current compiled source, set by successful glCompileShader. */ + uint8_t compiled_source_sha1[SHA1_DIGEST_LENGTH]; + + const GLchar *Source; /**< Source code string */ + const GLchar *FallbackSource; /**< Fallback string used by on-disk cache*/ + + GLchar *InfoLog; + + unsigned Version; /**< GLSL version used for linking */ + + /** + * A bitmask of gl_advanced_blend_mode values + */ + GLbitfield BlendSupport; + + struct exec_list *ir; + struct glsl_symbol_table *symbols; + + /** + * Whether early fragment tests are enabled as defined by + * ARB_shader_image_load_store. + */ + bool EarlyFragmentTests; + + bool ARB_fragment_coord_conventions_enable; + bool OES_geometry_point_size_enable; + bool OES_tessellation_point_size_enable; + + bool redeclares_gl_fragcoord; + bool uses_gl_fragcoord; + + bool PostDepthCoverage; + bool PixelInterlockOrdered; + bool PixelInterlockUnordered; + bool SampleInterlockOrdered; + bool SampleInterlockUnordered; + bool InnerCoverage; + + /** + * Fragment shader state from GLSL 1.50 layout qualifiers. + */ + bool origin_upper_left; + bool pixel_center_integer; + + /** + * Whether bindless_sampler/bindless_image, and respectively + * bound_sampler/bound_image are declared at global scope as defined by + * ARB_bindless_texture. + */ + bool bindless_sampler; + bool bindless_image; + bool bound_sampler; + bool bound_image; + + /** + * Whether layer output is viewport-relative. + */ + bool redeclares_gl_layer; + bool layer_viewport_relative; + + /** Global xfb_stride out qualifier if any */ + GLuint TransformFeedbackBufferStride[MAX_FEEDBACK_BUFFERS]; + + struct gl_shader_info info; + + /* ARB_gl_spirv related data */ + struct gl_shader_spirv_data *spirv_data; +}; + +/** + * A linked GLSL shader object. + */ +struct gl_linked_shader +{ + gl_shader_stage Stage; + + /** All gl_shader::compiled_source_sha1 combined. */ + uint8_t linked_source_sha1[SHA1_DIGEST_LENGTH]; + + struct gl_program *Program; /**< Post-compile assembly code */ + + /** + * \name Sampler tracking + * + * \note Each of these fields is only set post-linking. + */ + /*@{*/ + GLbitfield shadow_samplers; /**< Samplers used for shadow sampling. */ + /*@}*/ + + /** + * Number of default uniform block components used by this shader. + * + * This field is only set post-linking. + */ + unsigned num_uniform_components; + + /** + * Number of combined uniform components used by this shader. + * + * This field is only set post-linking. It is the sum of the uniform block + * sizes divided by sizeof(float), and num_uniform_compoennts. + */ + unsigned num_combined_uniform_components; + + struct exec_list *ir; + struct glsl_symbol_table *symbols; + + /** + * ARB_gl_spirv related data. + * + * This is actually a reference to the gl_shader::spirv_data, which + * stores information that is also needed during linking. + */ + struct gl_shader_spirv_data *spirv_data; +}; + + +/** + * Link status enum. LINKING_SKIPPED is used to indicate linking + * was skipped due to the shader being loaded from the on-disk cache. + */ +enum gl_link_status +{ + LINKING_FAILURE = 0, + LINKING_SUCCESS, + LINKING_SKIPPED +}; + +/* All GLSL program resource types are next to each other, so we can use that + * to make them 0-based like this: + */ +#define GET_PROGRAM_RESOURCE_TYPE_FROM_GLENUM(x) ((x) - GL_UNIFORM) +#define NUM_PROGRAM_RESOURCE_TYPES (GL_TRANSFORM_FEEDBACK_VARYING - GL_UNIFORM + 1) + +/** + * A data structure to be shared by gl_shader_program and gl_program. + */ +struct gl_shader_program_data +{ + GLint RefCount; /**< Reference count */ + + /** SHA1 hash of linked shader program */ + unsigned char sha1[20]; + + unsigned NumUniformStorage; + unsigned NumHiddenUniforms; + struct gl_uniform_storage *UniformStorage; + + unsigned NumUniformBlocks; + unsigned NumShaderStorageBlocks; + + struct gl_uniform_block *UniformBlocks; + struct gl_uniform_block *ShaderStorageBlocks; + + struct gl_active_atomic_buffer *AtomicBuffers; + unsigned NumAtomicBuffers; + + /* Shader cache variables used during restore */ + unsigned NumUniformDataSlots; + union gl_constant_value *UniformDataSlots; + + /* Used to hold initial uniform values for program binary restores. + * + * From the ARB_get_program_binary spec: + * + * "A successful call to ProgramBinary will reset all uniform + * variables to their initial values. The initial value is either + * the value of the variable's initializer as specified in the + * original shader source, or 0 if no initializer was present. + */ + union gl_constant_value *UniformDataDefaults; + + /** Hash for quick search by name. */ + struct hash_table *ProgramResourceHash[NUM_PROGRAM_RESOURCE_TYPES]; + + GLboolean Validated; + + /** List of all active resources after linking. */ + struct gl_program_resource *ProgramResourceList; + unsigned NumProgramResourceList; + + enum gl_link_status LinkStatus; /**< GL_LINK_STATUS */ + GLchar *InfoLog; + + /* Mask of stages this program was linked against */ + unsigned linked_stages; + + /* Whether the shaders of this program are loaded from SPIR-V binaries + * (all have the SPIR_V_BINARY_ARB state). This was introduced by the + * ARB_gl_spirv extension. + */ + bool spirv; +}; + +/** + * A GLSL program object. + * Basically a linked collection of vertex and fragment shaders. + */ +struct gl_shader_program +{ + GLenum16 Type; /**< Always GL_SHADER_PROGRAM (internal token) */ + GLuint Name; /**< aka handle or ID */ + GLchar *Label; /**< GL_KHR_debug */ + GLint RefCount; /**< Reference count */ + GLboolean DeletePending; + + /** + * Is the application intending to glGetProgramBinary this program? + * + * BinaryRetrievableHint is the currently active hint that gets set + * during initialization and after linking and BinaryRetrievableHintPending + * is the hint set by the user to be active when program is linked next time. + */ + GLboolean BinaryRetrievableHint; + GLboolean BinaryRetrievableHintPending; + + /** + * Indicates whether program can be bound for individual pipeline stages + * using UseProgramStages after it is next linked. + */ + GLboolean SeparateShader; + + GLuint NumShaders; /**< number of attached shaders */ + struct gl_shader **Shaders; /**< List of attached the shaders */ + + /** + * User-defined attribute bindings + * + * These are set via \c glBindAttribLocation and are used to direct the + * GLSL linker. These are \b not the values used in the compiled shader, + * and they are \b not the values returned by \c glGetAttribLocation. + */ + struct string_to_uint_map *AttributeBindings; + + /** + * User-defined fragment data bindings + * + * These are set via \c glBindFragDataLocation and are used to direct the + * GLSL linker. These are \b not the values used in the compiled shader, + * and they are \b not the values returned by \c glGetFragDataLocation. + */ + struct string_to_uint_map *FragDataBindings; + struct string_to_uint_map *FragDataIndexBindings; + + /** + * Transform feedback varyings last specified by + * glTransformFeedbackVaryings(). + * + * For the current set of transform feedback varyings used for transform + * feedback output, see LinkedTransformFeedback. + */ + struct { + GLenum16 BufferMode; + /** Global xfb_stride out qualifier if any */ + GLuint BufferStride[MAX_FEEDBACK_BUFFERS]; + GLuint NumVarying; + GLchar **VaryingNames; /**< Array [NumVarying] of char * */ + } TransformFeedback; + + struct gl_program *last_vert_prog; + + /** Data shared by gl_program and gl_shader_program */ + struct gl_shader_program_data *data; + + /** + * Mapping from GL uniform locations returned by \c glUniformLocation to + * UniformStorage entries. Arrays will have multiple contiguous slots + * in the UniformRemapTable, all pointing to the same UniformStorage entry. + */ + unsigned NumUniformRemapTable; + struct gl_uniform_storage **UniformRemapTable; + + /** + * Sometimes there are empty slots left over in UniformRemapTable after we + * allocate slots to explicit locations. This list stores the blocks of + * continuous empty slots inside UniformRemapTable. + */ + struct exec_list EmptyUniformLocations; + + /** + * Total number of explicit uniform location including inactive uniforms. + */ + unsigned NumExplicitUniformLocations; + + /** + * Map of active uniform names to locations + * + * Maps any active uniform that is not an array element to a location. + * Each active uniform, including individual structure members will appear + * in this map. This roughly corresponds to the set of names that would be + * enumerated by \c glGetActiveUniform. + */ + struct string_to_uint_map *UniformHash; + + GLboolean SamplersValidated; /**< Samplers validated against texture units? */ + + bool IsES; /**< True if this program uses GLSL ES */ + + /** + * Per-stage shaders resulting from the first stage of linking. + * + * Set of linked shaders for this program. The array is accessed using the + * \c MESA_SHADER_* defines. Entries for non-existent stages will be + * \c NULL. + */ + struct gl_linked_shader *_LinkedShaders[MESA_SHADER_STAGES]; + + unsigned GLSL_Version; /**< GLSL version used for linking */ +}; + +/** + * Base class for any kind of program object + */ +struct gl_program +{ + /** FIXME: This must be first until we split shader_info from nir_shader */ + struct shader_info info; + + GLuint Id; + GLint RefCount; + GLubyte *String; /**< Null-terminated program text */ + + /** GL_VERTEX/FRAGMENT_PROGRAM_ARB, GL_GEOMETRY_PROGRAM_NV */ + GLenum16 Target; + GLenum16 Format; /**< String encoding format */ + + GLboolean _Used; /**< Ever used for drawing? Used for debugging */ + + struct nir_shader *nir; + void *base_serialized_nir; + size_t base_serialized_nir_size; + + /* Saved and restored with metadata. Freed with ralloc. */ + void *driver_cache_blob; + size_t driver_cache_blob_size; + + /** whether to skip VARYING_SLOT_PSIZ in st_translate_stream_output_info() */ + bool skip_pointsize_xfb; + + /** A bitfield indicating which vertex shader inputs consume two slots + * + * This is used for mapping from single-slot input locations in the GL API + * to dual-slot double input locations in the shader. This field is set + * once as part of linking and never updated again to ensure the mapping + * remains consistent. + * + * Note: There may be dual-slot variables in the original shader source + * which do not appear in this bitfield due to having been eliminated by + * the compiler prior to DualSlotInputs being calculated. There may also + * be bits set in this bitfield which are set but which the shader never + * reads due to compiler optimizations eliminating such variables after + * DualSlotInputs is calculated. + */ + GLbitfield64 DualSlotInputs; + /** Subset of OutputsWritten outputs written with non-zero index. */ + GLbitfield64 SecondaryOutputsWritten; + /** TEXTURE_x_BIT bitmask */ + GLbitfield16 TexturesUsed[MAX_COMBINED_TEXTURE_IMAGE_UNITS]; + /** Bitfield of which samplers are used */ + GLbitfield SamplersUsed; + /** Texture units used for shadow sampling. */ + GLbitfield ShadowSamplers; + /** Texture units used for samplerExternalOES */ + GLbitfield ExternalSamplersUsed; + + /** Named parameters, constants, etc. from program text */ + struct gl_program_parameter_list *Parameters; + + /** Map from sampler unit to texture unit (set by glUniform1i()) */ + GLubyte SamplerUnits[MAX_SAMPLERS]; + + struct pipe_shader_state state; + struct ati_fragment_shader *ati_fs; + uint64_t affected_states; /**< ST_NEW_* flags to mark dirty when binding */ + + void *serialized_nir; + unsigned serialized_nir_size; + + struct gl_shader_program *shader_program; + + struct st_variant *variants; + + union { + /** Fields used by GLSL programs */ + struct { + /** Data shared by gl_program and gl_shader_program */ + struct gl_shader_program_data *data; + + struct gl_active_atomic_buffer **AtomicBuffers; + + /** Post-link transform feedback info. */ + struct gl_transform_feedback_info *LinkedTransformFeedback; + + /** + * Number of types for subroutine uniforms. + */ + GLuint NumSubroutineUniformTypes; + + /** + * Subroutine uniform remap table + * based on the program level uniform remap table. + */ + GLuint NumSubroutineUniforms; /* non-sparse total */ + GLuint NumSubroutineUniformRemapTable; + struct gl_uniform_storage **SubroutineUniformRemapTable; + + /** + * Num of subroutine functions for this stage and storage for them. + */ + GLuint NumSubroutineFunctions; + GLuint MaxSubroutineFunctionIndex; + struct gl_subroutine_function *SubroutineFunctions; + + /** + * Map from image uniform index to image unit (set by glUniform1i()) + * + * An image uniform index is associated with each image uniform by + * the linker. The image index associated with each uniform is + * stored in the \c gl_uniform_storage::image field. + */ + GLubyte ImageUnits[MAX_IMAGE_UNIFORMS]; + + /** Access qualifier from linked shader + */ + enum gl_access_qualifier image_access[MAX_IMAGE_UNIFORMS]; + + GLuint NumUniformBlocks; + struct gl_uniform_block **UniformBlocks; + struct gl_uniform_block **ShaderStorageBlocks; + + /** + * Bitmask of shader storage blocks not declared as read-only. + */ + unsigned ShaderStorageBlocksWriteAccess; + + /** Which texture target is being sampled + * (TEXTURE_1D/2D/3D/etc_INDEX) + */ + GLubyte SamplerTargets[MAX_SAMPLERS]; + + /** + * Number of samplers declared with the bindless_sampler layout + * qualifier as specified by ARB_bindless_texture. + */ + GLuint NumBindlessSamplers; + GLboolean HasBoundBindlessSampler; + struct gl_bindless_sampler *BindlessSamplers; + + /** + * Number of images declared with the bindless_image layout qualifier + * as specified by ARB_bindless_texture. + */ + GLuint NumBindlessImages; + GLboolean HasBoundBindlessImage; + struct gl_bindless_image *BindlessImages; + } sh; + + /** ARB assembly-style program fields */ + struct { + struct prog_instruction *Instructions; + + /** + * Local parameters used by the program. + * + * It's dynamically allocated because it is rarely used (just + * assembly-style programs), and MAX_PROGRAM_LOCAL_PARAMS entries + * once it's allocated. + */ + GLfloat (*LocalParams)[4]; + unsigned MaxLocalParams; + + /** Bitmask of which register files are read/written with indirect + * addressing. Mask of (1 << PROGRAM_x) bits. + */ + GLbitfield IndirectRegisterFiles; + + /** Logical counts */ + /*@{*/ + GLuint NumInstructions; + GLuint NumTemporaries; + GLuint NumParameters; + GLuint NumAttributes; + GLuint NumAddressRegs; + GLuint NumAluInstructions; + GLuint NumTexInstructions; + GLuint NumTexIndirections; + /*@}*/ + /** Native, actual h/w counts */ + /*@{*/ + GLuint NumNativeInstructions; + GLuint NumNativeTemporaries; + GLuint NumNativeParameters; + GLuint NumNativeAttributes; + GLuint NumNativeAddressRegs; + GLuint NumNativeAluInstructions; + GLuint NumNativeTexInstructions; + GLuint NumNativeTexIndirections; + /*@}*/ + + /** Used by ARB assembly-style programs. Can only be true for vertex + * programs. + */ + GLboolean IsPositionInvariant; + + /** Used by ARB_fp programs, enum gl_fog_mode */ + unsigned Fog; + } arb; + }; +}; + +/* + * State/IR translators needs to store some extra vp info. + */ +struct gl_vertex_program +{ + struct gl_program Base; + + uint32_t vert_attrib_mask; /**< mask of sourced vertex attribs */ + uint8_t num_inputs; + + /** Maps VARYING_SLOT_x to slot */ + uint8_t result_to_output[VARYING_SLOT_MAX]; +}; + +/** + * Structure that represents a reference to an atomic buffer from some + * shader program. + */ +struct gl_active_atomic_buffer +{ + /** Uniform indices of the atomic counters declared within it. */ + GLuint *Uniforms; + GLuint NumUniforms; + + /** Binding point index associated with it. */ + GLuint Binding; + + /** Minimum reasonable size it is expected to have. */ + GLuint MinimumSize; + + /** Shader stages making use of it. */ + GLboolean StageReferences[MESA_SHADER_STAGES]; +}; + +struct gl_transform_feedback_varying_info +{ + struct gl_resource_name name; + GLenum16 Type; + GLint BufferIndex; + GLint Size; + GLint Offset; +}; + + +/** + * Per-output info vertex shaders for transform feedback. + */ +struct gl_transform_feedback_output +{ + uint32_t OutputRegister; + uint32_t OutputBuffer; + uint32_t NumComponents; + uint32_t StreamId; + + /** offset (in DWORDs) of this output within the interleaved structure */ + uint32_t DstOffset; + + /** + * Offset into the output register of the data to output. For example, + * if NumComponents is 2 and ComponentOffset is 1, then the data to + * offset is in the y and z components of the output register. + */ + uint32_t ComponentOffset; +}; + + +struct gl_transform_feedback_buffer +{ + uint32_t Binding; + + uint32_t NumVaryings; + + /** + * Total number of components stored in each buffer. This may be used by + * hardware back-ends to determine the correct stride when interleaving + * multiple transform feedback outputs in the same buffer. + */ + uint32_t Stride; + + /** + * Which transform feedback stream this buffer binding is associated with. + */ + uint32_t Stream; +}; + + +/** Post-link transform feedback info. */ +struct gl_transform_feedback_info +{ + unsigned NumOutputs; + + /* Bitmask of active buffer indices. */ + unsigned ActiveBuffers; + + struct gl_transform_feedback_output *Outputs; + + /** Transform feedback varyings used for the linking of this shader program. + * + * Use for glGetTransformFeedbackVarying(). + */ + struct gl_transform_feedback_varying_info *Varyings; + GLint NumVarying; + + struct gl_transform_feedback_buffer Buffers[MAX_FEEDBACK_BUFFERS]; +}; + +/** + * Shader subroutine function definition + */ +struct gl_subroutine_function +{ + struct gl_resource_name name; + int index; + int num_compat_types; + const struct glsl_type **types; +}; + +/** + * Active resource in a gl_shader_program + */ +struct gl_program_resource +{ + GLenum16 Type; /** Program interface type. */ + const void *Data; /** Pointer to resource associated data structure. */ + uint8_t StageReferences; /** Bitmask of shader stage references. */ +}; + +struct gl_uniform_buffer_variable +{ + char *Name; + + /** + * Name of the uniform as seen by glGetUniformIndices. + * + * glGetUniformIndices requires that the block instance index \b not be + * present in the name of queried uniforms. + * + * \note + * \c gl_uniform_buffer_variable::IndexName and + * \c gl_uniform_buffer_variable::Name may point to identical storage. + */ + char *IndexName; + + const struct glsl_type *Type; + unsigned int Offset; + GLboolean RowMajor; +}; + + +struct gl_uniform_block +{ + /** Declared name of the uniform block */ + struct gl_resource_name name; + + /** Array of supplemental information about UBO ir_variables. */ + struct gl_uniform_buffer_variable *Uniforms; + GLuint NumUniforms; + + /** + * Index (GL_UNIFORM_BLOCK_BINDING) into ctx->UniformBufferBindings[] to use + * with glBindBufferBase to bind a buffer object to this uniform block. + */ + GLuint Binding; + + /** + * Minimum size (in bytes) of a buffer object to back this uniform buffer + * (GL_UNIFORM_BLOCK_DATA_SIZE). + */ + GLuint UniformBufferSize; + + /** Stages that reference this block */ + uint8_t stageref; + + /** + * Linearized array index for uniform block instance arrays + * + * Given a uniform block instance array declared with size + * blk[s_0][s_1]..[s_m], the block referenced by blk[i_0][i_1]..[i_m] will + * have the linearized array index + * + * m-1 m + * i_m + ∑ i_j * ∏ s_k + * j=0 k=j+1 + * + * For a uniform block instance that is not an array, this is always 0. + */ + uint8_t linearized_array_index; + + /** + * Layout specified in the shader + * + * This isn't accessible through the API, but it is used while + * cross-validating uniform blocks. + */ + enum glsl_interface_packing _Packing; + GLboolean _RowMajor; +}; + +/** + * A bindless sampler object. + */ +struct gl_bindless_sampler +{ + /** Texture unit (set by glUniform1()). */ + GLubyte unit; + + /** Whether this bindless sampler is bound to a unit. */ + GLboolean bound; + + /** Texture Target (TEXTURE_1D/2D/3D/etc_INDEX). */ + gl_texture_index target; + + /** Pointer to the base of the data. */ + GLvoid *data; +}; + + +/** + * A bindless image object. + */ +struct gl_bindless_image +{ + /** Image unit (set by glUniform1()). */ + GLubyte unit; + + /** Whether this bindless image is bound to a unit. */ + GLboolean bound; + + /** Access qualifier from linked shader + */ + enum gl_access_qualifier image_access; + + /** Pointer to the base of the data. */ + GLvoid *data; +}; + +/** + * Data container for shader queries. This holds only the minimal + * amount of required information for resource queries to work. + */ +struct gl_shader_variable +{ + /** + * Declared type of the variable + */ + const struct glsl_type *type; + + /** + * If the variable is in an interface block, this is the type of the block. + */ + const struct glsl_type *interface_type; + + /** + * For variables inside structs (possibly recursively), this is the + * outermost struct type. + */ + const struct glsl_type *outermost_struct_type; + + /** + * Declared name of the variable + */ + struct gl_resource_name name; + + /** + * Storage location of the base of this variable + * + * The precise meaning of this field depends on the nature of the variable. + * + * - Vertex shader input: one of the values from \c gl_vert_attrib. + * - Vertex shader output: one of the values from \c gl_varying_slot. + * - Geometry shader input: one of the values from \c gl_varying_slot. + * - Geometry shader output: one of the values from \c gl_varying_slot. + * - Fragment shader input: one of the values from \c gl_varying_slot. + * - Fragment shader output: one of the values from \c gl_frag_result. + * - Uniforms: Per-stage uniform slot number for default uniform block. + * - Uniforms: Index within the uniform block definition for UBO members. + * - Non-UBO Uniforms: explicit location until linking then reused to + * store uniform slot number. + * - Other: This field is not currently used. + * + * If the variable is a uniform, shader input, or shader output, and the + * slot has not been assigned, the value will be -1. + */ + int location; + + /** + * Specifies the first component the variable is stored in as per + * ARB_enhanced_layouts. + */ + unsigned component:2; + + /** + * Output index for dual source blending. + * + * \note + * The GLSL spec only allows the values 0 or 1 for the index in \b dual + * source blending. + */ + unsigned index:1; + + /** + * Specifies whether a shader input/output is per-patch in tessellation + * shader stages. + */ + unsigned patch:1; + + /** + * Storage class of the variable. + * + * \sa (n)ir_variable_mode + */ + unsigned mode:4; + + /** + * Interpolation mode for shader inputs / outputs + * + * \sa glsl_interp_mode + */ + unsigned interpolation:2; + + /** + * Was the location explicitly set in the shader? + * + * If the location is explicitly set in the shader, it \b cannot be changed + * by the linker or by the API (e.g., calls to \c glBindAttribLocation have + * no effect). + */ + unsigned explicit_location:1; + + /** + * Precision qualifier. + */ + unsigned precision:2; +}; + +#endif diff --git a/src/mesa/main/shaderapi.c b/src/mesa/main/shaderapi.c index 22f6c0cf708..2fdd05b0cc4 100644 --- a/src/mesa/main/shaderapi.c +++ b/src/mesa/main/shaderapi.c @@ -36,7 +36,7 @@ #include <stdbool.h> #include <c99_alloca.h> -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "draw_validate.h" #include "main/enums.h" @@ -60,11 +60,65 @@ #include "program/prog_parameter.h" #include "util/ralloc.h" #include "util/hash_table.h" -#include "util/mesa-sha1.h" #include "util/crc32.h" #include "util/os_file.h" -#include "util/simple_list.h" +#include "util/list.h" +#include "util/perf/cpu_trace.h" +#include "util/u_process.h" #include "util/u_string.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_context.h" +#include "state_tracker/st_glsl_to_nir.h" +#include "state_tracker/st_program.h" + +#ifdef ENABLE_SHADER_CACHE +#if CUSTOM_SHADER_REPLACEMENT +#include "shader_replacement.h" +/* shader_replacement.h must declare a variable like this: + + struct _shader_replacement { + // process name. If null, only sha1 is used to match + const char *app; + // original glsl shader sha1 + const char *sha1; + // shader stage + gl_shader_stage stage; + ... any other information ... + }; + struct _shader_replacement shader_replacements[...]; + + And a method to load a given replacement and return the new + glsl source: + + char* load_shader_replacement(struct _shader_replacement *repl); + + And a method to replace the shader without sha1 matching: + + char *try_direct_replace(const char *app, const char *source) + + shader_replacement.h can be generated at build time, or copied + from an external folder, or any other method. +*/ +#else +struct _shader_replacement { + const char *app; + const char *sha1; + gl_shader_stage stage; +}; +struct _shader_replacement shader_replacements[0]; + +static char *try_direct_replace(const char *app, const char *source) +{ + return NULL; +} + +static char* load_shader_replacement(struct _shader_replacement *repl) +{ + return NULL; +} +#endif +#endif /** * Return mask of GLSL_x flags by examining the MESA_GLSL env var. @@ -78,10 +132,14 @@ _mesa_get_shader_flags(void) if (env) { if (strstr(env, "dump_on_error")) flags |= GLSL_DUMP_ON_ERROR; +#ifndef CUSTOM_SHADER_REPLACEMENT else if (strstr(env, "dump")) flags |= GLSL_DUMP; if (strstr(env, "log")) flags |= GLSL_LOG; + if (strstr(env, "source")) + flags |= GLSL_SOURCE; +#endif if (strstr(env, "cache_fb")) flags |= GLSL_CACHE_FALLBACK; if (strstr(env, "cache_info")) @@ -101,6 +159,14 @@ _mesa_get_shader_flags(void) return flags; } +#define ANDROID_SHADER_CAPTURE 0 + +#if ANDROID_SHADER_CAPTURE +#include "util/u_process.h" +#include <sys/stat.h> +#include <sys/types.h> +#endif + /** * Memoized version of getenv("MESA_SHADER_CAPTURE_PATH"). */ @@ -111,8 +177,17 @@ _mesa_get_shader_capture_path(void) static const char *path = NULL; if (!read_env_var) { - path = getenv("MESA_SHADER_CAPTURE_PATH"); + path = secure_getenv("MESA_SHADER_CAPTURE_PATH"); read_env_var = true; + +#if ANDROID_SHADER_CAPTURE + if (!path) { + char *p; + asprintf(&p, "/data/shaders/%s", util_get_process_name()); + mkdir(p, 0755); + path = p; + } +#endif } return path; @@ -132,7 +207,6 @@ _mesa_init_shader_state(struct gl_context *ctx) int i; memset(&options, 0, sizeof(options)); - options.MaxUnrollIterations = 32; options.MaxIfDepth = UINT_MAX; for (sh = 0; sh < MESA_SHADER_STAGES; ++sh) @@ -338,12 +412,12 @@ create_shader(struct gl_context *ctx, GLenum type) struct gl_shader *sh; GLuint name; - _mesa_HashLockMutex(ctx->Shared->ShaderObjects); - name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); + _mesa_HashLockMutex(&ctx->Shared->ShaderObjects); + name = _mesa_HashFindFreeKeyBlock(&ctx->Shared->ShaderObjects, 1); sh = _mesa_new_shader(name, _mesa_shader_enum_to_shader_stage(type)); sh->Type = type; - _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, sh, true); - _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); + _mesa_HashInsertLocked(&ctx->Shared->ShaderObjects, name, sh); + _mesa_HashUnlockMutex(&ctx->Shared->ShaderObjects); return name; } @@ -368,17 +442,17 @@ create_shader_program(struct gl_context *ctx) GLuint name; struct gl_shader_program *shProg; - _mesa_HashLockMutex(ctx->Shared->ShaderObjects); + _mesa_HashLockMutex(&ctx->Shared->ShaderObjects); - name = _mesa_HashFindFreeKeyBlock(ctx->Shared->ShaderObjects, 1); + name = _mesa_HashFindFreeKeyBlock(&ctx->Shared->ShaderObjects, 1); shProg = _mesa_new_shader_program(name); - _mesa_HashInsertLocked(ctx->Shared->ShaderObjects, name, shProg, true); + _mesa_HashInsertLocked(&ctx->Shared->ShaderObjects, name, shProg); assert(shProg->RefCount == 1); - _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); + _mesa_HashUnlockMutex(&ctx->Shared->ShaderObjects); return name; } @@ -651,12 +725,32 @@ check_tes_query(struct gl_context *ctx, const struct gl_shader_program *shProg) return false; } -/** - * Return the length of a string, or 0 if the pointer passed in is NULL - */ -static size_t strlen_or_zero(const char *s) +static bool +get_shader_program_completion_status(struct gl_context *ctx, + struct gl_shader_program *shprog) { - return s ? strlen(s) : 0; + struct pipe_screen *screen = ctx->screen; + + if (!screen->is_parallel_shader_compilation_finished) + return true; + + for (unsigned i = 0; i < MESA_SHADER_STAGES; i++) { + struct gl_linked_shader *linked = shprog->_LinkedShaders[i]; + void *sh = NULL; + + if (!linked || !linked->Program) + continue; + + if (linked->Program->variants) + sh = linked->Program->variants->driver_shader; + + unsigned type = pipe_shader_type_from_mesa(i); + + if (sh && + !screen->is_parallel_shader_compilation_finished(screen, sh, type)) + return false; + } + return true; } /** @@ -674,8 +768,8 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, /* Is transform feedback available in this context? */ const bool has_xfb = - (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.EXT_transform_feedback) - || ctx->API == API_OPENGL_CORE + (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_transform_feedback) + || _mesa_is_desktop_gl_core(ctx) || _mesa_is_gles3(ctx); /* True if geometry shaders (of the form that was adopted into GLSL 1.50 @@ -687,9 +781,9 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, /* Are uniform buffer objects available in this context? */ const bool has_ubo = - (ctx->API == API_OPENGL_COMPAT && + (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ARB_uniform_buffer_object) - || ctx->API == API_OPENGL_CORE + || _mesa_is_desktop_gl_core(ctx) || _mesa_is_gles3(ctx); if (!shProg) { @@ -701,10 +795,7 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, *params = shProg->DeletePending; return; case GL_COMPLETION_STATUS_ARB: - if (ctx->Driver.GetShaderProgramCompletionStatus) - *params = ctx->Driver.GetShaderProgramCompletionStatus(ctx, shProg); - else - *params = GL_TRUE; + *params = get_shader_program_completion_status(ctx, shProg); return; case GL_LINK_STATUS: *params = shProg->data->LinkStatus ? GL_TRUE : GL_FALSE; @@ -726,48 +817,13 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, *params = _mesa_longest_attribute_name_length(shProg); return; case GL_ACTIVE_UNIFORMS: { - unsigned i; - const unsigned num_uniforms = - shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms; - for (*params = 0, i = 0; i < num_uniforms; i++) { - if (!shProg->data->UniformStorage[i].is_shader_storage) - (*params)++; - } + _mesa_get_program_interfaceiv(shProg, GL_UNIFORM, GL_ACTIVE_RESOURCES, + params); return; } case GL_ACTIVE_UNIFORM_MAX_LENGTH: { - unsigned i; - GLint max_len = 0; - const unsigned num_uniforms = - shProg->data->NumUniformStorage - shProg->data->NumHiddenUniforms; - - for (i = 0; i < num_uniforms; i++) { - if (shProg->data->UniformStorage[i].is_shader_storage) - continue; - - /* From ARB_gl_spirv spec: - * - * "If pname is ACTIVE_UNIFORM_MAX_LENGTH, the length of the - * longest active uniform name, including a null terminator, is - * returned. If no active uniforms exist, zero is returned. If no - * name reflection information is available, one is returned." - * - * We are setting 0 here, as below it will add 1 for the NUL character. - */ - const GLint base_len = - strlen_or_zero(shProg->data->UniformStorage[i].name); - - /* Add one for the terminating NUL character for a non-array, and - * 4 for the "[0]" and the NUL for an array. - */ - const GLint len = base_len + 1 + - ((shProg->data->UniformStorage[i].array_elements != 0) ? 3 : 0); - - if (len > max_len) - max_len = len; - } - - *params = max_len; + _mesa_get_program_interfaceiv(shProg, GL_UNIFORM, GL_MAX_NAME_LENGTH, + params); return; } case GL_TRANSFORM_FEEDBACK_VARYINGS: @@ -786,41 +842,11 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, *params = shProg->TransformFeedback.NumVarying; return; case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: { - unsigned i; - GLint max_len = 0; - bool in_shader_varyings; - int num_varying; - if (!has_xfb) break; - /* Check first if there are transform feedback varyings specified in the - * shader (ARB_enhanced_layouts). If there isn't any, use the ones - * specified using the API. - */ - in_shader_varyings = shProg->last_vert_prog && - shProg->last_vert_prog->sh.LinkedTransformFeedback->NumVarying > 0; - - num_varying = in_shader_varyings ? - shProg->last_vert_prog->sh.LinkedTransformFeedback->NumVarying : - shProg->TransformFeedback.NumVarying; - - for (i = 0; i < num_varying; i++) { - const char *name = in_shader_varyings ? - shProg->last_vert_prog->sh.LinkedTransformFeedback->Varyings[i].Name - : shProg->TransformFeedback.VaryingNames[i]; - - /* Add one for the terminating NUL character. We have to use - * strlen_or_zero, as for shaders constructed from SPIR-V binaries, - * it is possible that no name reflection information is available. - */ - const GLint len = strlen_or_zero(name) + 1; - - if (len > max_len) - max_len = len; - } - - *params = max_len; + _mesa_get_program_interfaceiv(shProg, GL_TRANSFORM_FEEDBACK_VARYING, + GL_MAX_NAME_LENGTH, params); return; } case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: @@ -863,29 +889,11 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, } return; case GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH: { - unsigned i; - GLint max_len = 0; - if (!has_ubo) break; - for (i = 0; i < shProg->data->NumUniformBlocks; i++) { - /* Add one for the terminating NUL character. Name can be NULL, in - * that case, from ARB_gl_spirv: - * "If pname is ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, the length of - * the longest active uniform block name, including the null - * terminator, is returned. If no active uniform blocks exist, - * zero is returned. If no name reflection information is - * available, one is returned." - */ - const GLint len = - strlen_or_zero(shProg->data->UniformBlocks[i].Name) + 1; - - if (len > max_len) - max_len = len; - } - - *params = max_len; + _mesa_get_program_interfaceiv(shProg, GL_UNIFORM_BLOCK, + GL_MAX_NAME_LENGTH, params); return; } case GL_ACTIVE_UNIFORM_BLOCKS: @@ -956,8 +964,22 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, if (!has_tess) break; if (check_tes_query(ctx, shProg)) { - *params = shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]-> - Program->info.tess.primitive_mode; + const struct gl_linked_shader *tes = + shProg->_LinkedShaders[MESA_SHADER_TESS_EVAL]; + switch (tes->Program->info.tess._primitive_mode) { + case TESS_PRIMITIVE_TRIANGLES: + *params = GL_TRIANGLES; + break; + case TESS_PRIMITIVE_QUADS: + *params = GL_QUADS; + break; + case TESS_PRIMITIVE_ISOLINES: + *params = GL_ISOLINES; + break; + case TESS_PRIMITIVE_UNSPECIFIED: + *params = 0; + break; + } } return; case GL_TESS_GEN_SPACING: @@ -1131,7 +1153,8 @@ get_shader_source(struct gl_context *ctx, GLuint shader, GLsizei maxLength, * glShaderSource[ARB]. */ static void -set_shader_source(struct gl_shader *sh, const GLchar *source) +set_shader_source(struct gl_shader *sh, const GLchar *source, + const uint8_t original_sha1[SHA1_DIGEST_LENGTH]) { assert(sh); @@ -1150,6 +1173,7 @@ set_shader_source(struct gl_shader *sh, const GLchar *source) * fallback. */ sh->FallbackSource = sh->Source; + memcpy(sh->fallback_source_sha1, sh->source_sha1, SHA1_DIGEST_LENGTH); sh->Source = source; } else { /* free old shader source string and install new one */ @@ -1157,9 +1181,7 @@ set_shader_source(struct gl_shader *sh, const GLchar *source) sh->Source = source; } -#ifdef DEBUG - sh->SourceChecksum = util_hash_crc32(sh->Source, strlen(sh->Source)); -#endif + memcpy(sh->source_sha1, original_sha1, SHA1_DIGEST_LENGTH); } static void @@ -1198,10 +1220,10 @@ _mesa_compile_shader(struct gl_context *ctx, struct gl_shader *sh) */ sh->CompileStatus = COMPILE_FAILURE; } else { - if (ctx->_Shader->Flags & GLSL_DUMP) { + if (ctx->_Shader->Flags & (GLSL_DUMP | GLSL_SOURCE)) { _mesa_log("GLSL source for %s shader %d:\n", _mesa_shader_stage_to_string(sh->Stage), sh->Name); - _mesa_log("%s\n", sh->Source); + _mesa_log_direct(sh->Source); } ensure_builtin_types(ctx); @@ -1284,6 +1306,8 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg, if (!shProg) return; + MESA_TRACE_FUNC(); + if (!no_error) { /* From the ARB_transform_feedback2 specification: * "The error INVALID_OPERATION is generated by LinkProgram if <program> @@ -1309,7 +1333,7 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg, ensure_builtin_types(ctx); FLUSH_VERTICES(ctx, 0, 0); - _mesa_glsl_link_shader(ctx, shProg); + st_link_shader(ctx, shProg); /* From section 7.3 (Program Objects) of the OpenGL 4.5 spec: * @@ -1332,16 +1356,15 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg, _mesa_use_program(ctx, stage, shProg, prog, ctx->_Shader); } - if (ctx->Pipeline.Objects) { - struct update_programs_in_pipeline_params params = { - .ctx = ctx, - .shProg = shProg - }; - _mesa_HashWalk(ctx->Pipeline.Objects, update_programs_in_pipeline, - ¶ms); - } + struct update_programs_in_pipeline_params params = { + .ctx = ctx, + .shProg = shProg + }; + _mesa_HashWalk(&ctx->Pipeline.Objects, update_programs_in_pipeline, + ¶ms); } +#ifndef CUSTOM_SHADER_REPLACEMENT /* Capture .shader_test files. */ const char *capture_path = _mesa_get_shader_capture_path(); if (shProg->Name != 0 && shProg->Name != ~0 && capture_path != NULL) { @@ -1368,8 +1391,8 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg, } if (file) { fprintf(file, "[require]\nGLSL%s >= %u.%02u\n", - shProg->IsES ? " ES" : "", - shProg->data->Version / 100, shProg->data->Version % 100); + shProg->IsES ? " ES" : "", shProg->GLSL_Version / 100, + shProg->GLSL_Version % 100); if (shProg->SeparateShader) fprintf(file, "GL_ARB_separate_shader_objects\nSSO ENABLED\n"); fprintf(file, "\n"); @@ -1386,6 +1409,7 @@ link_program(struct gl_context *ctx, struct gl_shader_program *shProg, ralloc_free(filename); } +#endif if (shProg->data->LinkStatus == LINKING_FAILURE && (ctx->_Shader->Flags & GLSL_REPORT_ERRORS)) { @@ -1446,16 +1470,9 @@ print_shader_info(const struct gl_shader_program *shProg) printf("Mesa: glUseProgram(%u)\n", shProg->Name); for (i = 0; i < shProg->NumShaders; i++) { -#ifdef DEBUG - printf(" %s shader %u, checksum %u\n", - _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), - shProg->Shaders[i]->Name, - shProg->Shaders[i]->SourceChecksum); -#else printf(" %s shader %u\n", _mesa_shader_stage_to_string(shProg->Shaders[i]->Stage), shProg->Shaders[i]->Name); -#endif } if (shProg->_LinkedShaders[MESA_SHADER_VERTEX]) printf(" vert prog %u\n", @@ -1691,7 +1708,7 @@ _mesa_DeleteObjectARB(GLhandleARB obj) delete_shader(ctx, obj); } else { - /* error? */ + _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteObjectARB"); } } } @@ -1915,16 +1932,6 @@ _mesa_LinkProgram(GLuint programObj) } #ifdef ENABLE_SHADER_CACHE -/** - * Generate a SHA-1 hash value string for given source string. - */ -static void -generate_sha1(const char *source, char sha_str[64]) -{ - unsigned char sha[20]; - _mesa_sha1_compute(source, strlen(source), sha); - _mesa_sha1_format(sha_str, sha); -} /** * Construct a full path for shader replacement functionality using @@ -1934,17 +1941,15 @@ generate_sha1(const char *source, char sha_str[64]) * <path>/<stage prefix>_<CHECKSUM>.arb */ static char * -construct_name(const gl_shader_stage stage, const char *source, - const char *path) +construct_name(const gl_shader_stage stage, const char *sha, + const char *source, const char *path) { - char sha[64]; static const char *types[] = { "VS", "TC", "TE", "GS", "FS", "CS", }; const char *format = strncmp(source, "!!ARB", 5) ? "glsl" : "arb"; - generate_sha1(source, sha); return ralloc_asprintf(NULL, "%s/%s_%s.%s", path, types[stage], sha, format); } @@ -1952,22 +1957,26 @@ construct_name(const gl_shader_stage stage, const char *source, * Write given shader source to a file in MESA_SHADER_DUMP_PATH. */ void -_mesa_dump_shader_source(const gl_shader_stage stage, const char *source) +_mesa_dump_shader_source(const gl_shader_stage stage, const char *source, + const uint8_t sha1[SHA1_DIGEST_LENGTH]) { +#ifndef CUSTOM_SHADER_REPLACEMENT static bool path_exists = true; char *dump_path; FILE *f; + char sha[64]; if (!path_exists) return; - dump_path = getenv("MESA_SHADER_DUMP_PATH"); + dump_path = secure_getenv("MESA_SHADER_DUMP_PATH"); if (!dump_path) { path_exists = false; return; } - char *name = construct_name(stage, source, dump_path); + _mesa_sha1_format(sha, sha1); + char *name = construct_name(stage, sha, source, dump_path); f = fopen(name, "w"); if (f) { @@ -1979,6 +1988,7 @@ _mesa_dump_shader_source(const gl_shader_stage stage, const char *source) strerror(errno)); } ralloc_free(name); +#endif } /** @@ -1986,13 +1996,39 @@ _mesa_dump_shader_source(const gl_shader_stage stage, const char *source) * Useful for debugging to override an app's shader. */ GLcharARB * -_mesa_read_shader_source(const gl_shader_stage stage, const char *source) +_mesa_read_shader_source(const gl_shader_stage stage, const char *source, + const uint8_t sha1[SHA1_DIGEST_LENGTH]) { char *read_path; static bool path_exists = true; int len, shader_size = 0; GLcharARB *buffer; FILE *f; + char sha[64]; + + _mesa_sha1_format(sha, sha1); + + if (!debug_get_bool_option("MESA_NO_SHADER_REPLACEMENT", false)) { + const char *process_name = util_get_process_name(); + + char *new_source = try_direct_replace(process_name, source); + if (new_source) + return new_source; + + for (size_t i = 0; i < ARRAY_SIZE(shader_replacements); i++) { + if (stage != shader_replacements[i].stage) + continue; + + if (shader_replacements[i].app && + strcmp(process_name, shader_replacements[i].app) != 0) + continue; + + if (memcmp(sha, shader_replacements[i].sha1, 40) != 0) + continue; + + return load_shader_replacement(&shader_replacements[i]); + } + } if (!path_exists) return NULL; @@ -2003,7 +2039,7 @@ _mesa_read_shader_source(const gl_shader_stage stage, const char *source) return NULL; } - char *name = construct_name(stage, source, read_path); + char *name = construct_name(stage, sha, source, read_path); f = fopen(name, "r"); ralloc_free(name); if (!f) @@ -2108,22 +2144,26 @@ shader_source(struct gl_context *ctx, GLuint shaderObj, GLsizei count, source[totalLength - 1] = '\0'; source[totalLength - 2] = '\0'; + /* Compute the original source sha1 before shader replacement. */ + uint8_t original_sha1[SHA1_DIGEST_LENGTH]; + _mesa_sha1_compute(source, strlen(source), original_sha1); + #ifdef ENABLE_SHADER_CACHE GLcharARB *replacement; /* Dump original shader source to MESA_SHADER_DUMP_PATH and replace * if corresponding entry found from MESA_SHADER_READ_PATH. */ - _mesa_dump_shader_source(sh->Stage, source); + _mesa_dump_shader_source(sh->Stage, source, original_sha1); - replacement = _mesa_read_shader_source(sh->Stage, source); + replacement = _mesa_read_shader_source(sh->Stage, source, original_sha1); if (replacement) { free(source); source = replacement; } #endif /* ENABLE_SHADER_CACHE */ - set_shader_source(sh, source); + set_shader_source(sh, source, original_sha1); free(offsets); } @@ -2321,6 +2361,10 @@ _mesa_ShaderBinary(GLint n, const GLuint* shaders, GLenum binaryformat, GET_CURRENT_CONTEXT(ctx); struct gl_shader **sh; + /* no binary data can be loaded if length==0 */ + if (!length) + binary = NULL; + /* Page 68, section 7.2 'Shader Binaries" of the of the OpenGL ES 3.1, and * page 88 of the OpenGL 4.5 specs state: * @@ -2588,7 +2632,6 @@ _mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, shProg); _mesa_reference_program(ctx, target, prog); _mesa_update_allow_draw_out_of_order(ctx); - _mesa_update_primitive_id_is_unused(ctx); _mesa_update_valid_to_render_state(ctx); if (stage == MESA_SHADER_VERTEX) _mesa_update_vertex_processing_mode(ctx); @@ -2599,51 +2642,13 @@ _mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, /** - * Copy program-specific data generated by linking from the gl_shader_program - * object to the gl_program object referred to by the gl_linked_shader. - * - * This function expects _mesa_reference_program() to have been previously - * called setting the gl_linked_shaders program reference. - */ -void -_mesa_copy_linked_program_data(const struct gl_shader_program *src, - struct gl_linked_shader *dst_sh) -{ - assert(dst_sh->Program); - - struct gl_program *dst = dst_sh->Program; - - dst->info.separate_shader = src->SeparateShader; - - switch (dst_sh->Stage) { - case MESA_SHADER_GEOMETRY: { - dst->info.gs.vertices_in = src->Geom.VerticesIn; - dst->info.gs.uses_end_primitive = src->Geom.UsesEndPrimitive; - dst->info.gs.active_stream_mask = src->Geom.ActiveStreamMask; - break; - } - case MESA_SHADER_FRAGMENT: { - dst->info.fs.depth_layout = src->FragDepthLayout; - break; - } - case MESA_SHADER_COMPUTE: { - dst->info.shared_size = src->Comp.SharedSize; - break; - } - default: - break; - } -} - -/** * ARB_separate_shader_objects: Compile & Link Program */ -GLuint GLAPIENTRY -_mesa_CreateShaderProgramv(GLenum type, GLsizei count, - const GLchar* const *strings) +GLuint +_mesa_CreateShaderProgramv_impl(struct gl_context *ctx, + GLenum type, GLsizei count, + const GLchar* const *strings) { - GET_CURRENT_CONTEXT(ctx); - const GLuint shader = create_shader_err(ctx, type, "glCreateShaderProgramv"); GLuint program = 0; @@ -2695,6 +2700,27 @@ _mesa_CreateShaderProgramv(GLenum type, GLsizei count, return program; } +/** + * ARB_separate_shader_objects: Compile & Link Program + */ +GLuint GLAPIENTRY +_mesa_CreateShaderProgramv(GLenum type, GLsizei count, + const GLchar* const *strings) +{ + GET_CURRENT_CONTEXT(ctx); + + return _mesa_CreateShaderProgramv_impl(ctx, type, count, strings); +} + +static void +set_patch_vertices(struct gl_context *ctx, GLint value) +{ + if (ctx->TessCtrlProgram.patch_vertices != value) { + FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT); + ctx->NewDriverState |= ST_NEW_TESS_STATE; + ctx->TessCtrlProgram.patch_vertices = value; + } +} /** * For GL_ARB_tessellation_shader @@ -2703,8 +2729,8 @@ void GLAPIENTRY _mesa_PatchParameteri_no_error(GLenum pname, GLint value) { GET_CURRENT_CONTEXT(ctx); - FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT); - ctx->TessCtrlProgram.patch_vertices = value; + + set_patch_vertices(ctx, value); } @@ -2728,8 +2754,7 @@ _mesa_PatchParameteri(GLenum pname, GLint value) return; } - FLUSH_VERTICES(ctx, 0, GL_CURRENT_BIT); - ctx->TessCtrlProgram.patch_vertices = value; + set_patch_vertices(ctx, value); } @@ -2748,13 +2773,13 @@ _mesa_PatchParameterfv(GLenum pname, const GLfloat *values) FLUSH_VERTICES(ctx, 0, 0); memcpy(ctx->TessCtrlProgram.patch_default_outer_level, values, 4 * sizeof(GLfloat)); - ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels; + ctx->NewDriverState |= ST_NEW_TESS_STATE; return; case GL_PATCH_DEFAULT_INNER_LEVEL: FLUSH_VERTICES(ctx, 0, 0); memcpy(ctx->TessCtrlProgram.patch_default_inner_level, values, 2 * sizeof(GLfloat)); - ctx->NewDriverState |= ctx->DriverFlags.NewDefaultTessLevels; + ctx->NewDriverState |= ST_NEW_TESS_STATE; return; default: _mesa_error(ctx, GL_INVALID_ENUM, "glPatchParameterfv"); @@ -2904,7 +2929,7 @@ _mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, case GL_UNIFORM_NAME_LENGTH: res = _mesa_program_resource_find_index(shProg, resource_type, index); if (res) { - values[0] = strlen(_mesa_program_resource_name(res)) + 1 + values[0] = _mesa_program_resource_name_length(res) + 1 + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0); } break; @@ -3149,7 +3174,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, for (i = 0; i < p->sh.NumSubroutineFunctions; i++) { res = _mesa_program_resource_find_index(shProg, resource_type, i); if (res) { - const GLint len = strlen(_mesa_program_resource_name(res)) + 1; + const GLint len = _mesa_program_resource_name_length(res) + 1; if (len > max_len) max_len = len; } @@ -3168,7 +3193,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, for (i = 0; i < p->sh.NumSubroutineUniformRemapTable; i++) { res = _mesa_program_resource_find_index(shProg, resource_type, i); if (res) { - const GLint len = strlen(_mesa_program_resource_name(res)) + 1 + const GLint len = _mesa_program_resource_name_length(res) + 1 + ((_mesa_program_resource_array_size(res) != 0) ? 3 : 0); if (len > max_len) @@ -3190,8 +3215,7 @@ _mesa_GetProgramStageiv(GLuint program, GLenum shadertype, */ struct sh_incl_path_entry { - struct sh_incl_path_entry *next; - struct sh_incl_path_entry *prev; + struct list_head list; char *path; }; @@ -3243,6 +3267,7 @@ destroy_shader_include(struct hash_entry *entry) _mesa_hash_table_destroy(sh_incl_ht_entry->path, destroy_shader_include); free(sh_incl_ht_entry->shader_source); free(sh_incl_ht_entry); + free((void *)entry->key); } void @@ -3308,8 +3333,8 @@ validate_and_tokenise_sh_incl(struct gl_context *ctx, char *path_str = strtok_r(full_path, "/", &save_ptr); *path_list = rzalloc(mem_ctx, struct sh_incl_path_entry); - - make_empty_list(*path_list); + struct sh_incl_path_entry * list = *path_list; + list_inithead(&list->list); while (path_str != NULL) { if (strlen(path_str) == 0) { @@ -3324,14 +3349,13 @@ validate_and_tokenise_sh_incl(struct gl_context *ctx, if (strcmp(path_str, ".") == 0) { /* Do nothing */ } else if (strcmp(path_str, "..") == 0) { - struct sh_incl_path_entry *last = last_elem(*path_list); - remove_from_list(last); + list_del(list->list.prev); } else { struct sh_incl_path_entry *path = rzalloc(mem_ctx, struct sh_incl_path_entry); - path->path = strdup(path_str); - insert_at_tail(*path_list, path); + path->path = ralloc_strdup(mem_ctx, path_str); + list_addtail(&path->list, &list->list); } path_str = strtok_r(NULL, "/", &save_ptr); @@ -3371,7 +3395,7 @@ next_relative_path: { struct sh_incl_path_entry *rel_path_list = ctx->Shared->ShaderIncludes->include_paths[i]; - foreach(entry, rel_path_list) { + LIST_FOR_EACH_ENTRY(entry, &rel_path_list->list, list) { struct hash_entry *ht_entry = _mesa_hash_table_search(path_ht, entry->path); @@ -3400,7 +3424,7 @@ next_relative_path: } } - foreach(entry, path_list) { + LIST_FOR_EACH_ENTRY(entry, &path_list->list, list) { struct hash_entry *ht_entry = _mesa_hash_table_search(path_ht, entry->path); @@ -3502,13 +3526,13 @@ _mesa_NamedStringARB(GLenum type, GLint namelen, const GLchar *name, return; } - mtx_lock(&ctx->Shared->ShaderIncludeMutex); + simple_mtx_lock(&ctx->Shared->ShaderIncludeMutex); struct hash_table *path_ht = ctx->Shared->ShaderIncludes->shader_include_tree; struct sh_incl_path_entry *entry; - foreach(entry, path_list) { + LIST_FOR_EACH_ENTRY(entry, &path_list->list, list) { struct hash_entry *ht_entry = _mesa_hash_table_search(path_ht, entry->path); @@ -3518,20 +3542,21 @@ _mesa_NamedStringARB(GLenum type, GLint namelen, const GLchar *name, sh_incl_ht_entry->path = _mesa_hash_table_create(NULL, _mesa_hash_string, _mesa_key_string_equal); - _mesa_hash_table_insert(path_ht, entry->path, sh_incl_ht_entry); + _mesa_hash_table_insert(path_ht, strdup(entry->path), + sh_incl_ht_entry); } else { sh_incl_ht_entry = (struct sh_incl_path_ht_entry *) ht_entry->data; } path_ht = sh_incl_ht_entry->path; - if (last_elem(path_list) == entry) { + if (list_last_entry(&path_list->list, struct sh_incl_path_entry, list) == entry) { free(sh_incl_ht_entry->shader_source); sh_incl_ht_entry->shader_source = string_cp; } } - mtx_unlock(&ctx->Shared->ShaderIncludeMutex); + simple_mtx_unlock(&ctx->Shared->ShaderIncludeMutex); free(name_cp); ralloc_free(mem_ctx); @@ -3557,12 +3582,12 @@ _mesa_DeleteNamedStringARB(GLint namelen, const GLchar *name) return; } - mtx_lock(&ctx->Shared->ShaderIncludeMutex); + simple_mtx_lock(&ctx->Shared->ShaderIncludeMutex); free(shader_include->shader_source); shader_include->shader_source = NULL; - mtx_unlock(&ctx->Shared->ShaderIncludeMutex); + simple_mtx_unlock(&ctx->Shared->ShaderIncludeMutex); free(name_cp); } @@ -3582,7 +3607,7 @@ _mesa_CompileShaderIncludeARB(GLuint shader, GLsizei count, void *mem_ctx = ralloc_context(NULL); - mtx_lock(&ctx->Shared->ShaderIncludeMutex); + simple_mtx_lock(&ctx->Shared->ShaderIncludeMutex); ctx->Shared->ShaderIncludes->include_paths = ralloc_array_size(mem_ctx, sizeof(struct sh_incl_path_entry *), count); @@ -3626,7 +3651,7 @@ exit: ctx->Shared->ShaderIncludes->relative_path_cursor = 0; ctx->Shared->ShaderIncludes->include_paths = NULL; - mtx_unlock(&ctx->Shared->ShaderIncludeMutex); + simple_mtx_unlock(&ctx->Shared->ShaderIncludeMutex); ralloc_free(mem_ctx); } diff --git a/src/mesa/main/shaderapi.h b/src/mesa/main/shaderapi.h index 10ef268f8fd..d46a3d688ba 100644 --- a/src/mesa/main/shaderapi.h +++ b/src/mesa/main/shaderapi.h @@ -28,15 +28,15 @@ #define SHADERAPI_H -#include "glheader.h" -#include "main/mtypes.h" +#include "util/glheader.h" #include "compiler/shader_enums.h" +#include "util/mesa-sha1.h" #ifdef __cplusplus extern "C" { #endif - +struct hash_entry; struct _glapi_table; struct gl_context; struct gl_linked_shader; @@ -45,6 +45,9 @@ struct gl_program; struct gl_program_resource; struct gl_shader; struct gl_shader_program; +struct gl_resource_name; +struct gl_shared_state; +struct gl_uniform_block; extern GLbitfield _mesa_get_shader_flags(void); @@ -80,207 +83,26 @@ extern void _mesa_shader_write_subroutine_indices(struct gl_context *ctx, gl_shader_stage stage); -void GLAPIENTRY -_mesa_AttachObjectARB_no_error(GLhandleARB, GLhandleARB); - -extern void GLAPIENTRY -_mesa_AttachObjectARB(GLhandleARB, GLhandleARB); - -extern void GLAPIENTRY -_mesa_CompileShader(GLuint); - -extern GLhandleARB GLAPIENTRY -_mesa_CreateProgramObjectARB(void); - -GLhandleARB GLAPIENTRY -_mesa_CreateShaderObjectARB_no_error(GLenum type); - -extern GLhandleARB GLAPIENTRY -_mesa_CreateShaderObjectARB(GLenum type); - -extern void GLAPIENTRY -_mesa_DeleteObjectARB(GLhandleARB obj); - -void GLAPIENTRY -_mesa_DetachObjectARB_no_error(GLhandleARB, GLhandleARB); - -extern void GLAPIENTRY -_mesa_DetachObjectARB(GLhandleARB, GLhandleARB); - -extern void GLAPIENTRY -_mesa_GetAttachedObjectsARB(GLhandleARB, GLsizei, GLsizei *, GLhandleARB *); - -extern GLint GLAPIENTRY -_mesa_GetFragDataLocation(GLuint program, const GLchar *name); - -extern GLint GLAPIENTRY -_mesa_GetFragDataIndex(GLuint program, const GLchar *name); - -extern GLhandleARB GLAPIENTRY -_mesa_GetHandleARB(GLenum pname); - -extern void GLAPIENTRY -_mesa_GetInfoLogARB(GLhandleARB, GLsizei, GLsizei *, GLcharARB *); - -extern void GLAPIENTRY -_mesa_GetObjectParameterfvARB(GLhandleARB, GLenum, GLfloat *); - -extern void GLAPIENTRY -_mesa_GetObjectParameterivARB(GLhandleARB, GLenum, GLint *); - -extern void GLAPIENTRY -_mesa_GetShaderSource(GLuint, GLsizei, GLsizei *, GLchar *); - -extern GLboolean GLAPIENTRY -_mesa_IsProgram(GLuint name); - -extern GLboolean GLAPIENTRY -_mesa_IsShader(GLuint name); - -void GLAPIENTRY -_mesa_LinkProgram_no_error(GLuint programObj); - -extern void GLAPIENTRY -_mesa_LinkProgram(GLuint programObj); - -void GLAPIENTRY -_mesa_ShaderSource_no_error(GLuint, GLsizei, const GLchar* const *, - const GLint *); - -extern void GLAPIENTRY -_mesa_ShaderSource(GLuint, GLsizei, const GLchar* const *, const GLint *); - -void GLAPIENTRY -_mesa_UseProgram_no_error(GLuint); -extern void GLAPIENTRY -_mesa_UseProgram(GLuint); - -extern void GLAPIENTRY -_mesa_ValidateProgram(GLuint); - - -void GLAPIENTRY -_mesa_BindAttribLocation_no_error(GLuint program, GLuint, const GLchar *); - -extern void GLAPIENTRY -_mesa_BindAttribLocation(GLuint program, GLuint, const GLchar *); - -extern void GLAPIENTRY -_mesa_BindFragDataLocation(GLuint program, GLuint colorNumber, - const GLchar *name); - -extern void GLAPIENTRY -_mesa_BindFragDataLocationIndexed(GLuint program, GLuint colorNumber, - GLuint index, const GLchar *name); - -extern void GLAPIENTRY -_mesa_BindFragDataLocation_no_error(GLuint program, GLuint colorNumber, - const GLchar *name); - -extern void GLAPIENTRY -_mesa_BindFragDataLocationIndexed_no_error(GLuint program, GLuint colorNumber, - GLuint index, const GLchar *name); - -extern void GLAPIENTRY -_mesa_GetActiveAttrib(GLuint, GLuint, GLsizei, GLsizei *, GLint *, - GLenum *, GLchar *); - -extern GLint GLAPIENTRY -_mesa_GetAttribLocation(GLuint, const GLchar *); - -void GLAPIENTRY -_mesa_AttachShader_no_error(GLuint program, GLuint shader); - -extern void GLAPIENTRY -_mesa_AttachShader(GLuint program, GLuint shader); - -GLuint GLAPIENTRY -_mesa_CreateShader_no_error(GLenum); - -extern GLuint GLAPIENTRY -_mesa_CreateShader(GLenum); - -extern GLuint GLAPIENTRY -_mesa_CreateProgram(void); - -extern void GLAPIENTRY -_mesa_DeleteProgram(GLuint program); - -extern void GLAPIENTRY -_mesa_DeleteShader(GLuint shader); - -void GLAPIENTRY -_mesa_DetachShader_no_error(GLuint program, GLuint shader); - -extern void GLAPIENTRY -_mesa_DetachShader(GLuint program, GLuint shader); - -extern void GLAPIENTRY -_mesa_GetAttachedShaders(GLuint program, GLsizei maxCount, - GLsizei *count, GLuint *obj); - -extern void GLAPIENTRY -_mesa_GetProgramiv(GLuint program, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetProgramInfoLog(GLuint program, GLsizei bufSize, - GLsizei *length, GLchar *infoLog); - -extern void GLAPIENTRY -_mesa_GetShaderiv(GLuint shader, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetShaderInfoLog(GLuint shader, GLsizei bufSize, - GLsizei *length, GLchar *infoLog); - - -extern void GLAPIENTRY -_mesa_GetShaderPrecisionFormat(GLenum shadertype, GLenum precisiontype, - GLint *range, GLint *precision); - -extern void GLAPIENTRY -_mesa_ReleaseShaderCompiler(void); - -extern void GLAPIENTRY -_mesa_ShaderBinary(GLint n, const GLuint *shaders, GLenum binaryformat, - const void* binary, GLint length); - -extern void GLAPIENTRY -_mesa_GetProgramBinary(GLuint program, GLsizei bufSize, GLsizei *length, - GLenum *binaryFormat, GLvoid *binary); - -extern void GLAPIENTRY -_mesa_ProgramBinary(GLuint program, GLenum binaryFormat, - const GLvoid *binary, GLsizei length); - -void GLAPIENTRY -_mesa_ProgramParameteri_no_error(GLuint program, GLenum pname, GLint value); - -extern void GLAPIENTRY -_mesa_ProgramParameteri(GLuint program, GLenum pname, GLint value); - void _mesa_use_program(struct gl_context *ctx, gl_shader_stage stage, struct gl_shader_program *shProg, struct gl_program *prog, struct gl_pipeline_object *shTarget); -extern void -_mesa_copy_linked_program_data(const struct gl_shader_program *src, - struct gl_linked_shader *dst_sh); - extern bool _mesa_validate_shader_target(const struct gl_context *ctx, GLenum type); -/* GL_ARB_separate_shader_objects */ -extern GLuint GLAPIENTRY -_mesa_CreateShaderProgramv(GLenum type, GLsizei count, - const GLchar* const *strings); - /* GL_ARB_program_resource_query */ extern const char* _mesa_program_resource_name(struct gl_program_resource *res); +int +_mesa_program_resource_name_length(struct gl_program_resource *res); + +bool +_mesa_program_get_resource_name(struct gl_program_resource *res, + struct gl_resource_name *out); + extern unsigned _mesa_program_resource_array_size(struct gl_program_resource *res); @@ -311,7 +133,7 @@ _mesa_get_program_resource_name(struct gl_shader_program *shProg, const char *caller); extern unsigned -_mesa_program_resource_name_len(struct gl_program_resource *res); +_mesa_program_resource_name_length_array(struct gl_program_resource *res); extern GLint _mesa_program_resource_location(struct gl_shader_program *shProg, @@ -335,84 +157,28 @@ _mesa_get_program_resourceiv(struct gl_shader_program *shProg, GLint *params); extern void -_mesa_create_program_resource_hash(struct gl_shader_program *shProg); - -/* GL_ARB_tessellation_shader */ -void GLAPIENTRY -_mesa_PatchParameteri_no_error(GLenum pname, GLint value); +_mesa_get_program_interfaceiv(struct gl_shader_program *shProg, + GLenum programInterface, GLenum pname, + GLint *params); -extern void GLAPIENTRY -_mesa_PatchParameteri(GLenum pname, GLint value); +extern void +_mesa_program_resource_hash_destroy(struct gl_shader_program *shProg); -extern void GLAPIENTRY -_mesa_PatchParameterfv(GLenum pname, const GLfloat *values); +extern void +_mesa_create_program_resource_hash(struct gl_shader_program *shProg); /* GL_ARB_shader_subroutine */ void _mesa_program_init_subroutine_defaults(struct gl_context *ctx, struct gl_program *prog); -extern GLint GLAPIENTRY -_mesa_GetSubroutineUniformLocation(GLuint program, GLenum shadertype, - const GLchar *name); - -extern GLuint GLAPIENTRY -_mesa_GetSubroutineIndex(GLuint program, GLenum shadertype, - const GLchar *name); - -extern GLvoid GLAPIENTRY -_mesa_GetActiveSubroutineUniformiv(GLuint program, GLenum shadertype, - GLuint index, GLenum pname, GLint *values); - -extern GLvoid GLAPIENTRY -_mesa_GetActiveSubroutineUniformName(GLuint program, GLenum shadertype, - GLuint index, GLsizei bufsize, - GLsizei *length, GLchar *name); - -extern GLvoid GLAPIENTRY -_mesa_GetActiveSubroutineName(GLuint program, GLenum shadertype, - GLuint index, GLsizei bufsize, - GLsizei *length, GLchar *name); - -extern GLvoid GLAPIENTRY -_mesa_UniformSubroutinesuiv(GLenum shadertype, GLsizei count, - const GLuint *indices); - -extern GLvoid GLAPIENTRY -_mesa_GetUniformSubroutineuiv(GLenum shadertype, GLint location, - GLuint *params); - -extern GLvoid GLAPIENTRY -_mesa_GetProgramStageiv(GLuint program, GLenum shadertype, - GLenum pname, GLint *values); - -extern GLvoid GLAPIENTRY -_mesa_NamedStringARB(GLenum type, GLint namelen, const GLchar *name, - GLint stringlen, const GLchar *string); - -extern GLvoid GLAPIENTRY -_mesa_DeleteNamedStringARB(GLint namelen, const GLchar *name); - -extern GLvoid GLAPIENTRY -_mesa_CompileShaderIncludeARB(GLuint shader, GLsizei count, - const GLchar* const *path, const GLint *length); - -extern GLboolean GLAPIENTRY -_mesa_IsNamedStringARB(GLint namelen, const GLchar *name); - -extern GLvoid GLAPIENTRY -_mesa_GetNamedStringARB(GLint namelen, const GLchar *name, GLsizei bufSize, - GLint *stringlen, GLchar *string); - -extern GLvoid GLAPIENTRY -_mesa_GetNamedStringivARB(GLint namelen, const GLchar *name, - GLenum pname, GLint *params); - GLcharARB * -_mesa_read_shader_source(const gl_shader_stage stage, const char *source); +_mesa_read_shader_source(const gl_shader_stage stage, const char *source, + const uint8_t sha1[SHA1_DIGEST_LENGTH]); void -_mesa_dump_shader_source(const gl_shader_stage stage, const char *source); +_mesa_dump_shader_source(const gl_shader_stage stage, const char *source, + const uint8_t sha1[SHA1_DIGEST_LENGTH]); void _mesa_init_shader_includes(struct gl_shared_state *shared); @@ -430,6 +196,10 @@ const char * _mesa_lookup_shader_include(struct gl_context *ctx, char *path, bool error_check); +GLuint +_mesa_CreateShaderProgramv_impl(struct gl_context *ctx, + GLenum type, GLsizei count, + const GLchar* const *strings); #ifdef __cplusplus } #endif diff --git a/src/mesa/main/shaderimage.c b/src/mesa/main/shaderimage.c index cfa229acdb5..64dd8e5376c 100644 --- a/src/mesa/main/shaderimage.c +++ b/src/mesa/main/shaderimage.c @@ -35,6 +35,9 @@ #include "texobj.h" #include "teximage.h" #include "enums.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_context.h" mesa_format _mesa_get_shader_image_format(GLenum format) @@ -589,7 +592,7 @@ bind_image_texture(struct gl_context *ctx, struct gl_texture_object *texObj, u = &ctx->ImageUnits[unit]; FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; + ctx->NewDriverState |= ST_NEW_IMAGE_UNITS; set_image_binding(u, texObj, level, layered, layer, access, format); } @@ -641,11 +644,10 @@ _mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, * so those are excluded from this requirement. * * Additionally, issue 10 of the OES_EGL_image_external_essl3 spec - * states that glBindImageTexture must accept external textures. + * states that glBindImageTexture must accept external texture objects. */ - if (_mesa_is_gles(ctx) && !texObj->Immutable && - texObj->Target != GL_TEXTURE_BUFFER && - texObj->Target != GL_TEXTURE_EXTERNAL_OES) { + if (_mesa_is_gles(ctx) && !texObj->Immutable && !texObj->External && + texObj->Target != GL_TEXTURE_BUFFER) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTexture(!immutable)"); return; @@ -688,7 +690,7 @@ bind_image_textures(struct gl_context *ctx, GLuint first, GLuint count, /* Assume that at least one binding will be changed */ FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; + ctx->NewDriverState |= ST_NEW_IMAGE_UNITS; /* Note that the error semantics for multi-bind commands differ from * those of other GL commands. @@ -709,7 +711,7 @@ bind_image_textures(struct gl_context *ctx, GLuint first, GLuint count, * their parameters are valid and no other error occurs." */ - _mesa_HashLockMutex(ctx->Shared->TexObjects); + _mesa_HashLockMutex(&ctx->Shared->TexObjects); for (i = 0; i < count; i++) { struct gl_image_unit *u = &ctx->ImageUnits[first + i]; @@ -786,7 +788,7 @@ bind_image_textures(struct gl_context *ctx, GLuint first, GLuint count, } } - _mesa_HashUnlockMutex(ctx->Shared->TexObjects); + _mesa_HashUnlockMutex(&ctx->Shared->TexObjects); } void GLAPIENTRY @@ -803,7 +805,8 @@ _mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures) { GET_CURRENT_CONTEXT(ctx); - if (!ctx->Extensions.ARB_shader_image_load_store) { + if (!ctx->Extensions.ARB_shader_image_load_store && + !_mesa_is_gles31(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindImageTextures()"); return; } diff --git a/src/mesa/main/shaderimage.h b/src/mesa/main/shaderimage.h index d43578b192b..2ebb5f2b047 100644 --- a/src/mesa/main/shaderimage.h +++ b/src/mesa/main/shaderimage.h @@ -27,7 +27,7 @@ #ifndef SHADERIMAGE_H #define SHADERIMAGE_H -#include "glheader.h" +#include "util/glheader.h" #include "formats.h" #ifdef __cplusplus @@ -82,28 +82,6 @@ _mesa_free_image_textures(struct gl_context *ctx); GLboolean _mesa_is_image_unit_valid(struct gl_context *ctx, struct gl_image_unit *u); -void GLAPIENTRY -_mesa_BindImageTexture_no_error(GLuint unit, GLuint texture, GLint level, - GLboolean layered, GLint layer, GLenum access, - GLenum format); - -void GLAPIENTRY -_mesa_BindImageTexture(GLuint unit, GLuint texture, GLint level, - GLboolean layered, GLint layer, GLenum access, - GLenum format); - -void GLAPIENTRY -_mesa_BindImageTextureEXT(GLuint unit, GLuint texture, GLint level, - GLboolean layered, GLint layer, GLenum access, - GLint format); - -void GLAPIENTRY -_mesa_BindImageTextures_no_error(GLuint first, GLsizei count, - const GLuint *textures); - -void GLAPIENTRY -_mesa_BindImageTextures(GLuint first, GLsizei count, const GLuint *textures); - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/shaderobj.c b/src/mesa/main/shaderobj.c index 27eab80b94a..2e98c9c1198 100644 --- a/src/mesa/main/shaderobj.c +++ b/src/mesa/main/shaderobj.c @@ -31,7 +31,7 @@ #include "compiler/glsl/string_to_uint_map.h" -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/glspirv.h" #include "main/hash.h" @@ -73,9 +73,9 @@ _reference_shader(struct gl_context *ctx, struct gl_shader **ptr, if (p_atomic_dec_zero(&old->RefCount)) { if (old->Name != 0) { if (skip_locking) - _mesa_HashRemoveLocked(ctx->Shared->ShaderObjects, old->Name); + _mesa_HashRemoveLocked(&ctx->Shared->ShaderObjects, old->Name); else - _mesa_HashRemove(ctx->Shared->ShaderObjects, old->Name); + _mesa_HashRemove(&ctx->Shared->ShaderObjects, old->Name); } _mesa_delete_shader(ctx, old); } @@ -103,8 +103,8 @@ _mesa_init_shader(struct gl_shader *shader) { shader->RefCount = 1; shader->info.Geom.VerticesOut = -1; - shader->info.Geom.InputType = GL_TRIANGLES; - shader->info.Geom.OutputType = GL_TRIANGLE_STRIP; + shader->info.Geom.InputType = MESA_PRIM_TRIANGLES; + shader->info.Geom.OutputType = MESA_PRIM_TRIANGLE_STRIP; } /** @@ -118,9 +118,6 @@ _mesa_new_shader(GLuint name, gl_shader_stage stage) if (shader) { shader->Stage = stage; shader->Name = name; -#ifdef DEBUG - shader->SourceChecksum = 0xa110c; /* alloc */ -#endif _mesa_init_shader(shader); } return shader; @@ -162,7 +159,7 @@ _mesa_lookup_shader(struct gl_context *ctx, GLuint name) { if (name) { struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + _mesa_HashLookup(&ctx->Shared->ShaderObjects, name); /* Note that both gl_shader and gl_shader_program objects are kept * in the same hash table. Check the object's type to be sure it's * what we're expecting. @@ -188,7 +185,7 @@ _mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) } else { struct gl_shader *sh = (struct gl_shader *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + _mesa_HashLookup(&ctx->Shared->ShaderObjects, name); if (!sh) { _mesa_error(ctx, GL_INVALID_VALUE, "%s", caller); return NULL; @@ -208,8 +205,7 @@ _mesa_lookup_shader_err(struct gl_context *ctx, GLuint name, const char *caller) /**********************************************************************/ void -_mesa_reference_shader_program_data(struct gl_context *ctx, - struct gl_shader_program_data **ptr, +_mesa_reference_shader_program_data(struct gl_shader_program_data **ptr, struct gl_shader_program_data *data) { if (*ptr == data) @@ -221,7 +217,6 @@ _mesa_reference_shader_program_data(struct gl_context *ctx, assert(oldData->RefCount > 0); if (p_atomic_dec_zero(&oldData->RefCount)) { - assert(ctx); assert(oldData->NumUniformStorage == 0 || oldData->UniformStorage); @@ -263,11 +258,11 @@ _mesa_reference_shader_program_(struct gl_context *ctx, assert(old->RefCount > 0); if (p_atomic_dec_zero(&old->RefCount)) { - _mesa_HashLockMutex(ctx->Shared->ShaderObjects); + _mesa_HashLockMutex(&ctx->Shared->ShaderObjects); if (old->Name != 0) - _mesa_HashRemoveLocked(ctx->Shared->ShaderObjects, old->Name); + _mesa_HashRemoveLocked(&ctx->Shared->ShaderObjects, old->Name); _mesa_delete_shader_program(ctx, old); - _mesa_HashUnlockMutex(ctx->Shared->ShaderObjects); + _mesa_HashUnlockMutex(&ctx->Shared->ShaderObjects); } *ptr = NULL; @@ -303,9 +298,6 @@ init_shader_program(struct gl_shader_program *prog) prog->FragDataBindings = string_to_uint_map_ctor(); prog->FragDataIndexBindings = string_to_uint_map_ctor(); - prog->Geom.UsesEndPrimitive = false; - prog->Geom.ActiveStreamMask = 0; - prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS; exec_list_make_empty(&prog->EmptyUniformLocations); @@ -357,12 +349,10 @@ _mesa_clear_shader_program_data(struct gl_context *ctx, shProg->UniformHash = NULL; } - if (shProg->data && shProg->data->ProgramResourceHash) { - _mesa_hash_table_u64_destroy(shProg->data->ProgramResourceHash); - shProg->data->ProgramResourceHash = NULL; - } + if (shProg->data) + _mesa_program_resource_hash_destroy(shProg); - _mesa_reference_shader_program_data(ctx, &shProg->data, NULL); + _mesa_reference_shader_program_data(&shProg->data, NULL); } @@ -439,7 +429,7 @@ _mesa_lookup_shader_program(struct gl_context *ctx, GLuint name) struct gl_shader_program *shProg; if (name) { shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + _mesa_HashLookup(&ctx->Shared->ShaderObjects, name); /* Note that both gl_shader and gl_shader_program objects are kept * in the same hash table. Check the object's type to be sure it's * what we're expecting. @@ -466,7 +456,7 @@ _mesa_lookup_shader_program_err_glthread(struct gl_context *ctx, GLuint name, } else { struct gl_shader_program *shProg = (struct gl_shader_program *) - _mesa_HashLookup(ctx->Shared->ShaderObjects, name); + _mesa_HashLookup(&ctx->Shared->ShaderObjects, name); if (!shProg) { _mesa_error_glthread_safe(ctx, GL_INVALID_VALUE, glthread, "%s", caller); @@ -488,10 +478,3 @@ _mesa_lookup_shader_program_err(struct gl_context *ctx, GLuint name, { return _mesa_lookup_shader_program_err_glthread(ctx, name, false, caller); } - - -void -_mesa_init_shader_object_functions(struct dd_function_table *driver) -{ - driver->LinkShader = _mesa_ir_link_shader; -} diff --git a/src/mesa/main/shaderobj.h b/src/mesa/main/shaderobj.h index 8c9cb8bc921..a4a4471920f 100644 --- a/src/mesa/main/shaderobj.h +++ b/src/mesa/main/shaderobj.h @@ -27,9 +27,8 @@ #define SHADEROBJ_H -#include "main/glheader.h" +#include "util/glheader.h" #include "compiler/shader_enums.h" -#include "program/ir_to_mesa.h" #include "util/macros.h" @@ -71,8 +70,7 @@ _mesa_reference_shader_program_(struct gl_context *ctx, struct gl_shader_program *shProg); void -_mesa_reference_shader_program_data(struct gl_context *ctx, - struct gl_shader_program_data **ptr, +_mesa_reference_shader_program_data(struct gl_shader_program_data **ptr, struct gl_shader_program_data *data); static inline void @@ -123,10 +121,6 @@ extern void _mesa_delete_shader_program(struct gl_context *ctx, struct gl_shader_program *shProg); - -extern void -_mesa_init_shader_object_functions(struct dd_function_table *driver); - static inline gl_shader_stage _mesa_shader_enum_to_shader_stage(GLenum v) { diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c index 1a5353479b8..41e05ed56b9 100644 --- a/src/mesa/main/shared.c +++ b/src/mesa/main/shared.c @@ -35,10 +35,12 @@ #include "shared.h" #include "program/program.h" #include "dlist.h" +#include "externalobjects.h" #include "samplerobj.h" #include "shaderapi.h" #include "shaderobj.h" #include "syncobj.h" +#include "texobj.h" #include "texturebindless.h" #include "util/hash_table.h" @@ -69,34 +71,33 @@ _mesa_alloc_shared_state(struct gl_context *ctx) simple_mtx_init(&shared->Mutex, mtx_plain); - shared->DisplayList = _mesa_NewHashTable(); - shared->BitmapAtlas = _mesa_NewHashTable(); - shared->TexObjects = _mesa_NewHashTable(); - shared->Programs = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->DisplayList); + _mesa_InitHashTable(&shared->TexObjects); + _mesa_InitHashTable(&shared->Programs); shared->DefaultVertexProgram = ctx->Driver.NewProgram(ctx, MESA_SHADER_VERTEX, 0, true); shared->DefaultFragmentProgram = ctx->Driver.NewProgram(ctx, MESA_SHADER_FRAGMENT, 0, true); - shared->ATIShaders = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->ATIShaders); shared->DefaultFragmentShader = _mesa_new_ati_fragment_shader(ctx, 0); - shared->ShaderObjects = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->ShaderObjects); - shared->BufferObjects = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->BufferObjects); shared->ZombieBufferObjects = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); /* GL_ARB_sampler_objects */ - shared->SamplerObjects = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->SamplerObjects); /* GL_ARB_bindless_texture */ _mesa_init_shared_handles(shared); /* ARB_shading_language_include */ _mesa_init_shader_includes(shared); - mtx_init(&shared->ShaderIncludeMutex, mtx_plain); + simple_mtx_init(&shared->ShaderIncludeMutex, mtx_plain); /* Create default texture objects */ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { @@ -116,7 +117,7 @@ _mesa_alloc_shared_state(struct gl_context *ctx) GL_TEXTURE_1D }; STATIC_ASSERT(ARRAY_SIZE(targets) == NUM_TEXTURE_TARGETS); - shared->DefaultTex[i] = ctx->Driver.NewTextureObject(ctx, 0, targets[i]); + shared->DefaultTex[i] = _mesa_new_texture_object(ctx, 0, targets[i]); /* Need to explicitly set/overwrite the TargetIndex field here since * the call to _mesa_tex_target_to_index() in NewTextureObject() may * fail if the texture target is not supported. @@ -128,24 +129,26 @@ _mesa_alloc_shared_state(struct gl_context *ctx) assert(shared->DefaultTex[TEXTURE_1D_INDEX]->RefCount == 1); /* Mutex and timestamp for texobj state validation */ - mtx_init(&shared->TexMutex, mtx_recursive); + simple_mtx_init(&shared->TexMutex, mtx_plain); shared->TextureStateStamp = 0; - shared->FrameBuffers = _mesa_NewHashTable(); - shared->RenderBuffers = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->FrameBuffers); + _mesa_InitHashTable(&shared->RenderBuffers); shared->SyncObjects = _mesa_set_create(NULL, _mesa_hash_pointer, _mesa_key_pointer_equal); - shared->MemoryObjects = _mesa_NewHashTable(); - shared->SemaphoreObjects = _mesa_NewHashTable(); + _mesa_InitHashTable(&shared->MemoryObjects); + _mesa_InitHashTable(&shared->SemaphoreObjects); + + shared->GLThread.NoLockDuration = ONE_SECOND_IN_NS; return shared; } /** - * Callback for deleting a display list. Called by _mesa_HashDeleteAll(). + * Callback for deleting a display list. Called by _mesa_DeleteHashTable(). */ static void delete_displaylist_cb(void *data, void *userData) @@ -157,31 +160,19 @@ delete_displaylist_cb(void *data, void *userData) /** - * Callback for deleting a bitmap atlas. Called by _mesa_HashDeleteAll(). - */ -static void -delete_bitmap_atlas_cb(void *data, void *userData) -{ - struct gl_bitmap_atlas *atlas = (struct gl_bitmap_atlas *) data; - struct gl_context *ctx = (struct gl_context *) userData; - _mesa_delete_bitmap_atlas(ctx, atlas); -} - - -/** - * Callback for deleting a texture object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a texture object. Called by _mesa_DeleteHashTable(). */ static void delete_texture_cb(void *data, void *userData) { struct gl_texture_object *texObj = (struct gl_texture_object *) data; struct gl_context *ctx = (struct gl_context *) userData; - ctx->Driver.DeleteTexture(ctx, texObj); + _mesa_delete_texture_object(ctx, texObj); } /** - * Callback for deleting a program object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a program object. Called by _mesa_DeleteHashTable(). */ static void delete_program_cb(void *data, void *userData) @@ -191,14 +182,14 @@ delete_program_cb(void *data, void *userData) if(prog != &_mesa_DummyProgram) { assert(prog->RefCount == 1); /* should only be referenced by hash table */ prog->RefCount = 0; /* now going away */ - ctx->Driver.DeleteProgram(ctx, prog); + _mesa_delete_program(ctx, prog); } } /** * Callback for deleting an ATI fragment shader object. - * Called by _mesa_HashDeleteAll(). + * Called by _mesa_DeleteHashTable(). */ static void delete_fragshader_cb(void *data, void *userData) @@ -210,7 +201,7 @@ delete_fragshader_cb(void *data, void *userData) /** - * Callback for deleting a buffer object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a buffer object. Called by _mesa_DeleteHashTable(). */ static void delete_bufferobj_cb(void *data, void *userData) @@ -241,7 +232,7 @@ free_shader_program_data_cb(void *data, void *userData) /** * Callback for deleting shader and shader programs objects. - * Called by _mesa_HashDeleteAll(). + * Called by _mesa_DeleteHashTable(). */ static void delete_shader_cb(void *data, void *userData) @@ -260,7 +251,7 @@ delete_shader_cb(void *data, void *userData) /** - * Callback for deleting a framebuffer object. Called by _mesa_HashDeleteAll() + * Callback for deleting a framebuffer object. Called by _mesa_DeleteHashTable() */ static void delete_framebuffer_cb(void *data, UNUSED void *userData) @@ -281,7 +272,7 @@ delete_framebuffer_cb(void *data, UNUSED void *userData) /** - * Callback for deleting a renderbuffer object. Called by _mesa_HashDeleteAll() + * Callback for deleting a renderbuffer object. Called by _mesa_DeleteHashTable() */ static void delete_renderbuffer_cb(void *data, void *userData) @@ -295,7 +286,7 @@ delete_renderbuffer_cb(void *data, void *userData) /** - * Callback for deleting a sampler object. Called by _mesa_HashDeleteAll() + * Callback for deleting a sampler object. Called by _mesa_DeleteHashTable() */ static void delete_sampler_object_cb(void *data, void *userData) @@ -306,25 +297,25 @@ delete_sampler_object_cb(void *data, void *userData) } /** - * Callback for deleting a memory object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a memory object. Called by _mesa_DeleteHashTable(). */ static void delete_memory_object_cb(void *data, void *userData) { struct gl_memory_object *memObj = (struct gl_memory_object *) data; struct gl_context *ctx = (struct gl_context *) userData; - ctx->Driver.DeleteMemoryObject(ctx, memObj); + _mesa_delete_memory_object(ctx, memObj); } /** - * Callback for deleting a memory object. Called by _mesa_HashDeleteAll(). + * Callback for deleting a memory object. Called by _mesa_DeleteHashTable(). */ static void delete_semaphore_object_cb(void *data, void *userData) { struct gl_semaphore_object *semObj = (struct gl_semaphore_object *) data; struct gl_context *ctx = (struct gl_context *) userData; - ctx->Driver.DeleteSemaphoreObject(ctx, semObj); + _mesa_delete_semaphore_object(ctx, semObj); } /** @@ -346,33 +337,22 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) /* Free the dummy/fallback texture objects */ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { - if (shared->FallbackTex[i]) - ctx->Driver.DeleteTexture(ctx, shared->FallbackTex[i]); + for (unsigned j = 0; j < ARRAY_SIZE(shared->FallbackTex[0]); j++) { + if (shared->FallbackTex[i][j]) + _mesa_delete_texture_object(ctx, shared->FallbackTex[i][j]); + } } /* * Free display lists */ - if (shared->DisplayList) { - _mesa_HashDeleteAll(shared->DisplayList, delete_displaylist_cb, ctx); - _mesa_DeleteHashTable(shared->DisplayList); - } + _mesa_DeinitHashTable(&shared->DisplayList, delete_displaylist_cb, ctx); + free(shared->small_dlist_store.ptr); + util_idalloc_fini(&shared->small_dlist_store.free_idx); - if (shared->BitmapAtlas) { - _mesa_HashDeleteAll(shared->BitmapAtlas, delete_bitmap_atlas_cb, ctx); - _mesa_DeleteHashTable(shared->BitmapAtlas); - } - - if (shared->ShaderObjects) { - _mesa_HashWalk(shared->ShaderObjects, free_shader_program_data_cb, ctx); - _mesa_HashDeleteAll(shared->ShaderObjects, delete_shader_cb, ctx); - _mesa_DeleteHashTable(shared->ShaderObjects); - } - - if (shared->Programs) { - _mesa_HashDeleteAll(shared->Programs, delete_program_cb, ctx); - _mesa_DeleteHashTable(shared->Programs); - } + _mesa_HashWalk(&shared->ShaderObjects, free_shader_program_data_cb, ctx); + _mesa_DeinitHashTable(&shared->ShaderObjects, delete_shader_cb, ctx); + _mesa_DeinitHashTable(&shared->Programs, delete_program_cb, ctx); if (shared->DefaultVertexProgram) _mesa_reference_program(ctx, &shared->DefaultVertexProgram, NULL); @@ -383,15 +363,8 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) if (shared->DefaultFragmentShader) _mesa_delete_ati_fragment_shader(ctx, shared->DefaultFragmentShader); - if (shared->ATIShaders) { - _mesa_HashDeleteAll(shared->ATIShaders, delete_fragshader_cb, ctx); - _mesa_DeleteHashTable(shared->ATIShaders); - } - - if (shared->BufferObjects) { - _mesa_HashDeleteAll(shared->BufferObjects, delete_bufferobj_cb, ctx); - _mesa_DeleteHashTable(shared->BufferObjects); - } + _mesa_DeinitHashTable(&shared->ATIShaders, delete_fragshader_cb, ctx); + _mesa_DeinitHashTable(&shared->BufferObjects, delete_bufferobj_cb, ctx); if (shared->ZombieBufferObjects) { set_foreach(shared->ZombieBufferObjects, entry) { @@ -400,15 +373,8 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) _mesa_set_destroy(shared->ZombieBufferObjects, NULL); } - if (shared->FrameBuffers) { - _mesa_HashDeleteAll(shared->FrameBuffers, delete_framebuffer_cb, ctx); - _mesa_DeleteHashTable(shared->FrameBuffers); - } - - if (shared->RenderBuffers) { - _mesa_HashDeleteAll(shared->RenderBuffers, delete_renderbuffer_cb, ctx); - _mesa_DeleteHashTable(shared->RenderBuffers); - } + _mesa_DeinitHashTable(&shared->FrameBuffers, delete_framebuffer_cb, ctx); + _mesa_DeinitHashTable(&shared->RenderBuffers, delete_renderbuffer_cb, ctx); if (shared->SyncObjects) { set_foreach(shared->SyncObjects, entry) { @@ -418,49 +384,37 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) _mesa_set_destroy(shared->SyncObjects, NULL); } - if (shared->SamplerObjects) { - _mesa_HashDeleteAll(shared->SamplerObjects, delete_sampler_object_cb, - ctx); - _mesa_DeleteHashTable(shared->SamplerObjects); - } + _mesa_DeinitHashTable(&shared->SamplerObjects, delete_sampler_object_cb, + ctx); /* * Free texture objects (after FBOs since some textures might have * been bound to FBOs). */ - assert(ctx->Driver.DeleteTexture); /* the default textures */ for (i = 0; i < NUM_TEXTURE_TARGETS; i++) { if (shared->DefaultTex[i]) - ctx->Driver.DeleteTexture(ctx, shared->DefaultTex[i]); + _mesa_delete_texture_object(ctx, shared->DefaultTex[i]); } /* all other textures */ - if (shared->TexObjects) { - _mesa_HashDeleteAll(shared->TexObjects, delete_texture_cb, ctx); - _mesa_DeleteHashTable(shared->TexObjects); - } + _mesa_DeinitHashTable(&shared->TexObjects, delete_texture_cb, ctx); _mesa_free_shared_handles(shared); /* ARB_shading_language_include */ _mesa_destroy_shader_includes(shared); - mtx_destroy(&shared->ShaderIncludeMutex); + simple_mtx_destroy(&shared->ShaderIncludeMutex); - if (shared->MemoryObjects) { - _mesa_HashDeleteAll(shared->MemoryObjects, delete_memory_object_cb, ctx); - _mesa_DeleteHashTable(shared->MemoryObjects); - } - - if (shared->SemaphoreObjects) { - _mesa_HashDeleteAll(shared->SemaphoreObjects, delete_semaphore_object_cb, ctx); - _mesa_DeleteHashTable(shared->SemaphoreObjects); - } + _mesa_DeinitHashTable(&shared->MemoryObjects, delete_memory_object_cb, + ctx); + _mesa_DeinitHashTable(&shared->SemaphoreObjects, + delete_semaphore_object_cb, ctx); simple_mtx_destroy(&shared->Mutex); - mtx_destroy(&shared->TexMutex); + simple_mtx_destroy(&shared->TexMutex); - free(shared); + FREE(shared); } diff --git a/src/mesa/main/sse_minmax.c b/src/mesa/main/sse_minmax.c index 2e3471625a1..c8c1fe04301 100644 --- a/src/mesa/main/sse_minmax.c +++ b/src/mesa/main/sse_minmax.c @@ -26,6 +26,7 @@ */ #include "main/sse_minmax.h" +#include "util/macros.h" #include <smmintrin.h> #include <stdint.h> @@ -54,8 +55,8 @@ _mesa_uint_array_min_max(const unsigned *ui_indices, unsigned *min_index, * find the actual tipping point. */ if (aligned_count >= 8) { - unsigned max_arr[4] __attribute__ ((aligned (16))); - unsigned min_arr[4] __attribute__ ((aligned (16))); + alignas(16) unsigned max_arr[4]; + alignas(16) unsigned min_arr[4]; unsigned vec_count; __m128i max_ui4 = _mm_setzero_si128(); __m128i min_ui4 = _mm_set1_epi32(~0U); diff --git a/src/mesa/main/state.c b/src/mesa/main/state.c index 38fd54ef0d1..784dafd07ff 100644 --- a/src/mesa/main/state.c +++ b/src/mesa/main/state.c @@ -31,7 +31,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "mtypes.h" #include "arrayobj.h" #include "context.h" @@ -55,6 +55,8 @@ #include "viewport.h" #include "blend.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_util.h" void _mesa_update_allow_draw_out_of_order(struct gl_context *ctx) @@ -89,9 +91,11 @@ _mesa_update_allow_draw_out_of_order(struct gl_context *ctx) * for driver-internal reasons. */ /* Only the compatibility profile with immediate mode needs this. */ - if (ctx->API != API_OPENGL_COMPAT || !ctx->Const.AllowDrawOutOfOrder) + if (!ctx->Const.AllowDrawOutOfOrder) return; + assert(_mesa_is_desktop_gl_compat(ctx)); + /* If all of these are NULL, GLSL is disabled. */ struct gl_program *vs = ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX]; @@ -146,45 +150,34 @@ _mesa_update_allow_draw_out_of_order(struct gl_context *ctx) FLUSH_VERTICES(ctx, 0, 0); } - -void -_mesa_update_primitive_id_is_unused(struct gl_context *ctx) +uint64_t +_mesa_get_active_states(struct gl_context *ctx) { - /* Only the compatibility profile with display lists needs this. */ - if (ctx->API != API_OPENGL_COMPAT || ctx->Const.AllowIncorrectPrimitiveId) - return; - - /* If all of these are NULL, GLSL is disabled. */ - struct gl_program *tcs = - ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_CTRL]; - struct gl_program *tes = - ctx->_Shader->CurrentProgram[MESA_SHADER_TESS_EVAL]; - struct gl_program *gs = - ctx->_Shader->CurrentProgram[MESA_SHADER_GEOMETRY]; - struct gl_program *fs = - ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT]; - - /* Update ctx->_PrimitiveIDIsUnused for display list if - * allow_incorrect_primitive_id isn't enabled. - * We can use merged primitives (see vbo_save) for drawing unless - * one program expects a correct primitive-ID value. - */ - /* TODO: it may be possible to relax the restriction in some cases. If the current - * geometry shader doesn't read gl_PrimitiveIDIn but does write gl_PrimitiveID, - * then the restriction on fragment shaders reading gl_PrimitiveID can be lifted. - */ - ctx->_PrimitiveIDIsUnused = !( - (tcs && (BITSET_TEST(tcs->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID) || - tcs->info.inputs_read & VARYING_BIT_PRIMITIVE_ID)) || - (tes && (BITSET_TEST(tes->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID) || - tes->info.inputs_read & VARYING_BIT_PRIMITIVE_ID)) || - (gs && (BITSET_TEST(gs->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID) || - gs->info.inputs_read & VARYING_BIT_PRIMITIVE_ID)) || - (fs && (BITSET_TEST(fs->info.system_values_read, SYSTEM_VALUE_PRIMITIVE_ID) || - fs->info.inputs_read & VARYING_BIT_PRIMITIVE_ID))); + struct gl_program *vp = ctx->VertexProgram._Current; + struct gl_program *tcp = ctx->TessCtrlProgram._Current; + struct gl_program *tep = ctx->TessEvalProgram._Current; + struct gl_program *gp = ctx->GeometryProgram._Current; + struct gl_program *fp = ctx->FragmentProgram._Current; + struct gl_program *cp = ctx->ComputeProgram._Current; + uint64_t active_shader_states = 0; + + if (vp) + active_shader_states |= vp->affected_states; + if (tcp) + active_shader_states |= tcp->affected_states; + if (tep) + active_shader_states |= tep->affected_states; + if (gp) + active_shader_states |= gp->affected_states; + if (fp) + active_shader_states |= fp->affected_states; + if (cp) + active_shader_states |= cp->affected_states; + + /* Mark non-shader-resource shader states as "always active". */ + return active_shader_states | ~ST_ALL_SHADER_RESOURCES; } - /** * Update the ctx->*Program._Current pointers to point to the * current/active programs. @@ -219,6 +212,12 @@ update_program(struct gl_context *ctx) const struct gl_program *prevTCP = ctx->TessCtrlProgram._Current; const struct gl_program *prevTEP = ctx->TessEvalProgram._Current; const struct gl_program *prevCP = ctx->ComputeProgram._Current; + uint64_t prev_vp_affected_states = prevVP ? prevVP->affected_states : 0; + uint64_t prev_tcp_affected_states = prevTCP ? prevTCP->affected_states : 0; + uint64_t prev_tep_affected_states = prevTEP ? prevTEP->affected_states : 0; + uint64_t prev_gp_affected_states = prevGP ? prevGP->affected_states : 0; + uint64_t prev_fp_affected_states = prevFP ? prevFP->affected_states : 0; + uint64_t prev_cp_affected_states = prevCP ? prevCP->affected_states : 0; /* * Set the ctx->VertexProgram._Current and ctx->FragmentProgram._Current @@ -242,62 +241,25 @@ update_program(struct gl_context *ctx) _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, fsProg); _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); - } - else if (_mesa_arb_fragment_program_enabled(ctx)) { + } else if (_mesa_arb_fragment_program_enabled(ctx)) { /* Use user-defined fragment program */ _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, ctx->FragmentProgram.Current); _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); - } - else if (_mesa_ati_fragment_shader_enabled(ctx) && + } else if (_mesa_ati_fragment_shader_enabled(ctx) && ctx->ATIFragmentShader.Current->Program) { /* Use the enabled ATI fragment shader's associated program */ _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, ctx->ATIFragmentShader.Current->Program); _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, NULL); - } - else if (ctx->FragmentProgram._MaintainTexEnvProgram) { + } else { /* Use fragment program generated from fixed-function state */ - struct gl_shader_program *f = _mesa_get_fixed_func_fragment_program(ctx); - _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, - f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); - _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, - f->_LinkedShaders[MESA_SHADER_FRAGMENT]->Program); - } - else { - /* No fragment program */ - _mesa_reference_program(ctx, &ctx->FragmentProgram._Current, NULL); + _mesa_get_fixed_func_fragment_program(ctx)); _mesa_reference_program(ctx, &ctx->FragmentProgram._TexEnvProgram, - NULL); - } - - if (gsProg) { - /* Use GLSL geometry shader */ - _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg); - } else { - /* No geometry program */ - _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, NULL); - } - - if (tesProg) { - /* Use GLSL tessellation evaluation shader */ - _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg); - } - else { - /* No tessellation evaluation program */ - _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, NULL); - } - - if (tcsProg) { - /* Use GLSL tessellation control shader */ - _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg); - } - else { - /* No tessellation control program */ - _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, NULL); + ctx->FragmentProgram._Current); } /* Examine vertex program after fragment program as @@ -308,14 +270,12 @@ update_program(struct gl_context *ctx) /* Use GLSL vertex shader */ assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, vsProg); - } - else if (_mesa_arb_vertex_program_enabled(ctx)) { + } else if (_mesa_arb_vertex_program_enabled(ctx)) { /* Use user-defined vertex program */ assert(VP_MODE_SHADER == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, ctx->VertexProgram.Current); - } - else if (ctx->VertexProgram._MaintainTnlProgram) { + } else { /* Use vertex program generated from fixed-function state */ assert(VP_MODE_FF == ctx->VertexProgram._VPMode); _mesa_reference_program(ctx, &ctx->VertexProgram._Current, @@ -323,29 +283,125 @@ update_program(struct gl_context *ctx) _mesa_reference_program(ctx, &ctx->VertexProgram._TnlProgram, ctx->VertexProgram._Current); } - else { - /* no vertex program */ - assert(VP_MODE_FF == ctx->VertexProgram._VPMode); - _mesa_reference_program(ctx, &ctx->VertexProgram._Current, NULL); + + /* Bind or unbind these shaders. (NULL = unbind) */ + _mesa_reference_program(ctx, &ctx->GeometryProgram._Current, gsProg); + _mesa_reference_program(ctx, &ctx->TessEvalProgram._Current, tesProg); + _mesa_reference_program(ctx, &ctx->TessCtrlProgram._Current, tcsProg); + _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg); + + bool vp_changed = ctx->VertexProgram._Current != prevVP; + bool tcp_changed = ctx->TessCtrlProgram._Current != prevTCP; + bool tep_changed = ctx->TessEvalProgram._Current != prevTEP; + bool gp_changed = ctx->GeometryProgram._Current != prevGP; + bool fp_changed = ctx->FragmentProgram._Current != prevFP; + bool cp_changed = ctx->ComputeProgram._Current != prevCP; + + /* Set NewDriverState depending on which shaders have changed. */ + uint64_t dirty = 0; + + /* Flag states used by both new and old shaders to rebind shader resources + * (because shaders pack them and reorder them) and to unbind shader + * resources properly when transitioning to shaders that don't use them. + */ + if (vp_changed) { + ctx->Array.NewVertexElements = true; + dirty |= prev_vp_affected_states; + if (ctx->VertexProgram._Current) + dirty |= ST_NEW_VERTEX_PROGRAM(ctx, ctx->VertexProgram._Current); + } + + if (tcp_changed) { + dirty |= prev_tcp_affected_states; + if (ctx->TessCtrlProgram._Current) + dirty |= ctx->TessCtrlProgram._Current->affected_states; + } + + if (tep_changed) { + dirty |= prev_tep_affected_states; + if (ctx->TessEvalProgram._Current) + dirty |= ctx->TessEvalProgram._Current->affected_states; + } + + if (gp_changed) { + dirty |= prev_gp_affected_states; + if (ctx->GeometryProgram._Current) + dirty |= ctx->GeometryProgram._Current->affected_states; } - if (csProg) { - /* Use GLSL compute shader */ - _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, csProg); + if (fp_changed) { + dirty |= prev_fp_affected_states; + if (ctx->FragmentProgram._Current) + dirty |= ctx->FragmentProgram._Current->affected_states; + + if (!ctx->st->needs_texcoord_semantic) + dirty |= ST_NEW_RASTERIZER; + } + + if (cp_changed) { + dirty |= prev_cp_affected_states; + if (ctx->ComputeProgram._Current) + dirty |= ctx->ComputeProgram._Current->affected_states; + } + + struct gl_program *last_vertex_stage; + bool last_vertex_stage_dirty; + + if (ctx->GeometryProgram._Current) { + last_vertex_stage = ctx->GeometryProgram._Current; + last_vertex_stage_dirty = gp_changed; + } else if (ctx->TessEvalProgram._Current) { + last_vertex_stage = ctx->TessEvalProgram._Current; + last_vertex_stage_dirty = gp_changed | tep_changed; } else { - /* no compute program */ - _mesa_reference_program(ctx, &ctx->ComputeProgram._Current, NULL); + last_vertex_stage = ctx->VertexProgram._Current; + last_vertex_stage_dirty = gp_changed | tep_changed | vp_changed; } - /* Let the driver know what's happening: + /* Find out the number of viewports. This determines how many scissors + * and viewport states we need to update. */ - if (ctx->FragmentProgram._Current != prevFP || - ctx->VertexProgram._Current != prevVP || - ctx->GeometryProgram._Current != prevGP || - ctx->TessEvalProgram._Current != prevTEP || - ctx->TessCtrlProgram._Current != prevTCP || - ctx->ComputeProgram._Current != prevCP) + struct st_context *st = ctx->st; + unsigned num_viewports = 1; + + if (last_vertex_stage && + last_vertex_stage->info.outputs_written & ( + VARYING_BIT_VIEWPORT | VARYING_BIT_VIEWPORT_MASK)) + num_viewports = ctx->Const.MaxViewports; + + if (st->state.num_viewports != num_viewports) { + st->state.num_viewports = num_viewports; + dirty |= ST_NEW_VIEWPORT; + + if (ctx->Scissor.EnableFlags & u_bit_consecutive(0, num_viewports)) + dirty |= ST_NEW_SCISSOR; + } + + if (st->lower_point_size && last_vertex_stage_dirty && + !ctx->VertexProgram.PointSizeEnabled && !ctx->PointSizeIsSet) { + if (ctx->GeometryProgram._Current) { + ctx->NewDriverState |= ST_NEW_GS_CONSTANTS; + } else if (ctx->TessEvalProgram._Current) { + ctx->NewDriverState |= ST_NEW_TES_CONSTANTS; + } else { + ctx->NewDriverState |= ST_NEW_VS_CONSTANTS; + } + } + + ctx->NewDriverState |= dirty; + + /* Let the driver know what's happening: */ + if (fp_changed || vp_changed || gp_changed || tep_changed || + tcp_changed || cp_changed) { + /* This will mask out unused shader resources. */ + st->active_states = _mesa_get_active_states(ctx); + + /* Some drivers need to clean up previous states too */ + if (st->validate_all_dirty_states) + st->active_states |= dirty; + return _NEW_PROGRAM; + } return 0; } @@ -382,7 +438,7 @@ update_program_constants(struct gl_context *ctx) update_single_program_constants(ctx, ctx->FragmentProgram._Current, MESA_SHADER_FRAGMENT); - if (ctx->API == API_OPENGL_COMPAT && + if (_mesa_is_desktop_gl_compat(ctx) && ctx->Const.GLSLVersionCompat >= 150) { new_state |= update_single_program_constants(ctx, ctx->GeometryProgram._Current, @@ -405,14 +461,12 @@ static void update_fixed_func_program_usage(struct gl_context *ctx) { ctx->FragmentProgram._UsesTexEnvProgram = - ctx->FragmentProgram._MaintainTexEnvProgram && !ctx->_Shader->CurrentProgram[MESA_SHADER_FRAGMENT] && /* GLSL*/ !_mesa_arb_fragment_program_enabled(ctx) && !(_mesa_ati_fragment_shader_enabled(ctx) && ctx->ATIFragmentShader.Current->Program); ctx->VertexProgram._UsesTnlProgram = - ctx->VertexProgram._MaintainTnlProgram && !ctx->_Shader->CurrentProgram[MESA_SHADER_VERTEX] && /* GLSL */ !_mesa_arb_vertex_program_enabled(ctx); } @@ -454,8 +508,8 @@ _mesa_update_state_locked( struct gl_context *ctx ) _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer); /* Handle Core and Compatibility contexts separately. */ - if (ctx->API == API_OPENGL_COMPAT || - ctx->API == API_OPENGLES) { + if (_mesa_is_desktop_gl_compat(ctx) || + _mesa_is_gles1(ctx)) { /* Update derived state. */ if (new_state & (_NEW_MODELVIEW|_NEW_PROJECTION)) _mesa_update_modelview_project( ctx, new_state ); @@ -525,7 +579,7 @@ _mesa_update_state_locked( struct gl_context *ctx ) * Also, this is where the driver can invalidate the state of any * active modules (such as swrast_setup, swrast, tnl, etc). */ - ctx->Driver.UpdateState(ctx); + st_invalidate_state(ctx); ctx->NewState = 0; } @@ -540,6 +594,23 @@ _mesa_update_state( struct gl_context *ctx ) _mesa_unlock_context_textures(ctx); } +/* This is the usual entrypoint for state updates in glClear calls: + */ +void +_mesa_update_clear_state( struct gl_context *ctx ) +{ + GLbitfield new_state = ctx->NewState; + + if (MESA_VERBOSE & VERBOSE_STATE) + _mesa_print_state("_mesa_update_clear_state", new_state); + + if (new_state & _NEW_BUFFERS) { + _mesa_update_framebuffer(ctx, ctx->ReadBuffer, ctx->DrawBuffer); + + st_invalidate_buffers(st_context(ctx)); + ctx->NewState &= ~_NEW_BUFFERS; + } +} /** * Used by drivers to tell core Mesa that the driver is going to @@ -568,7 +639,8 @@ set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) return; /* On change we may get new maps into the current values */ - ctx->NewDriverState |= ctx->DriverFlags.NewArray; + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; /* Finally memorize the value */ ctx->VertexProgram._VPMode = m; @@ -577,9 +649,7 @@ set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) * VP_MODE_FF mode and the fixed-func pipeline is emulated by shaders. */ ctx->VertexProgram._VPModeOptimizesConstantAttribs = - m == VP_MODE_FF && - ctx->VertexProgram._MaintainTnlProgram && - ctx->FragmentProgram._MaintainTexEnvProgram; + m == VP_MODE_FF; /* Set a filter mask for the net enabled vao arrays. * This is to mask out arrays that would otherwise supersede required current @@ -604,11 +674,11 @@ set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) assert(ctx->API != API_OPENGLES); /* Other parts of the code assume that inputs[VERT_ATTRIB_POS] through - * inputs[VERT_ATTRIB_FF_MAX] will be non-NULL. However, in OpenGL + * inputs[VERT_ATTRIB_GENERIC0-1] will be non-NULL. However, in OpenGL * ES 2.0+ or OpenGL core profile, none of these arrays should ever * be enabled. */ - if (ctx->API == API_OPENGL_COMPAT) + if (_mesa_is_desktop_gl_compat(ctx)) ctx->VertexProgram._VPModeInputFilter = VERT_BIT_ALL; else ctx->VertexProgram._VPModeInputFilter = VERT_BIT_GENERIC_ALL; @@ -618,11 +688,8 @@ set_vertex_processing_mode(struct gl_context *ctx, gl_vertex_processing_mode m) assert(0); } - /* Since we only track the varying inputs while being in fixed function - * vertex processing mode, we may need to update fixed-func shaders - * for zero-stride vertex attribs. - */ - _mesa_set_varying_vp_inputs(ctx, ctx->Array._DrawVAOEnabledAttribs); + _mesa_set_varying_vp_inputs(ctx, ctx->VertexProgram._VPModeInputFilter & + ctx->Array._DrawVAO->_EnabledWithMapMode); } diff --git a/src/mesa/main/state.h b/src/mesa/main/state.h index 957fd37d320..c7cb6f26e8f 100644 --- a/src/mesa/main/state.h +++ b/src/mesa/main/state.h @@ -31,8 +31,8 @@ extern void _mesa_update_allow_draw_out_of_order(struct gl_context *ctx); -extern void -_mesa_update_primitive_id_is_unused(struct gl_context *ctx); +extern uint64_t +_mesa_get_active_states(struct gl_context *ctx); extern void _mesa_update_state(struct gl_context *ctx); @@ -43,6 +43,12 @@ _mesa_update_state(struct gl_context *ctx); extern void _mesa_update_state_locked(struct gl_context *ctx); +/* + * Update state for glClear calls +*/ +extern void +_mesa_update_clear_state(struct gl_context *ctx); + extern void _mesa_set_vp_override(struct gl_context *ctx, GLboolean flag); diff --git a/src/mesa/main/stencil.c b/src/mesa/main/stencil.c index 0d60234607e..64307faf7cb 100644 --- a/src/mesa/main/stencil.c +++ b/src/mesa/main/stencil.c @@ -47,13 +47,15 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "macros.h" #include "stencil.h" #include "mtypes.h" +#include "api_exec_decl.h" +#include "state_tracker/st_context.h" static GLboolean validate_stencil_op(struct gl_context *ctx, GLenum op) @@ -158,19 +160,12 @@ _mesa_StencilFuncSeparateATI( GLenum frontfunc, GLenum backfunc, GLint ref, GLui ctx->Stencil.Ref[0] == ref && ctx->Stencil.Ref[1] == ref) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.Function[0] = frontfunc; ctx->Stencil.Function[1] = backfunc; ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; - if (ctx->Driver.StencilFuncSeparate) { - ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, - frontfunc, ref, mask); - ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, - backfunc, ref, mask); - } } @@ -197,19 +192,11 @@ stencil_func(struct gl_context *ctx, GLenum func, GLint ref, GLuint mask) ctx->Stencil.ValueMask[face] == mask && ctx->Stencil.Ref[face] == ref) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.Function[face] = func; ctx->Stencil.Ref[face] = ref; ctx->Stencil.ValueMask[face] = mask; - - /* Only propagate the change to the driver if EXT_stencil_two_side - * is enabled. - */ - if (ctx->Driver.StencilFuncSeparate && ctx->Stencil.TestTwoSide) { - ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, func, ref, mask); - } } else { /* set both front and back state */ @@ -220,18 +207,11 @@ stencil_func(struct gl_context *ctx, GLenum func, GLint ref, GLuint mask) ctx->Stencil.Ref[0] == ref && ctx->Stencil.Ref[1] == ref) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.Function[0] = ctx->Stencil.Function[1] = func; ctx->Stencil.Ref[0] = ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[0] = ctx->Stencil.ValueMask[1] = mask; - if (ctx->Driver.StencilFuncSeparate) { - ctx->Driver.StencilFuncSeparate(ctx, - ((ctx->Stencil.TestTwoSide) - ? GL_FRONT : GL_FRONT_AND_BACK), - func, ref, mask); - } } } @@ -286,33 +266,18 @@ _mesa_StencilMask( GLuint mask ) */ if (ctx->Stencil.WriteMask[face] == mask) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.WriteMask[face] = mask; - - /* Only propagate the change to the driver if EXT_stencil_two_side - * is enabled. - */ - if (ctx->Driver.StencilMaskSeparate && ctx->Stencil.TestTwoSide) { - ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, mask); - } } else { /* set both front and back state */ if (ctx->Stencil.WriteMask[0] == mask && ctx->Stencil.WriteMask[1] == mask) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.WriteMask[0] = ctx->Stencil.WriteMask[1] = mask; - if (ctx->Driver.StencilMaskSeparate) { - ctx->Driver.StencilMaskSeparate(ctx, - ((ctx->Stencil.TestTwoSide) - ? GL_FRONT : GL_FRONT_AND_BACK), - mask); - } } } @@ -342,19 +307,11 @@ stencil_op(struct gl_context *ctx, GLenum fail, GLenum zfail, GLenum zpass) ctx->Stencil.ZPassFunc[face] == zpass && ctx->Stencil.FailFunc[face] == fail) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.ZFailFunc[face] = zfail; ctx->Stencil.ZPassFunc[face] = zpass; ctx->Stencil.FailFunc[face] = fail; - - /* Only propagate the change to the driver if EXT_stencil_two_side - * is enabled. - */ - if (ctx->Driver.StencilOpSeparate && ctx->Stencil.TestTwoSide) { - ctx->Driver.StencilOpSeparate(ctx, GL_BACK, fail, zfail, zpass); - } } else { /* set both front and back state */ @@ -365,18 +322,11 @@ stencil_op(struct gl_context *ctx, GLenum fail, GLenum zfail, GLenum zpass) ctx->Stencil.FailFunc[0] == fail && ctx->Stencil.FailFunc[1] == fail) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.ZFailFunc[0] = ctx->Stencil.ZFailFunc[1] = zfail; ctx->Stencil.ZPassFunc[0] = ctx->Stencil.ZPassFunc[1] = zpass; ctx->Stencil.FailFunc[0] = ctx->Stencil.FailFunc[1] = fail; - if (ctx->Driver.StencilOpSeparate) { - ctx->Driver.StencilOpSeparate(ctx, - ((ctx->Stencil.TestTwoSide) - ? GL_FRONT : GL_FRONT_AND_BACK), - fail, zfail, zpass); - } } } @@ -443,20 +393,16 @@ static void stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum sfail, GLenum zfail, GLenum zpass) { - GLboolean set = GL_FALSE; - if (face != GL_BACK) { /* set front */ if (ctx->Stencil.ZFailFunc[0] != zfail || ctx->Stencil.ZPassFunc[0] != zpass || ctx->Stencil.FailFunc[0] != sfail){ - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.ZFailFunc[0] = zfail; ctx->Stencil.ZPassFunc[0] = zpass; ctx->Stencil.FailFunc[0] = sfail; - set = GL_TRUE; } } @@ -465,19 +411,13 @@ stencil_op_separate(struct gl_context *ctx, GLenum face, GLenum sfail, if (ctx->Stencil.ZFailFunc[1] != zfail || ctx->Stencil.ZPassFunc[1] != zpass || ctx->Stencil.FailFunc[1] != sfail) { - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; ctx->Stencil.ZFailFunc[1] = zfail; ctx->Stencil.ZPassFunc[1] = zpass; ctx->Stencil.FailFunc[1] = sfail; - set = GL_TRUE; } } - - if (set && ctx->Driver.StencilOpSeparate) { - ctx->Driver.StencilOpSeparate(ctx, face, sfail, zfail, zpass); - } } @@ -526,9 +466,8 @@ static void stencil_func_separate(struct gl_context *ctx, GLenum face, GLenum func, GLint ref, GLuint mask) { - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; if (face != GL_BACK) { /* set front */ @@ -543,10 +482,6 @@ stencil_func_separate(struct gl_context *ctx, GLenum face, GLenum func, ctx->Stencil.Ref[1] = ref; ctx->Stencil.ValueMask[1] = mask; } - - if (ctx->Driver.StencilFuncSeparate) { - ctx->Driver.StencilFuncSeparate(ctx, face, func, ref, mask); - } } @@ -585,9 +520,8 @@ _mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask) static void stencil_mask_separate(struct gl_context *ctx, GLenum face, GLuint mask) { - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewStencil ? 0 : _NEW_STENCIL, - GL_STENCIL_BUFFER_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewStencil; + FLUSH_VERTICES(ctx, 0, GL_STENCIL_BUFFER_BIT); + ctx->NewDriverState |= ST_NEW_DSA; if (face != GL_BACK) { ctx->Stencil.WriteMask[0] = mask; @@ -596,10 +530,6 @@ stencil_mask_separate(struct gl_context *ctx, GLenum face, GLuint mask) if (face != GL_FRONT) { ctx->Stencil.WriteMask[1] = mask; } - - if (ctx->Driver.StencilMaskSeparate) { - ctx->Driver.StencilMaskSeparate(ctx, face, mask); - } } diff --git a/src/mesa/main/stencil.h b/src/mesa/main/stencil.h index dc371ec36cd..90027cce95e 100644 --- a/src/mesa/main/stencil.h +++ b/src/mesa/main/stencil.h @@ -32,60 +32,11 @@ #define STENCIL_H -#include "glheader.h" +#include "util/glheader.h" #include "macros.h" struct gl_context; -extern void GLAPIENTRY -_mesa_ClearStencil( GLint s ); - - -void GLAPIENTRY -_mesa_StencilFunc_no_error(GLenum func, GLint ref, GLuint mask); - -extern void GLAPIENTRY -_mesa_StencilFunc(GLenum func, GLint ref, GLuint mask); - - -extern void GLAPIENTRY -_mesa_StencilMask( GLuint mask ); - -void GLAPIENTRY -_mesa_StencilOp_no_error(GLenum fail, GLenum zfail, GLenum zpass); - -extern void GLAPIENTRY -_mesa_StencilOp(GLenum fail, GLenum zfail, GLenum zpass); - - -extern void GLAPIENTRY -_mesa_ActiveStencilFaceEXT(GLenum face); - -void GLAPIENTRY -_mesa_StencilOpSeparate_no_error(GLenum face, GLenum fail, GLenum zfail, - GLenum zpass); - -extern void GLAPIENTRY -_mesa_StencilOpSeparate(GLenum face, GLenum fail, GLenum zfail, GLenum zpass); - - -void GLAPIENTRY -_mesa_StencilFuncSeparate_no_error(GLenum face, GLenum func, GLint ref, - GLuint mask); - -extern void GLAPIENTRY -_mesa_StencilFuncSeparate(GLenum face, GLenum func, GLint ref, GLuint mask); - - -extern void GLAPIENTRY -_mesa_StencilFuncSeparateATI(GLenum frontfunc, GLenum backfunc, GLint ref, GLuint mask); - -void GLAPIENTRY -_mesa_StencilMaskSeparate_no_error(GLenum face, GLuint mask); - -extern void GLAPIENTRY -_mesa_StencilMaskSeparate(GLenum face, GLuint mask); - extern void _mesa_init_stencil( struct gl_context * ctx ); diff --git a/src/mesa/main/streaming-load-memcpy.c b/src/mesa/main/streaming-load-memcpy.c deleted file mode 100644 index 32854b60eb2..00000000000 --- a/src/mesa/main/streaming-load-memcpy.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright © 2013 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Matt Turner <mattst88@gmail.com> - * - */ - -#include "main/macros.h" -#include "main/streaming-load-memcpy.h" -#include <smmintrin.h> - -/* Copies memory from src to dst, using SSE 4.1's MOVNTDQA to get streaming - * read performance from uncached memory. - */ -void -_mesa_streaming_load_memcpy(void *restrict dst, void *restrict src, size_t len) -{ - char *restrict d = dst; - char *restrict s = src; - - /* If dst and src are not co-aligned, fallback to memcpy(). */ - if (((uintptr_t)d & 15) != ((uintptr_t)s & 15)) { - memcpy(d, s, len); - return; - } - - /* memcpy() the misaligned header. At the end of this if block, <d> and <s> - * are aligned to a 16-byte boundary or <len> == 0. - */ - if ((uintptr_t)d & 15) { - uintptr_t bytes_before_alignment_boundary = 16 - ((uintptr_t)d & 15); - assert(bytes_before_alignment_boundary < 16); - - memcpy(d, s, MIN2(bytes_before_alignment_boundary, len)); - - d = (char *)ALIGN((uintptr_t)d, 16); - s = (char *)ALIGN((uintptr_t)s, 16); - len -= MIN2(bytes_before_alignment_boundary, len); - } - - if (len >= 64) - _mm_mfence(); - - while (len >= 64) { - __m128i *dst_cacheline = (__m128i *)d; - __m128i *src_cacheline = (__m128i *)s; - - __m128i temp1 = _mm_stream_load_si128(src_cacheline + 0); - __m128i temp2 = _mm_stream_load_si128(src_cacheline + 1); - __m128i temp3 = _mm_stream_load_si128(src_cacheline + 2); - __m128i temp4 = _mm_stream_load_si128(src_cacheline + 3); - - _mm_store_si128(dst_cacheline + 0, temp1); - _mm_store_si128(dst_cacheline + 1, temp2); - _mm_store_si128(dst_cacheline + 2, temp3); - _mm_store_si128(dst_cacheline + 3, temp4); - - d += 64; - s += 64; - len -= 64; - } - - /* memcpy() the tail. */ - if (len) { - memcpy(d, s, len); - } -} diff --git a/src/mesa/main/streaming-load-memcpy.h b/src/mesa/main/streaming-load-memcpy.h deleted file mode 100644 index 9ecb685d660..00000000000 --- a/src/mesa/main/streaming-load-memcpy.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright © 2013 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS - * IN THE SOFTWARE. - * - * Authors: - * Eric Anholt <eric@anholt.net> - * Matt Turner <mattst88@gmail.com> - * - */ - -/* Copies memory from src to dst, using SSE 4.1's MOVNTDQA to get streaming - * read performance from uncached memory. - */ - -#ifndef STREAMING_LOAD_MEMCPY_H -#define STREAMING_LOAD_MEMCPY_H - -#include <stdlib.h> - -void -_mesa_streaming_load_memcpy(void *restrict dst, void *restrict src, size_t len); - -#endif /* STREAMING_LOAD_MEMCPY_H */ diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c index 23b49c981ae..91e15920026 100644 --- a/src/mesa/main/syncobj.c +++ b/src/mesa/main/syncobj.c @@ -56,7 +56,7 @@ */ #include <inttypes.h> -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "macros.h" @@ -65,101 +65,101 @@ #include "util/hash_table.h" #include "util/set.h" #include "util/u_memory.h" +#include "util/perf/cpu_trace.h" #include "syncobj.h" -static struct gl_sync_object * -_mesa_new_sync_object(struct gl_context *ctx) -{ - struct gl_sync_object *s = CALLOC_STRUCT(gl_sync_object); - (void) ctx; - - return s; -} +#include "api_exec_decl.h" +#include "pipe/p_context.h" +#include "pipe/p_screen.h" -static void -_mesa_delete_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj) +/** + * Allocate/init the context state related to sync objects. + */ +void +_mesa_init_sync(struct gl_context *ctx) { (void) ctx; - free(syncObj->Label); - free(syncObj); } -static void -_mesa_fence_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, - GLenum condition, GLbitfield flags) +/** + * Free the context state related to sync objects. + */ +void +_mesa_free_sync_data(struct gl_context *ctx) { (void) ctx; - (void) condition; - (void) flags; - - syncObj->StatusFlag = 1; } - -static void -_mesa_check_sync(struct gl_context *ctx, struct gl_sync_object *syncObj) +static struct gl_sync_object * +new_sync_object(struct gl_context *ctx) { - (void) ctx; - (void) syncObj; + struct gl_sync_object *so = CALLOC_STRUCT(gl_sync_object); - /* No-op for software rendering. Hardware drivers will need to determine - * whether the state of the sync object has changed. - */ + simple_mtx_init(&so->mutex, mtx_plain); + return so; } - static void -_mesa_wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, - GLbitfield flags, GLuint64 timeout) +delete_sync_object(struct gl_context *ctx, + struct gl_sync_object *obj) { - (void) ctx; - (void) syncObj; - (void) flags; - (void) timeout; + struct pipe_screen *screen = ctx->pipe->screen; - /* No-op for software rendering. Hardware drivers will need to wait until - * the state of the sync object changes or the timeout expires. - */ + screen->fence_reference(screen, &obj->fence, NULL); + simple_mtx_destroy(&obj->mutex); + free(obj->Label); + FREE(obj); } - -void -_mesa_init_sync_object_functions(struct dd_function_table *driver) +static void +__client_wait_sync(struct gl_context *ctx, + struct gl_sync_object *obj, + GLbitfield flags, GLuint64 timeout) { - driver->NewSyncObject = _mesa_new_sync_object; - driver->FenceSync = _mesa_fence_sync; - driver->DeleteSyncObject = _mesa_delete_sync_object; - driver->CheckSync = _mesa_check_sync; + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_fence_handle *fence = NULL; - /* Use the same no-op wait function for both. - */ - driver->ClientWaitSync = _mesa_wait_sync; - driver->ServerWaitSync = _mesa_wait_sync; -} - -/** - * Allocate/init the context state related to sync objects. - */ -void -_mesa_init_sync(struct gl_context *ctx) -{ - (void) ctx; -} + MESA_TRACE_FUNC(); + /* If the fence doesn't exist, assume it's signalled. */ + simple_mtx_lock(&obj->mutex); + if (!obj->fence) { + simple_mtx_unlock(&obj->mutex); + obj->StatusFlag = GL_TRUE; + return; + } -/** - * Free the context state related to sync objects. - */ -void -_mesa_free_sync_data(struct gl_context *ctx) -{ - (void) ctx; + /* We need a local copy of the fence pointer, so that we can call + * fence_finish unlocked. + */ + screen->fence_reference(screen, &fence, obj->fence); + simple_mtx_unlock(&obj->mutex); + + /* Section 4.1.2 of OpenGL 4.5 (Compatibility Profile) says: + * [...] if ClientWaitSync is called and all of the following are true: + * - the SYNC_FLUSH_COMMANDS_BIT bit is set in flags, + * - sync is unsignaled when ClientWaitSync is called, + * - and the calls to ClientWaitSync and FenceSync were issued from + * the same context, + * then the GL will behave as if the equivalent of Flush were inserted + * immediately after the creation of sync. + * + * Assume GL_SYNC_FLUSH_COMMANDS_BIT is always set, because applications + * forget to set it. + */ + if (screen->fence_finish(screen, pipe, fence, timeout)) { + simple_mtx_lock(&obj->mutex); + screen->fence_reference(screen, &obj->fence, NULL); + simple_mtx_unlock(&obj->mutex); + obj->StatusFlag = GL_TRUE; + } + screen->fence_reference(screen, &fence, NULL); } - /** * Check if the given sync object is: * - non-null @@ -206,7 +206,7 @@ _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj, _mesa_set_remove(ctx->Shared->SyncObjects, entry); simple_mtx_unlock(&ctx->Shared->Mutex); - ctx->Driver.DeleteSyncObject(ctx, syncObj); + delete_sync_object(ctx, syncObj); } else { simple_mtx_unlock(&ctx->Shared->Mutex); } @@ -271,12 +271,12 @@ _mesa_DeleteSync(GLsync sync) } -static GLsync -fence_sync(struct gl_context *ctx, GLenum condition, GLbitfield flags) +GLsync +_mesa_fence_sync(struct gl_context *ctx, GLenum condition, GLbitfield flags) { struct gl_sync_object *syncObj; - syncObj = ctx->Driver.NewSyncObject(ctx); + syncObj = new_sync_object(ctx); if (syncObj != NULL) { /* The name is not currently used, and it is never visible to * applications. If sync support is extended to provide support for @@ -290,7 +290,11 @@ fence_sync(struct gl_context *ctx, GLenum condition, GLbitfield flags) syncObj->Flags = flags; syncObj->StatusFlag = 0; - ctx->Driver.FenceSync(ctx, syncObj, condition, flags); + assert(condition == GL_SYNC_GPU_COMMANDS_COMPLETE && flags == 0); + assert(syncObj->fence == NULL); + + /* Deferred flush are only allowed when there's a single context. See issue 1430 */ + ctx->pipe->flush(ctx->pipe, &syncObj->fence, ctx->Shared->RefCount == 1 ? PIPE_FLUSH_DEFERRED : 0); simple_mtx_lock(&ctx->Shared->Mutex); _mesa_set_add(ctx->Shared->SyncObjects, syncObj); @@ -307,7 +311,7 @@ GLsync GLAPIENTRY _mesa_FenceSync_no_error(GLenum condition, GLbitfield flags) { GET_CURRENT_CONTEXT(ctx); - return fence_sync(ctx, condition, flags); + return _mesa_fence_sync(ctx, condition, flags); } @@ -328,7 +332,7 @@ _mesa_FenceSync(GLenum condition, GLbitfield flags) return 0; } - return fence_sync(ctx, condition, flags); + return _mesa_fence_sync(ctx, condition, flags); } @@ -345,14 +349,14 @@ client_wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, * ClientWaitSync was called. ALREADY_SIGNALED will always be returned * if <sync> was signaled, even if the value of <timeout> is zero. */ - ctx->Driver.CheckSync(ctx, syncObj); + __client_wait_sync(ctx, syncObj, 0, 0); if (syncObj->StatusFlag) { ret = GL_ALREADY_SIGNALED; } else { if (timeout == 0) { ret = GL_TIMEOUT_EXPIRED; } else { - ctx->Driver.ClientWaitSync(ctx, syncObj, flags, timeout); + __client_wait_sync(ctx, syncObj, flags, timeout); ret = syncObj->StatusFlag ? GL_CONDITION_SATISFIED : GL_TIMEOUT_EXPIRED; @@ -402,7 +406,32 @@ static void wait_sync(struct gl_context *ctx, struct gl_sync_object *syncObj, GLbitfield flags, GLuint64 timeout) { - ctx->Driver.ServerWaitSync(ctx, syncObj, flags, timeout); + struct pipe_context *pipe = ctx->pipe; + struct pipe_screen *screen = pipe->screen; + struct pipe_fence_handle *fence = NULL; + + /* Nothing needs to be done here if the driver does not support async + * flushes. */ + if (!pipe->fence_server_sync) { + _mesa_unref_sync_object(ctx, syncObj, 1); + return; + } + + /* If the fence doesn't exist, assume it's signalled. */ + simple_mtx_lock(&syncObj->mutex); + if (!syncObj->fence) { + simple_mtx_unlock(&syncObj->mutex); + syncObj->StatusFlag = GL_TRUE; + _mesa_unref_sync_object(ctx, syncObj, 1); + return; + } + + /* We need a local copy of the fence pointer. */ + screen->fence_reference(screen, &fence, syncObj->fence); + simple_mtx_unlock(&syncObj->mutex); + + pipe->fence_server_sync(pipe, fence); + screen->fence_reference(screen, &fence, NULL); _mesa_unref_sync_object(ctx, syncObj, 1); } @@ -477,7 +506,7 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, * this call won't block. It just updates state in the common object * data from the current driver state. */ - ctx->Driver.CheckSync(ctx, syncObj); + __client_wait_sync(ctx, syncObj, 0, 0); v[0] = (syncObj->StatusFlag) ? GL_SIGNALED : GL_UNSIGNALED; size = 1; diff --git a/src/mesa/main/syncobj.h b/src/mesa/main/syncobj.h index 79cb0d26adb..9f69543f2ce 100644 --- a/src/mesa/main/syncobj.h +++ b/src/mesa/main/syncobj.h @@ -31,7 +31,7 @@ #ifndef SYNCOBJ_H #define SYNCOBJ_H -#include "glheader.h" +#include "util/glheader.h" struct _glapi_table; struct dd_function_table; @@ -39,14 +39,14 @@ struct gl_context; struct gl_sync_object; extern void -_mesa_init_sync_object_functions(struct dd_function_table *driver); - -extern void _mesa_init_sync(struct gl_context *); extern void _mesa_free_sync_data(struct gl_context *); +extern GLsync +_mesa_fence_sync(struct gl_context *ctx, GLenum condition, GLbitfield flags); + struct gl_sync_object * _mesa_get_and_ref_sync(struct gl_context *ctx, GLsync sync, bool incRefCount); @@ -54,35 +54,4 @@ extern void _mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj, int amount); -extern GLboolean GLAPIENTRY -_mesa_IsSync(GLsync sync); - -void GLAPIENTRY -_mesa_DeleteSync_no_error(GLsync sync); - -extern void GLAPIENTRY -_mesa_DeleteSync(GLsync sync); - -GLsync GLAPIENTRY -_mesa_FenceSync_no_error(GLenum condition, GLbitfield flags); - -extern GLsync GLAPIENTRY -_mesa_FenceSync(GLenum condition, GLbitfield flags); - -GLenum GLAPIENTRY -_mesa_ClientWaitSync_no_error(GLsync sync, GLbitfield flags, GLuint64 timeout); - -extern GLenum GLAPIENTRY -_mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); - -void GLAPIENTRY -_mesa_WaitSync_no_error(GLsync sync, GLbitfield flags, GLuint64 timeout); - -extern void GLAPIENTRY -_mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout); - -extern void GLAPIENTRY -_mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, - GLint *values); - #endif /* SYNCOBJ_H */ diff --git a/src/mesa/main/tests/disable_windows_include.c b/src/mesa/main/tests/disable_windows_include.c new file mode 100644 index 00000000000..5ff65d7dc68 --- /dev/null +++ b/src/mesa/main/tests/disable_windows_include.c @@ -0,0 +1,298 @@ +/* + * Copyright © Yonggang Luo + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* find | grep .*h$ >../headers.txt */ +#include <indices/u_indices.h> +#include <indices/u_indices_priv.h> +#include <indices/u_primconvert.h> +#include <mesa/main/accum.h> +#include <mesa/main/api_arrayelt.h> +#include <mesa/main/arrayobj.h> +#include <mesa/main/atifragshader.h> +#include <mesa/main/attrib.h> +#include <mesa/main/bbox.h> +#include <mesa/main/blend.h> +#include <mesa/main/blit.h> +#include <mesa/main/bufferobj.h> +#include <mesa/main/buffers.h> +#include <mesa/main/clip.h> +#include <mesa/main/colormac.h> +#include <mesa/main/condrender.h> +#include <mesa/main/config.h> +#include <mesa/main/conservativeraster.h> +#include <mesa/main/consts_exts.h> +#include <mesa/main/context.h> +#include <mesa/main/dd.h> +#include <mesa/main/debug.h> +#include <mesa/main/debug_output.h> +#include <mesa/main/depth.h> +#include <mesa/main/dlist.h> +#include <mesa/main/draw.h> +#include <mesa/main/draw_validate.h> +#include <mesa/main/enable.h> +#include <mesa/main/enums.h> +#include <mesa/main/errors.h> +#include <mesa/main/eval.h> +#include <mesa/main/extensions.h> +#include <mesa/main/externalobjects.h> +#include <mesa/main/fbobject.h> +#include <mesa/main/feedback.h> +#include <mesa/main/ffvertex_prog.h> +#include <mesa/main/fog.h> +#include <mesa/main/formatquery.h> +#include <mesa/main/formats.h> +#include <mesa/main/format_pack.h> +#include <mesa/main/format_unpack.h> +#include <mesa/main/format_utils.h> +#include <mesa/main/framebuffer.h> +#include <mesa/main/genmipmap.h> +#include <mesa/main/get.h> +#include <mesa/main/glconfig.h> +#include <mesa/main/glformats.h> +#include <mesa/main/glspirv.h> +#include <mesa/main/glthread.h> +#include <mesa/main/glthread_marshal.h> +#include <mesa/main/hash.h> +#include <mesa/main/hint.h> +#include <mesa/main/image.h> +#include <mesa/main/light.h> +#include <mesa/main/lines.h> +#include <mesa/main/macros.h> +#include <mesa/main/matrix.h> +#include <mesa/main/menums.h> +#include <mesa/main/mesa_private.h> +#include <mesa/main/mipmap.h> +#include <mesa/main/mtypes.h> +#include <mesa/main/multisample.h> +#include <mesa/main/pack.h> +#include <mesa/main/pbo.h> +#include <mesa/main/performance_monitor.h> +#include <mesa/main/performance_query.h> +#include <mesa/main/pipelineobj.h> +#include <mesa/main/pixel.h> +#include <mesa/main/pixelstore.h> +#include <mesa/main/pixeltransfer.h> +#include <mesa/main/points.h> +#include <mesa/main/polygon.h> +#include <mesa/main/program_binary.h> +#include <mesa/main/queryobj.h> +#include <mesa/main/rastpos.h> +#include <mesa/main/readpix.h> +#include <mesa/main/remap.h> +#include <mesa/main/renderbuffer.h> +#include <mesa/main/samplerobj.h> +#include <mesa/main/scissor.h> +#include <mesa/main/shaderapi.h> +#include <mesa/main/shaderimage.h> +#include <mesa/main/shaderobj.h> +#include <mesa/main/shader_types.h> +#include <mesa/main/shared.h> +#include <mesa/main/spirv_extensions.h> +#include <mesa/main/sse_minmax.h> +#include <mesa/main/state.h> +#include <mesa/main/stencil.h> +#include <mesa/main/syncobj.h> +#include <mesa/main/texcompress.h> +#include <mesa/main/texcompress_astc.h> +#include <mesa/main/texcompress_bptc.h> +#include <mesa/main/texcompress_cpal.h> +#include <mesa/main/texcompress_etc.h> +#include <mesa/main/texcompress_fxt1.h> +#include <mesa/main/texcompress_rgtc.h> +#include <mesa/main/texcompress_s3tc.h> +#include <mesa/main/texenvprogram.h> +#include <mesa/main/texgetimage.h> +#include <mesa/main/teximage.h> +#include <mesa/main/texobj.h> +#include <mesa/main/texparam.h> +#include <mesa/main/texstate.h> +#include <mesa/main/texstorage.h> +#include <mesa/main/texstore.h> +#include <mesa/main/texturebindless.h> +#include <mesa/main/textureview.h> +#include <mesa/main/transformfeedback.h> +#include <mesa/main/uniforms.h> +#include <mesa/main/varray.h> +#include <mesa/main/version.h> +#include <mesa/main/viewport.h> +#include <mesa/math/m_eval.h> +#include <mesa/math/m_matrix.h> +#include <mesa/program/arbprogparse.h> +#include <mesa/program/program.h> +#include <mesa/program/program_parser.h> +#include <mesa/program/prog_cache.h> +#include <mesa/program/prog_instruction.h> +#include <mesa/program/prog_parameter.h> +#include <mesa/program/prog_parameter_layout.h> +#include <mesa/program/prog_print.h> +#include <mesa/program/prog_statevars.h> +#include <mesa/program/prog_to_nir.h> +#include <mesa/program/symbol_table.h> +#include <mesa/state_tracker/st_atifs_to_nir.h> +#include <mesa/state_tracker/st_atom.h> +#include <mesa/state_tracker/st_atom_constbuf.h> +#include <mesa/state_tracker/st_cb_bitmap.h> +#include <mesa/state_tracker/st_cb_clear.h> +#include <mesa/state_tracker/st_cb_copyimage.h> +#include <mesa/state_tracker/st_cb_drawpixels.h> +#include <mesa/state_tracker/st_cb_drawtex.h> +#include <mesa/state_tracker/st_cb_eglimage.h> +#include <mesa/state_tracker/st_cb_feedback.h> +#include <mesa/state_tracker/st_cb_flush.h> +#include <mesa/state_tracker/st_cb_rasterpos.h> +#include <mesa/state_tracker/st_cb_readpixels.h> +#include <mesa/state_tracker/st_cb_texture.h> +#include <mesa/state_tracker/st_context.h> +#include <mesa/state_tracker/st_copytex.h> +#include <mesa/state_tracker/st_debug.h> +#include <mesa/state_tracker/st_draw.h> +#include <mesa/state_tracker/st_extensions.h> +#include <mesa/state_tracker/st_format.h> +#include <mesa/state_tracker/st_gen_mipmap.h> +#include <mesa/state_tracker/st_glsl_to_nir.h> +#include <mesa/state_tracker/st_manager.h> +#include <mesa/state_tracker/st_nir.h> +#include <mesa/state_tracker/st_pbo.h> +#include <mesa/state_tracker/st_program.h> +#include <mesa/state_tracker/st_sampler_view.h> +#include <mesa/state_tracker/st_scissor.h> +#include <mesa/state_tracker/st_shader_cache.h> +#include <mesa/state_tracker/st_texture.h> +#include <mesa/state_tracker/st_util.h> +#include <mesa/state_tracker/st_vdpau.h> +#include <mesa/vbo/vbo.h> +#include <mesa/vbo/vbo_attrib.h> +#include <mesa/vbo/vbo_exec.h> +#include <mesa/vbo/vbo_private.h> +#include <mesa/vbo/vbo_save.h> +#include <mesa/vbo/vbo_util.h> +#include <util/anon_file.h> +#include <util/bigmath.h> +#include <util/bitpack_helpers.h> +#include <util/bitscan.h> +#include <util/bitset.h> +#include <util/blob.h> +#include <util/build_id.h> +#include <util/compiler.h> +#include <util/compress.h> +#include <util/crc32.h> +#include <util/dag.h> +#include <util/detect_os.h> +#include <util/disk_cache.h> +#include <util/disk_cache_os.h> +#include <util/double.h> +#include <util/driconf.h> +#include <util/enum_operators.h> +#include <util/fast_idiv_by_const.h> +#include <util/fast_urem_by_const.h> +#include <util/format/format_utils.h> +#include <util/format/u_format.h> +#include <util/format/u_format_bptc.h> +#include <util/format/u_format_etc.h> +#include <util/format/u_format_fxt1.h> +#include <util/format/u_format_latc.h> +#include <util/format/u_format_other.h> +#include <util/format/u_format_rgtc.h> +#include <util/format/u_format_s3tc.h> +#include <util/format/u_format_tests.h> +#include <util/format/u_format_yuv.h> +#include <util/format/u_format_zs.h> +#include <util/format_r11g11b10f.h> +#include <util/format_rgb9e5.h> +#include <util/format_srgb.h> +#include <util/fossilize_db.h> +#include <util/futex.h> +#include <util/glheader.h> +#include <util/half_float.h> +#include <util/hash_table.h> +#include <util/list.h> +#include <util/log.h> +#include <util/macros.h> +#include <util/memstream.h> +#include <util/mesa-sha1.h> +#include <util/mesa_cache_db.h> +#include <util/os_file.h> +#include <util/os_memory.h> +#include <util/os_misc.h> +#include <util/os_socket.h> +#include <util/os_time.h> +#include <util/perf/cpu_trace.h> +#include <util/perf/u_perfetto.h> +#include <util/perf/u_trace.h> +#include <util/ptralloc.h> +#include <util/ralloc.h> +#include <util/rand_xor.h> +#include <util/rb_tree.h> +#include <util/reallocarray.h> +#include <util/register_allocate.h> +#include <util/register_allocate_internal.h> +#include <util/rgtc.h> +#include <util/rounding.h> +#include <util/rwlock.h> +#include <util/set.h> +#include <util/sha1/sha1.h> +#include <util/simple_mtx.h> +#include <util/slab.h> +#include <util/softfloat.h> +#include <util/sparse_array.h> +#include <util/streaming-load-memcpy.h> +#include <util/string_buffer.h> +#include <util/strndup.h> +#include <util/strtod.h> +#include <util/timespec.h> +#include <util/u_atomic.h> +#include <util/u_call_once.h> +#include <util/u_cpu_detect.h> +#include <util/u_debug.h> +#include <util/u_debug_describe.h> +#include <util/u_debug_refcnt.h> +#include <util/u_debug_stack.h> +#include <util/u_debug_symbol.h> +#include <util/u_dl.h> +#include <util/u_drm.h> +#include <util/u_dynarray.h> +#include <util/u_endian.h> +#include <util/u_hash_table.h> +#include <util/u_idalloc.h> +#include <util/u_math.h> +#include <util/u_memory.h> +#include <util/u_memset.h> +#include <util/u_mm.h> +#include <util/u_pointer.h> +#include <util/u_printf.h> +#include <util/u_process.h> +#include <util/u_qsort.h> +#include <util/u_queue.h> +#include <util/u_string.h> +#include <util/u_thread.h> +#include <util/u_vector.h> +#include <util/u_worklist.h> +#include <util/vl_rbsp.h> +#include <util/vl_vlc.h> +#include <util/vma.h> +#include <util/xmlconfig.h> +#include <util/xxhash.h> + +#if defined(_WIN32) && defined(_WINDOWS_) +#error "Should not include <windows.h> here" +#endif diff --git a/src/mesa/main/tests/dispatch_sanity.cpp b/src/mesa/main/tests/dispatch_sanity.cpp deleted file mode 100644 index aef00081744..00000000000 --- a/src/mesa/main/tests/dispatch_sanity.cpp +++ /dev/null @@ -1,2862 +0,0 @@ -/* - * Copyright © 2012 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/** - * \name dispatch_sanity.cpp - * - * Verify that only set of functions that should be available in a particular - * API are available in that API. - * - * The list of expected functions originally came from the functions set by - * api_exec_es2.c. This file no longer exists in Mesa (but api_exec_es1.c was - * still generated at the time this test was written). It was the generated - * file that configured the dispatch table for ES2 contexts. This test - * verifies that all of the functions set by the old api_exec_es2.c (with the - * recent addition of VAO functions) are set in the dispatch table and - * everything else is a NOP. - * - * When adding extensions that add new functions, this test will need to be - * modified to expect dispatch functions for the new extension functions. - */ - -#include <gtest/gtest.h> - -#include "GL/gl.h" -#include "GL/glext.h" -#include "util/compiler.h" -#include "main/api_exec.h" -#include "main/context.h" -#include "main/remap.h" -#include "main/vtxfmt.h" -#include "glapi/glapi.h" -#include "drivers/common/driverfuncs.h" - -#include "swrast/swrast.h" -#include "vbo/vbo.h" -#include "tnl/tnl.h" -#include "swrast_setup/swrast_setup.h" - -#ifndef GLAPIENTRYP -#define GLAPIENTRYP GL_APIENTRYP -#endif - -#include "main/dispatch.h" - -struct function { - const char *name; - unsigned int Version; - int offset; -}; - -extern const struct function common_desktop_functions_possible[]; -extern const struct function gl_compatibility_functions_possible[]; -extern const struct function gl_core_functions_possible[]; -extern const struct function gles11_functions_possible[]; -extern const struct function gles2_functions_possible[]; -extern const struct function gles3_functions_possible[]; -extern const struct function gles31_functions_possible[]; - -class DispatchSanity_test : public ::testing::Test { -public: - virtual void SetUp(); - virtual void TearDown(); - void SetUpCtx(gl_api api, unsigned int version); - void TearDownCtx(); - - struct gl_config visual; - struct dd_function_table driver_functions; - struct gl_context share_list; - struct gl_context ctx; - _glapi_proc *nop_table; -}; - -void -DispatchSanity_test::SetUp() -{ - memset(&visual, 0, sizeof(visual)); - memset(&driver_functions, 0, sizeof(driver_functions)); - memset(&share_list, 0, sizeof(share_list)); - memset(&ctx, 0, sizeof(ctx)); - - _mesa_init_driver_functions(&driver_functions); - - const unsigned size = _glapi_get_dispatch_table_size(); - nop_table = (_glapi_proc *) _mesa_new_nop_table(size); -} - -void -DispatchSanity_test::TearDown() -{ - free(nop_table); -} - -void -DispatchSanity_test::SetUpCtx(gl_api api, unsigned int version) -{ - _mesa_initialize_context(&ctx, - api, - &visual, - NULL, // share_list - &driver_functions); - _vbo_CreateContext(&ctx, false); - - _mesa_override_extensions(&ctx); - ctx.Version = version; - - _mesa_initialize_dispatch_tables(&ctx); - _mesa_initialize_vbo_vtxfmt(&ctx); -} - -void -DispatchSanity_test::TearDownCtx() -{ - _vbo_DestroyContext(&ctx); - _mesa_free_context_data(&ctx, false); -} - -static const char * -offset_to_proc_name_safe(unsigned offset) -{ - const char *name = _glapi_get_proc_name(offset); - return name ? name : "???"; -} - -/* Scan through the dispatch table and check that all the functions in - * _glapi_proc *table exist. - */ -static void -validate_functions(struct gl_context *ctx, const struct function *function_table, - const _glapi_proc *nop_table) -{ - _glapi_proc *table = (_glapi_proc *) ctx->Exec; - - for (unsigned i = 0; function_table[i].name != NULL; i++) { - /* The context version is >= the GL version where the function was - * introduced. Therefore, the function cannot be set to the nop - * function. - */ - const bool cant_be_nop = ctx->Version >= function_table[i].Version; - - const int offset = (function_table[i].offset != -1) - ? function_table[i].offset - : _glapi_get_proc_offset(function_table[i].name); - - ASSERT_NE(-1, offset) - << "Function: " << function_table[i].name; - ASSERT_EQ(offset, - _glapi_get_proc_offset(function_table[i].name)) - << "Function: " << function_table[i].name; - if (cant_be_nop) { - EXPECT_NE(nop_table[offset], table[offset]) - << "Function: " << function_table[i].name - << " at offset " << offset; - } - - table[offset] = nop_table[offset]; - } -} - -/* Scan through the table and ensure that there is nothing except - * nop functions (as set by validate_functions(). - */ -static void -validate_nops(struct gl_context *ctx, const _glapi_proc *nop_table) -{ - _glapi_proc *table = (_glapi_proc *) ctx->Exec; - - const unsigned size = _glapi_get_dispatch_table_size(); - for (unsigned i = 0; i < size; i++) { - EXPECT_EQ(nop_table[i], table[i]) - << "i = " << i << " (" << offset_to_proc_name_safe(i) << ")"; - } -} - -TEST_F(DispatchSanity_test, GL31_CORE) -{ - SetUpCtx(API_OPENGL_CORE, 31); - validate_functions(&ctx, common_desktop_functions_possible, nop_table); - validate_functions(&ctx, gl_core_functions_possible, nop_table); - validate_nops(&ctx, nop_table); - TearDownCtx(); -} - -TEST_F(DispatchSanity_test, GL30) -{ - SetUpCtx(API_OPENGL_COMPAT, 30); - validate_functions(&ctx, common_desktop_functions_possible, nop_table); - validate_functions(&ctx, gl_compatibility_functions_possible, nop_table); - validate_nops(&ctx, nop_table); - TearDownCtx(); -} - -TEST_F(DispatchSanity_test, GLES11) -{ - SetUpCtx(API_OPENGLES, 11); - validate_functions(&ctx, gles11_functions_possible, nop_table); - validate_nops(&ctx, nop_table); - TearDownCtx(); -} - -TEST_F(DispatchSanity_test, GLES2) -{ - SetUpCtx(API_OPENGLES2, 20); - validate_functions(&ctx, gles2_functions_possible, nop_table); - validate_nops(&ctx, nop_table); - TearDownCtx(); -} - -TEST_F(DispatchSanity_test, GLES3) -{ - SetUpCtx(API_OPENGLES2, 30); - validate_functions(&ctx, gles2_functions_possible, nop_table); - validate_functions(&ctx, gles3_functions_possible, nop_table); - validate_nops(&ctx, nop_table); - TearDownCtx(); -} - -TEST_F(DispatchSanity_test, GLES31) -{ - SetUpCtx(API_OPENGLES2, 31); - validate_functions(&ctx, gles2_functions_possible, nop_table); - validate_functions(&ctx, gles3_functions_possible, nop_table); - validate_functions(&ctx, gles31_functions_possible, nop_table); - validate_nops(&ctx, nop_table); - TearDownCtx(); -} - -const struct function common_desktop_functions_possible[] = { - { "glBindRenderbufferEXT", 10, -1 }, - { "glBindFramebufferEXT", 10, -1 }, - { "glCullFace", 10, -1 }, - { "glFrontFace", 10, -1 }, - { "glHint", 10, -1 }, - { "glLineWidth", 10, -1 }, - { "glPointSize", 10, -1 }, - { "glPolygonMode", 10, -1 }, - { "glScissor", 10, -1 }, - { "glTexParameterf", 10, -1 }, - { "glTexParameterfv", 10, -1 }, - { "glTexParameteri", 10, -1 }, - { "glTexParameteriv", 10, -1 }, - { "glTexImage1D", 10, _gloffset_TexImage1D }, - { "glTexImage2D", 10, _gloffset_TexImage2D }, - { "glDrawBuffer", 10, -1 }, - { "glClear", 10, -1 }, - { "glClearColor", 10, -1 }, - { "glClearStencil", 10, -1 }, - { "glClearDepth", 10, -1 }, - { "glStencilMask", 10, -1 }, - { "glColorMask", 10, -1 }, - { "glDepthMask", 10, -1 }, - { "glDisable", 10, -1 }, - { "glEnable", 10, -1 }, - { "glFinish", 10, -1 }, - { "glFlush", 10, -1 }, - { "glBlendFunc", 10, -1 }, - { "glLogicOp", 10, -1 }, - { "glStencilFunc", 10, -1 }, - { "glStencilOp", 10, -1 }, - { "glDepthFunc", 10, -1 }, - { "glPixelStoref", 10, -1 }, - { "glPixelStorei", 10, -1 }, - { "glReadBuffer", 10, -1 }, - { "glReadPixels", 10, -1 }, - { "glGetBooleanv", 10, -1 }, - { "glGetDoublev", 10, -1 }, - { "glGetError", 10, -1 }, - { "glGetFloatv", 10, -1 }, - { "glGetIntegerv", 10, -1 }, - { "glGetString", 10, -1 }, - { "glGetTexImage", 10, -1 }, - { "glGetTexParameterfv", 10, -1 }, - { "glGetTexParameteriv", 10, -1 }, - { "glGetTexLevelParameterfv", 10, -1 }, - { "glGetTexLevelParameteriv", 10, -1 }, - { "glIsEnabled", 10, -1 }, - { "glDepthRange", 10, -1 }, - { "glViewport", 10, -1 }, - - /* GL 1.1 */ - { "glDrawArrays", 11, -1 }, - { "glDrawElements", 11, -1 }, - { "glGetPointerv", 11, -1 }, - { "glPolygonOffset", 11, -1 }, - { "glCopyTexImage1D", 11, -1 }, - { "glCopyTexImage2D", 11, -1 }, - { "glCopyTexSubImage1D", 11, -1 }, - { "glCopyTexSubImage2D", 11, -1 }, - { "glTexSubImage1D", 11, -1 }, - { "glTexSubImage2D", 11, -1 }, - { "glBindTexture", 11, -1 }, - { "glDeleteTextures", 11, -1 }, - { "glGenTextures", 11, -1 }, - { "glIsTexture", 11, -1 }, - - /* GL 1.2 */ - { "glBlendColor", 12, -1 }, - { "glBlendEquation", 12, -1 }, - { "glDrawRangeElements", 12, -1 }, - { "glTexImage3D", 12, -1 }, - { "glTexSubImage3D", 12, -1 }, - { "glCopyTexSubImage3D", 12, -1 }, - - /* GL 1.3 */ - { "glActiveTexture", 13, -1 }, - { "glSampleCoverage", 13, -1 }, - { "glCompressedTexImage3D", 13, -1 }, - { "glCompressedTexImage2D", 13, -1 }, - { "glCompressedTexImage1D", 13, -1 }, - { "glCompressedTexSubImage3D", 13, -1 }, - { "glCompressedTexSubImage2D", 13, -1 }, - { "glCompressedTexSubImage1D", 13, -1 }, - { "glGetCompressedTexImage", 13, -1 }, - - /* GL 1.4 */ - { "glBlendFuncSeparate", 14, -1 }, - { "glMultiDrawArrays", 14, -1 }, - { "glMultiDrawElements", 14, -1 }, - { "glPointParameterf", 14, -1 }, - { "glPointParameterfv", 14, -1 }, - { "glPointParameteri", 14, -1 }, - { "glPointParameteriv", 14, -1 }, - - /* GL 1.5 */ - { "glGenQueries", 15, -1 }, - { "glDeleteQueries", 15, -1 }, - { "glIsQuery", 15, -1 }, - { "glBeginQuery", 15, -1 }, - { "glEndQuery", 15, -1 }, - { "glGetQueryiv", 15, -1 }, - { "glGetQueryObjectiv", 15, -1 }, - { "glGetQueryObjectuiv", 15, -1 }, - { "glBindBuffer", 15, -1 }, - { "glDeleteBuffers", 15, -1 }, - { "glGenBuffers", 15, -1 }, - { "glIsBuffer", 15, -1 }, - { "glBufferData", 15, -1 }, - { "glBufferSubData", 15, -1 }, - { "glGetBufferSubData", 15, -1 }, - { "glMapBuffer", 15, -1 }, - { "glUnmapBuffer", 15, -1 }, - { "glGetBufferParameteriv", 15, -1 }, - { "glGetBufferPointerv", 15, -1 }, - - /* GL 2.0 */ - { "glBlendEquationSeparate", 20, -1 }, - { "glDrawBuffers", 20, -1 }, - { "glStencilOpSeparate", 20, -1 }, - { "glStencilFuncSeparate", 20, -1 }, - { "glStencilMaskSeparate", 20, -1 }, - { "glAttachShader", 20, -1 }, - { "glBindAttribLocation", 20, -1 }, - { "glCompileShader", 20, -1 }, - { "glCreateProgram", 20, -1 }, - { "glCreateShader", 20, -1 }, - { "glDeleteProgram", 20, -1 }, - { "glDeleteShader", 20, -1 }, - { "glDetachShader", 20, -1 }, - { "glDisableVertexAttribArray", 20, -1 }, - { "glEnableVertexAttribArray", 20, -1 }, - { "glGetActiveAttrib", 20, -1 }, - { "glGetActiveUniform", 20, -1 }, - { "glGetAttachedShaders", 20, -1 }, - { "glGetAttribLocation", 20, -1 }, - { "glGetProgramiv", 20, -1 }, - { "glGetProgramInfoLog", 20, -1 }, - { "glGetShaderiv", 20, -1 }, - { "glGetShaderInfoLog", 20, -1 }, - { "glGetShaderSource", 20, -1 }, - { "glGetUniformLocation", 20, -1 }, - { "glGetUniformfv", 20, -1 }, - { "glGetUniformiv", 20, -1 }, - { "glGetVertexAttribdv", 20, -1 }, - { "glGetVertexAttribfv", 20, -1 }, - { "glGetVertexAttribiv", 20, -1 }, - { "glGetVertexAttribPointerv", 20, -1 }, - { "glIsProgram", 20, -1 }, - { "glIsShader", 20, -1 }, - { "glLinkProgram", 20, -1 }, - { "glShaderSource", 20, -1 }, - { "glUseProgram", 20, -1 }, - { "glUniform1f", 20, -1 }, - { "glUniform2f", 20, -1 }, - { "glUniform3f", 20, -1 }, - { "glUniform4f", 20, -1 }, - { "glUniform1i", 20, -1 }, - { "glUniform2i", 20, -1 }, - { "glUniform3i", 20, -1 }, - { "glUniform4i", 20, -1 }, - { "glUniform1fv", 20, -1 }, - { "glUniform2fv", 20, -1 }, - { "glUniform3fv", 20, -1 }, - { "glUniform4fv", 20, -1 }, - { "glUniform1iv", 20, -1 }, - { "glUniform2iv", 20, -1 }, - { "glUniform3iv", 20, -1 }, - { "glUniform4iv", 20, -1 }, - { "glUniformMatrix2fv", 20, -1 }, - { "glUniformMatrix3fv", 20, -1 }, - { "glUniformMatrix4fv", 20, -1 }, - { "glValidateProgram", 20, -1 }, - { "glVertexAttrib1d", 20, -1 }, - { "glVertexAttrib1dv", 20, -1 }, - { "glVertexAttrib1f", 20, -1 }, - { "glVertexAttrib1fv", 20, -1 }, - { "glVertexAttrib1s", 20, -1 }, - { "glVertexAttrib1sv", 20, -1 }, - { "glVertexAttrib2d", 20, -1 }, - { "glVertexAttrib2dv", 20, -1 }, - { "glVertexAttrib2f", 20, -1 }, - { "glVertexAttrib2fv", 20, -1 }, - { "glVertexAttrib2s", 20, -1 }, - { "glVertexAttrib2sv", 20, -1 }, - { "glVertexAttrib3d", 20, -1 }, - { "glVertexAttrib3dv", 20, -1 }, - { "glVertexAttrib3f", 20, -1 }, - { "glVertexAttrib3fv", 20, -1 }, - { "glVertexAttrib3s", 20, -1 }, - { "glVertexAttrib3sv", 20, -1 }, - { "glVertexAttrib4Nbv", 20, -1 }, - { "glVertexAttrib4Niv", 20, -1 }, - { "glVertexAttrib4Nsv", 20, -1 }, - { "glVertexAttrib4Nub", 20, -1 }, - { "glVertexAttrib4Nubv", 20, -1 }, - { "glVertexAttrib4Nuiv", 20, -1 }, - { "glVertexAttrib4Nusv", 20, -1 }, - { "glVertexAttrib4bv", 20, -1 }, - { "glVertexAttrib4d", 20, -1 }, - { "glVertexAttrib4dv", 20, -1 }, - { "glVertexAttrib4f", 20, -1 }, - { "glVertexAttrib4fv", 20, -1 }, - { "glVertexAttrib4iv", 20, -1 }, - { "glVertexAttrib4s", 20, -1 }, - { "glVertexAttrib4sv", 20, -1 }, - { "glVertexAttrib4ubv", 20, -1 }, - { "glVertexAttrib4uiv", 20, -1 }, - { "glVertexAttrib4usv", 20, -1 }, - { "glVertexAttribPointer", 20, -1 }, - - /* GL 2.1 */ - { "glUniformMatrix2x3fv", 21, -1 }, - { "glUniformMatrix3x2fv", 21, -1 }, - { "glUniformMatrix2x4fv", 21, -1 }, - { "glUniformMatrix4x2fv", 21, -1 }, - { "glUniformMatrix3x4fv", 21, -1 }, - { "glUniformMatrix4x3fv", 21, -1 }, - - /* GL 3.0 */ - { "glColorMaski", 30, -1 }, - { "glGetBooleani_v", 30, -1 }, - { "glGetIntegeri_v", 30, -1 }, - { "glEnablei", 30, -1 }, - { "glDisablei", 30, -1 }, - { "glIsEnabledi", 30, -1 }, - { "glBeginTransformFeedback", 30, -1 }, - { "glEndTransformFeedback", 30, -1 }, - { "glBindBufferRange", 30, -1 }, - { "glBindBufferBase", 30, -1 }, - { "glTransformFeedbackVaryings", 30, -1 }, - { "glGetTransformFeedbackVarying", 30, -1 }, - { "glClampColor", 30, -1 }, - { "glBeginConditionalRender", 30, -1 }, - { "glEndConditionalRender", 30, -1 }, - { "glVertexAttribIPointer", 30, -1 }, - { "glGetVertexAttribIiv", 30, -1 }, - { "glGetVertexAttribIuiv", 30, -1 }, - { "glVertexAttribI1i", 30, -1 }, - { "glVertexAttribI2i", 30, -1 }, - { "glVertexAttribI3i", 30, -1 }, - { "glVertexAttribI4i", 30, -1 }, - { "glVertexAttribI1ui", 30, -1 }, - { "glVertexAttribI2ui", 30, -1 }, - { "glVertexAttribI3ui", 30, -1 }, - { "glVertexAttribI4ui", 30, -1 }, - { "glVertexAttribI1iv", 30, -1 }, - { "glVertexAttribI2iv", 30, -1 }, - { "glVertexAttribI3iv", 30, -1 }, - { "glVertexAttribI4iv", 30, -1 }, - { "glVertexAttribI1uiv", 30, -1 }, - { "glVertexAttribI2uiv", 30, -1 }, - { "glVertexAttribI3uiv", 30, -1 }, - { "glVertexAttribI4uiv", 30, -1 }, - { "glVertexAttribI4bv", 30, -1 }, - { "glVertexAttribI4sv", 30, -1 }, - { "glVertexAttribI4ubv", 30, -1 }, - { "glVertexAttribI4usv", 30, -1 }, - { "glGetUniformuiv", 30, -1 }, - { "glBindFragDataLocation", 30, -1 }, - { "glGetFragDataLocation", 30, -1 }, - { "glUniform1ui", 30, -1 }, - { "glUniform2ui", 30, -1 }, - { "glUniform3ui", 30, -1 }, - { "glUniform4ui", 30, -1 }, - { "glUniform1uiv", 30, -1 }, - { "glUniform2uiv", 30, -1 }, - { "glUniform3uiv", 30, -1 }, - { "glUniform4uiv", 30, -1 }, - { "glTexParameterIiv", 30, -1 }, - { "glTexParameterIuiv", 30, -1 }, - { "glGetTexParameterIiv", 30, -1 }, - { "glGetTexParameterIuiv", 30, -1 }, - { "glClearBufferiv", 30, -1 }, - { "glClearBufferuiv", 30, -1 }, - { "glClearBufferfv", 30, -1 }, - { "glClearBufferfi", 30, -1 }, - { "glGetStringi", 30, -1 }, - - /* GL 3.1 */ - { "glDrawArraysInstanced", 31, -1 }, - { "glDrawElementsInstanced", 31, -1 }, - { "glPrimitiveRestartIndex", 31, -1 }, - { "glTexBuffer", 31, -1 }, - - /* GL_ARB_texture_buffer_range */ - { "glTexBufferRange", 43, -1 }, - - /* GL_ARB_shader_objects */ - { "glDeleteObjectARB", 31, -1 }, - { "glGetHandleARB", 31, -1 }, - { "glDetachObjectARB", 31, -1 }, - { "glCreateShaderObjectARB", 31, -1 }, - { "glCreateProgramObjectARB", 31, -1 }, - { "glAttachObjectARB", 31, -1 }, - { "glGetObjectParameterfvARB", 31, -1 }, - { "glGetObjectParameterivARB", 31, -1 }, - { "glGetInfoLogARB", 31, -1 }, - { "glGetAttachedObjectsARB", 31, -1 }, - - /* GL_ARB_get_program_binary */ - { "glGetProgramBinary", 30, -1 }, - { "glProgramBinary", 30, -1 }, - { "glProgramParameteri", 30, -1 }, - - /* GL_EXT_transform_feedback */ - { "glBindBufferOffsetEXT", 31, -1 }, - - /* GL_IBM_multimode_draw_arrays */ - { "glMultiModeDrawArraysIBM", 31, -1 }, - { "glMultiModeDrawElementsIBM", 31, -1 }, - - /* GL_EXT_depth_bounds_test */ - { "glDepthBoundsEXT", 31, -1 }, - - /* GL_apple_object_purgeable */ - { "glObjectPurgeableAPPLE", 31, -1 }, - { "glObjectUnpurgeableAPPLE", 31, -1 }, - { "glGetObjectParameterivAPPLE", 31, -1 }, - - /* GL_ARB_instanced_arrays */ - { "glVertexAttribDivisorARB", 31, -1 }, - { "glVertexArrayVertexAttribDivisorEXT", 31, -1 }, - - /* GL_NV_texture_barrier */ - { "glTextureBarrierNV", 31, -1 }, - - /* GL_EXT_texture_integer */ - { "glClearColorIiEXT", 31, -1 }, - { "glClearColorIuiEXT", 31, -1 }, - - /* GL_OES_EGL_image */ - { "glEGLImageTargetRenderbufferStorageOES", 31, -1 }, - { "glEGLImageTargetTexture2DOES", 31, -1 }, - - /* EXT_EGL_image_storage */ - { "glEGLImageTargetTexStorageEXT", 31, -1 }, - { "glEGLImageTargetTextureStorageEXT", 31, -1 }, - - /* GL_NV_copy_image */ - { "glCopyImageSubDataNV", 31, -1 }, - - /* GL 3.2 */ - { "glGetInteger64i_v", 32, -1 }, - { "glGetBufferParameteri64v", 32, -1 }, - { "glFramebufferTexture", 32, -1 }, - { "glProgramParameteri", 32, -1 }, - { "glFramebufferTextureLayer", 32, -1 }, - - /* GL 3.3 */ - { "glVertexAttribDivisor", 33, -1 }, - - /* GL 4.0 */ - { "glMinSampleShading", 40, -1 }, - { "glPatchParameteri", 40, -1 }, - { "glPatchParameterfv", 40, -1 }, - { "glBlendEquationi", 40, -1 }, - { "glBlendEquationSeparatei", 40, -1 }, - { "glBlendFunci", 40, -1 }, - { "glBlendFuncSeparatei", 40, -1 }, - - { "glGetSubroutineUniformLocation", 40, -1 }, - { "glGetSubroutineIndex", 40, -1 }, - { "glGetActiveSubroutineUniformiv", 40, -1 }, - { "glGetActiveSubroutineUniformName", 40, -1 }, - { "glGetActiveSubroutineName", 40, -1 }, - { "glUniformSubroutinesuiv", 40, -1 }, - { "glGetUniformSubroutineuiv", 40, -1 }, - { "glGetProgramStageiv", 40, -1 }, - - { "glUniform1d", 40, -1 }, - { "glUniform2d", 40, -1 }, - { "glUniform3d", 40, -1 }, - { "glUniform4d", 40, -1 }, - { "glUniform1dv", 40, -1 }, - { "glUniform2dv", 40, -1 }, - { "glUniform3dv", 40, -1 }, - { "glUniform4dv", 40, -1 }, - { "glUniformMatrix2dv", 40, -1 }, - { "glUniformMatrix3dv", 40, -1 }, - { "glUniformMatrix4dv", 40, -1 }, - { "glUniformMatrix2x3dv", 40, -1 }, - { "glUniformMatrix2x4dv", 40, -1 }, - { "glUniformMatrix3x2dv", 40, -1 }, - { "glUniformMatrix3x4dv", 40, -1 }, - { "glUniformMatrix4x2dv", 40, -1 }, - { "glUniformMatrix4x3dv", 40, -1 }, - { "glGetUniformdv", 43, -1 }, - - /* GL 4.1 */ - { "glVertexAttribL1d", 41, -1 }, - { "glVertexAttribL2d", 41, -1 }, - { "glVertexAttribL3d", 41, -1 }, - { "glVertexAttribL4d", 41, -1 }, - { "glVertexAttribL1dv", 41, -1 }, - { "glVertexAttribL2dv", 41, -1 }, - { "glVertexAttribL3dv", 41, -1 }, - { "glVertexAttribL4dv", 41, -1 }, - { "glVertexAttribLPointer", 41, -1 }, - { "glGetVertexAttribLdv", 41, -1 }, - { "glVertexArrayVertexAttribLOffsetEXT", 41, -1 }, - - /* GL 4.3 */ - { "glIsRenderbuffer", 43, -1 }, - { "glBindRenderbuffer", 43, -1 }, - { "glDeleteRenderbuffers", 43, -1 }, - { "glGenRenderbuffers", 43, -1 }, - { "glRenderbufferStorage", 43, -1 }, - { "glGetRenderbufferParameteriv", 43, -1 }, - { "glIsFramebuffer", 43, -1 }, - { "glBindFramebuffer", 43, -1 }, - { "glDeleteFramebuffers", 43, -1 }, - { "glGenFramebuffers", 43, -1 }, - { "glCheckFramebufferStatus", 43, -1 }, - { "glFramebufferTexture1D", 43, -1 }, - { "glFramebufferTexture2D", 43, -1 }, - { "glFramebufferTexture3D", 43, -1 }, - { "glFramebufferRenderbuffer", 43, -1 }, - { "glGetFramebufferAttachmentParameteriv", 43, -1 }, - { "glGenerateMipmap", 43, -1 }, - { "glBlitFramebuffer", 43, -1 }, - { "glRenderbufferStorageMultisample", 43, -1 }, - { "glFramebufferTextureLayer", 43, -1 }, - { "glMapBufferRange", 43, -1 }, - { "glFlushMappedBufferRange", 43, -1 }, - { "glBindVertexArray", 43, -1 }, - { "glDeleteVertexArrays", 43, -1 }, - { "glGenVertexArrays", 43, -1 }, - { "glIsVertexArray", 43, -1 }, - { "glGetUniformIndices", 43, -1 }, - { "glGetActiveUniformsiv", 43, -1 }, - { "glGetActiveUniformName", 43, -1 }, - { "glGetUniformBlockIndex", 43, -1 }, - { "glGetActiveUniformBlockiv", 43, -1 }, - { "glGetActiveUniformBlockName", 43, -1 }, - { "glUniformBlockBinding", 43, -1 }, - { "glCopyBufferSubData", 43, -1 }, - { "glDrawElementsBaseVertex", 43, -1 }, - { "glDrawRangeElementsBaseVertex", 43, -1 }, - { "glDrawElementsInstancedBaseVertex", 43, -1 }, - { "glMultiDrawElementsBaseVertex", 43, -1 }, - { "glProvokingVertex", 43, -1 }, - { "glFenceSync", 43, -1 }, - { "glIsSync", 43, -1 }, - { "glDeleteSync", 43, -1 }, - { "glClientWaitSync", 43, -1 }, - { "glWaitSync", 43, -1 }, - { "glGetInteger64v", 43, -1 }, - { "glGetSynciv", 43, -1 }, - { "glTexImage2DMultisample", 43, -1 }, - { "glTexImage3DMultisample", 43, -1 }, - { "glGetMultisamplefv", 43, -1 }, - { "glSampleMaski", 43, -1 }, - { "glBlendEquationiARB", 43, -1 }, - { "glBlendEquationSeparateiARB", 43, -1 }, - { "glBlendFunciARB", 43, -1 }, - { "glBlendFuncSeparateiARB", 43, -1 }, - { "glMinSampleShadingARB", 43, -1 }, // XXX: Add to xml - { "glBindFragDataLocationIndexed", 43, -1 }, - { "glGetFragDataIndex", 43, -1 }, - { "glGenSamplers", 43, -1 }, - { "glDeleteSamplers", 43, -1 }, - { "glIsSampler", 43, -1 }, - { "glBindSampler", 43, -1 }, - { "glSamplerParameteri", 43, -1 }, - { "glSamplerParameteriv", 43, -1 }, - { "glSamplerParameterf", 43, -1 }, - { "glSamplerParameterfv", 43, -1 }, - { "glSamplerParameterIiv", 43, -1 }, - { "glSamplerParameterIuiv", 43, -1 }, - { "glGetSamplerParameteriv", 43, -1 }, - { "glGetSamplerParameterIiv", 43, -1 }, - { "glGetSamplerParameterfv", 43, -1 }, - { "glGetSamplerParameterIuiv", 43, -1 }, - { "glQueryCounter", 43, -1 }, - { "glGetQueryObjecti64v", 43, -1 }, - { "glGetQueryObjectui64v", 43, -1 }, - { "glVertexP2ui", 43, -1 }, - { "glVertexP2uiv", 43, -1 }, - { "glVertexP3ui", 43, -1 }, - { "glVertexP3uiv", 43, -1 }, - { "glVertexP4ui", 43, -1 }, - { "glVertexP4uiv", 43, -1 }, - { "glTexCoordP1ui", 43, -1 }, - { "glTexCoordP1uiv", 43, -1 }, - { "glTexCoordP2ui", 43, -1 }, - { "glTexCoordP2uiv", 43, -1 }, - { "glTexCoordP3ui", 43, -1 }, - { "glTexCoordP3uiv", 43, -1 }, - { "glTexCoordP4ui", 43, -1 }, - { "glTexCoordP4uiv", 43, -1 }, - { "glMultiTexCoordP1ui", 43, -1 }, - { "glMultiTexCoordP1uiv", 43, -1 }, - { "glMultiTexCoordP2ui", 43, -1 }, - { "glMultiTexCoordP2uiv", 43, -1 }, - { "glMultiTexCoordP3ui", 43, -1 }, - { "glMultiTexCoordP3uiv", 43, -1 }, - { "glMultiTexCoordP4ui", 43, -1 }, - { "glMultiTexCoordP4uiv", 43, -1 }, - { "glNormalP3ui", 43, -1 }, - { "glNormalP3uiv", 43, -1 }, - { "glColorP3ui", 43, -1 }, - { "glColorP3uiv", 43, -1 }, - { "glColorP4ui", 43, -1 }, - { "glColorP4uiv", 43, -1 }, - { "glSecondaryColorP3ui", 43, -1 }, - { "glSecondaryColorP3uiv", 43, -1 }, - { "glVertexAttribP1ui", 43, -1 }, - { "glVertexAttribP1uiv", 43, -1 }, - { "glVertexAttribP2ui", 43, -1 }, - { "glVertexAttribP2uiv", 43, -1 }, - { "glVertexAttribP3ui", 43, -1 }, - { "glVertexAttribP3uiv", 43, -1 }, - { "glVertexAttribP4ui", 43, -1 }, - { "glVertexAttribP4uiv", 43, -1 }, - { "glDrawArraysIndirect", 43, -1 }, - { "glDrawElementsIndirect", 43, -1 }, - { "glBindTransformFeedback", 43, -1 }, - { "glDeleteTransformFeedbacks", 43, -1 }, - { "glGenTransformFeedbacks", 43, -1 }, - { "glIsTransformFeedback", 43, -1 }, - { "glPauseTransformFeedback", 43, -1 }, - { "glResumeTransformFeedback", 43, -1 }, - { "glDrawTransformFeedback", 43, -1 }, - { "glDrawTransformFeedbackStream", 43, -1 }, - { "glBeginQueryIndexed", 43, -1 }, - { "glEndQueryIndexed", 43, -1 }, - { "glGetQueryIndexediv", 43, -1 }, - { "glReleaseShaderCompiler", 43, -1 }, - { "glShaderBinary", 43, -1 }, - { "glGetShaderPrecisionFormat", 43, -1 }, - { "glDepthRangef", 43, -1 }, - { "glClearDepthf", 43, -1 }, - { "glGetProgramBinary", 43, -1 }, - { "glProgramBinary", 43, -1 }, - { "glProgramParameteri", 43, -1 }, - { "glUseProgramStages", 43, -1 }, - { "glActiveShaderProgram", 43, -1 }, - { "glCreateShaderProgramv", 43, -1 }, - { "glBindProgramPipeline", 43, -1 }, - { "glDeleteProgramPipelines", 43, -1 }, - { "glGenProgramPipelines", 43, -1 }, - { "glIsProgramPipeline", 43, -1 }, - { "glGetProgramPipelineiv", 43, -1 }, - { "glProgramUniform1d", 43, -1 }, - { "glProgramUniform1dv", 43, -1 }, - { "glProgramUniform1i", 43, -1 }, - { "glProgramUniform1iv", 43, -1 }, - { "glProgramUniform1f", 43, -1 }, - { "glProgramUniform1fv", 43, -1 }, - { "glProgramUniform1ui", 43, -1 }, - { "glProgramUniform1uiv", 43, -1 }, - { "glProgramUniform2i", 43, -1 }, - { "glProgramUniform2iv", 43, -1 }, - { "glProgramUniform2f", 43, -1 }, - { "glProgramUniform2fv", 43, -1 }, - { "glProgramUniform2d", 40, -1 }, - { "glProgramUniform2dv", 40, -1 }, - { "glProgramUniform2ui", 43, -1 }, - { "glProgramUniform2uiv", 43, -1 }, - { "glProgramUniform3i", 43, -1 }, - { "glProgramUniform3iv", 43, -1 }, - { "glProgramUniform3f", 43, -1 }, - { "glProgramUniform3fv", 43, -1 }, - { "glProgramUniform3d", 40, -1 }, - { "glProgramUniform3dv", 40, -1 }, - { "glProgramUniform3ui", 43, -1 }, - { "glProgramUniform3uiv", 43, -1 }, - { "glProgramUniform4i", 43, -1 }, - { "glProgramUniform4iv", 43, -1 }, - { "glProgramUniform4d", 43, -1 }, - { "glProgramUniform4dv", 43, -1 }, - { "glProgramUniform4f", 43, -1 }, - { "glProgramUniform4fv", 43, -1 }, - { "glProgramUniform4ui", 43, -1 }, - { "glProgramUniform4uiv", 43, -1 }, - { "glProgramUniformMatrix2dv", 43, -1 }, - { "glProgramUniformMatrix2fv", 43, -1 }, - { "glProgramUniformMatrix3dv", 43, -1 }, - { "glProgramUniformMatrix3fv", 43, -1 }, - { "glProgramUniformMatrix4dv", 43, -1 }, - { "glProgramUniformMatrix4fv", 43, -1 }, - { "glProgramUniformMatrix2x3dv", 43, -1 }, - { "glProgramUniformMatrix2x3fv", 43, -1 }, - { "glProgramUniformMatrix3x2dv", 43, -1 }, - { "glProgramUniformMatrix3x2fv", 43, -1 }, - { "glProgramUniformMatrix2x4dv", 43, -1 }, - { "glProgramUniformMatrix2x4fv", 43, -1 }, - { "glProgramUniformMatrix4x2dv", 43, -1 }, - { "glProgramUniformMatrix4x2fv", 43, -1 }, - { "glProgramUniformMatrix3x4dv", 43, -1 }, - { "glProgramUniformMatrix3x4fv", 43, -1 }, - { "glProgramUniformMatrix4x3dv", 43, -1 }, - { "glProgramUniformMatrix4x3fv", 43, -1 }, - { "glValidateProgramPipeline", 43, -1 }, - { "glGetProgramPipelineInfoLog", 43, -1 }, - { "glGetFloati_v", 43, -1 }, - { "glGetDoublei_v", 43, -1 }, -// { "glCreateSyncFromCLeventARB", 43, -1 }, // XXX: Add to xml - { "glGetGraphicsResetStatusARB", 43, -1 }, - { "glGetnMapdvARB", 43, -1 }, - { "glGetnMapfvARB", 43, -1 }, - { "glGetnMapivARB", 43, -1 }, - { "glGetnPixelMapfvARB", 43, -1 }, - { "glGetnPixelMapuivARB", 43, -1 }, - { "glGetnPixelMapusvARB", 43, -1 }, - { "glGetnPolygonStippleARB", 43, -1 }, - { "glGetnColorTableARB", 43, -1 }, - { "glGetnConvolutionFilterARB", 43, -1 }, - { "glGetnSeparableFilterARB", 43, -1 }, - { "glGetnHistogramARB", 43, -1 }, - { "glGetnMinmaxARB", 43, -1 }, - { "glGetnTexImageARB", 43, -1 }, - { "glReadnPixelsARB", 43, -1 }, - { "glGetnCompressedTexImageARB", 43, -1 }, - { "glGetnUniformfvARB", 43, -1 }, - { "glGetnUniformivARB", 43, -1 }, - { "glGetnUniformuivARB", 43, -1 }, - { "glGetnUniformdvARB", 43, -1 }, - { "glDrawArraysInstancedBaseInstance", 43, -1 }, - { "glDrawElementsInstancedBaseInstance", 43, -1 }, - { "glDrawElementsInstancedBaseVertexBaseInstance", 43, -1 }, - { "glDrawTransformFeedbackInstanced", 43, -1 }, - { "glDrawTransformFeedbackStreamInstanced", 43, -1 }, -// { "glGetInternalformativ", 43, -1 }, // XXX: Add to xml - { "glGetActiveAtomicCounterBufferiv", 43, -1 }, - { "glBindImageTexture", 43, -1 }, - { "glMemoryBarrier", 43, -1 }, - { "glTexStorage1D", 43, -1 }, - { "glTexStorage2D", 43, -1 }, - { "glTexStorage3D", 43, -1 }, - { "glTextureStorage1DEXT", 43, -1 }, - { "glTextureStorage2DEXT", 43, -1 }, - { "glTextureStorage3DEXT", 43, -1 }, - { "glClearBufferData", 43, -1 }, - { "glClearBufferSubData", 43, -1 }, - { "glClearNamedBufferDataEXT", 43, -1 }, - { "glClearNamedBufferSubDataEXT", 43, -1 }, - { "glCopyImageSubData", 43, -1 }, - { "glTextureView", 43, -1 }, - { "glBindVertexBuffer", 43, -1 }, - { "glVertexAttribFormat", 43, -1 }, - { "glVertexAttribIFormat", 43, -1 }, - { "glVertexAttribLFormat", 43, -1 }, - { "glVertexAttribBinding", 43, -1 }, - { "glVertexBindingDivisor", 43, -1 }, - { "glVertexArrayBindVertexBufferEXT", 43, -1 }, - { "glVertexArrayVertexAttribFormatEXT", 43, -1 }, - { "glVertexArrayVertexAttribIFormatEXT", 43, -1 }, - { "glVertexArrayVertexAttribLFormatEXT", 43, -1 }, - { "glVertexArrayVertexAttribBindingEXT", 43, -1 }, - { "glVertexArrayVertexBindingDivisorEXT", 43, -1 }, - { "glFramebufferParameteri", 43, -1 }, - { "glGetFramebufferParameteriv", 43, -1 }, - { "glNamedFramebufferParameteriEXT", 43, -1 }, - { "glGetNamedFramebufferParameterivEXT", 43, -1 }, -// { "glGetInternalformati64v", 43, -1 }, // XXX: Add to xml - { "glInvalidateTexSubImage", 43, -1 }, - { "glInvalidateTexImage", 43, -1 }, - { "glInvalidateBufferSubData", 43, -1 }, - { "glInvalidateBufferData", 43, -1 }, - { "glInvalidateFramebuffer", 43, -1 }, - { "glInvalidateSubFramebuffer", 43, -1 }, - { "glMultiDrawArraysIndirect", 43, -1 }, - { "glMultiDrawElementsIndirect", 43, -1 }, - { "glGetProgramInterfaceiv", 43, -1 }, - { "glGetProgramResourceIndex", 43, -1 }, - { "glGetProgramResourceName", 43, -1 }, - { "glGetProgramResourceiv", 43, -1 }, - { "glGetProgramResourceLocation", 43, -1 }, - { "glGetProgramResourceLocationIndex", 43, -1 }, - { "glShaderStorageBlockBinding", 43, -1 }, - { "glTextureBufferRangeEXT", 43, -1 }, - { "glTexStorage2DMultisample", 43, -1 }, - { "glTexStorage3DMultisample", 43, -1 }, - { "glTextureStorage2DMultisampleEXT", 43, -1 }, - { "glTextureStorage3DMultisampleEXT", 43, -1 }, - - { "glViewportArrayv", 43, -1 }, - { "glViewportIndexedf", 43, -1 }, - { "glViewportIndexedfv", 43, -1 }, - { "glScissorArrayv", 43, -1 }, - { "glScissorIndexed", 43, -1 }, - { "glScissorIndexedv", 43, -1 }, - { "glDepthRangeArrayv", 43, -1 }, - { "glDepthRangeIndexed", 43, -1 }, - -/* GL 4.4 */ - /* GL_NV_alpha_to_coverage_dither_control */ - { "glAlphaToCoverageDitherControlNV", 44, -1 }, - -/* GL 4.5 */ - /* aliased versions checked above */ - //{ "glGetGraphicsResetStatus", 45, -1 }, - //{ "glReadnPixels", 45, -1 }, - //{ "glGetnUniformfv", 45, -1 }, - //{ "glGetnUniformiv", 45, -1 }, - //{ "glGetnUniformuiv", 45, -1 }, - { "glMemoryBarrierByRegion", 45, -1 }, - - /* GL_ARB_direct_state_access */ - { "glCreateTransformFeedbacks", 45, -1 }, - { "glTransformFeedbackBufferBase", 45, -1 }, - { "glTransformFeedbackBufferRange", 45, -1 }, - { "glGetTransformFeedbackiv", 45, -1 }, - { "glGetTransformFeedbacki_v", 45, -1 }, - { "glGetTransformFeedbacki64_v", 45, -1 }, - { "glCreateBuffers", 45, -1 }, - { "glNamedBufferStorage", 45, -1 }, - { "glNamedBufferData", 45, -1 }, - { "glNamedBufferSubData", 45, -1 }, - { "glCopyNamedBufferSubData", 45, -1 }, - { "glClearNamedBufferData", 45, -1 }, - { "glClearNamedBufferSubData", 45, -1 }, - { "glMapNamedBuffer", 45, -1 }, - { "glMapNamedBufferRange", 45, -1 }, - { "glFlushMappedNamedBufferRange", 45, -1 }, - { "glGetNamedBufferParameteriv", 45, -1 }, - { "glGetNamedBufferParameteri64v", 45, -1 }, - { "glGetNamedBufferPointerv", 45, -1 }, - { "glGetNamedBufferSubData", 45, -1 }, - { "glCreateFramebuffers", 45, -1 }, - { "glNamedFramebufferRenderbuffer", 45, -1 }, - { "glNamedFramebufferParameteri", 45, -1 }, - { "glNamedFramebufferTexture", 45, -1 }, - { "glNamedFramebufferTextureLayer", 45, -1 }, - { "glNamedFramebufferDrawBuffer", 45, -1 }, - { "glNamedFramebufferDrawBuffers", 45, -1 }, - { "glNamedFramebufferReadBuffer", 45, -1 }, - { "glInvalidateNamedFramebufferSubData", 45, -1 }, - { "glInvalidateNamedFramebufferData", 45, -1 }, - { "glClearNamedFramebufferiv", 45, -1 }, - { "glClearNamedFramebufferuiv", 45, -1 }, - { "glClearNamedFramebufferfv", 45, -1 }, - { "glClearNamedFramebufferfi", 45, -1 }, - { "glBlitNamedFramebuffer", 45, -1 }, - { "glCheckNamedFramebufferStatus", 45, -1 }, - { "glGetNamedFramebufferParameteriv", 45, -1 }, - { "glGetNamedFramebufferAttachmentParameteriv", 45, -1 }, - { "glCreateRenderbuffers", 45, -1 }, - { "glNamedRenderbufferStorage", 45, -1 }, - { "glNamedRenderbufferStorageMultisample", 45, -1 }, - { "glGetNamedRenderbufferParameteriv", 45, -1 }, - { "glCreateTextures", 45, -1 }, - { "glTextureStorage1D", 45, -1 }, - { "glTextureStorage2D", 45, -1 }, - { "glTextureStorage3D", 45, -1 }, - { "glTextureSubImage1D", 45, -1 }, - { "glTextureSubImage2D", 45, -1 }, - { "glTextureSubImage3D", 45, -1 }, - { "glBindTextureUnit", 45, -1 }, - { "glTextureParameterf", 45, -1 }, - { "glTextureParameterfv", 45, -1 }, - { "glTextureParameteri", 45, -1 }, - { "glTextureParameterIiv", 45, -1 }, - { "glTextureParameterIuiv", 45, -1 }, - { "glTextureParameteriv", 45, -1 }, - { "glGetTextureLevelParameterfv", 45, -1 }, - { "glGetTextureLevelParameteriv", 45, -1 }, - { "glGetTextureParameterfv", 45, -1 }, - { "glGetTextureParameterIiv", 45, -1 }, - { "glGetTextureParameterIuiv", 45, -1 }, - { "glGetTextureParameteriv", 45, -1 }, - { "glCopyTextureSubImage1D", 45, -1 }, - { "glCopyTextureSubImage2D", 45, -1 }, - { "glCopyTextureSubImage3D", 45, -1 }, - { "glGetTextureImage", 45, -1 }, - { "glGetCompressedTextureImage", 45, -1 }, - { "glCompressedTextureSubImage1D", 45, -1 }, - { "glCompressedTextureSubImage2D", 45, -1 }, - { "glCompressedTextureSubImage3D", 45, -1 }, - { "glGenerateTextureMipmap", 45, -1 }, - { "glTextureStorage2DMultisample", 45, -1 }, - { "glTextureStorage3DMultisample", 45, -1 }, - { "glTextureBuffer", 45, -1 }, - { "glTextureBufferRange", 45, -1 }, - { "glCreateVertexArrays", 45, -1 }, - { "glDisableVertexArrayAttrib", 45, -1 }, - { "glEnableVertexArrayAttrib", 45, -1 }, - { "glVertexArrayElementBuffer", 45, -1 }, - { "glVertexArrayVertexBuffer", 45, -1 }, - { "glVertexArrayVertexBuffers", 45, -1 }, - { "glVertexArrayAttribFormat", 45, -1 }, - { "glVertexArrayAttribIFormat", 45, -1 }, - { "glVertexArrayAttribLFormat", 45, -1 }, - { "glVertexArrayAttribBinding", 45, -1 }, - { "glVertexArrayBindingDivisor", 45, -1 }, - { "glGetVertexArrayiv", 45, -1 }, - { "glGetVertexArrayIndexediv", 45, -1 }, - { "glGetVertexArrayIndexed64iv", 45, -1 }, - { "glCreateSamplers", 45, -1 }, - { "glCreateProgramPipelines", 45, -1 }, - { "glCreateQueries", 45, -1 }, - { "glGetQueryBufferObjectiv", 45, -1 }, - { "glGetQueryBufferObjectuiv", 45, -1 }, - { "glGetQueryBufferObjecti64v", 45, -1 }, - { "glGetQueryBufferObjectui64v", 45, -1 }, - - /* GL_EXT_direct_state_access - GL 1.0 */ - { "glMatrixLoadfEXT", 10, -1 }, - { "glMatrixLoaddEXT", 10, -1 }, - { "glMatrixMultfEXT", 10, -1 }, - { "glMatrixMultdEXT", 10, -1 }, - { "glMatrixLoadIdentityEXT", 10, -1 }, - { "glMatrixRotatefEXT", 10, -1 }, - { "glMatrixRotatedEXT", 10, -1 }, - { "glMatrixScalefEXT", 10, -1 }, - { "glMatrixScaledEXT", 10, -1 }, - { "glMatrixTranslatefEXT", 10, -1 }, - { "glMatrixTranslatedEXT", 10, -1 }, - { "glMatrixOrthoEXT", 10, -1 }, - { "glMatrixFrustumEXT", 10, -1 }, - { "glMatrixPushEXT", 10, -1 }, - { "glMatrixPopEXT", 10, -1 }, - /* GL_EXT_direct_state_access - GL 1.1 */ - { "glClientAttribDefaultEXT", 11, -1 }, - { "glPushClientAttribDefaultEXT", 11, -1 }, - { "glTextureParameteriEXT", 11, -1 }, - { "glTextureParameterivEXT", 11, -1 }, - { "glTextureParameterfEXT", 11, -1 }, - { "glTextureParameterfvEXT", 11, -1 }, - { "glTextureImage1DEXT", 11, -1 }, - { "glTextureImage2DEXT", 11, -1 }, - { "glTextureSubImage1DEXT", 11, -1 }, - { "glTextureSubImage2DEXT", 11, -1 }, - { "glCopyTextureImage1DEXT", 11, -1 }, - { "glCopyTextureImage2DEXT", 11, -1 }, - { "glCopyTextureSubImage1DEXT", 11, -1 }, - { "glCopyTextureSubImage2DEXT", 11, -1 }, - { "glGetTextureImageEXT", 11, -1 }, - { "glGetTextureParameterfvEXT", 11, -1 }, - { "glGetTextureParameterivEXT", 11, -1 }, - { "glGetTextureLevelParameterfvEXT", 11, -1 }, - { "glGetTextureLevelParameterivEXT", 11, -1 }, - /* GL_EXT_direct_state_access - GL 1.2 */ - { "glTextureImage3DEXT", 12, -1 }, - { "glTextureSubImage3DEXT", 12, -1 }, - { "glCopyTextureSubImage3DEXT", 12, -1 }, - /* GL_EXT_direct_state_access - GL 1.2.1 */ - { "glBindMultiTextureEXT", 12, -1 }, - { "glMultiTexCoordPointerEXT", 12, -1 }, - { "glMultiTexEnvfEXT", 12, -1 }, - { "glMultiTexEnvfvEXT", 12, -1 }, - { "glMultiTexEnviEXT", 12, -1 }, - { "glMultiTexEnvivEXT", 12, -1 }, - { "glMultiTexGendEXT", 12, -1 }, - { "glMultiTexGendvEXT", 12, -1 }, - { "glMultiTexGenfEXT", 12, -1 }, - { "glMultiTexGenfvEXT", 12, -1 }, - { "glMultiTexGeniEXT", 12, -1 }, - { "glMultiTexGenivEXT", 12, -1 }, - { "glGetMultiTexEnvfvEXT", 12, -1 }, - { "glGetMultiTexEnvivEXT", 12, -1 }, - { "glGetMultiTexGendvEXT", 12, -1 }, - { "glGetMultiTexGenfvEXT", 12, -1 }, - { "glGetMultiTexGenivEXT", 12, -1 }, - { "glMultiTexParameterfEXT", 12, -1 }, - { "glMultiTexParameterfvEXT", 12, -1 }, - { "glMultiTexParameteriEXT", 12, -1 }, - { "glMultiTexParameterivEXT", 12, -1 }, - { "glMultiTexImage1DEXT", 12, -1 }, - { "glMultiTexImage2DEXT", 12, -1 }, - { "glMultiTexSubImage1DEXT", 12, -1 }, - { "glMultiTexSubImage2DEXT", 12, -1 }, - { "glCopyMultiTexImage1DEXT", 12, -1 }, - { "glCopyMultiTexImage2DEXT", 12, -1 }, - { "glCopyMultiTexSubImage1DEXT", 12, -1 }, - { "glCopyMultiTexSubImage2DEXT", 12, -1 }, - { "glGetMultiTexImageEXT", 12, -1 }, - { "glGetMultiTexParameterfvEXT", 12, -1 }, - { "glGetMultiTexParameterivEXT", 12, -1 }, - { "glGetMultiTexLevelParameterfvEXT", 12, -1 }, - { "glGetMultiTexLevelParameterivEXT", 12, -1 }, - { "glMultiTexImage3DEXT", 12, -1 }, - { "glMultiTexSubImage3DEXT", 12, -1 }, - { "glCopyMultiTexSubImage3DEXT", 12, -1 }, - { "glEnableClientStateIndexedEXT", 12, -1 }, - { "glDisableClientStateIndexedEXT", 12, -1 }, - { "glGetPointerIndexedvEXT", 12, -1 }, - /* GL_EXT_direct_state_access - ARB_vertex_program */ - { "glNamedProgramStringEXT", 10, -1 }, - { "glNamedProgramLocalParameter4dEXT", 10, -1 }, - { "glNamedProgramLocalParameter4dvEXT", 10, -1 }, - { "glNamedProgramLocalParameter4fEXT", 10, -1 }, - { "glNamedProgramLocalParameter4fvEXT", 10, -1 }, - { "glGetNamedProgramLocalParameterdvEXT", 10, -1 }, - { "glGetNamedProgramLocalParameterfvEXT", 10, -1 }, - { "glGetNamedProgramivEXT", 10, -1 }, - { "glGetNamedProgramStringEXT", 10, -1 }, - /* GL_EXT_direct_state_access - GL 1.3 */ - { "glCompressedTextureImage1DEXT", 13, -1 }, - { "glCompressedTextureImage2DEXT", 13, -1 }, - { "glCompressedTextureImage3DEXT", 13, -1 }, - { "glCompressedTextureSubImage1DEXT", 13, -1 }, - { "glCompressedTextureSubImage2DEXT", 13, -1 }, - { "glCompressedTextureSubImage3DEXT", 13, -1 }, - { "glGetCompressedTextureImageEXT", 13, -1 }, - { "glCompressedMultiTexImage1DEXT", 13, -1 }, - { "glCompressedMultiTexImage2DEXT", 13, -1 }, - { "glCompressedMultiTexImage3DEXT", 13, -1 }, - { "glCompressedMultiTexSubImage1DEXT", 13, -1 }, - { "glCompressedMultiTexSubImage2DEXT", 13, -1 }, - { "glCompressedMultiTexSubImage3DEXT", 13, -1 }, - { "glGetCompressedMultiTexImageEXT", 13, -1 }, - { "glMatrixLoadTransposefEXT", 13, -1 }, - { "glMatrixLoadTransposedEXT", 13, -1 }, - { "glMatrixMultTransposefEXT", 13, -1 }, - { "glMatrixMultTransposedEXT", 13, -1 }, - /* GL_EXT_direct_state_access - GL 1.5 */ - { "glNamedBufferDataEXT", 15, -1 }, - { "glNamedBufferSubDataEXT", 15, -1 }, - { "glMapNamedBufferEXT", 15, -1 }, - { "glUnmapNamedBufferEXT", 15, -1 }, - { "glGetNamedBufferParameterivEXT", 15, -1 }, - { "glGetNamedBufferPointervEXT", 15, -1 }, - { "glGetNamedBufferSubDataEXT", 15, -1 }, - /* GL_EXT_direct_state_access - GL 2.0 */ - /* Added glProgramUniform*EXT functions are aliases */ - /* GL_EXT_direct_state_access - GL 2.1 */ - /* Added glProgramUniformMAtrix*EXT functions are aliases */ - /* GL_EXT_direct_state_access - EXT_texture_buffer_object */ - { "glTextureBufferEXT", 10, -1 }, - { "glMultiTexBufferEXT", 10, -1 }, - /* GL_EXT_direct_state_access - EXT_texture_integer */ - { "glTextureParameterIivEXT", 10, -1 }, - { "glTextureParameterIuivEXT", 10, -1 }, - { "glGetTextureParameterIivEXT", 10, -1 }, - { "glGetTextureParameterIuivEXT", 10, -1 }, - { "glMultiTexParameterIivEXT", 10, -1 }, - { "glMultiTexParameterIuivEXT", 10, -1 }, - { "glGetMultiTexParameterIivEXT", 10, -1 }, - { "glGetMultiTexParameterIuivEXT", 10, -1 }, - /* GL_EXT_direct_state_access - EXT_gpu_shader4 */ - /* Added glProgramUniform*u*EXT functions are aliases */ - /* GL_EXT_direct_state_access - EXT_gpu_program_parameters */ - { "glNamedProgramLocalParameters4fvEXT", 10, -1 }, - /* GL_EXT_direct_state_access - GL 3.0 */ - { "glNamedRenderbufferStorageEXT", 30, -1 }, - { "glGetNamedRenderbufferParameterivEXT", 30, -1 }, - { "glNamedRenderbufferStorageMultisampleEXT", 30, -1 }, - { "glCheckNamedFramebufferStatusEXT", 30, -1 }, - { "glNamedFramebufferTexture1DEXT", 30, -1 }, - { "glNamedFramebufferTexture2DEXT", 30, -1 }, - { "glNamedFramebufferTexture3DEXT", 30, -1 }, - { "glNamedFramebufferRenderbufferEXT", 30, -1 }, - { "glGetNamedFramebufferAttachmentParameterivEXT", 30, -1 }, - { "glGenerateTextureMipmapEXT", 30, -1 }, - { "glGenerateMultiTexMipmapEXT", 30, -1 }, - { "glFramebufferDrawBufferEXT", 30, -1 }, - { "glFramebufferDrawBuffersEXT", 30, -1 }, - { "glFramebufferReadBufferEXT", 30, -1 }, - { "glGetFramebufferParameterivEXT", 30, -1 }, - { "glNamedCopyBufferSubDataEXT", 30, -1 }, - { "glVertexArrayVertexOffsetEXT", 30, -1 }, - { "glVertexArrayColorOffsetEXT", 30, -1 }, - { "glVertexArrayEdgeFlagOffsetEXT", 30, -1 }, - { "glVertexArrayIndexOffsetEXT", 30, -1 }, - { "glVertexArrayNormalOffsetEXT", 30, -1 }, - { "glVertexArrayTexCoordOffsetEXT", 30, -1 }, - { "glVertexArrayMultiTexCoordOffsetEXT", 30, -1 }, - { "glVertexArrayFogCoordOffsetEXT", 30, -1 }, - { "glVertexArraySecondaryColorOffsetEXT", 30, -1 }, - { "glVertexArrayVertexAttribOffsetEXT", 30, -1 }, - { "glVertexArrayVertexAttribIOffsetEXT", 30, -1 }, - { "glEnableVertexArrayEXT", 30, -1 }, - { "glDisableVertexArrayEXT", 30, -1 }, - { "glEnableVertexArrayAttribEXT", 30, -1 }, - { "glDisableVertexArrayAttribEXT", 30, -1 }, - { "glGetVertexArrayIntegervEXT", 30, -1 }, - { "glGetVertexArrayPointervEXT", 30, -1 }, - { "glGetVertexArrayIntegeri_vEXT", 30, -1 }, - { "glGetVertexArrayPointeri_vEXT", 30, -1 }, - { "glMapNamedBufferRangeEXT", 30, -1 }, - { "glFlushMappedNamedBufferRangeEXT", 30, -1 }, - - /* GL_ARB_internalformat_query */ - { "glGetInternalformativ", 30, -1 }, - - /* GL_ARB_internalformat_query */ - { "glGetInternalformati64v", 30, -1 }, - - /* GL_ARB_multi_bind */ - { "glBindBuffersBase", 44, -1 }, - { "glBindBuffersRange", 44, -1 }, - { "glBindTextures", 44, -1 }, - { "glBindSamplers", 44, -1 }, - { "glBindImageTextures", 44, -1 }, - { "glBindVertexBuffers", 44, -1 }, - - /* GL_ARB_shading_language_include */ - { "glNamedStringARB", 20, -1 }, - { "glDeleteNamedStringARB", 20, -1 }, - { "glCompileShaderIncludeARB", 20, -1 }, - { "glIsNamedStringARB", 20, -1 }, - { "glGetNamedStringARB", 20, -1 }, - { "glGetNamedStringivARB", 20, -1 }, - - /* GL_KHR_debug/GL_ARB_debug_output */ - { "glPushDebugGroup", 11, -1 }, - { "glPopDebugGroup", 11, -1 }, - { "glDebugMessageCallback", 11, -1 }, - { "glDebugMessageControl", 11, -1 }, - { "glDebugMessageInsert", 11, -1 }, - { "glGetDebugMessageLog", 11, -1 }, - { "glGetObjectLabel", 11, -1 }, - { "glGetObjectPtrLabel", 11, -1 }, - { "glObjectLabel", 11, -1 }, - { "glObjectPtrLabel", 11, -1 }, - /* aliased versions checked above */ - //{ "glDebugMessageControlARB", 11, -1 }, - //{ "glDebugMessageInsertARB", 11, -1 }, - //{ "glDebugMessageCallbackARB", 11, -1 }, - //{ "glGetDebugMessageLogARB", 11, -1 }, - - /* GL_AMD_performance_monitor */ - { "glGetPerfMonitorGroupsAMD", 11, -1 }, - { "glGetPerfMonitorCountersAMD", 11, -1 }, - { "glGetPerfMonitorGroupStringAMD", 11, -1 }, - { "glGetPerfMonitorCounterStringAMD", 11, -1 }, - { "glGetPerfMonitorCounterInfoAMD", 11, -1 }, - { "glGenPerfMonitorsAMD", 11, -1 }, - { "glDeletePerfMonitorsAMD", 11, -1 }, - { "glSelectPerfMonitorCountersAMD", 11, -1 }, - { "glBeginPerfMonitorAMD", 11, -1 }, - { "glEndPerfMonitorAMD", 11, -1 }, - { "glGetPerfMonitorCounterDataAMD", 11, -1 }, - - /* GL_INTEL_performance_query */ - { "glGetFirstPerfQueryIdINTEL", 30, -1 }, - { "glGetNextPerfQueryIdINTEL", 30, -1 }, - { "glGetPerfQueryIdByNameINTEL", 30, -1 }, - { "glGetPerfQueryInfoINTEL", 30, -1 }, - { "glGetPerfCounterInfoINTEL", 30, -1 }, - { "glCreatePerfQueryINTEL", 30, -1 }, - { "glDeletePerfQueryINTEL", 30, -1 }, - { "glBeginPerfQueryINTEL", 30, -1 }, - { "glEndPerfQueryINTEL", 30, -1 }, - { "glGetPerfQueryDataINTEL", 30, -1 }, - - /* GL_NV_vdpau_interop */ - { "glVDPAUInitNV", 11, -1 }, - { "glVDPAUFiniNV", 11, -1 }, - { "glVDPAURegisterVideoSurfaceNV", 11, -1 }, - { "glVDPAURegisterOutputSurfaceNV", 11, -1 }, - { "glVDPAUIsSurfaceNV", 11, -1 }, - { "glVDPAUUnregisterSurfaceNV", 11, -1 }, - { "glVDPAUGetSurfaceivNV", 11, -1 }, - { "glVDPAUSurfaceAccessNV", 11, -1 }, - { "glVDPAUMapSurfacesNV", 11, -1 }, - { "glVDPAUUnmapSurfacesNV", 11, -1 }, - - /* GL_ARB_buffer_storage */ - { "glBufferStorage", 43, -1 }, - { "glNamedBufferStorageEXT", 43, -1 }, - - /* GL_ARB_clear_texture */ - { "glClearTexImage", 13, -1 }, - { "glClearTexSubImage", 13, -1 }, - - /* GL_ARB_clip_control */ - { "glClipControl", 45, -1 }, - - /* GL_ARB_compute_shader */ - { "glDispatchCompute", 43, -1 }, - { "glDispatchComputeIndirect", 43, -1 }, - - /* GL_ARB_compute_variable_group_size */ - { "glDispatchComputeGroupSizeARB", 43, -1 }, - - /* GL_EXT_polygon_offset_clamp */ - { "glPolygonOffsetClampEXT", 11, -1 }, - - /* GL_ARB_get_texture_sub_image */ - { "glGetTextureSubImage", 20, -1 }, - { "glGetCompressedTextureSubImage", 20, -1 }, - - /* GL_GREMEDY_string_marker */ - { "glStringMarkerGREMEDY", 15, -1 }, - - /* GL_EXT_window_rectangles */ - { "glWindowRectanglesEXT", 30, -1 }, - - /* GL_KHR_blend_equation_advanced */ - { "glBlendBarrierKHR", 20, -1 }, - - /* GL_ARB_sparse_buffer */ - { "glBufferPageCommitmentARB", 43, -1 }, - { "glNamedBufferPageCommitmentARB", 43, -1 }, - { "glNamedBufferPageCommitmentEXT", 43, -1 }, - - /* GL_ARB_bindless_texture */ - { "glGetTextureHandleARB", 40, -1 }, - { "glGetTextureSamplerHandleARB", 40, -1 }, - { "glMakeTextureHandleResidentARB", 40, -1 }, - { "glMakeTextureHandleNonResidentARB", 40, -1 }, - { "glIsTextureHandleResidentARB", 40, -1 }, - { "glGetImageHandleARB", 40, -1 }, - { "glMakeImageHandleResidentARB", 40, -1 }, - { "glMakeImageHandleNonResidentARB", 40, -1 }, - { "glIsImageHandleResidentARB", 40, -1 }, - { "glUniformHandleui64ARB", 40, -1 }, - { "glUniformHandleui64vARB", 40, -1 }, - { "glProgramUniformHandleui64ARB", 40, -1 }, - { "glProgramUniformHandleui64vARB", 40, -1 }, - { "glVertexAttribL1ui64ARB", 40, -1 }, - { "glVertexAttribL1ui64vARB", 40, -1 }, - { "glGetVertexAttribLui64vARB", 40, -1 }, - - /* GL_EXT_external_objects */ - { "glGetUnsignedBytevEXT", 45, -1 }, - { "glGetUnsignedBytei_vEXT", 45, -1 }, - { "glDeleteMemoryObjectsEXT", 45, -1 }, - { "glIsMemoryObjectEXT", 45, -1 }, - { "glCreateMemoryObjectsEXT", 45, -1 }, - { "glMemoryObjectParameterivEXT", 45, -1 }, - { "glGetMemoryObjectParameterivEXT", 45, -1 }, - { "glTexStorageMem2DEXT", 45, -1 }, - { "glTexStorageMem2DMultisampleEXT", 45, -1 }, - { "glTexStorageMem3DEXT", 45, -1 }, - { "glTexStorageMem3DMultisampleEXT", 45, -1 }, - { "glBufferStorageMemEXT", 45, -1 }, - { "glTextureStorageMem2DEXT", 45, -1 }, - { "glTextureStorageMem2DMultisampleEXT", 45, -1 }, - { "glTextureStorageMem3DEXT", 45, -1 }, - { "glTextureStorageMem3DMultisampleEXT", 45, -1 }, - { "glNamedBufferStorageMemEXT", 45, -1 }, - { "glTexStorageMem1DEXT", 45, -1 }, - { "glTextureStorageMem1DEXT", 45, -1 }, - { "glGenSemaphoresEXT", 45, -1 }, - { "glDeleteSemaphoresEXT", 45, -1 }, - { "glIsSemaphoreEXT", 45, -1 }, - { "glSemaphoreParameterui64vEXT", 45, -1 }, - { "glGetSemaphoreParameterui64vEXT", 45, -1 }, - { "glWaitSemaphoreEXT", 45, -1 }, - { "glSignalSemaphoreEXT", 45, -1 }, - - /* GL_EXT_external_objects_fd */ - { "glImportMemoryFdEXT", 45, -1 }, - { "glImportSemaphoreFdEXT", 45, -1 }, - - /* GL_ARB_gl_spirv */ - { "glSpecializeShaderARB", 45, -1 }, - - /* GL_EXT_shader_framebuffer_fetch_non_coherent */ - { "glFramebufferFetchBarrierEXT", 20, -1 }, - - /* GL_NV_conservative_raster */ - { "glSubpixelPrecisionBiasNV", 10, -1 }, - - /* GL_NV_conservative_raster_dilate */ - { "glConservativeRasterParameterfNV", 10, -1 }, - - /* GL_NV_conservative_raster_pre_snap_triangles */ - { "glConservativeRasterParameteriNV", 10, -1 }, - - /* GL_ARB_sample_locations */ - { "glFramebufferSampleLocationsfvARB", 30, -1 }, - { "glNamedFramebufferSampleLocationsfvARB", 30, -1 }, - { "glEvaluateDepthValuesARB", 30, -1 }, - - /* GL_ARB_indirect_parameters */ - { "glMultiDrawArraysIndirectCountARB", 11, -1 }, - { "glMultiDrawElementsIndirectCountARB", 11, -1 }, - - /* GL_AMD_framebuffer_multisample_advanced */ - { "glRenderbufferStorageMultisampleAdvancedAMD", 11, -1 }, - { "glNamedRenderbufferStorageMultisampleAdvancedAMD", 11, -1 }, - - { "glMaxShaderCompilerThreadsKHR", 11, -1 }, - - /* GL_EXT_shader_image_load_store */ - { "glBindImageTextureEXT", 30, -1 }, - - /* GL_MESA_framebuffer_flip_y */ - { "glFramebufferParameteriMESA", 43, -1 }, - { "glGetFramebufferParameterivMESA", 43, -1 }, - - /* GL_ARB_gpu_shader_int64 */ - { "glUniform1i64ARB", 40, -1 }, - { "glUniform2i64ARB", 40, -1 }, - { "glUniform3i64ARB", 40, -1 }, - { "glUniform4i64ARB", 40, -1 }, - { "glUniform1ui64ARB", 40, -1 }, - { "glUniform2ui64ARB", 40, -1 }, - { "glUniform3ui64ARB", 40, -1 }, - { "glUniform4ui64ARB", 40, -1 }, - { "glUniform1i64vARB", 40, -1 }, - { "glUniform2i64vARB", 40, -1 }, - { "glUniform3i64vARB", 40, -1 }, - { "glUniform4i64vARB", 40, -1 }, - { "glUniform1ui64vARB", 40, -1 }, - { "glUniform2ui64vARB", 40, -1 }, - { "glUniform3ui64vARB", 40, -1 }, - { "glUniform4ui64vARB", 40, -1 }, - { "glGetUniformi64vARB", 40, -1 }, - { "glGetUniformui64vARB", 40, -1 }, - { "glGetnUniformi64vARB", 40, -1 }, - { "glGetnUniformui64vARB", 40, -1 }, - { "glProgramUniform1i64ARB", 40, -1 }, - { "glProgramUniform2i64ARB", 40, -1 }, - { "glProgramUniform3i64ARB", 40, -1 }, - { "glProgramUniform4i64ARB", 40, -1 }, - { "glProgramUniform1ui64ARB", 40, -1 }, - { "glProgramUniform2ui64ARB", 40, -1 }, - { "glProgramUniform3ui64ARB", 40, -1 }, - { "glProgramUniform4ui64ARB", 40, -1 }, - { "glProgramUniform1i64vARB", 40, -1 }, - { "glProgramUniform2i64vARB", 40, -1 }, - { "glProgramUniform3i64vARB", 40, -1 }, - { "glProgramUniform4i64vARB", 40, -1 }, - { "glProgramUniform1ui64vARB", 40, -1 }, - { "glProgramUniform2ui64vARB", 40, -1 }, - { "glProgramUniform3ui64vARB", 40, -1 }, - { "glProgramUniform4ui64vARB", 40, -1 }, - - /* GL_NV_viewport_swizzle */ - { "glViewportSwizzleNV", 11, -1 }, - - { "glInternalBufferSubDataCopyMESA", 11, -1 }, - { "glInternalSetError", 20, -1 }, - - { NULL, 0, -1 } -}; - -const struct function gl_compatibility_functions_possible[] = { - { "glNewList", 10, _gloffset_NewList }, - { "glEndList", 10, _gloffset_EndList }, - { "glCallList", 10, _gloffset_CallList }, - { "glCallLists", 10, _gloffset_CallLists }, - { "glDeleteLists", 10, _gloffset_DeleteLists }, - { "glGenLists", 10, _gloffset_GenLists }, - { "glListBase", 10, _gloffset_ListBase }, - { "glBegin", 10, _gloffset_Begin }, - { "glBitmap", 10, _gloffset_Bitmap }, - { "glColor3b", 10, _gloffset_Color3b }, - { "glColor3bv", 10, _gloffset_Color3bv }, - { "glColor3d", 10, _gloffset_Color3d }, - { "glColor3dv", 10, _gloffset_Color3dv }, - { "glColor3f", 10, _gloffset_Color3f }, - { "glColor3fv", 10, _gloffset_Color3fv }, - { "glColor3i", 10, _gloffset_Color3i }, - { "glColor3iv", 10, _gloffset_Color3iv }, - { "glColor3s", 10, _gloffset_Color3s }, - { "glColor3sv", 10, _gloffset_Color3sv }, - { "glColor3ub", 10, _gloffset_Color3ub }, - { "glColor3ubv", 10, _gloffset_Color3ubv }, - { "glColor3ui", 10, _gloffset_Color3ui }, - { "glColor3uiv", 10, _gloffset_Color3uiv }, - { "glColor3us", 10, _gloffset_Color3us }, - { "glColor3usv", 10, _gloffset_Color3usv }, - { "glColor4b", 10, _gloffset_Color4b }, - { "glColor4bv", 10, _gloffset_Color4bv }, - { "glColor4d", 10, _gloffset_Color4d }, - { "glColor4dv", 10, _gloffset_Color4dv }, - { "glColor4f", 10, _gloffset_Color4f }, - { "glColor4fv", 10, _gloffset_Color4fv }, - { "glColor4i", 10, _gloffset_Color4i }, - { "glColor4iv", 10, _gloffset_Color4iv }, - { "glColor4s", 10, _gloffset_Color4s }, - { "glColor4sv", 10, _gloffset_Color4sv }, - { "glColor4ub", 10, _gloffset_Color4ub }, - { "glColor4ubv", 10, _gloffset_Color4ubv }, - { "glColor4ui", 10, _gloffset_Color4ui }, - { "glColor4uiv", 10, _gloffset_Color4uiv }, - { "glColor4us", 10, _gloffset_Color4us }, - { "glColor4usv", 10, _gloffset_Color4usv }, - { "glEdgeFlag", 10, _gloffset_EdgeFlag }, - { "glEdgeFlagv", 10, _gloffset_EdgeFlagv }, - { "glEnd", 10, _gloffset_End }, - { "glIndexd", 10, _gloffset_Indexd }, - { "glIndexdv", 10, _gloffset_Indexdv }, - { "glIndexf", 10, _gloffset_Indexf }, - { "glIndexfv", 10, _gloffset_Indexfv }, - { "glIndexi", 10, _gloffset_Indexi }, - { "glIndexiv", 10, _gloffset_Indexiv }, - { "glIndexs", 10, _gloffset_Indexs }, - { "glIndexsv", 10, _gloffset_Indexsv }, - { "glNormal3b", 10, _gloffset_Normal3b }, - { "glNormal3bv", 10, _gloffset_Normal3bv }, - { "glNormal3d", 10, _gloffset_Normal3d }, - { "glNormal3dv", 10, _gloffset_Normal3dv }, - { "glNormal3f", 10, _gloffset_Normal3f }, - { "glNormal3fv", 10, _gloffset_Normal3fv }, - { "glNormal3i", 10, _gloffset_Normal3i }, - { "glNormal3iv", 10, _gloffset_Normal3iv }, - { "glNormal3s", 10, _gloffset_Normal3s }, - { "glNormal3sv", 10, _gloffset_Normal3sv }, - { "glRasterPos2d", 10, _gloffset_RasterPos2d }, - { "glRasterPos2dv", 10, _gloffset_RasterPos2dv }, - { "glRasterPos2f", 10, _gloffset_RasterPos2f }, - { "glRasterPos2fv", 10, _gloffset_RasterPos2fv }, - { "glRasterPos2i", 10, _gloffset_RasterPos2i }, - { "glRasterPos2iv", 10, _gloffset_RasterPos2iv }, - { "glRasterPos2s", 10, _gloffset_RasterPos2s }, - { "glRasterPos2sv", 10, _gloffset_RasterPos2sv }, - { "glRasterPos3d", 10, _gloffset_RasterPos3d }, - { "glRasterPos3dv", 10, _gloffset_RasterPos3dv }, - { "glRasterPos3f", 10, _gloffset_RasterPos3f }, - { "glRasterPos3fv", 10, _gloffset_RasterPos3fv }, - { "glRasterPos3i", 10, _gloffset_RasterPos3i }, - { "glRasterPos3iv", 10, _gloffset_RasterPos3iv }, - { "glRasterPos3s", 10, _gloffset_RasterPos3s }, - { "glRasterPos3sv", 10, _gloffset_RasterPos3sv }, - { "glRasterPos4d", 10, _gloffset_RasterPos4d }, - { "glRasterPos4dv", 10, _gloffset_RasterPos4dv }, - { "glRasterPos4f", 10, _gloffset_RasterPos4f }, - { "glRasterPos4fv", 10, _gloffset_RasterPos4fv }, - { "glRasterPos4i", 10, _gloffset_RasterPos4i }, - { "glRasterPos4iv", 10, _gloffset_RasterPos4iv }, - { "glRasterPos4s", 10, _gloffset_RasterPos4s }, - { "glRasterPos4sv", 10, _gloffset_RasterPos4sv }, - { "glRectd", 10, _gloffset_Rectd }, - { "glRectdv", 10, _gloffset_Rectdv }, - { "glRectf", 10, _gloffset_Rectf }, - { "glRectfv", 10, _gloffset_Rectfv }, - { "glRecti", 10, _gloffset_Recti }, - { "glRectiv", 10, _gloffset_Rectiv }, - { "glRects", 10, _gloffset_Rects }, - { "glRectsv", 10, _gloffset_Rectsv }, - { "glTexCoord1d", 10, _gloffset_TexCoord1d }, - { "glTexCoord1dv", 10, _gloffset_TexCoord1dv }, - { "glTexCoord1f", 10, _gloffset_TexCoord1f }, - { "glTexCoord1fv", 10, _gloffset_TexCoord1fv }, - { "glTexCoord1i", 10, _gloffset_TexCoord1i }, - { "glTexCoord1iv", 10, _gloffset_TexCoord1iv }, - { "glTexCoord1s", 10, _gloffset_TexCoord1s }, - { "glTexCoord1sv", 10, _gloffset_TexCoord1sv }, - { "glTexCoord2d", 10, _gloffset_TexCoord2d }, - { "glTexCoord2dv", 10, _gloffset_TexCoord2dv }, - { "glTexCoord2f", 10, _gloffset_TexCoord2f }, - { "glTexCoord2fv", 10, _gloffset_TexCoord2fv }, - { "glTexCoord2i", 10, _gloffset_TexCoord2i }, - { "glTexCoord2iv", 10, _gloffset_TexCoord2iv }, - { "glTexCoord2s", 10, _gloffset_TexCoord2s }, - { "glTexCoord2sv", 10, _gloffset_TexCoord2sv }, - { "glTexCoord3d", 10, _gloffset_TexCoord3d }, - { "glTexCoord3dv", 10, _gloffset_TexCoord3dv }, - { "glTexCoord3f", 10, _gloffset_TexCoord3f }, - { "glTexCoord3fv", 10, _gloffset_TexCoord3fv }, - { "glTexCoord3i", 10, _gloffset_TexCoord3i }, - { "glTexCoord3iv", 10, _gloffset_TexCoord3iv }, - { "glTexCoord3s", 10, _gloffset_TexCoord3s }, - { "glTexCoord3sv", 10, _gloffset_TexCoord3sv }, - { "glTexCoord4d", 10, _gloffset_TexCoord4d }, - { "glTexCoord4dv", 10, _gloffset_TexCoord4dv }, - { "glTexCoord4f", 10, _gloffset_TexCoord4f }, - { "glTexCoord4fv", 10, _gloffset_TexCoord4fv }, - { "glTexCoord4i", 10, _gloffset_TexCoord4i }, - { "glTexCoord4iv", 10, _gloffset_TexCoord4iv }, - { "glTexCoord4s", 10, _gloffset_TexCoord4s }, - { "glTexCoord4sv", 10, _gloffset_TexCoord4sv }, - { "glVertex2d", 10, _gloffset_Vertex2d }, - { "glVertex2dv", 10, _gloffset_Vertex2dv }, - { "glVertex2f", 10, _gloffset_Vertex2f }, - { "glVertex2fv", 10, _gloffset_Vertex2fv }, - { "glVertex2i", 10, _gloffset_Vertex2i }, - { "glVertex2iv", 10, _gloffset_Vertex2iv }, - { "glVertex2s", 10, _gloffset_Vertex2s }, - { "glVertex2sv", 10, _gloffset_Vertex2sv }, - { "glVertex3d", 10, _gloffset_Vertex3d }, - { "glVertex3dv", 10, _gloffset_Vertex3dv }, - { "glVertex3f", 10, _gloffset_Vertex3f }, - { "glVertex3fv", 10, _gloffset_Vertex3fv }, - { "glVertex3i", 10, _gloffset_Vertex3i }, - { "glVertex3iv", 10, _gloffset_Vertex3iv }, - { "glVertex3s", 10, _gloffset_Vertex3s }, - { "glVertex3sv", 10, _gloffset_Vertex3sv }, - { "glVertex4d", 10, _gloffset_Vertex4d }, - { "glVertex4dv", 10, _gloffset_Vertex4dv }, - { "glVertex4f", 10, _gloffset_Vertex4f }, - { "glVertex4fv", 10, _gloffset_Vertex4fv }, - { "glVertex4i", 10, _gloffset_Vertex4i }, - { "glVertex4iv", 10, _gloffset_Vertex4iv }, - { "glVertex4s", 10, _gloffset_Vertex4s }, - { "glVertex4sv", 10, _gloffset_Vertex4sv }, - { "glClipPlane", 10, _gloffset_ClipPlane }, - { "glColorMaterial", 10, _gloffset_ColorMaterial }, - { "glFogf", 10, _gloffset_Fogf }, - { "glFogfv", 10, _gloffset_Fogfv }, - { "glFogi", 10, _gloffset_Fogi }, - { "glFogiv", 10, _gloffset_Fogiv }, - { "glLightf", 10, _gloffset_Lightf }, - { "glLightfv", 10, _gloffset_Lightfv }, - { "glLighti", 10, _gloffset_Lighti }, - { "glLightiv", 10, _gloffset_Lightiv }, - { "glLightModelf", 10, _gloffset_LightModelf }, - { "glLightModelfv", 10, _gloffset_LightModelfv }, - { "glLightModeli", 10, _gloffset_LightModeli }, - { "glLightModeliv", 10, _gloffset_LightModeliv }, - { "glLineStipple", 10, _gloffset_LineStipple }, - { "glMaterialf", 10, _gloffset_Materialf }, - { "glMaterialfv", 10, _gloffset_Materialfv }, - { "glMateriali", 10, _gloffset_Materiali }, - { "glMaterialiv", 10, _gloffset_Materialiv }, - { "glPolygonStipple", 10, _gloffset_PolygonStipple }, - { "glShadeModel", 10, _gloffset_ShadeModel }, - { "glTexEnvf", 10, _gloffset_TexEnvf }, - { "glTexEnvfv", 10, _gloffset_TexEnvfv }, - { "glTexEnvi", 10, _gloffset_TexEnvi }, - { "glTexEnviv", 10, _gloffset_TexEnviv }, - { "glTexGend", 10, _gloffset_TexGend }, - { "glTexGendv", 10, _gloffset_TexGendv }, - { "glTexGenf", 10, _gloffset_TexGenf }, - { "glTexGenfv", 10, _gloffset_TexGenfv }, - { "glTexGeni", 10, _gloffset_TexGeni }, - { "glTexGeniv", 10, _gloffset_TexGeniv }, - { "glFeedbackBuffer", 10, _gloffset_FeedbackBuffer }, - { "glSelectBuffer", 10, _gloffset_SelectBuffer }, - { "glRenderMode", 10, _gloffset_RenderMode }, - { "glInitNames", 10, _gloffset_InitNames }, - { "glLoadName", 10, _gloffset_LoadName }, - { "glPassThrough", 10, _gloffset_PassThrough }, - { "glPopName", 10, _gloffset_PopName }, - { "glPushName", 10, _gloffset_PushName }, - { "glClearAccum", 10, _gloffset_ClearAccum }, - { "glClearIndex", 10, _gloffset_ClearIndex }, - { "glIndexMask", 10, _gloffset_IndexMask }, - { "glAccum", 10, _gloffset_Accum }, - { "glPopAttrib", 10, _gloffset_PopAttrib }, - { "glPushAttrib", 10, _gloffset_PushAttrib }, - { "glMap1d", 10, _gloffset_Map1d }, - { "glMap1f", 10, _gloffset_Map1f }, - { "glMap2d", 10, _gloffset_Map2d }, - { "glMap2f", 10, _gloffset_Map2f }, - { "glMapGrid1d", 10, _gloffset_MapGrid1d }, - { "glMapGrid1f", 10, _gloffset_MapGrid1f }, - { "glMapGrid2d", 10, _gloffset_MapGrid2d }, - { "glMapGrid2f", 10, _gloffset_MapGrid2f }, - { "glEvalCoord1d", 10, _gloffset_EvalCoord1d }, - { "glEvalCoord1dv", 10, _gloffset_EvalCoord1dv }, - { "glEvalCoord1f", 10, _gloffset_EvalCoord1f }, - { "glEvalCoord1fv", 10, _gloffset_EvalCoord1fv }, - { "glEvalCoord2d", 10, _gloffset_EvalCoord2d }, - { "glEvalCoord2dv", 10, _gloffset_EvalCoord2dv }, - { "glEvalCoord2f", 10, _gloffset_EvalCoord2f }, - { "glEvalCoord2fv", 10, _gloffset_EvalCoord2fv }, - { "glEvalMesh1", 10, _gloffset_EvalMesh1 }, - { "glEvalPoint1", 10, _gloffset_EvalPoint1 }, - { "glEvalMesh2", 10, _gloffset_EvalMesh2 }, - { "glEvalPoint2", 10, _gloffset_EvalPoint2 }, - { "glAlphaFunc", 10, _gloffset_AlphaFunc }, - { "glPixelZoom", 10, _gloffset_PixelZoom }, - { "glPixelTransferf", 10, _gloffset_PixelTransferf }, - { "glPixelTransferi", 10, _gloffset_PixelTransferi }, - { "glPixelMapfv", 10, _gloffset_PixelMapfv }, - { "glPixelMapuiv", 10, _gloffset_PixelMapuiv }, - { "glPixelMapusv", 10, _gloffset_PixelMapusv }, - { "glCopyPixels", 10, _gloffset_CopyPixels }, - { "glDrawPixels", 10, _gloffset_DrawPixels }, - { "glGetClipPlane", 10, _gloffset_GetClipPlane }, - { "glGetLightfv", 10, _gloffset_GetLightfv }, - { "glGetLightiv", 10, _gloffset_GetLightiv }, - { "glGetMapdv", 10, _gloffset_GetMapdv }, - { "glGetMapfv", 10, _gloffset_GetMapfv }, - { "glGetMapiv", 10, _gloffset_GetMapiv }, - { "glGetMaterialfv", 10, _gloffset_GetMaterialfv }, - { "glGetMaterialiv", 10, _gloffset_GetMaterialiv }, - { "glGetPixelMapfv", 10, _gloffset_GetPixelMapfv }, - { "glGetPixelMapuiv", 10, _gloffset_GetPixelMapuiv }, - { "glGetPixelMapusv", 10, _gloffset_GetPixelMapusv }, - { "glGetPolygonStipple", 10, _gloffset_GetPolygonStipple }, - { "glGetTexEnvfv", 10, _gloffset_GetTexEnvfv }, - { "glGetTexEnviv", 10, _gloffset_GetTexEnviv }, - { "glGetTexGendv", 10, _gloffset_GetTexGendv }, - { "glGetTexGenfv", 10, _gloffset_GetTexGenfv }, - { "glGetTexGeniv", 10, _gloffset_GetTexGeniv }, - { "glIsList", 10, _gloffset_IsList }, - { "glFrustum", 10, _gloffset_Frustum }, - { "glLoadIdentity", 10, _gloffset_LoadIdentity }, - { "glLoadMatrixf", 10, _gloffset_LoadMatrixf }, - { "glLoadMatrixd", 10, _gloffset_LoadMatrixd }, - { "glMatrixMode", 10, _gloffset_MatrixMode }, - { "glMultMatrixf", 10, _gloffset_MultMatrixf }, - { "glMultMatrixd", 10, _gloffset_MultMatrixd }, - { "glOrtho", 10, _gloffset_Ortho }, - { "glPopMatrix", 10, _gloffset_PopMatrix }, - { "glPushMatrix", 10, _gloffset_PushMatrix }, - { "glRotated", 10, _gloffset_Rotated }, - { "glRotatef", 10, _gloffset_Rotatef }, - { "glScaled", 10, _gloffset_Scaled }, - { "glScalef", 10, _gloffset_Scalef }, - { "glTranslated", 10, _gloffset_Translated }, - { "glTranslatef", 10, _gloffset_Translatef }, - { "glArrayElement", 10, _gloffset_ArrayElement }, - { "glColorPointer", 10, _gloffset_ColorPointer }, - { "glDisableClientState", 10, _gloffset_DisableClientState }, - { "glEdgeFlagPointer", 10, _gloffset_EdgeFlagPointer }, - { "glEnableClientState", 10, _gloffset_EnableClientState }, - { "glIndexPointer", 10, _gloffset_IndexPointer }, - { "glInterleavedArrays", 10, _gloffset_InterleavedArrays }, - { "glNormalPointer", 10, _gloffset_NormalPointer }, - { "glTexCoordPointer", 10, _gloffset_TexCoordPointer }, - { "glVertexPointer", 10, _gloffset_VertexPointer }, - { "glAreTexturesResident", 10, _gloffset_AreTexturesResident }, - { "glPrioritizeTextures", 10, _gloffset_PrioritizeTextures }, - { "glIndexub", 10, _gloffset_Indexub }, - { "glIndexubv", 10, _gloffset_Indexubv }, - { "glPopClientAttrib", 10, _gloffset_PopClientAttrib }, - { "glPushClientAttrib", 10, _gloffset_PushClientAttrib }, - { "glColorTable", 10, _gloffset_ColorTable }, - { "glColorTableParameterfv", 10, _gloffset_ColorTableParameterfv }, - { "glColorTableParameteriv", 10, _gloffset_ColorTableParameteriv }, - { "glCopyColorTable", 10, _gloffset_CopyColorTable }, - { "glGetColorTable", 10, _gloffset_GetColorTable }, - { "glGetColorTableParameterfv", 10, _gloffset_GetColorTableParameterfv }, - { "glGetColorTableParameteriv", 10, _gloffset_GetColorTableParameteriv }, - { "glColorSubTable", 10, _gloffset_ColorSubTable }, - { "glCopyColorSubTable", 10, _gloffset_CopyColorSubTable }, - { "glConvolutionFilter1D", 10, _gloffset_ConvolutionFilter1D }, - { "glConvolutionFilter2D", 10, _gloffset_ConvolutionFilter2D }, - { "glConvolutionParameterf", 10, _gloffset_ConvolutionParameterf }, - { "glConvolutionParameterfv", 10, _gloffset_ConvolutionParameterfv }, - { "glConvolutionParameteri", 10, _gloffset_ConvolutionParameteri }, - { "glConvolutionParameteriv", 10, _gloffset_ConvolutionParameteriv }, - { "glCopyConvolutionFilter1D", 10, _gloffset_CopyConvolutionFilter1D }, - { "glCopyConvolutionFilter2D", 10, _gloffset_CopyConvolutionFilter2D }, - { "glGetConvolutionFilter", 10, _gloffset_GetConvolutionFilter }, - { "glGetConvolutionParameterfv", 10, _gloffset_GetConvolutionParameterfv }, - { "glGetConvolutionParameteriv", 10, _gloffset_GetConvolutionParameteriv }, - { "glGetSeparableFilter", 10, _gloffset_GetSeparableFilter }, - { "glSeparableFilter2D", 10, _gloffset_SeparableFilter2D }, - { "glGetHistogram", 10, _gloffset_GetHistogram }, - { "glGetHistogramParameterfv", 10, _gloffset_GetHistogramParameterfv }, - { "glGetHistogramParameteriv", 10, _gloffset_GetHistogramParameteriv }, - { "glGetMinmax", 10, _gloffset_GetMinmax }, - { "glGetMinmaxParameterfv", 10, _gloffset_GetMinmaxParameterfv }, - { "glGetMinmaxParameteriv", 10, _gloffset_GetMinmaxParameteriv }, - { "glHistogram", 10, _gloffset_Histogram }, - { "glMinmax", 10, _gloffset_Minmax }, - { "glResetHistogram", 10, _gloffset_ResetHistogram }, - { "glResetMinmax", 10, _gloffset_ResetMinmax }, - { "glClientActiveTexture", 10, _gloffset_ClientActiveTexture }, - { "glMultiTexCoord1d", 10, _gloffset_MultiTexCoord1d }, - { "glMultiTexCoord1dv", 10, _gloffset_MultiTexCoord1dv }, - { "glMultiTexCoord1f", 10, _gloffset_MultiTexCoord1fARB }, - { "glMultiTexCoord1fv", 10, _gloffset_MultiTexCoord1fvARB }, - { "glMultiTexCoord1i", 10, _gloffset_MultiTexCoord1i }, - { "glMultiTexCoord1iv", 10, _gloffset_MultiTexCoord1iv }, - { "glMultiTexCoord1s", 10, _gloffset_MultiTexCoord1s }, - { "glMultiTexCoord1sv", 10, _gloffset_MultiTexCoord1sv }, - { "glMultiTexCoord2d", 10, _gloffset_MultiTexCoord2d }, - { "glMultiTexCoord2dv", 10, _gloffset_MultiTexCoord2dv }, - { "glMultiTexCoord2f", 10, _gloffset_MultiTexCoord2fARB }, - { "glMultiTexCoord2fv", 10, _gloffset_MultiTexCoord2fvARB }, - { "glMultiTexCoord2i", 10, _gloffset_MultiTexCoord2i }, - { "glMultiTexCoord2iv", 10, _gloffset_MultiTexCoord2iv }, - { "glMultiTexCoord2s", 10, _gloffset_MultiTexCoord2s }, - { "glMultiTexCoord2sv", 10, _gloffset_MultiTexCoord2sv }, - { "glMultiTexCoord3d", 10, _gloffset_MultiTexCoord3d }, - { "glMultiTexCoord3dv", 10, _gloffset_MultiTexCoord3dv }, - { "glMultiTexCoord3f", 10, _gloffset_MultiTexCoord3fARB }, - { "glMultiTexCoord3fv", 10, _gloffset_MultiTexCoord3fvARB }, - { "glMultiTexCoord3i", 10, _gloffset_MultiTexCoord3i }, - { "glMultiTexCoord3iv", 10, _gloffset_MultiTexCoord3iv }, - { "glMultiTexCoord3s", 10, _gloffset_MultiTexCoord3s }, - { "glMultiTexCoord3sv", 10, _gloffset_MultiTexCoord3sv }, - { "glMultiTexCoord4d", 10, _gloffset_MultiTexCoord4d }, - { "glMultiTexCoord4dv", 10, _gloffset_MultiTexCoord4dv }, - { "glMultiTexCoord4f", 10, _gloffset_MultiTexCoord4fARB }, - { "glMultiTexCoord4fv", 10, _gloffset_MultiTexCoord4fvARB }, - { "glMultiTexCoord4i", 10, _gloffset_MultiTexCoord4i }, - { "glMultiTexCoord4iv", 10, _gloffset_MultiTexCoord4iv }, - { "glMultiTexCoord4s", 10, _gloffset_MultiTexCoord4s }, - { "glMultiTexCoord4sv", 10, _gloffset_MultiTexCoord4sv }, - { "glLoadTransposeMatrixf", 10, -1 }, - { "glLoadTransposeMatrixd", 10, -1 }, - { "glMultTransposeMatrixf", 10, -1 }, - { "glMultTransposeMatrixd", 10, -1 }, - { "glFogCoordf", 10, -1 }, - { "glFogCoordfv", 10, -1 }, - { "glFogCoordd", 10, -1 }, - { "glFogCoorddv", 10, -1 }, - { "glFogCoordPointer", 10, -1 }, - { "glSecondaryColor3b", 10, -1 }, - { "glSecondaryColor3bv", 10, -1 }, - { "glSecondaryColor3d", 10, -1 }, - { "glSecondaryColor3dv", 10, -1 }, - { "glSecondaryColor3f", 10, -1 }, - { "glSecondaryColor3fv", 10, -1 }, - { "glSecondaryColor3i", 10, -1 }, - { "glSecondaryColor3iv", 10, -1 }, - { "glSecondaryColor3s", 10, -1 }, - { "glSecondaryColor3sv", 10, -1 }, - { "glSecondaryColor3ub", 10, -1 }, - { "glSecondaryColor3ubv", 10, -1 }, - { "glSecondaryColor3ui", 10, -1 }, - { "glSecondaryColor3uiv", 10, -1 }, - { "glSecondaryColor3us", 10, -1 }, - { "glSecondaryColor3usv", 10, -1 }, - { "glSecondaryColorPointer", 10, -1 }, - { "glWindowPos2d", 10, -1 }, - { "glWindowPos2dv", 10, -1 }, - { "glWindowPos2f", 10, -1 }, - { "glWindowPos2fv", 10, -1 }, - { "glWindowPos2i", 10, -1 }, - { "glWindowPos2iv", 10, -1 }, - { "glWindowPos2s", 10, -1 }, - { "glWindowPos2sv", 10, -1 }, - { "glWindowPos3d", 10, -1 }, - { "glWindowPos3dv", 10, -1 }, - { "glWindowPos3f", 10, -1 }, - { "glWindowPos3fv", 10, -1 }, - { "glWindowPos3i", 10, -1 }, - { "glWindowPos3iv", 10, -1 }, - { "glWindowPos3s", 10, -1 }, - { "glWindowPos3sv", 10, -1 }, - { "glProgramStringARB", 10, -1 }, - { "glProgramEnvParameter4dARB", 10, -1 }, - { "glProgramEnvParameter4dvARB", 10, -1 }, - { "glProgramEnvParameter4fARB", 10, -1 }, - { "glProgramEnvParameter4fvARB", 10, -1 }, - { "glProgramLocalParameter4dARB", 10, -1 }, - { "glProgramLocalParameter4dvARB", 10, -1 }, - { "glProgramLocalParameter4fARB", 10, -1 }, - { "glProgramLocalParameter4fvARB", 10, -1 }, - { "glGetProgramEnvParameterdvARB", 10, -1 }, - { "glGetProgramEnvParameterfvARB", 10, -1 }, - { "glGetProgramLocalParameterdvARB", 10, -1 }, - { "glGetProgramLocalParameterfvARB", 10, -1 }, - { "glGetProgramivARB", 10, -1 }, - { "glGetProgramStringARB", 10, -1 }, - { "glColorPointerEXT", 10, -1 }, - { "glEdgeFlagPointerEXT", 10, -1 }, - { "glIndexPointerEXT", 10, -1 }, - { "glNormalPointerEXT", 10, -1 }, - { "glTexCoordPointerEXT", 10, -1 }, - { "glVertexPointerEXT", 10, -1 }, - { "glLockArraysEXT", 10, -1 }, - { "glUnlockArraysEXT", 10, -1 }, - { "glWindowPos4dMESA", 10, -1 }, - { "glWindowPos4dvMESA", 10, -1 }, - { "glWindowPos4fMESA", 10, -1 }, - { "glWindowPos4fvMESA", 10, -1 }, - { "glWindowPos4iMESA", 10, -1 }, - { "glWindowPos4ivMESA", 10, -1 }, - { "glWindowPos4sMESA", 10, -1 }, - { "glWindowPos4svMESA", 10, -1 }, - { "glBindProgramNV", 10, -1 }, - { "glDeleteProgramsNV", 10, -1 }, - { "glGenProgramsNV", 10, -1 }, - { "glIsProgramNV", 10, -1 }, - { "glVertexAttrib1sNV", 10, -1 }, - { "glVertexAttrib1svNV", 10, -1 }, - { "glVertexAttrib2sNV", 10, -1 }, - { "glVertexAttrib2svNV", 10, -1 }, - { "glVertexAttrib3sNV", 10, -1 }, - { "glVertexAttrib3svNV", 10, -1 }, - { "glVertexAttrib4sNV", 10, -1 }, - { "glVertexAttrib4svNV", 10, -1 }, - { "glVertexAttrib1fNV", 10, -1 }, - { "glVertexAttrib1fvNV", 10, -1 }, - { "glVertexAttrib2fNV", 10, -1 }, - { "glVertexAttrib2fvNV", 10, -1 }, - { "glVertexAttrib3fNV", 10, -1 }, - { "glVertexAttrib3fvNV", 10, -1 }, - { "glVertexAttrib4fNV", 10, -1 }, - { "glVertexAttrib4fvNV", 10, -1 }, - { "glVertexAttrib1dNV", 10, -1 }, - { "glVertexAttrib1dvNV", 10, -1 }, - { "glVertexAttrib2dNV", 10, -1 }, - { "glVertexAttrib2dvNV", 10, -1 }, - { "glVertexAttrib3dNV", 10, -1 }, - { "glVertexAttrib3dvNV", 10, -1 }, - { "glVertexAttrib4dNV", 10, -1 }, - { "glVertexAttrib4dvNV", 10, -1 }, - { "glVertexAttrib4ubNV", 10, -1 }, - { "glVertexAttrib4ubvNV", 10, -1 }, - { "glVertexAttribs1svNV", 10, -1 }, - { "glVertexAttribs2svNV", 10, -1 }, - { "glVertexAttribs3svNV", 10, -1 }, - { "glVertexAttribs4svNV", 10, -1 }, - { "glVertexAttribs1fvNV", 10, -1 }, - { "glVertexAttribs2fvNV", 10, -1 }, - { "glVertexAttribs3fvNV", 10, -1 }, - { "glVertexAttribs4fvNV", 10, -1 }, - { "glVertexAttribs1dvNV", 10, -1 }, - { "glVertexAttribs2dvNV", 10, -1 }, - { "glVertexAttribs3dvNV", 10, -1 }, - { "glVertexAttribs4dvNV", 10, -1 }, - { "glVertexAttribs4ubvNV", 10, -1 }, - { "glGenFragmentShadersATI", 10, -1 }, - { "glBindFragmentShaderATI", 10, -1 }, - { "glDeleteFragmentShaderATI", 10, -1 }, - { "glBeginFragmentShaderATI", 10, -1 }, - { "glEndFragmentShaderATI", 10, -1 }, - { "glPassTexCoordATI", 10, -1 }, - { "glSampleMapATI", 10, -1 }, - { "glColorFragmentOp1ATI", 10, -1 }, - { "glColorFragmentOp2ATI", 10, -1 }, - { "glColorFragmentOp3ATI", 10, -1 }, - { "glAlphaFragmentOp1ATI", 10, -1 }, - { "glAlphaFragmentOp2ATI", 10, -1 }, - { "glAlphaFragmentOp3ATI", 10, -1 }, - { "glSetFragmentShaderConstantATI", 10, -1 }, - { "glActiveStencilFaceEXT", 10, -1 }, - { "glStencilFuncSeparateATI", 10, -1 }, - { "glProgramEnvParameters4fvEXT", 10, -1 }, - { "glProgramLocalParameters4fvEXT", 10, -1 }, - { "glPrimitiveRestartNV", 10, -1 }, - - /* GL_NV_half_float */ - { "glVertex2hNV", 13, -1 }, - { "glVertex2hvNV", 13, -1 }, - { "glVertex3hNV", 13, -1 }, - { "glVertex3hvNV", 13, -1 }, - { "glVertex4hNV", 13, -1 }, - { "glVertex4hvNV", 13, -1 }, - { "glNormal3hNV", 13, -1 }, - { "glNormal3hvNV", 13, -1 }, - { "glColor3hNV", 13, -1 }, - { "glColor3hvNV", 13, -1 }, - { "glColor4hNV", 13, -1 }, - { "glColor4hvNV", 13, -1 }, - { "glTexCoord1hNV", 13, -1 }, - { "glTexCoord1hvNV", 13, -1 }, - { "glTexCoord2hNV", 13, -1 }, - { "glTexCoord2hvNV", 13, -1 }, - { "glTexCoord3hNV", 13, -1 }, - { "glTexCoord3hvNV", 13, -1 }, - { "glTexCoord4hNV", 13, -1 }, - { "glTexCoord4hvNV", 13, -1 }, - { "glMultiTexCoord1hNV", 13, -1 }, - { "glMultiTexCoord1hvNV", 13, -1 }, - { "glMultiTexCoord2hNV", 13, -1 }, - { "glMultiTexCoord2hvNV", 13, -1 }, - { "glMultiTexCoord3hNV", 13, -1 }, - { "glMultiTexCoord3hvNV", 13, -1 }, - { "glMultiTexCoord4hNV", 13, -1 }, - { "glMultiTexCoord4hvNV", 13, -1 }, - { "glFogCoordhNV", 13, -1 }, - { "glFogCoordhvNV", 13, -1 }, - { "glSecondaryColor3hNV", 13, -1 }, - { "glSecondaryColor3hvNV", 13, -1 }, - { "glVertexAttrib1hNV", 13, -1 }, - { "glVertexAttrib1hvNV", 13, -1 }, - { "glVertexAttrib2hNV", 13, -1 }, - { "glVertexAttrib2hvNV", 13, -1 }, - { "glVertexAttrib3hNV", 13, -1 }, - { "glVertexAttrib3hvNV", 13, -1 }, - { "glVertexAttrib4hNV", 13, -1 }, - { "glVertexAttrib4hvNV", 13, -1 }, - { "glVertexAttribs1hvNV", 13, -1 }, - { "glVertexAttribs2hvNV", 13, -1 }, - { "glVertexAttribs3hvNV", 13, -1 }, - { "glVertexAttribs4hvNV", 13, -1 }, - - { NULL, 0, -1 } -}; - -const struct function gl_core_functions_possible[] = { - /* GL_ARB_ES3_2_compatibility */ - { "glPrimitiveBoundingBoxARB", 45, -1 }, - - /* GL_ARB_gl_spirv */ - { "glSpecializeShaderARB", 45, -1 }, - - { NULL, 0, -1 } -}; - -const struct function gles11_functions_possible[] = { - { "glActiveTexture", 11, _gloffset_ActiveTexture }, - { "glAlphaFunc", 11, _gloffset_AlphaFunc }, - { "glAlphaFuncx", 11, -1 }, - { "glBindBuffer", 11, -1 }, - { "glBindFramebufferOES", 11, -1 }, - { "glBindRenderbufferOES", 11, -1 }, - { "glBindTexture", 11, _gloffset_BindTexture }, - { "glBlendEquationOES", 11, _gloffset_BlendEquation }, - { "glBlendEquationSeparateOES", 11, -1 }, - { "glBlendFunc", 11, _gloffset_BlendFunc }, - { "glBlendFuncSeparateOES", 11, -1 }, - { "glBufferData", 11, -1 }, - { "glBufferSubData", 11, -1 }, - { "glCheckFramebufferStatusOES", 11, -1 }, - { "glClear", 11, _gloffset_Clear }, - { "glClearColor", 11, _gloffset_ClearColor }, - { "glClearColorx", 11, -1 }, - { "glClearDepthf", 11, -1 }, - { "glClearDepthx", 11, -1 }, - { "glClearStencil", 11, _gloffset_ClearStencil }, - { "glClientActiveTexture", 11, _gloffset_ClientActiveTexture }, - { "glClipPlanef", 11, -1 }, - { "glClipPlanex", 11, -1 }, - { "glColor4f", 11, _gloffset_Color4f }, - { "glColor4ub", 11, _gloffset_Color4ub }, - { "glColor4x", 11, -1 }, - { "glColorMask", 11, _gloffset_ColorMask }, - { "glColorPointer", 11, _gloffset_ColorPointer }, - { "glCompressedTexImage2D", 11, -1 }, - { "glCompressedTexSubImage2D", 11, -1 }, - { "glCopyTexImage2D", 11, _gloffset_CopyTexImage2D }, - { "glCopyTexSubImage2D", 11, _gloffset_CopyTexSubImage2D }, - { "glCullFace", 11, _gloffset_CullFace }, - { "glDeleteBuffers", 11, -1 }, - { "glDeleteFramebuffersOES", 11, -1 }, - { "glDeleteRenderbuffersOES", 11, -1 }, - { "glDeleteTextures", 11, _gloffset_DeleteTextures }, - { "glDepthFunc", 11, _gloffset_DepthFunc }, - { "glDepthMask", 11, _gloffset_DepthMask }, - { "glDepthRangef", 11, -1 }, - { "glDepthRangex", 11, -1 }, - { "glDisable", 11, _gloffset_Disable }, - { "glDiscardFramebufferEXT", 11, -1 }, - { "glDisableClientState", 11, _gloffset_DisableClientState }, - { "glDrawArrays", 11, _gloffset_DrawArrays }, - { "glDrawElements", 11, _gloffset_DrawElements }, - { "glDrawTexfOES", 11, -1 }, - { "glDrawTexfvOES", 11, -1 }, - { "glDrawTexiOES", 11, -1 }, - { "glDrawTexivOES", 11, -1 }, - { "glDrawTexsOES", 11, -1 }, - { "glDrawTexsvOES", 11, -1 }, - { "glDrawTexxOES", 11, -1 }, - { "glDrawTexxvOES", 11, -1 }, - { "glEGLImageTargetRenderbufferStorageOES", 11, -1 }, - { "glEGLImageTargetTexture2DOES", 11, -1 }, - { "glEnable", 11, _gloffset_Enable }, - { "glEnableClientState", 11, _gloffset_EnableClientState }, - { "glFinish", 11, _gloffset_Finish }, - { "glFlush", 11, _gloffset_Flush }, - { "glFlushMappedBufferRangeEXT", 11, -1 }, - { "glFogf", 11, _gloffset_Fogf }, - { "glFogfv", 11, _gloffset_Fogfv }, - { "glFogx", 11, -1 }, - { "glFogxv", 11, -1 }, - { "glFramebufferRenderbufferOES", 11, -1 }, - { "glFramebufferTexture2DOES", 11, -1 }, - { "glFrontFace", 11, _gloffset_FrontFace }, - { "glFrustumf", 11, -1 }, - { "glFrustumx", 11, -1 }, - { "glGenBuffers", 11, -1 }, - { "glGenFramebuffersOES", 11, -1 }, - { "glGenRenderbuffersOES", 11, -1 }, - { "glGenTextures", 11, _gloffset_GenTextures }, - { "glGenerateMipmapOES", 11, -1 }, - { "glGetBooleanv", 11, _gloffset_GetBooleanv }, - { "glGetBufferParameteriv", 11, -1 }, - { "glGetBufferPointervOES", 11, -1 }, - { "glGetClipPlanef", 11, -1 }, - { "glGetClipPlanex", 11, -1 }, - { "glGetError", 11, _gloffset_GetError }, - { "glGetFixedv", 11, -1 }, - { "glGetFloatv", 11, _gloffset_GetFloatv }, - { "glGetFramebufferAttachmentParameterivOES", 11, -1 }, - { "glGetIntegerv", 11, _gloffset_GetIntegerv }, - { "glGetLightfv", 11, _gloffset_GetLightfv }, - { "glGetLightxv", 11, -1 }, - { "glGetMaterialfv", 11, _gloffset_GetMaterialfv }, - { "glGetMaterialxv", 11, -1 }, - // We check for the aliased -KHR version in GLES 1.1 -// { "glGetPointerv", 11, _gloffset_GetPointerv }, - { "glGetRenderbufferParameterivOES", 11, -1 }, - { "glGetString", 11, _gloffset_GetString }, - { "glGetTexEnvfv", 11, _gloffset_GetTexEnvfv }, - { "glGetTexEnviv", 11, _gloffset_GetTexEnviv }, - { "glGetTexEnvxv", 11, -1 }, - { "glGetTexGenfvOES", 11, _gloffset_GetTexGenfv }, - { "glGetTexGenivOES", 11, _gloffset_GetTexGeniv }, - { "glGetTexGenxvOES", 11, -1 }, - { "glGetTexParameterfv", 11, _gloffset_GetTexParameterfv }, - { "glGetTexParameteriv", 11, _gloffset_GetTexParameteriv }, - { "glGetTexParameterxv", 11, -1 }, - { "glHint", 11, _gloffset_Hint }, - { "glIsBuffer", 11, -1 }, - { "glIsEnabled", 11, _gloffset_IsEnabled }, - { "glIsFramebufferOES", 11, -1 }, - { "glIsRenderbufferOES", 11, -1 }, - { "glIsTexture", 11, _gloffset_IsTexture }, - { "glLightModelf", 11, _gloffset_LightModelf }, - { "glLightModelfv", 11, _gloffset_LightModelfv }, - { "glLightModelx", 11, -1 }, - { "glLightModelxv", 11, -1 }, - { "glLightf", 11, _gloffset_Lightf }, - { "glLightfv", 11, _gloffset_Lightfv }, - { "glLightx", 11, -1 }, - { "glLightxv", 11, -1 }, - { "glLineWidth", 11, _gloffset_LineWidth }, - { "glLineWidthx", 11, -1 }, - { "glLoadIdentity", 11, _gloffset_LoadIdentity }, - { "glLoadMatrixf", 11, _gloffset_LoadMatrixf }, - { "glLoadMatrixx", 11, -1 }, - { "glLogicOp", 11, _gloffset_LogicOp }, - { "glMapBufferOES", 11, -1 }, - { "glMapBufferRangeEXT", 11, -1 }, - { "glMaterialf", 11, _gloffset_Materialf }, - { "glMaterialfv", 11, _gloffset_Materialfv }, - { "glMaterialx", 11, -1 }, - { "glMaterialxv", 11, -1 }, - { "glMatrixMode", 11, _gloffset_MatrixMode }, - { "glMultMatrixf", 11, _gloffset_MultMatrixf }, - { "glMultMatrixx", 11, -1 }, - { "glMultiDrawArraysEXT", 11, -1 }, - { "glMultiDrawElementsEXT", 11, -1 }, - { "glMultiTexCoord4f", 11, _gloffset_MultiTexCoord4fARB }, - { "glMultiTexCoord4x", 11, -1 }, - { "glNormal3f", 11, _gloffset_Normal3f }, - { "glNormal3x", 11, -1 }, - { "glNormalPointer", 11, _gloffset_NormalPointer }, - { "glOrthof", 11, -1 }, - { "glOrthox", 11, -1 }, - { "glPixelStorei", 11, _gloffset_PixelStorei }, - { "glPointParameterf", 11, -1 }, - { "glPointParameterfv", 11, -1 }, - { "glPointParameterx", 11, -1 }, - { "glPointParameterxv", 11, -1 }, - { "glPointSize", 11, _gloffset_PointSize }, - { "glPointSizePointerOES", 11, -1 }, - { "glPointSizex", 11, -1 }, - { "glPolygonOffset", 11, _gloffset_PolygonOffset }, - { "glPolygonOffsetx", 11, -1 }, - { "glPopMatrix", 11, _gloffset_PopMatrix }, - { "glPushMatrix", 11, _gloffset_PushMatrix }, - { "glQueryMatrixxOES", 11, -1 }, - { "glReadPixels", 11, _gloffset_ReadPixels }, - { "glRenderbufferStorageOES", 11, -1 }, - { "glRotatef", 11, _gloffset_Rotatef }, - { "glRotatex", 11, -1 }, - { "glSampleCoverage", 11, -1 }, - { "glSampleCoveragex", 11, -1 }, - { "glScalef", 11, _gloffset_Scalef }, - { "glScalex", 11, -1 }, - { "glScissor", 11, _gloffset_Scissor }, - { "glShadeModel", 11, _gloffset_ShadeModel }, - { "glStencilFunc", 11, _gloffset_StencilFunc }, - { "glStencilMask", 11, _gloffset_StencilMask }, - { "glStencilOp", 11, _gloffset_StencilOp }, - { "glTexCoordPointer", 11, _gloffset_TexCoordPointer }, - { "glTexEnvf", 11, _gloffset_TexEnvf }, - { "glTexEnvfv", 11, _gloffset_TexEnvfv }, - { "glTexEnvi", 11, _gloffset_TexEnvi }, - { "glTexEnviv", 11, _gloffset_TexEnviv }, - { "glTexEnvx", 11, -1 }, - { "glTexEnvxv", 11, -1 }, - { "glTexGenfOES", 11, _gloffset_TexGenf }, - { "glTexGenfvOES", 11, _gloffset_TexGenfv }, - { "glTexGeniOES", 11, _gloffset_TexGeni }, - { "glTexGenivOES", 11, _gloffset_TexGeniv }, - { "glTexGenxOES", 11, -1 }, - { "glTexGenxvOES", 11, -1 }, - { "glTexImage2D", 11, _gloffset_TexImage2D }, - { "glTexParameterf", 11, _gloffset_TexParameterf }, - { "glTexParameterfv", 11, _gloffset_TexParameterfv }, - { "glTexParameteri", 11, _gloffset_TexParameteri }, - { "glTexParameteriv", 11, _gloffset_TexParameteriv }, - { "glTexParameterx", 11, -1 }, - { "glTexParameterxv", 11, -1 }, - { "glTexSubImage2D", 11, _gloffset_TexSubImage2D }, - { "glTranslatef", 11, _gloffset_Translatef }, - { "glTranslatex", 11, -1 }, - { "glUnmapBufferOES", 11, -1 }, - { "glVertexPointer", 11, _gloffset_VertexPointer }, - { "glViewport", 11, _gloffset_Viewport }, - - /* GL_KHR_debug */ - { "glPushDebugGroupKHR", 11, -1 }, - { "glPopDebugGroupKHR", 11, -1 }, - { "glDebugMessageCallbackKHR", 11, -1 }, - { "glDebugMessageControlKHR", 11, -1 }, - { "glDebugMessageInsertKHR", 11, -1 }, - { "glGetDebugMessageLogKHR", 11, -1 }, - { "glGetObjectLabelKHR", 11, -1 }, - { "glGetObjectPtrLabelKHR", 11, -1 }, - { "glGetPointervKHR", 11, _gloffset_GetPointerv }, - { "glObjectLabelKHR", 11, -1 }, - { "glObjectPtrLabelKHR", 11, -1 }, - - /* GL_EXT_polygon_offset_clamp */ - { "glPolygonOffsetClampEXT", 11, -1 }, - - /* GL_NV_conservative_raster */ - { "glSubpixelPrecisionBiasNV", 20, -1 }, - - /* GL_NV_conservative_raster_dilate */ - { "glConservativeRasterParameterfNV", 20, -1 }, - - /* GL_NV_conservative_raster_pre_snap_triangles */ - { "glConservativeRasterParameteriNV", 20, -1 }, - - { NULL, 0, -1 } -}; - -const struct function gles2_functions_possible[] = { - { "glActiveTexture", 20, _gloffset_ActiveTexture }, - { "glAttachShader", 20, -1 }, - { "glBindAttribLocation", 20, -1 }, - { "glBindBuffer", 20, -1 }, - { "glBindFramebuffer", 20, -1 }, - { "glBindRenderbuffer", 20, -1 }, - { "glBindTexture", 20, _gloffset_BindTexture }, - { "glBindVertexArrayOES", 20, -1 }, - { "glBlendColor", 20, _gloffset_BlendColor }, - { "glBlendEquation", 20, _gloffset_BlendEquation }, - { "glBlendEquationSeparate", 20, -1 }, - { "glBlendFunc", 20, _gloffset_BlendFunc }, - { "glBlendFuncSeparate", 20, -1 }, - { "glBufferData", 20, -1 }, - { "glBufferSubData", 20, -1 }, - { "glCheckFramebufferStatus", 20, -1 }, - { "glClear", 20, _gloffset_Clear }, - { "glClearColor", 20, _gloffset_ClearColor }, - { "glClearDepthf", 20, -1 }, - { "glClearStencil", 20, _gloffset_ClearStencil }, - { "glColorMask", 20, _gloffset_ColorMask }, - { "glCompileShader", 20, -1 }, - { "glCompressedTexImage2D", 20, -1 }, - { "glCompressedTexImage3DOES", 20, -1 }, - { "glCompressedTexSubImage2D", 20, -1 }, - { "glCompressedTexSubImage3DOES", 20, -1 }, - { "glCopyTexImage2D", 20, _gloffset_CopyTexImage2D }, - { "glCopyTexSubImage2D", 20, _gloffset_CopyTexSubImage2D }, - { "glCopyTexSubImage3DOES", 20, _gloffset_CopyTexSubImage3D }, - { "glCreateProgram", 20, -1 }, - { "glCreateShader", 20, -1 }, - { "glCullFace", 20, _gloffset_CullFace }, - { "glDeleteBuffers", 20, -1 }, - { "glDeleteFramebuffers", 20, -1 }, - { "glDeleteProgram", 20, -1 }, - { "glDeleteRenderbuffers", 20, -1 }, - { "glDeleteShader", 20, -1 }, - { "glDeleteTextures", 20, _gloffset_DeleteTextures }, - { "glDeleteVertexArraysOES", 20, -1 }, - { "glDepthFunc", 20, _gloffset_DepthFunc }, - { "glDepthMask", 20, _gloffset_DepthMask }, - { "glDepthRangef", 20, -1 }, - { "glDetachShader", 20, -1 }, - { "glDisable", 20, _gloffset_Disable }, - { "glDiscardFramebufferEXT", 20, -1 }, - { "glDisableVertexAttribArray", 20, -1 }, - { "glDrawArrays", 20, _gloffset_DrawArrays }, - { "glDrawBuffersNV", 20, -1 }, - { "glDrawElements", 20, _gloffset_DrawElements }, - { "glDrawElementsBaseVertex", 20, -1 }, - { "glEGLImageTargetRenderbufferStorageOES", 20, -1 }, - { "glEGLImageTargetTexture2DOES", 20, -1 }, - { "glEnable", 20, _gloffset_Enable }, - { "glEnableVertexAttribArray", 20, -1 }, - { "glFinish", 20, _gloffset_Finish }, - { "glFlush", 20, _gloffset_Flush }, - { "glFlushMappedBufferRangeEXT", 20, -1 }, - { "glFramebufferRenderbuffer", 20, -1 }, - { "glFramebufferTexture2D", 20, -1 }, - { "glFramebufferTexture3DOES", 20, -1 }, - { "glFrontFace", 20, _gloffset_FrontFace }, - { "glGenBuffers", 20, -1 }, - { "glGenFramebuffers", 20, -1 }, - { "glGenRenderbuffers", 20, -1 }, - { "glGenTextures", 20, _gloffset_GenTextures }, - { "glGenVertexArraysOES", 20, -1 }, - { "glGenerateMipmap", 20, -1 }, - { "glGetActiveAttrib", 20, -1 }, - { "glGetActiveUniform", 20, -1 }, - { "glGetAttachedShaders", 20, -1 }, - { "glGetAttribLocation", 20, -1 }, - { "glGetBooleanv", 20, _gloffset_GetBooleanv }, - { "glGetBufferParameteriv", 20, -1 }, - { "glGetBufferPointervOES", 20, -1 }, - { "glGetError", 20, _gloffset_GetError }, - { "glGetFloatv", 20, _gloffset_GetFloatv }, - { "glGetFramebufferAttachmentParameteriv", 20, -1 }, - { "glGetIntegerv", 20, _gloffset_GetIntegerv }, - { "glGetProgramInfoLog", 20, -1 }, - { "glGetProgramiv", 20, -1 }, - { "glGetRenderbufferParameteriv", 20, -1 }, - { "glGetShaderInfoLog", 20, -1 }, - { "glGetShaderPrecisionFormat", 20, -1 }, - { "glGetShaderSource", 20, -1 }, - { "glGetShaderiv", 20, -1 }, - { "glGetString", 20, _gloffset_GetString }, - { "glGetTexParameterfv", 20, _gloffset_GetTexParameterfv }, - { "glGetTexParameteriv", 20, _gloffset_GetTexParameteriv }, - { "glGetUniformLocation", 20, -1 }, - { "glGetUniformfv", 20, -1 }, - { "glGetUniformiv", 20, -1 }, - { "glGetVertexAttribPointerv", 20, -1 }, - { "glGetVertexAttribfv", 20, -1 }, - { "glGetVertexAttribiv", 20, -1 }, - { "glHint", 20, _gloffset_Hint }, - { "glIsBuffer", 20, -1 }, - { "glIsEnabled", 20, _gloffset_IsEnabled }, - { "glIsFramebuffer", 20, -1 }, - { "glIsProgram", 20, -1 }, - { "glIsRenderbuffer", 20, -1 }, - { "glIsShader", 20, -1 }, - { "glIsTexture", 20, _gloffset_IsTexture }, - { "glIsVertexArrayOES", 20, -1 }, - { "glLineWidth", 20, _gloffset_LineWidth }, - { "glLinkProgram", 20, -1 }, - { "glMapBufferOES", 20, -1 }, - { "glMapBufferRangeEXT", 20, -1 }, - { "glMultiDrawArraysEXT", 20, -1 }, - { "glMultiDrawElementsEXT", 20, -1 }, - { "glMultiDrawElementsBaseVertex", 20, -1 }, - { "glPixelStorei", 20, _gloffset_PixelStorei }, - { "glPolygonOffset", 20, _gloffset_PolygonOffset }, - { "glReadBufferNV", 20, _gloffset_ReadBuffer }, - { "glReadPixels", 20, _gloffset_ReadPixels }, - { "glReleaseShaderCompiler", 20, -1 }, - { "glRenderbufferStorage", 20, -1 }, - { "glSampleCoverage", 20, -1 }, - { "glScissor", 20, _gloffset_Scissor }, - { "glShaderBinary", 20, -1 }, - { "glShaderSource", 20, -1 }, - { "glStencilFunc", 20, _gloffset_StencilFunc }, - { "glStencilFuncSeparate", 20, -1 }, - { "glStencilMask", 20, _gloffset_StencilMask }, - { "glStencilMaskSeparate", 20, -1 }, - { "glStencilOp", 20, _gloffset_StencilOp }, - { "glStencilOpSeparate", 20, -1 }, - { "glTexImage2D", 20, _gloffset_TexImage2D }, - { "glTexImage3DOES", 20, _gloffset_TexImage3D }, - { "glTexParameterf", 20, _gloffset_TexParameterf }, - { "glTexParameterfv", 20, _gloffset_TexParameterfv }, - { "glTexParameteri", 20, _gloffset_TexParameteri }, - { "glTexParameteriv", 20, _gloffset_TexParameteriv }, - { "glTexSubImage2D", 20, _gloffset_TexSubImage2D }, - { "glTexSubImage3DOES", 20, _gloffset_TexSubImage3D }, - { "glUniform1f", 20, -1 }, - { "glUniform1fv", 20, -1 }, - { "glUniform1i", 20, -1 }, - { "glUniform1iv", 20, -1 }, - { "glUniform2f", 20, -1 }, - { "glUniform2fv", 20, -1 }, - { "glUniform2i", 20, -1 }, - { "glUniform2iv", 20, -1 }, - { "glUniform3f", 20, -1 }, - { "glUniform3fv", 20, -1 }, - { "glUniform3i", 20, -1 }, - { "glUniform3iv", 20, -1 }, - { "glUniform4f", 20, -1 }, - { "glUniform4fv", 20, -1 }, - { "glUniform4i", 20, -1 }, - { "glUniform4iv", 20, -1 }, - { "glUniformMatrix2fv", 20, -1 }, - { "glUniformMatrix3fv", 20, -1 }, - { "glUniformMatrix4fv", 20, -1 }, - { "glUnmapBufferOES", 20, -1 }, - { "glUseProgram", 20, -1 }, - { "glValidateProgram", 20, -1 }, - { "glVertexAttrib1f", 20, -1 }, - { "glVertexAttrib1fv", 20, -1 }, - { "glVertexAttrib2f", 20, -1 }, - { "glVertexAttrib2fv", 20, -1 }, - { "glVertexAttrib3f", 20, -1 }, - { "glVertexAttrib3fv", 20, -1 }, - { "glVertexAttrib4f", 20, -1 }, - { "glVertexAttrib4fv", 20, -1 }, - { "glVertexAttribPointer", 20, -1 }, - { "glViewport", 20, _gloffset_Viewport }, - - /* GL_OES_get_program_binary - Also part of OpenGL ES 3.0. */ - { "glGetProgramBinaryOES", 20, -1 }, - { "glProgramBinaryOES", 20, -1 }, - - /* GL_EXT_separate_shader_objects - Also part of OpenGL ES 3.1. */ - { "glProgramParameteriEXT", 20, -1 }, - { "glUseProgramStagesEXT", 20, -1 }, - { "glActiveShaderProgramEXT", 20, -1 }, - { "glCreateShaderProgramvEXT", 20, -1 }, - { "glBindProgramPipelineEXT", 20, -1 }, - { "glDeleteProgramPipelinesEXT", 20, -1 }, - { "glGenProgramPipelinesEXT", 20, -1 }, - { "glIsProgramPipelineEXT", 20, -1 }, - { "glGetProgramPipelineivEXT", 20, -1 }, - { "glProgramUniform1iEXT", 20, -1 }, - { "glProgramUniform1ivEXT", 20, -1 }, - { "glProgramUniform1fEXT", 20, -1 }, - { "glProgramUniform1fvEXT", 20, -1 }, - { "glProgramUniform2iEXT", 20, -1 }, - { "glProgramUniform2ivEXT", 20, -1 }, - { "glProgramUniform2fEXT", 20, -1 }, - { "glProgramUniform2fvEXT", 20, -1 }, - { "glProgramUniform3iEXT", 20, -1 }, - { "glProgramUniform3ivEXT", 20, -1 }, - { "glProgramUniform3fEXT", 20, -1 }, - { "glProgramUniform3fvEXT", 20, -1 }, - { "glProgramUniform4iEXT", 20, -1 }, - { "glProgramUniform4ivEXT", 20, -1 }, - { "glProgramUniform4fEXT", 20, -1 }, - { "glProgramUniform4fvEXT", 20, -1 }, - { "glProgramUniformMatrix2fvEXT", 20, -1 }, - { "glProgramUniformMatrix3fvEXT", 20, -1 }, - { "glProgramUniformMatrix4fvEXT", 20, -1 }, - { "glProgramUniformMatrix2x3fvEXT", 20, -1 }, - { "glProgramUniformMatrix3x2fvEXT", 20, -1 }, - { "glProgramUniformMatrix2x4fvEXT", 20, -1 }, - { "glProgramUniformMatrix4x2fvEXT", 20, -1 }, - { "glProgramUniformMatrix3x4fvEXT", 20, -1 }, - { "glProgramUniformMatrix4x3fvEXT", 20, -1 }, - { "glValidateProgramPipelineEXT", 20, -1 }, - { "glGetProgramPipelineInfoLogEXT", 20, -1 }, - - /* GL_AMD_performance_monitor */ - { "glGetPerfMonitorGroupsAMD", 20, -1 }, - { "glGetPerfMonitorCountersAMD", 20, -1 }, - { "glGetPerfMonitorGroupStringAMD", 20, -1 }, - { "glGetPerfMonitorCounterStringAMD", 20, -1 }, - { "glGetPerfMonitorCounterInfoAMD", 20, -1 }, - { "glGenPerfMonitorsAMD", 20, -1 }, - { "glDeletePerfMonitorsAMD", 20, -1 }, - { "glSelectPerfMonitorCountersAMD", 20, -1 }, - { "glBeginPerfMonitorAMD", 20, -1 }, - { "glEndPerfMonitorAMD", 20, -1 }, - { "glGetPerfMonitorCounterDataAMD", 20, -1 }, - - /* GL_INTEL_performance_query */ - { "glGetFirstPerfQueryIdINTEL", 20, -1 }, - { "glGetNextPerfQueryIdINTEL", 20, -1 }, - { "glGetPerfQueryIdByNameINTEL", 20, -1 }, - { "glGetPerfQueryInfoINTEL", 20, -1 }, - { "glGetPerfCounterInfoINTEL", 20, -1 }, - { "glCreatePerfQueryINTEL", 20, -1 }, - { "glDeletePerfQueryINTEL", 20, -1 }, - { "glBeginPerfQueryINTEL", 20, -1 }, - { "glEndPerfQueryINTEL", 20, -1 }, - { "glGetPerfQueryDataINTEL", 20, -1 }, - - /* GL_KHR_debug */ - { "glPushDebugGroupKHR", 20, -1 }, - { "glPopDebugGroupKHR", 20, -1 }, - { "glDebugMessageCallbackKHR", 20, -1 }, - { "glDebugMessageControlKHR", 20, -1 }, - { "glDebugMessageInsertKHR", 20, -1 }, - { "glGetDebugMessageLogKHR", 20, -1 }, - { "glGetObjectLabelKHR", 20, -1 }, - { "glGetObjectPtrLabelKHR", 20, -1 }, - { "glGetPointervKHR", 20, -1 }, - { "glObjectLabelKHR", 20, -1 }, - { "glObjectPtrLabelKHR", 20, -1 }, - - /* GL_EXT_polygon_offset_clamp */ - { "glPolygonOffsetClampEXT", 11, -1 }, - - /* GL_KHR_robustness */ - { "glGetGraphicsResetStatusKHR", 20, -1 }, - { "glReadnPixelsKHR", 20, -1 }, - { "glGetnUniformfvKHR", 20, -1 }, - { "glGetnUniformivKHR", 20, -1 }, - { "glGetnUniformuivKHR", 20, -1 }, - - /* GL_KHR_blend_equation_advanced */ - { "glBlendBarrierKHR", 20, -1 }, - - /* GL_EXT_occlusion_query_boolean */ - { "glGenQueriesEXT", 20, -1 }, - { "glDeleteQueriesEXT", 20, -1 }, - { "glIsQueryEXT", 20, -1 }, - { "glBeginQueryEXT", 20, -1 }, - { "glEndQueryEXT", 20, -1 }, - { "glGetQueryivEXT", 20, -1 }, - { "glGetQueryObjectivEXT", 20, -1 }, - { "glGetQueryObjectuivEXT", 20, -1 }, - - /* GL_EXT_clip_control */ - { "glClipControlEXT", 20, -1 }, - - /* GL_EXT_disjoint_timer_query */ - { "glGetQueryObjecti64vEXT", 20, -1 }, - { "glGetQueryObjectui64vEXT", 20, -1 }, - { "glQueryCounterEXT", 20, -1 }, - { "glGetInteger64vEXT", 20, -1 }, - - /* GL_EXT_shader_framebuffer_fetch_non_coherent */ - { "glFramebufferFetchBarrierEXT", 20, -1 }, - - /* GL_NV_conditional_render */ - { "glBeginConditionalRenderNV", 20, -1 }, - { "glEndConditionalRenderNV", 20, -1 }, - - /* GL_NV_conservative_raster */ - { "glSubpixelPrecisionBiasNV", 20, -1 }, - - /* GL_NV_conservative_raster_dilate */ - { "glConservativeRasterParameterfNV", 20, -1 }, - - /* GL_NV_conservative_raster_pre_snap_triangles */ - { "glConservativeRasterParameteriNV", 20, -1 }, - - /* GL_EXT_multisampled_render_to_texture */ - { "glRenderbufferStorageMultisampleEXT", 20, -1 }, - { "glFramebufferTexture2DMultisampleEXT", 20, -1 }, - - /* GL_KHR_parallel_shader_compile */ - { "glMaxShaderCompilerThreadsKHR", 20, -1 }, - - { "glInternalBufferSubDataCopyMESA", 20, -1 }, - { "glInternalSetError", 20, -1 }, - - { NULL, 0, -1 } -}; - -const struct function gles3_functions_possible[] = { - // We check for the aliased -EXT version in GLES 2 - // { "glBeginQuery", 30, -1 }, - { "glBeginTransformFeedback", 30, -1 }, - { "glBindBufferBase", 30, -1 }, - { "glBindBufferRange", 30, -1 }, - { "glBindSampler", 30, -1 }, - { "glBindTransformFeedback", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glBindVertexArray", 30, -1 }, - { "glBlitFramebuffer", 30, -1 }, - { "glClearBufferfi", 30, -1 }, - { "glClearBufferfv", 30, -1 }, - { "glClearBufferiv", 30, -1 }, - { "glClearBufferuiv", 30, -1 }, - { "glClientWaitSync", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glCompressedTexImage3D", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glCompressedTexSubImage3D", 30, -1 }, - { "glCopyBufferSubData", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glCopyTexSubImage3D", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glDeleteQueries", 30, -1 }, - { "glDeleteSamplers", 30, -1 }, - { "glDeleteSync", 30, -1 }, - { "glDeleteTransformFeedbacks", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glDeleteVertexArrays", 30, -1 }, - { "glDrawArraysInstanced", 30, -1 }, - // We check for the aliased -NV version in GLES 2 - // { "glDrawBuffers", 30, -1 }, - { "glDrawElementsInstanced", 30, -1 }, - { "glDrawRangeElements", 30, -1 }, - { "glDrawRangeElementsBaseVertex", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glEndQuery", 30, -1 }, - { "glEndTransformFeedback", 30, -1 }, - { "glFenceSync", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glFlushMappedBufferRange", 30, -1 }, - { "glFramebufferTextureLayer", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glGenQueries", 30, -1 }, - { "glGenSamplers", 30, -1 }, - { "glGenTransformFeedbacks", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glGenVertexArrays", 30, -1 }, - { "glGetActiveUniformBlockiv", 30, -1 }, - { "glGetActiveUniformBlockName", 30, -1 }, - { "glGetActiveUniformsiv", 30, -1 }, - { "glGetBufferParameteri64v", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glGetBufferPointerv", 30, -1 }, - { "glGetFragDataLocation", 30, -1 }, - { "glGetInteger64i_v", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - //{ "glGetInteger64v", 30, -1 }, - { "glGetIntegeri_v", 30, -1 }, - { "glGetInternalformativ", 30, -1 }, - { "glGetInternalformati64v", 30, -1 }, - // glGetProgramBinary aliases glGetProgramBinaryOES in GLES 2 - // We check for the aliased -EXT version in GLES 2 - // { "glGetQueryiv", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glGetQueryObjectuiv", 30, -1 }, - { "glGetSamplerParameterfv", 30, -1 }, - { "glGetSamplerParameteriv", 30, -1 }, - { "glGetStringi", 30, -1 }, - { "glGetSynciv", 30, -1 }, - { "glGetTransformFeedbackVarying", 30, -1 }, - { "glGetUniformBlockIndex", 30, -1 }, - { "glGetUniformIndices", 30, -1 }, - { "glGetUniformuiv", 30, -1 }, - { "glGetVertexAttribIiv", 30, -1 }, - { "glGetVertexAttribIuiv", 30, -1 }, - { "glInvalidateFramebuffer", 30, -1 }, - { "glInvalidateSubFramebuffer", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glIsQuery", 30, -1 }, - { "glIsSampler", 30, -1 }, - { "glIsSync", 30, -1 }, - { "glIsTransformFeedback", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glIsVertexArray", 30, -1 }, - // We check for the aliased -EXT version in GLES 2 - // { "glMapBufferRange", 30, -1 }, - { "glPauseTransformFeedback", 30, -1 }, - // glProgramBinary aliases glProgramBinaryOES in GLES 2 - // glProgramParameteri aliases glProgramParameteriEXT in GLES 2 - // We check for the aliased -NV version in GLES 2 - // { "glReadBuffer", 30, -1 }, - // glRenderbufferStorageMultisample aliases glRenderbufferStorageMultisampleEXT in GLES 2 - { "glResumeTransformFeedback", 30, -1 }, - { "glSamplerParameterf", 30, -1 }, - { "glSamplerParameterfv", 30, -1 }, - { "glSamplerParameteri", 30, -1 }, - { "glSamplerParameteriv", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glTexImage3D", 30, -1 }, - { "glTexStorage2D", 30, -1 }, - { "glTexStorage3D", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glTexSubImage3D", 30, -1 }, - { "glTransformFeedbackVaryings", 30, -1 }, - { "glUniform1ui", 30, -1 }, - { "glUniform1uiv", 30, -1 }, - { "glUniform2ui", 30, -1 }, - { "glUniform2uiv", 30, -1 }, - { "glUniform3ui", 30, -1 }, - { "glUniform3uiv", 30, -1 }, - { "glUniform4ui", 30, -1 }, - { "glUniform4uiv", 30, -1 }, - { "glUniformBlockBinding", 30, -1 }, - { "glUniformMatrix2x3fv", 30, -1 }, - { "glUniformMatrix2x4fv", 30, -1 }, - { "glUniformMatrix3x2fv", 30, -1 }, - { "glUniformMatrix3x4fv", 30, -1 }, - { "glUniformMatrix4x2fv", 30, -1 }, - { "glUniformMatrix4x3fv", 30, -1 }, - // We check for the aliased -OES version in GLES 2 - // { "glUnmapBuffer", 30, -1 }, - { "glVertexAttribDivisor", 30, -1 }, - { "glVertexAttribI4i", 30, -1 }, - { "glVertexAttribI4iv", 30, -1 }, - { "glVertexAttribI4ui", 30, -1 }, - { "glVertexAttribI4uiv", 30, -1 }, - { "glVertexAttribIPointer", 30, -1 }, - { "glWaitSync", 30, -1 }, - - /* GL_EXT_separate_shader_objects - Also part of OpenGL ES 3.1. */ - { "glProgramUniform1uiEXT", 30, -1 }, - { "glProgramUniform1uivEXT", 30, -1 }, - { "glProgramUniform2uiEXT", 30, -1 }, - { "glProgramUniform2uivEXT", 30, -1 }, - { "glProgramUniform3uiEXT", 30, -1 }, - { "glProgramUniform3uivEXT", 30, -1 }, - { "glProgramUniform4uiEXT", 30, -1 }, - { "glProgramUniform4uivEXT", 30, -1 }, - - /* GL_EXT_blend_func_extended */ - { "glBindFragDataLocationIndexedEXT", 30, -1 }, - { "glGetFragDataIndexEXT", 30, -1 }, - { "glBindFragDataLocationEXT", 30, -1 }, - - /* GL_OES_texture_border_clamp */ - { "glTexParameterIivOES", 30, -1 }, - { "glTexParameterIuivOES", 30, -1 }, - { "glGetTexParameterIivOES", 30, -1 }, - { "glGetTexParameterIuivOES", 30, -1 }, - { "glSamplerParameterIivOES", 30, -1 }, - { "glSamplerParameterIuivOES", 30, -1 }, - { "glGetSamplerParameterIivOES", 30, -1 }, - { "glGetSamplerParameterIuivOES", 30, -1 }, - - /* GL_OES_texture_buffer */ - { "glTexBufferOES", 31, -1 }, - { "glTexBufferRangeOES", 31, -1 }, - - /* GL_OES_sample_shading */ - { "glMinSampleShadingOES", 30, -1 }, - - /* GL_OES_copy_image */ - { "glCopyImageSubDataOES", 30, -1 }, - - /* GL_OES_draw_buffers_indexed */ - { "glBlendFunciOES", 30, -1 }, - { "glBlendFuncSeparateiOES", 30, -1 }, - { "glBlendEquationiOES", 30, -1 }, - { "glBlendEquationSeparateiOES", 30, -1 }, - { "glColorMaskiOES", 30, -1 }, - { "glEnableiOES", 30, -1 }, - { "glDisableiOES", 30, -1 }, - { "glIsEnablediOES", 30, -1 }, - - /* GL_EXT_base_instance */ - { "glDrawArraysInstancedBaseInstanceEXT", 30, -1 }, - { "glDrawElementsInstancedBaseInstanceEXT", 30, -1 }, - { "glDrawElementsInstancedBaseVertexBaseInstanceEXT", 30, -1 }, - - /* GL_EXT_window_rectangles */ - { "glWindowRectanglesEXT", 30, -1 }, - - /* GL_AMD_framebuffer_multisample_advanced */ - { "glRenderbufferStorageMultisampleAdvancedAMD", 11, -1 }, - { "glNamedRenderbufferStorageMultisampleAdvancedAMD", 11, -1 }, - - /* GL_MESA_framebuffer_flip_y */ - { "glFramebufferParameteriMESA", 30, -1 }, - { "glGetFramebufferParameterivMESA", 30, -1 }, - - /* EXT_EGL_image_storage */ - { "glEGLImageTargetTexStorageEXT", 30, -1 }, - - { "glDrawElementsInstancedBaseVertex", 30, -1 }, - - { NULL, 0, -1 } -}; - -const struct function gles31_functions_possible[] = { - { "glDispatchCompute", 31, -1 }, - { "glDispatchComputeIndirect", 31, -1 }, - { "glDrawArraysIndirect", 31, -1 }, - { "glDrawElementsIndirect", 31, -1 }, - - { "glFramebufferParameteri", 31, -1 }, - { "glGetFramebufferParameteriv", 31, -1 }, - - { "glGetProgramInterfaceiv", 31, -1 }, - { "glGetProgramResourceIndex", 31, -1 }, - { "glGetProgramResourceName", 31, -1 }, - { "glGetProgramResourceiv", 31, -1 }, - { "glGetProgramResourceLocation", 31, -1 }, - - // We check for the aliased EXT versions in GLES 2 - // { "glUseProgramStages", 31, -1 }, - // { "glActiveShaderProgram", 31, -1 }, - // { "glCreateShaderProgramv", 31, -1 }, - // { "glBindProgramPipeline", 31, -1 }, - // { "glDeleteProgramPipelines", 31, -1 }, - // { "glGenProgramPipelines", 31, -1 }, - // { "glIsProgramPipeline", 31, -1 }, - // { "glGetProgramPipelineiv", 31, -1 }, - // { "glProgramUniform1i", 31, -1 }, - // { "glProgramUniform2i", 31, -1 }, - // { "glProgramUniform3i", 31, -1 }, - // { "glProgramUniform4i", 31, -1 }, - // { "glProgramUniform1f", 31, -1 }, - // { "glProgramUniform2f", 31, -1 }, - // { "glProgramUniform3f", 31, -1 }, - // { "glProgramUniform4f", 31, -1 }, - // { "glProgramUniform1iv", 31, -1 }, - // { "glProgramUniform2iv", 31, -1 }, - // { "glProgramUniform3iv", 31, -1 }, - // { "glProgramUniform4iv", 31, -1 }, - // { "glProgramUniform1fv", 31, -1 }, - // { "glProgramUniform2fv", 31, -1 }, - // { "glProgramUniform3fv", 31, -1 }, - // { "glProgramUniform4fv", 31, -1 }, - // { "glProgramUniformMatrix2fv", 31, -1 }, - // { "glProgramUniformMatrix3fv", 31, -1 }, - // { "glProgramUniformMatrix4fv", 31, -1 }, - // { "glProgramUniformMatrix2x3fv", 31, -1 }, - // { "glProgramUniformMatrix3x2fv", 31, -1 }, - // { "glProgramUniformMatrix2x4fv", 31, -1 }, - // { "glProgramUniformMatrix4x2fv", 31, -1 }, - // { "glProgramUniformMatrix3x4fv", 31, -1 }, - // { "glProgramUniformMatrix4x3fv", 31, -1 }, - // { "glValidateProgramPipeline", 31, -1 }, - // { "glGetProgramPipelineInfoLog", 31, -1 }, - - // We check for the aliased EXT versions in GLES 3 - // { "glProgramUniform1ui", 31, -1 }, - // { "glProgramUniform2ui", 31, -1 }, - // { "glProgramUniform3ui", 31, -1 }, - // { "glProgramUniform4ui", 31, -1 }, - // { "glProgramUniform1uiv", 31, -1 }, - // { "glProgramUniform2uiv", 31, -1 }, - // { "glProgramUniform3uiv", 31, -1 }, - // { "glProgramUniform4uiv", 31, -1 }, - - { "glBindImageTexture", 31, -1 }, - { "glGetBooleani_v", 31, -1 }, - { "glMemoryBarrier", 31, -1 }, - - { "glMemoryBarrierByRegion", 31, -1 }, - - { "glTexStorage2DMultisample", 31, -1 }, - { "glGetMultisamplefv", 31, -1 }, - { "glSampleMaski", 31, -1 }, - { "glGetTexLevelParameteriv", 31, -1 }, - { "glGetTexLevelParameterfv", 31, -1 }, - { "glBindVertexBuffer", 31, -1 }, - { "glVertexAttribFormat", 31, -1 }, - { "glVertexAttribIFormat", 31, -1 }, - { "glVertexAttribBinding", 31, -1 }, - { "glVertexBindingDivisor", 31, -1 }, - - /* GL_OES_texture_storage_multisample_2d_array */ - { "glTexStorage3DMultisampleOES", 31, -1 }, - - /* GL_OES_texture_view */ - { "glTextureViewOES", 31, -1 }, - - /* GL_EXT_buffer_storage */ - { "glBufferStorageEXT", 31, -1 }, - - /* GL_EXT_blend_func_extended */ - { "glGetProgramResourceLocationIndexEXT", 31, -1 }, - - /* GL_OES_geometry_shader */ - { "glFramebufferTextureOES", 31, -1}, - - /* GL_EXT_geometry_shader */ - // We check for the aliased OES version above - // { "glFramebufferTextureEXT", 31, -1}, - - /* GL_OES_tessellation_shader */ - { "glPatchParameteriOES", 31, -1 }, - - /* GL_OES_primitive_bound_box */ - { "glPrimitiveBoundingBoxOES", 31, -1 }, - - /* GL_OES_viewport_array */ - { "glViewportArrayvOES", 31, -1 }, - { "glViewportIndexedfOES", 31, -1 }, - { "glViewportIndexedfvOES", 31, -1 }, - { "glScissorArrayvOES", 31, -1 }, - { "glScissorIndexedOES", 31, -1 }, - { "glScissorIndexedvOES", 31, -1 }, - { "glDepthRangeArrayfvOES", 31, -1 }, - { "glDepthRangeIndexedfOES", 31, -1 }, - { "glGetFloati_vOES", 31, -1 }, - - /* GL_ARB_sample_locations */ - { "glFramebufferSampleLocationsfvARB", 31, -1 }, - { "glNamedFramebufferSampleLocationsfvARB", 31, -1 }, - { "glEvaluateDepthValuesARB", 31, -1 }, - - /* GL_NV_viewport_swizzle */ - { "glViewportSwizzleNV", 31, -1 }, - - { NULL, 0, -1 }, - }; diff --git a/src/mesa/main/tests/enum_strings.cpp b/src/mesa/main/tests/enum_strings.cpp index 1395ac8fb33..17509c5f073 100644 --- a/src/mesa/main/tests/enum_strings.cpp +++ b/src/mesa/main/tests/enum_strings.cpp @@ -22,7 +22,6 @@ */ #include <gtest/gtest.h> -#include <GL/gl.h> #include "main/enums.h" diff --git a/src/mesa/main/tests/mesa_formats.cpp b/src/mesa/main/tests/mesa_formats.cpp index ae59c438b32..916f7378d38 100644 --- a/src/mesa/main/tests/mesa_formats.cpp +++ b/src/mesa/main/tests/mesa_formats.cpp @@ -36,12 +36,16 @@ #include "main/format_unpack.h" #include "main/format_pack.h" +// Test fixture for Format tests. +class MesaFormatsTest : public ::testing::Test { +}; + /** * Debug/test: check that all uncompressed formats are handled in the * _mesa_uncompressed_format_to_type_and_comps() function. When new pixel * formats are added to Mesa, that function needs to be updated. */ -TEST(MesaFormatsTest, FormatTypeAndComps) +TEST_F(MesaFormatsTest, FormatTypeAndComps) { for (int fi = MESA_FORMAT_NONE + 1; fi < MESA_FORMAT_COUNT; ++fi) { mesa_format f = (mesa_format) fi; @@ -68,7 +72,7 @@ TEST(MesaFormatsTest, FormatTypeAndComps) /** * Do sanity checking of the format info table. */ -TEST(MesaFormatsTest, FormatSanity) +TEST_F(MesaFormatsTest, FormatSanity) { for (int fi = 0; fi < MESA_FORMAT_COUNT; ++fi) { mesa_format f = (mesa_format) fi; @@ -139,7 +143,7 @@ TEST(MesaFormatsTest, FormatSanity) } } -TEST(MesaFormatsTest, IntensityToRed) +TEST_F(MesaFormatsTest, IntensityToRed) { EXPECT_EQ(_mesa_get_intensity_format_red(MESA_FORMAT_I_UNORM8), MESA_FORMAT_R_UNORM8); @@ -157,7 +161,7 @@ static mesa_format fffat_wrap(GLenum format, GLenum type) return (mesa_format)f; } -TEST(MesaFormatsTest, FormatFromFormatAndType) +TEST_F(MesaFormatsTest, FormatFromFormatAndType) { EXPECT_EQ(fffat_wrap(GL_RGBA, GL_SHORT), MESA_FORMAT_RGBA_SNORM16); @@ -171,7 +175,7 @@ TEST(MesaFormatsTest, FormatFromFormatAndType) GL_BYTE))); } -TEST(MesaFormatsTest, FormatMatchesFormatAndType) +TEST_F(MesaFormatsTest, FormatMatchesFormatAndType) { EXPECT_TRUE(_mesa_format_matches_format_and_type(MESA_FORMAT_RGBA_UNORM16, GL_RGBA, @@ -203,7 +207,7 @@ test_unpack_r32ui(uint32_t val) return result[0]; } -TEST(MesaFormatsTest, UnpackRGBAUintRow) +TEST_F(MesaFormatsTest, UnpackRGBAUintRow) { EXPECT_EQ(test_unpack_r8i(0), 0); EXPECT_EQ(test_unpack_r8i(1), 1); @@ -212,7 +216,7 @@ TEST(MesaFormatsTest, UnpackRGBAUintRow) EXPECT_EQ(test_unpack_r32ui(0xffffffff), 0xffffffff); } -TEST(MesaFormatsTest, UnpackRGBAUbyteRowRGBA32F) +TEST_F(MesaFormatsTest, UnpackRGBAUbyteRowRGBA32F) { float val[4] = {0, 0.5, -1, 2}; uint8_t result[4]; @@ -223,7 +227,7 @@ TEST(MesaFormatsTest, UnpackRGBAUbyteRowRGBA32F) EXPECT_EQ(result[3], 0xff); } -TEST(MesaFormatsTest, UnpackRGBAUbyteRowRGBA4) +TEST_F(MesaFormatsTest, UnpackRGBAUbyteRowRGBA4) { uint16_t val = (1 << 0) | (0x3f << 5) | (0x10 << 11); uint8_t result[4]; @@ -242,7 +246,7 @@ test_unpack_floatz_z32f(float val) return result; } -TEST(MesaFormatsTest, UnpackFloatZRow) +TEST_F(MesaFormatsTest, UnpackFloatZRow) { EXPECT_EQ(test_unpack_floatz_z32f(0.5), 0.5); EXPECT_EQ(test_unpack_floatz_z32f(-1.0), -1.0); @@ -257,7 +261,7 @@ test_unpack_uintz_z32f(float val) return result; } -TEST(MesaFormatsTest, UnpackUintZRow) +TEST_F(MesaFormatsTest, UnpackUintZRow) { EXPECT_EQ(test_unpack_uintz_z32f(0.5), 0x7fffffff); EXPECT_EQ(test_unpack_uintz_z32f(-1.0), 0); @@ -265,7 +269,7 @@ TEST(MesaFormatsTest, UnpackUintZRow) } /* It's easy to have precision issues packing 32-bit floats to unorm. */ -TEST(MesaFormatsTest, PackFloatZ) +TEST_F(MesaFormatsTest, PackFloatZ) { float val = 0.571428597f; uint32_t result; @@ -273,7 +277,7 @@ TEST(MesaFormatsTest, PackFloatZ) EXPECT_EQ(result, 0x924924ff); } -TEST(MesaFormatsTest, PackUbyteRGBARounding) +TEST_F(MesaFormatsTest, PackUbyteRGBARounding) { for (int i = 0; i <= 255; i++) { uint8_t val[4] = {(uint8_t)i, 0, 0, 0}; diff --git a/src/mesa/main/tests/meson.build b/src/mesa/main/tests/meson.build index 7e9e843cab4..36615c2f288 100644 --- a/src/mesa/main/tests/meson.build +++ b/src/mesa/main/tests/meson.build @@ -18,12 +18,16 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. -files_main_test = files('enum_strings.cpp') +files_main_test = files( + 'enum_strings.cpp', + 'disable_windows_include.c', +) +# disable_windows_include.c includes this generated header. +files_main_test += main_marshal_generated_h link_main_test = [] if with_shared_glapi files_main_test += files( - 'dispatch_sanity.cpp', 'mesa_formats.cpp', 'mesa_extensions.cpp', 'program_state_string.cpp', @@ -38,9 +42,10 @@ test( executable( 'main_test', [files_main_test, main_dispatch_h], - include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium], - dependencies : [idep_gtest, dep_clock, dep_dl, dep_thread, idep_mesautil], - link_with : [libmesa_classic, link_main_test], + include_directories : [inc_include, inc_src, inc_mapi, inc_mesa, inc_gallium, inc_gallium_aux], + dependencies : [idep_gtest, dep_clock, dep_dl, dep_thread, idep_nir_headers, idep_mesautil], + link_with : [libmesa, libgallium, link_main_test], ), suite : ['mesa'], + protocol : 'gtest', ) diff --git a/src/mesa/main/tests/program_state_string.cpp b/src/mesa/main/tests/program_state_string.cpp index 38805f92c77..e606194e55a 100644 --- a/src/mesa/main/tests/program_state_string.cpp +++ b/src/mesa/main/tests/program_state_string.cpp @@ -23,9 +23,6 @@ #include <gtest/gtest.h> -#include "GL/gl.h" -#include "GL/glext.h" - #include "program/prog_statevars.h" TEST(program_state_string, depth_range) diff --git a/src/mesa/main/tests/stubs.cpp b/src/mesa/main/tests/stubs.cpp index c24df53a561..0d1f463b65f 100644 --- a/src/mesa/main/tests/stubs.cpp +++ b/src/mesa/main/tests/stubs.cpp @@ -20,7 +20,6 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. */ -#include <GL/gl.h> #include "main/errors.h" extern "C" { diff --git a/src/mesa/main/texcompress.c b/src/mesa/main/texcompress.c index 992818cc001..c57d46ba8f7 100644 --- a/src/mesa/main/texcompress.c +++ b/src/mesa/main/texcompress.c @@ -30,7 +30,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "formats.h" @@ -347,7 +347,7 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) formats[n++] = GL_COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; } - if (ctx->API == API_OPENGLES) { + if (_mesa_is_gles1(ctx)) { formats[n++] = GL_PALETTE4_RGB8_OES; formats[n++] = GL_PALETTE4_RGBA8_OES; formats[n++] = GL_PALETTE4_R5_G6_B5_OES; @@ -402,7 +402,7 @@ _mesa_get_compressed_formats(struct gl_context *ctx, GLint *formats) * COMPRESSED_TEXTURE_FORMATS query returns the set of supported specific * compressed formats. */ - if (ctx->API == API_OPENGLES2 && + if (_mesa_is_gles2(ctx) && ctx->Extensions.KHR_texture_compression_astc_ldr) { formats[n++] = GL_COMPRESSED_RGBA_ASTC_4x4_KHR; formats[n++] = GL_COMPRESSED_RGBA_ASTC_5x4_KHR; @@ -871,38 +871,6 @@ _mesa_compressed_format_to_glenum(struct gl_context *ctx, } -/* - * Return the address of the pixel at (col, row, img) in a - * compressed texture image. - * \param col, row, img - image position (3D), should be a multiple of the - * format's block size. - * \param format - compressed image format - * \param width - image width (stride) in pixels - * \param image - the image address - * \return address of pixel at (row, col, img) - */ -GLubyte * -_mesa_compressed_image_address(GLint col, GLint row, GLint img, - mesa_format mesaFormat, - GLsizei width, const GLubyte *image) -{ - /* XXX only 2D images implemented, not 3D */ - const GLuint blockSize = _mesa_get_format_bytes(mesaFormat); - GLuint bw, bh; - GLint offset; - - _mesa_get_format_block_size(mesaFormat, &bw, &bh); - - assert(col % bw == 0); - assert(row % bh == 0); - - offset = ((width + bw - 1) / bw) * (row / bh) + col / bw; - offset *= blockSize; - - return (GLubyte *) image + offset; -} - - /** * Return a texel-fetch function for the given format, or NULL if * invalid format. diff --git a/src/mesa/main/texcompress.h b/src/mesa/main/texcompress.h index b00924d02eb..25e02981c1c 100644 --- a/src/mesa/main/texcompress.h +++ b/src/mesa/main/texcompress.h @@ -26,7 +26,7 @@ #define TEXCOMPRESS_H #include "formats.h" -#include "glheader.h" +#include "util/glheader.h" struct gl_context; diff --git a/src/mesa/main/texcompress_astc.cpp b/src/mesa/main/texcompress_astc.cpp index 583e582a4b6..e628c4c81bf 100644 --- a/src/mesa/main/texcompress_astc.cpp +++ b/src/mesa/main/texcompress_astc.cpp @@ -42,12 +42,6 @@ static bool VERBOSE_DECODE = false; static bool VERBOSE_WRITE = false; -static inline uint8_t -uint16_div_64k_to_half_to_unorm8(uint16_t v) -{ - return _mesa_half_to_unorm8(_mesa_uint16_div_64k_to_half(v)); -} - class decode_error { public: @@ -1614,16 +1608,10 @@ void Block::write_decoded(const Decoder &decoder, uint16_t *output) if (is_void_extent) { for (int idx = 0; idx < decoder.block_w*decoder.block_h*decoder.block_d; ++idx) { if (decoder.output_unorm8) { - if (decoder.srgb) { - output[idx*4+0] = void_extent_colour_r >> 8; - output[idx*4+1] = void_extent_colour_g >> 8; - output[idx*4+2] = void_extent_colour_b >> 8; - } else { - output[idx*4+0] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_r); - output[idx*4+1] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_g); - output[idx*4+2] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_b); - } - output[idx*4+3] = uint16_div_64k_to_half_to_unorm8(void_extent_colour_a); + output[idx*4+0] = void_extent_colour_r >> 8; + output[idx*4+1] = void_extent_colour_g >> 8; + output[idx*4+2] = void_extent_colour_b >> 8; + output[idx*4+3] = void_extent_colour_a >> 8; } else { /* Store the color as FP16. */ output[idx*4+0] = _mesa_uint16_div_64k_to_half(void_extent_colour_r); @@ -1699,16 +1687,10 @@ void Block::write_decoded(const Decoder &decoder, uint16_t *output) }; if (decoder.output_unorm8) { - if (decoder.srgb) { - output[idx*4+0] = c[0] >> 8; - output[idx*4+1] = c[1] >> 8; - output[idx*4+2] = c[2] >> 8; - } else { - output[idx*4+0] = c[0] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[0]); - output[idx*4+1] = c[1] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[1]); - output[idx*4+2] = c[2] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[2]); - } - output[idx*4+3] = c[3] == 65535 ? 0xff : uint16_div_64k_to_half_to_unorm8(c[3]); + output[idx*4+0] = c[0] >> 8; + output[idx*4+1] = c[1] >> 8; + output[idx*4+2] = c[2] >> 8; + output[idx*4+3] = c[3] >> 8; } else { /* Store the color as FP16. */ output[idx*4+0] = c[0] == 65535 ? FP16_ONE : _mesa_uint16_div_64k_to_half(c[0]); diff --git a/src/mesa/main/texcompress_bptc.c b/src/mesa/main/texcompress_bptc.c index 70dc37d8897..09e2a64f763 100644 --- a/src/mesa/main/texcompress_bptc.c +++ b/src/mesa/main/texcompress_bptc.c @@ -29,7 +29,7 @@ #include <stdbool.h> #include "texcompress.h" #include "texcompress_bptc.h" -#include "texcompress_bptc_tmp.h" +#include "util/format/texcompress_bptc_tmp.h" #include "texstore.h" #include "image.h" #include "mtypes.h" @@ -241,3 +241,35 @@ _mesa_texstore_bptc_rgb_unsigned_float(TEXSTORE_PARAMS) srcAddr, srcPacking, false /* unsigned */); } + +void +_mesa_unpack_bptc(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format) +{ + switch (format) { + case MESA_FORMAT_BPTC_RGB_SIGNED_FLOAT: + decompress_rgb_fp16(src_width, src_height, + src_row, src_stride, + (uint16_t *)dst_row, dst_stride, + true); + break; + + case MESA_FORMAT_BPTC_RGB_UNSIGNED_FLOAT: + decompress_rgb_fp16(src_width, src_height, + src_row, src_stride, + (uint16_t *)dst_row, dst_stride, + false); + break; + + default: + decompress_rgba_unorm(src_width, src_height, + src_row, src_stride, + dst_row, dst_stride); + break; + } +} diff --git a/src/mesa/main/texcompress_bptc.h b/src/mesa/main/texcompress_bptc.h index 814548e2bcc..0de1bd31f2a 100644 --- a/src/mesa/main/texcompress_bptc.h +++ b/src/mesa/main/texcompress_bptc.h @@ -25,7 +25,7 @@ #define TEXCOMPRESS_BPTC_H #include <inttypes.h> -#include "glheader.h" +#include "util/glheader.h" #include "texcompress.h" #include "texstore.h" @@ -41,4 +41,13 @@ _mesa_texstore_bptc_rgb_unsigned_float(TEXSTORE_PARAMS); compressed_fetch_func _mesa_get_bptc_fetch_func(mesa_format format); +void +_mesa_unpack_bptc(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format); + #endif diff --git a/src/mesa/main/texcompress_bptc_tmp.h b/src/mesa/main/texcompress_bptc_tmp.h deleted file mode 100644 index 0f5db4396ef..00000000000 --- a/src/mesa/main/texcompress_bptc_tmp.h +++ /dev/null @@ -1,1745 +0,0 @@ -/* - * Copyright (C) 2014 Intel Corporation - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* - * Included by texcompress_bptc and gallium to define BPTC decoding routines. - */ - -#ifndef TEXCOMPRESS_BPTC_TMP_H -#define TEXCOMPRESS_BPTC_TMP_H - -#include "util/format_srgb.h" -#include "util/half_float.h" -#include "macros.h" - -#define BLOCK_SIZE 4 -#define N_PARTITIONS 64 -#define BLOCK_BYTES 16 - -struct bptc_unorm_mode { - int n_subsets; - int n_partition_bits; - bool has_rotation_bits; - bool has_index_selection_bit; - int n_color_bits; - int n_alpha_bits; - bool has_endpoint_pbits; - bool has_shared_pbits; - int n_index_bits; - int n_secondary_index_bits; -}; - -struct bptc_float_bitfield { - int8_t endpoint; - uint8_t component; - uint8_t offset; - uint8_t n_bits; - bool reverse; -}; - -struct bptc_float_mode { - bool reserved; - bool transformed_endpoints; - int n_partition_bits; - int n_endpoint_bits; - int n_index_bits; - int n_delta_bits[3]; - struct bptc_float_bitfield bitfields[24]; -}; - -struct bit_writer { - uint8_t buf; - int pos; - uint8_t *dst; -}; - -static const struct bptc_unorm_mode -bptc_unorm_modes[] = { - /* 0 */ { 3, 4, false, false, 4, 0, true, false, 3, 0 }, - /* 1 */ { 2, 6, false, false, 6, 0, false, true, 3, 0 }, - /* 2 */ { 3, 6, false, false, 5, 0, false, false, 2, 0 }, - /* 3 */ { 2, 6, false, false, 7, 0, true, false, 2, 0 }, - /* 4 */ { 1, 0, true, true, 5, 6, false, false, 2, 3 }, - /* 5 */ { 1, 0, true, false, 7, 8, false, false, 2, 2 }, - /* 6 */ { 1, 0, false, false, 7, 7, true, false, 4, 0 }, - /* 7 */ { 2, 6, false, false, 5, 5, true, false, 2, 0 } -}; - -static const struct bptc_float_mode -bptc_float_modes[] = { - /* 00 */ - { false, true, 5, 10, 3, { 5, 5, 5 }, - { { 2, 1, 4, 1, false }, { 2, 2, 4, 1, false }, { 3, 2, 4, 1, false }, - { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, - { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, - { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 01 */ - { false, true, 5, 7, 3, { 6, 6, 6 }, - { { 2, 1, 5, 1, false }, { 3, 1, 4, 1, false }, { 3, 1, 5, 1, false }, - { 0, 0, 0, 7, false }, { 3, 2, 0, 1, false }, { 3, 2, 1, 1, false }, - { 2, 2, 4, 1, false }, { 0, 1, 0, 7, false }, { 2, 2, 5, 1, false }, - { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, { 0, 2, 0, 7, false }, - { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 6, false }, - { 3, 0, 0, 6, false }, - { -1 } } - }, - /* 00010 */ - { false, true, 5, 11, 3, { 5, 4, 4 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 5, false }, { 0, 0, 10, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, { 3, 2, 0, 1, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, - { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 00011 */ - { false, false, 0, 10, 4, { 10, 10, 10 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 10, false }, { 1, 1, 0, 10, false }, { 1, 2, 0, 10, false }, - { -1 } } - }, - /* 00110 */ - { false, true, 5, 11, 3, { 4, 5, 4 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 3, 1, 4, 1, false }, - { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, { 0, 1, 10, 1, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 4, false }, { 0, 2, 10, 1, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false }, - { 3, 2, 0, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false }, - { 2, 1, 4, 1, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 00111 */ - { false, true, 0, 11, 4, { 9, 9, 9 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 9, false }, { 0, 0, 10, 1, false }, { 1, 1, 0, 9, false }, - { 0, 1, 10, 1, false }, { 1, 2, 0, 9, false }, { 0, 2, 10, 1, false }, - { -1 } } - }, - /* 01010 */ - { false, true, 5, 11, 3, { 4, 4, 5 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 4, false }, { 0, 0, 10, 1, false }, { 2, 2, 4, 1, false }, - { 2, 1, 0, 4, false }, { 1, 1, 0, 4, false }, { 0, 1, 10, 1, false }, - { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, - { 0, 2, 10, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 4, false }, - { 3, 2, 1, 1, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 4, false }, - { 3, 2, 4, 1, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 01011 */ - { false, true, 0, 12, 4, { 8, 8, 8 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 8, false }, { 0, 0, 10, 2, true }, { 1, 1, 0, 8, false }, - { 0, 1, 10, 2, true }, { 1, 2, 0, 8, false }, { 0, 2, 10, 2, true }, - { -1 } } - }, - /* 01110 */ - { false, true, 5, 9, 3, { 5, 5, 5 }, - { { 0, 0, 0, 9, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 9, false }, - { 2, 1, 4, 1, false }, { 0, 2, 0, 9, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, - { 1, 2, 0, 5, false }, { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 5, false }, { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, - { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 01111 */ - { false, true, 0, 16, 4, { 4, 4, 4 }, - { { 0, 0, 0, 10, false }, { 0, 1, 0, 10, false }, { 0, 2, 0, 10, false }, - { 1, 0, 0, 4, false }, { 0, 0, 10, 6, true }, { 1, 1, 0, 4, false }, - { 0, 1, 10, 6, true }, { 1, 2, 0, 4, false }, { 0, 2, 10, 6, true }, - { -1 } } - }, - /* 10010 */ - { false, true, 5, 8, 3, { 6, 5, 5 }, - { { 0, 0, 0, 8, false }, { 3, 1, 4, 1, false }, { 2, 2, 4, 1, false }, - { 0, 1, 0, 8, false }, { 3, 2, 2, 1, false }, { 2, 1, 4, 1, false }, - { 0, 2, 0, 8, false }, { 3, 2, 3, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 5, false }, - { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 6, false }, - { 3, 0, 0, 6, false }, - { -1 } } - }, - /* 10011 */ - { true /* reserved */ }, - /* 10110 */ - { false, true, 5, 8, 3, { 5, 6, 5 }, - { { 0, 0, 0, 8, false }, { 3, 2, 0, 1, false }, { 2, 2, 4, 1, false }, - { 0, 1, 0, 8, false }, { 2, 1, 5, 1, false }, { 2, 1, 4, 1, false }, - { 0, 2, 0, 8, false }, { 3, 1, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 6, false }, { 3, 1, 0, 4, false }, { 1, 2, 0, 5, false }, - { 3, 2, 1, 1, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, - { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 10111 */ - { true /* reserved */ }, - /* 11010 */ - { false, true, 5, 8, 3, { 5, 5, 6 }, - { { 0, 0, 0, 8, false }, { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, - { 0, 1, 0, 8, false }, { 2, 2, 5, 1, false }, { 2, 1, 4, 1, false }, - { 0, 2, 0, 8, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 5, false }, { 3, 1, 4, 1, false }, { 2, 1, 0, 4, false }, - { 1, 1, 0, 5, false }, { 3, 2, 0, 1, false }, { 3, 1, 0, 4, false }, - { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, { 2, 0, 0, 5, false }, - { 3, 2, 2, 1, false }, { 3, 0, 0, 5, false }, { 3, 2, 3, 1, false }, - { -1 } } - }, - /* 11011 */ - { true /* reserved */ }, - /* 11110 */ - { false, false, 5, 6, 3, { 6, 6, 6 }, - { { 0, 0, 0, 6, false }, { 3, 1, 4, 1, false }, { 3, 2, 0, 1, false }, - { 3, 2, 1, 1, false }, { 2, 2, 4, 1, false }, { 0, 1, 0, 6, false }, - { 2, 1, 5, 1, false }, { 2, 2, 5, 1, false }, { 3, 2, 2, 1, false }, - { 2, 1, 4, 1, false }, { 0, 2, 0, 6, false }, { 3, 1, 5, 1, false }, - { 3, 2, 3, 1, false }, { 3, 2, 5, 1, false }, { 3, 2, 4, 1, false }, - { 1, 0, 0, 6, false }, { 2, 1, 0, 4, false }, { 1, 1, 0, 6, false }, - { 3, 1, 0, 4, false }, { 1, 2, 0, 6, false }, { 2, 2, 0, 4, false }, - { 2, 0, 0, 6, false }, { 3, 0, 0, 6, false }, - { -1 } } - }, - /* 11111 */ - { true /* reserved */ }, -}; - -/* This partition table is used when the mode has two subsets. Each - * partition is represented by a 32-bit value which gives 2 bits per texel - * within the block. The value of the two bits represents which subset to use - * (0 or 1). - */ -static const uint32_t -partition_table1[N_PARTITIONS] = { - 0x50505050U, 0x40404040U, 0x54545454U, 0x54505040U, - 0x50404000U, 0x55545450U, 0x55545040U, 0x54504000U, - 0x50400000U, 0x55555450U, 0x55544000U, 0x54400000U, - 0x55555440U, 0x55550000U, 0x55555500U, 0x55000000U, - 0x55150100U, 0x00004054U, 0x15010000U, 0x00405054U, - 0x00004050U, 0x15050100U, 0x05010000U, 0x40505054U, - 0x00404050U, 0x05010100U, 0x14141414U, 0x05141450U, - 0x01155440U, 0x00555500U, 0x15014054U, 0x05414150U, - 0x44444444U, 0x55005500U, 0x11441144U, 0x05055050U, - 0x05500550U, 0x11114444U, 0x41144114U, 0x44111144U, - 0x15055054U, 0x01055040U, 0x05041050U, 0x05455150U, - 0x14414114U, 0x50050550U, 0x41411414U, 0x00141400U, - 0x00041504U, 0x00105410U, 0x10541000U, 0x04150400U, - 0x50410514U, 0x41051450U, 0x05415014U, 0x14054150U, - 0x41050514U, 0x41505014U, 0x40011554U, 0x54150140U, - 0x50505500U, 0x00555050U, 0x15151010U, 0x54540404U, -}; - -/* This partition table is used when the mode has three subsets. In this case - * the values can be 0, 1 or 2. - */ -static const uint32_t -partition_table2[N_PARTITIONS] = { - 0xaa685050U, 0x6a5a5040U, 0x5a5a4200U, 0x5450a0a8U, - 0xa5a50000U, 0xa0a05050U, 0x5555a0a0U, 0x5a5a5050U, - 0xaa550000U, 0xaa555500U, 0xaaaa5500U, 0x90909090U, - 0x94949494U, 0xa4a4a4a4U, 0xa9a59450U, 0x2a0a4250U, - 0xa5945040U, 0x0a425054U, 0xa5a5a500U, 0x55a0a0a0U, - 0xa8a85454U, 0x6a6a4040U, 0xa4a45000U, 0x1a1a0500U, - 0x0050a4a4U, 0xaaa59090U, 0x14696914U, 0x69691400U, - 0xa08585a0U, 0xaa821414U, 0x50a4a450U, 0x6a5a0200U, - 0xa9a58000U, 0x5090a0a8U, 0xa8a09050U, 0x24242424U, - 0x00aa5500U, 0x24924924U, 0x24499224U, 0x50a50a50U, - 0x500aa550U, 0xaaaa4444U, 0x66660000U, 0xa5a0a5a0U, - 0x50a050a0U, 0x69286928U, 0x44aaaa44U, 0x66666600U, - 0xaa444444U, 0x54a854a8U, 0x95809580U, 0x96969600U, - 0xa85454a8U, 0x80959580U, 0xaa141414U, 0x96960000U, - 0xaaaa1414U, 0xa05050a0U, 0xa0a5a5a0U, 0x96000000U, - 0x40804080U, 0xa9a8a9a8U, 0xaaaaaa44U, 0x2a4a5254U -}; - -static const uint8_t -anchor_indices[][N_PARTITIONS] = { - /* Anchor index values for the second subset of two-subset partitioning */ - { - 0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf, - 0xf,0x2,0x8,0x2,0x2,0x8,0x8,0xf,0x2,0x8,0x2,0x2,0x8,0x8,0x2,0x2, - 0xf,0xf,0x6,0x8,0x2,0x8,0xf,0xf,0x2,0x8,0x2,0x2,0x2,0xf,0xf,0x6, - 0x6,0x2,0x6,0x8,0xf,0xf,0x2,0x2,0xf,0xf,0xf,0xf,0xf,0x2,0x2,0xf - }, - - /* Anchor index values for the second subset of three-subset partitioning */ - { - 0x3,0x3,0xf,0xf,0x8,0x3,0xf,0xf,0x8,0x8,0x6,0x6,0x6,0x5,0x3,0x3, - 0x3,0x3,0x8,0xf,0x3,0x3,0x6,0xa,0x5,0x8,0x8,0x6,0x8,0x5,0xf,0xf, - 0x8,0xf,0x3,0x5,0x6,0xa,0x8,0xf,0xf,0x3,0xf,0x5,0xf,0xf,0xf,0xf, - 0x3,0xf,0x5,0x5,0x5,0x8,0x5,0xa,0x5,0xa,0x8,0xd,0xf,0xc,0x3,0x3 - }, - - /* Anchor index values for the third subset of three-subset - * partitioning - */ - { - 0xf,0x8,0x8,0x3,0xf,0xf,0x3,0x8,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x8, - 0xf,0x8,0xf,0x3,0xf,0x8,0xf,0x8,0x3,0xf,0x6,0xa,0xf,0xf,0xa,0x8, - 0xf,0x3,0xf,0xa,0xa,0x8,0x9,0xa,0x6,0xf,0x8,0xf,0x3,0x6,0x6,0x8, - 0xf,0x3,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0xf,0x3,0xf,0xf,0x8 - } -}; - -static int -extract_bits(const uint8_t *block, - int offset, - int n_bits) -{ - int byte_index = offset / 8; - int bit_index = offset % 8; - int n_bits_in_byte = MIN2(n_bits, 8 - bit_index); - int result = 0; - int bit = 0; - - while (true) { - result |= ((block[byte_index] >> bit_index) & - ((1 << n_bits_in_byte) - 1)) << bit; - - n_bits -= n_bits_in_byte; - - if (n_bits <= 0) - return result; - - bit += n_bits_in_byte; - byte_index++; - bit_index = 0; - n_bits_in_byte = MIN2(n_bits, 8); - } -} - -static uint8_t -expand_component(uint8_t byte, - int n_bits) -{ - /* Expands a n-bit quantity into a byte by copying the most-significant - * bits into the unused least-significant bits. - */ - return byte << (8 - n_bits) | (byte >> (2 * n_bits - 8)); -} - -static int -extract_unorm_endpoints(const struct bptc_unorm_mode *mode, - const uint8_t *block, - int bit_offset, - uint8_t endpoints[][4]) -{ - int component; - int subset; - int endpoint; - int pbit; - int n_components; - - /* Extract each color component */ - for (component = 0; component < 3; component++) { - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoints[subset * 2 + endpoint][component] = - extract_bits(block, bit_offset, mode->n_color_bits); - bit_offset += mode->n_color_bits; - } - } - } - - /* Extract the alpha values */ - if (mode->n_alpha_bits > 0) { - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoints[subset * 2 + endpoint][3] = - extract_bits(block, bit_offset, mode->n_alpha_bits); - bit_offset += mode->n_alpha_bits; - } - } - - n_components = 4; - } else { - for (subset = 0; subset < mode->n_subsets; subset++) - for (endpoint = 0; endpoint < 2; endpoint++) - endpoints[subset * 2 + endpoint][3] = 255; - - n_components = 3; - } - - /* Add in the p-bits */ - if (mode->has_endpoint_pbits) { - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - pbit = extract_bits(block, bit_offset, 1); - bit_offset += 1; - - for (component = 0; component < n_components; component++) { - endpoints[subset * 2 + endpoint][component] <<= 1; - endpoints[subset * 2 + endpoint][component] |= pbit; - } - } - } - } else if (mode->has_shared_pbits) { - for (subset = 0; subset < mode->n_subsets; subset++) { - pbit = extract_bits(block, bit_offset, 1); - bit_offset += 1; - - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < n_components; component++) { - endpoints[subset * 2 + endpoint][component] <<= 1; - endpoints[subset * 2 + endpoint][component] |= pbit; - } - } - } - } - - /* Expand the n-bit values to a byte */ - for (subset = 0; subset < mode->n_subsets; subset++) { - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < 3; component++) { - endpoints[subset * 2 + endpoint][component] = - expand_component(endpoints[subset * 2 + endpoint][component], - mode->n_color_bits + - mode->has_endpoint_pbits + - mode->has_shared_pbits); - } - - if (mode->n_alpha_bits > 0) { - endpoints[subset * 2 + endpoint][3] = - expand_component(endpoints[subset * 2 + endpoint][3], - mode->n_alpha_bits + - mode->has_endpoint_pbits + - mode->has_shared_pbits); - } - } - } - - return bit_offset; -} - -static bool -is_anchor(int n_subsets, - int partition_num, - int texel) -{ - if (texel == 0) - return true; - - switch (n_subsets) { - case 1: - return false; - case 2: - return anchor_indices[0][partition_num] == texel; - case 3: - return (anchor_indices[1][partition_num] == texel || - anchor_indices[2][partition_num] == texel); - default: - assert(false); - return false; - } -} - -static int -count_anchors_before_texel(int n_subsets, - int partition_num, - int texel) -{ - int count = 1; - - if (texel == 0) - return 0; - - switch (n_subsets) { - case 1: - break; - case 2: - if (texel > anchor_indices[0][partition_num]) - count++; - break; - case 3: - if (texel > anchor_indices[1][partition_num]) - count++; - if (texel > anchor_indices[2][partition_num]) - count++; - break; - default: - assert(false); - return 0; - } - - return count; -} - -static int32_t -interpolate(int32_t a, int32_t b, - int index, - int index_bits) -{ - static const uint8_t weights2[] = { 0, 21, 43, 64 }; - static const uint8_t weights3[] = { 0, 9, 18, 27, 37, 46, 55, 64 }; - static const uint8_t weights4[] = - { 0, 4, 9, 13, 17, 21, 26, 30, 34, 38, 43, 47, 51, 55, 60, 64 }; - static const uint8_t *weights[] = { - NULL, NULL, weights2, weights3, weights4 - }; - int weight; - - weight = weights[index_bits][index]; - - return ((64 - weight) * a + weight * b + 32) >> 6; -} - -static void -apply_rotation(int rotation, - uint8_t *result) -{ - uint8_t t; - - if (rotation == 0) - return; - - rotation--; - - t = result[rotation]; - result[rotation] = result[3]; - result[3] = t; -} - -static void -fetch_rgba_unorm_from_block(const uint8_t *block, - uint8_t *result, - int texel) -{ - int mode_num = ffs(block[0]); - const struct bptc_unorm_mode *mode; - int bit_offset, secondary_bit_offset; - int partition_num; - int subset_num; - int rotation; - int index_selection; - int index_bits; - int indices[2]; - int index; - int anchors_before_texel; - bool anchor; - uint8_t endpoints[3 * 2][4]; - uint32_t subsets; - int component; - - if (mode_num == 0) { - /* According to the spec this mode is reserved and shouldn't be used. */ - memset(result, 0, 4); - return; - } - - mode = bptc_unorm_modes + mode_num - 1; - bit_offset = mode_num; - - partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); - bit_offset += mode->n_partition_bits; - - switch (mode->n_subsets) { - case 1: - subsets = 0; - break; - case 2: - subsets = partition_table1[partition_num]; - break; - case 3: - subsets = partition_table2[partition_num]; - break; - default: - assert(false); - return; - } - - if (mode->has_rotation_bits) { - rotation = extract_bits(block, bit_offset, 2); - bit_offset += 2; - } else { - rotation = 0; - } - - if (mode->has_index_selection_bit) { - index_selection = extract_bits(block, bit_offset, 1); - bit_offset++; - } else { - index_selection = 0; - } - - bit_offset = extract_unorm_endpoints(mode, block, bit_offset, endpoints); - - anchors_before_texel = count_anchors_before_texel(mode->n_subsets, - partition_num, texel); - - /* Calculate the offset to the secondary index */ - secondary_bit_offset = (bit_offset + - BLOCK_SIZE * BLOCK_SIZE * mode->n_index_bits - - mode->n_subsets + - mode->n_secondary_index_bits * texel - - anchors_before_texel); - - /* Calculate the offset to the primary index for this texel */ - bit_offset += mode->n_index_bits * texel - anchors_before_texel; - - subset_num = (subsets >> (texel * 2)) & 3; - - anchor = is_anchor(mode->n_subsets, partition_num, texel); - - index_bits = mode->n_index_bits; - if (anchor) - index_bits--; - indices[0] = extract_bits(block, bit_offset, index_bits); - - if (mode->n_secondary_index_bits) { - index_bits = mode->n_secondary_index_bits; - if (anchor) - index_bits--; - indices[1] = extract_bits(block, secondary_bit_offset, index_bits); - } - - index = indices[index_selection]; - index_bits = (index_selection ? - mode->n_secondary_index_bits : - mode->n_index_bits); - - for (component = 0; component < 3; component++) - result[component] = interpolate(endpoints[subset_num * 2][component], - endpoints[subset_num * 2 + 1][component], - index, - index_bits); - - /* Alpha uses the opposite index from the color components */ - if (mode->n_secondary_index_bits && !index_selection) { - index = indices[1]; - index_bits = mode->n_secondary_index_bits; - } else { - index = indices[0]; - index_bits = mode->n_index_bits; - } - - result[3] = interpolate(endpoints[subset_num * 2][3], - endpoints[subset_num * 2 + 1][3], - index, - index_bits); - - apply_rotation(rotation, result); -} - -#ifdef BPTC_BLOCK_DECODE -static void -decompress_rgba_unorm_block(int src_width, int src_height, - const uint8_t *block, - uint8_t *dst_row, int dst_rowstride) -{ - int mode_num = ffs(block[0]); - const struct bptc_unorm_mode *mode; - int bit_offset_head, bit_offset, secondary_bit_offset; - int partition_num; - int subset_num; - int rotation; - int index_selection; - int index_bits; - int indices[2]; - int index; - int anchors_before_texel; - bool anchor; - uint8_t endpoints[3 * 2][4]; - uint32_t subsets; - int component; - unsigned x, y; - - if (mode_num == 0) { - /* According to the spec this mode is reserved and shouldn't be used. */ - for(y = 0; y < src_height; y += 1) { - uint8_t *result = dst_row; - memset(result, 0, 4 * src_width); - dst_row += dst_rowstride; - } - return; - } - - mode = bptc_unorm_modes + mode_num - 1; - bit_offset_head = mode_num; - - partition_num = extract_bits(block, bit_offset_head, mode->n_partition_bits); - bit_offset_head += mode->n_partition_bits; - - switch (mode->n_subsets) { - case 1: - subsets = 0; - break; - case 2: - subsets = partition_table1[partition_num]; - break; - case 3: - subsets = partition_table2[partition_num]; - break; - default: - assert(false); - return; - } - - if (mode->has_rotation_bits) { - rotation = extract_bits(block, bit_offset_head, 2); - bit_offset_head += 2; - } else { - rotation = 0; - } - - if (mode->has_index_selection_bit) { - index_selection = extract_bits(block, bit_offset_head, 1); - bit_offset_head++; - } else { - index_selection = 0; - } - - bit_offset_head = extract_unorm_endpoints(mode, block, bit_offset_head, endpoints); - - for(y = 0; y < src_height; y += 1) { - uint8_t *result = dst_row; - for(x = 0; x < src_width; x += 1) { - int texel; - texel = x + y * 4; - bit_offset = bit_offset_head; - - anchors_before_texel = count_anchors_before_texel(mode->n_subsets, - partition_num, - texel); - - /* Calculate the offset to the secondary index */ - secondary_bit_offset = (bit_offset + - BLOCK_SIZE * BLOCK_SIZE * mode->n_index_bits - - mode->n_subsets + - mode->n_secondary_index_bits * texel - - anchors_before_texel); - - /* Calculate the offset to the primary index for this texel */ - bit_offset += mode->n_index_bits * texel - anchors_before_texel; - - subset_num = (subsets >> (texel * 2)) & 3; - - anchor = is_anchor(mode->n_subsets, partition_num, texel); - - index_bits = mode->n_index_bits; - if (anchor) - index_bits--; - indices[0] = extract_bits(block, bit_offset, index_bits); - - if (mode->n_secondary_index_bits) { - index_bits = mode->n_secondary_index_bits; - if (anchor) - index_bits--; - indices[1] = extract_bits(block, secondary_bit_offset, index_bits); - } - - index = indices[index_selection]; - index_bits = (index_selection ? - mode->n_secondary_index_bits : - mode->n_index_bits); - - for (component = 0; component < 3; component++) - result[component] = interpolate(endpoints[subset_num * 2][component], - endpoints[subset_num * 2 + 1][component], - index, - index_bits); - - /* Alpha uses the opposite index from the color components */ - if (mode->n_secondary_index_bits && !index_selection) { - index = indices[1]; - index_bits = mode->n_secondary_index_bits; - } else { - index = indices[0]; - index_bits = mode->n_index_bits; - } - - result[3] = interpolate(endpoints[subset_num * 2][3], - endpoints[subset_num * 2 + 1][3], - index, - index_bits); - - apply_rotation(rotation, result); - result += 4; - } - dst_row += dst_rowstride; - } -} - -static void -decompress_rgba_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - uint8_t *dst, int dst_rowstride) -{ - int src_row_diff; - int y, x; - - if (src_rowstride >= width * 4) - src_row_diff = src_rowstride - ((width + 3) & ~3) * 4; - else - src_row_diff = 0; - - for (y = 0; y < height; y += BLOCK_SIZE) { - for (x = 0; x < width; x += BLOCK_SIZE) { - decompress_rgba_unorm_block(MIN2(width - x, BLOCK_SIZE), - MIN2(height - y, BLOCK_SIZE), - src, - dst + x * 4 + y * dst_rowstride, - dst_rowstride); - src += BLOCK_BYTES; - } - src += src_row_diff; - } -} -#endif // BPTC_BLOCK_DECODE - -static int32_t -sign_extend(int32_t value, - int n_bits) -{ - assert(n_bits > 0 && n_bits < 32); - - const unsigned n = 32 - n_bits; - return (int32_t)((uint32_t)value << n) >> n; -} - -static int -signed_unquantize(int value, int n_endpoint_bits) -{ - bool sign; - - if (n_endpoint_bits >= 16) - return value; - - if (value == 0) - return 0; - - sign = false; - - if (value < 0) { - sign = true; - value = -value; - } - - if (value >= (1 << (n_endpoint_bits - 1)) - 1) - value = 0x7fff; - else - value = ((value << 15) + 0x4000) >> (n_endpoint_bits - 1); - - if (sign) - value = -value; - - return value; -} - -static int -unsigned_unquantize(int value, int n_endpoint_bits) -{ - if (n_endpoint_bits >= 15) - return value; - - if (value == 0) - return 0; - - if (value == (1 << n_endpoint_bits) - 1) - return 0xffff; - - return ((value << 15) + 0x4000) >> (n_endpoint_bits - 1); -} - -static int -extract_float_endpoints(const struct bptc_float_mode *mode, - const uint8_t *block, - int bit_offset, - int32_t endpoints[][3], - bool is_signed) -{ - const struct bptc_float_bitfield *bitfield; - int endpoint, component; - int n_endpoints; - int value; - int i; - - if (mode->n_partition_bits) - n_endpoints = 4; - else - n_endpoints = 2; - - memset(endpoints, 0, sizeof endpoints[0][0] * n_endpoints * 3); - - for (bitfield = mode->bitfields; bitfield->endpoint != -1; bitfield++) { - value = extract_bits(block, bit_offset, bitfield->n_bits); - bit_offset += bitfield->n_bits; - - if (bitfield->reverse) { - for (i = 0; i < bitfield->n_bits; i++) { - if (value & (1 << i)) - endpoints[bitfield->endpoint][bitfield->component] |= - 1 << ((bitfield->n_bits - 1 - i) + bitfield->offset); - } - } else { - endpoints[bitfield->endpoint][bitfield->component] |= - value << bitfield->offset; - } - } - - if (mode->transformed_endpoints) { - /* The endpoints are specified as signed offsets from e0 */ - for (endpoint = 1; endpoint < n_endpoints; endpoint++) { - for (component = 0; component < 3; component++) { - value = sign_extend(endpoints[endpoint][component], - mode->n_delta_bits[component]); - endpoints[endpoint][component] = - ((endpoints[0][component] + value) & - ((1 << mode->n_endpoint_bits) - 1)); - } - } - } - - if (is_signed) { - for (endpoint = 0; endpoint < n_endpoints; endpoint++) { - for (component = 0; component < 3; component++) { - value = sign_extend(endpoints[endpoint][component], - mode->n_endpoint_bits); - endpoints[endpoint][component] = - signed_unquantize(value, mode->n_endpoint_bits); - } - } - } else { - for (endpoint = 0; endpoint < n_endpoints; endpoint++) { - for (component = 0; component < 3; component++) { - endpoints[endpoint][component] = - unsigned_unquantize(endpoints[endpoint][component], - mode->n_endpoint_bits); - } - } - } - - return bit_offset; -} - -static int32_t -finish_unsigned_unquantize(int32_t value) -{ - return value * 31 / 64; -} - -static int32_t -finish_signed_unquantize(int32_t value) -{ - if (value < 0) - return (-value * 31 / 32) | 0x8000; - else - return value * 31 / 32; -} - -static void -fetch_rgb_float_from_block(const uint8_t *block, - float *result, - int texel, - bool is_signed) -{ - int mode_num; - const struct bptc_float_mode *mode; - int bit_offset; - int partition_num; - int subset_num; - int index_bits; - int index; - int anchors_before_texel; - int32_t endpoints[2 * 2][3]; - uint32_t subsets; - int n_subsets; - int component; - int32_t value; - - if (block[0] & 0x2) { - mode_num = (((block[0] >> 1) & 0xe) | (block[0] & 1)) + 2; - bit_offset = 5; - } else { - mode_num = block[0] & 3; - bit_offset = 2; - } - - mode = bptc_float_modes + mode_num; - - if (mode->reserved) { - memset(result, 0, sizeof result[0] * 3); - result[3] = 1.0f; - return; - } - - bit_offset = extract_float_endpoints(mode, block, bit_offset, - endpoints, is_signed); - - if (mode->n_partition_bits) { - partition_num = extract_bits(block, bit_offset, mode->n_partition_bits); - bit_offset += mode->n_partition_bits; - - subsets = partition_table1[partition_num]; - n_subsets = 2; - } else { - partition_num = 0; - subsets = 0; - n_subsets = 1; - } - - anchors_before_texel = - count_anchors_before_texel(n_subsets, partition_num, texel); - - /* Calculate the offset to the primary index for this texel */ - bit_offset += mode->n_index_bits * texel - anchors_before_texel; - - subset_num = (subsets >> (texel * 2)) & 3; - - index_bits = mode->n_index_bits; - if (is_anchor(n_subsets, partition_num, texel)) - index_bits--; - index = extract_bits(block, bit_offset, index_bits); - - for (component = 0; component < 3; component++) { - value = interpolate(endpoints[subset_num * 2][component], - endpoints[subset_num * 2 + 1][component], - index, - mode->n_index_bits); - - if (is_signed) - value = finish_signed_unquantize(value); - else - value = finish_unsigned_unquantize(value); - - result[component] = _mesa_half_to_float(value); - } - - result[3] = 1.0f; -} - -#ifdef BPTC_BLOCK_DECODE -static void -decompress_rgb_float_block(unsigned src_width, unsigned src_height, - const uint8_t *block, - float *dst_row, unsigned dst_rowstride, - bool is_signed) -{ - int mode_num; - const struct bptc_float_mode *mode; - int bit_offset_head, bit_offset; - int partition_num; - int subset_num; - int index_bits; - int index; - int anchors_before_texel; - int32_t endpoints[2 * 2][3]; - uint32_t subsets; - int n_subsets; - int component; - int32_t value; - unsigned x, y; - - if (block[0] & 0x2) { - mode_num = (((block[0] >> 1) & 0xe) | (block[0] & 1)) + 2; - bit_offset_head = 5; - } else { - mode_num = block[0] & 3; - bit_offset_head = 2; - } - - mode = bptc_float_modes + mode_num; - - if (mode->reserved) { - for(y = 0; y < src_height; y += 1) { - float *result = dst_row; - memset(result, 0, sizeof result[0] * 4 * src_width); - for(x = 0; x < src_width; x += 1) { - result[3] = 1.0f; - result += 4; - } - dst_row += dst_rowstride / sizeof dst_row[0]; - } - return; - } - - bit_offset_head = extract_float_endpoints(mode, block, bit_offset_head, - endpoints, is_signed); - - if (mode->n_partition_bits) { - partition_num = extract_bits(block, bit_offset_head, mode->n_partition_bits); - bit_offset_head += mode->n_partition_bits; - - subsets = partition_table1[partition_num]; - n_subsets = 2; - } else { - partition_num = 0; - subsets = 0; - n_subsets = 1; - } - - for(y = 0; y < src_height; y += 1) { - float *result = dst_row; - for(x = 0; x < src_width; x += 1) { - int texel; - - bit_offset = bit_offset_head; - - texel = x + y * 4; - - anchors_before_texel = - count_anchors_before_texel(n_subsets, partition_num, texel); - - /* Calculate the offset to the primary index for this texel */ - bit_offset += mode->n_index_bits * texel - anchors_before_texel; - - subset_num = (subsets >> (texel * 2)) & 3; - - index_bits = mode->n_index_bits; - if (is_anchor(n_subsets, partition_num, texel)) - index_bits--; - index = extract_bits(block, bit_offset, index_bits); - - for (component = 0; component < 3; component++) { - value = interpolate(endpoints[subset_num * 2][component], - endpoints[subset_num * 2 + 1][component], - index, - mode->n_index_bits); - - if (is_signed) - value = finish_signed_unquantize(value); - else - value = finish_unsigned_unquantize(value); - - result[component] = _mesa_half_to_float(value); - } - - result[3] = 1.0f; - result += 4; - } - dst_row += dst_rowstride / sizeof dst_row[0]; - } -} - -static void -decompress_rgb_float(int width, int height, - const uint8_t *src, int src_rowstride, - float *dst, int dst_rowstride, bool is_signed) -{ - int src_row_diff; - int y, x; - - if (src_rowstride >= width * 4) - src_row_diff = src_rowstride - ((width + 3) & ~3) * 4; - else - src_row_diff = 0; - - for (y = 0; y < height; y += BLOCK_SIZE) { - for (x = 0; x < width; x += BLOCK_SIZE) { - decompress_rgb_float_block(MIN2(width - x, BLOCK_SIZE), - MIN2(height - y, BLOCK_SIZE), - src, - (dst + x * 4 + - (y * dst_rowstride / sizeof dst[0])), - dst_rowstride, is_signed); - src += BLOCK_BYTES; - } - src += src_row_diff; - } -} -#endif // BPTC_BLOCK_DECODE - -static void -write_bits(struct bit_writer *writer, int n_bits, int value) -{ - do { - if (n_bits + writer->pos >= 8) { - *(writer->dst++) = writer->buf | (value << writer->pos); - writer->buf = 0; - value >>= (8 - writer->pos); - n_bits -= (8 - writer->pos); - writer->pos = 0; - } else { - writer->buf |= value << writer->pos; - writer->pos += n_bits; - break; - } - } while (n_bits > 0); -} - -static void -get_average_luminance_alpha_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - int *average_luminance, int *average_alpha) -{ - int luminance_sum = 0, alpha_sum = 0; - int y, x; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance_sum += src[0] + src[1] + src[2]; - alpha_sum += src[3]; - src += 4; - } - src += src_rowstride - width * 4; - } - - *average_luminance = luminance_sum / (width * height); - *average_alpha = alpha_sum / (width * height); -} - -static void -get_rgba_endpoints_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - int average_luminance, int average_alpha, - uint8_t endpoints[][4]) -{ - int endpoint_luminances[2]; - int midpoint; - int sums[2][4]; - int endpoint; - int luminance; - uint8_t temp[3]; - const uint8_t *p = src; - int rgb_left_endpoint_count = 0; - int alpha_left_endpoint_count = 0; - int y, x, i; - - memset(sums, 0, sizeof sums); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance = p[0] + p[1] + p[2]; - if (luminance < average_luminance) { - endpoint = 0; - rgb_left_endpoint_count++; - } else { - endpoint = 1; - } - for (i = 0; i < 3; i++) - sums[endpoint][i] += p[i]; - - if (p[2] < average_alpha) { - endpoint = 0; - alpha_left_endpoint_count++; - } else { - endpoint = 1; - } - sums[endpoint][3] += p[3]; - - p += 4; - } - - p += src_rowstride - width * 4; - } - - if (rgb_left_endpoint_count == 0 || - rgb_left_endpoint_count == width * height) { - for (i = 0; i < 3; i++) - endpoints[0][i] = endpoints[1][i] = - (sums[0][i] + sums[1][i]) / (width * height); - } else { - for (i = 0; i < 3; i++) { - endpoints[0][i] = sums[0][i] / rgb_left_endpoint_count; - endpoints[1][i] = (sums[1][i] / - (width * height - rgb_left_endpoint_count)); - } - } - - if (alpha_left_endpoint_count == 0 || - alpha_left_endpoint_count == width * height) { - endpoints[0][3] = endpoints[1][3] = - (sums[0][3] + sums[1][3]) / (width * height); - } else { - endpoints[0][3] = sums[0][3] / alpha_left_endpoint_count; - endpoints[1][3] = (sums[1][3] / - (width * height - alpha_left_endpoint_count)); - } - - /* We may need to swap the endpoints to ensure the most-significant bit of - * the first index is zero */ - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - midpoint = (endpoint_luminances[0] + endpoint_luminances[1]) / 2; - - if ((src[0] + src[1] + src[2] <= midpoint) != - (endpoint_luminances[0] <= midpoint)) { - memcpy(temp, endpoints[0], 3); - memcpy(endpoints[0], endpoints[1], 3); - memcpy(endpoints[1], temp, 3); - } - - /* Same for the alpha endpoints */ - - midpoint = (endpoints[0][3] + endpoints[1][3]) / 2; - - if ((src[3] <= midpoint) != (endpoints[0][3] <= midpoint)) { - temp[0] = endpoints[0][3]; - endpoints[0][3] = endpoints[1][3]; - endpoints[1][3] = temp[0]; - } -} - -static void -write_rgb_indices_unorm(struct bit_writer *writer, - int src_width, int src_height, - const uint8_t *src, int src_rowstride, - uint8_t endpoints[][4]) -{ - int luminance; - int endpoint_luminances[2]; - int endpoint; - int index; - int y, x; - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - - /* If the endpoints have the same luminance then we'll just use index 0 for - * all of the texels */ - if (endpoint_luminances[0] == endpoint_luminances[1]) { - write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 2 - 1, 0); - return; - } - - for (y = 0; y < src_height; y++) { - for (x = 0; x < src_width; x++) { - luminance = src[0] + src[1] + src[2]; - - index = ((luminance - endpoint_luminances[0]) * 3 / - (endpoint_luminances[1] - endpoint_luminances[0])); - if (index < 0) - index = 0; - else if (index > 3) - index = 3; - - assert(x != 0 || y != 0 || index < 2); - - write_bits(writer, (x == 0 && y == 0) ? 1 : 2, index); - - src += 4; - } - - /* Pad the indices out to the block size */ - if (src_width < BLOCK_SIZE) - write_bits(writer, 2 * (BLOCK_SIZE - src_width), 0); - - src += src_rowstride - src_width * 4; - } - - /* Pad the indices out to the block size */ - if (src_height < BLOCK_SIZE) - write_bits(writer, 2 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); -} - -static void -write_alpha_indices_unorm(struct bit_writer *writer, - int src_width, int src_height, - const uint8_t *src, int src_rowstride, - uint8_t endpoints[][4]) -{ - int index; - int y, x; - - /* If the endpoints have the same alpha then we'll just use index 0 for - * all of the texels */ - if (endpoints[0][3] == endpoints[1][3]) { - write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 3 - 1, 0); - return; - } - - for (y = 0; y < src_height; y++) { - for (x = 0; x < src_width; x++) { - index = (((int) src[3] - (int) endpoints[0][3]) * 7 / - ((int) endpoints[1][3] - endpoints[0][3])); - if (index < 0) - index = 0; - else if (index > 7) - index = 7; - - assert(x != 0 || y != 0 || index < 4); - - /* The first index has one less bit */ - write_bits(writer, (x == 0 && y == 0) ? 2 : 3, index); - - src += 4; - } - - /* Pad the indices out to the block size */ - if (src_width < BLOCK_SIZE) - write_bits(writer, 3 * (BLOCK_SIZE - src_width), 0); - - src += src_rowstride - src_width * 4; - } - - /* Pad the indices out to the block size */ - if (src_height < BLOCK_SIZE) - write_bits(writer, 3 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); -} - -static void -compress_rgba_unorm_block(int src_width, int src_height, - const uint8_t *src, int src_rowstride, - uint8_t *dst) -{ - int average_luminance, average_alpha; - uint8_t endpoints[2][4]; - struct bit_writer writer; - int component, endpoint; - - get_average_luminance_alpha_unorm(src_width, src_height, src, src_rowstride, - &average_luminance, &average_alpha); - get_rgba_endpoints_unorm(src_width, src_height, src, src_rowstride, - average_luminance, average_alpha, - endpoints); - - writer.dst = dst; - writer.pos = 0; - writer.buf = 0; - - write_bits(&writer, 5, 0x10); /* mode 4 */ - write_bits(&writer, 2, 0); /* rotation 0 */ - write_bits(&writer, 1, 0); /* index selection bit */ - - /* Write the color endpoints */ - for (component = 0; component < 3; component++) - for (endpoint = 0; endpoint < 2; endpoint++) - write_bits(&writer, 5, endpoints[endpoint][component] >> 3); - - /* Write the alpha endpoints */ - for (endpoint = 0; endpoint < 2; endpoint++) - write_bits(&writer, 6, endpoints[endpoint][3] >> 2); - - write_rgb_indices_unorm(&writer, - src_width, src_height, - src, src_rowstride, - endpoints); - write_alpha_indices_unorm(&writer, - src_width, src_height, - src, src_rowstride, - endpoints); -} - -static void -compress_rgba_unorm(int width, int height, - const uint8_t *src, int src_rowstride, - uint8_t *dst, int dst_rowstride) -{ - int dst_row_diff; - int y, x; - - if (dst_rowstride >= width * 4) - dst_row_diff = dst_rowstride - ((width + 3) & ~3) * 4; - else - dst_row_diff = 0; - - for (y = 0; y < height; y += BLOCK_SIZE) { - for (x = 0; x < width; x += BLOCK_SIZE) { - compress_rgba_unorm_block(MIN2(width - x, BLOCK_SIZE), - MIN2(height - y, BLOCK_SIZE), - src + x * 4 + y * src_rowstride, - src_rowstride, - dst); - dst += BLOCK_BYTES; - } - dst += dst_row_diff; - } -} - -static float -get_average_luminance_float(int width, int height, - const float *src, int src_rowstride) -{ - float luminance_sum = 0; - int y, x; - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance_sum += src[0] + src[1] + src[2]; - src += 3; - } - src += (src_rowstride - width * 3 * sizeof (float)) / sizeof (float); - } - - return luminance_sum / (width * height); -} - -static float -clamp_value(float value, bool is_signed) -{ - if (value > 65504.0f) - return 65504.0f; - - if (is_signed) { - if (value < -65504.0f) - return -65504.0f; - else - return value; - } - - if (value < 0.0f) - return 0.0f; - - return value; -} - -static void -get_endpoints_float(int width, int height, - const float *src, int src_rowstride, - float average_luminance, float endpoints[][3], - bool is_signed) -{ - float endpoint_luminances[2]; - float midpoint; - float sums[2][3]; - int endpoint, component; - float luminance; - float temp[3]; - const float *p = src; - int left_endpoint_count = 0; - int y, x, i; - - memset(sums, 0, sizeof sums); - - for (y = 0; y < height; y++) { - for (x = 0; x < width; x++) { - luminance = p[0] + p[1] + p[2]; - if (luminance < average_luminance) { - endpoint = 0; - left_endpoint_count++; - } else { - endpoint = 1; - } - for (i = 0; i < 3; i++) - sums[endpoint][i] += p[i]; - - p += 3; - } - - p += (src_rowstride - width * 3 * sizeof (float)) / sizeof (float); - } - - if (left_endpoint_count == 0 || - left_endpoint_count == width * height) { - for (i = 0; i < 3; i++) - endpoints[0][i] = endpoints[1][i] = - (sums[0][i] + sums[1][i]) / (width * height); - } else { - for (i = 0; i < 3; i++) { - endpoints[0][i] = sums[0][i] / left_endpoint_count; - endpoints[1][i] = sums[1][i] / (width * height - left_endpoint_count); - } - } - - /* Clamp the endpoints to the range of a half float and strip out - * infinities */ - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < 3; component++) { - endpoints[endpoint][component] = - clamp_value(endpoints[endpoint][component], is_signed); - } - } - - /* We may need to swap the endpoints to ensure the most-significant bit of - * the first index is zero */ - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - midpoint = (endpoint_luminances[0] + endpoint_luminances[1]) / 2.0f; - - if ((src[0] + src[1] + src[2] <= midpoint) != - (endpoint_luminances[0] <= midpoint)) { - memcpy(temp, endpoints[0], sizeof temp); - memcpy(endpoints[0], endpoints[1], sizeof temp); - memcpy(endpoints[1], temp, sizeof temp); - } -} - -static void -write_rgb_indices_float(struct bit_writer *writer, - int src_width, int src_height, - const float *src, int src_rowstride, - float endpoints[][3]) -{ - float luminance; - float endpoint_luminances[2]; - int endpoint; - int index; - int y, x; - - for (endpoint = 0; endpoint < 2; endpoint++) { - endpoint_luminances[endpoint] = - endpoints[endpoint][0] + - endpoints[endpoint][1] + - endpoints[endpoint][2]; - } - - /* If the endpoints have the same luminance then we'll just use index 0 for - * all of the texels */ - if (endpoint_luminances[0] == endpoint_luminances[1]) { - write_bits(writer, BLOCK_SIZE * BLOCK_SIZE * 4 - 1, 0); - return; - } - - for (y = 0; y < src_height; y++) { - for (x = 0; x < src_width; x++) { - luminance = src[0] + src[1] + src[2]; - - index = ((luminance - endpoint_luminances[0]) * 15 / - (endpoint_luminances[1] - endpoint_luminances[0])); - if (index < 0) - index = 0; - else if (index > 15) - index = 15; - - assert(x != 0 || y != 0 || index < 8); - - write_bits(writer, (x == 0 && y == 0) ? 3 : 4, index); - - src += 3; - } - - /* Pad the indices out to the block size */ - if (src_width < BLOCK_SIZE) - write_bits(writer, 4 * (BLOCK_SIZE - src_width), 0); - - src += (src_rowstride - src_width * 3 * sizeof (float)) / sizeof (float); - } - - /* Pad the indices out to the block size */ - if (src_height < BLOCK_SIZE) - write_bits(writer, 4 * BLOCK_SIZE * (BLOCK_SIZE - src_height), 0); -} - -static int -get_endpoint_value(float value, bool is_signed) -{ - bool sign = false; - int half; - - if (is_signed) { - half = _mesa_float_to_half(value); - - if (half & 0x8000) { - half &= 0x7fff; - sign = true; - } - - half = (32 * half / 31) >> 6; - - if (sign) - half = -half & ((1 << 10) - 1); - - return half; - } else { - if (value <= 0.0f) - return 0; - - half = _mesa_float_to_half(value); - - return (64 * half / 31) >> 6; - } -} - -static void -compress_rgb_float_block(int src_width, int src_height, - const float *src, int src_rowstride, - uint8_t *dst, - bool is_signed) -{ - float average_luminance; - float endpoints[2][3]; - struct bit_writer writer; - int component, endpoint; - int endpoint_value; - - average_luminance = - get_average_luminance_float(src_width, src_height, src, src_rowstride); - get_endpoints_float(src_width, src_height, src, src_rowstride, - average_luminance, endpoints, is_signed); - - writer.dst = dst; - writer.pos = 0; - writer.buf = 0; - - write_bits(&writer, 5, 3); /* mode 3 */ - - /* Write the endpoints */ - for (endpoint = 0; endpoint < 2; endpoint++) { - for (component = 0; component < 3; component++) { - endpoint_value = - get_endpoint_value(endpoints[endpoint][component], is_signed); - write_bits(&writer, 10, endpoint_value); - } - } - - write_rgb_indices_float(&writer, - src_width, src_height, - src, src_rowstride, - endpoints); -} - -static void -compress_rgb_float(int width, int height, - const float *src, int src_rowstride, - uint8_t *dst, int dst_rowstride, - bool is_signed) -{ - int dst_row_diff; - int y, x; - - if (dst_rowstride >= width * 4) - dst_row_diff = dst_rowstride - ((width + 3) & ~3) * 4; - else - dst_row_diff = 0; - - for (y = 0; y < height; y += BLOCK_SIZE) { - for (x = 0; x < width; x += BLOCK_SIZE) { - compress_rgb_float_block(MIN2(width - x, BLOCK_SIZE), - MIN2(height - y, BLOCK_SIZE), - src + x * 3 + - y * src_rowstride / sizeof (float), - src_rowstride, - dst, - is_signed); - dst += BLOCK_BYTES; - } - dst += dst_row_diff; - } -} - -#endif diff --git a/src/mesa/main/texcompress_cpal.c b/src/mesa/main/texcompress_cpal.c index 76f3cd9bfb4..0db3bf6536e 100644 --- a/src/mesa/main/texcompress_cpal.c +++ b/src/mesa/main/texcompress_cpal.c @@ -31,13 +31,14 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "mtypes.h" #include "pixelstore.h" #include "texcompress_cpal.h" #include "teximage.h" +#include "api_exec_decl.h" static const struct cpal_format_info { diff --git a/src/mesa/main/texcompress_cpal.h b/src/mesa/main/texcompress_cpal.h index 1b8542f080e..dca0844a927 100644 --- a/src/mesa/main/texcompress_cpal.h +++ b/src/mesa/main/texcompress_cpal.h @@ -27,7 +27,7 @@ #define TEXCOMPRESS_CPAL_H -#include "main/glheader.h" +#include "util/glheader.h" extern void _mesa_cpal_compressed_teximage2d(GLenum target, GLint level, GLenum internalFormat, diff --git a/src/mesa/main/texcompress_etc.c b/src/mesa/main/texcompress_etc.c index f14b1670728..607686ef6dd 100644 --- a/src/mesa/main/texcompress_etc.c +++ b/src/mesa/main/texcompress_etc.c @@ -101,7 +101,7 @@ static const int etc2_modifier_tables_non_opaque[8][4] = { /* define etc1_parse_block and etc. */ #define UINT8_TYPE GLubyte #define TAG(x) x -#include "texcompress_etc_tmp.h" +#include "util/format/texcompress_etc_tmp.h" #undef TAG #undef UINT8_TYPE diff --git a/src/mesa/main/texcompress_etc.h b/src/mesa/main/texcompress_etc.h index 2c764b88b09..24075f5111f 100644 --- a/src/mesa/main/texcompress_etc.h +++ b/src/mesa/main/texcompress_etc.h @@ -25,7 +25,7 @@ #define TEXCOMPRESS_ETC1_H #include <inttypes.h> -#include "glheader.h" +#include "util/glheader.h" #include "texcompress.h" #include "texstore.h" diff --git a/src/mesa/main/texcompress_etc_tmp.h b/src/mesa/main/texcompress_etc_tmp.h deleted file mode 100644 index 5497566324f..00000000000 --- a/src/mesa/main/texcompress_etc_tmp.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (C) 2011 LunarG, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - */ - -/* - * Included by texcompress_etc1 and gallium to define ETC1 decoding routines. - */ - -struct TAG(etc1_block) { - uint32_t pixel_indices; - int flipped; - const int *modifier_tables[2]; - UINT8_TYPE base_colors[2][3]; -}; - -static UINT8_TYPE -TAG(etc1_base_color_diff_hi)(UINT8_TYPE in) -{ - return (in & 0xf8) | (in >> 5); -} - -static UINT8_TYPE -TAG(etc1_base_color_diff_lo)(UINT8_TYPE in) -{ - static const int lookup[8] = { 0, 1, 2, 3, -4, -3, -2, -1 }; - - in = (in >> 3) + lookup[in & 0x7]; - - return (in << 3) | (in >> 2); -} - -static UINT8_TYPE -TAG(etc1_base_color_ind_hi)(UINT8_TYPE in) -{ - return (in & 0xf0) | ((in & 0xf0) >> 4); -} - -static UINT8_TYPE -TAG(etc1_base_color_ind_lo)(UINT8_TYPE in) -{ - return ((in & 0xf) << 4) | (in & 0xf); -} - -static UINT8_TYPE -TAG(etc1_clamp)(UINT8_TYPE base, int modifier) -{ - int tmp = (int) base + modifier; - - /* CLAMP(tmp, 0, 255) */ - return (UINT8_TYPE) ((tmp < 0) ? 0 : ((tmp > 255) ? 255 : tmp)); -} - -static const int TAG(etc1_modifier_tables)[8][4] = { - { 2, 8, -2, -8}, - { 5, 17, -5, -17}, - { 9, 29, -9, -29}, - { 13, 42, -13, -42}, - { 18, 60, -18, -60}, - { 24, 80, -24, -80}, - { 33, 106, -33, -106}, - { 47, 183, -47, -183} -}; - -static void -TAG(etc1_parse_block)(struct TAG(etc1_block) *block, const UINT8_TYPE *src) -{ - if (src[3] & 0x2) { - /* differential mode */ - block->base_colors[0][0] = (int) TAG(etc1_base_color_diff_hi)(src[0]); - block->base_colors[1][0] = (int) TAG(etc1_base_color_diff_lo)(src[0]); - block->base_colors[0][1] = (int) TAG(etc1_base_color_diff_hi)(src[1]); - block->base_colors[1][1] = (int) TAG(etc1_base_color_diff_lo)(src[1]); - block->base_colors[0][2] = (int) TAG(etc1_base_color_diff_hi)(src[2]); - block->base_colors[1][2] = (int) TAG(etc1_base_color_diff_lo)(src[2]); - } - else { - /* individual mode */ - block->base_colors[0][0] = (int) TAG(etc1_base_color_ind_hi)(src[0]); - block->base_colors[1][0] = (int) TAG(etc1_base_color_ind_lo)(src[0]); - block->base_colors[0][1] = (int) TAG(etc1_base_color_ind_hi)(src[1]); - block->base_colors[1][1] = (int) TAG(etc1_base_color_ind_lo)(src[1]); - block->base_colors[0][2] = (int) TAG(etc1_base_color_ind_hi)(src[2]); - block->base_colors[1][2] = (int) TAG(etc1_base_color_ind_lo)(src[2]); - } - - /* pick modifier tables */ - block->modifier_tables[0] = TAG(etc1_modifier_tables)[(src[3] >> 5) & 0x7]; - block->modifier_tables[1] = TAG(etc1_modifier_tables)[(src[3] >> 2) & 0x7]; - - block->flipped = (src[3] & 0x1); - - block->pixel_indices = - (src[4] << 24) | (src[5] << 16) | (src[6] << 8) | src[7]; -} - -static void -TAG(etc1_fetch_texel)(const struct TAG(etc1_block) *block, - int x, int y, UINT8_TYPE *dst) -{ - const UINT8_TYPE *base_color; - int modifier, bit, idx, blk; - - /* get pixel index */ - bit = y + x * 4; - idx = ((block->pixel_indices >> (15 + bit)) & 0x2) | - ((block->pixel_indices >> (bit)) & 0x1); - - /* get subblock */ - blk = (block->flipped) ? (y >= 2) : (x >= 2); - - base_color = block->base_colors[blk]; - modifier = block->modifier_tables[blk][idx]; - - dst[0] = TAG(etc1_clamp)(base_color[0], modifier); - dst[1] = TAG(etc1_clamp)(base_color[1], modifier); - dst[2] = TAG(etc1_clamp)(base_color[2], modifier); -} - -static void -etc1_unpack_rgba8888(uint8_t *dst_row, - unsigned dst_stride, - const uint8_t *src_row, - unsigned src_stride, - unsigned width, - unsigned height) -{ - const unsigned bw = 4, bh = 4, bs = 8, comps = 4; - struct etc1_block block; - unsigned x, y, i, j; - - for (y = 0; y < height; y += bh) { - const uint8_t *src = src_row; - - for (x = 0; x < width; x+= bw) { - etc1_parse_block(&block, src); - - for (j = 0; j < MIN2(bh, height - y); j++) { - uint8_t *dst = dst_row + (y + j) * dst_stride + x * comps; - for (i = 0; i < MIN2(bw, width - x); i++) { - etc1_fetch_texel(&block, i, j, dst); - dst[3] = 255; - dst += comps; - } - } - - src += bs; - } - - src_row += src_stride; - } -} diff --git a/src/mesa/main/texcompress_fxt1.c b/src/mesa/main/texcompress_fxt1.c index fd9e408bedf..2af091637a7 100644 --- a/src/mesa/main/texcompress_fxt1.c +++ b/src/mesa/main/texcompress_fxt1.c @@ -30,7 +30,7 @@ #include "errors.h" -#include "glheader.h" +#include "util/glheader.h" #include "image.h" #include "macros.h" diff --git a/src/mesa/main/texcompress_fxt1.h b/src/mesa/main/texcompress_fxt1.h index 71094f27e43..35556c2c78f 100644 --- a/src/mesa/main/texcompress_fxt1.h +++ b/src/mesa/main/texcompress_fxt1.h @@ -25,7 +25,7 @@ #ifndef TEXCOMPRESS_FXT1_H #define TEXCOMPRESS_FXT1_H -#include "glheader.h" +#include "util/glheader.h" #include "texstore.h" diff --git a/src/mesa/main/texcompress_rgtc.c b/src/mesa/main/texcompress_rgtc.c index 6839432966f..a87493ec814 100644 --- a/src/mesa/main/texcompress_rgtc.c +++ b/src/mesa/main/texcompress_rgtc.c @@ -35,13 +35,14 @@ #include <stdlib.h> #include "config.h" -#include "glheader.h" +#include "util/glheader.h" #include "image.h" #include "macros.h" #include "mipmap.h" #include "texcompress.h" #include "util/rgtc.h" +#include "util/format/u_format_rgtc.h" #include "texcompress_rgtc.h" #include "texstore.h" @@ -53,22 +54,22 @@ static void extractsrc_u( GLubyte srcpixels[4][4], const GLubyte *srcaddr, for (j = 0; j < numypixels; j++) { curaddr = srcaddr + j * srcRowStride * comps; for (i = 0; i < numxpixels; i++) { - srcpixels[j][i] = *curaddr; - curaddr += comps; + srcpixels[j][i] = *curaddr; + curaddr += comps; } } } -static void extractsrc_s( GLbyte srcpixels[4][4], const GLfloat *srcaddr, +static void extractsrc_s( GLbyte srcpixels[4][4], const GLbyte *srcaddr, GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps) { GLubyte i, j; - const GLfloat *curaddr; + const GLbyte *curaddr; for (j = 0; j < numypixels; j++) { curaddr = srcaddr + j * srcRowStride * comps; for (i = 0; i < numxpixels; i++) { - srcpixels[j][i] = FLOAT_TO_BYTE_TEX(*curaddr); - curaddr += comps; + srcpixels[j][i] = *curaddr; + curaddr += comps; } } } @@ -112,12 +113,12 @@ _mesa_texstore_red_rgtc1(TEXSTORE_PARAMS) else numypixels = srcHeight - j; srcaddr = tempImage + j * srcWidth; for (i = 0; i < srcWidth; i += 4) { - if (srcWidth > i + 3) numxpixels = 4; - else numxpixels = srcWidth - i; - extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1); - util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); - srcaddr += numxpixels; - blkaddr += 8; + if (srcWidth > i + 3) numxpixels = 4; + else numxpixels = srcWidth - i; + extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1); + util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); + srcaddr += numxpixels; + blkaddr += 8; } blkaddr += dstRowDiff; } @@ -131,26 +132,26 @@ GLboolean _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS) { GLbyte *dst; - const GLfloat *tempImage = NULL; + const GLbyte *tempImage = NULL; int i, j; int numxpixels, numypixels; - const GLfloat *srcaddr; + const GLbyte *srcaddr; GLbyte srcpixels[4][4]; GLbyte *blkaddr; GLint dstRowDiff, redRowStride; - GLfloat *tempImageSlices[1]; + GLbyte *tempImageSlices[1]; assert(dstFormat == MESA_FORMAT_R_RGTC1_SNORM || dstFormat == MESA_FORMAT_L_LATC1_SNORM); - redRowStride = 1 * srcWidth * sizeof(GLfloat); - tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLfloat)); + redRowStride = 1 * srcWidth * sizeof(GLbyte); + tempImage = malloc(srcWidth * srcHeight * 1 * sizeof(GLbyte)); if (!tempImage) return GL_FALSE; /* out of memory */ - tempImageSlices[0] = (GLfloat *) tempImage; + tempImageSlices[0] = (GLbyte *) tempImage; _mesa_texstore(ctx, dims, baseInternalFormat, - MESA_FORMAT_R_FLOAT32, + MESA_FORMAT_R_SNORM8, redRowStride, (GLubyte **)tempImageSlices, srcWidth, srcHeight, srcDepth, srcFormat, srcType, srcAddr, @@ -165,12 +166,12 @@ _mesa_texstore_signed_red_rgtc1(TEXSTORE_PARAMS) else numypixels = srcHeight - j; srcaddr = tempImage + j * srcWidth; for (i = 0; i < srcWidth; i += 4) { - if (srcWidth > i + 3) numxpixels = 4; - else numxpixels = srcWidth - i; - extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1); - util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); - srcaddr += numxpixels; - blkaddr += 8; + if (srcWidth > i + 3) numxpixels = 4; + else numxpixels = srcWidth - i; + extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 1); + util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); + srcaddr += numxpixels; + blkaddr += 8; } blkaddr += dstRowDiff; } @@ -224,18 +225,18 @@ _mesa_texstore_rg_rgtc2(TEXSTORE_PARAMS) else numypixels = srcHeight - j; srcaddr = tempImage + j * srcWidth * 2; for (i = 0; i < srcWidth; i += 4) { - if (srcWidth > i + 3) numxpixels = 4; - else numxpixels = srcWidth - i; - extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2); - util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); + if (srcWidth > i + 3) numxpixels = 4; + else numxpixels = srcWidth - i; + extractsrc_u(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2); + util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); - blkaddr += 8; - extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2); - util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); + blkaddr += 8; + extractsrc_u(srcpixels, (GLubyte *)srcaddr + 1, srcWidth, numxpixels, numypixels, 2); + util_format_unsigned_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); - blkaddr += 8; + blkaddr += 8; - srcaddr += numxpixels * 2; + srcaddr += numxpixels * 2; } blkaddr += dstRowDiff; } @@ -249,29 +250,29 @@ GLboolean _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS) { GLbyte *dst; - const GLfloat *tempImage = NULL; + const GLbyte *tempImage = NULL; int i, j; int numxpixels, numypixels; - const GLfloat *srcaddr; + const GLbyte *srcaddr; GLbyte srcpixels[4][4]; GLbyte *blkaddr; GLint dstRowDiff, rgRowStride; mesa_format tempFormat; - GLfloat *tempImageSlices[1]; + GLbyte *tempImageSlices[1]; assert(dstFormat == MESA_FORMAT_RG_RGTC2_SNORM || dstFormat == MESA_FORMAT_LA_LATC2_SNORM); if (baseInternalFormat == GL_RG) - tempFormat = MESA_FORMAT_RG_FLOAT32; + tempFormat = MESA_FORMAT_RG_SNORM8; else - tempFormat = MESA_FORMAT_LA_FLOAT32; + tempFormat = MESA_FORMAT_LA_SNORM8; - rgRowStride = 2 * srcWidth * sizeof(GLfloat); - tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLfloat)); + rgRowStride = 2 * srcWidth * sizeof(GLbyte); + tempImage = malloc(srcWidth * srcHeight * 2 * sizeof(GLbyte)); if (!tempImage) return GL_FALSE; /* out of memory */ - tempImageSlices[0] = (GLfloat *) tempImage; + tempImageSlices[0] = (GLbyte *) tempImage; _mesa_texstore(ctx, dims, baseInternalFormat, tempFormat, @@ -289,19 +290,18 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS) else numypixels = srcHeight - j; srcaddr = tempImage + j * srcWidth * 2; for (i = 0; i < srcWidth; i += 4) { - if (srcWidth > i + 3) numxpixels = 4; - else numxpixels = srcWidth - i; + if (srcWidth > i + 3) numxpixels = 4; + else numxpixels = srcWidth - i; - extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2); - util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); - blkaddr += 8; + extractsrc_s(srcpixels, srcaddr, srcWidth, numxpixels, numypixels, 2); + util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); + blkaddr += 8; - extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2); - util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); - blkaddr += 8; - - srcaddr += numxpixels * 2; + extractsrc_s(srcpixels, srcaddr + 1, srcWidth, numxpixels, numypixels, 2); + util_format_signed_encode_rgtc_ubyte(blkaddr, srcpixels, numxpixels, numypixels); + blkaddr += 8; + srcaddr += numxpixels * 2; } blkaddr += dstRowDiff; } @@ -456,3 +456,46 @@ _mesa_get_compressed_rgtc_func(mesa_format format) return NULL; } } + +void +_mesa_unpack_rgtc(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format) +{ + switch (format) { + case MESA_FORMAT_R_RGTC1_UNORM: + case MESA_FORMAT_L_LATC1_UNORM: + util_format_rgtc1_unorm_unpack_r_8unorm(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + case MESA_FORMAT_R_RGTC1_SNORM: + case MESA_FORMAT_L_LATC1_SNORM: + util_format_rgtc1_snorm_unpack_r_8snorm((int8_t *)dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + case MESA_FORMAT_RG_RGTC2_UNORM: + case MESA_FORMAT_LA_LATC2_UNORM: + util_format_rgtc2_unorm_unpack_rg_8unorm(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + case MESA_FORMAT_RG_RGTC2_SNORM: + case MESA_FORMAT_LA_LATC2_SNORM: + util_format_rgtc2_snorm_unpack_rg_8snorm((int8_t *)dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + default: + unreachable("unexpected format"); + } +} diff --git a/src/mesa/main/texcompress_rgtc.h b/src/mesa/main/texcompress_rgtc.h index e9e24950adf..e78a7dff5f6 100644 --- a/src/mesa/main/texcompress_rgtc.h +++ b/src/mesa/main/texcompress_rgtc.h @@ -24,7 +24,7 @@ #ifndef TEXCOMPRESS_RGTC_H #define TEXCOMPRESS_RGTC_H -#include "glheader.h" +#include "util/glheader.h" #include "texstore.h" @@ -43,5 +43,13 @@ _mesa_texstore_signed_rg_rgtc2(TEXSTORE_PARAMS); extern compressed_fetch_func _mesa_get_compressed_rgtc_func(mesa_format format); +extern void +_mesa_unpack_rgtc(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format); #endif diff --git a/src/mesa/main/texcompress_s3tc.c b/src/mesa/main/texcompress_s3tc.c index 06546a2a590..585fa8b9062 100644 --- a/src/mesa/main/texcompress_s3tc.c +++ b/src/mesa/main/texcompress_s3tc.c @@ -29,17 +29,18 @@ * GL_EXT_texture_compression_s3tc support. */ -#include "glheader.h" +#include "util/glheader.h" #include "image.h" #include "macros.h" #include "mtypes.h" #include "texcompress.h" #include "texcompress_s3tc.h" -#include "texcompress_s3tc_tmp.h" +#include "util/format/texcompress_s3tc_tmp.h" #include "texstore.h" #include "format_unpack.h" #include "util/format_srgb.h" +#include "util/format/u_format_s3tc.h" /** @@ -51,14 +52,16 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS) const GLubyte *pixels; GLubyte *dst; const GLubyte *tempImage = NULL; + int srccomps = srcFormat == GL_RGB ? 3 : 4; assert(dstFormat == MESA_FORMAT_RGB_DXT1 || dstFormat == MESA_FORMAT_SRGB_DXT1); - if (srcFormat != GL_RGB || + if (!(srcFormat == GL_RGB || srcFormat == GL_RGBA) || srcType != GL_UNSIGNED_BYTE || ctx->_ImageTransferState || - ALIGN(srcPacking->RowLength, srcPacking->Alignment) != srcWidth || + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != srccomps * srcWidth * sizeof(GLubyte) || + srcPacking->SkipImages || srcPacking->SwapBytes) { /* convert image to RGB/GLubyte */ GLubyte *tempImageSlices[1]; @@ -76,6 +79,7 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS) srcPacking); pixels = tempImage; srcFormat = GL_RGB; + srccomps = 3; } else { pixels = _mesa_image_address2d(srcPacking, srcAddr, srcWidth, srcHeight, @@ -84,9 +88,8 @@ _mesa_texstore_rgb_dxt1(TEXSTORE_PARAMS) dst = dstSlices[0]; - tx_compress_dxtn(3, srcWidth, srcHeight, pixels, - GL_COMPRESSED_RGB_S3TC_DXT1_EXT, - dst, dstRowStride); + tx_compress_dxt1(srccomps, srcWidth, srcHeight, pixels, + dst, dstRowStride, 3); free((void *) tempImage); @@ -103,6 +106,7 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS) const GLubyte *pixels; GLubyte *dst; const GLubyte *tempImage = NULL; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); assert(dstFormat == MESA_FORMAT_RGBA_DXT1 || dstFormat == MESA_FORMAT_SRGBA_DXT1); @@ -110,11 +114,11 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS) if (srcFormat != GL_RGBA || srcType != GL_UNSIGNED_BYTE || ctx->_ImageTransferState || - ALIGN(srcPacking->RowLength, srcPacking->Alignment) != srcWidth || + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != rgbaRowStride || + srcPacking->SkipImages || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ GLubyte *tempImageSlices[1]; - int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ @@ -140,9 +144,7 @@ _mesa_texstore_rgba_dxt1(TEXSTORE_PARAMS) dst = dstSlices[0]; - tx_compress_dxtn(4, srcWidth, srcHeight, pixels, - GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, - dst, dstRowStride); + tx_compress_dxt1(4, srcWidth, srcHeight, pixels, dst, dstRowStride, 4); free((void*) tempImage); @@ -159,6 +161,7 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS) const GLubyte *pixels; GLubyte *dst; const GLubyte *tempImage = NULL; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); assert(dstFormat == MESA_FORMAT_RGBA_DXT3 || dstFormat == MESA_FORMAT_SRGBA_DXT3); @@ -166,11 +169,11 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS) if (srcFormat != GL_RGBA || srcType != GL_UNSIGNED_BYTE || ctx->_ImageTransferState || - ALIGN(srcPacking->RowLength, srcPacking->Alignment) != srcWidth || + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != rgbaRowStride || + srcPacking->SkipImages || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ GLubyte *tempImageSlices[1]; - int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ @@ -195,9 +198,7 @@ _mesa_texstore_rgba_dxt3(TEXSTORE_PARAMS) dst = dstSlices[0]; - tx_compress_dxtn(4, srcWidth, srcHeight, pixels, - GL_COMPRESSED_RGBA_S3TC_DXT3_EXT, - dst, dstRowStride); + tx_compress_dxt3(4, srcWidth, srcHeight, pixels, dst, dstRowStride); free((void *) tempImage); @@ -214,6 +215,7 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS) const GLubyte *pixels; GLubyte *dst; const GLubyte *tempImage = NULL; + int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); assert(dstFormat == MESA_FORMAT_RGBA_DXT5 || dstFormat == MESA_FORMAT_SRGBA_DXT5); @@ -221,11 +223,11 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS) if (srcFormat != GL_RGBA || srcType != GL_UNSIGNED_BYTE || ctx->_ImageTransferState || - ALIGN(srcPacking->RowLength, srcPacking->Alignment) != srcWidth || + _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) != rgbaRowStride || + srcPacking->SkipImages || srcPacking->SwapBytes) { /* convert image to RGBA/GLubyte */ GLubyte *tempImageSlices[1]; - int rgbaRowStride = 4 * srcWidth * sizeof(GLubyte); tempImage = malloc(srcWidth * srcHeight * 4 * sizeof(GLubyte)); if (!tempImage) return GL_FALSE; /* out of memory */ @@ -250,9 +252,7 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS) dst = dstSlices[0]; - tx_compress_dxtn(4, srcWidth, srcHeight, pixels, - GL_COMPRESSED_RGBA_S3TC_DXT5_EXT, - dst, dstRowStride); + tx_compress_dxt5(4, srcWidth, srcHeight, pixels, dst, dstRowStride); free((void *) tempImage); @@ -383,3 +383,49 @@ _mesa_get_dxt_fetch_func(mesa_format format) return NULL; } } + +extern void +_mesa_unpack_s3tc(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format) +{ + /* We treat sRGB formats as RGB, because we're unpacking to another sRGB + * format. + */ + switch (format) { + case MESA_FORMAT_RGB_DXT1: + case MESA_FORMAT_SRGB_DXT1: + util_format_dxt1_rgb_unpack_rgba_8unorm(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + case MESA_FORMAT_RGBA_DXT1: + case MESA_FORMAT_SRGBA_DXT1: + util_format_dxt1_rgba_unpack_rgba_8unorm(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + case MESA_FORMAT_RGBA_DXT3: + case MESA_FORMAT_SRGBA_DXT3: + util_format_dxt3_rgba_unpack_rgba_8unorm(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + case MESA_FORMAT_RGBA_DXT5: + case MESA_FORMAT_SRGBA_DXT5: + util_format_dxt5_rgba_unpack_rgba_8unorm(dst_row, dst_stride, + src_row, src_stride, + src_width, src_height); + break; + + default: + unreachable("unexpected format"); + } +} diff --git a/src/mesa/main/texcompress_s3tc.h b/src/mesa/main/texcompress_s3tc.h index 0dbb5fc5371..f0728fdd590 100644 --- a/src/mesa/main/texcompress_s3tc.h +++ b/src/mesa/main/texcompress_s3tc.h @@ -25,7 +25,7 @@ #ifndef TEXCOMPRESS_S3TC_H #define TEXCOMPRESS_S3TC_H -#include "glheader.h" +#include "util/glheader.h" #include "texstore.h" #include "texcompress.h" @@ -47,5 +47,13 @@ _mesa_texstore_rgba_dxt5(TEXSTORE_PARAMS); extern compressed_fetch_func _mesa_get_dxt_fetch_func(mesa_format format); +extern void +_mesa_unpack_s3tc(uint8_t *dst_row, + unsigned dst_stride, + const uint8_t *src_row, + unsigned src_stride, + unsigned src_width, + unsigned src_height, + mesa_format format); #endif /* TEXCOMPRESS_S3TC_H */ diff --git a/src/mesa/main/texcompress_s3tc_tmp.h b/src/mesa/main/texcompress_s3tc_tmp.h deleted file mode 100644 index 5dd25222f15..00000000000 --- a/src/mesa/main/texcompress_s3tc_tmp.h +++ /dev/null @@ -1,994 +0,0 @@ -/* - * libtxc_dxtn - * Version: 1.0 - * - * Copyright (C) 2004 Roland Scheidegger All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN - * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN - * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef TEXCOMPRESS_S3TC_TMP_H -#define TEXCOMPRESS_S3TC_TMP_H - -#ifdef __APPLE__ -#include <OpenGL/gl.h> -#else -#include <GL/gl.h> -#endif - -typedef GLubyte GLchan; -#define UBYTE_TO_CHAN(b) (b) -#define CHAN_MAX 255 -#define RCOMP 0 -#define GCOMP 1 -#define BCOMP 2 -#define ACOMP 3 - -#define EXP5TO8R(packedcol) \ - ((((packedcol) >> 8) & 0xf8) | (((packedcol) >> 13) & 0x7)) - -#define EXP6TO8G(packedcol) \ - ((((packedcol) >> 3) & 0xfc) | (((packedcol) >> 9) & 0x3)) - -#define EXP5TO8B(packedcol) \ - ((((packedcol) << 3) & 0xf8) | (((packedcol) >> 2) & 0x7)) - -#define EXP4TO8(col) \ - ((col) | ((col) << 4)) - -/* inefficient. To be efficient, it would be necessary to decode 16 pixels at once */ - -static void dxt135_decode_imageblock ( const GLubyte *img_block_src, - GLint i, GLint j, GLuint dxt_type, GLvoid *texel ) { - GLchan *rgba = (GLchan *) texel; - const GLushort color0 = img_block_src[0] | (img_block_src[1] << 8); - const GLushort color1 = img_block_src[2] | (img_block_src[3] << 8); - const GLuint bits = img_block_src[4] | (img_block_src[5] << 8) | - (img_block_src[6] << 16) | ((GLuint)img_block_src[7] << 24); - /* What about big/little endian? */ - GLubyte bit_pos = 2 * (j * 4 + i) ; - GLubyte code = (GLubyte) ((bits >> bit_pos) & 3); - - rgba[ACOMP] = CHAN_MAX; - switch (code) { - case 0: - rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color0) ); - rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color0) ); - rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color0) ); - break; - case 1: - rgba[RCOMP] = UBYTE_TO_CHAN( EXP5TO8R(color1) ); - rgba[GCOMP] = UBYTE_TO_CHAN( EXP6TO8G(color1) ); - rgba[BCOMP] = UBYTE_TO_CHAN( EXP5TO8B(color1) ); - break; - case 2: - if ((dxt_type > 1) || (color0 > color1)) { - rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) * 2 + EXP5TO8R(color1)) / 3) ); - rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) * 2 + EXP6TO8G(color1)) / 3) ); - rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) * 2 + EXP5TO8B(color1)) / 3) ); - } - else { - rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1)) / 2) ); - rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1)) / 2) ); - rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1)) / 2) ); - } - break; - case 3: - if ((dxt_type > 1) || (color0 > color1)) { - rgba[RCOMP] = UBYTE_TO_CHAN( ((EXP5TO8R(color0) + EXP5TO8R(color1) * 2) / 3) ); - rgba[GCOMP] = UBYTE_TO_CHAN( ((EXP6TO8G(color0) + EXP6TO8G(color1) * 2) / 3) ); - rgba[BCOMP] = UBYTE_TO_CHAN( ((EXP5TO8B(color0) + EXP5TO8B(color1) * 2) / 3) ); - } - else { - rgba[RCOMP] = 0; - rgba[GCOMP] = 0; - rgba[BCOMP] = 0; - if (dxt_type == 1) rgba[ACOMP] = UBYTE_TO_CHAN(0); - } - break; - default: - /* CANNOT happen (I hope) */ - break; - } -} - - -static void fetch_2d_texel_rgb_dxt1(GLint srcRowStride, const GLubyte *pixdata, - GLint i, GLint j, GLvoid *texel) -{ - /* Extract the (i,j) pixel from pixdata and return it - * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP]. - */ - - const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8); - dxt135_decode_imageblock(blksrc, (i&3), (j&3), 0, texel); -} - - -static void fetch_2d_texel_rgba_dxt1(GLint srcRowStride, const GLubyte *pixdata, - GLint i, GLint j, GLvoid *texel) -{ - /* Extract the (i,j) pixel from pixdata and return it - * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP]. - */ - - const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 8); - dxt135_decode_imageblock(blksrc, (i&3), (j&3), 1, texel); -} - -static void fetch_2d_texel_rgba_dxt3(GLint srcRowStride, const GLubyte *pixdata, - GLint i, GLint j, GLvoid *texel) { - - /* Extract the (i,j) pixel from pixdata and return it - * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP]. - */ - - GLchan *rgba = (GLchan *) texel; - const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16); - const GLubyte anibble = (blksrc[((j&3) * 4 + (i&3)) / 2] >> (4 * (i&1))) & 0xf; - dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel); - rgba[ACOMP] = UBYTE_TO_CHAN( (GLubyte)(EXP4TO8(anibble)) ); -} - -static void fetch_2d_texel_rgba_dxt5(GLint srcRowStride, const GLubyte *pixdata, - GLint i, GLint j, GLvoid *texel) { - - /* Extract the (i,j) pixel from pixdata and return it - * in texel[RCOMP], texel[GCOMP], texel[BCOMP], texel[ACOMP]. - */ - - GLchan *rgba = (GLchan *) texel; - const GLubyte *blksrc = (pixdata + ((srcRowStride + 3) / 4 * (j / 4) + (i / 4)) * 16); - const GLubyte alpha0 = blksrc[0]; - const GLubyte alpha1 = blksrc[1]; - const GLubyte bit_pos = ((j&3) * 4 + (i&3)) * 3; - const GLubyte acodelow = blksrc[2 + bit_pos / 8]; - const GLubyte acodehigh = blksrc[3 + bit_pos / 8]; - const GLubyte code = (acodelow >> (bit_pos & 0x7) | - (acodehigh << (8 - (bit_pos & 0x7)))) & 0x7; - dxt135_decode_imageblock(blksrc + 8, (i&3), (j&3), 2, texel); - if (code == 0) - rgba[ACOMP] = UBYTE_TO_CHAN( alpha0 ); - else if (code == 1) - rgba[ACOMP] = UBYTE_TO_CHAN( alpha1 ); - else if (alpha0 > alpha1) - rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (8 - code) + (alpha1 * (code - 1))) / 7) ); - else if (code < 6) - rgba[ACOMP] = UBYTE_TO_CHAN( ((alpha0 * (6 - code) + (alpha1 * (code - 1))) / 5) ); - else if (code == 6) - rgba[ACOMP] = 0; - else - rgba[ACOMP] = CHAN_MAX; -} - - -/* weights used for error function, basically weights (unsquared 2/4/1) according to rgb->luminance conversion - not sure if this really reflects visual perception */ -#define REDWEIGHT 4 -#define GREENWEIGHT 16 -#define BLUEWEIGHT 1 - -#define ALPHACUT 127 - -static void fancybasecolorsearch( UNUSED GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2], - GLint numxpixels, GLint numypixels, UNUSED GLint type, UNUSED GLboolean haveAlpha) -{ - /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */ - - /* TODO could also try to find a better encoding for the 3-color-encoding type, this really should be done - if it's rgba_dxt1 and we have alpha in the block, currently even values which will be mapped to black - due to their alpha value will influence the result */ - GLint i, j, colors, z; - GLuint pixerror, pixerrorred, pixerrorgreen, pixerrorblue, pixerrorbest; - GLint colordist, blockerrlin[2][3]; - GLubyte nrcolor[2]; - GLint pixerrorcolorbest[3] = {0}; - GLubyte enc = 0; - GLubyte cv[4][4]; - GLubyte testcolor[2][3]; - -/* fprintf(stderr, "color begin 0 r/g/b %d/%d/%d, 1 r/g/b %d/%d/%d\n", - bestcolor[0][0], bestcolor[0][1], bestcolor[0][2], bestcolor[1][0], bestcolor[1][1], bestcolor[1][2]);*/ - if (((bestcolor[0][0] & 0xf8) << 8 | (bestcolor[0][1] & 0xfc) << 3 | bestcolor[0][2] >> 3) < - ((bestcolor[1][0] & 0xf8) << 8 | (bestcolor[1][1] & 0xfc) << 3 | bestcolor[1][2] >> 3)) { - testcolor[0][0] = bestcolor[0][0]; - testcolor[0][1] = bestcolor[0][1]; - testcolor[0][2] = bestcolor[0][2]; - testcolor[1][0] = bestcolor[1][0]; - testcolor[1][1] = bestcolor[1][1]; - testcolor[1][2] = bestcolor[1][2]; - } - else { - testcolor[1][0] = bestcolor[0][0]; - testcolor[1][1] = bestcolor[0][1]; - testcolor[1][2] = bestcolor[0][2]; - testcolor[0][0] = bestcolor[1][0]; - testcolor[0][1] = bestcolor[1][1]; - testcolor[0][2] = bestcolor[1][2]; - } - - for (i = 0; i < 3; i ++) { - cv[0][i] = testcolor[0][i]; - cv[1][i] = testcolor[1][i]; - cv[2][i] = (testcolor[0][i] * 2 + testcolor[1][i]) / 3; - cv[3][i] = (testcolor[0][i] + testcolor[1][i] * 2) / 3; - } - - blockerrlin[0][0] = 0; - blockerrlin[0][1] = 0; - blockerrlin[0][2] = 0; - blockerrlin[1][0] = 0; - blockerrlin[1][1] = 0; - blockerrlin[1][2] = 0; - - nrcolor[0] = 0; - nrcolor[1] = 0; - - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - pixerrorbest = 0xffffffff; - for (colors = 0; colors < 4; colors++) { - colordist = srccolors[j][i][0] - (cv[colors][0]); - pixerror = colordist * colordist * REDWEIGHT; - pixerrorred = colordist; - colordist = srccolors[j][i][1] - (cv[colors][1]); - pixerror += colordist * colordist * GREENWEIGHT; - pixerrorgreen = colordist; - colordist = srccolors[j][i][2] - (cv[colors][2]); - pixerror += colordist * colordist * BLUEWEIGHT; - pixerrorblue = colordist; - if (pixerror < pixerrorbest) { - enc = colors; - pixerrorbest = pixerror; - pixerrorcolorbest[0] = pixerrorred; - pixerrorcolorbest[1] = pixerrorgreen; - pixerrorcolorbest[2] = pixerrorblue; - } - } - if (enc == 0) { - for (z = 0; z < 3; z++) { - blockerrlin[0][z] += 3 * pixerrorcolorbest[z]; - } - nrcolor[0] += 3; - } - else if (enc == 2) { - for (z = 0; z < 3; z++) { - blockerrlin[0][z] += 2 * pixerrorcolorbest[z]; - } - nrcolor[0] += 2; - for (z = 0; z < 3; z++) { - blockerrlin[1][z] += 1 * pixerrorcolorbest[z]; - } - nrcolor[1] += 1; - } - else if (enc == 3) { - for (z = 0; z < 3; z++) { - blockerrlin[0][z] += 1 * pixerrorcolorbest[z]; - } - nrcolor[0] += 1; - for (z = 0; z < 3; z++) { - blockerrlin[1][z] += 2 * pixerrorcolorbest[z]; - } - nrcolor[1] += 2; - } - else if (enc == 1) { - for (z = 0; z < 3; z++) { - blockerrlin[1][z] += 3 * pixerrorcolorbest[z]; - } - nrcolor[1] += 3; - } - } - } - if (nrcolor[0] == 0) nrcolor[0] = 1; - if (nrcolor[1] == 0) nrcolor[1] = 1; - for (j = 0; j < 2; j++) { - for (i = 0; i < 3; i++) { - GLint newvalue = testcolor[j][i] + blockerrlin[j][i] / nrcolor[j]; - if (newvalue <= 0) - testcolor[j][i] = 0; - else if (newvalue >= 255) - testcolor[j][i] = 255; - else testcolor[j][i] = newvalue; - } - } - - if ((abs(testcolor[0][0] - testcolor[1][0]) < 8) && - (abs(testcolor[0][1] - testcolor[1][1]) < 4) && - (abs(testcolor[0][2] - testcolor[1][2]) < 8)) { - /* both colors are so close they might get encoded as the same 16bit values */ - GLubyte coldiffred, coldiffgreen, coldiffblue, coldiffmax, factor, ind0, ind1; - - coldiffred = abs(testcolor[0][0] - testcolor[1][0]); - coldiffgreen = 2 * abs(testcolor[0][1] - testcolor[1][1]); - coldiffblue = abs(testcolor[0][2] - testcolor[1][2]); - coldiffmax = coldiffred; - if (coldiffmax < coldiffgreen) coldiffmax = coldiffgreen; - if (coldiffmax < coldiffblue) coldiffmax = coldiffblue; - if (coldiffmax > 0) { - if (coldiffmax > 4) factor = 2; - else if (coldiffmax > 2) factor = 3; - else factor = 4; - /* Won't do much if the color value is near 255... */ - /* argh so many ifs */ - if (testcolor[1][1] >= testcolor[0][1]) { - ind1 = 1; ind0 = 0; - } - else { - ind1 = 0; ind0 = 1; - } - if ((testcolor[ind1][1] + factor * coldiffgreen) <= 255) - testcolor[ind1][1] += factor * coldiffgreen; - else testcolor[ind1][1] = 255; - if ((testcolor[ind1][0] - testcolor[ind0][1]) > 0) { - if ((testcolor[ind1][0] + factor * coldiffred) <= 255) - testcolor[ind1][0] += factor * coldiffred; - else testcolor[ind1][0] = 255; - } - else { - if ((testcolor[ind0][0] + factor * coldiffred) <= 255) - testcolor[ind0][0] += factor * coldiffred; - else testcolor[ind0][0] = 255; - } - if ((testcolor[ind1][2] - testcolor[ind0][2]) > 0) { - if ((testcolor[ind1][2] + factor * coldiffblue) <= 255) - testcolor[ind1][2] += factor * coldiffblue; - else testcolor[ind1][2] = 255; - } - else { - if ((testcolor[ind0][2] + factor * coldiffblue) <= 255) - testcolor[ind0][2] += factor * coldiffblue; - else testcolor[ind0][2] = 255; - } - } - } - - if (((testcolor[0][0] & 0xf8) << 8 | (testcolor[0][1] & 0xfc) << 3 | testcolor[0][2] >> 3) < - ((testcolor[1][0] & 0xf8) << 8 | (testcolor[1][1] & 0xfc) << 3 | testcolor[1][2]) >> 3) { - for (i = 0; i < 3; i++) { - bestcolor[0][i] = testcolor[0][i]; - bestcolor[1][i] = testcolor[1][i]; - } - } - else { - for (i = 0; i < 3; i++) { - bestcolor[0][i] = testcolor[1][i]; - bestcolor[1][i] = testcolor[0][i]; - } - } - -/* fprintf(stderr, "color end 0 r/g/b %d/%d/%d, 1 r/g/b %d/%d/%d\n", - bestcolor[0][0], bestcolor[0][1], bestcolor[0][2], bestcolor[1][0], bestcolor[1][1], bestcolor[1][2]);*/ -} - - - -static void storedxtencodedblock( GLubyte *blkaddr, GLubyte srccolors[4][4][4], GLubyte *bestcolor[2], - GLint numxpixels, GLint numypixels, GLuint type, GLboolean haveAlpha) -{ - /* use same luminance-weighted distance metric to determine encoding as for finding the base colors */ - - GLint i, j, colors; - GLuint testerror, testerror2, pixerror, pixerrorbest; - GLint colordist; - GLushort color0, color1, tempcolor; - GLuint bits = 0, bits2 = 0; - GLubyte *colorptr; - GLubyte enc = 0; - GLubyte cv[4][4]; - - bestcolor[0][0] = bestcolor[0][0] & 0xf8; - bestcolor[0][1] = bestcolor[0][1] & 0xfc; - bestcolor[0][2] = bestcolor[0][2] & 0xf8; - bestcolor[1][0] = bestcolor[1][0] & 0xf8; - bestcolor[1][1] = bestcolor[1][1] & 0xfc; - bestcolor[1][2] = bestcolor[1][2] & 0xf8; - - color0 = bestcolor[0][0] << 8 | bestcolor[0][1] << 3 | bestcolor[0][2] >> 3; - color1 = bestcolor[1][0] << 8 | bestcolor[1][1] << 3 | bestcolor[1][2] >> 3; - if (color0 < color1) { - tempcolor = color0; color0 = color1; color1 = tempcolor; - colorptr = bestcolor[0]; bestcolor[0] = bestcolor[1]; bestcolor[1] = colorptr; - } - - - for (i = 0; i < 3; i++) { - cv[0][i] = bestcolor[0][i]; - cv[1][i] = bestcolor[1][i]; - cv[2][i] = (bestcolor[0][i] * 2 + bestcolor[1][i]) / 3; - cv[3][i] = (bestcolor[0][i] + bestcolor[1][i] * 2) / 3; - } - - testerror = 0; - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - pixerrorbest = 0xffffffff; - for (colors = 0; colors < 4; colors++) { - colordist = srccolors[j][i][0] - cv[colors][0]; - pixerror = colordist * colordist * REDWEIGHT; - colordist = srccolors[j][i][1] - cv[colors][1]; - pixerror += colordist * colordist * GREENWEIGHT; - colordist = srccolors[j][i][2] - cv[colors][2]; - pixerror += colordist * colordist * BLUEWEIGHT; - if (pixerror < pixerrorbest) { - pixerrorbest = pixerror; - enc = colors; - } - } - testerror += pixerrorbest; - bits |= (uint32_t)enc << (2 * (j * 4 + i)); - } - } - /* some hw might disagree but actually decoding should always use 4-color encoding - for non-dxt1 formats */ - if (type == GL_COMPRESSED_RGB_S3TC_DXT1_EXT || type == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) { - for (i = 0; i < 3; i++) { - cv[2][i] = (bestcolor[0][i] + bestcolor[1][i]) / 2; - /* this isn't used. Looks like the black color constant can only be used - with RGB_DXT1 if I read the spec correctly (note though that the radeon gpu disagrees, - it will decode 3 to black even with DXT3/5), and due to how the color searching works - it won't get used even then */ - cv[3][i] = 0; - } - testerror2 = 0; - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - pixerrorbest = 0xffffffff; - if ((type == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) && (srccolors[j][i][3] <= ALPHACUT)) { - enc = 3; - pixerrorbest = 0; /* don't calculate error */ - } - else { - /* we're calculating the same what we have done already for colors 0-1 above... */ - for (colors = 0; colors < 3; colors++) { - colordist = srccolors[j][i][0] - cv[colors][0]; - pixerror = colordist * colordist * REDWEIGHT; - colordist = srccolors[j][i][1] - cv[colors][1]; - pixerror += colordist * colordist * GREENWEIGHT; - colordist = srccolors[j][i][2] - cv[colors][2]; - pixerror += colordist * colordist * BLUEWEIGHT; - if (pixerror < pixerrorbest) { - pixerrorbest = pixerror; - /* need to exchange colors later */ - if (colors > 1) enc = colors; - else enc = colors ^ 1; - } - } - } - testerror2 += pixerrorbest; - bits2 |= (uint32_t)enc << (2 * (j * 4 + i)); - } - } - } else { - testerror2 = 0xffffffff; - } - - /* finally we're finished, write back colors and bits */ - if ((testerror > testerror2) || (haveAlpha)) { - *blkaddr++ = color1 & 0xff; - *blkaddr++ = color1 >> 8; - *blkaddr++ = color0 & 0xff; - *blkaddr++ = color0 >> 8; - *blkaddr++ = bits2 & 0xff; - *blkaddr++ = ( bits2 >> 8) & 0xff; - *blkaddr++ = ( bits2 >> 16) & 0xff; - *blkaddr = bits2 >> 24; - } - else { - *blkaddr++ = color0 & 0xff; - *blkaddr++ = color0 >> 8; - *blkaddr++ = color1 & 0xff; - *blkaddr++ = color1 >> 8; - *blkaddr++ = bits & 0xff; - *blkaddr++ = ( bits >> 8) & 0xff; - *blkaddr++ = ( bits >> 16) & 0xff; - *blkaddr = bits >> 24; - } -} - -static void encodedxtcolorblockfaster( GLubyte *blkaddr, GLubyte srccolors[4][4][4], - GLint numxpixels, GLint numypixels, GLuint type ) -{ -/* simplistic approach. We need two base colors, simply use the "highest" and the "lowest" color - present in the picture as base colors */ - - /* define lowest and highest color as shortest and longest vector to 0/0/0, though the - vectors are weighted similar to their importance in rgb-luminance conversion - doesn't work too well though... - This seems to be a rather difficult problem */ - - GLubyte *bestcolor[2]; - GLubyte basecolors[2][3]; - GLubyte i, j; - GLuint lowcv, highcv, testcv; - GLboolean haveAlpha = GL_FALSE; - - lowcv = highcv = srccolors[0][0][0] * srccolors[0][0][0] * REDWEIGHT + - srccolors[0][0][1] * srccolors[0][0][1] * GREENWEIGHT + - srccolors[0][0][2] * srccolors[0][0][2] * BLUEWEIGHT; - bestcolor[0] = bestcolor[1] = srccolors[0][0]; - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - /* don't use this as a base color if the pixel will get black/transparent anyway */ - if ((type != GL_COMPRESSED_RGBA_S3TC_DXT1_EXT) || (srccolors[j][i][3] > ALPHACUT)) { - testcv = srccolors[j][i][0] * srccolors[j][i][0] * REDWEIGHT + - srccolors[j][i][1] * srccolors[j][i][1] * GREENWEIGHT + - srccolors[j][i][2] * srccolors[j][i][2] * BLUEWEIGHT; - if (testcv > highcv) { - highcv = testcv; - bestcolor[1] = srccolors[j][i]; - } - else if (testcv < lowcv) { - lowcv = testcv; - bestcolor[0] = srccolors[j][i]; - } - } - else haveAlpha = GL_TRUE; - } - } - /* make sure the original color values won't get touched... */ - for (j = 0; j < 2; j++) { - for (i = 0; i < 3; i++) { - basecolors[j][i] = bestcolor[j][i]; - } - } - bestcolor[0] = basecolors[0]; - bestcolor[1] = basecolors[1]; - - /* try to find better base colors */ - fancybasecolorsearch(blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha); - /* find the best encoding for these colors, and store the result */ - storedxtencodedblock(blkaddr, srccolors, bestcolor, numxpixels, numypixels, type, haveAlpha); -} - -static void writedxt5encodedalphablock( GLubyte *blkaddr, GLubyte alphabase1, GLubyte alphabase2, - GLubyte alphaenc[16]) -{ - *blkaddr++ = alphabase1; - *blkaddr++ = alphabase2; - *blkaddr++ = alphaenc[0] | (alphaenc[1] << 3) | ((alphaenc[2] & 3) << 6); - *blkaddr++ = (alphaenc[2] >> 2) | (alphaenc[3] << 1) | (alphaenc[4] << 4) | ((alphaenc[5] & 1) << 7); - *blkaddr++ = (alphaenc[5] >> 1) | (alphaenc[6] << 2) | (alphaenc[7] << 5); - *blkaddr++ = alphaenc[8] | (alphaenc[9] << 3) | ((alphaenc[10] & 3) << 6); - *blkaddr++ = (alphaenc[10] >> 2) | (alphaenc[11] << 1) | (alphaenc[12] << 4) | ((alphaenc[13] & 1) << 7); - *blkaddr++ = (alphaenc[13] >> 1) | (alphaenc[14] << 2) | (alphaenc[15] << 5); -} - -static void encodedxt5alpha(GLubyte *blkaddr, GLubyte srccolors[4][4][4], - GLint numxpixels, GLint numypixels) -{ - GLubyte alphabase[2], alphause[2]; - GLshort alphatest[2]; - GLuint alphablockerror1, alphablockerror2, alphablockerror3; - GLubyte i, j, aindex, acutValues[7]; - GLubyte alphaenc1[16], alphaenc2[16], alphaenc3[16]; - GLboolean alphaabsmin = GL_FALSE; - GLboolean alphaabsmax = GL_FALSE; - GLshort alphadist; - - /* find lowest and highest alpha value in block, alphabase[0] lowest, alphabase[1] highest */ - alphabase[0] = 0xff; alphabase[1] = 0x0; - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - if (srccolors[j][i][3] == 0) - alphaabsmin = GL_TRUE; - else if (srccolors[j][i][3] == 255) - alphaabsmax = GL_TRUE; - else { - if (srccolors[j][i][3] > alphabase[1]) - alphabase[1] = srccolors[j][i][3]; - if (srccolors[j][i][3] < alphabase[0]) - alphabase[0] = srccolors[j][i][3]; - } - } - } - - - if ((alphabase[0] > alphabase[1]) && !(alphaabsmin && alphaabsmax)) { /* one color, either max or min */ - /* shortcut here since it is a very common case (and also avoids later problems) */ - /* || (alphabase[0] == alphabase[1] && !alphaabsmin && !alphaabsmax) */ - /* could also thest for alpha0 == alpha1 (and not min/max), but probably not common, so don't bother */ - - *blkaddr++ = srccolors[0][0][3]; - blkaddr++; - *blkaddr++ = 0; - *blkaddr++ = 0; - *blkaddr++ = 0; - *blkaddr++ = 0; - *blkaddr++ = 0; - *blkaddr++ = 0; -/* fprintf(stderr, "enc0 used\n");*/ - return; - } - - /* find best encoding for alpha0 > alpha1 */ - /* it's possible this encoding is better even if both alphaabsmin and alphaabsmax are true */ - alphablockerror1 = 0x0; - alphablockerror2 = 0xffffffff; - alphablockerror3 = 0xffffffff; - if (alphaabsmin) alphause[0] = 0; - else alphause[0] = alphabase[0]; - if (alphaabsmax) alphause[1] = 255; - else alphause[1] = alphabase[1]; - /* calculate the 7 cut values, just the middle between 2 of the computed alpha values */ - for (aindex = 0; aindex < 7; aindex++) { - /* don't forget here is always rounded down */ - acutValues[aindex] = (alphause[0] * (2*aindex + 1) + alphause[1] * (14 - (2*aindex + 1))) / 14; - } - - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - /* maybe it's overkill to have the most complicated calculation just for the error - calculation which we only need to figure out if encoding1 or encoding2 is better... */ - if (srccolors[j][i][3] > acutValues[0]) { - alphaenc1[4*j + i] = 0; - alphadist = srccolors[j][i][3] - alphause[1]; - } - else if (srccolors[j][i][3] > acutValues[1]) { - alphaenc1[4*j + i] = 2; - alphadist = srccolors[j][i][3] - (alphause[1] * 6 + alphause[0] * 1) / 7; - } - else if (srccolors[j][i][3] > acutValues[2]) { - alphaenc1[4*j + i] = 3; - alphadist = srccolors[j][i][3] - (alphause[1] * 5 + alphause[0] * 2) / 7; - } - else if (srccolors[j][i][3] > acutValues[3]) { - alphaenc1[4*j + i] = 4; - alphadist = srccolors[j][i][3] - (alphause[1] * 4 + alphause[0] * 3) / 7; - } - else if (srccolors[j][i][3] > acutValues[4]) { - alphaenc1[4*j + i] = 5; - alphadist = srccolors[j][i][3] - (alphause[1] * 3 + alphause[0] * 4) / 7; - } - else if (srccolors[j][i][3] > acutValues[5]) { - alphaenc1[4*j + i] = 6; - alphadist = srccolors[j][i][3] - (alphause[1] * 2 + alphause[0] * 5) / 7; - } - else if (srccolors[j][i][3] > acutValues[6]) { - alphaenc1[4*j + i] = 7; - alphadist = srccolors[j][i][3] - (alphause[1] * 1 + alphause[0] * 6) / 7; - } - else { - alphaenc1[4*j + i] = 1; - alphadist = srccolors[j][i][3] - alphause[0]; - } - alphablockerror1 += alphadist * alphadist; - } - } -/* for (i = 0; i < 16; i++) { - fprintf(stderr, "%d ", alphaenc1[i]); - } - fprintf(stderr, "cutVals "); - for (i = 0; i < 8; i++) { - fprintf(stderr, "%d ", acutValues[i]); - } - fprintf(stderr, "srcVals "); - for (j = 0; j < numypixels; j++) - for (i = 0; i < numxpixels; i++) { - fprintf(stderr, "%d ", srccolors[j][i][3]); - } - - fprintf(stderr, "\n"); - }*/ - /* it's not very likely this encoding is better if both alphaabsmin and alphaabsmax - are false but try it anyway */ - if (alphablockerror1 >= 32) { - - /* don't bother if encoding is already very good, this condition should also imply - we have valid alphabase colors which we absolutely need (alphabase[0] <= alphabase[1]) */ - alphablockerror2 = 0; - for (aindex = 0; aindex < 5; aindex++) { - /* don't forget here is always rounded down */ - acutValues[aindex] = (alphabase[0] * (10 - (2*aindex + 1)) + alphabase[1] * (2*aindex + 1)) / 10; - } - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - /* maybe it's overkill to have the most complicated calculation just for the error - calculation which we only need to figure out if encoding1 or encoding2 is better... */ - if (srccolors[j][i][3] == 0) { - alphaenc2[4*j + i] = 6; - alphadist = 0; - } - else if (srccolors[j][i][3] == 255) { - alphaenc2[4*j + i] = 7; - alphadist = 0; - } - else if (srccolors[j][i][3] <= acutValues[0]) { - alphaenc2[4*j + i] = 0; - alphadist = srccolors[j][i][3] - alphabase[0]; - } - else if (srccolors[j][i][3] <= acutValues[1]) { - alphaenc2[4*j + i] = 2; - alphadist = srccolors[j][i][3] - (alphabase[0] * 4 + alphabase[1] * 1) / 5; - } - else if (srccolors[j][i][3] <= acutValues[2]) { - alphaenc2[4*j + i] = 3; - alphadist = srccolors[j][i][3] - (alphabase[0] * 3 + alphabase[1] * 2) / 5; - } - else if (srccolors[j][i][3] <= acutValues[3]) { - alphaenc2[4*j + i] = 4; - alphadist = srccolors[j][i][3] - (alphabase[0] * 2 + alphabase[1] * 3) / 5; - } - else if (srccolors[j][i][3] <= acutValues[4]) { - alphaenc2[4*j + i] = 5; - alphadist = srccolors[j][i][3] - (alphabase[0] * 1 + alphabase[1] * 4) / 5; - } - else { - alphaenc2[4*j + i] = 1; - alphadist = srccolors[j][i][3] - alphabase[1]; - } - alphablockerror2 += alphadist * alphadist; - } - } - - - /* skip this if the error is already very small - this encoding is MUCH better on average than #2 though, but expensive! */ - if ((alphablockerror2 > 96) && (alphablockerror1 > 96)) { - GLshort blockerrlin1 = 0; - GLshort blockerrlin2 = 0; - GLubyte nralphainrangelow = 0; - GLubyte nralphainrangehigh = 0; - alphatest[0] = 0xff; - alphatest[1] = 0x0; - /* if we have large range it's likely there are values close to 0/255, try to map them to 0/255 */ - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - if ((srccolors[j][i][3] > alphatest[1]) && (srccolors[j][i][3] < (255 -(alphabase[1] - alphabase[0]) / 28))) - alphatest[1] = srccolors[j][i][3]; - if ((srccolors[j][i][3] < alphatest[0]) && (srccolors[j][i][3] > (alphabase[1] - alphabase[0]) / 28)) - alphatest[0] = srccolors[j][i][3]; - } - } - /* shouldn't happen too often, don't really care about those degenerated cases */ - if (alphatest[1] <= alphatest[0]) { - alphatest[0] = 1; - alphatest[1] = 254; -/* fprintf(stderr, "only 1 or 0 colors for encoding!\n");*/ - } - for (aindex = 0; aindex < 5; aindex++) { - /* don't forget here is always rounded down */ - acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; - } - - /* find the "average" difference between the alpha values and the next encoded value. - This is then used to calculate new base values. - Should there be some weighting, i.e. those values closer to alphatest[x] have more weight, - since they will see more improvement, and also because the values in the middle are somewhat - likely to get no improvement at all (because the base values might move in different directions)? - OTOH it would mean the values in the middle are even less likely to get an improvement - */ - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - if (srccolors[j][i][3] <= alphatest[0] / 2) { - } - else if (srccolors[j][i][3] > ((255 + alphatest[1]) / 2)) { - } - else if (srccolors[j][i][3] <= acutValues[0]) { - blockerrlin1 += (srccolors[j][i][3] - alphatest[0]); - nralphainrangelow += 1; - } - else if (srccolors[j][i][3] <= acutValues[1]) { - blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); - blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5); - nralphainrangelow += 1; - nralphainrangehigh += 1; - } - else if (srccolors[j][i][3] <= acutValues[2]) { - blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); - blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5); - nralphainrangelow += 1; - nralphainrangehigh += 1; - } - else if (srccolors[j][i][3] <= acutValues[3]) { - blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); - blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5); - nralphainrangelow += 1; - nralphainrangehigh += 1; - } - else if (srccolors[j][i][3] <= acutValues[4]) { - blockerrlin1 += (srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); - blockerrlin2 += (srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5); - nralphainrangelow += 1; - nralphainrangehigh += 1; - } - else { - blockerrlin2 += (srccolors[j][i][3] - alphatest[1]); - nralphainrangehigh += 1; - } - } - } - /* shouldn't happen often, needed to avoid div by zero */ - if (nralphainrangelow == 0) nralphainrangelow = 1; - if (nralphainrangehigh == 0) nralphainrangehigh = 1; - alphatest[0] = alphatest[0] + (blockerrlin1 / nralphainrangelow); -/* fprintf(stderr, "block err lin low %d, nr %d\n", blockerrlin1, nralphainrangelow); - fprintf(stderr, "block err lin high %d, nr %d\n", blockerrlin2, nralphainrangehigh);*/ - /* again shouldn't really happen often... */ - if (alphatest[0] < 0) { - alphatest[0] = 0; -/* fprintf(stderr, "adj alpha base val to 0\n");*/ - } - alphatest[1] = alphatest[1] + (blockerrlin2 / nralphainrangehigh); - if (alphatest[1] > 255) { - alphatest[1] = 255; -/* fprintf(stderr, "adj alpha base val to 255\n");*/ - } - - alphablockerror3 = 0; - for (aindex = 0; aindex < 5; aindex++) { - /* don't forget here is always rounded down */ - acutValues[aindex] = (alphatest[0] * (10 - (2*aindex + 1)) + alphatest[1] * (2*aindex + 1)) / 10; - } - for (j = 0; j < numypixels; j++) { - for (i = 0; i < numxpixels; i++) { - /* maybe it's overkill to have the most complicated calculation just for the error - calculation which we only need to figure out if encoding1 or encoding2 is better... */ - if (srccolors[j][i][3] <= alphatest[0] / 2) { - alphaenc3[4*j + i] = 6; - alphadist = srccolors[j][i][3]; - } - else if (srccolors[j][i][3] > ((255 + alphatest[1]) / 2)) { - alphaenc3[4*j + i] = 7; - alphadist = 255 - srccolors[j][i][3]; - } - else if (srccolors[j][i][3] <= acutValues[0]) { - alphaenc3[4*j + i] = 0; - alphadist = srccolors[j][i][3] - alphatest[0]; - } - else if (srccolors[j][i][3] <= acutValues[1]) { - alphaenc3[4*j + i] = 2; - alphadist = srccolors[j][i][3] - (alphatest[0] * 4 + alphatest[1] * 1) / 5; - } - else if (srccolors[j][i][3] <= acutValues[2]) { - alphaenc3[4*j + i] = 3; - alphadist = srccolors[j][i][3] - (alphatest[0] * 3 + alphatest[1] * 2) / 5; - } - else if (srccolors[j][i][3] <= acutValues[3]) { - alphaenc3[4*j + i] = 4; - alphadist = srccolors[j][i][3] - (alphatest[0] * 2 + alphatest[1] * 3) / 5; - } - else if (srccolors[j][i][3] <= acutValues[4]) { - alphaenc3[4*j + i] = 5; - alphadist = srccolors[j][i][3] - (alphatest[0] * 1 + alphatest[1] * 4) / 5; - } - else { - alphaenc3[4*j + i] = 1; - alphadist = srccolors[j][i][3] - alphatest[1]; - } - alphablockerror3 += alphadist * alphadist; - } - } - } - } - /* write the alpha values and encoding back. */ - if ((alphablockerror1 <= alphablockerror2) && (alphablockerror1 <= alphablockerror3)) { -/* if (alphablockerror1 > 96) fprintf(stderr, "enc1 used, error %d\n", alphablockerror1);*/ - writedxt5encodedalphablock( blkaddr, alphause[1], alphause[0], alphaenc1 ); - } - else if (alphablockerror2 <= alphablockerror3) { -/* if (alphablockerror2 > 96) fprintf(stderr, "enc2 used, error %d\n", alphablockerror2);*/ - writedxt5encodedalphablock( blkaddr, alphabase[0], alphabase[1], alphaenc2 ); - } - else { -/* fprintf(stderr, "enc3 used, error %d\n", alphablockerror3);*/ - writedxt5encodedalphablock( blkaddr, (GLubyte)alphatest[0], (GLubyte)alphatest[1], alphaenc3 ); - } -} - -static void extractsrccolors( GLubyte srcpixels[4][4][4], const GLchan *srcaddr, - GLint srcRowStride, GLint numxpixels, GLint numypixels, GLint comps) -{ - GLubyte i, j, c; - const GLchan *curaddr; - for (j = 0; j < numypixels; j++) { - curaddr = srcaddr + j * srcRowStride * comps; - for (i = 0; i < numxpixels; i++) { - for (c = 0; c < comps; c++) { - srcpixels[j][i][c] = *curaddr++ / (CHAN_MAX / 255); - } - } - } -} - - -static void tx_compress_dxtn(GLint srccomps, GLint width, GLint height, const GLubyte *srcPixData, - GLenum destFormat, GLubyte *dest, GLint dstRowStride) -{ - GLubyte *blkaddr = dest; - GLubyte srcpixels[4][4][4]; - const GLchan *srcaddr = srcPixData; - GLint numxpixels, numypixels; - GLint i, j; - GLint dstRowDiff; - - switch (destFormat) { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - /* hmm we used to get called without dstRowStride... */ - dstRowDiff = dstRowStride >= (width * 2) ? dstRowStride - (((width + 3) & ~3) * 2) : 0; -/* fprintf(stderr, "dxt1 tex width %d tex height %d dstRowStride %d\n", - width, height, dstRowStride); */ - for (j = 0; j < height; j += 4) { - if (height > j + 3) numypixels = 4; - else numypixels = height - j; - srcaddr = srcPixData + j * width * srccomps; - for (i = 0; i < width; i += 4) { - if (width > i + 3) numxpixels = 4; - else numxpixels = width - i; - extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps); - encodedxtcolorblockfaster(blkaddr, srcpixels, numxpixels, numypixels, destFormat); - srcaddr += srccomps * numxpixels; - blkaddr += 8; - } - blkaddr += dstRowDiff; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0; -/* fprintf(stderr, "dxt3 tex width %d tex height %d dstRowStride %d\n", - width, height, dstRowStride); */ - for (j = 0; j < height; j += 4) { - if (height > j + 3) numypixels = 4; - else numypixels = height - j; - srcaddr = srcPixData + j * width * srccomps; - for (i = 0; i < width; i += 4) { - if (width > i + 3) numxpixels = 4; - else numxpixels = width - i; - extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps); - *blkaddr++ = (srcpixels[0][0][3] >> 4) | (srcpixels[0][1][3] & 0xf0); - *blkaddr++ = (srcpixels[0][2][3] >> 4) | (srcpixels[0][3][3] & 0xf0); - *blkaddr++ = (srcpixels[1][0][3] >> 4) | (srcpixels[1][1][3] & 0xf0); - *blkaddr++ = (srcpixels[1][2][3] >> 4) | (srcpixels[1][3][3] & 0xf0); - *blkaddr++ = (srcpixels[2][0][3] >> 4) | (srcpixels[2][1][3] & 0xf0); - *blkaddr++ = (srcpixels[2][2][3] >> 4) | (srcpixels[2][3][3] & 0xf0); - *blkaddr++ = (srcpixels[3][0][3] >> 4) | (srcpixels[3][1][3] & 0xf0); - *blkaddr++ = (srcpixels[3][2][3] >> 4) | (srcpixels[3][3][3] & 0xf0); - encodedxtcolorblockfaster(blkaddr, srcpixels, numxpixels, numypixels, destFormat); - srcaddr += srccomps * numxpixels; - blkaddr += 8; - } - blkaddr += dstRowDiff; - } - break; - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - dstRowDiff = dstRowStride >= (width * 4) ? dstRowStride - (((width + 3) & ~3) * 4) : 0; -/* fprintf(stderr, "dxt5 tex width %d tex height %d dstRowStride %d\n", - width, height, dstRowStride); */ - for (j = 0; j < height; j += 4) { - if (height > j + 3) numypixels = 4; - else numypixels = height - j; - srcaddr = srcPixData + j * width * srccomps; - for (i = 0; i < width; i += 4) { - if (width > i + 3) numxpixels = 4; - else numxpixels = width - i; - extractsrccolors(srcpixels, srcaddr, width, numxpixels, numypixels, srccomps); - encodedxt5alpha(blkaddr, srcpixels, numxpixels, numypixels); - encodedxtcolorblockfaster(blkaddr + 8, srcpixels, numxpixels, numypixels, destFormat); - srcaddr += srccomps * numxpixels; - blkaddr += 16; - } - blkaddr += dstRowDiff; - } - break; - default: - assert(false); - return; - } -} - -#endif diff --git a/src/mesa/main/texenv.c b/src/mesa/main/texenv.c index 9f7125d51b6..bd643bac5da 100644 --- a/src/mesa/main/texenv.c +++ b/src/mesa/main/texenv.c @@ -30,15 +30,15 @@ */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/blend.h" #include "main/enums.h" #include "main/macros.h" #include "main/mtypes.h" #include "main/state.h" -#include "main/texenv.h" #include "main/texstate.h" +#include "api_exec_decl.h" #define TE_ERROR(errCode, msg, value) \ @@ -116,26 +116,23 @@ set_combiner_mode(struct gl_context *ctx, case GL_ADD: case GL_ADD_SIGNED: case GL_INTERPOLATE: - legal = GL_TRUE; - break; case GL_SUBTRACT: - legal = ctx->Extensions.ARB_texture_env_combine; + legal = GL_TRUE; break; case GL_DOT3_RGB_EXT: case GL_DOT3_RGBA_EXT: - legal = (ctx->API == API_OPENGL_COMPAT && + legal = (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.EXT_texture_env_dot3 && pname == GL_COMBINE_RGB); break; case GL_DOT3_RGB: case GL_DOT3_RGBA: - legal = (ctx->Extensions.ARB_texture_env_dot3 && - pname == GL_COMBINE_RGB); + legal = (pname == GL_COMBINE_RGB); break; case GL_MODULATE_ADD_ATI: case GL_MODULATE_SIGNED_ADD_ATI: case GL_MODULATE_SUBTRACT_ATI: - legal = (ctx->API == API_OPENGL_COMPAT && + legal = (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ATI_texture_env_combine3); break; default: @@ -231,16 +228,15 @@ set_combiner_source(struct gl_context *ctx, case GL_TEXTURE5: case GL_TEXTURE6: case GL_TEXTURE7: - legal = (ctx->Extensions.ARB_texture_env_crossbar && - param - GL_TEXTURE0 < ctx->Const.MaxTextureUnits); + legal = (param - GL_TEXTURE0 < ctx->Const.MaxTextureUnits); break; case GL_ZERO: - legal = (ctx->API == API_OPENGL_COMPAT && + legal = (_mesa_is_desktop_gl_compat(ctx) && (ctx->Extensions.ATI_texture_env_combine3 || ctx->Extensions.NV_texture_env_combine4)); break; case GL_ONE: - legal = (ctx->API == API_OPENGL_COMPAT && + legal = (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.ATI_texture_env_combine3); break; default: @@ -308,22 +304,9 @@ set_combiner_operand(struct gl_context *ctx, switch (param) { case GL_SRC_COLOR: case GL_ONE_MINUS_SRC_COLOR: - /* The color input can only be used with GL_OPERAND[01]_RGB in the EXT - * version. In the ARB and NV versions and OpenGL ES 1.x they can be - * used for any RGB operand. - */ - legal = !alpha - && ((term < 2) || ctx->Extensions.ARB_texture_env_combine - || ctx->Extensions.NV_texture_env_combine4); + legal = !alpha; break; case GL_ONE_MINUS_SRC_ALPHA: - /* GL_ONE_MINUS_SRC_ALPHA can only be used with - * GL_OPERAND[01]_(RGB|ALPHA) in the EXT version. In the ARB and NV - * versions and OpenGL ES 1.x it can be used for any operand. - */ - legal = (term < 2) || ctx->Extensions.ARB_texture_env_combine - || ctx->Extensions.NV_texture_env_combine4; - break; case GL_SRC_ALPHA: legal = GL_TRUE; break; @@ -471,6 +454,7 @@ _mesa_texenvfv_indexed( struct gl_context* ctx, GLuint texunit, GLenum target, return; FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); texUnit->LodBias = param[0]; + texUnit->LodBiasQuantized = util_quantize_lod_bias(param[0]); } else { TE_ERROR(GL_INVALID_ENUM, "glTexEnv(pname=%s)", pname); @@ -478,11 +462,6 @@ _mesa_texenvfv_indexed( struct gl_context* ctx, GLuint texunit, GLenum target, } } else if (target == GL_POINT_SPRITE) { - /* GL_ARB_point_sprite */ - if (!ctx->Extensions.ARB_point_sprite) { - _mesa_error( ctx, GL_INVALID_ENUM, "glTexEnv(target=0x%x)", target ); - return; - } if (pname == GL_COORD_REPLACE) { /* It's kind of weird to set point state via glTexEnv, * but that's what the spec calls for. @@ -521,11 +500,6 @@ _mesa_texenvfv_indexed( struct gl_context* ctx, GLuint texunit, GLenum target, _mesa_enum_to_string(pname), *param, _mesa_enum_to_string((GLenum) iparam0)); - - /* Tell device driver about the new texture environment */ - if (ctx->Driver.TexEnv) { - ctx->Driver.TexEnv(ctx, target, pname, param); - } } @@ -653,7 +627,7 @@ get_texenvi(struct gl_context *ctx, return texUnit->Combine.SourceRGB[rgb_idx]; } case GL_SOURCE3_RGB_NV: - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { + if (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.NV_texture_env_combine4) { return texUnit->Combine.SourceRGB[3]; } else { @@ -667,7 +641,7 @@ get_texenvi(struct gl_context *ctx, return texUnit->Combine.SourceA[alpha_idx]; } case GL_SOURCE3_ALPHA_NV: - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { + if (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.NV_texture_env_combine4) { return texUnit->Combine.SourceA[3]; } else { @@ -681,7 +655,7 @@ get_texenvi(struct gl_context *ctx, return texUnit->Combine.OperandRGB[op_rgb]; } case GL_OPERAND3_RGB_NV: - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { + if (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.NV_texture_env_combine4) { return texUnit->Combine.OperandRGB[3]; } else { @@ -695,7 +669,7 @@ get_texenvi(struct gl_context *ctx, return texUnit->Combine.OperandA[op_alpha]; } case GL_OPERAND3_ALPHA_NV: - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.NV_texture_env_combine4) { + if (_mesa_is_desktop_gl_compat(ctx) && ctx->Extensions.NV_texture_env_combine4) { return texUnit->Combine.OperandA[3]; } else { @@ -766,11 +740,6 @@ _mesa_gettexenvfv_indexed( GLuint texunit, GLenum target, GLenum pname, GLfloat } } else if (target == GL_POINT_SPRITE) { - /* GL_ARB_point_sprite */ - if (!ctx->Extensions.ARB_point_sprite) { - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnvfv(target)" ); - return; - } if (pname == GL_COORD_REPLACE) { if (ctx->Point.CoordReplace & (1u << texunit)) *params = 1.0f; @@ -842,11 +811,6 @@ _mesa_gettexenviv_indexed( GLuint texunit, GLenum target, } } else if (target == GL_POINT_SPRITE) { - /* GL_ARB_point_sprite */ - if (!ctx->Extensions.ARB_point_sprite) { - _mesa_error( ctx, GL_INVALID_ENUM, "glGetTexEnviv(target)" ); - return; - } if (pname == GL_COORD_REPLACE) { if (ctx->Point.CoordReplace & (1u << texunit)) *params = GL_TRUE; diff --git a/src/mesa/main/texenv.h b/src/mesa/main/texenv.h deleted file mode 100644 index e5f968db9da..00000000000 --- a/src/mesa/main/texenv.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef TEXENV_H -#define TEXENV_H - - -#include "main/glheader.h" - - -extern void GLAPIENTRY -_mesa_GetTexEnvfv( GLenum target, GLenum pname, GLfloat *params ); - -extern void GLAPIENTRY -_mesa_GetTexEnviv( GLenum target, GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_mesa_TexEnvf( GLenum target, GLenum pname, GLfloat param ); - -extern void GLAPIENTRY -_mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ); - -extern void GLAPIENTRY -_mesa_TexEnvi( GLenum target, GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_TexEnviv( GLenum target, GLenum pname, const GLint *param ); - -extern void GLAPIENTRY -_mesa_MultiTexEnvfEXT( GLenum texunit, GLenum target, - GLenum pname, GLfloat param ); - -extern void GLAPIENTRY -_mesa_MultiTexEnvfvEXT( GLenum texunit, GLenum target, - GLenum pname, const GLfloat *param ); - -extern void GLAPIENTRY -_mesa_MultiTexEnviEXT( GLenum texunit, GLenum target, - GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_MultiTexEnvivEXT( GLenum texunit, GLenum target, - GLenum pname, const GLint *param ); - -extern void GLAPIENTRY -_mesa_GetMultiTexEnvivEXT( GLenum texunit, GLenum target, - GLenum pname, GLint *param ); - -extern void GLAPIENTRY -_mesa_GetMultiTexEnvfvEXT( GLenum texunit, GLenum target, - GLenum pname, GLfloat *param ); - -#endif /* TEXENV_H */ diff --git a/src/mesa/main/texenvprogram.h b/src/mesa/main/texenvprogram.h index 11439f13b35..52101c86a00 100644 --- a/src/mesa/main/texenvprogram.h +++ b/src/mesa/main/texenvprogram.h @@ -34,7 +34,7 @@ extern "C" { struct gl_context; -extern struct gl_shader_program * +extern struct gl_program * _mesa_get_fixed_func_fragment_program(struct gl_context *ctx); diff --git a/src/mesa/main/texformat.c b/src/mesa/main/texformat.c deleted file mode 100644 index bf46b6658d9..00000000000 --- a/src/mesa/main/texformat.c +++ /dev/null @@ -1,792 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (c) 2008-2009 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -/** - * \file texformat.c - * Texture formats. - * - * \author Gareth Hughes - * \author Brian Paul - */ - - -#include "context.h" -#include "enums.h" -#include "mtypes.h" -#include "texcompress.h" -#include "texformat.h" -#include "glformats.h" - -#define RETURN_IF_SUPPORTED(f) do { \ - if (ctx->TextureFormatSupported[f]) \ - return f; \ -} while (0) - -/** - * Choose an appropriate texture format given the format, type and - * internalFormat parameters passed to glTexImage(). - * - * \param ctx the GL context. - * \param target a texture target (GL_TEXTURE_x) - * \param internalFormat user's prefered internal texture format. - * \param format incoming image pixel format. - * \param type incoming image data type. - * - * \return the closest mesa_format for the given format/type arguments - * - * This is called via dd_function_table::ChooseTextureFormat. Hardware - * drivers may override this function with a specialized version. - */ -mesa_format -_mesa_choose_tex_format(struct gl_context *ctx, GLenum target, - GLint internalFormat, GLenum format, GLenum type) -{ - (void) format; - - switch (internalFormat) { - /* shallow RGBA formats */ - case 4: - case GL_RGBA: - if (type == GL_UNSIGNED_SHORT_4_4_4_4_REV) { - RETURN_IF_SUPPORTED(MESA_FORMAT_B4G4R4A4_UNORM); - } else if (type == GL_UNSIGNED_SHORT_1_5_5_5_REV) { - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM); - } else if (type == GL_UNSIGNED_SHORT_5_5_5_1) { - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM); - } else if (type == GL_UNSIGNED_INT_2_10_10_10_REV) { - RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM); - } - FALLTHROUGH; - - case GL_RGBA8: - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - case GL_RGB5_A1: - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G5R5A1_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_A1B5G5R5_UNORM); - break; - case GL_RGBA2: - RETURN_IF_SUPPORTED(MESA_FORMAT_A4R4G4B4_UNORM); /* just to test another format*/ - RETURN_IF_SUPPORTED(MESA_FORMAT_B4G4R4A4_UNORM); - break; - case GL_RGBA4: - RETURN_IF_SUPPORTED(MESA_FORMAT_B4G4R4A4_UNORM); - break; - - /* deep RGBA formats */ - case GL_RGB10_A2: - RETURN_IF_SUPPORTED(MESA_FORMAT_R10G10B10A2_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - case GL_RGBA12: - case GL_RGBA16: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - - /* shallow RGB formats */ - case 3: - case GL_RGB: - if (type == GL_UNSIGNED_INT_2_10_10_10_REV) { - RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UNORM); - } - if (type == GL_UNSIGNED_SHORT_5_6_5) { - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); - } - FALLTHROUGH; - case GL_RGB8: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8X8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_UNORM); - - RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - case GL_R3_G3_B2: - RETURN_IF_SUPPORTED(MESA_FORMAT_B2G3R3_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R5G6B5_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - case GL_RGB4: - RETURN_IF_SUPPORTED(MESA_FORMAT_R5G6B5_UNORM); /* just to test another format */ - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); - break; - case GL_RGB5: - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); - break; - - /* deep RGB formats */ - case GL_RGB10: - case GL_RGB12: - case GL_RGB16: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - - /* Alpha formats */ - case GL_ALPHA: - case GL_ALPHA4: - case GL_ALPHA8: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - - case GL_ALPHA12: - case GL_ALPHA16: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - - /* Luminance formats */ - case 1: - case GL_LUMINANCE: - case GL_LUMINANCE4: - case GL_LUMINANCE8: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM8); - break; - - case GL_LUMINANCE12: - case GL_LUMINANCE16: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM8); - break; - - /* Luminance/Alpha formats */ - case GL_LUMINANCE4_ALPHA4: - RETURN_IF_SUPPORTED(MESA_FORMAT_L4A4_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - - case 2: - case GL_LUMINANCE_ALPHA: - case GL_LUMINANCE6_ALPHA2: - case GL_LUMINANCE8_ALPHA8: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - - case GL_LUMINANCE12_ALPHA4: - case GL_LUMINANCE12_ALPHA12: - case GL_LUMINANCE16_ALPHA16: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - - case GL_INTENSITY: - case GL_INTENSITY4: - case GL_INTENSITY8: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM8); - break; - - case GL_INTENSITY12: - case GL_INTENSITY16: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM8); - break; - - case GL_DEPTH_COMPONENT: - case GL_DEPTH_COMPONENT24: - case GL_DEPTH_COMPONENT32: - RETURN_IF_SUPPORTED(MESA_FORMAT_Z_UNORM32); - RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT); - RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT); - break; - case GL_DEPTH_COMPONENT16: - RETURN_IF_SUPPORTED(MESA_FORMAT_Z_UNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_X8_UINT); - RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT); - break; - - case GL_COMPRESSED_ALPHA_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - case GL_COMPRESSED_LUMINANCE_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UNORM8); - break; - case GL_COMPRESSED_LUMINANCE_ALPHA_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UNORM8); - break; - case GL_COMPRESSED_INTENSITY_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UNORM8); - break; - case GL_COMPRESSED_RGB_ARB: - /* We don't use texture compression for 1D and 1D array textures. - * For 1D textures, compressions doesn't buy us much. - * For 1D ARRAY textures, there's complicated issues with updating - * sub-regions on non-block boundaries with glCopyTexSubImage, among - * other issues. FWIW, the GL_EXT_texture_array extension prohibits - * 1D ARRAY textures in S3TC format. - */ - if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) { - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_DXT1); - } - RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_UNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8X8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - case GL_COMPRESSED_RGBA_ARB: - /* We don't use texture compression for 1D and 1D array textures. */ - if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) { - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_DXT3); /* Not rgba_dxt1, see spec */ - } - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - - case GL_RGB565: - RETURN_IF_SUPPORTED(MESA_FORMAT_B5G6R5_UNORM); - break; - - case GL_YCBCR_MESA: - if (type == GL_UNSIGNED_SHORT_8_8_MESA) - RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR); - else - RETURN_IF_SUPPORTED(MESA_FORMAT_YCBCR_REV); - break; - - case GL_ALPHA16F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_ALPHA32F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_A_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - case GL_LUMINANCE16F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_LUMINANCE32F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_L_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - case GL_LUMINANCE_ALPHA16F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_LUMINANCE_ALPHA32F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - case GL_INTENSITY16F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_INTENSITY32F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_I_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - case GL_RGB16F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_RGB32F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - case GL_RGBA16F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_RGBA32F_ARB: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - - case GL_RGB9_E5: - /* GL_EXT_texture_shared_exponent -- just one format to support */ - assert(ctx->TextureFormatSupported[MESA_FORMAT_R9G9B9E5_FLOAT]); - return MESA_FORMAT_R9G9B9E5_FLOAT; - - case GL_R11F_G11F_B10F: - /* GL_EXT_texture_packed_float -- just one format to support */ - assert(ctx->TextureFormatSupported[MESA_FORMAT_R11G11B10_FLOAT]); - return MESA_FORMAT_R11G11B10_FLOAT; - - case GL_DEPTH_STENCIL_EXT: - case GL_DEPTH24_STENCIL8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_S8_UINT_Z24_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_Z24_UNORM_S8_UINT); - break; - - case GL_DEPTH_COMPONENT32F: - assert(ctx->TextureFormatSupported[MESA_FORMAT_Z_FLOAT32]); - return MESA_FORMAT_Z_FLOAT32; - case GL_DEPTH32F_STENCIL8: - assert(ctx->TextureFormatSupported[MESA_FORMAT_Z32_FLOAT_S8X24_UINT]); - return MESA_FORMAT_Z32_FLOAT_S8X24_UINT; - - case GL_RED_SNORM: - case GL_R8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_SNORM8); - break; - case GL_RG_SNORM: - case GL_RG8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SNORM8); - break; - case GL_RGB_SNORM: - case GL_RGB8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8X8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_X8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - break; - case GL_RGBA_SNORM: - case GL_RGBA8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_ALPHA_SNORM: - case GL_ALPHA8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_SNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_LUMINANCE_SNORM: - case GL_LUMINANCE8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_X8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_LUMINANCE_ALPHA_SNORM: - case GL_LUMINANCE8_ALPHA8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_INTENSITY_SNORM: - case GL_INTENSITY8_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_SNORM8); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_R16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_SNORM16); - break; - case GL_RG16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SNORM16); - break; - case GL_RGB16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SNORM16); - FALLTHROUGH; - case GL_RGBA16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_ALPHA16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_LUMINANCE16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SNORM16); - FALLTHROUGH; - case GL_LUMINANCE16_ALPHA16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - case GL_INTENSITY16_SNORM: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SNORM16); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SNORM); - break; - - case GL_SRGB_EXT: - case GL_SRGB8_EXT: - /* there is no MESA_FORMAT_RGB_SRGB8 */ - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8X8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SRGB); - - RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_SRGB8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - - RETURN_IF_SUPPORTED(MESA_FORMAT_X8B8G8R8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_SRGB_ALPHA_EXT: - case GL_SRGB8_ALPHA8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_R8G8B8A8_SRGB); - - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_SR8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_SRGB8); - break; - case GL_SRG8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SRGB8); - break; - case GL_SLUMINANCE_EXT: - case GL_SLUMINANCE8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SRGB8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_SLUMINANCE_ALPHA_EXT: - case GL_SLUMINANCE8_ALPHA8_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SRGB8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_COMPRESSED_SLUMINANCE_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SRGB8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_COMPRESSED_SLUMINANCE_ALPHA_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SRGB8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_COMPRESSED_SRGB_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_SRGB_DXT1); - RETURN_IF_SUPPORTED(MESA_FORMAT_BGR_SRGB8); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - case GL_COMPRESSED_SRGB_ALPHA_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_SRGBA_DXT3); /* Not srgba_dxt1, see spec */ - RETURN_IF_SUPPORTED(MESA_FORMAT_A8B8G8R8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_SRGB); - RETURN_IF_SUPPORTED(MESA_FORMAT_A8R8G8B8_SRGB); - break; - - case GL_ALPHA8UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); - break; - case GL_ALPHA16UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); - break; - case GL_ALPHA32UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_UINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); - break; - case GL_ALPHA8I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_SINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); - break; - case GL_ALPHA16I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_SINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); - break; - case GL_ALPHA32I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_A_SINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); - break; - case GL_LUMINANCE8UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); - break; - case GL_LUMINANCE16UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); - break; - case GL_LUMINANCE32UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_UINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); - break; - case GL_LUMINANCE8I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); - break; - case GL_LUMINANCE16I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); - break; - case GL_LUMINANCE32I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_L_SINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); - break; - case GL_LUMINANCE_ALPHA8UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); - break; - case GL_LUMINANCE_ALPHA16UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); - break; - case GL_LUMINANCE_ALPHA32UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_UINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); - break; - case GL_LUMINANCE_ALPHA8I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); - break; - case GL_LUMINANCE_ALPHA16I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); - break; - case GL_LUMINANCE_ALPHA32I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_LA_SINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); - break; - case GL_INTENSITY8UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); - break; - case GL_INTENSITY16UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); - break; - case GL_INTENSITY32UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_UINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); - break; - case GL_INTENSITY8I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_SINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); - break; - case GL_INTENSITY16I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_SINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); - break; - case GL_INTENSITY32I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_I_SINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); - break; - - case GL_RGB8UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); - break; - case GL_RGB16UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); - break; - case GL_RGB32UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_UINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_UINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); - break; - case GL_RGB8I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SINT8); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); - break; - case GL_RGB16I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SINT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); - break; - case GL_RGB32I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGB_SINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBX_SINT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); - break; - case GL_RGBA8UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT8); - break; - case GL_RGBA16UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT16); - break; - case GL_RGBA32UI_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_UINT32); - break; - case GL_RGBA8I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT8); - break; - case GL_RGBA16I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT16); - break; - case GL_RGBA32I_EXT: - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_SINT32); - break; - - case GL_R8: - case GL_RED: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_UNORM8); - break; - - case GL_COMPRESSED_RED: - if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) - RETURN_IF_SUPPORTED(MESA_FORMAT_R_RGTC1_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_R_UNORM8); - break; - - case GL_R16: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_UNORM16); - break; - - case GL_RG: - case GL_RG8: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UNORM8); - break; - - case GL_COMPRESSED_RG: - if (target != GL_TEXTURE_1D && target != GL_TEXTURE_1D_ARRAY) - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_RGTC2_UNORM); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UNORM8); - break; - - case GL_RG16: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UNORM16); - break; - - case GL_R16F: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_R32F: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_R_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - case GL_RG16F: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - break; - case GL_RG32F: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT32); - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_FLOAT16); - RETURN_IF_SUPPORTED(MESA_FORMAT_RGBA_FLOAT16); - break; - - case GL_R8UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT8); - break; - case GL_RG8UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT8); - break; - case GL_R16UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT16); - break; - case GL_RG16UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT16); - break; - case GL_R32UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_UINT32); - break; - case GL_RG32UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_UINT32); - break; - case GL_R8I: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_SINT8); - break; - case GL_RG8I: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SINT8); - break; - case GL_R16I: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_SINT16); - break; - case GL_RG16I: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SINT16); - break; - case GL_R32I: - RETURN_IF_SUPPORTED(MESA_FORMAT_R_SINT32); - break; - case GL_RG32I: - RETURN_IF_SUPPORTED(MESA_FORMAT_RG_SINT32); - break; - - case GL_RGB10_A2UI: - RETURN_IF_SUPPORTED(MESA_FORMAT_B10G10R10A2_UINT); - RETURN_IF_SUPPORTED(MESA_FORMAT_R10G10B10A2_UINT); - break; - - case GL_BGRA: - RETURN_IF_SUPPORTED(MESA_FORMAT_B8G8R8A8_UNORM); - break; - - case GL_STENCIL_INDEX: - case GL_STENCIL_INDEX8: - RETURN_IF_SUPPORTED(MESA_FORMAT_S_UINT8); - break; - - default: - /* For non-generic compressed format we assert two things: - * - * 1. The format has already been validated against the set of available - * extensions. - * - * 2. The driver only enables the extension if it supports all of the - * formats that are part of that extension. - */ - if (_mesa_is_compressed_format(ctx, internalFormat)) - return _mesa_glenum_to_compressed_format(internalFormat); - } - - _mesa_problem(ctx, "unexpected format %s in _mesa_choose_tex_format()", - _mesa_enum_to_string(internalFormat)); - return MESA_FORMAT_NONE; -} diff --git a/src/mesa/main/texformat.h b/src/mesa/main/texformat.h deleted file mode 100644 index ed965f84f1d..00000000000 --- a/src/mesa/main/texformat.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * Copyright (c) 2008-2009 VMware, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - -#ifndef TEXFORMAT_H -#define TEXFORMAT_H - - -#include "formats.h" - -struct gl_context; - -extern mesa_format -_mesa_choose_tex_format(struct gl_context *ctx, GLenum target, - GLint internalFormat, GLenum format, GLenum type); - -#endif diff --git a/src/mesa/main/texgen.c b/src/mesa/main/texgen.c index 57aa5c5d767..f52b67ce1cd 100644 --- a/src/mesa/main/texgen.c +++ b/src/mesa/main/texgen.c @@ -30,13 +30,15 @@ */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/enums.h" #include "main/macros.h" -#include "main/texgen.h" +#include "main/texparam.h" #include "main/texstate.h" #include "math/m_matrix.h" +#include "main/texobj.h" +#include "api_exec_decl.h" /** @@ -53,7 +55,7 @@ get_texgen(struct gl_context *ctx, GLuint texunitIndex, GLenum coord, const char texUnit = _mesa_get_fixedfunc_tex_unit(ctx, texunitIndex); - if (ctx->API == API_OPENGLES) { + if (_mesa_is_gles1(ctx)) { return (coord == GL_TEXTURE_GEN_STR_OES) ? &texUnit->GenS : NULL; } @@ -175,9 +177,6 @@ texgenfv( GLuint texunitIndex, GLenum coord, GLenum pname, _mesa_error( ctx, GL_INVALID_ENUM, "glTexGenfv(pname)" ); return; } - - if (ctx->Driver.TexGen) - ctx->Driver.TexGen( ctx, coord, pname, params ); } @@ -371,42 +370,6 @@ _mesa_MultiTexGendEXT(GLenum texunit, GLenum coord, GLenum pname, GLdouble param texgenfv(texunit - GL_TEXTURE0, coord, pname, p, "glMultiTexGendEXT"); } -void GLAPIENTRY -_es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params) -{ - _mesa_GetTexGenfv(GL_S, pname, params); -} - - -void GLAPIENTRY -_es_TexGenf(GLenum coord, GLenum pname, GLfloat param) -{ - if (coord != GL_TEXTURE_GEN_STR_OES) { - GET_CURRENT_CONTEXT(ctx); - _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx](pname)" ); - return; - } - /* set S, T, and R at the same time */ - _mesa_TexGenf(GL_S, pname, param); - _mesa_TexGenf(GL_T, pname, param); - _mesa_TexGenf(GL_R, pname, param); -} - - -void GLAPIENTRY -_es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params) -{ - if (coord != GL_TEXTURE_GEN_STR_OES) { - GET_CURRENT_CONTEXT(ctx); - _mesa_error( ctx, GL_INVALID_ENUM, "glTexGen[fx]v(pname)" ); - return; - } - /* set S, T, and R at the same time */ - _mesa_TexGenfv(GL_S, pname, params); - _mesa_TexGenfv(GL_T, pname, params); - _mesa_TexGenfv(GL_R, pname, params); -} - void GLAPIENTRY _mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ) diff --git a/src/mesa/main/texgen.h b/src/mesa/main/texgen.h deleted file mode 100644 index ad36aca60df..00000000000 --- a/src/mesa/main/texgen.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2008 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef TEXGEN_H -#define TEXGEN_H - - -#include "glheader.h" - -struct _glapi_table; - - -void GLAPIENTRY -_mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ); -void GLAPIENTRY -_mesa_TexGeniv(GLenum coord, GLenum pname, const GLint *params ); -void GLAPIENTRY -_mesa_TexGend(GLenum coord, GLenum pname, GLdouble param ); -void GLAPIENTRY -_mesa_TexGendv(GLenum coord, GLenum pname, const GLdouble *params ); -void GLAPIENTRY -_mesa_TexGenf( GLenum coord, GLenum pname, GLfloat param ); -void GLAPIENTRY -_mesa_TexGeni( GLenum coord, GLenum pname, GLint param ); -void GLAPIENTRY -_mesa_GetTexGendv( GLenum coord, GLenum pname, GLdouble *params ); -void GLAPIENTRY -_mesa_GetTexGenfv( GLenum coord, GLenum pname, GLfloat *params ); -void GLAPIENTRY -_mesa_GetTexGeniv( GLenum coord, GLenum pname, GLint *params ); - -void GLAPIENTRY -_mesa_MultiTexGenfvEXT( GLenum texunit, GLenum coord, GLenum pname, const GLfloat *params ); -void GLAPIENTRY -_mesa_MultiTexGenivEXT(GLenum texunit, GLenum coord, GLenum pname, const GLint *params ); -void GLAPIENTRY -_mesa_MultiTexGendEXT(GLenum texunit, GLenum coord, GLenum pname, GLdouble param ); -void GLAPIENTRY -_mesa_MultiTexGendvEXT(GLenum texunit, GLenum coord, GLenum pname, const GLdouble *params ); -void GLAPIENTRY -_mesa_MultiTexGenfEXT( GLenum texunit, GLenum coord, GLenum pname, GLfloat param ); -void GLAPIENTRY -_mesa_MultiTexGeniEXT( GLenum texunit, GLenum coord, GLenum pname, GLint param ); -void GLAPIENTRY -_mesa_GetMultiTexGendvEXT( GLenum texunit, GLenum coord, GLenum pname, GLdouble *params ); -void GLAPIENTRY -_mesa_GetMultiTexGenfvEXT( GLenum texunit, GLenum coord, GLenum pname, GLfloat *params ); -void GLAPIENTRY -_mesa_GetMultiTexGenivEXT( GLenum texunit, GLenum coord, GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_es_GetTexGenfv(GLenum coord, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_es_TexGenf(GLenum coord, GLenum pname, GLfloat param); - -extern void GLAPIENTRY -_es_TexGenfv(GLenum coord, GLenum pname, const GLfloat *params); - - -#endif /* TEXGEN_H */ diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 0b8a031fbf0..6d0db242cff 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -29,7 +29,7 @@ */ -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "enums.h" #include "context.h" @@ -48,6 +48,9 @@ #include "texstore.h" #include "format_utils.h" #include "pixeltransfer.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_texture.h" /** * Can the given type represent negative values? @@ -93,9 +96,9 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions, GLint srcRowStride; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, &srcMap, &srcRowStride); + st_MapTextureImage(ctx, texImage, zoffset + img, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, &srcMap, &srcRowStride); if (srcMap) { for (row = 0; row < height; row++) { @@ -107,7 +110,7 @@ get_tex_depth(struct gl_context *ctx, GLuint dimensions, _mesa_pack_depth_span(ctx, width, dest, type, depthRow, &ctx->Pack); } - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); + st_UnmapTextureImage(ctx, texImage, zoffset + img); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); @@ -138,9 +141,9 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions, GLint rowstride; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, &srcMap, &rowstride); + st_MapTextureImage(ctx, texImage, zoffset + img, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, &srcMap, &rowstride); if (srcMap) { for (row = 0; row < height; row++) { @@ -166,7 +169,7 @@ get_tex_depth_stencil(struct gl_context *ctx, GLuint dimensions, } } - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); + st_UnmapTextureImage(ctx, texImage, zoffset + img); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); @@ -194,10 +197,10 @@ get_tex_stencil(struct gl_context *ctx, GLuint dimensions, GLint rowstride; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, - &srcMap, &rowstride); + st_MapTextureImage(ctx, texImage, zoffset + img, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, + &srcMap, &rowstride); if (srcMap) { for (row = 0; row < height; row++) { @@ -211,7 +214,7 @@ get_tex_stencil(struct gl_context *ctx, GLuint dimensions, dest); } - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); + st_UnmapTextureImage(ctx, texImage, zoffset + img); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); @@ -238,9 +241,9 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions, GLint rowstride; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, &srcMap, &rowstride); + st_MapTextureImage(ctx, texImage, zoffset + img, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, &srcMap, &rowstride); if (srcMap) { for (row = 0; row < height; row++) { @@ -263,7 +266,7 @@ get_tex_ycbcr(struct gl_context *ctx, GLuint dimensions, } } - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); + st_UnmapTextureImage(ctx, texImage, zoffset + img); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); @@ -343,15 +346,15 @@ get_tex_rgba_compressed(struct gl_context *ctx, GLuint dimensions, tempSlice = tempImage + slice * 4 * width * height; - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, - &srcMap, &srcRowStride); + st_MapTextureImage(ctx, texImage, zoffset + slice, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, + &srcMap, &srcRowStride); if (srcMap) { _mesa_decompress_image(texFormat, width, height, srcMap, srcRowStride, tempSlice); - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice); + st_UnmapTextureImage(ctx, texImage, zoffset + slice); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); @@ -472,10 +475,10 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, uint32_t src_format; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + img, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, - &srcMap, &rowstride); + st_MapTextureImage(ctx, texImage, zoffset + img, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, + &srcMap, &rowstride); if (!srcMap) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); goto done; @@ -508,7 +511,7 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, rgba = malloc(height * rgba_stride); if (!rgba) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage()"); - ctx->Driver.UnmapTextureImage(ctx, texImage, img); + st_UnmapTextureImage(ctx, texImage, img); return; } } @@ -555,7 +558,7 @@ get_tex_rgba_uncompressed(struct gl_context *ctx, GLuint dimensions, width, height, dest, dest); /* Unmap the src texture buffer */ - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + img); + st_UnmapTextureImage(ctx, texImage, zoffset + img); } done: @@ -655,9 +658,9 @@ get_tex_memcpy(struct gl_context *ctx, GLint srcRowStride; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, &src, &srcRowStride); + st_MapTextureImage(ctx, texImage, zoffset, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, &src, &srcRowStride); if (src) { if (bytesPerRow == dstRowStride && bytesPerRow == srcRowStride) { @@ -673,7 +676,7 @@ get_tex_memcpy(struct gl_context *ctx, } /* unmap src texture buffer */ - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset); + st_UnmapTextureImage(ctx, texImage, zoffset); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage"); @@ -685,10 +688,8 @@ get_tex_memcpy(struct gl_context *ctx, /** - * This is the software fallback for Driver.GetTexSubImage(). + * This is the software fallback for GetTexSubImage(). * All error checking will have been done before this routine is called. - * We'll call ctx->Driver.MapTextureImage() to access the data, then - * unmap with ctx->Driver.UnmapTextureImage(). */ void _mesa_GetTexSubImage_sw(struct gl_context *ctx, @@ -709,9 +710,9 @@ _mesa_GetTexSubImage_sw(struct gl_context *ctx, * texture data to the PBO if the PBO is in VRAM along with the texture. */ GLubyte *buf = (GLubyte *) - ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size, - GL_MAP_WRITE_BIT, ctx->Pack.BufferObj, - MAP_INTERNAL); + _mesa_bufferobj_map_range(ctx, 0, ctx->Pack.BufferObj->Size, + GL_MAP_WRITE_BIT, ctx->Pack.BufferObj, + MAP_INTERNAL); if (!buf) { /* out of memory or other unexpected error */ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexImage(map PBO failed)"); @@ -761,7 +762,7 @@ _mesa_GetTexSubImage_sw(struct gl_context *ctx, } if (ctx->Pack.BufferObj) { - ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, ctx->Pack.BufferObj, MAP_INTERNAL); } } @@ -791,9 +792,9 @@ get_compressed_texsubimage_sw(struct gl_context *ctx, if (ctx->Pack.BufferObj) { /* pack texture image into a PBO */ dest = (GLubyte *) - ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size, - GL_MAP_WRITE_BIT, ctx->Pack.BufferObj, - MAP_INTERNAL); + _mesa_bufferobj_map_range(ctx, 0, ctx->Pack.BufferObj->Size, + GL_MAP_WRITE_BIT, ctx->Pack.BufferObj, + MAP_INTERNAL); if (!dest) { /* out of memory or other unexpected error */ _mesa_error(ctx, GL_OUT_OF_MEMORY, @@ -812,9 +813,9 @@ get_compressed_texsubimage_sw(struct gl_context *ctx, GLubyte *src; /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, zoffset + slice, - xoffset, yoffset, width, height, - GL_MAP_READ_BIT, &src, &srcRowStride); + st_MapTextureImage(ctx, texImage, zoffset + slice, + xoffset, yoffset, width, height, + GL_MAP_READ_BIT, &src, &srcRowStride); if (src) { GLint i; @@ -824,7 +825,7 @@ get_compressed_texsubimage_sw(struct gl_context *ctx, src += srcRowStride; } - ctx->Driver.UnmapTextureImage(ctx, texImage, zoffset + slice); + st_UnmapTextureImage(ctx, texImage, zoffset + slice); /* Advance to next slice */ dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice - @@ -836,7 +837,7 @@ get_compressed_texsubimage_sw(struct gl_context *ctx, } if (ctx->Pack.BufferObj) { - ctx->Driver.UnmapBuffer(ctx, ctx->Pack.BufferObj, MAP_INTERNAL); + _mesa_bufferobj_unmap(ctx, ctx->Pack.BufferObj, MAP_INTERNAL); } } @@ -875,7 +876,7 @@ legal_getteximage_target(struct gl_context *ctx, GLenum target, bool dsa) case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return dsa ? GL_FALSE : ctx->Extensions.ARB_texture_cube_map; + return dsa ? GL_FALSE : GL_TRUE; case GL_TEXTURE_CUBE_MAP: return dsa ? GL_TRUE : GL_FALSE; default: @@ -1392,7 +1393,7 @@ get_texture_image(struct gl_context *ctx, { struct gl_texture_image *texImage; unsigned firstFace, numFaces, i; - GLint imageStride; + intptr_t imageStride; FLUSH_VERTICES(ctx, 0, 0); @@ -1428,15 +1429,18 @@ get_texture_image(struct gl_context *ctx, numFaces = 1; } + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + _mesa_lock_texture(ctx, texObj); for (i = 0; i < numFaces; i++) { texImage = texObj->Image[firstFace + i][level]; assert(texImage); - ctx->Driver.GetTexSubImage(ctx, xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, texImage); + st_GetTexSubImage(ctx, xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, texImage); /* next cube face */ pixels = (GLubyte *) pixels + imageStride; @@ -1804,6 +1808,9 @@ get_compressed_texture_image(struct gl_context *ctx, numFaces = 1; } + if (ctx->Pack.BufferObj) + ctx->Pack.BufferObj->UsageHistory |= USAGE_PIXEL_PACK_BUFFER; + _mesa_lock_texture(ctx, texObj); for (i = 0; i < numFaces; i++) { diff --git a/src/mesa/main/texgetimage.h b/src/mesa/main/texgetimage.h index ab31eaa8f44..98e0de9bc30 100644 --- a/src/mesa/main/texgetimage.h +++ b/src/mesa/main/texgetimage.h @@ -27,7 +27,7 @@ #ifndef TEXGETIMAGE_H #define TEXGETIMAGE_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; struct gl_texture_image; @@ -51,56 +51,4 @@ _mesa_get_compressed_texture_image( struct gl_context *ctx, GLsizei bufSize, GLvoid *pixels, bool dsa ); - -extern void GLAPIENTRY -_mesa_GetTexImage( GLenum target, GLint level, - GLenum format, GLenum type, GLvoid *pixels ); -extern void GLAPIENTRY -_mesa_GetnTexImageARB( GLenum target, GLint level, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *pixels ); -extern void GLAPIENTRY -_mesa_GetTextureImage(GLuint texture, GLint level, GLenum format, - GLenum type, GLsizei bufSize, GLvoid *pixels); -extern void GLAPIENTRY -_mesa_GetTextureImageEXT( GLuint texture, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_GetMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, - GLenum format, GLenum type, GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_GetTextureSubImage(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, GLsizei bufSize, - void *pixels); - - -extern void GLAPIENTRY -_mesa_GetCompressedTexImage(GLenum target, GLint lod, GLvoid *img); - -extern void GLAPIENTRY -_mesa_GetnCompressedTexImageARB(GLenum target, GLint level, GLsizei bufSize, - GLvoid *img); - -extern void GLAPIENTRY -_mesa_GetCompressedTextureImage(GLuint texture, GLint level, GLsizei bufSize, - GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_GetCompressedTextureImageEXT(GLuint texture, GLenum target, GLint level, - GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_GetCompressedMultiTexImageEXT(GLenum texunit, GLenum target, GLint level, - GLvoid *pixels); - -extern void APIENTRY -_mesa_GetCompressedTextureSubImage(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, - GLsizei bufSize, void *pixels); - #endif /* TEXGETIMAGE_H */ diff --git a/src/mesa/main/teximage.c b/src/mesa/main/teximage.c index e97753ef459..b10c1a3fc02 100644 --- a/src/mesa/main/teximage.c +++ b/src/mesa/main/teximage.c @@ -30,7 +30,7 @@ */ #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "context.h" #include "enums.h" @@ -56,14 +56,18 @@ #include "glformats.h" #include "texstore.h" #include "pbo.h" +#include "api_exec_decl.h" +#include "util/u_memory.h" -/** - * State changes which we care about for glCopyTex[Sub]Image() calls. - * In particular, we care about pixel transfer state and buffer state - * (such as glReadBuffer to make sure we read from the right renderbuffer). - */ -#define NEW_COPY_TEX_STATE (_NEW_BUFFERS | _NEW_PIXEL) +#include "program/prog_instruction.h" + +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_format.h" +#include "state_tracker/st_gen_mipmap.h" +#include "state_tracker/st_cb_eglimage.h" +#include "state_tracker/st_sampler_view.h" /** * Returns a corresponding internal floating point format for a given base @@ -206,7 +210,7 @@ set_tex_image(struct gl_texture_object *tObj, /** * Free a gl_texture_image and associated data. - * This function is a fallback called via ctx->Driver.DeleteTextureImage(). + * This function is a fallback. * * \param texImage texture image. * @@ -219,9 +223,8 @@ _mesa_delete_texture_image(struct gl_context *ctx, /* Free texImage->Data and/or any other driver-specific texture * image storage. */ - assert(ctx->Driver.FreeTextureImageBuffer); - ctx->Driver.FreeTextureImageBuffer( ctx, texImage ); - free(texImage); + st_FreeTextureImageBuffer( ctx, texImage ); + FREE(texImage); } @@ -394,7 +397,7 @@ _mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj, texImage = _mesa_select_tex_image(texObj, target, level); if (!texImage) { - texImage = ctx->Driver.NewTextureImage(ctx); + texImage = CALLOC_STRUCT(gl_texture_image); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "texture image allocation"); return NULL; @@ -461,7 +464,7 @@ get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level) texImage = ctx->Texture.ProxyTex[texIndex]->Image[0][level]; if (!texImage) { - texImage = ctx->Driver.NewTextureImage(ctx); + texImage = CALLOC_STRUCT(gl_texture_image); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "proxy texture allocation"); return NULL; @@ -496,7 +499,8 @@ _mesa_max_texture_levels(const struct gl_context *ctx, GLenum target) return ffs(util_next_power_of_two(ctx->Const.MaxTextureSize)); case GL_TEXTURE_3D: case GL_PROXY_TEXTURE_3D: - return ctx->Const.Max3DTextureLevels; + return !(_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D) + ? ctx->Const.Max3DTextureLevels : 0; case GL_TEXTURE_CUBE_MAP: case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: @@ -505,8 +509,7 @@ _mesa_max_texture_levels(const struct gl_context *ctx, GLenum target) case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_PROXY_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map - ? ctx->Const.MaxCubeTextureLevels : 0; + return ctx->Const.MaxCubeTextureLevels; case GL_TEXTURE_RECTANGLE_NV: case GL_PROXY_TEXTURE_RECTANGLE_NV: return ctx->Extensions.NV_texture_rectangle ? 1 : 0; @@ -736,7 +739,7 @@ make_null_texture(GLint width, GLint height, GLint depth, GLenum format) const GLint numPixels = width * height * depth; GLubyte *data = (GLubyte *) malloc(numPixels * components * sizeof(GLubyte)); -#ifdef DEBUG +#if MESA_DEBUG /* * Let's see if anyone finds this. If glTexImage2D() is called with * a NULL image pointer then load the texture image with something @@ -794,14 +797,105 @@ clear_teximage_fields(struct gl_texture_image *img) img->Width2 = 0; img->Height2 = 0; img->Depth2 = 0; - img->WidthLog2 = 0; - img->HeightLog2 = 0; - img->DepthLog2 = 0; img->TexFormat = MESA_FORMAT_NONE; img->NumSamples = 0; img->FixedSampleLocations = GL_TRUE; } +/** + * Given a user-specified texture base format, the actual gallium texture + * format and the current GL_DEPTH_MODE, return a texture swizzle. + * + * Consider the case where the user requests a GL_RGB internal texture + * format the driver actually uses an RGBA format. The A component should + * be ignored and sampling from the texture should always return (r,g,b,1). + * But if we rendered to the texture we might have written A values != 1. + * By sampling the texture with a ".xyz1" swizzle we'll get the expected A=1. + * This function computes the texture swizzle needed to get the expected + * values. + * + * In the case of depth textures, the GL_DEPTH_MODE state determines the + * texture swizzle. + * + * This result must be composed with the user-specified swizzle to get + * the final swizzle. + */ +static unsigned +compute_texture_format_swizzle(GLenum baseFormat, GLenum depthMode, + bool glsl130_or_later) +{ + switch (baseFormat) { + case GL_RGBA: + return SWIZZLE_XYZW; + case GL_RGB: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_Z, SWIZZLE_ONE); + case GL_RG: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_Y, SWIZZLE_ZERO, SWIZZLE_ONE); + case GL_RED: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, + SWIZZLE_ZERO, SWIZZLE_ONE); + case GL_ALPHA: + return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, + SWIZZLE_ZERO, SWIZZLE_W); + case GL_LUMINANCE: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE); + case GL_LUMINANCE_ALPHA: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_W); + case GL_INTENSITY: + return SWIZZLE_XXXX; + case GL_STENCIL_INDEX: + case GL_DEPTH_STENCIL: + case GL_DEPTH_COMPONENT: + /* Now examine the depth mode */ + switch (depthMode) { + case GL_LUMINANCE: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_ONE); + case GL_INTENSITY: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_X, SWIZZLE_X, SWIZZLE_X); + case GL_ALPHA: + /* The texture(sampler*Shadow) functions from GLSL 1.30 ignore + * the depth mode and return float, while older shadow* functions + * and ARB_fp instructions return vec4 according to the depth mode. + * + * The problem with the GLSL 1.30 functions is that GL_ALPHA forces + * them to return 0, breaking them completely. + * + * A proper fix would increase code complexity and that's not worth + * it for a rarely used feature such as the GL_ALPHA depth mode + * in GL3. Therefore, change GL_ALPHA to GL_INTENSITY for all + * shaders that use GLSL 1.30 or later. + * + * BTW, it's required that sampler views are updated when + * shaders change (check_sampler_swizzle takes care of that). + */ + if (glsl130_or_later) + return SWIZZLE_XXXX; + else + return MAKE_SWIZZLE4(SWIZZLE_ZERO, SWIZZLE_ZERO, + SWIZZLE_ZERO, SWIZZLE_X); + case GL_RED: + return MAKE_SWIZZLE4(SWIZZLE_X, SWIZZLE_ZERO, + SWIZZLE_ZERO, SWIZZLE_ONE); + default: + assert(!"Unexpected depthMode"); + return SWIZZLE_XYZW; + } + default: + assert(!"Unexpected baseFormat"); + return SWIZZLE_XYZW; + } +} + +void +_mesa_update_teximage_format_swizzle(struct gl_context *ctx, + struct gl_texture_image *img, + GLenum depth_mode) +{ + if (!img) + return; + img->FormatSwizzle = compute_texture_format_swizzle(img->_BaseFormat, depth_mode, false); + img->FormatSwizzleGLSL130 = compute_texture_format_swizzle(img->_BaseFormat, depth_mode, true); +} /** * Initialize basic fields of the gl_texture_image struct. @@ -844,8 +938,23 @@ _mesa_init_teximage_fields_ms(struct gl_context *ctx, img->Height = height; img->Depth = depth; - img->Width2 = width - 2 * border; /* == 1 << img->WidthLog2; */ - img->WidthLog2 = util_logbase2(img->Width2); + GLenum depth_mode = _mesa_is_desktop_gl_core(ctx) ? GL_RED : GL_LUMINANCE; + + /* In ES 3.0, DEPTH_TEXTURE_MODE is expected to be GL_RED for textures + * with depth component data specified with a sized internal format. + */ + if (_mesa_is_gles3(ctx) && + (base_format == GL_DEPTH_COMPONENT || + base_format == GL_DEPTH_STENCIL || + base_format == GL_STENCIL_INDEX)) { + if (internalFormat != GL_DEPTH_COMPONENT && + internalFormat != GL_DEPTH_STENCIL && + internalFormat != GL_STENCIL_INDEX) + depth_mode = GL_RED; + } + _mesa_update_teximage_format_swizzle(ctx, img, depth_mode); + + img->Width2 = width - 2 * border; switch(target) { case GL_TEXTURE_1D: @@ -855,22 +964,18 @@ _mesa_init_teximage_fields_ms(struct gl_context *ctx, img->Height2 = 0; else img->Height2 = 1; - img->HeightLog2 = 0; if (depth == 0) img->Depth2 = 0; else img->Depth2 = 1; - img->DepthLog2 = 0; break; case GL_TEXTURE_1D_ARRAY: case GL_PROXY_TEXTURE_1D_ARRAY: img->Height2 = height; /* no border */ - img->HeightLog2 = 0; /* not used */ if (depth == 0) img->Depth2 = 0; else img->Depth2 = 1; - img->DepthLog2 = 0; break; case GL_TEXTURE_2D: case GL_TEXTURE_RECTANGLE: @@ -887,13 +992,11 @@ _mesa_init_teximage_fields_ms(struct gl_context *ctx, case GL_PROXY_TEXTURE_CUBE_MAP: case GL_TEXTURE_2D_MULTISAMPLE: case GL_PROXY_TEXTURE_2D_MULTISAMPLE: - img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ - img->HeightLog2 = util_logbase2(img->Height2); + img->Height2 = height - 2 * border; if (depth == 0) img->Depth2 = 0; else img->Depth2 = 1; - img->DepthLog2 = 0; break; case GL_TEXTURE_2D_ARRAY: case GL_PROXY_TEXTURE_2D_ARRAY: @@ -901,17 +1004,13 @@ _mesa_init_teximage_fields_ms(struct gl_context *ctx, case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: case GL_PROXY_TEXTURE_2D_MULTISAMPLE_ARRAY: - img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ - img->HeightLog2 = util_logbase2(img->Height2); + img->Height2 = height - 2 * border; img->Depth2 = depth; /* no border */ - img->DepthLog2 = 0; /* not used */ break; case GL_TEXTURE_3D: case GL_PROXY_TEXTURE_3D: - img->Height2 = height - 2 * border; /* == 1 << img->HeightLog2; */ - img->HeightLog2 = util_logbase2(img->Height2); - img->Depth2 = depth - 2 * border; /* == 1 << img->DepthLog2; */ - img->DepthLog2 = util_logbase2(img->Depth2); + img->Height2 = height - 2 * border; + img->Depth2 = depth - 2 * border; break; default: _mesa_problem(NULL, "invalid target 0x%x in _mesa_init_teximage_fields()", @@ -952,7 +1051,7 @@ void _mesa_clear_texture_image(struct gl_context *ctx, struct gl_texture_image *texImage) { - ctx->Driver.FreeTextureImageBuffer(ctx, texImage); + st_FreeTextureImageBuffer(ctx, texImage); clear_teximage_fields(texImage); } @@ -1403,7 +1502,7 @@ _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - target_can_be_compresed = ctx->Extensions.ARB_texture_cube_map; + target_can_be_compresed = GL_TRUE; break; case GL_PROXY_TEXTURE_2D_ARRAY_EXT: case GL_TEXTURE_2D_ARRAY_EXT: @@ -1471,13 +1570,32 @@ _mesa_target_can_be_compressed(const struct gl_context *ctx, GLenum target, case GL_TEXTURE_3D: switch (layout) { case MESA_FORMAT_LAYOUT_ETC2: - /* See ETC2/EAC comment in case GL_TEXTURE_CUBE_MAP_ARRAY. */ - if (_mesa_is_gles3(ctx)) - return write_error(error, GL_INVALID_OPERATION); - break; + case MESA_FORMAT_LAYOUT_RGTC: + /* From the OpenGL 4.4 compatibility spec: + * An INVALID_OPERATION error is generated by TexImage3D if + * internalformat is one of the EAC, ETC2, or RGTC compressed + * formats and either border is non-zero, or target is not + * TEXTURE_2D_ARRAY. + */ + return write_error(error, GL_INVALID_OPERATION); case MESA_FORMAT_LAYOUT_BPTC: target_can_be_compresed = ctx->Extensions.ARB_texture_compression_bptc; break; + case MESA_FORMAT_LAYOUT_S3TC: + /* From the EXT_texture_compression_s3tc spec: + * + * In extended OpenGL ES 3.0.2 these new tokens are also accepted by the + * <internalformat> parameter of TexImage3D, CompressedTexImage3D, + * TexStorage2D, TexStorage3D and the <format> parameter of + * CompressedTexSubImage3D. + * + * The spec does not clarify whether the same applies to newer desktop GL versions + * (where 3D textures were introduced), check compatibility ext to be safe. + */ + target_can_be_compresed = + ctx->Extensions.EXT_texture_compression_s3tc && + (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility); + break; case MESA_FORMAT_LAYOUT_ASTC: target_can_be_compresed = ctx->Extensions.KHR_texture_compression_astc_hdr || @@ -1525,15 +1643,14 @@ legal_teximage_target(struct gl_context *ctx, GLuint dims, GLenum target) case GL_PROXY_TEXTURE_2D: return _mesa_is_desktop_gl(ctx); case GL_PROXY_TEXTURE_CUBE_MAP: - return _mesa_is_desktop_gl(ctx) - && ctx->Extensions.ARB_texture_cube_map; + return _mesa_is_desktop_gl(ctx); case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return ctx->Extensions.ARB_texture_cube_map; + return GL_TRUE; case GL_TEXTURE_RECTANGLE_NV: case GL_PROXY_TEXTURE_RECTANGLE_NV: return _mesa_is_desktop_gl(ctx) @@ -1591,7 +1708,7 @@ legal_texsubimage_target(struct gl_context *ctx, GLuint dims, GLenum target, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return ctx->Extensions.ARB_texture_cube_map; + return GL_TRUE; case GL_TEXTURE_RECTANGLE_NV: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle; @@ -1714,7 +1831,7 @@ _mesa_legal_texture_base_format_for_target(struct gl_context *ctx, target == GL_TEXTURE_CUBE_MAP || target == GL_PROXY_TEXTURE_CUBE_MAP) && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4 - || (ctx->API == API_OPENGLES2 && ctx->Extensions.OES_depth_texture_cube_map))) && + || (_mesa_is_gles2(ctx) && ctx->Extensions.OES_depth_texture_cube_map))) && !((target == GL_TEXTURE_CUBE_MAP_ARRAY || target == GL_PROXY_TEXTURE_CUBE_MAP_ARRAY) && _mesa_has_texture_cube_map_array(ctx))) { @@ -2099,7 +2216,7 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, /* No compressed formats support borders at this time */ if (border != 0) { reason = "border != 0"; - error = GL_INVALID_VALUE; + error = _mesa_is_desktop_gl(ctx) ? GL_INVALID_OPERATION : GL_INVALID_VALUE; goto error; } @@ -2294,13 +2411,6 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, struct gl_renderbuffer *rb; GLenum rb_internal_format; - /* check target */ - if (!legal_texsubimage_target(ctx, dimensions, target, false)) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", - dimensions, _mesa_enum_to_string(target)); - return GL_TRUE; - } - /* level check */ if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { _mesa_error(ctx, GL_INVALID_VALUE, @@ -2319,7 +2429,8 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } - if (ctx->ReadBuffer->Visual.samples > 0) { + if (!ctx->st_opts->allow_multisampled_copyteximage && + ctx->ReadBuffer->Visual.samples > 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%dD(multisample FBO)", dimensions); return GL_TRUE; @@ -2346,7 +2457,34 @@ copytexture_error_check( struct gl_context *ctx, GLuint dimensions, case GL_RGBA: case GL_LUMINANCE: case GL_LUMINANCE_ALPHA: + + /* Added by GL_OES_required_internalformat (always enabled) in table 3.4.y.*/ + case GL_ALPHA8: + case GL_LUMINANCE8: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE4_ALPHA4: + case GL_RGB565: + case GL_RGB8: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT24: + case GL_DEPTH_COMPONENT32: + case GL_DEPTH24_STENCIL8: + case GL_RGB10: + case GL_RGB10_A2: break; + + case GL_RED: + case GL_RG: + /* GL_EXT_texture_rg adds support for GL_RED and GL_RG as an internal + * format + */ + if (_mesa_has_EXT_texture_rg(ctx)) + break; + + FALLTHROUGH; default: _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%dD(internalFormat=%s)", dimensions, @@ -2568,9 +2706,29 @@ copytexsubimage_error_check(struct gl_context *ctx, GLuint dimensions, return GL_TRUE; } - if (ctx->ReadBuffer->Visual.samples > 0) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "%s(multisample FBO)", caller); + /** + * From the GL_EXT_multisampled_render_to_texture spec: + * + * "An INVALID_OPERATION error is generated by CopyTexSubImage3D, + * CopyTexImage2D, or CopyTexSubImage2D if [...] the value of + * READ_FRAMEBUFFER_BINDING is non-zero, and: + * - the read buffer selects an attachment that has no image attached, + * or + * - the value of SAMPLE_BUFFERS for the read framebuffer is one." + * + * [...] + * These errors do not apply to textures and renderbuffers that have + * associated multisample data specified by the mechanisms described in + * this extension, i.e., the above operations are allowed even when + * SAMPLE_BUFFERS is non-zero for renderbuffers created via Renderbuffer- + * StorageMultisampleEXT or textures attached via FramebufferTexture2D- + * MultisampleEXT. + */ + if (!ctx->st_opts->allow_multisampled_copyteximage && + ctx->ReadBuffer->Visual.samples > 0 && + !_mesa_has_rtt_samples(ctx->ReadBuffer)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(multisample FBO)", + caller); return GL_TRUE; } } @@ -2732,7 +2890,7 @@ _mesa_update_fbo_texture(struct gl_context *ctx, info.texObj = texObj; info.level = level; info.face = face; - _mesa_HashWalk(ctx->Shared->FrameBuffers, check_rtt_cb, &info); + _mesa_HashWalk(&ctx->Shared->FrameBuffers, check_rtt_cb, &info); } } @@ -2749,8 +2907,7 @@ check_gen_mipmap(struct gl_context *ctx, GLenum target, if (texObj->Attrib.GenerateMipmap && level == texObj->Attrib.BaseLevel && level < texObj->Attrib.MaxLevel) { - assert(ctx->Driver.GenerateMipmap); - ctx->Driver.GenerateMipmap(ctx, target, texObj); + st_generate_mipmap(ctx, target, texObj); } } @@ -2814,7 +2971,7 @@ _mesa_choose_texture_format(struct gl_context *ctx, GLenum target, GLint level, GLenum internalFormat, GLenum format, GLenum type) { - mesa_format f; + mesa_format f = MESA_FORMAT_NONE; /* see if we've already chosen a format for the previous level */ if (level > 0) { @@ -2832,8 +2989,8 @@ _mesa_choose_texture_format(struct gl_context *ctx, } } - f = ctx->Driver.ChooseTextureFormat(ctx, target, internalFormat, - format, type); + f = st_ChooseTextureFormat(ctx, target, internalFormat, + format, type); assert(f != MESA_FORMAT_NONE); return f; } @@ -2917,23 +3074,21 @@ lookup_texture_ext_dsa(struct gl_context *ctx, GLenum target, GLuint texture, texObj = ctx->Shared->DefaultTex[targetIndex]; assert(texObj); } else { - bool isGenName; texObj = _mesa_lookup_texture(ctx, texture); - isGenName = texObj != NULL; - if (!texObj && ctx->API == API_OPENGL_CORE) { + if (!texObj && _mesa_is_desktop_gl_core(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller); return NULL; } if (!texObj) { - texObj = ctx->Driver.NewTextureObject(ctx, texture, boundTarget); + texObj = _mesa_new_texture_object(ctx, texture, boundTarget); if (!texObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); return NULL; } /* insert into hash table */ - _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj, isGenName); + _mesa_HashInsert(&ctx->Shared->TexObjects, texObj->Name, texObj); } if (texObj->Target != boundTarget) { @@ -3024,7 +3179,7 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, * call by decompressing the texture. If we really want to support cpal * textures in any driver this would have to be changed. */ - if (ctx->API == API_OPENGLES && compressed && dims == 2) { + if (_mesa_is_gles1(ctx) && compressed && dims == 2) { switch (internalFormat) { case GL_PALETTE4_RGB8_OES: case GL_PALETTE4_RGBA8_OES: @@ -3075,9 +3230,9 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, height, depth, border); /* check that the texture won't take too much memory, etc */ - sizeOK = ctx->Driver.TestProxyTexImage(ctx, proxy_target(target), - 0, level, texFormat, 1, - width, height, depth); + sizeOK = st_TestProxyTexImage(ctx, proxy_target(target), + 0, level, texFormat, 1, + width, height, depth); } if (_mesa_is_proxy_texture(target)) { @@ -3120,25 +3275,26 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, * reliable but slightly incorrect hardware rendering instead of * rarely-tested software fallback rendering. */ - if (border && ctx->Const.StripTextureBorder) { + if (border) { strip_texture_border(target, &width, &height, &depth, unpack, &unpack_no_border); border = 0; unpack = &unpack_no_border; } - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); _mesa_lock_texture(ctx, texObj); { + texObj->External = GL_FALSE; + texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s%uD", func, dims); } else { - ctx->Driver.FreeTextureImageBuffer(ctx, texImage); + st_FreeTextureImageBuffer(ctx, texImage); _mesa_init_teximage_fields(ctx, texImage, width, height, depth, @@ -3147,12 +3303,12 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, /* Give the texture to the driver. <pixels> may be null. */ if (width > 0 && height > 0 && depth > 0) { if (compressed) { - ctx->Driver.CompressedTexImage(ctx, dims, texImage, - imageSize, pixels); + st_CompressedTexImage(ctx, dims, texImage, + imageSize, pixels); } else { - ctx->Driver.TexImage(ctx, dims, texImage, format, - type, pixels, unpack); + st_TexImage(ctx, dims, texImage, format, + type, pixels, unpack); } } @@ -3161,6 +3317,11 @@ teximage(struct gl_context *ctx, GLboolean compressed, GLuint dims, _mesa_update_fbo_texture(ctx, texObj, face, level); _mesa_dirty_texobj(ctx, texObj); + /* only apply depthMode swizzle if it was explicitly changed */ + GLenum depth_mode = _mesa_is_desktop_gl_core(ctx) ? GL_RED : GL_LUMINANCE; + if (texObj->Attrib.DepthMode != depth_mode) + _mesa_update_teximage_format_swizzle(ctx, texObj->Image[0][texObj->Attrib.BaseLevel], texObj->Attrib.DepthMode); + _mesa_update_texture_object_swizzle(ctx, texObj); } } _mesa_unlock_texture(ctx, texObj); @@ -3343,17 +3504,6 @@ _mesa_MultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, void GLAPIENTRY -_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalFormat, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum format, GLenum type, - const GLvoid *pixels ) -{ - _mesa_TexImage3D(target, level, (GLint) internalFormat, width, height, - depth, border, format, type, pixels); -} - - -void GLAPIENTRY _mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalFormat, GLsizei width, GLint border, GLenum format, GLenum type, const GLvoid *pixels) @@ -3397,29 +3547,15 @@ egl_image_target_texture(struct gl_context *ctx, const char *caller) { struct gl_texture_image *texImage; - bool valid_target; FLUSH_VERTICES(ctx, 0, 0); - switch (target) { - case GL_TEXTURE_2D: - valid_target = _mesa_has_OES_EGL_image(ctx) || - (tex_storage && _mesa_has_EXT_EGL_image_storage(ctx)); - break; - case GL_TEXTURE_EXTERNAL_OES: - valid_target = - _mesa_is_gles(ctx) ? _mesa_has_OES_EGL_image_external(ctx) : false; - break; - default: - valid_target = false; - break; - } - - if (!valid_target) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%d)", caller, target); + if (!texObj) + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) return; - } - if (!image) { + if (!image || (ctx->Driver.ValidateEGLImage && + !ctx->Driver.ValidateEGLImage(ctx, image))) { _mesa_error(ctx, GL_INVALID_VALUE, "%s(image=%p)", caller, image); return; } @@ -3436,39 +3572,76 @@ egl_image_target_texture(struct gl_context *ctx, if (!texImage) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); } else { - ctx->Driver.FreeTextureImageBuffer(ctx, texImage); + st_FreeTextureImageBuffer(ctx, texImage); + + texObj->External = GL_TRUE; + + struct st_egl_image stimg; + bool native_supported; + if (!st_get_egl_image(ctx, image, PIPE_BIND_SAMPLER_VIEW, caller, + &stimg, &native_supported)) { + _mesa_unlock_texture(ctx, texObj); + return; + } if (tex_storage) { - ctx->Driver.EGLImageTargetTexStorage(ctx, target, texObj, texImage, - image); + /* EXT_EGL_image_storage + * If the EGL image was created using EGL_EXT_image_dma_buf_import, + * then the following applies: + * - <target> must be GL_TEXTURE_2D or GL_TEXTURE_EXTERNAL_OES. + * Otherwise, the error INVALID_OPERATION is generated. + */ + if (stimg.imported_dmabuf && + !(target == GL_TEXTURE_2D || target == GL_TEXTURE_EXTERNAL_OES)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(texture is imported from dmabuf)", caller); + pipe_resource_reference(&stimg.texture, NULL); + _mesa_unlock_texture(ctx, texObj); + return; + } + st_bind_egl_image(ctx, texObj, texImage, &stimg, true, native_supported); } else { - ctx->Driver.EGLImageTargetTexture2D(ctx, target, texObj, texImage, - image); + st_bind_egl_image(ctx, texObj, texImage, &stimg, + target != GL_TEXTURE_EXTERNAL_OES, native_supported); } + pipe_resource_reference(&stimg.texture, NULL); + _mesa_dirty_texobj(ctx, texObj); } if (tex_storage) _mesa_set_texture_view_state(ctx, texObj, target, 1); + _mesa_update_fbo_texture(ctx, texObj, 0, 0); + _mesa_unlock_texture(ctx, texObj); } void GLAPIENTRY _mesa_EGLImageTargetTexture2DOES(GLenum target, GLeglImageOES image) { - struct gl_texture_object *texObj; const char *func = "glEGLImageTargetTexture2D"; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%d)", func, target); - return; + bool valid_target; + switch (target) { + case GL_TEXTURE_2D: + valid_target = _mesa_has_OES_EGL_image(ctx); + break; + case GL_TEXTURE_EXTERNAL_OES: + valid_target = _mesa_has_OES_EGL_image_external(ctx); + break; + default: + valid_target = false; + break; } - egl_image_target_texture(ctx, texObj, target, image, false, func); + if (valid_target) { + egl_image_target_texture(ctx, NULL, target, image, false, func); + } else { + _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%d)", func, target); + } } static void @@ -3487,22 +3660,42 @@ egl_image_target_texture_storage(struct gl_context *ctx, return; } + /* + * <target> must be one of GL_TEXTURE_2D, GL_TEXTURE_2D_ARRAY, + * GL_TEXTURE_3D, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_CUBE_MAP_ARRAY. On + * OpenGL implementations (non-ES), <target> can also be GL_TEXTURE_1D or + * GL_TEXTURE_1D_ARRAY. + * If the implementation supports OES_EGL_image_external, <target> can be + * GL_TEXTURE_EXTERNAL_OES. + */ + bool valid_target; switch (target) { case GL_TEXTURE_2D: + case GL_TEXTURE_2D_ARRAY: + case GL_TEXTURE_3D: + case GL_TEXTURE_CUBE_MAP: + case GL_TEXTURE_CUBE_MAP_ARRAY: + valid_target = true; + break; + case GL_TEXTURE_1D: + case GL_TEXTURE_1D_ARRAY: + /* No eglImageOES for 1D textures */ + valid_target = !_mesa_is_gles(ctx); + break; case GL_TEXTURE_EXTERNAL_OES: + valid_target = _mesa_has_OES_EGL_image_external(ctx); break; default: - /* - * The EXT_EGL_image_storage spec allows for many other targets besides - * GL_TEXTURE_2D and GL_TEXTURE_EXTERNAL_OES, however these are complicated - * to implement. - */ - _mesa_error(ctx, GL_INVALID_OPERATION, "%s(unsupported target=%d)", - caller, target); - return; + valid_target = false; + break; + } + + if (valid_target) { + egl_image_target_texture(ctx, texObj, target, image, true, caller); + } else { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(target=%d)", caller, target); } - egl_image_target_texture(ctx, texObj, target, image, true, caller); } @@ -3510,17 +3703,17 @@ void GLAPIENTRY _mesa_EGLImageTargetTexStorageEXT(GLenum target, GLeglImageOES image, const GLint *attrib_list) { - struct gl_texture_object *texObj; const char *func = "glEGLImageTargetTexStorageEXT"; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) { - _mesa_error(ctx, GL_INVALID_ENUM, "%s(target=%d)", func, target); + if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 42) && + !_mesa_is_gles3(ctx) && !_mesa_has_ARB_texture_storage(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "OpenGL 4.2, OpenGL ES 3.0 or ARB_texture_storage required"); return; } - egl_image_target_texture_storage(ctx, texObj, target, image, attrib_list, + egl_image_target_texture_storage(ctx, NULL, target, image, attrib_list, func); } @@ -3532,13 +3725,19 @@ _mesa_EGLImageTargetTextureStorageEXT(GLuint texture, GLeglImageOES image, const char *func = "glEGLImageTargetTextureStorageEXT"; GET_CURRENT_CONTEXT(ctx); - if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 45) && - !_mesa_has_ARB_direct_state_access(ctx) && + if (!_mesa_has_ARB_direct_state_access(ctx) && !_mesa_has_EXT_direct_state_access(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "direct access not supported"); return; } + if (!(_mesa_is_desktop_gl(ctx) && ctx->Version >= 42) && + !_mesa_is_gles3(ctx) && !_mesa_has_ARB_texture_storage(ctx)) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "OpenGL 4.2, OpenGL ES 3.0 or ARB_texture_storage required"); + return; + } + texObj = _mesa_lookup_texture_err(ctx, texture, func); if (!texObj) return; @@ -3562,8 +3761,7 @@ texture_sub_image(struct gl_context *ctx, GLuint dims, { FLUSH_VERTICES(ctx, 0, 0); - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); _mesa_lock_texture(ctx, texObj); { @@ -3582,10 +3780,10 @@ texture_sub_image(struct gl_context *ctx, GLuint dims, xoffset += texImage->Border; } - ctx->Driver.TexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, - width, height, depth, - format, type, pixels, &ctx->Unpack); + st_TexSubImage(ctx, dims, texImage, + xoffset, yoffset, zoffset, + width, height, depth, + format, type, pixels, &ctx->Unpack); check_gen_mipmap(ctx, target, texObj, level); @@ -3719,7 +3917,7 @@ texturesubimage(struct gl_context *ctx, GLuint dims, /* Must handle special case GL_TEXTURE_CUBE_MAP. */ if (texObj->Target == GL_TEXTURE_CUBE_MAP) { - GLint imageStride; + intptr_t imageStride; /* * What do we do if the user created a texture with the following code @@ -4121,14 +4319,14 @@ copytexsubimage_by_slice(struct gl_context *ctx, for (slice = 0; slice < height; slice++) { assert(yoffset + slice < texImage->Height); - ctx->Driver.CopyTexSubImage(ctx, 2, texImage, - xoffset, 0, yoffset + slice, - rb, x, y + slice, width, 1); + st_CopyTexSubImage(ctx, 2, texImage, + xoffset, 0, yoffset + slice, + rb, x, y + slice, width, 1); } } else { - ctx->Driver.CopyTexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, - rb, x, y, width, height); + st_CopyTexSubImage(ctx, dims, texImage, + xoffset, yoffset, zoffset, + rb, x, y, width, height); } } @@ -4246,10 +4444,9 @@ copy_texture_sub_image_err(struct gl_context *ctx, GLuint dims, _mesa_enum_to_string(target), level, xoffset, yoffset, zoffset, x, y, width, height); - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); - if (ctx->NewState & NEW_COPY_TEX_STATE) + if (ctx->NewState & _NEW_BUFFERS) _mesa_update_state(ctx); if (copytexsubimage_error_check(ctx, dims, texObj, target, level, @@ -4272,10 +4469,9 @@ copy_texture_sub_image_no_error(struct gl_context *ctx, GLuint dims, { FLUSH_VERTICES(ctx, 0, 0); - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); - if (ctx->NewState & NEW_COPY_TEX_STATE) + if (ctx->NewState & _NEW_BUFFERS) _mesa_update_state(ctx); copy_texture_sub_image(ctx, dims, texObj, target, level, xoffset, yoffset, @@ -4304,12 +4500,21 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texO _mesa_enum_to_string(internalFormat), x, y, width, height, border); - if (ctx->NewState & _NEW_PIXEL) - _mesa_update_pixel(ctx); + _mesa_update_pixel(ctx); - if (ctx->NewState & NEW_COPY_TEX_STATE) + if (ctx->NewState & _NEW_BUFFERS) _mesa_update_state(ctx); + /* check target */ + if (!no_error && !legal_texsubimage_target(ctx, dims, target, false)) { + _mesa_error(ctx, GL_INVALID_ENUM, "glCopyTexImage%uD(target=%s)", + dims, _mesa_enum_to_string(target)); + return; + } + + if (!texObj) + texObj = _mesa_get_current_tex_object(ctx, target); + if (!no_error) { if (copytexture_error_check(ctx, dims, target, texObj, level, internalFormat, border)) @@ -4367,36 +4572,47 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texO return; } } - /* From Page 139 of OpenGL ES 3.0 spec: - * "If internalformat is sized, the internal format of the new texel - * array is internalformat, and this is also the new texel array’s - * effective internal format. If the component sizes of internalformat - * do not exactly match the corresponding component sizes of the source - * buffer’s effective internal format, described below, an - * INVALID_OPERATION error is generated. If internalformat is unsized, - * the internal format of the new texel array is the effective internal - * format of the source buffer, and this is also the new texel array’s - * effective internal format. - */ - else if (formats_differ_in_component_sizes (texFormat, rb->Format)) { + else { + /* From Page 139 of OpenGL ES 3.0 spec: + * "If internalformat is sized, the internal format of the new texel + * array is internalformat, and this is also the new texel array’s + * effective internal format. If the component sizes of internalformat + * do not exactly match the corresponding component sizes of the source + * buffer’s effective internal format, described below, an + * INVALID_OPERATION error is generated. If internalformat is unsized, + * the internal format of the new texel array is the effective internal + * format of the source buffer, and this is also the new texel array’s + * effective internal format. + */ + enum pipe_format rb_format = st_choose_format(ctx->st, rb->InternalFormat, + GL_NONE, GL_NONE, + PIPE_TEXTURE_2D, 0, 0, 0, + false, false); + enum pipe_format new_format = st_choose_format(ctx->st, internalFormat, + GL_NONE, GL_NONE, + PIPE_TEXTURE_2D, 0, 0, 0, + false, false); + /* this comparison must be done on the API format, not the driver format */ + if (formats_differ_in_component_sizes (new_format, rb_format)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glCopyTexImage%uD(component size changed in" " internal format)", dims); return; + } } } assert(texFormat != MESA_FORMAT_NONE); - if (!ctx->Driver.TestProxyTexImage(ctx, proxy_target(target), - 0, level, texFormat, 1, - width, height, 1)) { + if (!st_TestProxyTexImage(ctx, proxy_target(target), + 0, level, texFormat, 1, + width, height, 1)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage%uD(image too large)", dims); return; } - if (border && ctx->Const.StripTextureBorder) { + if (border) { x += border; width -= border * 2; if (dims == 2) { @@ -4408,6 +4624,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texO _mesa_lock_texture(ctx, texObj); { + texObj->External = GL_FALSE; texImage = _mesa_get_tex_image(ctx, texObj, target, level); if (!texImage) { @@ -4418,14 +4635,14 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texO const GLuint face = _mesa_tex_target_to_face(target); /* Free old texture image */ - ctx->Driver.FreeTextureImageBuffer(ctx, texImage); + st_FreeTextureImageBuffer(ctx, texImage); _mesa_init_teximage_fields(ctx, texImage, width, height, 1, border, internalFormat, texFormat); if (width && height) { /* Allocate texture memory (no pixel data yet) */ - ctx->Driver.AllocTextureImageBuffer(ctx, texImage); + st_AllocTextureImageBuffer(ctx, texImage); if (ctx->Const.NoClippingOnCopyTex || _mesa_clip_copytexsubimage(ctx, &dstX, &dstY, &srcX, &srcY, @@ -4444,6 +4661,7 @@ copyteximage(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texO _mesa_update_fbo_texture(ctx, texObj, face, level); _mesa_dirty_texobj(ctx, texObj); + _mesa_update_texture_object_swizzle(ctx, texObj); } } _mesa_unlock_texture(ctx, texObj); @@ -4456,8 +4674,7 @@ copyteximage_err(struct gl_context *ctx, GLuint dims, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); - copyteximage(ctx, dims, texObj, target, level, internalFormat, x, y, width, height, + copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height, border, false); } @@ -4467,8 +4684,7 @@ copyteximage_no_error(struct gl_context *ctx, GLuint dims, GLenum target, GLint level, GLenum internalFormat, GLint x, GLint y, GLsizei width, GLsizei height, GLint border) { - struct gl_texture_object* texObj = _mesa_get_current_tex_object(ctx, target); - copyteximage(ctx, dims, texObj, target, level, internalFormat, x, y, width, height, + copyteximage(ctx, dims, NULL, target, level, internalFormat, x, y, width, height, border, true); } @@ -5175,11 +5391,11 @@ _mesa_ClearTexSubImage(GLuint texture, GLint level, if (numImages == 1) { if (check_clear_tex_image(ctx, "glClearTexSubImage", texImages[0], format, type, data, clearValue[0])) { - ctx->Driver.ClearTexSubImage(ctx, - texImages[0], - xoffset, yoffset, zoffset, - width, height, depth, - data ? clearValue[0] : NULL); + st_ClearTexSubImage(ctx, + texImages[0], + xoffset, yoffset, zoffset, + width, height, depth, + data ? clearValue[0] : NULL); } } else { /* loop over cube face images */ @@ -5190,11 +5406,11 @@ _mesa_ClearTexSubImage(GLuint texture, GLint level, goto out; } for (i = zoffset; i < zoffset + depth; i++) { - ctx->Driver.ClearTexSubImage(ctx, - texImages[i], - xoffset, yoffset, 0, - width, height, 1, - data ? clearValue[i] : NULL); + st_ClearTexSubImage(ctx, + texImages[i], + xoffset, yoffset, 0, + width, height, 1, + data ? clearValue[i] : NULL); } } @@ -5230,14 +5446,14 @@ _mesa_ClearTexImage( GLuint texture, GLint level, } for (i = 0; i < numImages; i++) { - ctx->Driver.ClearTexSubImage(ctx, texImages[i], - -(GLint) texImages[i]->Border, /* xoffset */ - -(GLint) texImages[i]->Border, /* yoffset */ - -(GLint) texImages[i]->Border, /* zoffset */ - texImages[i]->Width, - texImages[i]->Height, - texImages[i]->Depth, - data ? clearValue[i] : NULL); + st_ClearTexSubImage(ctx, texImages[i], + -(GLint) texImages[i]->Border, /* xoffset */ + -(GLint) texImages[i]->Border, /* yoffset */ + -(GLint) texImages[i]->Border, /* zoffset */ + texImages[i]->Width, + texImages[i]->Height, + texImages[i]->Depth, + data ? clearValue[i] : NULL); } out: @@ -5285,7 +5501,7 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target, case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - targetOK = ctx->Extensions.ARB_texture_cube_map; + targetOK = GL_TRUE; break; default: targetOK = GL_FALSE; @@ -5295,7 +5511,7 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target, case 3: switch (target) { case GL_TEXTURE_CUBE_MAP: - targetOK = dsa && ctx->Extensions.ARB_texture_cube_map; + targetOK = dsa; break; case GL_TEXTURE_2D_ARRAY: targetOK = _mesa_is_gles3(ctx) || @@ -5353,6 +5569,11 @@ compressed_subtexture_target_check(struct gl_context *ctx, GLenum target, case MESA_FORMAT_LAYOUT_BPTC: /* valid format */ break; + case MESA_FORMAT_LAYOUT_S3TC: + targetOK = + ctx->Extensions.EXT_texture_compression_s3tc && + (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility); + break; case MESA_FORMAT_LAYOUT_ASTC: targetOK = ctx->Extensions.KHR_texture_compression_astc_hdr || @@ -5688,10 +5909,10 @@ compressed_texture_sub_image(struct gl_context *ctx, GLuint dims, _mesa_lock_texture(ctx, texObj); { if (width > 0 && height > 0 && depth > 0) { - ctx->Driver.CompressedTexSubImage(ctx, dims, texImage, - xoffset, yoffset, zoffset, - width, height, depth, - format, imageSize, data); + st_CompressedTexSubImage(ctx, dims, texImage, + xoffset, yoffset, zoffset, + width, height, depth, + format, imageSize, data); check_gen_mipmap(ctx, target, texObj, level); @@ -6092,7 +6313,7 @@ _mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, mesa_format _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat) { - if (ctx->API == API_OPENGL_COMPAT) { + if (_mesa_is_desktop_gl_compat(ctx)) { switch (internalFormat) { case GL_ALPHA8: return MESA_FORMAT_A_UNORM8; @@ -6324,6 +6545,7 @@ texture_buffer_range(struct gl_context *ctx, GLintptr oldOffset = texObj->BufferOffset; GLsizeiptr oldSize = texObj->BufferSize; mesa_format format; + mesa_format old_format; /* NOTE: ARB_texture_buffer_object might not be supported in * the compatibility profile. @@ -6361,22 +6583,25 @@ texture_buffer_range(struct gl_context *ctx, { _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, bufObj); texObj->BufferObjectFormat = internalFormat; + old_format = texObj->_BufferObjectFormat; texObj->_BufferObjectFormat = format; texObj->BufferOffset = offset; texObj->BufferSize = size; } _mesa_unlock_texture(ctx, texObj); - if (ctx->Driver.TexParameter) { + if (old_format != format) { + st_texture_release_all_sampler_views(st_context(ctx), texObj); + } else { if (offset != oldOffset) { - ctx->Driver.TexParameter(ctx, texObj, GL_TEXTURE_BUFFER_OFFSET); + st_texture_release_all_sampler_views(st_context(ctx), texObj); } if (size != oldSize) { - ctx->Driver.TexParameter(ctx, texObj, GL_TEXTURE_BUFFER_SIZE); + st_texture_release_all_sampler_views(st_context(ctx), texObj); } } - ctx->NewDriverState |= ctx->DriverFlags.NewTextureBuffer; + ctx->NewDriverState |= ST_NEW_SAMPLER_VIEWS; if (bufObj) { bufObj->UsageHistory |= USAGE_TEXTURE_BUFFER; @@ -6823,7 +7048,13 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims, return; } - if (immutable && (!texObj || (texObj->Name == 0))) { + if (!texObj) { + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) + return; + } + + if (immutable && texObj->Name == 0) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(texture object 0)", func); @@ -6844,8 +7075,8 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims, dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, width, height, depth, 0); - sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 0, 0, texFormat, - samples, width, height, depth); + sizeOK = st_TestProxyTexImage(ctx, target, 0, 0, texFormat, + samples, width, height, depth); if (_mesa_is_proxy_texture(target)) { if (samplesOK && dimensionsOK && sizeOK) { @@ -6876,7 +7107,12 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims, return; } - ctx->Driver.FreeTextureImageBuffer(ctx, texImage); + if (texObj->IsSparse && + _mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, 0, + width, height, depth, func)) + return; /* error was recorded */ + + st_FreeTextureImageBuffer(ctx, texImage); _mesa_init_teximage_fields_ms(ctx, texImage, width, height, depth, 0, internalformat, texFormat, @@ -6884,17 +7120,17 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims, if (width > 0 && height > 0 && depth > 0) { if (memObj) { - if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj, - memObj, 1, width, - height, depth, - offset)) { + if (!st_SetTextureStorageForMemoryObject(ctx, texObj, + memObj, 1, width, + height, depth, + offset, func)) { _mesa_init_teximage_fields(ctx, texImage, 0, 0, 0, 0, internalformat, texFormat); } } else { - if (!ctx->Driver.AllocTextureStorage(ctx, texObj, 1, - width, height, depth)) { + if (!st_AllocTextureStorage(ctx, texObj, 1, + width, height, depth, func)) { /* tidy up the texture image state. strictly speaking, * we're allowed to just leave this in whatever state we * like, but being tidy is good. @@ -6905,6 +7141,7 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims, } } + texObj->External = GL_FALSE; texObj->Immutable |= immutable; if (immutable) { @@ -6913,6 +7150,7 @@ texture_image_multisample(struct gl_context *ctx, GLuint dims, _mesa_update_fbo_texture(ctx, texObj, 0, 0); } + _mesa_update_texture_object_swizzle(ctx, texObj); } @@ -6921,14 +7159,9 @@ _mesa_TexImage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) - return; - - texture_image_multisample(ctx, 2, texObj, NULL, target, samples, + texture_image_multisample(ctx, 2, NULL, NULL, target, samples, internalformat, width, height, 1, fixedsamplelocations, GL_FALSE, 0, "glTexImage2DMultisample"); @@ -6941,14 +7174,9 @@ _mesa_TexImage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) - return; - - texture_image_multisample(ctx, 3, texObj, NULL, target, samples, + texture_image_multisample(ctx, 3, NULL, NULL, target, samples, internalformat, width, height, depth, fixedsamplelocations, GL_FALSE, 0, "glTexImage3DMultisample"); @@ -6974,17 +7202,12 @@ _mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations) { - struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) - return; - if (!valid_texstorage_ms_parameters(width, height, 1, 2)) return; - texture_image_multisample(ctx, 2, texObj, NULL, target, samples, + texture_image_multisample(ctx, 2, NULL, NULL, target, samples, internalformat, width, height, 1, fixedsamplelocations, GL_TRUE, 0, "glTexStorage2DMultisample"); @@ -6996,17 +7219,12 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations) { - struct gl_texture_object *texObj; GET_CURRENT_CONTEXT(ctx); - texObj = _mesa_get_current_tex_object(ctx, target); - if (!texObj) - return; - if (!valid_texstorage_ms_parameters(width, height, depth, 3)) return; - texture_image_multisample(ctx, 3, texObj, NULL, target, samples, + texture_image_multisample(ctx, 3, NULL, NULL, target, samples, internalformat, width, height, depth, fixedsamplelocations, GL_TRUE, 0, "glTexStorage3DMultisample"); diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index f9e5042ad8c..c630e530d59 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -139,7 +139,10 @@ _mesa_init_teximage_fields_ms(struct gl_context *ctx, GLuint numSamples, GLboolean fixedSampleLocations); - +void +_mesa_update_teximage_format_swizzle(struct gl_context *ctx, + struct gl_texture_image *img, + GLenum depth_mode); extern mesa_format _mesa_choose_texture_format(struct gl_context *ctx, struct gl_texture_object *texObj, @@ -171,10 +174,11 @@ _mesa_get_texbuffer_format(const struct gl_context *ctx, GLenum internalFormat); /** * Return the base-level texture image for the given texture object. */ -static inline const struct gl_texture_image * +static inline struct gl_texture_image * _mesa_base_tex_image(const struct gl_texture_object *texObj) { - return texObj->Image[0][texObj->Attrib.BaseLevel]; + int base_level = MIN2(texObj->Attrib.BaseLevel, MAX_TEXTURE_LEVELS - 1); + return texObj->Image[0][base_level]; } @@ -250,610 +254,12 @@ _mesa_texture_storage_ms_memory(struct gl_context *ctx, GLuint dims, bool _mesa_is_cube_map_texture(GLenum target); -/*@}*/ - - -/** \name API entry point functions */ -/*@{*/ - -extern void GLAPIENTRY -_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat, - GLsizei width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TextureImage1DEXT( GLuint texture, GLenum target, GLint level, - GLint internalformat, GLsizei width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_MultiTexImage1DEXT( GLenum texture, GLenum target, GLint level, - GLint internalformat, GLsizei width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TextureImage2DEXT( GLuint texture, GLenum target, GLint level, - GLint internalformat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, - const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_MultiTexImage2DEXT(GLenum texture, GLenum target, GLint level, - GLint internalFormat, GLsizei width, GLsizei height, - GLint border, GLenum format, GLenum type, - const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat, - GLsizei width, GLsizei height, GLsizei depth, GLint border, - GLenum format, GLenum type, const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TextureImage3DEXT( GLuint texture, GLenum target, GLint level, - GLint internalformat, GLsizei width, GLsizei height, - GLsizei depth, GLint border, GLenum format, - GLenum type, const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum format, GLenum type, - const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_MultiTexImage3DEXT(GLenum texture, GLenum target, GLint level, - GLint internalFormat, GLsizei width, GLsizei height, - GLsizei depth, GLint border, GLenum format, GLenum type, - const GLvoid *pixels ); - -extern void GLAPIENTRY -_mesa_TexImage1D_no_error(GLenum target, GLint level, GLint internalformat, - GLsizei width, GLint border, - GLenum format, GLenum type, const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TexImage2D_no_error(GLenum target, GLint level, GLint internalformat, - GLsizei width, GLsizei height, GLint border, - GLenum format, GLenum type, const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TexImage3D_no_error(GLenum target, GLint level, GLint internalformat, - GLsizei width, GLsizei height, GLsizei depth, - GLint border, GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image ); - -extern void GLAPIENTRY -_mesa_EGLImageTargetTexStorageEXT(GLenum target, GLeglImageOES image, - const GLint *attrib_list); -extern void GLAPIENTRY -_mesa_EGLImageTargetTextureStorageEXT(GLuint texture, GLeglImageOES image, - const GLint *attrib_list); -void GLAPIENTRY -_mesa_TexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels ); - -void GLAPIENTRY -_mesa_TexSubImage2D_no_error(GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TexSubImage2D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels ); - -void GLAPIENTRY -_mesa_TexSubImage3D_no_error(GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TexSubImage3D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid *pixels ); - -void GLAPIENTRY -_mesa_TextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, - GLsizei width, GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TextureSubImage1D(GLuint texture, GLint level, GLint xoffset, - GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, - GLint xoffset, GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_MultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, - GLint xoffset, GLsizei width, - GLenum format, GLenum type, - const GLvoid *pixels); - -void GLAPIENTRY -_mesa_TextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_MultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLsizei width, - GLsizei height, GLenum format, GLenum type, - const GLvoid *pixels); - -void GLAPIENTRY -_mesa_TextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TextureSubImage2D(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - const GLvoid *pixels); - -void GLAPIENTRY -_mesa_TextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, - GLenum type, const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TextureSubImage3D(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_TextureSubImage3DEXT(GLuint texture, GLenum target, - GLint level, GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, GLsizei height, - GLsizei depth, GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_MultiTexSubImage3DEXT(GLenum texunit, GLenum target, - GLint level, GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, GLsizei height, - GLsizei depth, GLenum format, GLenum type, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_CopyTexImage1D(GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLint border); - -extern void GLAPIENTRY -_mesa_CopyMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, - GLenum internalformat, GLint x, GLint y, - GLsizei width, GLint border); - -extern void GLAPIENTRY -_mesa_CopyTexImage2D( GLenum target, GLint level, - GLenum internalformat, GLint x, GLint y, - GLsizei width, GLsizei height, GLint border ); - -extern void GLAPIENTRY -_mesa_CopyMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, - GLenum internalformat, GLint x, GLint y, - GLsizei width, GLsizei hright, GLint border); - -extern void GLAPIENTRY -_mesa_CopyTextureImage1DEXT( GLuint texture, GLenum target, GLint level, - GLenum internalformat, GLint x, GLint y, - GLsizei width, GLint border); - -extern void GLAPIENTRY -_mesa_CopyTextureImage2DEXT( GLuint texture, GLenum target, GLint level, - GLenum internalformat, GLint x, GLint y, - GLsizei width, GLsizei height, GLint border ); - -extern void GLAPIENTRY -_mesa_CopyTexImage1D_no_error(GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLint border); - - -extern void GLAPIENTRY -_mesa_CopyTexImage2D_no_error(GLenum target, GLint level, GLenum internalformat, - GLint x, GLint y, GLsizei width, GLsizei height, - GLint border ); - - -extern void GLAPIENTRY -_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset, - GLint x, GLint y, GLsizei width ); - - -extern void GLAPIENTRY -_mesa_CopyTexSubImage2D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, GLsizei width, GLsizei height ); - - -extern void GLAPIENTRY -_mesa_CopyTexSubImage3D( GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, GLsizei width, GLsizei height ); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage1D(GLuint texture, GLint level, - GLint xoffset, GLint x, GLint y, GLsizei width); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage1DEXT(GLuint texture, GLenum target, - GLint level, GLint xoffset, GLint x, GLint y, - GLsizei width); - -extern void GLAPIENTRY -_mesa_CopyMultiTexSubImage1DEXT(GLenum texunit, GLenum target, - GLint level, GLint xoffset, GLint x, GLint y, - GLsizei width); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage2D(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage2DEXT(GLuint texture, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyMultiTexSubImage2DEXT(GLenum texunit, GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage3D(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage3DEXT(GLuint texture, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyMultiTexSubImage3DEXT(GLenum texunit, GLenum target, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTexSubImage1D_no_error(GLenum target, GLint level, GLint xoffset, - GLint x, GLint y, GLsizei width ); - -extern void GLAPIENTRY -_mesa_CopyTexSubImage2D_no_error(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLint x, GLint y, GLsizei width, - GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTexSubImage3D_no_error(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage1D_no_error(GLuint texture, GLint level, GLint xoffset, - GLint x, GLint y, GLsizei width); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage2D_no_error(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLint x, GLint y, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_CopyTextureSubImage3D_no_error(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLint x, - GLint y, GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_ClearTexSubImage( GLuint texture, GLint level, - GLint xoffset, GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLenum type, const void *data ); - -extern void GLAPIENTRY -_mesa_ClearTexImage( GLuint texture, GLint level, - GLenum format, GLenum type, const void *data ); - -extern void GLAPIENTRY -_mesa_CompressedTexImage1D(GLenum target, GLint level, - GLenum internalformat, GLsizei width, - GLint border, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureImage1DEXT(GLuint texture, GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLint border, GLsizei imageSize, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_CompressedMultiTexImage1DEXT(GLenum texunit, GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLint border, GLsizei imageSize, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_CompressedTexImage2D(GLenum target, GLint level, - GLenum internalformat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureImage2DEXT(GLuint texture, GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_CompressedMultiTexImage2DEXT(GLenum texunit, GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLsizei height, GLint border, GLsizei imageSize, - const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_CompressedTexImage3D(GLenum target, GLint level, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, GLint border, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureImage3DEXT(GLuint texture, GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLsizei height, GLsizei depth, GLint border, - GLsizei imageSize, const GLvoid *pixels); - -extern void GLAPIENTRY -_mesa_CompressedMultiTexImage3DEXT(GLenum texunit, GLenum target, GLint level, - GLenum internalFormat, GLsizei width, - GLsizei height, GLsizei depth, GLint border, - GLsizei imageSize, const GLvoid *pixels); - - -extern void GLAPIENTRY -_mesa_CompressedTexImage1D_no_error(GLenum target, GLint level, - GLenum internalformat, GLsizei width, - GLint border, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTexImage2D_no_error(GLenum target, GLint level, - GLenum internalformat, GLsizei width, - GLsizei height, GLint border, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTexImage3D_no_error(GLenum target, GLint level, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, GLint border, - GLsizei imageSize, const GLvoid *data); - - -extern void GLAPIENTRY -_mesa_CompressedTexSubImage1D_no_error(GLenum target, GLint level, - GLint xoffset, GLsizei width, - GLenum format, GLsizei imageSize, - const GLvoid *data); -extern void GLAPIENTRY -_mesa_CompressedTexSubImage1D(GLenum target, GLint level, GLint xoffset, - GLsizei width, GLenum format, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage1D_no_error(GLuint texture, GLint level, - GLint xoffset, GLsizei width, - GLenum format, GLsizei imageSize, - const GLvoid *data); -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage1D(GLuint texture, GLint level, GLint xoffset, - GLsizei width, GLenum format, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage1DEXT(GLuint texture, GLenum target, GLint level, - GLint xoffset, GLsizei width, GLenum format, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedMultiTexSubImage1DEXT(GLenum texunit, GLenum target, GLint level, - GLint xoffset, GLsizei width, GLenum format, - GLsizei imageSize, const GLvoid *data); - - -void GLAPIENTRY -_mesa_CompressedTextureSubImage2DEXT(GLuint texture, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedMultiTexSubImage2DEXT(GLenum texunit, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLsizei width, - GLsizei height, GLenum format, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage3DEXT(GLuint texture, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedMultiTexSubImage3DEXT(GLenum texunit, GLenum target, - GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTexSubImage2D_no_error(GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data); -extern void GLAPIENTRY -_mesa_CompressedTexSubImage2D(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage2D_no_error(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data); -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage2D(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, - GLsizei width, GLsizei height, - GLenum format, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTexSubImage3D_no_error(GLenum target, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, - const GLvoid *data); -extern void GLAPIENTRY -_mesa_CompressedTexSubImage3D(GLenum target, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, GLenum format, - GLsizei imageSize, const GLvoid *data); - -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage3D_no_error(GLuint texture, GLint level, - GLint xoffset, GLint yoffset, - GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth, - GLenum format, GLsizei imageSize, - const GLvoid *data); -extern void GLAPIENTRY -_mesa_CompressedTextureSubImage3D(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, - GLsizei depth, - GLenum format, GLsizei imageSize, - const GLvoid *data); - -extern void GLAPIENTRY -_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer); - -extern void GLAPIENTRY -_mesa_TexBufferRange(GLenum target, GLenum internalFormat, GLuint buffer, - GLintptr offset, GLsizeiptr size); - -extern void GLAPIENTRY -_mesa_TextureBufferRangeEXT(GLuint texture, GLenum target, GLenum internalFormat, - GLuint buffer, GLintptr offset, GLsizeiptr size); - -extern void GLAPIENTRY -_mesa_TextureBuffer(GLuint texture, GLenum internalFormat, GLuint buffer); - -extern void GLAPIENTRY -_mesa_TextureBufferEXT(GLuint texture, GLenum target, GLenum internalFormat, - GLuint buffer); - -extern void GLAPIENTRY -_mesa_MultiTexBufferEXT(GLenum texunit, GLenum target, GLenum internalFormat, - GLuint buffer); - -extern void GLAPIENTRY -_mesa_TextureBufferRange(GLuint texture, GLenum internalFormat, GLuint buffer, - GLintptr offset, GLsizeiptr size); - - -extern void GLAPIENTRY -_mesa_TexImage2DMultisample(GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLboolean fixedsamplelocations); - -extern void GLAPIENTRY -_mesa_TexImage3DMultisample(GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, - GLboolean fixedsamplelocations); - -extern void GLAPIENTRY -_mesa_TexStorage2DMultisample(GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLboolean fixedsamplelocations); - -extern void GLAPIENTRY -_mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, - GLboolean fixedsamplelocations); - -void GLAPIENTRY -_mesa_TextureStorage2DMultisample(GLuint texture, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, - GLboolean fixedsamplelocations); - -void GLAPIENTRY -_mesa_TextureStorage3DMultisample(GLuint texture, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, - GLboolean fixedsamplelocations); - -extern void GLAPIENTRY -_mesa_TextureStorage2DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLboolean fixedsamplelocations); - -extern void GLAPIENTRY -_mesa_TextureStorage3DMultisampleEXT(GLuint texture, GLenum target, GLsizei samples, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, - GLboolean fixedsamplelocations); +GLboolean +_mesa_sparse_texture_error_check(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + mesa_format format, GLenum target, GLsizei levels, + GLsizei width, GLsizei height, GLsizei depth, + const char *func); /*@}*/ diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index 4b8a1260593..64465325064 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -45,8 +45,15 @@ #include "program/prog_instruction.h" #include "texturebindless.h" #include "util/u_memory.h" +#include "util/u_inlines.h" +#include "api_exec_decl.h" - +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_context.h" +#include "state_tracker/st_format.h" +#include "state_tracker/st_cb_flush.h" +#include "state_tracker/st_texture.h" +#include "state_tracker/st_sampler_view.h" /**********************************************************************/ /** \name Internal functions */ @@ -110,7 +117,7 @@ struct gl_texture_object * _mesa_lookup_texture(struct gl_context *ctx, GLuint id) { return (struct gl_texture_object *) - _mesa_HashLookup(ctx->Shared->TexObjects, id); + _mesa_HashLookup(&ctx->Shared->TexObjects, id); } /** @@ -136,7 +143,7 @@ struct gl_texture_object * _mesa_lookup_texture_locked(struct gl_context *ctx, GLuint id) { return (struct gl_texture_object *) - _mesa_HashLookupLocked(ctx->Shared->TexObjects, id); + _mesa_HashLookupLocked(&ctx->Shared->TexObjects, id); } /** @@ -162,7 +169,8 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) case GL_TEXTURE_3D: return texUnit->CurrentTex[TEXTURE_3D_INDEX]; case GL_PROXY_TEXTURE_3D: - return ctx->Texture.ProxyTex[TEXTURE_3D_INDEX]; + return !(_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D) + ? ctx->Texture.ProxyTex[TEXTURE_3D_INDEX] : NULL; case GL_TEXTURE_CUBE_MAP_POSITIVE_X: case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: @@ -170,11 +178,9 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: case GL_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map - ? texUnit->CurrentTex[TEXTURE_CUBE_INDEX] : NULL; + return texUnit->CurrentTex[TEXTURE_CUBE_INDEX]; case GL_PROXY_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map - ? ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX] : NULL; + return ctx->Texture.ProxyTex[TEXTURE_CUBE_INDEX]; case GL_TEXTURE_CUBE_MAP_ARRAY: return _mesa_has_texture_cube_map_array(ctx) ? texUnit->CurrentTex[TEXTURE_CUBE_ARRAY_INDEX] : NULL; @@ -215,7 +221,7 @@ _mesa_get_current_tex_object(struct gl_context *ctx, GLenum target) return ctx->Extensions.ARB_texture_multisample ? ctx->Texture.ProxyTex[TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX] : NULL; default: - _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object()"); + _mesa_problem(NULL, "bad target in _mesa_get_current_tex_object(): 0x%04x", target); return NULL; } } @@ -256,35 +262,55 @@ _mesa_get_texobj_by_target_and_texunit(struct gl_context *ctx, GLenum target, return texUnit->CurrentTex[targetIndex]; } - /** - * Allocate and initialize a new texture object. But don't put it into the - * texture object hash table. - * - * Called via ctx->Driver.NewTextureObject, unless overridden by a device - * driver. - * - * \param shared the shared GL state structure to contain the texture object - * \param name integer name for the texture object - * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, - * GL_TEXTURE_CUBE_MAP or GL_TEXTURE_RECTANGLE_NV. zero is ok for the sake - * of GenTextures() - * - * \return pointer to new texture object. + * Return swizzle1(swizzle2) */ -struct gl_texture_object * -_mesa_new_texture_object(struct gl_context *ctx, GLuint name, GLenum target) +static unsigned +swizzle_swizzle(unsigned swizzle1, unsigned swizzle2) { - struct gl_texture_object *obj; + unsigned i, swz[4]; - obj = MALLOC_STRUCT(gl_texture_object); - if (!obj) - return NULL; + if (swizzle1 == SWIZZLE_XYZW) { + /* identity swizzle, no change to swizzle2 */ + return swizzle2; + } - _mesa_initialize_texture_object(ctx, obj, name, target); - return obj; + for (i = 0; i < 4; i++) { + unsigned s = GET_SWZ(swizzle1, i); + switch (s) { + case SWIZZLE_X: + case SWIZZLE_Y: + case SWIZZLE_Z: + case SWIZZLE_W: + swz[i] = GET_SWZ(swizzle2, s); + break; + case SWIZZLE_ZERO: + swz[i] = SWIZZLE_ZERO; + break; + case SWIZZLE_ONE: + swz[i] = SWIZZLE_ONE; + break; + default: + assert(!"Bad swizzle term"); + swz[i] = SWIZZLE_X; + } + } + + return MAKE_SWIZZLE4(swz[0], swz[1], swz[2], swz[3]); } +void +_mesa_update_texture_object_swizzle(struct gl_context *ctx, + struct gl_texture_object *texObj) +{ + const struct gl_texture_image *img = _mesa_base_tex_image(texObj); + if (!img) + return; + + /* Combine the texture format swizzle with user's swizzle */ + texObj->Swizzle = swizzle_swizzle(texObj->Attrib._Swizzle, img->FormatSwizzle); + texObj->SwizzleGLSL130 = swizzle_swizzle(texObj->Attrib._Swizzle, img->FormatSwizzleGLSL130); +} /** * Initialize a new texture object to default values. @@ -292,7 +318,7 @@ _mesa_new_texture_object(struct gl_context *ctx, GLuint name, GLenum target) * \param name the texture name * \param target the texture target */ -void +static bool _mesa_initialize_texture_object( struct gl_context *ctx, struct gl_texture_object *obj, GLuint name, GLenum target ) @@ -313,7 +339,6 @@ _mesa_initialize_texture_object( struct gl_context *ctx, memset(obj, 0, sizeof(*obj)); /* init the non-zero fields */ - simple_mtx_init(&obj->Mutex, mtx_plain); obj->RefCount = 1; obj->Name = name; obj->Target = target; @@ -337,23 +362,41 @@ _mesa_initialize_texture_object( struct gl_context *ctx, obj->Sampler.Attrib.WrapT = GL_CLAMP_TO_EDGE; obj->Sampler.Attrib.WrapR = GL_CLAMP_TO_EDGE; obj->Sampler.Attrib.MinFilter = GL_LINEAR; + obj->Sampler.Attrib.state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + obj->Sampler.Attrib.state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + obj->Sampler.Attrib.state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + obj->Sampler.Attrib.state.min_img_filter = PIPE_TEX_FILTER_LINEAR; + obj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; } else { obj->Sampler.Attrib.WrapS = GL_REPEAT; obj->Sampler.Attrib.WrapT = GL_REPEAT; obj->Sampler.Attrib.WrapR = GL_REPEAT; obj->Sampler.Attrib.MinFilter = GL_NEAREST_MIPMAP_LINEAR; + obj->Sampler.Attrib.state.wrap_s = PIPE_TEX_WRAP_REPEAT; + obj->Sampler.Attrib.state.wrap_t = PIPE_TEX_WRAP_REPEAT; + obj->Sampler.Attrib.state.wrap_r = PIPE_TEX_WRAP_REPEAT; + obj->Sampler.Attrib.state.min_img_filter = PIPE_TEX_FILTER_NEAREST; + obj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_LINEAR; } obj->Sampler.Attrib.MagFilter = GL_LINEAR; + obj->Sampler.Attrib.state.mag_img_filter = PIPE_TEX_FILTER_LINEAR; obj->Sampler.Attrib.MinLod = -1000.0; obj->Sampler.Attrib.MaxLod = 1000.0; + obj->Sampler.Attrib.state.min_lod = 0; /* no negative numbers */ + obj->Sampler.Attrib.state.max_lod = 1000; obj->Sampler.Attrib.LodBias = 0.0; + obj->Sampler.Attrib.state.lod_bias = 0; obj->Sampler.Attrib.MaxAnisotropy = 1.0; + obj->Sampler.Attrib.state.max_anisotropy = 0; /* gallium sets 0 instead of 1 */ obj->Sampler.Attrib.CompareMode = GL_NONE; /* ARB_shadow */ obj->Sampler.Attrib.CompareFunc = GL_LEQUAL; /* ARB_shadow */ - obj->Attrib.DepthMode = ctx->API == API_OPENGL_CORE ? GL_RED : GL_LUMINANCE; + obj->Sampler.Attrib.state.compare_mode = PIPE_TEX_COMPARE_NONE; + obj->Sampler.Attrib.state.compare_func = PIPE_FUNC_LEQUAL; + obj->Attrib.DepthMode = _mesa_is_desktop_gl_core(ctx) ? GL_RED : GL_LUMINANCE; obj->StencilSampling = false; obj->Sampler.Attrib.CubeMapSeamless = GL_FALSE; + obj->Sampler.Attrib.state.seamless_cube_map = false; obj->Sampler.HandleAllocated = GL_FALSE; obj->Attrib.Swizzle[0] = GL_RED; obj->Attrib.Swizzle[1] = GL_GREEN; @@ -362,14 +405,57 @@ _mesa_initialize_texture_object( struct gl_context *ctx, obj->Attrib._Swizzle = SWIZZLE_NOOP; obj->Sampler.Attrib.sRGBDecode = GL_DECODE_EXT; obj->Sampler.Attrib.ReductionMode = GL_WEIGHTED_AVERAGE_EXT; - obj->BufferObjectFormat = GL_R8; - obj->_BufferObjectFormat = MESA_FORMAT_R_UNORM8; + obj->Sampler.Attrib.state.reduction_mode = PIPE_TEX_REDUCTION_WEIGHTED_AVERAGE; + obj->BufferObjectFormat = _mesa_is_desktop_gl_compat(ctx) ? GL_LUMINANCE8 : GL_R8; + obj->_BufferObjectFormat = _mesa_is_desktop_gl_compat(ctx) + ? MESA_FORMAT_L_UNORM8 : MESA_FORMAT_R_UNORM8; obj->Attrib.ImageFormatCompatibilityType = GL_IMAGE_FORMAT_COMPATIBILITY_BY_SIZE; /* GL_ARB_bindless_texture */ _mesa_init_texture_handles(obj); + + obj->level_override = -1; + obj->layer_override = -1; + simple_mtx_init(&obj->validate_mutex, mtx_plain); + obj->needs_validation = true; + /* Pre-allocate a sampler views container to save a branch in the + * fast path. + */ + obj->sampler_views = calloc(1, sizeof(struct st_sampler_views) + + sizeof(struct st_sampler_view)); + if (!obj->sampler_views) { + return false; + } + obj->sampler_views->max = 1; + return true; } +/** + * Allocate and initialize a new texture object. But don't put it into the + * texture object hash table. + * + * \param name integer name for the texture object + * \param target either GL_TEXTURE_1D, GL_TEXTURE_2D, GL_TEXTURE_3D, + * GL_TEXTURE_CUBE_MAP or GL_TEXTURE_RECTANGLE_NV. zero is ok for the sake + * of GenTextures() + * + * \return pointer to new texture object. + */ +struct gl_texture_object * +_mesa_new_texture_object(struct gl_context *ctx, GLuint name, GLenum target) +{ + struct gl_texture_object *obj; + + obj = MALLOC_STRUCT(gl_texture_object); + if (!obj) + return NULL; + + if (!_mesa_initialize_texture_object(ctx, obj, name, target)) { + free(obj); + return NULL; + } + return obj; +} /** * Some texture initialization can't be finished until we know which @@ -398,16 +484,14 @@ finish_texture_init(struct gl_context *ctx, GLenum target, obj->Sampler.Attrib.WrapS = GL_CLAMP_TO_EDGE; obj->Sampler.Attrib.WrapT = GL_CLAMP_TO_EDGE; obj->Sampler.Attrib.WrapR = GL_CLAMP_TO_EDGE; + obj->Sampler.Attrib.state.wrap_s = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + obj->Sampler.Attrib.state.wrap_t = PIPE_TEX_WRAP_CLAMP_TO_EDGE; + obj->Sampler.Attrib.state.wrap_r = PIPE_TEX_WRAP_CLAMP_TO_EDGE; obj->Sampler.Attrib.MinFilter = filter; obj->Sampler.Attrib.MagFilter = filter; - if (ctx->Driver.TexParameter) { - /* XXX we probably don't need to make all these calls */ - ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_S); - ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_T); - ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_WRAP_R); - ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_MIN_FILTER); - ctx->Driver.TexParameter(ctx, obj, GL_TEXTURE_MAG_FILTER); - } + obj->Sampler.Attrib.state.min_img_filter = filter_to_gallium(filter); + obj->Sampler.Attrib.state.min_mip_filter = mipfilter_to_gallium(filter); + obj->Sampler.Attrib.state.mag_img_filter = filter_to_gallium(filter); break; default: @@ -420,7 +504,6 @@ finish_texture_init(struct gl_context *ctx, GLenum target, /** * Deallocate a texture object struct. It should have already been * removed from the texture object pool. - * Called via ctx->Driver.DeleteTexture() if not overriden by a driver. * * \param shared the shared GL state to which the object belongs. * \param texObj the texture object to delete. @@ -436,11 +519,15 @@ _mesa_delete_texture_object(struct gl_context *ctx, */ texObj->Target = 0x99; + pipe_resource_reference(&texObj->pt, NULL); + st_delete_texture_sampler_views(ctx->st, texObj); + simple_mtx_destroy(&texObj->validate_mutex); + /* free the texture images */ for (face = 0; face < 6; face++) { for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { if (texObj->Image[face][i]) { - ctx->Driver.DeleteTextureImage(ctx, texObj->Image[face][i]); + _mesa_delete_texture_image(ctx, texObj->Image[face][i]); } } } @@ -449,14 +536,10 @@ _mesa_delete_texture_object(struct gl_context *ctx, _mesa_delete_texture_handles(ctx, texObj); _mesa_reference_buffer_object_shared(ctx, &texObj->BufferObject, NULL); - - /* destroy the mutex -- it may have allocated memory (eg on bsd) */ - simple_mtx_destroy(&texObj->Mutex); - free(texObj->Label); /* free this object */ - free(texObj); + FREE(texObj); } @@ -538,44 +621,34 @@ _mesa_reference_texobj_(struct gl_texture_object **ptr, if (*ptr) { /* Unreference the old texture */ - GLboolean deleteFlag = GL_FALSE; struct gl_texture_object *oldTex = *ptr; assert(valid_texture_object(oldTex)); (void) valid_texture_object; /* silence warning in release builds */ - simple_mtx_lock(&oldTex->Mutex); assert(oldTex->RefCount > 0); - oldTex->RefCount--; - deleteFlag = (oldTex->RefCount == 0); - simple_mtx_unlock(&oldTex->Mutex); - - if (deleteFlag) { + if (p_atomic_dec_zero(&oldTex->RefCount)) { /* Passing in the context drastically changes the driver code for * framebuffer deletion. */ GET_CURRENT_CONTEXT(ctx); if (ctx) - ctx->Driver.DeleteTexture(ctx, oldTex); + _mesa_delete_texture_object(ctx, oldTex); else _mesa_problem(NULL, "Unable to delete texture, no context"); } - - *ptr = NULL; } - assert(!*ptr); if (tex) { /* reference new texture */ assert(valid_texture_object(tex)); - simple_mtx_lock(&tex->Mutex); assert(tex->RefCount > 0); - tex->RefCount++; - *ptr = tex; - simple_mtx_unlock(&tex->Mutex); + p_atomic_inc(&tex->RefCount); } + + *ptr = tex; } @@ -744,7 +817,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, return; } if (t->Image[face][baseLevel]->InternalFormat != - baseImage->InternalFormat) { + baseImage->InternalFormat || + t->Image[face][baseLevel]->TexFormat != baseImage->TexFormat) { incomplete(t, BASE, "Cube face format mismatch"); return; } @@ -803,7 +877,8 @@ _mesa_test_texobj_completeness( const struct gl_context *ctx, incomplete(t, MIPMAP, "TexImage[%d] is missing", i); return; } - if (img->InternalFormat != baseImage->InternalFormat) { + if (img->InternalFormat != baseImage->InternalFormat || + img->TexFormat != baseImage->TexFormat) { incomplete(t, MIPMAP, "Format[i] != Format[baseLevel]"); return; } @@ -899,14 +974,15 @@ _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj) /** * Return pointer to a default/fallback texture of the given type/target. - * The texture is an RGBA texture with all texels = (0,0,0,1). + * The texture is an RGBA texture with all texels = (0,0,0,1) OR + * a depth texture that returns 0. * That's the value a GLSL sampler should get when sampling from an * incomplete texture. */ struct gl_texture_object * -_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) +_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex, bool is_depth) { - if (!ctx->Shared->FallbackTex[tex]) { + if (!ctx->Shared->FallbackTex[tex][is_depth]) { /* create fallback texture now */ const GLsizei width = 1, height = 1; GLsizei depth = 1; @@ -981,17 +1057,25 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) } /* create texture object */ - texObj = ctx->Driver.NewTextureObject(ctx, 0, target); + texObj = _mesa_new_texture_object(ctx, 0, target); if (!texObj) return NULL; assert(texObj->RefCount == 1); texObj->Sampler.Attrib.MinFilter = GL_NEAREST; texObj->Sampler.Attrib.MagFilter = GL_NEAREST; - - texFormat = ctx->Driver.ChooseTextureFormat(ctx, target, - GL_RGBA, GL_RGBA, - GL_UNSIGNED_BYTE); + texObj->Sampler.Attrib.state.min_img_filter = PIPE_TEX_FILTER_NEAREST; + texObj->Sampler.Attrib.state.min_mip_filter = PIPE_TEX_MIPFILTER_NONE; + texObj->Sampler.Attrib.state.mag_img_filter = PIPE_TEX_FILTER_NEAREST; + + if (is_depth) + texFormat = st_ChooseTextureFormat(ctx, target, + GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, + GL_UNSIGNED_INT); + else + texFormat = st_ChooseTextureFormat(ctx, target, + GL_RGBA, GL_RGBA, + GL_UNSIGNED_BYTE); /* need a loop here just for cube maps */ for (face = 0; face < numFaces; face++) { @@ -1000,30 +1084,54 @@ _mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex) /* initialize level[0] texture image */ texImage = _mesa_get_tex_image(ctx, texObj, faceTarget, 0); - _mesa_init_teximage_fields(ctx, texImage, - width, - (dims > 1) ? height : 1, - (dims > 2) ? depth : 1, - 0, /* border */ - GL_RGBA, texFormat); - - ctx->Driver.TexImage(ctx, dims, texImage, - GL_RGBA, GL_UNSIGNED_BYTE, texel, - &ctx->DefaultPacking); + GLenum internalFormat = is_depth ? GL_DEPTH_COMPONENT : GL_RGBA; + if (tex == TEXTURE_2D_MULTISAMPLE_INDEX || + tex == TEXTURE_2D_MULTISAMPLE_ARRAY_INDEX) { + int samples[16]; + st_QueryInternalFormat(ctx, 0, internalFormat, GL_SAMPLES, samples); + _mesa_init_teximage_fields_ms(ctx, texImage, + width, + (dims > 1) ? height : 1, + (dims > 2) ? depth : 1, + 0, /* border */ + internalFormat, texFormat, + samples[0], + GL_TRUE); + } else { + _mesa_init_teximage_fields(ctx, texImage, + width, + (dims > 1) ? height : 1, + (dims > 2) ? depth : 1, + 0, /* border */ + internalFormat, texFormat); + } + _mesa_update_texture_object_swizzle(ctx, texObj); + if (ctx->st->can_null_texture && is_depth) { + texObj->NullTexture = GL_TRUE; + } else { + if (is_depth) + st_TexImage(ctx, dims, texImage, + GL_DEPTH_COMPONENT, GL_FLOAT, texel, + &ctx->DefaultPacking); + else + st_TexImage(ctx, dims, texImage, + GL_RGBA, GL_UNSIGNED_BYTE, texel, + &ctx->DefaultPacking); + } } _mesa_test_texobj_completeness(ctx, texObj); assert(texObj->_BaseComplete); assert(texObj->_MipmapComplete); - ctx->Shared->FallbackTex[tex] = texObj; + ctx->Shared->FallbackTex[tex][is_depth] = texObj; /* Complete the driver's operation in case another context will also * use the same fallback texture. */ - if (ctx->Driver.Finish) - ctx->Driver.Finish(ctx); + if (!ctx->st->can_null_texture || !is_depth) + st_glFinish(ctx); } - return ctx->Shared->FallbackTex[tex]; + return ctx->Shared->FallbackTex[tex][is_depth]; } @@ -1074,7 +1182,7 @@ _mesa_total_texture_memory(struct gl_context *ctx) { GLuint tgt, total = 0; - _mesa_HashWalk(ctx->Shared->TexObjects, count_tex_size, &total); + _mesa_HashWalk(&ctx->Shared->TexObjects, count_tex_size, &total); /* plus, the default texture objects */ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { @@ -1172,25 +1280,25 @@ create_textures(struct gl_context *ctx, GLenum target, /* * This must be atomic (generation and allocation of texture IDs) */ - _mesa_HashLockMutex(ctx->Shared->TexObjects); + _mesa_HashLockMutex(&ctx->Shared->TexObjects); - _mesa_HashFindFreeKeys(ctx->Shared->TexObjects, textures, n); + _mesa_HashFindFreeKeys(&ctx->Shared->TexObjects, textures, n); /* Allocate new, empty texture objects */ for (i = 0; i < n; i++) { struct gl_texture_object *texObj; - texObj = ctx->Driver.NewTextureObject(ctx, textures[i], target); + texObj = _mesa_new_texture_object(ctx, textures[i], target); if (!texObj) { - _mesa_HashUnlockMutex(ctx->Shared->TexObjects); + _mesa_HashUnlockMutex(&ctx->Shared->TexObjects); _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); return; } /* insert into hash table */ - _mesa_HashInsertLocked(ctx->Shared->TexObjects, texObj->Name, texObj, true); + _mesa_HashInsertLocked(&ctx->Shared->TexObjects, texObj->Name, texObj); } - _mesa_HashUnlockMutex(ctx->Shared->TexObjects); + _mesa_HashUnlockMutex(&ctx->Shared->TexObjects); } @@ -1391,10 +1499,6 @@ unbind_textures_from_unit(struct gl_context *ctx, GLuint unit) _mesa_reference_texobj(&texUnit->CurrentTex[index], texObj); - /* Pass BindTexture call to device driver */ - if (ctx->Driver.BindTexture) - ctx->Driver.BindTexture(ctx, unit, 0, texObj); - texUnit->_BoundTextures &= ~(1 << index); ctx->NewState |= _NEW_TEXTURE_OBJECT; ctx->PopAttribState |= GL_TEXTURE_BIT; @@ -1462,11 +1566,9 @@ delete_textures(struct gl_context *ctx, GLsizei n, const GLuint *textures) /* The texture _name_ is now free for re-use. * Remove it from the hash table now. */ - _mesa_HashRemove(ctx->Shared->TexObjects, delObj->Name); + _mesa_HashRemove(&ctx->Shared->TexObjects, delObj->Name); - if (ctx->Driver.TextureRemovedFromShared) { - ctx->Driver.TextureRemovedFromShared(ctx, delObj); - } + st_texture_release_all_sampler_views(st_context(ctx), delObj); /* Unreference the texobj. If refcount hits zero, the texture * will be deleted. @@ -1477,46 +1579,6 @@ delete_textures(struct gl_context *ctx, GLsizei n, const GLuint *textures) } } -/** - * This deletes a texObj without altering the hash table. - */ -void -_mesa_delete_nameless_texture(struct gl_context *ctx, - struct gl_texture_object *texObj) -{ - if (!texObj) - return; - - FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); - - _mesa_lock_texture(ctx, texObj); - { - /* Check if texture is bound to any framebuffer objects. - * If so, unbind. - * See section 4.4.2.3 of GL_EXT_framebuffer_object. - */ - unbind_texobj_from_fbo(ctx, texObj); - - /* Check if this texture is currently bound to any texture units. - * If so, unbind it. - */ - unbind_texobj_from_texunits(ctx, texObj); - - /* Check if this texture is currently bound to any shader - * image unit. If so, unbind it. - * See section 3.9.X of GL_ARB_shader_image_load_store. - */ - unbind_texobj_from_image_units(ctx, texObj); - } - _mesa_unlock_texture(ctx, texObj); - - /* Unreference the texobj. If refcount hits zero, the texture - * will be deleted. - */ - _mesa_reference_texobj(&texObj, NULL); -} - - void GLAPIENTRY _mesa_DeleteTextures_no_error(GLsizei n, const GLuint *textures) { @@ -1557,10 +1619,11 @@ _mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target) case GL_TEXTURE_2D: return TEXTURE_2D_INDEX; case GL_TEXTURE_3D: - return ctx->API != API_OPENGLES ? TEXTURE_3D_INDEX : -1; + return (ctx->API != API_OPENGLES && + !(_mesa_is_gles2(ctx) && !ctx->Extensions.OES_texture_3D)) + ? TEXTURE_3D_INDEX : -1; case GL_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map - ? TEXTURE_CUBE_INDEX : -1; + return TEXTURE_CUBE_INDEX; case GL_TEXTURE_RECTANGLE: return _mesa_is_desktop_gl(ctx) && ctx->Extensions.NV_texture_rectangle ? TEXTURE_RECT_INDEX : -1; @@ -1623,16 +1686,10 @@ bind_texture_object(struct gl_context *ctx, unsigned unit, * If so, just return. For GL_OES_image_external, rebinding the texture * always must invalidate cached resources. */ - if (targetIndex != TEXTURE_EXTERNAL_INDEX) { - bool early_out; - simple_mtx_lock(&ctx->Shared->Mutex); - early_out = ((ctx->Shared->RefCount == 1) - && (texObj == texUnit->CurrentTex[targetIndex])); - simple_mtx_unlock(&ctx->Shared->Mutex); - if (early_out) { - return; - } - } + if (targetIndex != TEXTURE_EXTERNAL_INDEX && + ctx->Shared->RefCount == 1 && + texObj == texUnit->CurrentTex[targetIndex]) + return; /* Flush before changing binding. * @@ -1643,6 +1700,14 @@ bind_texture_object(struct gl_context *ctx, unsigned unit, */ FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); + /* if the previously bound texture uses GL_CLAMP, flag the driver here + * to ensure any emulation is disabled + */ + if (texUnit->CurrentTex[targetIndex] && + texUnit->CurrentTex[targetIndex]->Sampler.glclamp_mask != + texObj->Sampler.glclamp_mask) + ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + /* If the refcount on the previously bound texture is decremented to * zero, it'll be deleted here. */ @@ -1655,35 +1720,6 @@ bind_texture_object(struct gl_context *ctx, unsigned unit, texUnit->_BoundTextures |= (1 << targetIndex); else texUnit->_BoundTextures &= ~(1 << targetIndex); - - /* Pass BindTexture call to device driver */ - if (ctx->Driver.BindTexture) { - ctx->Driver.BindTexture(ctx, unit, texObj->Target, texObj); - } -} - -/** - * Light-weight bind texture for internal users - * - * This is really just \c finish_texture_init plus \c bind_texture_object. - * This is intended to be used by internal Mesa functions that use - * \c _mesa_CreateTexture and need to bind textures (e.g., meta). - */ -void -_mesa_bind_texture(struct gl_context *ctx, GLenum target, - struct gl_texture_object *tex_obj) -{ - const GLint targetIndex = _mesa_tex_target_to_index(ctx, target); - - assert(targetIndex >= 0 && targetIndex < NUM_TEXTURE_TARGETS); - - if (tex_obj->Target == 0) - finish_texture_init(ctx, target, tex_obj, targetIndex); - - assert(tex_obj->Target == target); - assert(tex_obj->TargetIndex == targetIndex); - - bind_texture_object(ctx, ctx->Texture.CurrentUnit, tex_obj); } struct gl_texture_object * @@ -1742,21 +1778,21 @@ _mesa_lookup_or_create_texture(struct gl_context *ctx, GLenum target, finish_texture_init(ctx, target, newTexObj, targetIndex); } } else { - if (!no_error && ctx->API == API_OPENGL_CORE) { + if (!no_error && _mesa_is_desktop_gl_core(ctx)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(non-gen name)", caller); return NULL; } /* if this is a new texture id, allocate a texture object now */ - newTexObj = ctx->Driver.NewTextureObject(ctx, texName, target); + newTexObj = _mesa_new_texture_object(ctx, texName, target); if (!newTexObj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", caller); return NULL; } /* and insert it into hash table */ - _mesa_HashInsert(ctx->Shared->TexObjects, texName, newTexObj, false); + _mesa_HashInsert(&ctx->Shared->TexObjects, texName, newTexObj); } } @@ -1939,7 +1975,7 @@ bind_textures(struct gl_context *ctx, GLuint first, GLsizei count, * their parameters are valid and no other error occurs." */ - _mesa_HashLockMutex(ctx->Shared->TexObjects); + _mesa_HashLockMutex(&ctx->Shared->TexObjects); for (i = 0; i < count; i++) { if (textures[i] != 0) { @@ -1971,7 +2007,7 @@ bind_textures(struct gl_context *ctx, GLuint first, GLsizei count, } } - _mesa_HashUnlockMutex(ctx->Shared->TexObjects); + _mesa_HashUnlockMutex(&ctx->Shared->TexObjects); } else { /* Unbind all textures in the range <first> through <first>+<count>-1 */ for (i = 0; i < count; i++) @@ -2153,7 +2189,7 @@ void _mesa_lock_context_textures( struct gl_context *ctx ) { if (!ctx->TexturesLocked) - mtx_lock(&ctx->Shared->TexMutex); + simple_mtx_lock(&ctx->Shared->TexMutex); if (ctx->Shared->TextureStateStamp != ctx->TextureStateTimestamp) { ctx->NewState |= _NEW_TEXTURE_OBJECT; @@ -2168,7 +2204,7 @@ _mesa_unlock_context_textures( struct gl_context *ctx ) { assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp); if (!ctx->TexturesLocked) - mtx_unlock(&ctx->Shared->TexMutex); + simple_mtx_unlock(&ctx->Shared->TexMutex); } @@ -2353,4 +2389,94 @@ _mesa_InvalidateTexImage(GLuint texture, GLint level) return; } +static void +texture_page_commitment(struct gl_context *ctx, GLenum target, + struct gl_texture_object *tex_obj, + GLint level, GLint xoffset, GLint yoffset, GLint zoffset, + GLsizei width, GLsizei height, GLsizei depth, + GLboolean commit, const char *func) +{ + if (!tex_obj->Immutable || !tex_obj->IsSparse) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(immutable sparse texture)", func); + return; + } + + if (level < 0 || level > tex_obj->_MaxLevel) { + /* Not in error list of ARB_sparse_texture. */ + _mesa_error(ctx, GL_INVALID_VALUE, "%s(level %d)", func, level); + return; + } + + struct gl_texture_image *image = tex_obj->Image[0][level]; + + int max_depth = image->Depth; + if (target == GL_TEXTURE_CUBE_MAP) + max_depth *= 6; + + if (xoffset + width > image->Width || + yoffset + height > image->Height || + zoffset + depth > max_depth) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(exceed max size)", func); + return; + } + + int px, py, pz; + ASSERTED bool ret = st_GetSparseTextureVirtualPageSize( + ctx, target, image->TexFormat, tex_obj->VirtualPageSizeIndex, &px, &py, &pz); + assert(ret); + + if (xoffset % px || yoffset % py || zoffset % pz) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(offset multiple of page size)", func); + return; + } + + if ((width % px && xoffset + width != image->Width) || + (height % py && yoffset + height != image->Height) || + (depth % pz && zoffset + depth != max_depth)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(alignment)", func); + return; + } + + st_TexturePageCommitment(ctx, tex_obj, level, xoffset, yoffset, zoffset, + width, height, depth, commit); +} + +void GLAPIENTRY +_mesa_TexPageCommitmentARB(GLenum target, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLboolean commit) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + + texObj = _mesa_get_current_tex_object(ctx, target); + if (!texObj) { + _mesa_error(ctx, GL_INVALID_ENUM, "glTexPageCommitmentARB(target)"); + return; + } + + texture_page_commitment(ctx, target, texObj, level, xoffset, yoffset, zoffset, + width, height, depth, commit, + "glTexPageCommitmentARB"); +} + +void GLAPIENTRY +_mesa_TexturePageCommitmentEXT(GLuint texture, GLint level, GLint xoffset, + GLint yoffset, GLint zoffset, GLsizei width, + GLsizei height, GLsizei depth, GLboolean commit) +{ + GET_CURRENT_CONTEXT(ctx); + struct gl_texture_object *texObj; + + texObj = _mesa_lookup_texture(ctx, texture); + if (texture == 0 || texObj == NULL) { + _mesa_error(ctx, GL_INVALID_OPERATION, "glTexturePageCommitmentEXT(texture)"); + return; + } + + texture_page_commitment(ctx, texObj->Target, texObj, level, xoffset, yoffset, + zoffset, width, height, depth, commit, + "glTexturePageCommitmentEXT"); +} + /*@}*/ diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index 22e98d9684e..6b813a07c99 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -32,8 +32,9 @@ #define TEXTOBJ_H -#include "glheader.h" +#include "util/glheader.h" #include "samplerobj.h" +#include "teximage.h" #ifdef __cplusplus @@ -67,11 +68,6 @@ _mesa_get_texobj_by_target_and_texunit(struct gl_context *ctx, GLenum target, extern struct gl_texture_object * _mesa_new_texture_object( struct gl_context *ctx, GLuint name, GLenum target ); -extern void -_mesa_initialize_texture_object( struct gl_context *ctx, - struct gl_texture_object *obj, - GLuint name, GLenum target ); - extern int _mesa_tex_target_to_index(const struct gl_context *ctx, GLenum target); @@ -103,7 +99,7 @@ static inline void _mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) { if (!ctx->TexturesLocked) - mtx_lock(&ctx->Shared->TexMutex); + simple_mtx_lock(&ctx->Shared->TexMutex); ctx->Shared->TextureStateStamp++; (void) texObj; } @@ -113,7 +109,7 @@ _mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj) { (void) texObj; if (!ctx->TexturesLocked) - mtx_unlock(&ctx->Shared->TexMutex); + simple_mtx_unlock(&ctx->Shared->TexMutex); } @@ -123,7 +119,7 @@ _mesa_is_texture_complete(const struct gl_texture_object *texObj, const struct gl_sampler_object *sampler, bool linear_as_nearest_for_int_tex) { - struct gl_texture_image *img = texObj->Image[0][texObj->Attrib.BaseLevel]; + struct gl_texture_image *img = _mesa_base_tex_image(texObj); bool isMultisample = img && img->NumSamples >= 2; /* @@ -191,7 +187,7 @@ extern void _mesa_dirty_texobj(struct gl_context *ctx, struct gl_texture_object *texObj); extern struct gl_texture_object * -_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex); +_mesa_get_fallback_texture(struct gl_context *ctx, gl_texture_index tex, bool is_depth); extern GLuint _mesa_total_texture_memory(struct gl_context *ctx); @@ -205,99 +201,15 @@ _mesa_unlock_context_textures( struct gl_context *ctx ); extern void _mesa_lock_context_textures( struct gl_context *ctx ); -extern void -_mesa_delete_nameless_texture(struct gl_context *ctx, - struct gl_texture_object *texObj); - -extern void -_mesa_bind_texture(struct gl_context *ctx, GLenum target, - struct gl_texture_object *tex_obj); - extern struct gl_texture_object * _mesa_lookup_or_create_texture(struct gl_context *ctx, GLenum target, GLuint texName, bool no_error, bool is_ext_dsa, const char *name); - -/*@}*/ - -/** - * \name API functions - */ -/*@{*/ - -void GLAPIENTRY -_mesa_GenTextures_no_error(GLsizei n, GLuint *textures); - -extern void GLAPIENTRY -_mesa_GenTextures(GLsizei n, GLuint *textures); - -void GLAPIENTRY -_mesa_CreateTextures_no_error(GLenum target, GLsizei n, GLuint *textures); - -extern void GLAPIENTRY -_mesa_CreateTextures(GLenum target, GLsizei n, GLuint *textures); - -void GLAPIENTRY -_mesa_DeleteTextures_no_error(GLsizei n, const GLuint *textures); - -extern void GLAPIENTRY -_mesa_DeleteTextures( GLsizei n, const GLuint *textures ); - - -void GLAPIENTRY -_mesa_BindTexture_no_error(GLenum target, GLuint texture); - -extern void GLAPIENTRY -_mesa_BindTexture( GLenum target, GLuint texture ); - -void GLAPIENTRY -_mesa_BindMultiTextureEXT(GLenum texunit, GLenum target, GLuint texture); - -void GLAPIENTRY -_mesa_BindTextureUnit_no_error(GLuint unit, GLuint texture); - -extern void GLAPIENTRY -_mesa_BindTextureUnit(GLuint unit, GLuint texture); - -void GLAPIENTRY -_mesa_BindTextures_no_error(GLuint first, GLsizei count, - const GLuint *textures); - -extern void GLAPIENTRY -_mesa_BindTextures( GLuint first, GLsizei count, const GLuint *textures ); - - -extern void GLAPIENTRY -_mesa_PrioritizeTextures( GLsizei n, const GLuint *textures, - const GLclampf *priorities ); - - -extern GLboolean GLAPIENTRY -_mesa_AreTexturesResident( GLsizei n, const GLuint *textures, - GLboolean *residences ); - -extern GLboolean GLAPIENTRY -_mesa_IsTexture( GLuint texture ); - -void GLAPIENTRY -_mesa_InvalidateTexSubImage_no_error(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, - GLsizei width, GLsizei height, - GLsizei depth); - -extern void GLAPIENTRY -_mesa_InvalidateTexSubImage(GLuint texture, GLint level, GLint xoffset, - GLint yoffset, GLint zoffset, GLsizei width, - GLsizei height, GLsizei depth); -void GLAPIENTRY -_mesa_InvalidateTexImage_no_error(GLuint texture, GLint level); - -extern void GLAPIENTRY -_mesa_InvalidateTexImage(GLuint texture, GLint level); - +void +_mesa_update_texture_object_swizzle(struct gl_context *ctx, + struct gl_texture_object *texObj); /*@}*/ - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/texparam.c b/src/mesa/main/texparam.c index f4f61f52883..303e28d7eb0 100644 --- a/src/mesa/main/texparam.c +++ b/src/mesa/main/texparam.c @@ -30,7 +30,7 @@ */ #include <stdbool.h> -#include "main/glheader.h" +#include "util/glheader.h" #include "main/blend.h" #include "main/context.h" #include "main/enums.h" @@ -46,11 +46,15 @@ #include "main/texstate.h" #include "program/prog_instruction.h" #include "util/u_math.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_sampler_view.h" /** * Use macro to resolve undefined clamping behaviour when using lroundf */ -#define LCLAMPF(a, lmin, lmax) ((a) > (lmin) ? ( (a) >= (lmax) ? (lmax) : (lroundf(a)) ) : (lmin)) +#define LCLAMPF(a, lmin, lmax) ((a) > (float)(lmin) ? ( (a) >= (float)(lmax) ? (lmax) : (lroundf(a)) ) : (lmin)) /** * Check if a coordinate wrap mode is supported for the texture target. @@ -68,7 +72,7 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) /* GL_CLAMP was removed in the core profile, and it has never existed in * OpenGL ES. */ - supported = (ctx->API == API_OPENGL_COMPAT) + supported = _mesa_is_desktop_gl_compat(ctx) && (target != GL_TEXTURE_EXTERNAL_OES); break; @@ -77,7 +81,7 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) break; case GL_CLAMP_TO_BORDER: - supported = ctx->API != API_OPENGLES && e->ARB_texture_border_clamp + supported = ctx->API != API_OPENGLES && (target != GL_TEXTURE_EXTERNAL_OES); break; @@ -95,10 +99,12 @@ validate_texture_wrap_mode(struct gl_context * ctx, GLenum target, GLenum wrap) break; case GL_MIRROR_CLAMP_TO_EDGE_EXT: - supported = is_desktop_gl - && (e->ATI_texture_mirror_once || e->EXT_texture_mirror_clamp || e->ARB_texture_mirror_clamp_to_edge) - && (target != GL_TEXTURE_RECTANGLE_NV) - && (target != GL_TEXTURE_EXTERNAL_OES); + supported = (target != GL_TEXTURE_RECTANGLE_NV) + && (target != GL_TEXTURE_EXTERNAL_OES) + && (_mesa_has_ARB_texture_mirror_clamp_to_edge(ctx) || + _mesa_has_EXT_texture_mirror_clamp_to_edge(ctx) || + _mesa_has_ATI_texture_mirror_once(ctx) || + _mesa_has_EXT_texture_mirror_clamp(ctx)); break; case GL_MIRROR_CLAMP_TO_BORDER_EXT: @@ -243,12 +249,6 @@ _mesa_target_allows_setting_sampler_parameters(GLenum target) } -static inline GLboolean -is_wrap_gl_clamp(GLint param) -{ - return param == GL_CLAMP || param == GL_MIRROR_CLAMP_EXT; -} - /** * Set an integer-valued texture parameter * \return GL_TRUE if legal AND the value changed, GL_FALSE otherwise @@ -285,6 +285,9 @@ set_tex_parameteri(struct gl_context *ctx, case GL_LINEAR: flush(ctx); texObj->Sampler.Attrib.MinFilter = params[0]; + texObj->Sampler.Attrib.state.min_img_filter = filter_to_gallium(params[0]); + texObj->Sampler.Attrib.state.min_mip_filter = mipfilter_to_gallium(params[0]); + _mesa_lower_gl_clamp(ctx, &texObj->Sampler); return GL_TRUE; case GL_NEAREST_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_NEAREST: @@ -294,6 +297,9 @@ set_tex_parameteri(struct gl_context *ctx, texObj->Target != GL_TEXTURE_EXTERNAL_OES) { flush(ctx); texObj->Sampler.Attrib.MinFilter = params[0]; + texObj->Sampler.Attrib.state.min_img_filter = filter_to_gallium(params[0]); + texObj->Sampler.Attrib.state.min_mip_filter = mipfilter_to_gallium(params[0]); + _mesa_lower_gl_clamp(ctx, &texObj->Sampler); return GL_TRUE; } FALLTHROUGH; @@ -313,6 +319,8 @@ set_tex_parameteri(struct gl_context *ctx, case GL_LINEAR: flush(ctx); /* does not effect completeness */ texObj->Sampler.Attrib.MagFilter = params[0]; + texObj->Sampler.Attrib.state.mag_img_filter = filter_to_gallium(params[0]); + _mesa_lower_gl_clamp(ctx, &texObj->Sampler); return GL_TRUE; default: goto invalid_param; @@ -327,9 +335,10 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { flush(ctx); - if (is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapS) != is_wrap_gl_clamp(params[0])) - ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + update_sampler_gl_clamp(ctx, &texObj->Sampler, is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapS), is_wrap_gl_clamp(params[0]), WRAP_S); texObj->Sampler.Attrib.WrapS = params[0]; + texObj->Sampler.Attrib.state.wrap_s = wrap_to_gallium(params[0]); + _mesa_lower_gl_clamp(ctx, &texObj->Sampler); return GL_TRUE; } return GL_FALSE; @@ -342,9 +351,10 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { flush(ctx); - if (is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapT) != is_wrap_gl_clamp(params[0])) - ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + update_sampler_gl_clamp(ctx, &texObj->Sampler, is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapT), is_wrap_gl_clamp(params[0]), WRAP_T); texObj->Sampler.Attrib.WrapT = params[0]; + texObj->Sampler.Attrib.state.wrap_t = wrap_to_gallium(params[0]); + _mesa_lower_gl_clamp(ctx, &texObj->Sampler); return GL_TRUE; } return GL_FALSE; @@ -357,9 +367,10 @@ set_tex_parameteri(struct gl_context *ctx, return GL_FALSE; if (validate_texture_wrap_mode(ctx, texObj->Target, params[0])) { flush(ctx); - if (is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapR) != is_wrap_gl_clamp(params[0])) - ctx->NewDriverState |= ctx->DriverFlags.NewSamplersWithClamp; + update_sampler_gl_clamp(ctx, &texObj->Sampler, is_wrap_gl_clamp(texObj->Sampler.Attrib.WrapR), is_wrap_gl_clamp(params[0]), WRAP_R); texObj->Sampler.Attrib.WrapR = params[0]; + texObj->Sampler.Attrib.state.wrap_r = wrap_to_gallium(params[0]); + _mesa_lower_gl_clamp(ctx, &texObj->Sampler); return GL_TRUE; } return GL_FALSE; @@ -406,6 +417,9 @@ set_tex_parameteri(struct gl_context *ctx, else texObj->Attrib.BaseLevel = params[0]; + _mesa_update_teximage_format_swizzle(ctx, _mesa_base_tex_image(texObj), texObj->Attrib.DepthMode); + _mesa_update_texture_object_swizzle(ctx, texObj); + return GL_TRUE; case GL_TEXTURE_MAX_LEVEL: @@ -487,6 +501,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_NEVER: flush(ctx); texObj->Sampler.Attrib.CompareFunc = params[0]; + texObj->Sampler.Attrib.state.compare_func = func_to_gallium(params[0]); return GL_TRUE; default: goto invalid_param; @@ -498,7 +513,7 @@ set_tex_parameteri(struct gl_context *ctx, /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has never * existed in OpenGL ES. */ - if (ctx->API == API_OPENGL_COMPAT && ctx->Extensions.ARB_depth_texture) { + if (_mesa_is_desktop_gl_compat(ctx)) { if (texObj->Attrib.DepthMode == params[0]) return GL_FALSE; if (params[0] == GL_LUMINANCE || @@ -507,6 +522,8 @@ set_tex_parameteri(struct gl_context *ctx, (ctx->Extensions.ARB_texture_rg && params[0] == GL_RED)) { flush(ctx); texObj->Attrib.DepthMode = params[0]; + _mesa_update_teximage_format_swizzle(ctx, _mesa_base_tex_image(texObj), texObj->Attrib.DepthMode); + _mesa_update_texture_object_swizzle(ctx, texObj); return GL_TRUE; } goto invalid_param; @@ -543,8 +560,7 @@ set_tex_parameteri(struct gl_context *ctx, case GL_TEXTURE_SWIZZLE_G_EXT: case GL_TEXTURE_SWIZZLE_B_EXT: case GL_TEXTURE_SWIZZLE_A_EXT: - if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) - || _mesa_is_gles3(ctx)) { + if (_mesa_has_EXT_texture_swizzle(ctx) || _mesa_is_gles3(ctx)) { const GLuint comp = pname - GL_TEXTURE_SWIZZLE_R_EXT; const GLint swz = comp_to_swizzle(params[0]); if (swz < 0) { @@ -557,20 +573,20 @@ set_tex_parameteri(struct gl_context *ctx, flush(ctx); texObj->Attrib.Swizzle[comp] = params[0]; set_swizzle_component(&texObj->Attrib._Swizzle, comp, swz); + _mesa_update_texture_object_swizzle(ctx, texObj); return GL_TRUE; } goto invalid_pname; case GL_TEXTURE_SWIZZLE_RGBA_EXT: - if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.EXT_texture_swizzle) - || _mesa_is_gles3(ctx)) { - GLuint comp; + if (_mesa_has_EXT_texture_swizzle(ctx) || _mesa_is_gles3(ctx)) { flush(ctx); - for (comp = 0; comp < 4; comp++) { + for (GLuint comp = 0; comp < 4; comp++) { const GLint swz = comp_to_swizzle(params[comp]); if (swz >= 0) { texObj->Attrib.Swizzle[comp] = params[comp]; set_swizzle_component(&texObj->Attrib._Swizzle, comp, swz); + _mesa_update_texture_object_swizzle(ctx, texObj); } else { _mesa_error(ctx, GL_INVALID_ENUM, @@ -612,6 +628,7 @@ set_tex_parameteri(struct gl_context *ctx, if (texObj->Sampler.Attrib.ReductionMode != mode) { flush(ctx); texObj->Sampler.Attrib.ReductionMode = mode; + texObj->Sampler.Attrib.state.reduction_mode = reduction_to_gallium(mode); } return GL_TRUE; } @@ -619,8 +636,7 @@ set_tex_parameteri(struct gl_context *ctx, goto invalid_pname; case GL_TEXTURE_CUBE_MAP_SEAMLESS: - if (_mesa_is_desktop_gl(ctx) - && ctx->Extensions.AMD_seamless_cubemap_per_texture) { + if (_mesa_has_AMD_seamless_cubemap_per_texture(ctx)) { GLenum param = params[0]; if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) @@ -632,6 +648,7 @@ set_tex_parameteri(struct gl_context *ctx, if (param != texObj->Sampler.Attrib.CubeMapSeamless) { flush(ctx); texObj->Sampler.Attrib.CubeMapSeamless = param; + texObj->Sampler.Attrib.state.seamless_cube_map = param; } return GL_TRUE; } @@ -645,6 +662,46 @@ set_tex_parameteri(struct gl_context *ctx, } goto invalid_pname; + case GL_TEXTURE_SPARSE_ARB: + case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + + if (texObj->Immutable) + goto invalid_operation; + + if (pname == GL_TEXTURE_SPARSE_ARB) { + /* ARB_sparse_texture spec: + * + * INVALID_VALUE is generated if <pname> is TEXTURE_SPARSE_ARB, <param> + * is TRUE and <target> is not one of TEXTURE_2D, TEXTURE_2D_ARRAY, + * TEXTURE_CUBE_MAP, TEXTURE_CUBE_MAP_ARRAY, TEXTURE_3D, or + * TEXTURE_RECTANGLE. + * + * ARB_sparse_texture2 also allow TEXTURE_2D_MULTISAMPLE and + * TEXTURE_2D_MULTISAMPLE_ARRAY. + */ + if (params[0] && + texObj->Target != GL_TEXTURE_2D && + texObj->Target != GL_TEXTURE_2D_ARRAY && + texObj->Target != GL_TEXTURE_CUBE_MAP && + texObj->Target != GL_TEXTURE_CUBE_MAP_ARRAY && + texObj->Target != GL_TEXTURE_3D && + texObj->Target != GL_TEXTURE_RECTANGLE && + (!_mesa_has_ARB_sparse_texture2(ctx) || + (texObj->Target != GL_TEXTURE_2D_MULTISAMPLE && + texObj->Target != GL_TEXTURE_2D_MULTISAMPLE_ARRAY))) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glTex%sParameter(target=%d)", suffix, texObj->Target); + return GL_FALSE; + } + + texObj->IsSparse = !!params[0]; + } else + texObj->VirtualPageSizeIndex = params[0]; + + return GL_TRUE; + default: goto invalid_pname; } @@ -711,6 +768,7 @@ set_tex_parameterf(struct gl_context *ctx, return GL_FALSE; flush(ctx); texObj->Sampler.Attrib.MinLod = params[0]; + texObj->Sampler.Attrib.state.min_lod = MAX2(params[0], 0.0f); /* only positive vals */ return GL_TRUE; case GL_TEXTURE_MAX_LOD: @@ -724,6 +782,7 @@ set_tex_parameterf(struct gl_context *ctx, return GL_FALSE; flush(ctx); texObj->Sampler.Attrib.MaxLod = params[0]; + texObj->Sampler.Attrib.state.max_lod = params[0]; return GL_TRUE; case GL_TEXTURE_PRIORITY: @@ -750,6 +809,9 @@ set_tex_parameterf(struct gl_context *ctx, /* clamp to max, that's what NVIDIA does */ texObj->Sampler.Attrib.MaxAnisotropy = MIN2(params[0], ctx->Const.MaxTextureMaxAnisotropy); + texObj->Sampler.Attrib.state.max_anisotropy = + texObj->Sampler.Attrib.MaxAnisotropy == 1 ? + 0 : texObj->Sampler.Attrib.MaxAnisotropy; /* gallium sets 0 for 1 */ return GL_TRUE; } else { @@ -770,6 +832,7 @@ set_tex_parameterf(struct gl_context *ctx, if (texObj->Sampler.Attrib.LodBias != params[0]) { flush(ctx); texObj->Sampler.Attrib.LodBias = params[0]; + texObj->Sampler.Attrib.state.lod_bias = util_quantize_lod_bias(params[0]); return GL_TRUE; } break; @@ -778,13 +841,8 @@ set_tex_parameterf(struct gl_context *ctx, /* Border color exists in desktop OpenGL since 1.0 for GL_CLAMP. In * OpenGL ES 2.0+, it only exists in when GL_OES_texture_border_clamp is * enabled. It is never available in OpenGL ES 1.x. - * - * FIXME: Every driver that supports GLES2 has this extension. Elide - * the check? */ - if (ctx->API == API_OPENGLES || - (ctx->API == API_OPENGLES2 && - !ctx->Extensions.ARB_texture_border_clamp)) + if (_mesa_is_gles1(ctx)) goto invalid_pname; if (!_mesa_target_allows_setting_sampler_parameters(texObj->Target)) @@ -793,16 +851,14 @@ set_tex_parameterf(struct gl_context *ctx, flush(ctx); /* ARB_texture_float disables clamping */ if (ctx->Extensions.ARB_texture_float) { - texObj->Sampler.Attrib.BorderColor.f[RCOMP] = params[0]; - texObj->Sampler.Attrib.BorderColor.f[GCOMP] = params[1]; - texObj->Sampler.Attrib.BorderColor.f[BCOMP] = params[2]; - texObj->Sampler.Attrib.BorderColor.f[ACOMP] = params[3]; + memcpy(texObj->Sampler.Attrib.state.border_color.f, params, 4 * sizeof(float)); } else { - texObj->Sampler.Attrib.BorderColor.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F); - texObj->Sampler.Attrib.BorderColor.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F); - texObj->Sampler.Attrib.BorderColor.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F); - texObj->Sampler.Attrib.BorderColor.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F); + texObj->Sampler.Attrib.state.border_color.f[RCOMP] = CLAMP(params[0], 0.0F, 1.0F); + texObj->Sampler.Attrib.state.border_color.f[GCOMP] = CLAMP(params[1], 0.0F, 1.0F); + texObj->Sampler.Attrib.state.border_color.f[BCOMP] = CLAMP(params[2], 0.0F, 1.0F); + texObj->Sampler.Attrib.state.border_color.f[ACOMP] = CLAMP(params[3], 0.0F, 1.0F); } + _mesa_update_is_border_color_nonzero(&texObj->Sampler); return GL_TRUE; case GL_TEXTURE_TILING_EXT: @@ -834,6 +890,41 @@ invalid_enum: return GL_FALSE; } +static bool +texparam_invalidates_sampler_views(GLenum pname) +{ + switch (pname) { + /* + * Changing any of these texture parameters means we must create + * new sampler views. + */ + case GL_ALL_ATTRIB_BITS: /* meaning is all pnames, internal */ + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_DEPTH_TEXTURE_MODE: + case GL_DEPTH_STENCIL_TEXTURE_MODE: + case GL_TEXTURE_SRGB_DECODE_EXT: + case GL_TEXTURE_SWIZZLE_R: + case GL_TEXTURE_SWIZZLE_G: + case GL_TEXTURE_SWIZZLE_B: + case GL_TEXTURE_SWIZZLE_A: + case GL_TEXTURE_SWIZZLE_RGBA: + case GL_TEXTURE_BUFFER_SIZE: + case GL_TEXTURE_BUFFER_OFFSET: + return true; + default: + return false; + } +} + +static void +_mesa_texture_parameter_invalidate(struct gl_context *ctx, + struct gl_texture_object *texObj, + GLenum pname) +{ + if (texparam_invalidates_sampler_views(pname)) + st_texture_release_all_sampler_views(st_context(ctx), texObj); +} void _mesa_texture_parameterf(struct gl_context *ctx, @@ -862,11 +953,13 @@ _mesa_texture_parameterf(struct gl_context *ctx, case GL_TEXTURE_SWIZZLE_G_EXT: case GL_TEXTURE_SWIZZLE_B_EXT: case GL_TEXTURE_SWIZZLE_A_EXT: + case GL_TEXTURE_SPARSE_ARB: + case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB: { GLint p[4]; p[0] = (param > 0) ? - ((param > INT_MAX) ? INT_MAX : (GLint) (param + 0.5)) : - ((param < INT_MIN) ? INT_MIN : (GLint) (param - 0.5)); + ((param > (float)INT32_MAX) ? INT32_MAX : (GLint) (param + 0.5)) : + ((param < (float)INT32_MIN) ? INT32_MIN : (GLint) (param - 0.5)); p[1] = p[2] = p[3] = 0; need_update = set_tex_parameteri(ctx, texObj, pname, p, dsa); @@ -887,8 +980,8 @@ _mesa_texture_parameterf(struct gl_context *ctx, } } - if (ctx->Driver.TexParameter && need_update) { - ctx->Driver.TexParameter(ctx, texObj, pname); + if (need_update) { + _mesa_texture_parameter_invalidate(ctx, texObj, pname); } } @@ -915,6 +1008,8 @@ _mesa_texture_parameterfv(struct gl_context *ctx, case GL_TEXTURE_SRGB_DECODE_EXT: case GL_TEXTURE_REDUCTION_MODE_EXT: case GL_TEXTURE_CUBE_MAP_SEAMLESS: + case GL_TEXTURE_SPARSE_ARB: + case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB: { /* convert float param to int */ GLint p[4]; @@ -955,8 +1050,8 @@ _mesa_texture_parameterfv(struct gl_context *ctx, need_update = set_tex_parameterf(ctx, texObj, pname, params, dsa); } - if (ctx->Driver.TexParameter && need_update) { - ctx->Driver.TexParameter(ctx, texObj, pname); + if (need_update) { + _mesa_texture_parameter_invalidate(ctx, texObj, pname); } } @@ -999,8 +1094,8 @@ _mesa_texture_parameteri(struct gl_context *ctx, } } - if (ctx->Driver.TexParameter && need_update) { - ctx->Driver.TexParameter(ctx, texObj, pname); + if (need_update) { + _mesa_texture_parameter_invalidate(ctx, texObj, pname); } } @@ -1042,8 +1137,8 @@ _mesa_texture_parameteriv(struct gl_context *ctx, need_update = set_tex_parameteri(ctx, texObj, pname, params, dsa); } - if (ctx->Driver.TexParameter && need_update) { - ctx->Driver.TexParameter(ctx, texObj, pname); + if (need_update) { + _mesa_texture_parameter_invalidate(ctx, texObj, pname); } } @@ -1066,7 +1161,8 @@ _mesa_texture_parameterIiv(struct gl_context *ctx, } FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); /* set the integer-valued border color */ - COPY_4V(texObj->Sampler.Attrib.BorderColor.i, params); + COPY_4V(texObj->Sampler.Attrib.state.border_color.i, params); + _mesa_update_is_border_color_nonzero(&texObj->Sampler); break; default: _mesa_texture_parameteriv(ctx, texObj, pname, params, dsa); @@ -1094,7 +1190,8 @@ _mesa_texture_parameterIuiv(struct gl_context *ctx, } FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, GL_TEXTURE_BIT); /* set the unsigned integer-valued border color */ - COPY_4V(texObj->Sampler.Attrib.BorderColor.ui, params); + COPY_4V(texObj->Sampler.Attrib.state.border_color.ui, params); + _mesa_update_is_border_color_nonzero(&texObj->Sampler); break; default: _mesa_texture_parameteriv(ctx, texObj, pname, (const GLint *) params, @@ -1535,7 +1632,7 @@ _mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - return ctx->Extensions.ARB_texture_cube_map; + return GL_TRUE; case GL_TEXTURE_2D_MULTISAMPLE: case GL_TEXTURE_2D_MULTISAMPLE_ARRAY: return ctx->Extensions.ARB_texture_multisample; @@ -1556,9 +1653,13 @@ _mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target * * From the OpenGL 3.1 spec: * "target may also be TEXTURE_BUFFER, indicating the texture buffer." + * + * From ARB_texture_buffer_range, GL_TEXTURE is a valid target in + * GetTexLevelParameter. */ return (_mesa_is_desktop_gl(ctx) && ctx->Version >= 31) || - _mesa_has_OES_texture_buffer(ctx); + _mesa_has_OES_texture_buffer(ctx) || + _mesa_has_ARB_texture_buffer_range(ctx); case GL_TEXTURE_CUBE_MAP_ARRAY: return _mesa_has_texture_cube_map_array(ctx); } @@ -1572,9 +1673,8 @@ _mesa_legal_get_tex_level_parameter_target(struct gl_context *ctx, GLenum target case GL_PROXY_TEXTURE_1D: case GL_PROXY_TEXTURE_2D: case GL_PROXY_TEXTURE_3D: - return GL_TRUE; case GL_PROXY_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map; + return GL_TRUE; case GL_PROXY_TEXTURE_CUBE_MAP_ARRAY: return ctx->Extensions.ARB_texture_cube_map_array; case GL_TEXTURE_RECTANGLE_NV: @@ -1707,8 +1807,6 @@ get_tex_level_parameter_image(struct gl_context *ctx, } break; case GL_TEXTURE_DEPTH_SIZE_ARB: - if (!ctx->Extensions.ARB_depth_texture) - goto invalid_pname; *params = _mesa_get_format_bits(texFormat, pname); break; case GL_TEXTURE_STENCIL_SIZE: @@ -2199,21 +2297,20 @@ get_tex_parameterfv(struct gl_context *ctx, *params = ENUM_TO_FLOAT(obj->Sampler.Attrib.WrapR); break; case GL_TEXTURE_BORDER_COLOR: - if (ctx->API == API_OPENGLES || - !ctx->Extensions.ARB_texture_border_clamp) + if (_mesa_is_gles1(ctx)) goto invalid_pname; if (_mesa_get_clamp_fragment_color(ctx, ctx->DrawBuffer)) { - params[0] = CLAMP(obj->Sampler.Attrib.BorderColor.f[0], 0.0F, 1.0F); - params[1] = CLAMP(obj->Sampler.Attrib.BorderColor.f[1], 0.0F, 1.0F); - params[2] = CLAMP(obj->Sampler.Attrib.BorderColor.f[2], 0.0F, 1.0F); - params[3] = CLAMP(obj->Sampler.Attrib.BorderColor.f[3], 0.0F, 1.0F); + params[0] = CLAMP(obj->Sampler.Attrib.state.border_color.f[0], 0.0F, 1.0F); + params[1] = CLAMP(obj->Sampler.Attrib.state.border_color.f[1], 0.0F, 1.0F); + params[2] = CLAMP(obj->Sampler.Attrib.state.border_color.f[2], 0.0F, 1.0F); + params[3] = CLAMP(obj->Sampler.Attrib.state.border_color.f[3], 0.0F, 1.0F); } else { - params[0] = obj->Sampler.Attrib.BorderColor.f[0]; - params[1] = obj->Sampler.Attrib.BorderColor.f[1]; - params[2] = obj->Sampler.Attrib.BorderColor.f[2]; - params[3] = obj->Sampler.Attrib.BorderColor.f[3]; + params[0] = obj->Sampler.Attrib.state.border_color.f[0]; + params[1] = obj->Sampler.Attrib.state.border_color.f[1]; + params[2] = obj->Sampler.Attrib.state.border_color.f[2]; + params[3] = obj->Sampler.Attrib.state.border_color.f[3]; } break; case GL_TEXTURE_RESIDENT: @@ -2276,7 +2373,7 @@ get_tex_parameterfv(struct gl_context *ctx, /* GL_DEPTH_TEXTURE_MODE_ARB is removed in core-profile and it has * never existed in OpenGL ES. */ - if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) + if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLfloat) obj->Attrib.DepthMode; break; @@ -2306,30 +2403,20 @@ get_tex_parameterfv(struct gl_context *ctx, case GL_TEXTURE_SWIZZLE_G_EXT: case GL_TEXTURE_SWIZZLE_B_EXT: case GL_TEXTURE_SWIZZLE_A_EXT: - if ((!_mesa_is_desktop_gl(ctx) - || !ctx->Extensions.EXT_texture_swizzle) - && !_mesa_is_gles3(ctx)) + if (!_mesa_has_EXT_texture_swizzle(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; *params = (GLfloat) obj->Attrib.Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; break; case GL_TEXTURE_SWIZZLE_RGBA_EXT: - if ((!_mesa_is_desktop_gl(ctx) - || !ctx->Extensions.EXT_texture_swizzle) - && !_mesa_is_gles3(ctx)) { + if (!_mesa_has_EXT_texture_swizzle(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; - } - else { - GLuint comp; - for (comp = 0; comp < 4; comp++) { - params[comp] = (GLfloat) obj->Attrib.Swizzle[comp]; - } - } + for (GLuint comp = 0; comp < 4; comp++) + params[comp] = (GLfloat) obj->Attrib.Swizzle[comp]; break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: - if (!_mesa_is_desktop_gl(ctx) - || !ctx->Extensions.AMD_seamless_cubemap_per_texture) + if (!_mesa_has_AMD_seamless_cubemap_per_texture(ctx)) goto invalid_pname; *params = (GLfloat) obj->Sampler.Attrib.CubeMapSeamless; break; @@ -2389,7 +2476,8 @@ get_tex_parameterfv(struct gl_context *ctx, break; case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: - if (!ctx->Extensions.ARB_shader_image_load_store) + if (!ctx->Extensions.ARB_shader_image_load_store && + !_mesa_is_gles31(ctx)) goto invalid_pname; *params = (GLfloat) obj->Attrib.ImageFormatCompatibilityType; break; @@ -2406,6 +2494,24 @@ get_tex_parameterfv(struct gl_context *ctx, *params = ENUM_TO_FLOAT(obj->TextureTiling); break; + case GL_TEXTURE_SPARSE_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + *params = (GLfloat) obj->IsSparse; + break; + + case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + *params = (GLfloat) obj->VirtualPageSizeIndex; + break; + + case GL_NUM_SPARSE_LEVELS_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + *params = (GLfloat) obj->NumSparseLevels; + break; + default: goto invalid_pname; } @@ -2444,16 +2550,15 @@ get_tex_parameteriv(struct gl_context *ctx, *params = (GLint) obj->Sampler.Attrib.WrapR; break; case GL_TEXTURE_BORDER_COLOR: - if (ctx->API == API_OPENGLES || - !ctx->Extensions.ARB_texture_border_clamp) + if (_mesa_is_gles1(ctx)) goto invalid_pname; { GLfloat b[4]; - b[0] = CLAMP(obj->Sampler.Attrib.BorderColor.f[0], 0.0F, 1.0F); - b[1] = CLAMP(obj->Sampler.Attrib.BorderColor.f[1], 0.0F, 1.0F); - b[2] = CLAMP(obj->Sampler.Attrib.BorderColor.f[2], 0.0F, 1.0F); - b[3] = CLAMP(obj->Sampler.Attrib.BorderColor.f[3], 0.0F, 1.0F); + b[0] = CLAMP(obj->Sampler.Attrib.state.border_color.f[0], 0.0F, 1.0F); + b[1] = CLAMP(obj->Sampler.Attrib.state.border_color.f[1], 0.0F, 1.0F); + b[2] = CLAMP(obj->Sampler.Attrib.state.border_color.f[2], 0.0F, 1.0F); + b[3] = CLAMP(obj->Sampler.Attrib.state.border_color.f[3], 0.0F, 1.0F); params[0] = FLOAT_TO_INT(b[0]); params[1] = FLOAT_TO_INT(b[1]); params[2] = FLOAT_TO_INT(b[2]); @@ -2485,7 +2590,7 @@ get_tex_parameteriv(struct gl_context *ctx, * it cannot be represented by the returned data type, then the * nearest value representable using that type is returned. */ - *params = LCLAMPF(obj->Sampler.Attrib.MinLod, INT_MIN, INT_MAX); + *params = LCLAMPF(obj->Sampler.Attrib.MinLod, INT32_MIN, INT32_MAX); break; case GL_TEXTURE_MAX_LOD: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) @@ -2500,7 +2605,7 @@ get_tex_parameteriv(struct gl_context *ctx, * it cannot be represented by the returned data type, then the * nearest value representable using that type is returned. */ - *params = LCLAMPF(obj->Sampler.Attrib.MaxLod, INT_MIN, INT_MAX); + *params = LCLAMPF(obj->Sampler.Attrib.MaxLod, INT32_MIN, INT32_MAX); break; case GL_TEXTURE_BASE_LEVEL: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) @@ -2524,7 +2629,7 @@ get_tex_parameteriv(struct gl_context *ctx, * it cannot be represented by the returned data type, then the * nearest value representable using that type is returned. */ - *params = LCLAMPF(obj->Sampler.Attrib.MaxAnisotropy, INT_MIN, INT_MAX); + *params = LCLAMPF(obj->Sampler.Attrib.MaxAnisotropy, INT32_MIN, INT32_MAX); break; case GL_GENERATE_MIPMAP_SGIS: if (ctx->API != API_OPENGL_COMPAT && ctx->API != API_OPENGLES) @@ -2545,7 +2650,7 @@ get_tex_parameteriv(struct gl_context *ctx, *params = (GLint) obj->Sampler.Attrib.CompareFunc; break; case GL_DEPTH_TEXTURE_MODE_ARB: - if (ctx->API != API_OPENGL_COMPAT || !ctx->Extensions.ARB_depth_texture) + if (ctx->API != API_OPENGL_COMPAT) goto invalid_pname; *params = (GLint) obj->Attrib.DepthMode; break; @@ -2569,7 +2674,7 @@ get_tex_parameteriv(struct gl_context *ctx, * it cannot be represented by the returned data type, then the * nearest value representable using that type is returned. */ - *params = LCLAMPF(obj->Sampler.Attrib.LodBias, INT_MIN, INT_MAX); + *params = LCLAMPF(obj->Sampler.Attrib.LodBias, INT32_MIN, INT32_MAX); break; case GL_TEXTURE_CROP_RECT_OES: if (ctx->API != API_OPENGLES || !ctx->Extensions.OES_draw_texture) @@ -2584,24 +2689,19 @@ get_tex_parameteriv(struct gl_context *ctx, case GL_TEXTURE_SWIZZLE_G_EXT: case GL_TEXTURE_SWIZZLE_B_EXT: case GL_TEXTURE_SWIZZLE_A_EXT: - if ((!_mesa_is_desktop_gl(ctx) - || !ctx->Extensions.EXT_texture_swizzle) - && !_mesa_is_gles3(ctx)) + if (!_mesa_has_EXT_texture_swizzle(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; *params = obj->Attrib.Swizzle[pname - GL_TEXTURE_SWIZZLE_R_EXT]; break; case GL_TEXTURE_SWIZZLE_RGBA_EXT: - if ((!_mesa_is_desktop_gl(ctx) - || !ctx->Extensions.EXT_texture_swizzle) - && !_mesa_is_gles3(ctx)) + if (!_mesa_has_EXT_texture_swizzle(ctx) && !_mesa_is_gles3(ctx)) goto invalid_pname; COPY_4V(params, obj->Attrib.Swizzle); break; case GL_TEXTURE_CUBE_MAP_SEAMLESS: - if (!_mesa_is_desktop_gl(ctx) - || !ctx->Extensions.AMD_seamless_cubemap_per_texture) + if (_mesa_has_AMD_seamless_cubemap_per_texture(ctx)) goto invalid_pname; *params = (GLint) obj->Sampler.Attrib.CubeMapSeamless; break; @@ -2611,8 +2711,7 @@ get_tex_parameteriv(struct gl_context *ctx, break; case GL_TEXTURE_IMMUTABLE_LEVELS: - if (_mesa_is_gles3(ctx) || - (_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_texture_view)) + if (_mesa_has_ARB_texture_view(ctx) || _mesa_is_gles3(ctx)) *params = obj->Attrib.ImmutableLevels; else goto invalid_pname; @@ -2662,7 +2761,8 @@ get_tex_parameteriv(struct gl_context *ctx, break; case GL_IMAGE_FORMAT_COMPATIBILITY_TYPE: - if (!ctx->Extensions.ARB_shader_image_load_store) + if (!ctx->Extensions.ARB_shader_image_load_store && + !_mesa_is_gles31(ctx)) goto invalid_pname; *params = obj->Attrib.ImageFormatCompatibilityType; break; @@ -2679,6 +2779,24 @@ get_tex_parameteriv(struct gl_context *ctx, *params = (GLint) obj->TextureTiling; break; + case GL_TEXTURE_SPARSE_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + *params = obj->IsSparse; + break; + + case GL_VIRTUAL_PAGE_SIZE_INDEX_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + *params = obj->VirtualPageSizeIndex; + break; + + case GL_NUM_SPARSE_LEVELS_ARB: + if (!_mesa_has_ARB_sparse_texture(ctx)) + goto invalid_pname; + *params = obj->NumSparseLevels; + break; + default: goto invalid_pname; } @@ -2700,7 +2818,7 @@ get_tex_parameterIiv(struct gl_context *ctx, { switch (pname) { case GL_TEXTURE_BORDER_COLOR: - COPY_4V(params, obj->Sampler.Attrib.BorderColor.i); + COPY_4V(params, obj->Sampler.Attrib.state.border_color.i); break; default: get_tex_parameteriv(ctx, obj, pname, params, dsa); diff --git a/src/mesa/main/texparam.h b/src/mesa/main/texparam.h index d352b560138..113ed1d989b 100644 --- a/src/mesa/main/texparam.h +++ b/src/mesa/main/texparam.h @@ -27,7 +27,7 @@ #define TEXPARAM_H -#include "main/glheader.h" +#include "util/glheader.h" /** * \name Internal functions @@ -74,167 +74,4 @@ _mesa_target_allows_setting_sampler_parameters(GLenum target); /*@}*/ -/** - * \name API functions - */ -/*@{*/ - - -extern void GLAPIENTRY -_mesa_GetTexLevelParameterfv( GLenum target, GLint level, - GLenum pname, GLfloat *params ); - -extern void GLAPIENTRY -_mesa_GetTexLevelParameteriv( GLenum target, GLint level, - GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_mesa_GetTextureLevelParameterfv(GLuint texture, GLint level, - GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetTextureLevelParameteriv(GLuint texture, GLint level, - GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetTextureLevelParameterfvEXT(GLuint texture, GLenum target, - GLint level, GLenum pname, - GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetTextureLevelParameterivEXT(GLuint texture, GLenum target, - GLint level, GLenum pname, - GLint *params); - -extern void GLAPIENTRY -_mesa_GetMultiTexLevelParameterfvEXT(GLenum texunit, GLenum target, - GLint level, GLenum pname, - GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetMultiTexLevelParameterivEXT(GLenum texunit, GLenum target, - GLint level, GLenum pname, - GLint *params); - -extern void GLAPIENTRY -_mesa_GetTexParameterfv( GLenum target, GLenum pname, GLfloat *params ); - -extern void GLAPIENTRY -_mesa_GetTexParameteriv( GLenum target, GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_mesa_GetTexParameterIiv(GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetTexParameterIuiv(GLenum target, GLenum pname, GLuint *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterfv(GLuint texture, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params ); - -extern void GLAPIENTRY -_mesa_GetTextureParameteriv(GLuint texture, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterIiv(GLuint texture, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetMultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterIuiv(GLuint texture, GLenum pname, GLuint *params); - -extern void GLAPIENTRY -_mesa_GetTextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, GLuint *params); - -extern void GLAPIENTRY -_mesa_GetMultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, GLuint *params); - - -extern void GLAPIENTRY -_mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ); - -extern void GLAPIENTRY -_mesa_TexParameterf( GLenum target, GLenum pname, GLfloat param ); - -extern void GLAPIENTRY -_mesa_TexParameteri( GLenum target, GLenum pname, GLint param ); - -extern void GLAPIENTRY -_mesa_TexParameteriv( GLenum target, GLenum pname, const GLint *params ); - -extern void GLAPIENTRY -_mesa_TexParameterIiv(GLenum target, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_TexParameterIuiv(GLenum target, GLenum pname, const GLuint *params); - -extern void GLAPIENTRY -_mesa_TextureParameterfvEXT(GLuint texture, GLenum target, GLenum pname, const GLfloat *params); - -extern void GLAPIENTRY -_mesa_TextureParameterfv(GLuint texture, GLenum pname, const GLfloat *params); - -extern void GLAPIENTRY -_mesa_TextureParameterfEXT(GLuint texture, GLenum target, GLenum pname, GLfloat param); - -extern void GLAPIENTRY -_mesa_TextureParameterf(GLuint texture, GLenum pname, GLfloat param); - -extern void GLAPIENTRY -_mesa_TextureParameteriEXT(GLuint texture, GLenum target, GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_TextureParameteri(GLuint texture, GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_TextureParameterivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_TextureParameteriv(GLuint texture, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_TextureParameterIiv(GLuint texture, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_TextureParameterIivEXT(GLuint texture, GLenum target, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_MultiTexParameterIivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_TextureParameterIuiv(GLuint texture, GLenum pname, const GLuint *params); - -extern void GLAPIENTRY -_mesa_TextureParameterIuivEXT(GLuint texture, GLenum target, GLenum pname, const GLuint *params); - -extern void GLAPIENTRY -_mesa_MultiTexParameterIuivEXT(GLenum texunit, GLenum target, GLenum pname, const GLuint *params); - -extern void GLAPIENTRY -_mesa_MultiTexParameterfEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat param); - -extern void GLAPIENTRY -_mesa_MultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, const GLfloat *params); - -extern void GLAPIENTRY -_mesa_MultiTexParameteriEXT(GLenum texunit, GLenum target, GLenum pname, GLint param); - -extern void GLAPIENTRY -_mesa_MultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, const GLint *params); - -extern void GLAPIENTRY -_mesa_GetMultiTexParameterfvEXT(GLenum texunit, GLenum target, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetMultiTexParameterivEXT(GLenum texunit, GLenum target, GLenum pname, GLint *params); - #endif /* TEXPARAM_H */ diff --git a/src/mesa/main/texstate.c b/src/mesa/main/texstate.c index cbdfb1899cf..f2c0e5e5acb 100644 --- a/src/mesa/main/texstate.c +++ b/src/mesa/main/texstate.c @@ -29,7 +29,7 @@ */ #include <stdio.h> -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "context.h" #include "enums.h" @@ -41,7 +41,9 @@ #include "state.h" #include "util/bitscan.h" #include "util/bitset.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_texture.h" /** * Default texture combine environment state. This is used to initialize @@ -76,6 +78,7 @@ _mesa_copy_texture_state( const struct gl_context *src, struct gl_context *dst ) /* per-unit state */ for (u = 0; u < src->Const.MaxCombinedTextureImageUnits; u++) { dst->Texture.Unit[u].LodBias = src->Texture.Unit[u].LodBias; + dst->Texture.Unit[u].LodBiasQuantized = src->Texture.Unit[u].LodBiasQuantized; /* * XXX strictly speaking, we should compare texture names/ids and @@ -538,7 +541,7 @@ update_tex_combine(struct gl_context *ctx, } else { const struct gl_texture_object *texObj = texUnit->_Current; - GLenum format = texObj->Image[0][texObj->Attrib.BaseLevel]->_BaseFormat; + GLenum format = _mesa_base_tex_image(texObj)->_BaseFormat; if (format == GL_DEPTH_COMPONENT || format == GL_DEPTH_STENCIL_EXT) { format = texObj->Attrib.DepthMode; @@ -701,7 +704,7 @@ update_single_program_texture(struct gl_context *ctx, struct gl_program *prog, * Mesa implements this by creating a hidden texture object with a pixel of * that value. */ - texObj = _mesa_get_fallback_texture(ctx, target_index); + texObj = _mesa_get_fallback_texture(ctx, target_index, !!(prog->ShadowSamplers & BITFIELD_BIT(unit))); assert(texObj); return texObj; @@ -867,7 +870,7 @@ fix_missing_textures_for_atifs(struct gl_context *ctx, if (!ctx->Texture.Unit[unit]._Current) { struct gl_texture_object *texObj = - _mesa_get_fallback_texture(ctx, target_index); + _mesa_get_fallback_texture(ctx, target_index, false); _mesa_reference_texobj(&ctx->Texture.Unit[unit]._Current, texObj); BITSET_SET(enabled_texture_units, unit); ctx->Texture._MaxEnabledTexImageUnit = @@ -1004,10 +1007,10 @@ alloc_proxy_textures( struct gl_context *ctx ) for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) { if (!(ctx->Texture.ProxyTex[tgt] - = ctx->Driver.NewTextureObject(ctx, 0, targets[tgt]))) { + = _mesa_new_texture_object(ctx, 0, targets[tgt]))) { /* out of memory, free what we did allocate */ while (--tgt >= 0) { - ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); + _mesa_delete_texture_object(ctx, ctx->Texture.ProxyTex[tgt]); } return GL_FALSE; } @@ -1029,23 +1032,6 @@ _mesa_init_texture(struct gl_context *ctx) /* Texture group */ ctx->Texture.CurrentUnit = 0; /* multitexture */ - /* Appendix F.2 of the OpenGL ES 3.0 spec says: - * - * "OpenGL ES 3.0 requires that all cube map filtering be - * seamless. OpenGL ES 2.0 specified that a single cube map face be - * selected and used for filtering." - * - * Unfortunatley, a call to _mesa_is_gles3 below will only work if - * the driver has already computed and set ctx->Version, however drivers - * seem to call _mesa_initialize_context (which calls this) early - * in the CreateContext hook and _mesa_compute_version much later (since - * it needs information about available extensions). So, we will - * enable seamless cubemaps by default since GLES2. This should work - * for most implementations and drivers that don't support seamless - * cubemaps for GLES2 can still disable it. - */ - ctx->Texture.CubeMapSeamless = ctx->API == API_OPENGLES2; - for (u = 0; u < ARRAY_SIZE(ctx->Texture.Unit); u++) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[u]; GLuint tex; @@ -1131,7 +1117,7 @@ _mesa_free_texture_data(struct gl_context *ctx) /* Free proxy texture objects */ for (tgt = 0; tgt < NUM_TEXTURE_TARGETS; tgt++) - ctx->Driver.DeleteTexture(ctx, ctx->Texture.ProxyTex[tgt]); + _mesa_delete_texture_object(ctx, ctx->Texture.ProxyTex[tgt]); /* GL_ARB_texture_buffer_object */ _mesa_reference_buffer_object(ctx, &ctx->Texture.BufferObject, NULL); diff --git a/src/mesa/main/texstate.h b/src/mesa/main/texstate.h index bc9a6457305..da3dd4bde10 100644 --- a/src/mesa/main/texstate.h +++ b/src/mesa/main/texstate.h @@ -86,24 +86,6 @@ extern void _mesa_print_texunit_state( struct gl_context *ctx, GLuint unit ); - -/** - * \name Called from API - */ -/*@{*/ - -extern void GLAPIENTRY -_mesa_ActiveTexture_no_error( GLenum target ); - -extern void GLAPIENTRY -_mesa_ActiveTexture( GLenum target ); - -extern void GLAPIENTRY -_mesa_ClientActiveTexture( GLenum target ); - -/*@}*/ - - /** * \name Initialization, state maintenance */ diff --git a/src/mesa/main/texstorage.c b/src/mesa/main/texstorage.c index 932308c6471..8ecaa7b4f14 100644 --- a/src/mesa/main/texstorage.c +++ b/src/mesa/main/texstorage.c @@ -27,7 +27,7 @@ * GL_ARB_texture_storage functions */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" @@ -40,7 +40,9 @@ #include "mtypes.h" #include "glformats.h" #include "hash.h" +#include "api_exec_decl.h" +#include "state_tracker/st_cb_texture.h" /** * Check if the given texture target is a legal texture object target @@ -48,11 +50,12 @@ * This is a bit different than legal_teximage_target() when it comes * to cube maps. */ -static bool -legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target) +bool +_mesa_is_legal_tex_storage_target(const struct gl_context *ctx, + GLuint dims, GLenum target) { if (dims < 1 || dims > 3) { - _mesa_problem(ctx, "invalid dims=%u in legal_texobj_target()", dims); + _mesa_problem(ctx, "invalid dims=%u in _mesa_is_legal_tex_storage_target()", dims); return false; } @@ -60,9 +63,8 @@ legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target) case 2: switch (target) { case GL_TEXTURE_2D: - return true; case GL_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map; + return true; } break; case 3: @@ -92,9 +94,8 @@ legal_texobj_target(const struct gl_context *ctx, GLuint dims, GLenum target) case 2: switch (target) { case GL_PROXY_TEXTURE_2D: - return true; case GL_PROXY_TEXTURE_CUBE_MAP: - return ctx->Extensions.ARB_texture_cube_map; + return true; case GL_TEXTURE_RECTANGLE: case GL_PROXY_TEXTURE_RECTANGLE: return ctx->Extensions.NV_texture_rectangle; @@ -168,6 +169,7 @@ initialize_texture_fields(struct gl_context *ctx, levelWidth, levelHeight, levelDepth, &levelWidth, &levelHeight, &levelDepth); } + _mesa_update_texture_object_swizzle(ctx, texObj); return GL_TRUE; } @@ -219,6 +221,56 @@ GLboolean _mesa_is_legal_tex_storage_format(const struct gl_context *ctx, GLenum internalformat) { + if (!_mesa_is_desktop_gl(ctx)) { + assert(_mesa_has_EXT_texture_storage(ctx)); + + /* EXT_texture_storage allows us to use some sized internal formats + * for TexStorage* that aren't otherwise allowed in OpenGL ES. + **/ + switch (internalformat) { + case GL_ALPHA8: + case GL_LUMINANCE8: + case GL_LUMINANCE8_ALPHA8: + return true; + + case GL_RGBA32F: + case GL_RGB32F: + case GL_ALPHA32F_EXT: + case GL_LUMINANCE32F_EXT: + case GL_LUMINANCE_ALPHA32F_EXT: + return _mesa_has_OES_texture_float(ctx); + + case GL_RGBA16F: + case GL_RGB16F: + case GL_ALPHA16F_EXT: + case GL_LUMINANCE16F_EXT: + case GL_LUMINANCE_ALPHA16F_EXT: + return _mesa_has_OES_texture_half_float(ctx); + + case GL_RGB10_A2: + case GL_RGB10: + return _mesa_has_EXT_texture_type_2_10_10_10_REV(ctx); + + case GL_BGRA8_EXT: + assert(_mesa_has_EXT_texture_format_BGRA8888(ctx)); + return true; + + case GL_R8: + case GL_RG8: + return _mesa_has_EXT_texture_rg(ctx); + + case GL_R32F_EXT: + case GL_RG32F_EXT: + return _mesa_has_EXT_texture_rg(ctx) && + _mesa_has_OES_texture_float(ctx); + + case GL_R16F_EXT: + case GL_RG16F_EXT: + return _mesa_has_EXT_texture_rg(ctx) && + _mesa_has_OES_texture_half_float(ctx); + } + } + /* check internal format - note that only sized formats are allowed */ switch (internalformat) { case GL_ALPHA: @@ -261,41 +313,6 @@ _mesa_is_legal_tex_storage_format(const struct gl_context *ctx, /** - * Default ctx->Driver.AllocTextureStorage() handler. - * - * The driver can override this with a more specific implementation if it - * desires, but this can be used to get the texture images allocated using the - * usual texture image handling code. The immutability of - * GL_ARB_texture_storage texture layouts is handled by texObj->Immutable - * checks at glTexImage* time. - */ -GLboolean -_mesa_AllocTextureStorage_sw(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth) -{ - const int numFaces = _mesa_num_tex_faces(texObj->Target); - int face; - int level; - - (void) width; - (void) height; - (void) depth; - - for (face = 0; face < numFaces; face++) { - for (level = 0; level < levels; level++) { - struct gl_texture_image *const texImage = texObj->Image[face][level]; - if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) - return GL_FALSE; - } - } - - return GL_TRUE; -} - - -/** * Do error checking for calls to glTexStorage1/2/3D(). * If an error is found, record it with _mesa_error(), unless the target * is a proxy texture. @@ -383,6 +400,84 @@ tex_storage_error_check(struct gl_context *ctx, return GL_FALSE; } +GLboolean +_mesa_sparse_texture_error_check(struct gl_context *ctx, GLuint dims, + struct gl_texture_object *texObj, + mesa_format format, GLenum target, GLsizei levels, + GLsizei width, GLsizei height, GLsizei depth, + const char *func) +{ + int px, py, pz; + int index = texObj->VirtualPageSizeIndex; + if (!st_GetSparseTextureVirtualPageSize(ctx, target, format, index, + &px, &py, &pz)) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse index = %d)", + func, index); + return GL_TRUE; + } + + if (target == GL_TEXTURE_3D) { + if (width > ctx->Const.MaxSparse3DTextureSize || + height > ctx->Const.MaxSparse3DTextureSize || + depth > ctx->Const.MaxSparse3DTextureSize) + goto exceed_max_size; + } else { + if (width > ctx->Const.MaxSparseTextureSize || + height > ctx->Const.MaxSparseTextureSize) + goto exceed_max_size; + + if (target == GL_TEXTURE_2D_ARRAY || + target == GL_TEXTURE_CUBE_MAP_ARRAY) { + if (depth > ctx->Const.MaxSparseArrayTextureLayers) + goto exceed_max_size; + } else if (target == GL_TEXTURE_1D_ARRAY) { + if (height > ctx->Const.MaxSparseArrayTextureLayers) + goto exceed_max_size; + } + } + + /* ARB_sparse_texture2 allow non-page-aligned base texture size. */ + if (!_mesa_has_ARB_sparse_texture2(ctx) && + (width % px || height % py || depth % pz)) { + _mesa_error(ctx, GL_INVALID_VALUE, "%s(sparse page size)", func); + return GL_TRUE; + } + + /* ARB_sparse_texture spec: + * + * If the value of SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE, + * then TexStorage* will generate an INVALID_OPERATION error if + * * the texture's TEXTURE_SPARSE_ARB parameter is TRUE, + * * <target> is one of TEXTURE_1D_ARRAY, TEXTURE_2D_ARRAY, + * TEXTURE_CUBE_MAP, or TEXTURE_CUBE_MAP_ARRAY, and + * * for the virtual page size corresponding to the + * VIRTUAL_PAGE_SIZE_INDEX_ARB parameter, either of the following is + * true: + * - <width> is not a multiple of VIRTUAL_PAGE_SIZE_X_ARB * + * 2^(<levels>-1), or + * - <height> is not a multiple of VIRTUAL_PAGE_SIZE_Y_ARB * + * 2^(<levels>-1). + * + * This make sure all allocated mipmap level size is multiple of virtual + * page size when SPARSE_TEXTURE_FULL_ARRAY_CUBE_MIPMAPS_ARB is FALSE. + */ + if (!ctx->Const.SparseTextureFullArrayCubeMipmaps && + (target == GL_TEXTURE_1D_ARRAY || + target == GL_TEXTURE_2D_ARRAY || + target == GL_TEXTURE_CUBE_MAP || + target == GL_TEXTURE_CUBE_MAP_ARRAY) && + (width % (px << (levels - 1)) || + height % (py << (levels - 1)))) { + _mesa_error(ctx, GL_INVALID_OPERATION, "%s(sparse array align)", func); + return GL_TRUE; + } + + return GL_FALSE; + +exceed_max_size: + _mesa_error(ctx, GL_INVALID_VALUE, "%s(exceed max sparse size)", func); + return GL_TRUE; +} /** * Helper that does the storage allocation for _mesa_TexStorage1/2/3D() @@ -394,7 +489,7 @@ texture_storage(struct gl_context *ctx, GLuint dims, struct gl_memory_object *memObj, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth, GLuint64 offset, bool dsa, - bool no_error) + bool no_error, const char *func) { GLboolean sizeOK = GL_TRUE, dimensionsOK = GL_TRUE; mesa_format texFormat; @@ -418,8 +513,8 @@ texture_storage(struct gl_context *ctx, GLuint dims, dimensionsOK = _mesa_legal_texture_dimensions(ctx, target, 0, width, height, depth, 0); - sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, levels, 0, texFormat, - 1, width, height, depth); + sizeOK = st_TestProxyTexImage(ctx, target, levels, 0, texFormat, + 1, width, height, depth); } if (_mesa_is_proxy_texture(target)) { @@ -447,6 +542,14 @@ texture_storage(struct gl_context *ctx, GLuint dims, suffix, dims); return; } + + if (texObj->IsSparse) { + char func[32]; + snprintf(func, 32, "glTex%sStorage%uD", suffix, dims); + if (_mesa_sparse_texture_error_check(ctx, dims, texObj, texFormat, target, + levels, width, height, depth, func)) + return; /* error was recorded */ + } } assert(levels > 0); @@ -461,18 +564,18 @@ texture_storage(struct gl_context *ctx, GLuint dims, /* Setup the backing memory */ if (memObj) { - if (!ctx->Driver.SetTextureStorageForMemoryObject(ctx, texObj, memObj, - levels, - width, height, depth, - offset)) { + if (!st_SetTextureStorageForMemoryObject(ctx, texObj, memObj, + levels, + width, height, depth, + offset, func)) { clear_texture_fields(ctx, texObj); return; } } else { - if (!ctx->Driver.AllocTextureStorage(ctx, texObj, levels, - width, height, depth)) { + if (!st_AllocTextureStorage(ctx, texObj, levels, + width, height, depth, func)) { /* Reset the texture images' info to zeros. * Strictly speaking, we probably don't have to do this since * generating GL_OUT_OF_MEMORY can leave things in an undefined @@ -497,10 +600,10 @@ texture_storage_error(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, bool dsa) + GLsizei height, GLsizei depth, bool dsa, const char *func) { texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat, - width, height, depth, dsa, 0, false); + width, height, depth, dsa, 0, false, func); } @@ -509,10 +612,10 @@ texture_storage_no_error(struct gl_context *ctx, GLuint dims, struct gl_texture_object *texObj, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth, bool dsa) + GLsizei height, GLsizei depth, bool dsa, const char *func) { texture_storage(ctx, dims, texObj, NULL, target, levels, internalformat, - width, height, depth, dsa, 0, true); + width, height, depth, dsa, 0, true, func); } @@ -530,7 +633,7 @@ texstorage_error(GLuint dims, GLenum target, GLsizei levels, /* Check target. This is done here so that texture_storage * can receive unsized formats. */ - if (!legal_texobj_target(ctx, dims, target)) { + if (!_mesa_is_legal_tex_storage_target(ctx, dims, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "%s(illegal target=%s)", caller, _mesa_enum_to_string(target)); @@ -556,20 +659,20 @@ texstorage_error(GLuint dims, GLenum target, GLsizei levels, return; texture_storage_error(ctx, dims, texObj, target, levels, - internalformat, width, height, depth, false); + internalformat, width, height, depth, false, caller); } static void texstorage_no_error(GLuint dims, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, - GLsizei depth) + GLsizei depth, const char *caller) { GET_CURRENT_CONTEXT(ctx); struct gl_texture_object *texObj = _mesa_get_current_tex_object(ctx, target); texture_storage_no_error(ctx, dims, texObj, target, levels, - internalformat, width, height, depth, false); + internalformat, width, height, depth, false, caller); } @@ -605,7 +708,7 @@ texturestorage_error(GLuint dims, GLuint texture, GLsizei levels, /* Check target. This is done here so that texture_storage * can receive unsized formats. */ - if (!legal_texobj_target(ctx, dims, texObj->Target)) { + if (!_mesa_is_legal_tex_storage_target(ctx, dims, texObj->Target)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(illegal target=%s)", caller, _mesa_enum_to_string(texObj->Target)); @@ -613,20 +716,20 @@ texturestorage_error(GLuint dims, GLuint texture, GLsizei levels, } texture_storage_error(ctx, dims, texObj, texObj->Target, - levels, internalformat, width, height, depth, true); + levels, internalformat, width, height, depth, true, caller); } static void texturestorage_no_error(GLuint dims, GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, - GLsizei depth) + GLsizei depth, const char *caller) { GET_CURRENT_CONTEXT(ctx); struct gl_texture_object *texObj = _mesa_lookup_texture(ctx, texture); texture_storage_no_error(ctx, dims, texObj, texObj->Target, - levels, internalformat, width, height, depth, true); + levels, internalformat, width, height, depth, true, caller); } @@ -634,7 +737,8 @@ void GLAPIENTRY _mesa_TexStorage1D_no_error(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width) { - texstorage_no_error(1, target, levels, internalformat, width, 1, 1); + texstorage_no_error(1, target, levels, internalformat, width, 1, 1, + "glTexStorage1D"); } @@ -652,7 +756,8 @@ _mesa_TexStorage2D_no_error(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - texstorage_no_error(2, target, levels, internalformat, width, height, 1); + texstorage_no_error(2, target, levels, internalformat, width, height, 1, + "glTexStorage2D"); } @@ -670,7 +775,8 @@ _mesa_TexStorage3D_no_error(GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) { - texstorage_no_error(3, target, levels, internalformat, width, height, depth); + texstorage_no_error(3, target, levels, internalformat, width, height, depth, + "glTexStorage3D"); } @@ -687,7 +793,8 @@ void GLAPIENTRY _mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width) { - texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1); + texturestorage_no_error(1, texture, levels, internalformat, width, 1, 1, + "glTextureStorage1D"); } @@ -705,7 +812,8 @@ _mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height) { - texturestorage_no_error(2, texture, levels, internalformat, width, height, 1); + texturestorage_no_error(2, texture, levels, internalformat, width, height, 1, + "glTextureStorage2D"); } @@ -725,7 +833,7 @@ _mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels, GLsizei height, GLsizei depth) { texturestorage_no_error(3, texture, levels, internalformat, width, height, - depth); + depth, "glTextureStorage3D"); } @@ -801,5 +909,5 @@ _mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims, assert(memObj); texture_storage(ctx, dims, texObj, memObj, target, levels, internalformat, - width, height, depth, offset, dsa, false); + width, height, depth, offset, dsa, false, ""); } diff --git a/src/mesa/main/texstorage.h b/src/mesa/main/texstorage.h index f184dfd86eb..f02c2d77bb6 100644 --- a/src/mesa/main/texstorage.h +++ b/src/mesa/main/texstorage.h @@ -54,88 +54,13 @@ _mesa_valid_tex_storage_dim(GLsizei width, GLsizei height, GLsizei depth) /*@}*/ -/** - * \name API functions - */ -/*@{*/ - -void GLAPIENTRY -_mesa_TexStorage1D_no_error(GLenum target, GLsizei levels, - GLenum internalformat, GLsizei width); - -extern void GLAPIENTRY -_mesa_TexStorage1D(GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width); - -void GLAPIENTRY -_mesa_TexStorage2D_no_error(GLenum target, GLsizei levels, - GLenum internalformat, GLsizei width, - GLsizei height); - -extern void GLAPIENTRY -_mesa_TexStorage2D(GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height); - -void GLAPIENTRY -_mesa_TexStorage3D_no_error(GLenum target, GLsizei levels, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth); - -extern void GLAPIENTRY -_mesa_TexStorage3D(GLenum target, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth); - -void GLAPIENTRY -_mesa_TextureStorage1D_no_error(GLuint texture, GLsizei levels, - GLenum internalformat, GLsizei width); - -extern void GLAPIENTRY -_mesa_TextureStorage1D(GLuint texture, GLsizei levels, GLenum internalformat, - GLsizei width); - -void GLAPIENTRY -_mesa_TextureStorage2D_no_error(GLuint texture, GLsizei levels, - GLenum internalformat, GLsizei width, - GLsizei height); - -extern void GLAPIENTRY -_mesa_TextureStorage2D(GLuint texture, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height); - -void GLAPIENTRY -_mesa_TextureStorage3D_no_error(GLuint texture, GLsizei levels, - GLenum internalformat, GLsizei width, - GLsizei height, GLsizei depth); - -extern void GLAPIENTRY -_mesa_TextureStorage3D(GLuint texture, GLsizei levels, GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth); - - -extern void GLAPIENTRY -_mesa_TextureStorage1DEXT(GLuint texture, GLenum target, GLsizei levels, - GLenum internalformat, - GLsizei width); - -extern void GLAPIENTRY -_mesa_TextureStorage2DEXT(GLuint texture, GLenum target, GLsizei levels, - GLenum internalformat, - GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_TextureStorage3DEXT(GLuint texture, GLenum target, GLsizei levels, - GLenum internalformat, - GLsizei width, GLsizei height, GLsizei depth); - extern GLboolean _mesa_is_legal_tex_storage_format(const struct gl_context *ctx, GLenum internalformat); -extern GLboolean -_mesa_AllocTextureStorage_sw(struct gl_context *ctx, - struct gl_texture_object *texObj, - GLsizei levels, GLsizei width, - GLsizei height, GLsizei depth); +extern bool +_mesa_is_legal_tex_storage_target(const struct gl_context *ctx, + GLuint dims, GLenum target); extern void _mesa_texture_storage_memory(struct gl_context *ctx, GLuint dims, diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index 8e0d8e951c2..d5b8dbf7e56 100755 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -37,7 +37,6 @@ * However, most device drivers will be able to use the fallback functions * in this file. That is, most drivers will have the following bit of * code: - * ctx->Driver.TexImage = _mesa_store_teximage; * ctx->Driver.TexSubImage = _mesa_store_texsubimage; * etc... * @@ -52,7 +51,7 @@ #include "errors.h" -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "format_pack.h" #include "format_utils.h" @@ -77,6 +76,7 @@ #include "util/format_rgb9e5.h" #include "util/format_r11g11b10f.h" +#include "state_tracker/st_cb_texture.h" enum { ZERO = 4, @@ -108,7 +108,7 @@ _mesa_memcpy_texture(struct gl_context *ctx, { const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType); - const GLint srcImageStride = _mesa_image_image_stride(srcPacking, + const intptr_t srcImageStride = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, srcType); const GLubyte *srcImage = (const GLubyte *) _mesa_image_address(dimensions, srcPacking, srcAddr, srcWidth, srcHeight, srcFormat, srcType, 0, 0, 0); @@ -344,6 +344,17 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) return GL_FALSE; } + /* + * The spec "8.5. TEXTURE IMAGE SPECIFICATION" says: + * + * If the base internal format is DEPTH_STENCIL and format is not DEPTH_STENCIL, + * then the values of the stencil index texture components are undefined. + * + * but there doesn't seem to be corresponding text saying that depth is + * undefined when a stencil format is supplied. + */ + const bool keepdepth = (srcFormat == GL_STENCIL_INDEX); + /* In case we only upload depth we need to preserve the stencil */ for (img = 0; img < srcDepth; img++) { GLuint *dstRow = (GLuint *) dstSlices[img]; @@ -354,24 +365,16 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) img, 0, 0); for (row = 0; row < srcHeight; row++) { GLint i; - GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; - - if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ - keepstencil = GL_TRUE; - } - else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ - keepdepth = GL_TRUE; - } - if (keepdepth == GL_FALSE) + if (!keepdepth) /* the 24 depth bits will be in the low position: */ _mesa_unpack_depth_span(ctx, srcWidth, GL_UNSIGNED_INT, /* dst type */ - keepstencil ? depth : dstRow, /* dst addr */ + depth, /* dst addr */ depthScale, srcType, src, srcPacking); - if (keepstencil == GL_FALSE) + if (srcFormat != GL_DEPTH_COMPONENT) /* get the 8-bit stencil values */ _mesa_unpack_stencil_span(ctx, srcWidth, GL_UNSIGNED_BYTE, /* dst type */ @@ -380,10 +383,10 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) ctx->_ImageTransferState); for (i = 0; i < srcWidth; i++) { - if (keepstencil) - dstRow[i] = depth[i] << 8 | (dstRow[i] & 0x000000FF); - else + if (keepdepth) dstRow[i] = (dstRow[i] & 0xFFFFFF00) | (stencil[i] & 0xFF); + else + dstRow[i] = depth[i] << 8 | (stencil[i] & 0xFF); } src += srcRowStride; dstRow += dstRowStride / sizeof(GLuint); @@ -426,6 +429,17 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) return GL_FALSE; } + /* + * The spec "8.5. TEXTURE IMAGE SPECIFICATION" says: + * + * If the base internal format is DEPTH_STENCIL and format is not DEPTH_STENCIL, + * then the values of the stencil index texture components are undefined. + * + * but there doesn't seem to be corresponding text saying that depth is + * undefined when a stencil format is supplied. + */ + const bool keepdepth = (srcFormat == GL_STENCIL_INDEX); + for (img = 0; img < srcDepth; img++) { GLuint *dstRow = (GLuint *) dstSlices[img]; const GLubyte *src @@ -433,26 +447,19 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) srcWidth, srcHeight, srcFormat, srcType, img, 0, 0); + for (row = 0; row < srcHeight; row++) { GLint i; - GLboolean keepdepth = GL_FALSE, keepstencil = GL_FALSE; - if (srcFormat == GL_DEPTH_COMPONENT) { /* preserve stencil */ - keepstencil = GL_TRUE; - } - else if (srcFormat == GL_STENCIL_INDEX) { /* preserve depth */ - keepdepth = GL_TRUE; - } - - if (keepdepth == GL_FALSE) + if (!keepdepth) /* the 24 depth bits will be in the low position: */ _mesa_unpack_depth_span(ctx, srcWidth, GL_UNSIGNED_INT, /* dst type */ - keepstencil ? depth : dstRow, /* dst addr */ + depth, /* dst addr */ depthScale, srcType, src, srcPacking); - if (keepstencil == GL_FALSE) + if (srcFormat != GL_DEPTH_COMPONENT) /* get the 8-bit stencil values */ _mesa_unpack_stencil_span(ctx, srcWidth, GL_UNSIGNED_BYTE, /* dst type */ @@ -462,12 +469,12 @@ _mesa_texstore_s8_z24(TEXSTORE_PARAMS) /* merge stencil values into depth values */ for (i = 0; i < srcWidth; i++) { - if (keepstencil) - dstRow[i] = depth[i] | (dstRow[i] & 0xFF000000); - else + if (keepdepth) dstRow[i] = (dstRow[i] & 0xFFFFFF) | (stencil[i] << 24); - + else + dstRow[i] = depth[i] | (stencil[i] << 24); } + src += srcRowStride; dstRow += dstRowStride / sizeof(GLuint); } @@ -721,7 +728,7 @@ texstore_rgba(TEXSTORE_PARAMS) */ GLint swapSize = _mesa_sizeof_packed_type(srcType); if (swapSize == 2 || swapSize == 4) { - int imageStride = _mesa_image_image_stride(srcPacking, srcWidth, + intptr_t imageStride = _mesa_image_image_stride(srcPacking, srcWidth, srcHeight, srcFormat, srcType); int bufferSize = imageStride * srcDepth; @@ -981,7 +988,7 @@ store_texsubimage(struct gl_context *ctx, const GLenum target = texImage->TexObject->Target; GLboolean success = GL_FALSE; GLuint dims, slice, numSlices = 1, sliceOffset = 0; - GLint srcImageStride = 0; + intptr_t srcImageStride = 0; const GLubyte *src; assert(xoffset + width <= texImage->Width); @@ -1066,10 +1073,10 @@ store_texsubimage(struct gl_context *ctx, GLubyte *dstMap; GLint dstRowStride; - ctx->Driver.MapTextureImage(ctx, texImage, - slice + sliceOffset, - xoffset, yoffset, width, height, - mapMode, &dstMap, &dstRowStride); + st_MapTextureImage(ctx, texImage, + slice + sliceOffset, + xoffset, yoffset, width, height, + mapMode, &dstMap, &dstRowStride); if (dstMap) { /* Note: we're only storing a 2D (or 1D) slice at a time but we need * to pass the right 'dims' value so that GL_UNPACK_SKIP_IMAGES is @@ -1082,7 +1089,7 @@ store_texsubimage(struct gl_context *ctx, width, height, 1, /* w, h, d */ format, type, src, packing); - ctx->Driver.UnmapTextureImage(ctx, texImage, slice + sliceOffset); + st_UnmapTextureImage(ctx, texImage, slice + sliceOffset); } src += srcImageStride; @@ -1097,37 +1104,6 @@ store_texsubimage(struct gl_context *ctx, _mesa_unmap_teximage_pbo(ctx, packing); } - - -/** - * Fallback code for ctx->Driver.TexImage(). - * Basically, allocate storage for the texture image, then copy the - * user's image into it. - */ -void -_mesa_store_teximage(struct gl_context *ctx, - GLuint dims, - struct gl_texture_image *texImage, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing) -{ - assert(dims == 1 || dims == 2 || dims == 3); - - if (texImage->Width == 0 || texImage->Height == 0 || texImage->Depth == 0) - return; - - /* allocate storage for texture data */ - if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage%uD", dims); - return; - } - - store_texsubimage(ctx, texImage, - 0, 0, 0, texImage->Width, texImage->Height, texImage->Depth, - format, type, pixels, packing, "glTexImage"); -} - - /* * Fallback for Driver.TexSubImage(). */ @@ -1192,11 +1168,11 @@ _mesa_store_cleartexsubimage(struct gl_context *ctx, clearValueSize = _mesa_get_format_bytes(texImage->TexFormat); for (z = 0; z < depth; z++) { - ctx->Driver.MapTextureImage(ctx, texImage, - z + zoffset, xoffset, yoffset, - width, height, - GL_MAP_WRITE_BIT, - &dstMap, &dstRowStride); + st_MapTextureImage(ctx, texImage, + z + zoffset, xoffset, yoffset, + width, height, + GL_MAP_WRITE_BIT, + &dstMap, &dstRowStride); if (dstMap == NULL) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glClearTex*Image"); return; @@ -1213,7 +1189,7 @@ _mesa_store_cleartexsubimage(struct gl_context *ctx, clearValueSize); } - ctx->Driver.UnmapTextureImage(ctx, texImage, z + zoffset); + st_UnmapTextureImage(ctx, texImage, z + zoffset); } } @@ -1241,16 +1217,16 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, assert(texImage->Depth > 0); /* allocate storage for texture data */ - if (!ctx->Driver.AllocTextureImageBuffer(ctx, texImage)) { + if (!st_AllocTextureImageBuffer(ctx, texImage)) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexImage%uD", dims); return; } - ctx->Driver.CompressedTexSubImage(ctx, dims, texImage, - 0, 0, 0, - texImage->Width, texImage->Height, texImage->Depth, - texImage->TexFormat, - imageSize, data); + st_CompressedTexSubImage(ctx, dims, texImage, + 0, 0, 0, + texImage->Width, texImage->Height, texImage->Depth, + texImage->TexFormat, + imageSize, data); } @@ -1356,10 +1332,10 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, for (slice = 0; slice < store.CopySlices; slice++) { /* Map dest texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset, - xoffset, yoffset, width, height, - GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, - &dstMap, &dstRowStride); + st_MapTextureImage(ctx, texImage, slice + zoffset, + xoffset, yoffset, width, height, + GL_MAP_WRITE_BIT | GL_MAP_INVALIDATE_RANGE_BIT, + &dstMap, &dstRowStride); if (dstMap) { @@ -1377,7 +1353,7 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, } } - ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset); + st_UnmapTextureImage(ctx, texImage, slice + zoffset); /* advance to next slice */ src += store.TotalBytesPerRow * (store.TotalRowsPerSlice diff --git a/src/mesa/main/texstore.h b/src/mesa/main/texstore.h index 9d735d16c70..889eb2a5442 100644 --- a/src/mesa/main/texstore.h +++ b/src/mesa/main/texstore.h @@ -36,7 +36,7 @@ #define TEXSTORE_H -#include "glheader.h" +#include "util/glheader.h" #include "formats.h" #include "util/macros.h" @@ -111,14 +111,6 @@ _mesa_texstore_can_use_memcpy(struct gl_context *ctx, extern void -_mesa_store_teximage(struct gl_context *ctx, - GLuint dims, - struct gl_texture_image *texImage, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing); - - -extern void _mesa_store_texsubimage(struct gl_context *ctx, GLuint dims, struct gl_texture_image *texImage, GLint xoffset, GLint yoffset, GLint zoffset, diff --git a/src/mesa/main/texturebindless.c b/src/mesa/main/texturebindless.c index 18f82c5d2ec..c8e30315173 100644 --- a/src/mesa/main/texturebindless.c +++ b/src/mesa/main/texturebindless.c @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" @@ -34,6 +34,12 @@ #include "util/hash_table.h" #include "util/u_memory.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_context.h" +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_texture.h" +#include "state_tracker/st_sampler_view.h" /** * Return the gl_texture_handle_object for a given 64-bit handle. @@ -77,7 +83,7 @@ delete_texture_handle(struct gl_context *ctx, GLuint64 id) _mesa_hash_table_u64_remove(ctx->Shared->TextureHandles, id); mtx_unlock(&ctx->Shared->HandlesMutex); - ctx->Driver.DeleteTextureHandle(ctx, id); + ctx->pipe->delete_texture_handle(ctx->pipe, id); } /** @@ -90,7 +96,7 @@ delete_image_handle(struct gl_context *ctx, GLuint64 id) _mesa_hash_table_u64_remove(ctx->Shared->ImageHandles, id); mtx_unlock(&ctx->Shared->HandlesMutex); - ctx->Driver.DeleteImageHandle(ctx, id); + ctx->pipe->delete_image_handle(ctx->pipe, id); } /** @@ -131,7 +137,7 @@ make_texture_handle_resident(struct gl_context *ctx, _mesa_hash_table_u64_insert(ctx->ResidentTextureHandles, handle, texHandleObj); - ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_TRUE); + ctx->pipe->make_texture_handle_resident(ctx->pipe, handle, GL_TRUE); /* Reference the texture object (and the separate sampler if needed) to * be sure it won't be deleted until it is not bound anywhere and there @@ -145,7 +151,7 @@ make_texture_handle_resident(struct gl_context *ctx, _mesa_hash_table_u64_remove(ctx->ResidentTextureHandles, handle); - ctx->Driver.MakeTextureHandleResident(ctx, handle, GL_FALSE); + ctx->pipe->make_texture_handle_resident(ctx->pipe, handle, GL_FALSE); /* Unreference the texture object but keep the pointer intact, if * refcount hits zero, the texture and all handles will be deleted. @@ -180,7 +186,7 @@ make_image_handle_resident(struct gl_context *ctx, _mesa_hash_table_u64_insert(ctx->ResidentImageHandles, handle, imgHandleObj); - ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_TRUE); + ctx->pipe->make_image_handle_resident(ctx->pipe, handle, access, GL_TRUE); /* Reference the texture object to be sure it won't be deleted until it * is not bound anywhere and there are no handles using the object that @@ -192,7 +198,7 @@ make_image_handle_resident(struct gl_context *ctx, _mesa_hash_table_u64_remove(ctx->ResidentImageHandles, handle); - ctx->Driver.MakeImageHandleResident(ctx, handle, access, GL_FALSE); + ctx->pipe->make_image_handle_resident(ctx->pipe, handle, access, GL_FALSE); /* Unreference the texture object but keep the pointer intact, if * refcount hits zero, the texture and all handles will be deleted. @@ -215,6 +221,32 @@ find_texhandleobj(struct gl_texture_object *texObj, } static GLuint64 +new_texture_handle(struct gl_context *ctx, struct gl_texture_object *texObj, + struct gl_sampler_object *sampObj) +{ + struct st_context *st = st_context(ctx); + struct pipe_context *pipe = ctx->pipe; + struct pipe_sampler_view *view; + struct pipe_sampler_state sampler = {0}; + + if (texObj->Target != GL_TEXTURE_BUFFER) { + if (!st_finalize_texture(ctx, pipe, texObj, 0)) + return 0; + + st_convert_sampler(st, texObj, sampObj, 0, &sampler, false, false, true); + + /* TODO: Clarify the interaction of ARB_bindless_texture and EXT_texture_sRGB_decode */ + view = st_get_texture_sampler_view_from_stobj(st, texObj, sampObj, 0, + true, false); + } else { + view = st_get_buffer_sampler_view_from_stobj(st, texObj, false); + sampler.unnormalized_coords = 0; + } + + return pipe->create_texture_handle(pipe, view, &sampler); +} + +static GLuint64 get_texture_handle(struct gl_context *ctx, struct gl_texture_object *texObj, struct gl_sampler_object *sampObj) { @@ -237,7 +269,7 @@ get_texture_handle(struct gl_context *ctx, struct gl_texture_object *texObj, } /* Request a new texture handle from the driver. */ - handle = ctx->Driver.NewTextureHandle(ctx, texObj, sampObj); + handle = new_texture_handle(ctx, texObj, sampObj); if (!handle) { mtx_unlock(&ctx->Shared->HandlesMutex); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetTexture*HandleARB()"); @@ -332,7 +364,9 @@ get_image_handle(struct gl_context *ctx, struct gl_texture_object *texObj, } /* Request a new image handle from the driver. */ - handle = ctx->Driver.NewImageHandle(ctx, &imgObj); + struct pipe_image_view image; + st_convert_image(st_context(ctx), &imgObj, &image, 0); + handle = ctx->pipe->create_image_handle(ctx->pipe, &image); if (!handle) { mtx_unlock(&ctx->Shared->HandlesMutex); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetImageHandleARB()"); @@ -390,7 +424,7 @@ _mesa_init_shared_handles(struct gl_shared_state *shared) { shared->TextureHandles = _mesa_hash_table_u64_create(NULL); shared->ImageHandles = _mesa_hash_table_u64_create(NULL); - mtx_init(&shared->HandlesMutex, mtx_recursive); + mtx_init(&shared->HandlesMutex, mtx_plain | mtx_recursive); } void @@ -454,7 +488,7 @@ _mesa_delete_texture_handles(struct gl_context *ctx, *texHandleObj); } delete_texture_handle(ctx, (*texHandleObj)->handle); - free(*texHandleObj); + FREE(*texHandleObj); } util_dynarray_fini(&texObj->SamplerHandles); @@ -462,7 +496,7 @@ _mesa_delete_texture_handles(struct gl_context *ctx, util_dynarray_foreach(&texObj->ImageHandles, struct gl_image_handle_object *, imgHandleObj) { delete_image_handle(ctx, (*imgHandleObj)->handle); - free(*imgHandleObj); + FREE(*imgHandleObj); } util_dynarray_fini(&texObj->ImageHandles); } @@ -490,7 +524,7 @@ _mesa_delete_sampler_handles(struct gl_context *ctx, *texHandleObj); delete_texture_handle(ctx, (*texHandleObj)->handle); - free(*texHandleObj); + FREE(*texHandleObj); } util_dynarray_fini(&sampObj->Handles); } @@ -510,7 +544,7 @@ is_sampler_border_color_valid(struct gl_sampler_object *samp) { 1, 1, 1, 0 }, { 1, 1, 1, 1 }, }; - size_t size = sizeof(samp->Attrib.BorderColor.ui); + size_t size = sizeof(samp->Attrib.state.border_color.ui); /* The ARB_bindless_texture spec says: * @@ -523,16 +557,16 @@ is_sampler_border_color_valid(struct gl_sampler_object *samp) * (0.0,0.0,0.0,0.0), (0.0,0.0,0.0,1.0), (1.0,1.0,1.0,0.0), and * (1.0,1.0,1.0,1.0)." */ - if (!memcmp(samp->Attrib.BorderColor.f, valid_float_border_colors[0], size) || - !memcmp(samp->Attrib.BorderColor.f, valid_float_border_colors[1], size) || - !memcmp(samp->Attrib.BorderColor.f, valid_float_border_colors[2], size) || - !memcmp(samp->Attrib.BorderColor.f, valid_float_border_colors[3], size)) + if (!memcmp(samp->Attrib.state.border_color.f, valid_float_border_colors[0], size) || + !memcmp(samp->Attrib.state.border_color.f, valid_float_border_colors[1], size) || + !memcmp(samp->Attrib.state.border_color.f, valid_float_border_colors[2], size) || + !memcmp(samp->Attrib.state.border_color.f, valid_float_border_colors[3], size)) return GL_TRUE; - if (!memcmp(samp->Attrib.BorderColor.ui, valid_integer_border_colors[0], size) || - !memcmp(samp->Attrib.BorderColor.ui, valid_integer_border_colors[1], size) || - !memcmp(samp->Attrib.BorderColor.ui, valid_integer_border_colors[2], size) || - !memcmp(samp->Attrib.BorderColor.ui, valid_integer_border_colors[3], size)) + if (!memcmp(samp->Attrib.state.border_color.ui, valid_integer_border_colors[0], size) || + !memcmp(samp->Attrib.state.border_color.ui, valid_integer_border_colors[1], size) || + !memcmp(samp->Attrib.state.border_color.ui, valid_integer_border_colors[2], size) || + !memcmp(samp->Attrib.state.border_color.ui, valid_integer_border_colors[3], size)) return GL_TRUE; return GL_FALSE; diff --git a/src/mesa/main/texturebindless.h b/src/mesa/main/texturebindless.h index ac97e95e81c..f045742755f 100644 --- a/src/mesa/main/texturebindless.h +++ b/src/mesa/main/texturebindless.h @@ -24,7 +24,7 @@ #ifndef TEXTUREBINDLESS_H #define TEXTUREBINDLESS_H -#include "glheader.h" +#include "util/glheader.h" #ifdef __cplusplus extern "C" { @@ -64,69 +64,6 @@ _mesa_delete_sampler_handles(struct gl_context *ctx, /*@}*/ -/** - * \name API functions - */ -/*@{*/ - -GLuint64 GLAPIENTRY -_mesa_GetTextureHandleARB_no_error(GLuint texture); - -GLuint64 GLAPIENTRY -_mesa_GetTextureHandleARB(GLuint texture); - -GLuint64 GLAPIENTRY -_mesa_GetTextureSamplerHandleARB_no_error(GLuint texture, GLuint sampler); - -GLuint64 GLAPIENTRY -_mesa_GetTextureSamplerHandleARB(GLuint texture, GLuint sampler); - -void GLAPIENTRY -_mesa_MakeTextureHandleResidentARB_no_error(GLuint64 handle); - -void GLAPIENTRY -_mesa_MakeTextureHandleResidentARB(GLuint64 handle); - -void GLAPIENTRY -_mesa_MakeTextureHandleNonResidentARB_no_error(GLuint64 handle); - -void GLAPIENTRY -_mesa_MakeTextureHandleNonResidentARB(GLuint64 handle); - -GLuint64 GLAPIENTRY -_mesa_GetImageHandleARB_no_error(GLuint texture, GLint level, GLboolean layered, - GLint layer, GLenum format); - -GLuint64 GLAPIENTRY -_mesa_GetImageHandleARB(GLuint texture, GLint level, GLboolean layered, - GLint layer, GLenum format); - -void GLAPIENTRY -_mesa_MakeImageHandleResidentARB_no_error(GLuint64 handle, GLenum access); - -void GLAPIENTRY -_mesa_MakeImageHandleResidentARB(GLuint64 handle, GLenum access); - -void GLAPIENTRY -_mesa_MakeImageHandleNonResidentARB_no_error(GLuint64 handle); - -void GLAPIENTRY -_mesa_MakeImageHandleNonResidentARB(GLuint64 handle); - -GLboolean GLAPIENTRY -_mesa_IsTextureHandleResidentARB_no_error(GLuint64 handle); - -GLboolean GLAPIENTRY -_mesa_IsTextureHandleResidentARB(GLuint64 handle); - -GLboolean GLAPIENTRY -_mesa_IsImageHandleResidentARB_no_error(GLuint64 handle); - -GLboolean GLAPIENTRY -_mesa_IsImageHandleResidentARB(GLuint64 handle); - -/*@}*/ - #ifdef __cplusplus } #endif diff --git a/src/mesa/main/textureview.c b/src/mesa/main/textureview.c index 48596487d22..e682346748d 100644 --- a/src/mesa/main/textureview.c +++ b/src/mesa/main/textureview.c @@ -31,7 +31,7 @@ * GL_ARB_texture_view functions */ -#include "glheader.h" +#include "util/glheader.h" #include "context.h" #include "enums.h" @@ -43,6 +43,9 @@ #include "textureview.h" #include "stdbool.h" #include "mtypes.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_texture.h" /* Table 3.X.2 (Compatible internal formats for TextureView) --------------------------------------------------------------------------- @@ -486,6 +489,7 @@ _mesa_set_texture_view_state(struct gl_context *ctx, */ texObj->Immutable = GL_TRUE; + texObj->External = GL_FALSE; texObj->Attrib.ImmutableLevels = levels; texObj->Attrib.MinLevel = 0; texObj->Attrib.NumLevels = levels; @@ -604,6 +608,22 @@ texture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj, } if (!no_error) { + /* OpenGL 4.6 (Core Profile) - May 14, 2018, 8.18 Texture Views, p.271 + * An INVALID_OPERATION error is generated if the computed values of + * TEXTURE_VIEW_NUM_LEVELS or TEXTURE_VIEW_NUM_LAYERS for texture, + * as described above, are less than or equal to zero. + */ + if (newViewNumLevels == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureView(invalid minlevels or numlevels)"); + return; + } + if (newViewNumLayers == 0) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "glTextureView(invalid minlayers or numlayers)"); + return; + } + /* If the dimensions of the original texture are larger than the maximum * supported dimensions of the new target, the error INVALID_OPERATION is * generated. For example, if the original texture has a TEXTURE_2D_ARRAY @@ -619,9 +639,9 @@ texture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj, return; } - sizeOK = ctx->Driver.TestProxyTexImage(ctx, target, 1, 0, texFormat, - origTexImage->NumSamples, - width, height, depth); + sizeOK = st_TestProxyTexImage(ctx, target, 1, 0, texFormat, + origTexImage->NumSamples, + width, height, depth); if (!sizeOK) { _mesa_error(ctx, GL_INVALID_OPERATION, "glTextureView(invalid texture size)"); @@ -692,13 +712,14 @@ texture_view(struct gl_context *ctx, struct gl_texture_object *origTexObj, texObj->Attrib.NumLevels = newViewNumLevels; texObj->Attrib.NumLayers = newViewNumLayers; texObj->Immutable = GL_TRUE; + texObj->External = GL_FALSE; texObj->Attrib.ImmutableLevels = origTexObj->Attrib.ImmutableLevels; texObj->Target = target; texObj->TargetIndex = _mesa_tex_target_to_index(ctx, target); assert(texObj->TargetIndex < NUM_TEXTURE_TARGETS); + _mesa_update_texture_object_swizzle(ctx, texObj); - if (ctx->Driver.TextureView != NULL && - !ctx->Driver.TextureView(ctx, texObj, origTexObj)) { + if (!st_TextureView(ctx, texObj, origTexObj)) { return; /* driver recorded error */ } } diff --git a/src/mesa/main/textureview.h b/src/mesa/main/textureview.h index e2f18aed017..6045d6b8d4c 100644 --- a/src/mesa/main/textureview.h +++ b/src/mesa/main/textureview.h @@ -42,18 +42,6 @@ GLenum _mesa_texture_view_lookup_view_class(const struct gl_context *ctx, GLenum internalformat); -void GLAPIENTRY -_mesa_TextureView_no_error(GLuint texture, GLenum target, GLuint origtexture, - GLenum internalformat, - GLuint minlevel, GLuint numlevels, - GLuint minlayer, GLuint numlayers); - -extern void GLAPIENTRY -_mesa_TextureView(GLuint texture, GLenum target, GLuint origtexture, - GLenum internalformat, - GLuint minlevel, GLuint numlevels, - GLuint minlayer, GLuint numlayers); - extern void _mesa_set_texture_view_state(struct gl_context *ctx, struct gl_texture_object *texObj, diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c index e24a388f623..73411146de3 100644 --- a/src/mesa/main/transformfeedback.c +++ b/src/mesa/main/transformfeedback.c @@ -45,7 +45,11 @@ #include "program/prog_parameter.h" #include "util/u_memory.h" +#include "util/u_inlines.h" +#include "api_exec_decl.h" + +#include "cso_cache/cso_context.h" struct using_program_tuple { struct gl_program *prog; @@ -75,7 +79,7 @@ _mesa_transform_feedback_is_using_program(struct gl_context *ctx, callback_data.found = false; callback_data.prog = shProg->last_vert_prog; - _mesa_HashWalkLocked(ctx->TransformFeedback.Objects, + _mesa_HashWalkLocked(&ctx->TransformFeedback.Objects, active_xfb_object_references_program, &callback_data); /* Also check DefaultObject, as it's not in the Objects hash table. */ @@ -85,6 +89,44 @@ _mesa_transform_feedback_is_using_program(struct gl_context *ctx, return callback_data.found; } +static struct gl_transform_feedback_object * +new_transform_feedback(struct gl_context *ctx, GLuint name) +{ + struct gl_transform_feedback_object *obj; + + obj = CALLOC_STRUCT(gl_transform_feedback_object); + if (!obj) + return NULL; + + obj->Name = name; + obj->RefCount = 1; + obj->EverBound = GL_FALSE; + + return obj; +} + +static void +delete_transform_feedback(struct gl_context *ctx, + struct gl_transform_feedback_object *obj) +{ + unsigned i; + + for (i = 0; i < ARRAY_SIZE(obj->draw_count); i++) + pipe_so_target_reference(&obj->draw_count[i], NULL); + + /* Unreference targets. */ + for (i = 0; i < obj->num_targets; i++) { + pipe_so_target_reference(&obj->targets[i], NULL); + } + + for (unsigned i = 0; i < ARRAY_SIZE(obj->Buffers); i++) { + _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL); + } + + free(obj->Label); + FREE(obj); +} + /** * Do reference counting of transform feedback buffers. */ @@ -105,7 +147,7 @@ reference_transform_feedback_object(struct gl_transform_feedback_object **ptr, if (oldObj->RefCount == 0) { GET_CURRENT_CONTEXT(ctx); if (ctx) - ctx->Driver.DeleteTransformFeedback(ctx, oldObj); + delete_transform_feedback(ctx, oldObj); } *ptr = NULL; @@ -130,10 +172,8 @@ void _mesa_init_transform_feedback(struct gl_context *ctx) { /* core mesa expects this, even a dummy one, to be available */ - assert(ctx->Driver.NewTransformFeedback); - ctx->TransformFeedback.DefaultObject = - ctx->Driver.NewTransformFeedback(ctx, 0); + new_transform_feedback(ctx, 0); assert(ctx->TransformFeedback.DefaultObject->RefCount == 1); @@ -142,7 +182,7 @@ _mesa_init_transform_feedback(struct gl_context *ctx) assert(ctx->TransformFeedback.DefaultObject->RefCount == 2); - ctx->TransformFeedback.Objects = _mesa_NewHashTable(); + _mesa_InitHashTable(&ctx->TransformFeedback.Objects); _mesa_reference_buffer_object(ctx, &ctx->TransformFeedback.CurrentBuffer, NULL); @@ -151,7 +191,7 @@ _mesa_init_transform_feedback(struct gl_context *ctx) /** - * Callback for _mesa_HashDeleteAll(). + * Callback for _mesa_DeleteHashTable(). */ static void delete_cb(void *data, void *userData) @@ -160,7 +200,7 @@ delete_cb(void *data, void *userData) struct gl_transform_feedback_object *obj = (struct gl_transform_feedback_object *) data; - ctx->Driver.DeleteTransformFeedback(ctx, obj); + delete_transform_feedback(ctx, obj); } @@ -171,120 +211,20 @@ void _mesa_free_transform_feedback(struct gl_context *ctx) { /* core mesa expects this, even a dummy one, to be available */ - assert(ctx->Driver.NewTransformFeedback); - _mesa_reference_buffer_object(ctx, &ctx->TransformFeedback.CurrentBuffer, NULL); /* Delete all feedback objects */ - _mesa_HashDeleteAll(ctx->TransformFeedback.Objects, delete_cb, ctx); - _mesa_DeleteHashTable(ctx->TransformFeedback.Objects); + _mesa_DeinitHashTable(&ctx->TransformFeedback.Objects, delete_cb, ctx); /* Delete the default feedback object */ - assert(ctx->Driver.DeleteTransformFeedback); - ctx->Driver.DeleteTransformFeedback(ctx, - ctx->TransformFeedback.DefaultObject); + delete_transform_feedback(ctx, + ctx->TransformFeedback.DefaultObject); ctx->TransformFeedback.CurrentObject = NULL; } - -/** Initialize the fields of a gl_transform_feedback_object. */ -void -_mesa_init_transform_feedback_object(struct gl_transform_feedback_object *obj, - GLuint name) -{ - obj->Name = name; - obj->RefCount = 1; - obj->EverBound = GL_FALSE; -} - -/** - * Delete a transform feedback object. Called via - * ctx->Driver->DeleteTransformFeedback, if not overwritten by driver. In - * the latter case, called from the driver after all driver-specific clean-up - * has been done. - * - * \param ctx GL context to wich transform feedback object belongs. - * \param obj Transform feedback object due to be deleted. - */ -void -_mesa_delete_transform_feedback_object(struct gl_context *ctx, - struct gl_transform_feedback_object - *obj) -{ - for (unsigned i = 0; i < ARRAY_SIZE(obj->Buffers); i++) { - _mesa_reference_buffer_object(ctx, &obj->Buffers[i], NULL); - } - - free(obj->Label); - free(obj); -} - -/** Default fallback for ctx->Driver.NewTransformFeedback() */ -static struct gl_transform_feedback_object * -new_transform_feedback_fallback(struct gl_context *ctx, GLuint name) -{ - struct gl_transform_feedback_object *obj; - - obj = CALLOC_STRUCT(gl_transform_feedback_object); - if (!obj) - return NULL; - - _mesa_init_transform_feedback_object(obj, name); - return obj; -} - -/** Default fallback for ctx->Driver.BeginTransformFeedback() */ -static void -begin_transform_feedback_fallback(struct gl_context *ctx, GLenum mode, - struct gl_transform_feedback_object *obj) -{ - /* nop */ -} - -/** Default fallback for ctx->Driver.EndTransformFeedback() */ -static void -end_transform_feedback_fallback(struct gl_context *ctx, - struct gl_transform_feedback_object *obj) -{ - /* nop */ -} - -/** Default fallback for ctx->Driver.PauseTransformFeedback() */ -static void -pause_transform_feedback_fallback(struct gl_context *ctx, - struct gl_transform_feedback_object *obj) -{ - /* nop */ -} - -/** Default fallback for ctx->Driver.ResumeTransformFeedback() */ -static void -resume_transform_feedback_fallback(struct gl_context *ctx, - struct gl_transform_feedback_object *obj) -{ - /* nop */ -} - - -/** - * Plug in default device driver functions for transform feedback. - * Most drivers will override some/all of these. - */ -void -_mesa_init_transform_feedback_functions(struct dd_function_table *driver) -{ - driver->NewTransformFeedback = new_transform_feedback_fallback; - driver->DeleteTransformFeedback = _mesa_delete_transform_feedback_object; - driver->BeginTransformFeedback = begin_transform_feedback_fallback; - driver->EndTransformFeedback = end_transform_feedback_fallback; - driver->PauseTransformFeedback = pause_transform_feedback_fallback; - driver->ResumeTransformFeedback = resume_transform_feedback_fallback; -} - - /** * Fill in the correct Size value for each buffer in \c obj. * @@ -457,7 +397,6 @@ begin_transform_feedback(struct gl_context *ctx, GLenum mode, bool no_error) } FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback; obj->Active = GL_TRUE; ctx->TransformFeedback.Mode = mode; @@ -477,13 +416,50 @@ begin_transform_feedback(struct gl_context *ctx, GLenum mode, bool no_error) } if (obj->program != source) { - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedbackProg; _mesa_reference_program_(ctx, &obj->program, source); obj->program = source; } - assert(ctx->Driver.BeginTransformFeedback); - ctx->Driver.BeginTransformFeedback(ctx, mode, obj); + struct pipe_context *pipe = ctx->pipe; + unsigned max_num_targets; + unsigned offsets[PIPE_MAX_SO_BUFFERS] = {0}; + + max_num_targets = MIN2(ARRAY_SIZE(obj->Buffers), + ARRAY_SIZE(obj->targets)); + + /* Convert the transform feedback state into the gallium representation. */ + for (i = 0; i < max_num_targets; i++) { + struct gl_buffer_object *bo = obj->Buffers[i]; + + if (bo && bo->buffer) { + unsigned stream = obj->program->sh.LinkedTransformFeedback-> + Buffers[i].Stream; + + /* Check whether we need to recreate the target. */ + if (!obj->targets[i] || + obj->targets[i] == obj->draw_count[stream] || + obj->targets[i]->buffer != bo->buffer || + obj->targets[i]->buffer_offset != obj->Offset[i] || + obj->targets[i]->buffer_size != obj->Size[i]) { + /* Create a new target. */ + struct pipe_stream_output_target *so_target = + pipe->create_stream_output_target(pipe, bo->buffer, + obj->Offset[i], + obj->Size[i]); + + pipe_so_target_reference(&obj->targets[i], NULL); + obj->targets[i] = so_target; + } + + obj->num_targets = i+1; + } else { + pipe_so_target_reference(&obj->targets[i], NULL); + } + } + + /* Start writing at the beginning of each target. */ + cso_set_stream_outputs(ctx->cso_context, obj->num_targets, + obj->targets, offsets); _mesa_update_valid_to_render_state(ctx); } @@ -508,11 +484,30 @@ static void end_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj) { + unsigned i; FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback; - assert(ctx->Driver.EndTransformFeedback); - ctx->Driver.EndTransformFeedback(ctx, obj); + cso_set_stream_outputs(ctx->cso_context, 0, NULL, NULL); + + /* The next call to glDrawTransformFeedbackStream should use the vertex + * count from the last call to glEndTransformFeedback. + * Therefore, save the targets for each stream. + * + * NULL means the vertex counter is 0 (initial state). + */ + for (i = 0; i < ARRAY_SIZE(obj->draw_count); i++) + pipe_so_target_reference(&obj->draw_count[i], NULL); + + for (i = 0; i < ARRAY_SIZE(obj->targets); i++) { + unsigned stream = obj->program->sh.LinkedTransformFeedback-> + Buffers[i].Stream; + + /* Is it not bound or already set for this stream? */ + if (!obj->targets[i] || obj->draw_count[stream]) + continue; + + pipe_so_target_reference(&obj->draw_count[stream], obj->targets[i]); + } _mesa_reference_program_(ctx, &obj->program, NULL); ctx->TransformFeedback.CurrentObject->Active = GL_FALSE; @@ -559,7 +554,7 @@ bind_buffer_range(struct gl_context *ctx, GLintptr offset, GLsizeiptr size, bool dsa) { - /* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because + /* Note: no need to FLUSH_VERTICES because * transform feedback buffers can't be changed while transform feedback is * active. */ @@ -899,7 +894,7 @@ transform_feedback_varyings(struct gl_context *ctx, shProg->TransformFeedback.BufferMode = bufferMode; - /* No need to invoke FLUSH_VERTICES or flag NewTransformFeedback since + /* No need to invoke FLUSH_VERTICES since * the varyings won't be used until shader link time. */ } @@ -1050,7 +1045,7 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name) } else return (struct gl_transform_feedback_object *) - _mesa_HashLookupLocked(ctx->TransformFeedback.Objects, name); + _mesa_HashLookupLocked(&ctx->TransformFeedback.Objects, name); } static void @@ -1072,17 +1067,16 @@ create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids, if (!ids) return; - if (_mesa_HashFindFreeKeys(ctx->TransformFeedback.Objects, ids, n)) { + if (_mesa_HashFindFreeKeys(&ctx->TransformFeedback.Objects, ids, n)) { GLsizei i; for (i = 0; i < n; i++) { struct gl_transform_feedback_object *obj - = ctx->Driver.NewTransformFeedback(ctx, ids[i]); + = new_transform_feedback(ctx, ids[i]); if (!obj) { _mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func); return; } - _mesa_HashInsertLocked(ctx->TransformFeedback.Objects, ids[i], - obj, true); + _mesa_HashInsertLocked(&ctx->TransformFeedback.Objects, ids[i], obj); if (dsa) { /* this is normally done at bind time in the non-dsa case */ obj->EverBound = GL_TRUE; @@ -1230,7 +1224,7 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names) names[i]); return; } - _mesa_HashRemoveLocked(ctx->TransformFeedback.Objects, names[i]); + _mesa_HashRemoveLocked(&ctx->TransformFeedback.Objects, names[i]); /* unref, but object may not be deleted until later */ if (obj == ctx->TransformFeedback.CurrentObject) { reference_transform_feedback_object( @@ -1253,10 +1247,8 @@ pause_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj) { FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback; - assert(ctx->Driver.PauseTransformFeedback); - ctx->Driver.PauseTransformFeedback(ctx, obj); + cso_set_stream_outputs(ctx->cso_context, 0, NULL, NULL); obj->Paused = GL_TRUE; _mesa_update_valid_to_render_state(ctx); @@ -1298,12 +1290,17 @@ resume_transform_feedback(struct gl_context *ctx, struct gl_transform_feedback_object *obj) { FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewTransformFeedback; obj->Paused = GL_FALSE; - assert(ctx->Driver.ResumeTransformFeedback); - ctx->Driver.ResumeTransformFeedback(ctx, obj); + unsigned offsets[PIPE_MAX_SO_BUFFERS]; + unsigned i; + + for (i = 0; i < PIPE_MAX_SO_BUFFERS; i++) + offsets[i] = (unsigned)-1; + + cso_set_stream_outputs(ctx->cso_context, obj->num_targets, + obj->targets, offsets); _mesa_update_valid_to_render_state(ctx); } diff --git a/src/mesa/main/transformfeedback.h b/src/mesa/main/transformfeedback.h index c699fcb94f3..f299c80676c 100644 --- a/src/mesa/main/transformfeedback.h +++ b/src/mesa/main/transformfeedback.h @@ -29,7 +29,7 @@ #include <stdbool.h> #include "bufferobj.h" #include "util/compiler.h" -#include "glheader.h" +#include "util/glheader.h" #include "mtypes.h" struct _glapi_table; @@ -42,9 +42,6 @@ _mesa_init_transform_feedback(struct gl_context *ctx); extern void _mesa_free_transform_feedback(struct gl_context *ctx); -extern void -_mesa_init_transform_feedback_functions(struct dd_function_table *driver); - extern unsigned _mesa_compute_max_transform_feedback_vertices( struct gl_context *ctx, const struct gl_transform_feedback_object *obj, @@ -53,18 +50,6 @@ _mesa_compute_max_transform_feedback_vertices( struct gl_context *ctx, /*** GL_EXT_transform_feedback ***/ -void GLAPIENTRY -_mesa_BeginTransformFeedback_no_error(GLenum mode); - -extern void GLAPIENTRY -_mesa_BeginTransformFeedback(GLenum mode); - -void GLAPIENTRY -_mesa_EndTransformFeedback_no_error(void); - -extern void GLAPIENTRY -_mesa_EndTransformFeedback(void); - extern bool _mesa_validate_buffer_range_xfb(struct gl_context *ctx, struct gl_transform_feedback_object *obj, @@ -78,31 +63,6 @@ _mesa_bind_buffer_base_transform_feedback(struct gl_context *ctx, struct gl_buffer_object *bufObj, bool dsa); -void GLAPIENTRY -_mesa_BindBufferOffsetEXT_no_error(GLenum target, GLuint index, GLuint buffer, - GLintptr offset); - -extern void GLAPIENTRY -_mesa_BindBufferOffsetEXT(GLenum target, GLuint index, GLuint buffer, - GLintptr offset); - -void GLAPIENTRY -_mesa_TransformFeedbackVaryings_no_error(GLuint program, GLsizei count, - const GLchar *const *varyings, - GLenum bufferMode); - -extern void GLAPIENTRY -_mesa_TransformFeedbackVaryings(GLuint program, GLsizei count, - const GLchar * const *varyings, - GLenum bufferMode); - -extern void GLAPIENTRY -_mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, - GLsizei bufSize, GLsizei *length, - GLsizei *size, GLenum *type, GLchar *name); - - - /*** GL_ARB_transform_feedback2 ***/ extern void _mesa_init_transform_feedback_object(struct gl_transform_feedback_object *obj, @@ -116,36 +76,6 @@ _mesa_delete_transform_feedback_object(struct gl_context *ctx, struct gl_transform_feedback_object * _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name); -extern void GLAPIENTRY -_mesa_GenTransformFeedbacks(GLsizei n, GLuint *names); - -extern void GLAPIENTRY -_mesa_CreateTransformFeedbacks(GLsizei n, GLuint *names); - -extern GLboolean GLAPIENTRY -_mesa_IsTransformFeedback(GLuint name); - -void GLAPIENTRY -_mesa_BindTransformFeedback_no_error(GLenum target, GLuint name); - -extern void GLAPIENTRY -_mesa_BindTransformFeedback(GLenum target, GLuint name); - -extern void GLAPIENTRY -_mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names); - -void GLAPIENTRY -_mesa_PauseTransformFeedback_no_error(void); - -extern void GLAPIENTRY -_mesa_PauseTransformFeedback(void); - -void GLAPIENTRY -_mesa_ResumeTransformFeedback_no_error(void); - -extern void GLAPIENTRY -_mesa_ResumeTransformFeedback(void); - static inline bool _mesa_is_xfb_active_and_unpaused(const struct gl_context *ctx) { @@ -179,7 +109,7 @@ _mesa_bind_buffer_range_xfb(struct gl_context *ctx, GLuint index, struct gl_buffer_object *bufObj, GLintptr offset, GLsizeiptr size) { - /* Note: no need to FLUSH_VERTICES or flag NewTransformFeedback, because + /* Note: no need to FLUSH_VERTICES because * transform feedback buffers can't be changed while transform feedback is * active. */ @@ -193,24 +123,4 @@ _mesa_bind_buffer_range_xfb(struct gl_context *ctx, _mesa_set_transform_feedback_binding(ctx, obj, index, bufObj, offset, size); } -/*** GL_ARB_direct_state_access ***/ - -extern void GLAPIENTRY -_mesa_TransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer); - -extern void GLAPIENTRY -_mesa_TransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, - GLintptr offset, GLsizeiptr size); - -extern void GLAPIENTRY -_mesa_GetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param); - -extern void GLAPIENTRY -_mesa_GetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, - GLint *param); - -extern void GLAPIENTRY -_mesa_GetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, - GLint64 *param); - #endif /* TRANSFORM_FEEDBACK_H */ diff --git a/src/mesa/main/uniform_query.cpp b/src/mesa/main/uniform_query.cpp index b5b5f1a6ec4..193833bdf2a 100644 --- a/src/mesa/main/uniform_query.cpp +++ b/src/mesa/main/uniform_query.cpp @@ -39,6 +39,7 @@ #include "compiler/glsl/program.h" #include "util/bitscan.h" +#include "state_tracker/st_context.h" /* This is one of the few glGet that can be called from the app thread safely. * Only these conditions must be met: @@ -271,7 +272,7 @@ validate_uniform_parameters(GLint location, GLsizei count, if (count > 1) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(count = %u for non-array \"%s\"@%d)", - caller, count, uni->name, location); + caller, count, uni->name.string, location); return NULL; } @@ -344,13 +345,13 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, } { - unsigned elements = uni->type->components(); + unsigned elements = glsl_get_components(uni->type); unsigned components = uni->type->vector_elements; const int rmul = glsl_base_type_is_64bit(returnType) ? 2 : 1; - int dmul = (uni->type->is_64bit()) ? 2 : 1; + int dmul = (glsl_type_is_64bit(uni->type)) ? 2 : 1; - if ((uni->type->is_sampler() || uni->type->is_image()) && + if ((glsl_type_is_sampler(uni->type) || glsl_type_is_image(uni->type)) && !uni->is_bindless) { /* Non-bindless samplers/images are represented using unsigned integer * 32-bit, while bindless handles are 64-bit. @@ -363,7 +364,7 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, */ const union gl_constant_value *src; if (ctx->Const.PackedDriverUniformStorage && - (uni->is_bindless || !uni->type->contains_opaque())) { + (uni->is_bindless || !glsl_contains_opaque(uni->type))) { unsigned dword_elements = elements; /* 16-bit uniforms are packed. */ @@ -397,7 +398,7 @@ _mesa_get_uniform(struct gl_context *ctx, GLuint program, GLint location, */ if (returnType == uni->type->base_type || ((returnType == GLSL_TYPE_INT || returnType == GLSL_TYPE_UINT) && - (uni->type->is_sampler() || uni->type->is_image())) || + (glsl_type_is_sampler(uni->type) || glsl_type_is_image(uni->type))) || (returnType == GLSL_TYPE_UINT64 && uni->is_bindless)) { memcpy(paramsOut, src, bytes); } else { @@ -741,7 +742,7 @@ log_uniform(const void *values, enum glsl_base_type basicType, printf("Mesa: set program %u %s \"%s\" (loc %d, type \"%s\", " "transpose = %s) to: ", - shProg->Name, extra, uni->name, location, uni->type->name, + shProg->Name, extra, uni->name.string, location, glsl_get_type_name(uni->type), transpose ? "true" : "false"); for (unsigned i = 0; i < elems; i++) { if (i != 0 && ((i % rows) == 0)) @@ -835,7 +836,7 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, const unsigned components = uni->type->vector_elements; const unsigned vectors = uni->type->matrix_columns; - const int dmul = uni->type->is_64bit() ? 2 : 1; + const int dmul = glsl_type_is_64bit(uni->type) ? 2 : 1; /* Store the data in the driver's requested type in the driver's storage * areas. @@ -922,6 +923,177 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, } +static void +associate_uniform_storage(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_program *prog) +{ + struct gl_program_parameter_list *params = prog->Parameters; + gl_shader_stage shader_type = prog->info.stage; + + _mesa_disallow_parameter_storage_realloc(params); + + /* After adding each uniform to the parameter list, connect the storage for + * the parameter with the tracking structure used by the API for the + * uniform. + */ + unsigned last_location = unsigned(~0); + for (unsigned i = 0; i < params->NumParameters; i++) { + if (params->Parameters[i].Type != PROGRAM_UNIFORM) + continue; + + unsigned location = params->Parameters[i].UniformStorageIndex; + + struct gl_uniform_storage *storage = + &shader_program->data->UniformStorage[location]; + + /* Do not associate any uniform storage to built-in uniforms */ + if (storage->builtin) + continue; + + if (location != last_location) { + enum gl_uniform_driver_format format = uniform_native; + unsigned columns = 0; + + int dmul; + if (ctx->Const.PackedDriverUniformStorage && !prog->info.use_legacy_math_rules) { + dmul = storage->type->vector_elements * sizeof(float); + } else { + dmul = 4 * sizeof(float); + } + + switch (storage->type->base_type) { + case GLSL_TYPE_UINT64: + if (storage->type->vector_elements > 2) + dmul *= 2; + FALLTHROUGH; + case GLSL_TYPE_UINT: + case GLSL_TYPE_UINT16: + case GLSL_TYPE_UINT8: + assert(ctx->Const.NativeIntegers); + format = uniform_native; + columns = 1; + break; + case GLSL_TYPE_INT64: + if (storage->type->vector_elements > 2) + dmul *= 2; + FALLTHROUGH; + case GLSL_TYPE_INT: + case GLSL_TYPE_INT16: + case GLSL_TYPE_INT8: + format = + (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float; + columns = 1; + break; + case GLSL_TYPE_DOUBLE: + if (storage->type->vector_elements > 2) + dmul *= 2; + FALLTHROUGH; + case GLSL_TYPE_FLOAT: + case GLSL_TYPE_FLOAT16: + format = uniform_native; + columns = storage->type->matrix_columns; + break; + case GLSL_TYPE_BOOL: + format = uniform_native; + columns = 1; + break; + case GLSL_TYPE_SAMPLER: + case GLSL_TYPE_TEXTURE: + case GLSL_TYPE_IMAGE: + case GLSL_TYPE_SUBROUTINE: + format = uniform_native; + columns = 1; + break; + case GLSL_TYPE_ATOMIC_UINT: + case GLSL_TYPE_ARRAY: + case GLSL_TYPE_VOID: + case GLSL_TYPE_STRUCT: + case GLSL_TYPE_ERROR: + case GLSL_TYPE_INTERFACE: + case GLSL_TYPE_COOPERATIVE_MATRIX: + assert(!"Should not get here."); + break; + } + + unsigned pvo = params->Parameters[i].ValueOffset; + _mesa_uniform_attach_driver_storage(storage, dmul * columns, dmul, + format, + ¶ms->ParameterValues[pvo]); + + /* When a bindless sampler/image is bound to a texture/image unit, we + * have to overwrite the constant value by the resident handle + * directly in the constant buffer before the next draw. One solution + * is to keep track a pointer to the base of the data. + */ + if (storage->is_bindless && (prog->sh.NumBindlessSamplers || + prog->sh.NumBindlessImages)) { + unsigned array_elements = MAX2(1, storage->array_elements); + + for (unsigned j = 0; j < array_elements; ++j) { + unsigned unit = storage->opaque[shader_type].index + j; + + if (glsl_type_is_sampler(glsl_without_array(storage->type))) { + assert(unit >= 0 && unit < prog->sh.NumBindlessSamplers); + prog->sh.BindlessSamplers[unit].data = + ¶ms->ParameterValues[pvo] + 4 * j; + } else if (glsl_type_is_image(glsl_without_array(storage->type))) { + assert(unit >= 0 && unit < prog->sh.NumBindlessImages); + prog->sh.BindlessImages[unit].data = + ¶ms->ParameterValues[pvo] + 4 * j; + } + } + } + + /* After attaching the driver's storage to the uniform, propagate any + * data from the linker's backing store. This will cause values from + * initializers in the source code to be copied over. + */ + unsigned array_elements = MAX2(1, storage->array_elements); + if (ctx->Const.PackedDriverUniformStorage && !prog->info.use_legacy_math_rules && + (storage->is_bindless || !glsl_contains_opaque(storage->type))) { + const int dmul = glsl_type_is_64bit(storage->type) ? 2 : 1; + const unsigned components = + storage->type->vector_elements * + storage->type->matrix_columns; + + for (unsigned s = 0; s < storage->num_driver_storage; s++) { + gl_constant_value *uni_storage = (gl_constant_value *) + storage->driver_storage[s].data; + memcpy(uni_storage, storage->storage, + sizeof(storage->storage[0]) * components * + array_elements * dmul); + } + } else { + _mesa_propagate_uniforms_to_driver_storage(storage, 0, + array_elements); + } + + last_location = location; + } + } +} + + +void +_mesa_ensure_and_associate_uniform_storage(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_program *prog, unsigned required_space) +{ + /* Avoid reallocation of the program parameter list, because the uniform + * storage is only associated with the original parameter list. + */ + _mesa_reserve_parameter_storage(prog->Parameters, required_space, + required_space); + + /* This has to be done last. Any operation the can cause + * prog->ParameterValues to get reallocated (e.g., anything that adds a + * program constant) has to happen before creating this linkage. + */ + associate_uniform_storage(ctx, shader_program, prog); +} + + /** * Return printable string for a given GLSL_TYPE_x */ @@ -977,11 +1149,11 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values, if (uni == NULL) return NULL; - if (uni->type->is_matrix()) { + if (glsl_type_is_matrix(uni->type)) { /* Can't set matrix uniforms (like mat4) with glUniform */ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform%u(uniform \"%s\"@%d is matrix)", - src_components, uni->name, location); + src_components, uni->name.string, location); return NULL; } @@ -992,7 +1164,7 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values, /* glUniformN() must match float/vecN type */ _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform%u(\"%s\"@%u has %u components, not %u)", - src_components, uni->name, location, + src_components, uni->name.string, location, components, src_components); return NULL; } @@ -1019,7 +1191,7 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values, if (!match) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform%u(\"%s\"@%d is %s, not %s)", - src_components, uni->name, location, + src_components, uni->name.string, location, glsl_type_name(uni->type->base_type), glsl_type_name(basicType)); return NULL; @@ -1047,7 +1219,7 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values, * Based on that, when an invalid sampler is specified, we generate a * GL_INVALID_VALUE error and ignore the command. */ - if (uni->type->is_sampler()) { + if (glsl_type_is_sampler(uni->type)) { for (int i = 0; i < count; i++) { const unsigned texUnit = ((unsigned *) values)[i]; @@ -1065,7 +1237,7 @@ validate_uniform(GLint location, GLsizei count, const GLvoid *values, ctx->_Shader->Validated = ctx->_Shader->UserValidated = GL_FALSE; } - if (uni->type->is_image()) { + if (glsl_type_is_image(uni->type)) { for (int i = 0; i < count; i++) { const int unit = ((GLint *) values)[i]; @@ -1087,9 +1259,9 @@ _mesa_flush_vertices_for_uniforms(struct gl_context *ctx, const struct gl_uniform_storage *uni) { /* Opaque uniforms have no storage unless they are bindless */ - if (!uni->is_bindless && uni->type->contains_opaque()) { + if (!uni->is_bindless && glsl_contains_opaque(uni->type)) { /* Samplers flush on demand and ignore redundant updates. */ - if (!uni->type->is_sampler()) + if (!glsl_type_is_sampler(uni->type)) FLUSH_VERTICES(ctx, 0, 0); return; } @@ -1118,10 +1290,10 @@ copy_uniforms_to_storage(gl_constant_value *storage, { const gl_constant_value *src = (const gl_constant_value*)values; bool copy_as_uint64 = uni->is_bindless && - (uni->type->is_sampler() || uni->type->is_image()); + (glsl_type_is_sampler(uni->type) || glsl_type_is_image(uni->type)); bool copy_to_float16 = uni->type->base_type == GLSL_TYPE_FLOAT16; - if (!uni->type->is_boolean() && !copy_as_uint64 && !copy_to_float16) { + if (!glsl_type_is_boolean(uni->type) && !copy_as_uint64 && !copy_to_float16) { unsigned size = sizeof(storage[0]) * components * count * size_mul; if (!memcmp(storage, values, size)) @@ -1280,7 +1452,7 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, return; uni = shProg->UniformRemapTable[location]; - if (!uni) + if (!uni || uni == INACTIVE_UNIFORM_EXPLICIT_LOCATION) return; /* The array index specified by the uniform location is just the @@ -1317,7 +1489,7 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, bool ctx_flushed = false; gl_constant_value *storage; if (ctx->Const.PackedDriverUniformStorage && - (uni->is_bindless || !uni->type->contains_opaque())) { + (uni->is_bindless || !glsl_contains_opaque(uni->type))) { for (unsigned s = 0; s < uni->num_driver_storage; s++) { unsigned dword_components = components; @@ -1340,18 +1512,22 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, ctx_flushed = true; } } - if (!ctx_flushed) + /* Return early if possible. Bindless samplers need to be processed + * because of the !sampler->bound codepath below. + */ + if (!ctx_flushed && !(glsl_type_is_sampler(uni->type) && uni->is_bindless)) return; /* no change in uniform values */ /* If the uniform is a sampler, do the extra magic necessary to propagate * the changes through. */ - if (uni->type->is_sampler()) { + if (glsl_type_is_sampler(uni->type)) { /* Note that samplers are the only uniforms that don't call * FLUSH_VERTICES above. */ bool flushed = false; bool any_changed = false; + bool samplers_validated = shProg->SamplersValidated; shProg->SamplersValidated = GL_TRUE; @@ -1375,7 +1551,7 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, */ if (sampler->unit != value || !sampler->bound) { if (!flushed) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM, 0); + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, 0); flushed = true; } sampler->unit = value; @@ -1386,7 +1562,7 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, } else { if (sh->Program->SamplerUnits[unit] != value) { if (!flushed) { - FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT | _NEW_PROGRAM, 0); + FLUSH_VERTICES(ctx, _NEW_TEXTURE_OBJECT, 0); flushed = true; } sh->Program->SamplerUnits[unit] = value; @@ -1398,20 +1574,20 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, if (changed) { struct gl_program *const prog = sh->Program; _mesa_update_shader_textures_used(shProg, prog); - if (ctx->Driver.SamplerUniformChange) - ctx->Driver.SamplerUniformChange(ctx, prog->Target, prog); any_changed = true; } } if (any_changed) _mesa_update_valid_to_render_state(ctx); + else + shProg->SamplersValidated = samplers_validated; } /* If the uniform is an image, update the mapping from image * uniforms to image units present in the shader data structure. */ - if (uni->type->is_image()) { + if (glsl_type_is_image(uni->type)) { for (int i = 0; i < MESA_SHADER_STAGES; i++) { struct gl_linked_shader *sh = shProg->_LinkedShaders[i]; @@ -1438,7 +1614,7 @@ _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, } } - ctx->NewDriverState |= ctx->DriverFlags.NewImageUnits; + ctx->NewDriverState |= ST_NEW_IMAGE_UNITS; } } @@ -1674,7 +1850,18 @@ _mesa_uniform_matrix(GLint location, GLsizei count, if (uni == NULL) return; - if (!uni->type->is_matrix()) { + /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. + * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml + */ + if (transpose) { + if (_mesa_is_gles2(ctx) && ctx->Version < 30) { + _mesa_error(ctx, GL_INVALID_VALUE, + "glUniformMatrix(matrix transpose is not GL_FALSE)"); + return; + } + } + + if (!glsl_type_is_matrix(uni->type)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix(non-matrix uniform)"); return; @@ -1683,7 +1870,7 @@ _mesa_uniform_matrix(GLint location, GLsizei count, assert(basicType == GLSL_TYPE_FLOAT || basicType == GLSL_TYPE_DOUBLE); const unsigned size_mul = basicType == GLSL_TYPE_DOUBLE ? 2 : 1; - assert(!uni->type->is_sampler()); + assert(!glsl_type_is_sampler(uni->type)); const unsigned vectors = uni->type->matrix_columns; const unsigned components = uni->type->vector_elements; @@ -1696,17 +1883,6 @@ _mesa_uniform_matrix(GLint location, GLsizei count, return; } - /* GL_INVALID_VALUE is generated if `transpose' is not GL_FALSE. - * http://www.khronos.org/opengles/sdk/docs/man/xhtml/glUniform.xml - */ - if (transpose) { - if (ctx->API == API_OPENGLES2 && ctx->Version < 30) { - _mesa_error(ctx, GL_INVALID_VALUE, - "glUniformMatrix(matrix transpose is not GL_FALSE)"); - return; - } - } - /* Section 2.11.7 (Uniform Variables) of the OpenGL 4.2 Core Profile spec * says: * @@ -1728,7 +1904,7 @@ _mesa_uniform_matrix(GLint location, GLsizei count, basicType == GLSL_TYPE_FLOAT)) { _mesa_error(ctx, GL_INVALID_OPERATION, "glUniformMatrix%ux%u(\"%s\"@%d is %s, not %s)", - cols, rows, uni->name, location, + cols, rows, uni->name.string, location, glsl_type_name(uni->type->base_type), glsl_type_name(basicType)); return; @@ -1843,6 +2019,8 @@ _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values, return; uni = shProg->UniformRemapTable[location]; + if (!uni || uni == INACTIVE_UNIFORM_EXPLICIT_LOCATION) + return; /* The array index specified by the uniform location is just the * uniform location minus the base location of of the uniform. @@ -1931,7 +2109,7 @@ _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values, _mesa_propagate_uniforms_to_driver_storage(uni, offset, count); } - if (uni->type->is_sampler()) { + if (glsl_type_is_sampler(uni->type)) { /* Mark this bindless sampler as not bound to a texture unit because * it refers to a texture handle. */ @@ -1954,7 +2132,7 @@ _mesa_uniform_handle(GLint location, GLsizei count, const GLvoid *values, } } - if (uni->type->is_image()) { + if (glsl_type_is_image(uni->type)) { /* Mark this bindless image as not bound to an image unit because it * refers to a texture handle. */ diff --git a/src/mesa/main/uniforms.c b/src/mesa/main/uniforms.c index 7172cbd0ae4..47a8a869ce6 100644 --- a/src/mesa/main/uniforms.c +++ b/src/mesa/main/uniforms.c @@ -36,7 +36,7 @@ * 2. Insert FLUSH_VERTICES calls in various places */ -#include "main/glheader.h" +#include "util/glheader.h" #include "main/context.h" #include "main/shaderapi.h" #include "main/shaderobj.h" @@ -46,6 +46,9 @@ #include "compiler/glsl_types.h" #include "program/program.h" #include "util/bitscan.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_context.h" /** * Update the vertex/fragment program's TexturesUsed array. @@ -108,6 +111,7 @@ _mesa_update_shader_textures_used(struct gl_shader_program *shProg, assert(shProg->_LinkedShaders[prog_stage]); memset(prog->TexturesUsed, 0, sizeof(prog->TexturesUsed)); + prog->ShadowSamplers = prog->shader_program->_LinkedShaders[prog_stage]->shadow_samplers; while (mask) { s = u_bit_scan(&mask); @@ -996,15 +1000,16 @@ _mesa_GetUniformui64vARB(GLuint program, GLint location, GLuint64 *params) } -GLint GLAPIENTRY -_mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) +GLint +_mesa_GetUniformLocation_impl(GLuint programObj, const GLcharARB *name, + bool glthread) { struct gl_shader_program *shProg; GET_CURRENT_CONTEXT(ctx); - shProg = _mesa_lookup_shader_program_err(ctx, programObj, - "glGetUniformLocation"); + shProg = _mesa_lookup_shader_program_err_glthread(ctx, programObj, glthread, + "glGetUniformLocation"); if (!shProg || !name) return -1; @@ -1014,8 +1019,8 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) * INVALID_OPERATION is generated." */ if (shProg->data->LinkStatus == LINKING_FAILURE) { - _mesa_error(ctx, GL_INVALID_OPERATION, - "glGetUniformLocation(program not linked)"); + _mesa_error_glthread_safe(ctx, GL_INVALID_OPERATION, glthread, + "glGetUniformLocation(program not linked)"); return -1; } @@ -1023,6 +1028,12 @@ _mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) } GLint GLAPIENTRY +_mesa_GetUniformLocation(GLuint programObj, const GLcharARB *name) +{ + return _mesa_GetUniformLocation_impl(programObj, name, false); +} + +GLint GLAPIENTRY _mesa_GetUniformLocation_no_error(GLuint programObj, const GLcharARB *name) { GET_CURRENT_CONTEXT(ctx); @@ -1101,7 +1112,7 @@ uniform_block_binding(struct gl_context *ctx, struct gl_shader_program *shProg, uniformBlockBinding) { FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewUniformBuffer; + ctx->NewDriverState |= ST_NEW_UNIFORM_BUFFER; shProg->data->UniformBlocks[uniformBlockIndex].Binding = uniformBlockBinding; @@ -1163,7 +1174,7 @@ shader_storage_block_binding(struct gl_context *ctx, shaderStorageBlockBinding) { FLUSH_VERTICES(ctx, 0, 0); - ctx->NewDriverState |= ctx->DriverFlags.NewShaderStorageBuffer; + ctx->NewDriverState |= ST_NEW_STORAGE_BUFFER; shProg->data->ShaderStorageBlocks[shaderStorageBlockIndex].Binding = shaderStorageBlockBinding; diff --git a/src/mesa/main/uniforms.h b/src/mesa/main/uniforms.h index 70d13b82577..7c96a0736d3 100644 --- a/src/mesa/main/uniforms.h +++ b/src/mesa/main/uniforms.h @@ -26,7 +26,7 @@ #ifndef UNIFORMS_H #define UNIFORMS_H -#include "main/glheader.h" +#include "util/glheader.h" #include "compiler/glsl_types.h" #include "compiler/glsl/ir_uniform.h" #include "program/prog_parameter.h" @@ -39,425 +39,6 @@ extern "C" { struct gl_program; struct _glapi_table; -void GLAPIENTRY -_mesa_Uniform1f(GLint, GLfloat); -void GLAPIENTRY -_mesa_Uniform2f(GLint, GLfloat, GLfloat); -void GLAPIENTRY -_mesa_Uniform3f(GLint, GLfloat, GLfloat, GLfloat); -void GLAPIENTRY -_mesa_Uniform4f(GLint, GLfloat, GLfloat, GLfloat, GLfloat); -void GLAPIENTRY -_mesa_Uniform1i(GLint, GLint); -void GLAPIENTRY -_mesa_Uniform2i(GLint, GLint, GLint); -void GLAPIENTRY -_mesa_Uniform3i(GLint, GLint, GLint, GLint); -void GLAPIENTRY -_mesa_Uniform4i(GLint, GLint, GLint, GLint, GLint); -void GLAPIENTRY -_mesa_Uniform1fv(GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_Uniform2fv(GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_Uniform3fv(GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_Uniform4fv(GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_Uniform1iv(GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_Uniform2iv(GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_Uniform3iv(GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_Uniform4iv(GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_Uniform1ui(GLint location, GLuint v0); -void GLAPIENTRY -_mesa_Uniform2ui(GLint location, GLuint v0, GLuint v1); -void GLAPIENTRY -_mesa_Uniform3ui(GLint location, GLuint v0, GLuint v1, GLuint v2); -void GLAPIENTRY -_mesa_Uniform4ui(GLint location, GLuint v0, GLuint v1, GLuint v2, GLuint v3); -void GLAPIENTRY -_mesa_Uniform1uiv(GLint location, GLsizei count, const GLuint *value); -void GLAPIENTRY -_mesa_Uniform2uiv(GLint location, GLsizei count, const GLuint *value); -void GLAPIENTRY -_mesa_Uniform3uiv(GLint location, GLsizei count, const GLuint *value); -void GLAPIENTRY -_mesa_Uniform4uiv(GLint location, GLsizei count, const GLuint *value); -void GLAPIENTRY -_mesa_UniformMatrix2fv(GLint, GLsizei, GLboolean, const GLfloat *); -void GLAPIENTRY -_mesa_UniformMatrix3fv(GLint, GLsizei, GLboolean, const GLfloat *); -void GLAPIENTRY -_mesa_UniformMatrix4fv(GLint, GLsizei, GLboolean, const GLfloat *); -void GLAPIENTRY -_mesa_UniformMatrix2x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); -void GLAPIENTRY -_mesa_UniformMatrix3x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); -void GLAPIENTRY -_mesa_UniformMatrix2x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); -void GLAPIENTRY -_mesa_UniformMatrix4x2fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); -void GLAPIENTRY -_mesa_UniformMatrix3x4fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); -void GLAPIENTRY -_mesa_UniformMatrix4x3fv(GLint location, GLsizei count, GLboolean transpose, - const GLfloat *value); - -void GLAPIENTRY -_mesa_UniformHandleui64ARB(GLint location, GLuint64 value); -void GLAPIENTRY -_mesa_UniformHandleui64vARB(GLint location, GLsizei count, - const GLuint64 *value); -void GLAPIENTRY -_mesa_ProgramUniformHandleui64ARB(GLuint program, GLint location, - GLuint64 value); -void GLAPIENTRY -_mesa_ProgramUniformHandleui64vARB(GLuint program, GLint location, - GLsizei count, const GLuint64 *values); - -void GLAPIENTRY -_mesa_ProgramUniform1f(GLuint program, GLint, GLfloat); -void GLAPIENTRY -_mesa_ProgramUniform2f(GLuint program, GLint, GLfloat, GLfloat); -void GLAPIENTRY -_mesa_ProgramUniform3f(GLuint program, GLint, GLfloat, GLfloat, GLfloat); -void GLAPIENTRY -_mesa_ProgramUniform4f(GLuint program, GLint, GLfloat, GLfloat, GLfloat, GLfloat); -void GLAPIENTRY -_mesa_ProgramUniform1i(GLuint program, GLint, GLint); -void GLAPIENTRY -_mesa_ProgramUniform2i(GLuint program, GLint, GLint, GLint); -void GLAPIENTRY -_mesa_ProgramUniform3i(GLuint program, GLint, GLint, GLint, GLint); -void GLAPIENTRY -_mesa_ProgramUniform4i(GLuint program, GLint, GLint, GLint, GLint, GLint); -void GLAPIENTRY -_mesa_ProgramUniform1fv(GLuint program, GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniform2fv(GLuint program, GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniform3fv(GLuint program, GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniform4fv(GLuint program, GLint, GLsizei, const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniform1iv(GLuint program, GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_ProgramUniform2iv(GLuint program, GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_ProgramUniform3iv(GLuint program, GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_ProgramUniform4iv(GLuint program, GLint, GLsizei, const GLint *); -void GLAPIENTRY -_mesa_ProgramUniform1ui(GLuint program, GLint location, GLuint v0); -void GLAPIENTRY -_mesa_ProgramUniform2ui(GLuint program, GLint location, GLuint v0, GLuint v1); -void GLAPIENTRY -_mesa_ProgramUniform3ui(GLuint program, GLint location, GLuint v0, GLuint v1, - GLuint v2); -void GLAPIENTRY -_mesa_ProgramUniform4ui(GLuint program, GLint location, GLuint v0, GLuint v1, - GLuint v2, GLuint v3); -void GLAPIENTRY -_mesa_ProgramUniform1uiv(GLuint program, GLint location, GLsizei count, - const GLuint *value); -void GLAPIENTRY -_mesa_ProgramUniform2uiv(GLuint program, GLint location, GLsizei count, - const GLuint *value); -void GLAPIENTRY -_mesa_ProgramUniform3uiv(GLuint program, GLint location, GLsizei count, - const GLuint *value); -void GLAPIENTRY -_mesa_ProgramUniform4uiv(GLuint program, GLint location, GLsizei count, - const GLuint *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix2fv(GLuint program, GLint, GLsizei, GLboolean, - const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniformMatrix3fv(GLuint program, GLint, GLsizei, GLboolean, - const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniformMatrix4fv(GLuint program, GLint, GLsizei, GLboolean, - const GLfloat *); -void GLAPIENTRY -_mesa_ProgramUniformMatrix2x3fv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix3x2fv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix2x4fv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix4x2fv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix3x4fv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix4x3fv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLfloat *value); - -void GLAPIENTRY -_mesa_GetnUniformfvARB(GLuint, GLint, GLsizei, GLfloat *); -void GLAPIENTRY -_mesa_GetUniformfv(GLuint, GLint, GLfloat *); -void GLAPIENTRY -_mesa_GetnUniformivARB(GLuint, GLint, GLsizei, GLint *); -void GLAPIENTRY -_mesa_GetUniformuiv(GLuint, GLint, GLuint *); -void GLAPIENTRY -_mesa_GetnUniformuivARB(GLuint, GLint, GLsizei, GLuint *); -void GLAPIENTRY -_mesa_GetUniformuiv(GLuint program, GLint location, GLuint *params); -void GLAPIENTRY -_mesa_GetnUniformdvARB(GLuint, GLint, GLsizei, GLdouble *); -void GLAPIENTRY -_mesa_GetUniformdv(GLuint, GLint, GLdouble *); -GLint GLAPIENTRY -_mesa_GetUniformLocation(GLuint, const GLcharARB *); -GLint GLAPIENTRY -_mesa_GetUniformLocation_no_error(GLuint, const GLcharARB *); -GLuint GLAPIENTRY -_mesa_GetUniformBlockIndex(GLuint program, - const GLchar *uniformBlockName); -void GLAPIENTRY -_mesa_GetUniformIndices(GLuint program, - GLsizei uniformCount, - const GLchar * const *uniformNames, - GLuint *uniformIndices); - -void GLAPIENTRY -_mesa_UniformBlockBinding_no_error(GLuint program, GLuint uniformBlockIndex, - GLuint uniformBlockBinding); - -void GLAPIENTRY -_mesa_UniformBlockBinding(GLuint program, - GLuint uniformBlockIndex, - GLuint uniformBlockBinding); - -void GLAPIENTRY -_mesa_ShaderStorageBlockBinding_no_error(GLuint program, - GLuint shaderStorageBlockIndex, - GLuint shaderStorageBlockBinding); - -void GLAPIENTRY -_mesa_ShaderStorageBlockBinding(GLuint program, - GLuint shaderStorageBlockIndex, - GLuint shaderStorageBlockBinding); -void GLAPIENTRY -_mesa_GetActiveAtomicCounterBufferiv(GLuint program, GLuint bufferIndex, - GLenum pname, GLint *params); -void GLAPIENTRY -_mesa_GetActiveUniformBlockiv(GLuint program, - GLuint uniformBlockIndex, - GLenum pname, - GLint *params); -void GLAPIENTRY -_mesa_GetActiveUniformBlockName(GLuint program, - GLuint uniformBlockIndex, - GLsizei bufSize, - GLsizei *length, - GLchar *uniformBlockName); -void GLAPIENTRY -_mesa_GetActiveUniformName(GLuint program, GLuint uniformIndex, - GLsizei bufSize, GLsizei *length, - GLchar *uniformName); -void -_mesa_GetActiveUniform_impl(GLuint, GLuint, GLsizei, GLsizei *, - GLint *, GLenum *, GLcharARB *, - bool glthread); -void GLAPIENTRY -_mesa_GetActiveUniform(GLuint, GLuint, GLsizei, GLsizei *, - GLint *, GLenum *, GLcharARB *); -void GLAPIENTRY -_mesa_GetActiveUniformsiv(GLuint program, - GLsizei uniformCount, - const GLuint *uniformIndices, - GLenum pname, - GLint *params); -void GLAPIENTRY -_mesa_GetUniformiv(GLuint, GLint, GLint *); - -void GLAPIENTRY -_mesa_Uniform1d(GLint, GLdouble); -void GLAPIENTRY -_mesa_Uniform2d(GLint, GLdouble, GLdouble); -void GLAPIENTRY -_mesa_Uniform3d(GLint, GLdouble, GLdouble, GLdouble); -void GLAPIENTRY -_mesa_Uniform4d(GLint, GLdouble, GLdouble, GLdouble, GLdouble); - -void GLAPIENTRY -_mesa_Uniform1dv(GLint, GLsizei, const GLdouble *); -void GLAPIENTRY -_mesa_Uniform2dv(GLint, GLsizei, const GLdouble *); -void GLAPIENTRY -_mesa_Uniform3dv(GLint, GLsizei, const GLdouble *); -void GLAPIENTRY -_mesa_Uniform4dv(GLint, GLsizei, const GLdouble *); - -void GLAPIENTRY -_mesa_GetUniformi64vARB(GLuint, GLint, GLint64 *); -void GLAPIENTRY -_mesa_GetUniformui64vARB(GLuint, GLint, GLuint64 *); - -void GLAPIENTRY -_mesa_GetnUniformi64vARB(GLuint, GLint, GLsizei, GLint64 *); -void GLAPIENTRY -_mesa_GetnUniformui64vARB(GLuint, GLint, GLsizei, GLuint64 *); - -void GLAPIENTRY -_mesa_UniformMatrix2dv(GLint, GLsizei, GLboolean, const GLdouble *); -void GLAPIENTRY -_mesa_UniformMatrix3dv(GLint, GLsizei, GLboolean, const GLdouble *); -void GLAPIENTRY -_mesa_UniformMatrix4dv(GLint, GLsizei, GLboolean, const GLdouble *); -void GLAPIENTRY -_mesa_UniformMatrix2x3dv(GLint location, GLsizei count, GLboolean transpose, - const GLdouble *value); -void GLAPIENTRY -_mesa_UniformMatrix3x2dv(GLint location, GLsizei count, GLboolean transpose, - const GLdouble *value); -void GLAPIENTRY -_mesa_UniformMatrix2x4dv(GLint location, GLsizei count, GLboolean transpose, - const GLdouble *value); -void GLAPIENTRY -_mesa_UniformMatrix4x2dv(GLint location, GLsizei count, GLboolean transpose, - const GLdouble *value); -void GLAPIENTRY -_mesa_UniformMatrix3x4dv(GLint location, GLsizei count, GLboolean transpose, - const GLdouble *value); -void GLAPIENTRY -_mesa_UniformMatrix4x3dv(GLint location, GLsizei count, GLboolean transpose, - const GLdouble *value); - -void GLAPIENTRY -_mesa_ProgramUniform1d(GLuint program, GLint, GLdouble); -void GLAPIENTRY -_mesa_ProgramUniform2d(GLuint program, GLint, GLdouble, GLdouble); -void GLAPIENTRY -_mesa_ProgramUniform3d(GLuint program, GLint, GLdouble, GLdouble, GLdouble); -void GLAPIENTRY -_mesa_ProgramUniform4d(GLuint program, GLint, GLdouble, GLdouble, GLdouble, GLdouble); - -void GLAPIENTRY -_mesa_ProgramUniform1dv(GLuint program, GLint, GLsizei, const GLdouble *); -void GLAPIENTRY -_mesa_ProgramUniform2dv(GLuint program, GLint, GLsizei, const GLdouble *); -void GLAPIENTRY -_mesa_ProgramUniform3dv(GLuint program, GLint, GLsizei, const GLdouble *); -void GLAPIENTRY -_mesa_ProgramUniform4dv(GLuint program, GLint, GLsizei, const GLdouble *); - -void GLAPIENTRY -_mesa_ProgramUniformMatrix2dv(GLuint program, GLint, GLsizei, GLboolean, - const GLdouble *); -void GLAPIENTRY -_mesa_ProgramUniformMatrix3dv(GLuint program, GLint, GLsizei, GLboolean, - const GLdouble *); -void GLAPIENTRY -_mesa_ProgramUniformMatrix4dv(GLuint program, GLint, GLsizei, GLboolean, - const GLdouble *); -void GLAPIENTRY -_mesa_ProgramUniformMatrix2x3dv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLdouble *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix3x2dv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLdouble *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix2x4dv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLdouble *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix4x2dv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLdouble *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix3x4dv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLdouble *value); -void GLAPIENTRY -_mesa_ProgramUniformMatrix4x3dv(GLuint program, GLint location, GLsizei count, - GLboolean transpose, const GLdouble *value); - -void GLAPIENTRY -_mesa_Uniform1i64ARB(GLint, GLint64); -void GLAPIENTRY -_mesa_Uniform2i64ARB(GLint, GLint64, GLint64); -void GLAPIENTRY -_mesa_Uniform3i64ARB(GLint, GLint64, GLint64, GLint64); -void GLAPIENTRY -_mesa_Uniform4i64ARB(GLint, GLint64, GLint64, GLint64, GLint64); - -void GLAPIENTRY -_mesa_Uniform1i64vARB(GLint, GLsizei, const GLint64 *); -void GLAPIENTRY -_mesa_Uniform2i64vARB(GLint, GLsizei, const GLint64 *); -void GLAPIENTRY -_mesa_Uniform3i64vARB(GLint, GLsizei, const GLint64 *); -void GLAPIENTRY -_mesa_Uniform4i64vARB(GLint, GLsizei, const GLint64 *); - -void GLAPIENTRY -_mesa_Uniform1ui64ARB(GLint, GLuint64); -void GLAPIENTRY -_mesa_Uniform2ui64ARB(GLint, GLuint64, GLuint64); -void GLAPIENTRY -_mesa_Uniform3ui64ARB(GLint, GLuint64, GLuint64, GLuint64); -void GLAPIENTRY -_mesa_Uniform4ui64ARB(GLint, GLuint64, GLuint64, GLuint64, GLuint64); - -void GLAPIENTRY -_mesa_Uniform1ui64vARB(GLint, GLsizei, const GLuint64 *); -void GLAPIENTRY -_mesa_Uniform2ui64vARB(GLint, GLsizei, const GLuint64 *); -void GLAPIENTRY -_mesa_Uniform3ui64vARB(GLint, GLsizei, const GLuint64 *); -void GLAPIENTRY -_mesa_Uniform4ui64vARB(GLint, GLsizei, const GLuint64 *); - -void GLAPIENTRY -_mesa_ProgramUniform1i64ARB(GLuint, GLint, GLint64); -void GLAPIENTRY -_mesa_ProgramUniform2i64ARB(GLuint, GLint, GLint64, GLint64); -void GLAPIENTRY -_mesa_ProgramUniform3i64ARB(GLuint, GLint, GLint64, GLint64, GLint64); -void GLAPIENTRY -_mesa_ProgramUniform4i64ARB(GLuint, GLint, GLint64, GLint64, GLint64, GLint64); - -void GLAPIENTRY -_mesa_ProgramUniform1i64vARB(GLuint, GLint, GLsizei, const GLint64 *); -void GLAPIENTRY -_mesa_ProgramUniform2i64vARB(GLuint, GLint, GLsizei, const GLint64 *); -void GLAPIENTRY -_mesa_ProgramUniform3i64vARB(GLuint, GLint, GLsizei, const GLint64 *); -void GLAPIENTRY -_mesa_ProgramUniform4i64vARB(GLuint, GLint, GLsizei, const GLint64 *); - -void GLAPIENTRY -_mesa_ProgramUniform1ui64ARB(GLuint, GLint, GLuint64); -void GLAPIENTRY -_mesa_ProgramUniform2ui64ARB(GLuint, GLint, GLuint64, GLuint64); -void GLAPIENTRY -_mesa_ProgramUniform3ui64ARB(GLuint, GLint, GLuint64, GLuint64, GLuint64); -void GLAPIENTRY -_mesa_ProgramUniform4ui64ARB(GLuint, GLint, GLuint64, GLuint64, GLuint64, GLuint64); - -void GLAPIENTRY -_mesa_ProgramUniform1ui64vARB(GLuint, GLint, GLsizei, const GLuint64 *); -void GLAPIENTRY -_mesa_ProgramUniform2ui64vARB(GLuint, GLint, GLsizei, const GLuint64 *); -void GLAPIENTRY -_mesa_ProgramUniform3ui64vARB(GLuint, GLint, GLsizei, const GLuint64 *); -void GLAPIENTRY -_mesa_ProgramUniform4ui64vARB(GLuint, GLint, GLsizei, const GLuint64 *); - void _mesa_uniform(GLint location, GLsizei count, const GLvoid *values, struct gl_context *, struct gl_shader_program *, @@ -493,6 +74,11 @@ _mesa_propagate_uniforms_to_driver_storage(struct gl_uniform_storage *uni, unsigned array_index, unsigned count); +void +_mesa_ensure_and_associate_uniform_storage(struct gl_context *ctx, + struct gl_shader_program *shader_program, + struct gl_program *prog, unsigned required_space); + extern void _mesa_update_shader_textures_used(struct gl_shader_program *shProg, struct gl_program *prog); @@ -507,6 +93,15 @@ extern void _mesa_flush_vertices_for_uniforms(struct gl_context *ctx, const struct gl_uniform_storage *uni); +extern GLint +_mesa_GetUniformLocation_impl(GLuint programObj, const GLcharARB *name, + bool glthread); + +extern void +_mesa_GetActiveUniform_impl(GLuint program, GLuint index, + GLsizei maxLength, GLsizei *length, GLint *size, + GLenum *type, GLcharARB *nameOut, bool glthread); + struct gl_builtin_uniform_element { const char *field; gl_state_index16 tokens[STATE_LENGTH]; diff --git a/src/mesa/main/varray.c b/src/mesa/main/varray.c index ad34e44a49e..d9365616eb9 100644 --- a/src/mesa/main/varray.c +++ b/src/mesa/main/varray.c @@ -27,7 +27,7 @@ #include <stdio.h> #include <inttypes.h> /* for PRId64 macro */ -#include "glheader.h" +#include "util/glheader.h" #include "bufferobj.h" #include "context.h" @@ -42,7 +42,57 @@ #include "arrayobj.h" #include "get.h" #include "main/dispatch.h" +#include "api_exec_decl.h" +#include "state_tracker/st_atom.h" +#include "state_tracker/st_util.h" + +/* The values are multiplied by the component count to get the attrib size. + * Indexed by PERF_HASH_GL_TYPE(GLenum). + * Generated by src/util/tools/find_hash_func.c. + */ +const uint8_t _mesa_vertex_type_bytes[16] = { + /* These elements are listed out of order. */ + [/* 7*/ PERF_HASH_GL_VERTEX_TYPE(GL_BYTE)] = 1, + [/* 8*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_BYTE)] = 1, + [/* 5*/ PERF_HASH_GL_VERTEX_TYPE(GL_INT_2_10_10_10_REV)] = 1, /* count is 4 */ + [/* 0*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV)] = 1, /* count is 4 */ + [/* 9*/ PERF_HASH_GL_VERTEX_TYPE(GL_SHORT)] = 2, + [/*10*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_SHORT)] = 2, + [/* 2*/ PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_ARB)] = 2, + [/* 4*/ PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_OES)] = 2, + [/*11*/ PERF_HASH_GL_VERTEX_TYPE(GL_INT)] = 4, + [/*12*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT)] = 4, + [/*13*/ PERF_HASH_GL_VERTEX_TYPE(GL_FLOAT)] = 4, + [/* 3*/ PERF_HASH_GL_VERTEX_TYPE(GL_FIXED)] = 4, + [/* 1*/ PERF_HASH_GL_VERTEX_TYPE(GL_DOUBLE)] = 8, + [/* 6*/ PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT64_ARB)] = 8, +}; + +static inline void +compile_check_uniqueness_of_gl_vertex_type(unsigned x) +{ + /* This switch has the same purpose as static_assert. + * It should fail compilation if any case is not unique. + */ + switch (x) { + case PERF_HASH_GL_VERTEX_TYPE(GL_BYTE): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_BYTE): + case PERF_HASH_GL_VERTEX_TYPE(GL_INT_2_10_10_10_REV): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT_2_10_10_10_REV): + case PERF_HASH_GL_VERTEX_TYPE(GL_SHORT): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_SHORT): + case PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_ARB): + case PERF_HASH_GL_VERTEX_TYPE(GL_HALF_FLOAT_OES): + case PERF_HASH_GL_VERTEX_TYPE(GL_INT): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT): + case PERF_HASH_GL_VERTEX_TYPE(GL_FLOAT): + case PERF_HASH_GL_VERTEX_TYPE(GL_FIXED): + case PERF_HASH_GL_VERTEX_TYPE(GL_DOUBLE): + case PERF_HASH_GL_VERTEX_TYPE(GL_UNSIGNED_INT64_ARB): + break; + } +} /** Used to do error checking for GL_EXT_vertex_array_bgra */ #define BGRA_OR_4 5 @@ -66,7 +116,8 @@ #define UNSIGNED_INT_2_10_10_10_REV_BIT (1 << 12) #define INT_2_10_10_10_REV_BIT (1 << 13) #define UNSIGNED_INT_10F_11F_11F_REV_BIT (1 << 14) -#define ALL_TYPE_BITS ((1 << 15) - 1) +#define UNSIGNED_INT64_BIT (1 << 15) +#define ALL_TYPE_BITS ((1 << 16) - 1) #define ATTRIB_FORMAT_TYPES_MASK (BYTE_BIT | UNSIGNED_BYTE_BIT | \ SHORT_BIT | UNSIGNED_SHORT_BIT | \ @@ -81,7 +132,7 @@ SHORT_BIT | UNSIGNED_SHORT_BIT | \ INT_BIT | UNSIGNED_INT_BIT) -#define ATTRIB_LFORMAT_TYPES_MASK DOUBLE_BIT +#define ATTRIB_LFORMAT_TYPES_MASK (DOUBLE_BIT | UNSIGNED_INT64_BIT) /** Convert GL datatype enum into a <type>_BIT value seen above */ @@ -184,8 +235,17 @@ _mesa_vertex_attrib_binding(struct gl_context *ctx, array->BufferBindingIndex = bindingIndex; - vao->NewArrays |= vao->Enabled & array_bit; + if (vao->Enabled & array_bit) { + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; + } + vao->NonDefaultStateMask |= array_bit | BITFIELD_BIT(bindingIndex); + + if (attribIndex != bindingIndex) + vao->NonIdentityBufferAttribMapping |= array_bit; + else + vao->NonIdentityBufferAttribMapping &= ~array_bit; } } @@ -223,6 +283,7 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, if (binding->BufferObj != vbo || binding->Offset != offset || binding->Stride != stride) { + bool stride_changed = binding->Stride != stride; if (take_vbo_ownership) { _mesa_reference_buffer_object(ctx, &binding->BufferObj, NULL); @@ -241,8 +302,22 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, vbo->UsageHistory |= USAGE_ARRAY_BUFFER; } - vao->NewArrays |= vao->Enabled & binding->_BoundArrays; + if (vao->Enabled & binding->_BoundArrays) { + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + /* The slow path merges vertex buffers, which affects vertex elements. + * Stride changes also require new vertex elements. + */ + if (!ctx->Const.UseVAOFastPath || stride_changed) + ctx->Array.NewVertexElements = true; + } + vao->NonDefaultStateMask |= BITFIELD_BIT(index); + } else { + /* Since this function owns the vbo reference, it must release it if it + * doesn't use it. + */ + if (take_vbo_ownership) + _mesa_reference_buffer_object(ctx, &vbo, NULL); } } @@ -269,13 +344,17 @@ vertex_binding_divisor(struct gl_context *ctx, else vao->NonZeroDivisorMask &= ~binding->_BoundArrays; - vao->NewArrays |= vao->Enabled & binding->_BoundArrays; + if (vao->Enabled & binding->_BoundArrays) { + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; + } + vao->NonDefaultStateMask |= BITFIELD_BIT(bindingIndex); } } -/* vertex_formats[gltype - GL_BYTE][integer*2 + normalized][size - 1] */ -static const uint16_t vertex_formats[][4][4] = { +/* vertex_formats[(gltype & 0x3f) | (double << 5)][integer*2 + normalized][size - 1] */ +static const uint8_t vertex_formats[][4][4] = { { /* GL_BYTE */ { PIPE_FORMAT_R8_SSCALED, @@ -455,6 +534,138 @@ static const uint16_t vertex_formats[][4][4] = { PIPE_FORMAT_R32G32B32A32_FIXED }, }, + {{0}}, /* unused (13) */ + {{0}}, /* unused (14) */ + {{0}}, /* unused (15) */ + {{0}}, /* unused (16) */ + {{0}}, /* unused (17) */ + {{0}}, /* unused (18) */ + {{0}}, /* unused (19) */ + {{0}}, /* unused (20) */ + {{0}}, /* unused (21) */ + {{0}}, /* unused (22) */ + {{0}}, /* unused (23) */ + {{0}}, /* unused (24) */ + {{0}}, /* unused (25) */ + {{0}}, /* unused (26) */ + {{0}}, /* unused (27) */ + {{0}}, /* unused (28) */ + {{0}}, /* unused (29) */ + {{0}}, /* unused (30) */ + { /* GL_INT_2_10_10_10_REV */ + { + 0, + 0, + 0, + PIPE_FORMAT_R10G10B10A2_SSCALED + }, + { + 0, + 0, + 0, + PIPE_FORMAT_R10G10B10A2_SNORM + }, + }, + {{0}}, /* unused (32) */ + { /* GL_HALF_FLOAT_OES */ + { + PIPE_FORMAT_R16_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, + PIPE_FORMAT_R16G16B16_FLOAT, + PIPE_FORMAT_R16G16B16A16_FLOAT + }, + { + PIPE_FORMAT_R16_FLOAT, + PIPE_FORMAT_R16G16_FLOAT, + PIPE_FORMAT_R16G16B16_FLOAT, + PIPE_FORMAT_R16G16B16A16_FLOAT + }, + }, + {{0}}, /* unused (34) */ + {{0}}, /* unused (35) */ + {{0}}, /* unused (36) */ + {{0}}, /* unused (37) */ + {{0}}, /* unused (38) */ + {{0}}, /* unused (39) */ + { /* GL_UNSIGNED_INT_2_10_10_10_REV */ + { + 0, + 0, + 0, + PIPE_FORMAT_R10G10B10A2_USCALED + }, + { + 0, + 0, + 0, + PIPE_FORMAT_R10G10B10A2_UNORM + }, + }, + {{0}}, /* unused (41) */ + { /* GL_DOUBLE | (doubles << 5) (real double) */ + { + PIPE_FORMAT_R64_UINT, + PIPE_FORMAT_R64G64_UINT, + PIPE_FORMAT_R64G64B64_UINT, + PIPE_FORMAT_R64G64B64A64_UINT, + }, + }, + {{0}}, /* unused (43) */ + {{0}}, /* unused (44) */ + {{0}}, /* unused (45) */ + {{0}}, /* unused (46) */ + { /* GL_UNSIGNED_INT64_ARB | (doubles << 5) (doubles is always true) */ + {0}, + {0}, + { + PIPE_FORMAT_R64_UINT, + PIPE_FORMAT_R64G64_UINT, + PIPE_FORMAT_R64G64B64_UINT, + PIPE_FORMAT_R64G64B64A64_UINT, + }, + }, + {{0}}, /* unused (48) */ + {{0}}, /* unused (49) */ + {{0}}, /* unused (50) */ + {{0}}, /* unused (51) */ + {{0}}, /* unused (52) */ + {{0}}, /* unused (53) */ + {{0}}, /* unused (54) */ + {{0}}, /* unused (55) */ + {{0}}, /* unused (56) */ + {{0}}, /* unused (57) */ + {{0}}, /* unused (58) */ + { /* GL_UNSIGNED_INT_10F_11F_11F_REV */ + { + 0, + 0, + PIPE_FORMAT_R11G11B10_FLOAT, + 0 + }, + { + 0, + 0, + PIPE_FORMAT_R11G11B10_FLOAT, + 0 + }, + }, +}; + +/* bgra_vertex_formats[type & 0x3][normalized] */ +static const uint8_t bgra_vertex_formats[4][2] = { + { /* GL_UNSIGNED_INT_2_10_10_10_REV */ + PIPE_FORMAT_B10G10R10A2_USCALED, + PIPE_FORMAT_B10G10R10A2_UNORM + }, + { /* GL_UNSIGNED_BYTE */ + 0, + PIPE_FORMAT_B8G8R8A8_UNORM + }, + {0}, /* unused (2) */ + { /* GL_INT_2_10_10_10_REV */ + PIPE_FORMAT_B10G10R10A2_SSCALED, + PIPE_FORMAT_B10G10R10A2_SNORM + } }; /** @@ -467,84 +678,73 @@ vertex_format_to_pipe_format(GLubyte size, GLenum16 type, GLenum16 format, assert(size >= 1 && size <= 4); assert(format == GL_RGBA || format == GL_BGRA); - /* 64-bit attributes are translated by drivers. */ - if (doubles) - return PIPE_FORMAT_NONE; - - switch (type) { - case GL_HALF_FLOAT_OES: - type = GL_HALF_FLOAT; - break; - - case GL_INT_2_10_10_10_REV: - assert(size == 4 && !integer); - - if (format == GL_BGRA) { - if (normalized) - return PIPE_FORMAT_B10G10R10A2_SNORM; - else - return PIPE_FORMAT_B10G10R10A2_SSCALED; - } else { - if (normalized) - return PIPE_FORMAT_R10G10B10A2_SNORM; - else - return PIPE_FORMAT_R10G10B10A2_SSCALED; - } - break; - - case GL_UNSIGNED_INT_2_10_10_10_REV: + if (format == GL_BGRA) { assert(size == 4 && !integer); - - if (format == GL_BGRA) { - if (normalized) - return PIPE_FORMAT_B10G10R10A2_UNORM; - else - return PIPE_FORMAT_B10G10R10A2_USCALED; - } else { - if (normalized) - return PIPE_FORMAT_R10G10B10A2_UNORM; - else - return PIPE_FORMAT_R10G10B10A2_USCALED; - } - break; - - case GL_UNSIGNED_INT_10F_11F_11F_REV: - assert(size == 3 && !integer && format == GL_RGBA); - return PIPE_FORMAT_R11G11B10_FLOAT; - - case GL_UNSIGNED_BYTE: - if (format == GL_BGRA) { - /* this is an odd-ball case */ - assert(normalized); - return PIPE_FORMAT_B8G8R8A8_UNORM; - } - break; + assert(type == GL_UNSIGNED_BYTE || + type == GL_INT_2_10_10_10_REV || + type == GL_UNSIGNED_INT_2_10_10_10_REV); + + enum pipe_format pipe_format = + bgra_vertex_formats[type & 0x3][normalized]; + assert(pipe_format); + return pipe_format; } unsigned index = integer*2 + normalized; assert(index <= 2); - assert(type >= GL_BYTE && type <= GL_FIXED); - return vertex_formats[type - GL_BYTE][index][size-1]; + assert((type >= GL_BYTE && type <= GL_FIXED) || + type == GL_HALF_FLOAT_OES || + type == GL_INT_2_10_10_10_REV || + type == GL_UNSIGNED_INT_2_10_10_10_REV || + type == GL_UNSIGNED_INT_10F_11F_11F_REV || + (type == GL_UNSIGNED_INT64_ARB && doubles)); + + enum pipe_format pipe_format = + vertex_formats[(type & 0x3f) | ((int)doubles << 5)][index][size-1]; + assert(pipe_format); + return pipe_format; } -void -_mesa_set_vertex_format(struct gl_vertex_format *vertex_format, - GLubyte size, GLenum16 type, GLenum16 format, - GLboolean normalized, GLboolean integer, - GLboolean doubles) +static void +set_vertex_format_user(union gl_vertex_format_user *vertex_format, + GLubyte size, GLenum16 type, GLenum16 format, + GLboolean normalized, GLboolean integer, + GLboolean doubles) { assert(size <= 4); vertex_format->Type = type; - vertex_format->Format = format; + vertex_format->Bgra = format == GL_BGRA; vertex_format->Size = size; vertex_format->Normalized = normalized; vertex_format->Integer = integer; vertex_format->Doubles = doubles; +} + +static void +recompute_vertex_format_fields(struct gl_vertex_format *vertex_format, + GLubyte size, GLenum16 type, GLenum16 format, + GLboolean normalized, GLboolean integer, + GLboolean doubles) +{ vertex_format->_ElementSize = _mesa_bytes_per_vertex_attrib(size, type); assert(vertex_format->_ElementSize <= 4*sizeof(double)); vertex_format->_PipeFormat = vertex_format_to_pipe_format(size, type, format, normalized, integer, doubles); + /* pipe_vertex_element::src_format has only 8 bits, assuming a signed enum */ + assert(vertex_format->_PipeFormat <= 255); +} + +void +_mesa_set_vertex_format(struct gl_vertex_format *vertex_format, + GLubyte size, GLenum16 type, GLenum16 format, + GLboolean normalized, GLboolean integer, + GLboolean doubles) +{ + set_vertex_format_user(&vertex_format->User, size, type, format, + normalized, integer, doubles); + recompute_vertex_format_fields(vertex_format, size, type, format, + normalized, integer, doubles); } @@ -560,7 +760,8 @@ get_legal_types_mask(const struct gl_context *ctx) if (_mesa_is_gles(ctx)) { legalTypesMask &= ~(FIXED_GL_BIT | DOUBLE_BIT | - UNSIGNED_INT_10F_11F_11F_REV_BIT); + UNSIGNED_INT_10F_11F_11F_REV_BIT | + UNSIGNED_INT64_BIT); /* GL_INT and GL_UNSIGNED_INT data is not allowed in OpenGL ES until * 3.0. The 2_10_10_10 types are added in OpenGL ES 3.0 or @@ -591,6 +792,9 @@ get_legal_types_mask(const struct gl_context *ctx) if (!ctx->Extensions.ARB_vertex_type_10f_11f_11f_rev) legalTypesMask &= ~UNSIGNED_INT_10F_11F_11F_REV_BIT; + + if (!ctx->Extensions.ARB_bindless_texture) + legalTypesMask &= ~UNSIGNED_INT64_BIT; } return legalTypesMask; @@ -635,22 +839,28 @@ _mesa_update_array_format(struct gl_context *ctx, GLuint relativeOffset) { struct gl_array_attributes *const array = &vao->VertexAttrib[attrib]; - struct gl_vertex_format new_format; + union gl_vertex_format_user new_format; assert(!vao->SharedAndImmutable); assert(size <= 4); - _mesa_set_vertex_format(&new_format, size, type, format, - normalized, integer, doubles); + set_vertex_format_user(&new_format, size, type, format, + normalized, integer, doubles); - if ((array->RelativeOffset == relativeOffset) && - !memcmp(&new_format, &array->Format, sizeof(new_format))) + if (array->RelativeOffset == relativeOffset && + array->Format.User.All == new_format.All) return; array->RelativeOffset = relativeOffset; - array->Format = new_format; + array->Format.User = new_format; + recompute_vertex_format_fields(&array->Format, size, type, format, + normalized, integer, doubles); + + if (vao->Enabled & VERT_BIT(attrib)) { + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; + } - vao->NewArrays |= vao->Enabled & VERT_BIT(attrib); vao->NonDefaultStateMask |= BITFIELD_BIT(attrib); } @@ -816,7 +1026,7 @@ validate_array(struct gl_context *ctx, const char *func, * * The check for VBOs is handled below. */ - if (ctx->API == API_OPENGL_CORE && (vao == ctx->Array.DefaultVAO)) { + if (_mesa_is_desktop_gl_core(ctx) && (vao == ctx->Array.DefaultVAO)) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(no array object bound)", func); return; @@ -910,7 +1120,16 @@ update_array(struct gl_context *ctx, if ((array->Stride != stride) || (array->Ptr != ptr)) { array->Stride = stride; array->Ptr = ptr; - vao->NewArrays |= vao->Enabled & VERT_BIT(attrib); + + if (vao->Enabled & VERT_BIT(attrib)) { + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + /* The slow path merges vertex buffers, which affects vertex + * elements. + */ + if (!ctx->Const.UseVAOFastPath) + ctx->Array.NewVertexElements = true; + } + vao->NonDefaultStateMask |= BITFIELD_BIT(attrib); } @@ -938,7 +1157,7 @@ _lookup_vao_and_vbo_dsa(struct gl_context *ctx, if (buffer != 0) { *vbo = _mesa_lookup_bufferobj(ctx, buffer); - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, vbo, caller)) + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, vbo, caller, false)) return false; if (offset < 0) { @@ -953,6 +1172,25 @@ _lookup_vao_and_vbo_dsa(struct gl_context *ctx, return true; } +static bool +error_check_vertex_pointer(struct gl_context *ctx, const char *caller, + struct gl_vertex_array_object *vao, + struct gl_buffer_object *vbo, GLint size, + GLenum type, GLsizei stride, const GLvoid *ptr) +{ + GLenum format = GL_RGBA; + GLbitfield legalTypes = _mesa_is_gles1(ctx) + ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) + : (SHORT_BIT | INT_BIT | FLOAT_BIT | + DOUBLE_BIT | HALF_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); + + return validate_array_and_format(ctx, caller, vao, vbo, + VERT_ATTRIB_POS, legalTypes, 2, 4, size, + type, stride, GL_FALSE, GL_FALSE, GL_FALSE, + format, ptr); +} void GLAPIENTRY _mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride, @@ -971,23 +1209,13 @@ _mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - GLenum format = GL_RGBA; - GLbitfield legalTypes = (ctx->API == API_OPENGLES) - ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) - : (SHORT_BIT | INT_BIT | FLOAT_BIT | - DOUBLE_BIT | HALF_BIT | - UNSIGNED_INT_2_10_10_10_REV_BIT | - INT_2_10_10_10_REV_BIT); - - if (!validate_array_and_format(ctx, "glVertexPointer", - ctx->Array.VAO, ctx->Array.ArrayBufferObj, - VERT_ATTRIB_POS, legalTypes, 2, 4, size, - type, stride, GL_FALSE, GL_FALSE, GL_FALSE, - format, ptr)) + if (!error_check_vertex_pointer(ctx, "glVertexPointer", ctx->Array.VAO, + ctx->Array.ArrayBufferObj, size, type, + stride, ptr)) return; update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, - VERT_ATTRIB_POS, format, 4, size, type, stride, + VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, ptr); } @@ -997,15 +1225,6 @@ _mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { GET_CURRENT_CONTEXT(ctx); - - GLenum format = GL_RGBA; - GLbitfield legalTypes = (ctx->API == API_OPENGLES) - ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) - : (SHORT_BIT | INT_BIT | FLOAT_BIT | - DOUBLE_BIT | HALF_BIT | - UNSIGNED_INT_2_10_10_10_REV_BIT | - INT_2_10_10_10_REV_BIT); - struct gl_vertex_array_object* vao; struct gl_buffer_object* vbo; @@ -1014,19 +1233,36 @@ _mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, "glVertexArrayVertexOffsetEXT")) return; - if (!validate_array_and_format(ctx, "glVertexArrayVertexOffsetEXT", - vao, vbo, - VERT_ATTRIB_POS, legalTypes, 2, 4, size, - type, stride, GL_FALSE, GL_FALSE, GL_FALSE, - format, (void*) offset)) + if (!error_check_vertex_pointer(ctx, "glVertexArrayVertexOffsetEXT", vao, + vbo, size, type, stride, (void*)offset)) return; update_array(ctx, vao, vbo, - VERT_ATTRIB_POS, format, 4, size, type, stride, + VERT_ATTRIB_POS, GL_RGBA, 4, size, type, stride, GL_FALSE, GL_FALSE, GL_FALSE, (void*) offset); } +static bool +error_check_normal_pointer(struct gl_context *ctx, const char *caller, + struct gl_vertex_array_object *vao, + struct gl_buffer_object *vbo, GLenum type, + GLsizei stride, const GLvoid *ptr) +{ + GLenum format = GL_RGBA; + const GLbitfield legalTypes = _mesa_is_gles1(ctx) + ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) + : (BYTE_BIT | SHORT_BIT | INT_BIT | + HALF_BIT | FLOAT_BIT | DOUBLE_BIT | + UNSIGNED_INT_2_10_10_10_REV_BIT | + INT_2_10_10_10_REV_BIT); + + return validate_array_and_format(ctx, caller, vao, vbo, + VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, + type, stride, GL_TRUE, GL_FALSE, + GL_FALSE, format, ptr); +} + void GLAPIENTRY _mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr ) { @@ -1043,23 +1279,13 @@ _mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr ) { GET_CURRENT_CONTEXT(ctx); - GLenum format = GL_RGBA; - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) - ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) - : (BYTE_BIT | SHORT_BIT | INT_BIT | - HALF_BIT | FLOAT_BIT | DOUBLE_BIT | - UNSIGNED_INT_2_10_10_10_REV_BIT | - INT_2_10_10_10_REV_BIT); - - if (!validate_array_and_format(ctx, "glNormalPointer", - ctx->Array.VAO, ctx->Array.ArrayBufferObj, - VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, - type, stride, GL_TRUE, GL_FALSE, - GL_FALSE, format, ptr)) - return; + if (!error_check_normal_pointer(ctx, "glNormalPointer", ctx->Array.VAO, + ctx->Array.ArrayBufferObj, type, stride, + ptr)) + return; update_array(ctx, ctx->Array.VAO, ctx->Array.ArrayBufferObj, - VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, + VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, ptr); } @@ -1069,32 +1295,20 @@ _mesa_VertexArrayNormalOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, GLsizei stride, GLintptr offset) { GET_CURRENT_CONTEXT(ctx); - - GLenum format = GL_RGBA; - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) - ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) - : (BYTE_BIT | SHORT_BIT | INT_BIT | - HALF_BIT | FLOAT_BIT | DOUBLE_BIT | - UNSIGNED_INT_2_10_10_10_REV_BIT | - INT_2_10_10_10_REV_BIT); - struct gl_vertex_array_object* vao; struct gl_buffer_object* vbo; if (!_lookup_vao_and_vbo_dsa(ctx, vaobj, buffer, offset, &vao, &vbo, - "glNormalPointer")) + "glVertexArrayNormalOffsetEXT")) return; - if (!validate_array_and_format(ctx, "glNormalPointer", - vao, vbo, - VERT_ATTRIB_NORMAL, legalTypes, 3, 3, 3, - type, stride, GL_TRUE, GL_FALSE, - GL_FALSE, format, (void*) offset)) - return; + if (!error_check_normal_pointer(ctx, "glVertexArrayNormalOffsetEXT", + vao, vbo, type, stride, (void*)offset)) + return; update_array(ctx, vao, vbo, - VERT_ATTRIB_NORMAL, format, 3, 3, type, stride, GL_TRUE, + VERT_ATTRIB_NORMAL, GL_RGBA, 3, 3, type, stride, GL_TRUE, GL_FALSE, GL_FALSE, (void*) offset); } @@ -1116,10 +1330,10 @@ void GLAPIENTRY _mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3; + const GLint sizeMin = _mesa_is_gles1(ctx) ? 4 : 3; GLenum format = get_array_format(ctx, BGRA_OR_4, &size); - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) + const GLbitfield legalTypes = _mesa_is_gles1(ctx) ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT) : (BYTE_BIT | UNSIGNED_BYTE_BIT | SHORT_BIT | UNSIGNED_SHORT_BIT | @@ -1146,10 +1360,10 @@ _mesa_VertexArrayColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { GET_CURRENT_CONTEXT(ctx); - const GLint sizeMin = (ctx->API == API_OPENGLES) ? 4 : 3; + const GLint sizeMin = _mesa_is_gles1(ctx) ? 4 : 3; GLenum format = get_array_format(ctx, BGRA_OR_4, &size); - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) + const GLbitfield legalTypes = _mesa_is_gles1(ctx) ? (UNSIGNED_BYTE_BIT | HALF_BIT | FLOAT_BIT | FIXED_ES_BIT) : (BYTE_BIT | UNSIGNED_BYTE_BIT | SHORT_BIT | UNSIGNED_SHORT_BIT | @@ -1398,11 +1612,11 @@ _mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr) { GET_CURRENT_CONTEXT(ctx); - const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; + const GLint sizeMin = _mesa_is_gles1(ctx) ? 2 : 1; const GLuint unit = ctx->Array.ActiveTexture; GLenum format = GL_RGBA; - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) + const GLbitfield legalTypes = _mesa_is_gles1(ctx) ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) : (SHORT_BIT | INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | @@ -1427,11 +1641,11 @@ _mesa_VertexArrayTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, GLenum type, GLsizei stride, GLintptr offset) { GET_CURRENT_CONTEXT(ctx); - const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; + const GLint sizeMin = _mesa_is_gles1(ctx) ? 2 : 1; const GLuint unit = ctx->Array.ActiveTexture; GLenum format = GL_RGBA; - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) + const GLbitfield legalTypes = _mesa_is_gles1(ctx) ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) : (SHORT_BIT | INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | @@ -1465,11 +1679,11 @@ _mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texu GLintptr offset) { GET_CURRENT_CONTEXT(ctx); - const GLint sizeMin = (ctx->API == API_OPENGLES) ? 2 : 1; + const GLint sizeMin = _mesa_is_gles1(ctx) ? 2 : 1; const GLuint unit = texunit - GL_TEXTURE0; GLenum format = GL_RGBA; - const GLbitfield legalTypes = (ctx->API == API_OPENGLES) + const GLbitfield legalTypes = _mesa_is_gles1(ctx) ? (BYTE_BIT | SHORT_BIT | FLOAT_BIT | FIXED_ES_BIT) : (SHORT_BIT | INT_BIT | HALF_BIT | FLOAT_BIT | DOUBLE_BIT | @@ -1725,7 +1939,7 @@ _mesa_VertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint inde return; } - const GLbitfield legalTypes = DOUBLE_BIT; + const GLbitfield legalTypes = ATTRIB_LFORMAT_TYPES_MASK; if (!validate_array_and_format(ctx, "glVertexArrayVertexAttribLOffsetEXT", vao, vbo, @@ -1854,7 +2068,7 @@ _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, return; } - const GLbitfield legalTypes = DOUBLE_BIT; + const GLbitfield legalTypes = ATTRIB_LFORMAT_TYPES_MASK; if (!validate_array_and_format(ctx, "glVertexAttribLPointer", ctx->Array.VAO, ctx->Array.ArrayBufferObj, @@ -1868,13 +2082,68 @@ _mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, stride, GL_FALSE, GL_FALSE, GL_TRUE, ptr); } +/** + * Set the per-vertex edge flag enablement according to the "enable" + * parameter. If "enable" is false, the zero-stride edge flag attribute value + * will be used instead. + * + * This is used by VAOs, glBegin/End and display lists. + */ +void +_mesa_update_edgeflag_state_explicit(struct gl_context *ctx, + bool per_vertex_enable) +{ + if (ctx->API != API_OPENGL_COMPAT) + return; + + /* Edge flags take effect only if the polygon mode is not FILL, and they + * determine whether a line or point is drawn with that polygon mode. + */ + bool edgeflags_have_effect = ctx->Polygon.FrontMode != GL_FILL || + ctx->Polygon.BackMode != GL_FILL; + per_vertex_enable &= edgeflags_have_effect; + + if (per_vertex_enable != ctx->Array._PerVertexEdgeFlagsEnabled) { + ctx->Array._PerVertexEdgeFlagsEnabled = per_vertex_enable; + + struct gl_program *vp = ctx->VertexProgram._Current; + if (vp) { + ctx->NewDriverState |= ST_NEW_VS_STATE | + ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; + } + } + + /* If there are no per-vertex edge flags and the zero-stride edge flag is + * false, all front and back points and lines generated by polygon mode + * are not drawn. + */ + bool polygon_mode_always_culls = edgeflags_have_effect && + !ctx->Array._PerVertexEdgeFlagsEnabled && + !ctx->Current.Attrib[VERT_ATTRIB_EDGEFLAG][0]; + if (polygon_mode_always_culls != ctx->Array._PolygonModeAlwaysCulls) { + ctx->Array._PolygonModeAlwaysCulls = polygon_mode_always_culls; + ctx->NewDriverState |= ST_NEW_RASTERIZER; + } +} + +/** + * Set the edge flag state using the current VAO and the zero-stride + * edge flag attribute value if per-vertex edge flags are disabled. + */ +void +_mesa_update_edgeflag_state_vao(struct gl_context *ctx) +{ + _mesa_update_edgeflag_state_explicit(ctx, + ctx->Array._DrawVAO->Enabled & + VERT_BIT_EDGEFLAG); +} void _mesa_enable_vertex_array_attribs(struct gl_context *ctx, struct gl_vertex_array_object *vao, GLbitfield attrib_bits) { - assert((attrib_bits & ~VERT_BIT_ALL) == 0); assert(!vao->SharedAndImmutable); /* Only work on bits that are disabled */ @@ -1882,13 +2151,17 @@ _mesa_enable_vertex_array_attribs(struct gl_context *ctx, if (attrib_bits) { /* was disabled, now being enabled */ vao->Enabled |= attrib_bits; - vao->NewArrays |= attrib_bits; vao->NonDefaultStateMask |= attrib_bits; + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; /* Update the map mode if needed */ if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) update_attribute_map_mode(ctx, vao); + if (attrib_bits & VERT_BIT_EDGEFLAG) + _mesa_update_edgeflag_state_vao(ctx); + vao->_EnabledWithMapMode = _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled); } @@ -1975,7 +2248,6 @@ _mesa_disable_vertex_array_attribs(struct gl_context *ctx, struct gl_vertex_array_object *vao, GLbitfield attrib_bits) { - assert((attrib_bits & ~VERT_BIT_ALL) == 0); assert(!vao->SharedAndImmutable); /* Only work on bits that are enabled */ @@ -1983,12 +2255,16 @@ _mesa_disable_vertex_array_attribs(struct gl_context *ctx, if (attrib_bits) { /* was enabled, now being disabled */ vao->Enabled &= ~attrib_bits; - vao->NewArrays |= attrib_bits; + ctx->NewDriverState |= ST_NEW_VERTEX_ARRAYS; + ctx->Array.NewVertexElements = true; /* Update the map mode if needed */ if (attrib_bits & (VERT_BIT_POS|VERT_BIT_GENERIC0)) update_attribute_map_mode(ctx, vao); + if (attrib_bits & VERT_BIT_EDGEFLAG) + _mesa_update_edgeflag_state_vao(ctx); + vao->_EnabledWithMapMode = _mesa_vao_enable_to_vp_inputs(vao->_AttributeMapMode, vao->Enabled); } @@ -2102,13 +2378,13 @@ get_vertex_array_attrib(struct gl_context *ctx, case GL_VERTEX_ATTRIB_ARRAY_ENABLED_ARB: return !!(vao->Enabled & VERT_BIT_GENERIC(index)); case GL_VERTEX_ATTRIB_ARRAY_SIZE_ARB: - return (array->Format.Format == GL_BGRA) ? GL_BGRA : array->Format.Size; + return array->Format.User.Bgra ? GL_BGRA : array->Format.User.Size; case GL_VERTEX_ATTRIB_ARRAY_STRIDE_ARB: return array->Stride; case GL_VERTEX_ATTRIB_ARRAY_TYPE_ARB: - return array->Format.Type; + return array->Format.User.Type; case GL_VERTEX_ATTRIB_ARRAY_NORMALIZED_ARB: - return array->Format.Normalized; + return array->Format.User.Normalized; case GL_VERTEX_ATTRIB_ARRAY_BUFFER_BINDING_ARB: buf = vao->BufferBinding[array->BufferBindingIndex].BufferObj; return buf ? buf->Name : 0; @@ -2116,17 +2392,17 @@ get_vertex_array_attrib(struct gl_context *ctx, if ((_mesa_is_desktop_gl(ctx) && (ctx->Version >= 30 || ctx->Extensions.EXT_gpu_shader4)) || _mesa_is_gles3(ctx)) { - return array->Format.Integer; + return array->Format.User.Integer; } goto error; case GL_VERTEX_ATTRIB_ARRAY_LONG: if (_mesa_is_desktop_gl(ctx)) { - return array->Format.Doubles; + return array->Format.User.Doubles; } goto error; case GL_VERTEX_ATTRIB_ARRAY_DIVISOR_ARB: - if ((_mesa_is_desktop_gl(ctx) && ctx->Extensions.ARB_instanced_arrays) - || _mesa_is_gles3(ctx)) { + if (_mesa_has_ARB_instanced_arrays(ctx) || + _mesa_has_EXT_instanced_arrays(ctx)) { return vao->BufferBinding[array->BufferBindingIndex].InstanceDivisor; } goto error; @@ -2941,7 +3217,7 @@ vertex_array_vertex_buffer(struct gl_context *ctx, * Otherwise, we fall back to the same compat profile behavior as other * object references (automatically gen it). */ - if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func)) + if (!_mesa_handle_bind_buffer_gen(ctx, buffer, &vbo, func, no_error)) return; } else { /* The ARB_vertex_attrib_binding spec says: @@ -3034,7 +3310,7 @@ _mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, * "An INVALID_OPERATION error is generated if no vertex array object * is bound." */ - if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && + if ((_mesa_is_desktop_gl_core(ctx) || _mesa_is_gles31(ctx)) && ctx->Array.VAO == ctx->Array.DefaultVAO) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexBuffer(No array object bound)"); @@ -3142,7 +3418,7 @@ vertex_array_vertex_buffers(struct gl_context *ctx, * their parameters are valid and no other error occurs." */ - _mesa_HashLockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashLockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); for (i = 0; i < count; i++) { @@ -3200,7 +3476,7 @@ vertex_array_vertex_buffers(struct gl_context *ctx, vbo, offsets[i], strides[i], false, false); } - _mesa_HashUnlockMaybeLocked(ctx->Shared->BufferObjects, + _mesa_HashUnlockMaybeLocked(&ctx->Shared->BufferObjects, ctx->BufferObjectsLocked); } @@ -3256,7 +3532,7 @@ _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, * "An INVALID_OPERATION error is generated if no * vertex array object is bound." */ - if (ctx->API == API_OPENGL_CORE && + if (_mesa_is_desktop_gl_core(ctx) && ctx->Array.VAO == ctx->Array.DefaultVAO) { _mesa_error(ctx, GL_INVALID_OPERATION, "glBindVertexBuffers(No array object bound)"); @@ -3271,31 +3547,18 @@ _mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, void _mesa_InternalBindVertexBuffers(struct gl_context *ctx, - const struct glthread_attrib_binding *buffers, - GLbitfield buffer_mask, - GLboolean restore_pointers) + struct gl_buffer_object **buffers, + const int *offsets, GLbitfield buffer_mask) { struct gl_vertex_array_object *vao = ctx->Array.VAO; unsigned param_index = 0; - if (restore_pointers) { - while (buffer_mask) { - unsigned i = u_bit_scan(&buffer_mask); - - _mesa_bind_vertex_buffer(ctx, vao, i, NULL, - (GLintptr)buffers[param_index].original_pointer, - vao->BufferBinding[i].Stride, false, false); - param_index++; - } - return; - } - while (buffer_mask) { unsigned i = u_bit_scan(&buffer_mask); - struct gl_buffer_object *buf = buffers[param_index].buffer; + struct gl_buffer_object *buf = buffers[param_index]; /* The buffer reference is passed to _mesa_bind_vertex_buffer. */ - _mesa_bind_vertex_buffer(ctx, vao, i, buf, buffers[param_index].offset, + _mesa_bind_vertex_buffer(ctx, vao, i, buf, offsets[param_index], vao->BufferBinding[i].Stride, true, true); param_index++; } @@ -3367,7 +3630,7 @@ vertex_attrib_format(GLuint attribIndex, GLint size, GLenum type, * is an oversight. In the OpenGL 4.3 (Core Profile) spec, it applies * to all three functions. */ - if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && + if ((_mesa_is_desktop_gl_core(ctx) || _mesa_is_gles31(ctx)) && ctx->Array.VAO == ctx->Array.DefaultVAO) { _mesa_error(ctx, GL_INVALID_OPERATION, "%s(No array object bound)", func); @@ -3615,7 +3878,7 @@ _mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex) * "An INVALID_OPERATION error is generated if no vertex array object * is bound." */ - if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && + if ((_mesa_is_desktop_gl_core(ctx) || _mesa_is_gles31(ctx)) && ctx->Array.VAO == ctx->Array.DefaultVAO) { _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexAttribBinding(No array object bound)"); @@ -3725,7 +3988,7 @@ _mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor) * "An INVALID_OPERATION error is generated if no vertex array object * is bound." */ - if ((ctx->API == API_OPENGL_CORE || _mesa_is_gles31(ctx)) && + if ((_mesa_is_desktop_gl_core(ctx) || _mesa_is_gles31(ctx)) && ctx->Array.VAO == ctx->Array.DefaultVAO) { _mesa_error(ctx, GL_INVALID_OPERATION, "glVertexBindingDivisor(No array object bound)"); @@ -3814,8 +4077,8 @@ _mesa_print_arrays(struct gl_context *ctx) fprintf(stderr, " %s: Ptr=%p, Type=%s, Size=%d, ElemSize=%u, " "Stride=%d, Buffer=%u(Size %lu)\n", gl_vert_attrib_name((gl_vert_attrib)i), - array->Ptr, _mesa_enum_to_string(array->Format.Type), - array->Format.Size, + array->Ptr, _mesa_enum_to_string(array->Format.User.Type), + array->Format.User.Size, array->Format._ElementSize, binding->Stride, bo ? bo->Name : 0, (unsigned long)(bo ? bo->Size : 0)); } @@ -3838,6 +4101,8 @@ init_array(struct gl_context *ctx, assert(index < ARRAY_SIZE(vao->BufferBinding)); struct gl_vertex_buffer_binding *binding = &vao->BufferBinding[index]; + vao->NonIdentityBufferAttribMapping &= ~BITFIELD_BIT(index); + _mesa_set_vertex_format(&array->Format, size, type, GL_RGBA, GL_FALSE, GL_FALSE, GL_FALSE); array->Stride = 0; @@ -3901,16 +4166,15 @@ _mesa_init_varray(struct gl_context *ctx) ctx->Array.DefaultVAO = _mesa_new_vao(ctx, 0); _mesa_reference_vao(ctx, &ctx->Array.VAO, ctx->Array.DefaultVAO); - ctx->Array._EmptyVAO = _mesa_new_vao(ctx, ~0u); - _mesa_reference_vao(ctx, &ctx->Array._DrawVAO, ctx->Array._EmptyVAO); + _mesa_set_draw_vao(ctx, ctx->Array.VAO); ctx->Array.ActiveTexture = 0; /* GL_ARB_multitexture */ - ctx->Array.Objects = _mesa_NewHashTable(); + _mesa_InitHashTable(&ctx->Array.Objects); } /** - * Callback for deleting an array object. Called by _mesa_HashDeleteAll(). + * Callback for deleting an array object. Called by _mesa_DeleteHashTable(). */ static void delete_arrayobj_cb(void *data, void *userData) @@ -3927,8 +4191,7 @@ delete_arrayobj_cb(void *data, void *userData) void _mesa_free_varray_data(struct gl_context *ctx) { - _mesa_HashDeleteAll(ctx->Array.Objects, delete_arrayobj_cb, ctx); - _mesa_DeleteHashTable(ctx->Array.Objects); + _mesa_DeinitHashTable(&ctx->Array.Objects, delete_arrayobj_cb, ctx); } void GLAPIENTRY @@ -3957,10 +4220,10 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = GL_TEXTURE0_ARB + ctx->Array.ActiveTexture; break; case GL_VERTEX_ARRAY_SIZE: - *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Size; + *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.User.Size; break; case GL_VERTEX_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_POS].Format.User.Type; break; case GL_VERTEX_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_POS].Stride; @@ -3970,10 +4233,10 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = buf ? buf->Name : 0; break; case GL_COLOR_ARRAY_SIZE: - *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Size; + *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.User.Size; break; case GL_COLOR_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Format.User.Type; break; case GL_COLOR_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_COLOR0].Stride; @@ -3990,7 +4253,7 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = buf ? buf->Name : 0; break; case GL_INDEX_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Format.User.Type; break; case GL_INDEX_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Stride; @@ -4000,7 +4263,7 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = buf ? buf->Name : 0; break; case GL_NORMAL_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Format.User.Type; break; case GL_NORMAL_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_NORMAL].Stride; @@ -4010,10 +4273,10 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = buf ? buf->Name : 0; break; case GL_TEXTURE_COORD_ARRAY_SIZE: - *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Size; + *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.User.Size; break; case GL_TEXTURE_COORD_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Format.User.Type; break; case GL_TEXTURE_COORD_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_TEX(ctx->Array.ActiveTexture)].Stride; @@ -4023,7 +4286,7 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = buf ? buf->Name : 0; break; case GL_FOG_COORD_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Format.User.Type; break; case GL_FOG_COORD_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_FOG].Stride; @@ -4033,10 +4296,10 @@ _mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param) *param = buf ? buf->Name : 0; break; case GL_SECONDARY_COLOR_ARRAY_SIZE: - *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Size; + *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.User.Size; break; case GL_SECONDARY_COLOR_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Format.User.Type; break; case GL_SECONDARY_COLOR_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_COLOR1].Stride; @@ -4154,10 +4417,10 @@ _mesa_GetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLin *param = !!(vao->Enabled & VERT_BIT_TEX(index)); break; case GL_TEXTURE_COORD_ARRAY_SIZE: - *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Size; + *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.User.Size; break; case GL_TEXTURE_COORD_ARRAY_TYPE: - *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.Type; + *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Format.User.Type; break; case GL_TEXTURE_COORD_ARRAY_STRIDE: *param = vao->VertexAttrib[VERT_ATTRIB_TEX(index)].Stride; diff --git a/src/mesa/main/varray.h b/src/mesa/main/varray.h index bb02a31535e..98412547115 100644 --- a/src/mesa/main/varray.h +++ b/src/mesa/main/varray.h @@ -125,215 +125,6 @@ _mesa_bind_vertex_buffer(struct gl_context *ctx, GLintptr offset, GLsizei stride, bool offset_is_int32, bool take_vbo_ownership); -extern void GLAPIENTRY -_mesa_VertexPointer_no_error(GLint size, GLenum type, GLsizei stride, - const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_VertexPointer(GLint size, GLenum type, GLsizei stride, - const GLvoid *ptr); - -extern void GLAPIENTRY -_mesa_NormalPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_NormalPointer(GLenum type, GLsizei stride, const GLvoid *ptr); - -extern void GLAPIENTRY -_mesa_ColorPointer_no_error(GLint size, GLenum type, GLsizei stride, - const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_IndexPointer_no_error(GLenum type, GLsizei stride, const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_IndexPointer(GLenum type, GLsizei stride, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_TexCoordPointer_no_error(GLint size, GLenum type, GLsizei stride, - const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_TexCoordPointer(GLint size, GLenum type, GLsizei stride, - const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_MultiTexCoordPointerEXT(GLenum texunit, GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr); - -extern void GLAPIENTRY -_mesa_EdgeFlagPointer_no_error(GLsizei stride, const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_EdgeFlagPointer(GLsizei stride, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_VertexPointerEXT(GLint size, GLenum type, GLsizei stride, - GLsizei count, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_NormalPointerEXT(GLenum type, GLsizei stride, GLsizei count, - const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_ColorPointerEXT(GLint size, GLenum type, GLsizei stride, GLsizei count, - const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_IndexPointerEXT(GLenum type, GLsizei stride, GLsizei count, - const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_TexCoordPointerEXT(GLint size, GLenum type, GLsizei stride, - GLsizei count, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_EdgeFlagPointerEXT(GLsizei stride, GLsizei count, const GLboolean *ptr); - -extern void GLAPIENTRY -_mesa_FogCoordPointer_no_error(GLenum type, GLsizei stride, - const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_FogCoordPointer(GLenum type, GLsizei stride, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_SecondaryColorPointer_no_error(GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_SecondaryColorPointer(GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_PointSizePointerOES_no_error(GLenum type, GLsizei stride, - const GLvoid *ptr); -extern void GLAPIENTRY -_mesa_PointSizePointerOES(GLenum type, GLsizei stride, const GLvoid *ptr); - - -extern void GLAPIENTRY -_mesa_VertexAttribPointer_no_error(GLuint index, GLint size, GLenum type, - GLboolean normalized, GLsizei stride, - const GLvoid *pointer); -extern void GLAPIENTRY -_mesa_VertexAttribPointer(GLuint index, GLint size, GLenum type, - GLboolean normalized, GLsizei stride, - const GLvoid *pointer); - -void GLAPIENTRY -_mesa_VertexAttribIPointer_no_error(GLuint index, GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr); -void GLAPIENTRY -_mesa_VertexAttribIPointer(GLuint index, GLint size, GLenum type, - GLsizei stride, const GLvoid *ptr); - -extern void GLAPIENTRY -_mesa_VertexAttribLPointer_no_error(GLuint index, GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer); -extern void GLAPIENTRY -_mesa_VertexAttribLPointer(GLuint index, GLint size, GLenum type, - GLsizei stride, const GLvoid *pointer); - -extern void GLAPIENTRY -_mesa_EnableVertexAttribArray(GLuint index); - -extern void GLAPIENTRY -_mesa_EnableVertexAttribArray_no_error(GLuint index); - - -extern void GLAPIENTRY -_mesa_EnableVertexArrayAttrib(GLuint vaobj, GLuint index); - -extern void GLAPIENTRY -_mesa_EnableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index); - -extern void GLAPIENTRY -_mesa_EnableVertexArrayAttribEXT( GLuint vaobj, GLuint index ); - - -extern void GLAPIENTRY -_mesa_DisableVertexAttribArray(GLuint index); - -extern void GLAPIENTRY -_mesa_DisableVertexAttribArray_no_error(GLuint index); - - -extern void GLAPIENTRY -_mesa_DisableVertexArrayAttrib(GLuint vaobj, GLuint index); - -extern void GLAPIENTRY -_mesa_DisableVertexArrayAttrib_no_error(GLuint vaobj, GLuint index); - -extern void GLAPIENTRY -_mesa_DisableVertexArrayAttribEXT( GLuint vaobj, GLuint index ); - -extern void GLAPIENTRY -_mesa_GetVertexAttribdv(GLuint index, GLenum pname, GLdouble *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribfv(GLuint index, GLenum pname, GLfloat *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribLdv(GLuint index, GLenum pname, GLdouble *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribiv(GLuint index, GLenum pname, GLint *params); - -extern void GLAPIENTRY -_mesa_GetVertexAttribLui64vARB(GLuint index, GLenum pname, GLuint64EXT *params); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribIiv(GLuint index, GLenum pname, GLint *params); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribIuiv(GLuint index, GLenum pname, GLuint *params); - - -extern void GLAPIENTRY -_mesa_GetVertexAttribPointerv(GLuint index, GLenum pname, GLvoid **pointer); - - -void GLAPIENTRY -_mesa_GetVertexArrayIndexediv(GLuint vaobj, GLuint index, - GLenum pname, GLint *param); - - -void GLAPIENTRY -_mesa_GetVertexArrayIndexed64iv(GLuint vaobj, GLuint index, - GLenum pname, GLint64 *param); - - -extern void GLAPIENTRY -_mesa_InterleavedArrays(GLenum format, GLsizei stride, const GLvoid *pointer); - - -extern void GLAPIENTRY -_mesa_LockArraysEXT(GLint first, GLsizei count); - -extern void GLAPIENTRY -_mesa_UnlockArraysEXT(void); - - -void GLAPIENTRY -_mesa_PrimitiveRestartIndex_no_error(GLuint index); - -extern void GLAPIENTRY -_mesa_PrimitiveRestartIndex(GLuint index); - -extern void GLAPIENTRY -_mesa_VertexAttribDivisor_no_error(GLuint index, GLuint divisor); -extern void GLAPIENTRY -_mesa_VertexAttribDivisor(GLuint index, GLuint divisor); -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribDivisorEXT(GLuint vaobj, GLuint index, GLuint divisor); - static inline unsigned _mesa_get_prim_restart_index(bool fixed_index, unsigned restart_index, unsigned index_size) @@ -362,128 +153,10 @@ _mesa_primitive_restart_index(const struct gl_context *ctx, ctx->Array.RestartIndex, index_size); } -extern void GLAPIENTRY -_mesa_BindVertexBuffer_no_error(GLuint bindingIndex, GLuint buffer, - GLintptr offset, GLsizei stride); -extern void GLAPIENTRY -_mesa_BindVertexBuffer(GLuint bindingIndex, GLuint buffer, GLintptr offset, - GLsizei stride); - -void GLAPIENTRY -_mesa_VertexArrayVertexBuffer_no_error(GLuint vaobj, GLuint bindingIndex, - GLuint buffer, GLintptr offset, - GLsizei stride); -extern void GLAPIENTRY -_mesa_VertexArrayVertexBuffer(GLuint vaobj, GLuint bindingIndex, GLuint buffer, - GLintptr offset, GLsizei stride); - -extern void GLAPIENTRY -_mesa_VertexArrayBindVertexBufferEXT(GLuint vaobj, GLuint bindingIndex, GLuint buffer, - GLintptr offset, GLsizei stride); - -void GLAPIENTRY -_mesa_BindVertexBuffers_no_error(GLuint first, GLsizei count, - const GLuint *buffers, const GLintptr *offsets, - const GLsizei *strides); - -extern void GLAPIENTRY -_mesa_BindVertexBuffers(GLuint first, GLsizei count, const GLuint *buffers, - const GLintptr *offsets, const GLsizei *strides); - void _mesa_InternalBindVertexBuffers(struct gl_context *ctx, - const struct glthread_attrib_binding *buffers, - GLbitfield buffer_mask, - GLboolean restore_pointers); - -void GLAPIENTRY -_mesa_VertexArrayVertexBuffers_no_error(GLuint vaobj, GLuint first, - GLsizei count, const GLuint *buffers, - const GLintptr *offsets, - const GLsizei *strides); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexBuffers(GLuint vaobj, GLuint first, GLsizei count, - const GLuint *buffers, - const GLintptr *offsets, const GLsizei *strides); - -extern void GLAPIENTRY -_mesa_VertexAttribFormat(GLuint attribIndex, GLint size, GLenum type, - GLboolean normalized, GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexArrayAttribFormat(GLuint vaobj, GLuint attribIndex, GLint size, - GLenum type, GLboolean normalized, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribFormatEXT(GLuint vaobj, GLuint attribIndex, GLint size, - GLenum type, GLboolean normalized, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexAttribIFormat(GLuint attribIndex, GLint size, GLenum type, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexArrayAttribIFormat(GLuint vaobj, GLuint attribIndex, - GLint size, GLenum type, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribIFormatEXT(GLuint vaobj, GLuint attribIndex, - GLint size, GLenum type, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexAttribLFormat(GLuint attribIndex, GLint size, GLenum type, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexArrayAttribLFormat(GLuint vaobj, GLuint attribIndex, - GLint size, GLenum type, - GLuint relativeOffset); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribLFormatEXT(GLuint vaobj, GLuint attribIndex, - GLint size, GLenum type, - GLuint relativeOffset); - -void GLAPIENTRY -_mesa_VertexAttribBinding_no_error(GLuint attribIndex, GLuint bindingIndex); - -extern void GLAPIENTRY -_mesa_VertexAttribBinding(GLuint attribIndex, GLuint bindingIndex); - -void GLAPIENTRY -_mesa_VertexArrayAttribBinding_no_error(GLuint vaobj, GLuint attribIndex, - GLuint bindingIndex); - -extern void GLAPIENTRY -_mesa_VertexArrayAttribBinding(GLuint vaobj, GLuint attribIndex, - GLuint bindingIndex); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribBindingEXT(GLuint vaobj, GLuint attribIndex, - GLuint bindingIndex); - -void GLAPIENTRY -_mesa_VertexBindingDivisor_no_error(GLuint bindingIndex, GLuint divisor); - -extern void GLAPIENTRY -_mesa_VertexBindingDivisor(GLuint bindingIndex, GLuint divisor); - -void GLAPIENTRY -_mesa_VertexArrayBindingDivisor_no_error(GLuint vaobj, GLuint bindingIndex, - GLuint divisor); - -extern void GLAPIENTRY -_mesa_VertexArrayBindingDivisor(GLuint vaobj, GLuint bindingIndex, - GLuint divisor); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexBindingDivisorEXT(GLuint vaobj, GLuint bindingIndex, - GLuint divisor); + struct gl_buffer_object **buffers, + const int *offsets, GLbitfield buffer_mask); extern void _mesa_print_arrays(struct gl_context *ctx); @@ -494,66 +167,45 @@ _mesa_init_varray(struct gl_context *ctx); extern void _mesa_free_varray_data(struct gl_context *ctx); -extern void GLAPIENTRY -_mesa_VertexArrayVertexOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, - GLenum type, GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, - GLenum type, GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayEdgeFlagOffsetEXT(GLuint vaobj, GLuint buffer, GLsizei stride, - GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayIndexOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, - GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayNormalOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, - GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, - GLenum type, GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayMultiTexCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum texunit, - GLint size, GLenum type, GLsizei stride, - GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayFogCoordOffsetEXT(GLuint vaobj, GLuint buffer, GLenum type, - GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArraySecondaryColorOffsetEXT(GLuint vaobj, GLuint buffer, GLint size, - GLenum type, GLsizei stride, GLintptr offset); - -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, - GLenum type, GLboolean normalized, - GLsizei stride, GLintptr offset); +void +_mesa_update_edgeflag_state_explicit(struct gl_context *ctx, + bool per_vertex_enable); -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribIOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, - GLenum type, GLsizei stride, GLintptr offset); +void +_mesa_update_edgeflag_state_vao(struct gl_context *ctx); -extern void GLAPIENTRY -_mesa_VertexArrayVertexAttribLOffsetEXT(GLuint vaobj, GLuint buffer, GLuint index, GLint size, - GLenum type, GLsizei stride, GLintptr offset); -extern void GLAPIENTRY -_mesa_GetVertexArrayIntegervEXT(GLuint vaobj, GLenum pname, GLint *param); +/** + * Get the number of bytes for a vertex attrib with the given number of + * components and type. + * + * Note that this function will return some number between 0 and + * "8 * comps" if the type is invalid. It's assumed that error checking + * was done before this, or was skipped intentionally by mesa_no_error. + * + * \param comps number of components. + * \param type data type. + */ +static inline int +_mesa_bytes_per_vertex_attrib(int comps, GLenum type) +{ + /* This has comps = 3, but should return 4, so it's difficult to + * incorporate it into the "bytes * comps" formula below. + */ + if (type == GL_UNSIGNED_INT_10F_11F_11F_REV) + return 4; -extern void GLAPIENTRY -_mesa_GetVertexArrayPointervEXT(GLuint vaobj, GLenum pname, GLvoid** param); + /* This is a perfect hash for the specific set of GLenums that is valid + * here. It injectively maps a small set of GLenums into smaller numbers + * that can be used for indexing into small translation tables. It has + * hash collisions with enums that are invalid here. + */ + #define PERF_HASH_GL_VERTEX_TYPE(x) ((((x) * 17175) >> 14) & 0xf) -extern void GLAPIENTRY -_mesa_GetVertexArrayIntegeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLint *param); + extern const uint8_t _mesa_vertex_type_bytes[16]; -extern void GLAPIENTRY -_mesa_GetVertexArrayPointeri_vEXT(GLuint vaobj, GLuint index, GLenum pname, GLvoid** param); + assert(PERF_HASH_GL_VERTEX_TYPE(type) < ARRAY_SIZE(_mesa_vertex_type_bytes)); + return _mesa_vertex_type_bytes[PERF_HASH_GL_VERTEX_TYPE(type)] * comps; +} #endif diff --git a/src/mesa/main/vdpau.c b/src/mesa/main/vdpau.c index 6a96c40bdb8..a9d1e97fd31 100644 --- a/src/mesa/main/vdpau.c +++ b/src/mesa/main/vdpau.c @@ -39,7 +39,11 @@ #include "glformats.h" #include "texobj.h" #include "teximage.h" -#include "vdpau.h" +#include "textureview.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_cb_texture.h" +#include "state_tracker/st_vdpau.h" #define MAX_TEXTURES 4 @@ -90,7 +94,7 @@ unregister_surface(struct set_entry *entry) } _mesa_set_remove(ctx->vdpSurfaces, entry); - free(surf); + FREE(surf); } void GLAPIENTRY @@ -176,7 +180,7 @@ register_surface(struct gl_context *ctx, GLboolean isOutput, } /* This will disallow respecifying the storage. */ - tex->Immutable = GL_TRUE; + _mesa_set_texture_view_state(ctx, tex, target, 1); _mesa_unlock_texture(ctx, tex); _mesa_reference_texobj(&surf->textures[i], tex); @@ -377,11 +381,11 @@ _mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) return; } - ctx->Driver.FreeTextureImageBuffer(ctx, image); + st_FreeTextureImageBuffer(ctx, image); - ctx->Driver.VDPAUMapSurface(ctx, surf->target, surf->access, - surf->output, tex, image, - surf->vdpSurface, j); + st_vdpau_map_surface(ctx, surf->target, surf->access, + surf->output, tex, image, + surf->vdpSurface, j); _mesa_unlock_texture(ctx, tex); } @@ -427,12 +431,12 @@ _mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces) image = _mesa_select_tex_image(tex, surf->target, 0); - ctx->Driver.VDPAUUnmapSurface(ctx, surf->target, surf->access, - surf->output, tex, image, - surf->vdpSurface, j); + st_vdpau_unmap_surface(ctx, surf->target, surf->access, + surf->output, tex, image, + surf->vdpSurface, j); if (image) - ctx->Driver.FreeTextureImageBuffer(ctx, image); + st_FreeTextureImageBuffer(ctx, image); _mesa_unlock_texture(ctx, tex); } diff --git a/src/mesa/main/vdpau.h b/src/mesa/main/vdpau.h deleted file mode 100644 index 627609c50de..00000000000 --- a/src/mesa/main/vdpau.h +++ /dev/null @@ -1,72 +0,0 @@ -/************************************************************************** - * - * Copyright 2013 Advanced Micro Devices, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - * - **************************************************************************/ - -/* - * Authors: - * Christian König <christian.koenig@amd.com> - * - */ - -#ifndef VDPAU_H -#define VDPAU_H - -extern void GLAPIENTRY -_mesa_VDPAUInitNV(const GLvoid *vdpDevice, const GLvoid *getProcAddress); - -extern void GLAPIENTRY -_mesa_VDPAUFiniNV(void); - -extern GLintptr GLAPIENTRY -_mesa_VDPAURegisterVideoSurfaceNV(const GLvoid *vdpSurface, GLenum target, - GLsizei numTextureNames, - const GLuint *textureNames); - -extern GLintptr GLAPIENTRY -_mesa_VDPAURegisterOutputSurfaceNV(const GLvoid *vdpSurface, GLenum target, - GLsizei numTextureNames, - const GLuint *textureNames); - -extern GLboolean GLAPIENTRY -_mesa_VDPAUIsSurfaceNV(GLintptr surface); - -extern void GLAPIENTRY -_mesa_VDPAUUnregisterSurfaceNV(GLintptr surface); - -extern void GLAPIENTRY -_mesa_VDPAUGetSurfaceivNV(GLintptr surface, GLenum pname, GLsizei bufSize, - GLsizei *length, GLint *values); - -extern void GLAPIENTRY -_mesa_VDPAUSurfaceAccessNV(GLintptr surface, GLenum access); - -extern void GLAPIENTRY -_mesa_VDPAUMapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces); - -extern void GLAPIENTRY -_mesa_VDPAUUnmapSurfacesNV(GLsizei numSurfaces, const GLintptr *surfaces); - -#endif /* VDPAU_H */ diff --git a/src/mesa/main/version.c b/src/mesa/main/version.c index 3b37b135184..d9811650a9e 100644 --- a/src/mesa/main/version.c +++ b/src/mesa/main/version.c @@ -34,7 +34,9 @@ #include "version.h" #include "git_sha1.h" -static simple_mtx_t override_lock = _SIMPLE_MTX_INITIALIZER_NP; +#include "state_tracker/st_context.h" + +static simple_mtx_t override_lock = SIMPLE_MTX_INITIALIZER; /** * Scans 'string' to see if it ends with 'ending'. @@ -134,8 +136,8 @@ create_version_string(struct gl_context *ctx, const char *prefix) "%s%u.%u%s Mesa " PACKAGE_VERSION MESA_GIT_SHA1, prefix, ctx->Version / 10, ctx->Version % 10, - (ctx->API == API_OPENGL_CORE) ? " (Core Profile)" : - (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 32) ? + _mesa_is_desktop_gl_core(ctx) ? " (Core Profile)" : + (_mesa_is_desktop_gl_compat(ctx) && ctx->Version >= 32) ? " (Compatibility Profile)" : "" ); } @@ -249,32 +251,24 @@ compute_version(const struct gl_extensions *extensions, { GLuint major, minor, version; - const bool ver_1_3 = (extensions->ARB_texture_border_clamp && - extensions->ARB_texture_cube_map && - extensions->ARB_texture_env_combine && - extensions->ARB_texture_env_dot3); - const bool ver_1_4 = (ver_1_3 && - extensions->ARB_depth_texture && - extensions->ARB_shadow && - extensions->ARB_texture_env_crossbar && - extensions->EXT_blend_color && - extensions->EXT_blend_func_separate && - extensions->EXT_blend_minmax && - extensions->EXT_point_parameters); - const bool ver_1_5 = (ver_1_4 && - extensions->ARB_occlusion_query); + const bool ver_1_4 = (extensions->ARB_shadow); + const bool ver_1_5 = ver_1_4; const bool ver_2_0 = (ver_1_5 && - extensions->ARB_point_sprite && extensions->ARB_vertex_shader && extensions->ARB_fragment_shader && extensions->ARB_texture_non_power_of_two && extensions->EXT_blend_equation_separate && extensions->EXT_stencil_two_side); const bool ver_2_1 = (ver_2_0 && - extensions->EXT_pixel_buffer_object && extensions->EXT_texture_sRGB); + /* We lie about the minimum number of color attachments. Strictly, OpenGL + * 3.0 requires 8, whereas OpenGL ES requires 4. OpenGL ES 3.0 class + * hardware may only support 4 render targets. Advertise non-conformant + * OpenGL 3.0 anyway. Affects freedreno on a3xx + */ const bool ver_3_0 = (ver_2_1 && consts->GLSLVersion >= 130 && + consts->MaxColorAttachments >= 4 && (consts->MaxSamples >= 4 || consts->FakeSWMSAA) && (api == API_OPENGL_CORE || extensions->ARB_color_buffer_float) && @@ -317,7 +311,6 @@ compute_version(const struct gl_extensions *extensions, extensions->ARB_blend_func_extended && extensions->ARB_explicit_attrib_location && extensions->ARB_instanced_arrays && - extensions->ARB_occlusion_query2 && extensions->ARB_shader_bit_encoding && extensions->ARB_texture_rgb10_a2ui && extensions->ARB_timer_query && @@ -342,6 +335,9 @@ compute_version(const struct gl_extensions *extensions, consts->GLSLVersion >= 410 && consts->MaxTextureSize >= 16384 && consts->MaxRenderbufferSize >= 16384 && + consts->MaxCubeTextureLevels >= 15 && + consts->Max3DTextureLevels >= 12 && + consts->MaxArrayTextureLayers >= 2048 && extensions->ARB_ES2_compatibility && extensions->ARB_shader_precision && extensions->ARB_vertex_attrib_64bit && @@ -379,7 +375,6 @@ compute_version(const struct gl_extensions *extensions, consts->GLSLVersion >= 440 && consts->MaxVertexAttribStride >= 2048 && extensions->ARB_buffer_storage && - extensions->ARB_clear_texture && extensions->ARB_enhanced_layouts && extensions->ARB_query_buffer_object && extensions->ARB_texture_mirror_clamp_to_edge && @@ -399,7 +394,6 @@ compute_version(const struct gl_extensions *extensions, extensions->ARB_gl_spirv && extensions->ARB_spirv_extensions && extensions->ARB_indirect_parameters && - extensions->ARB_pipeline_statistics_query && extensions->ARB_polygon_offset_clamp && extensions->ARB_shader_atomic_counter_ops && extensions->ARB_shader_draw_parameters && @@ -467,13 +461,9 @@ compute_version(const struct gl_extensions *extensions, major = 1; minor = 4; } - else if (ver_1_3) { - major = 1; - minor = 3; - } else { major = 1; - minor = 2; + minor = 3; } version = major * 10 + minor; @@ -485,34 +475,11 @@ compute_version(const struct gl_extensions *extensions, } static GLuint -compute_version_es1(const struct gl_extensions *extensions) -{ - /* OpenGL ES 1.0 is derived from OpenGL 1.3 */ - const bool ver_1_0 = (extensions->ARB_texture_env_combine && - extensions->ARB_texture_env_dot3); - /* OpenGL ES 1.1 is derived from OpenGL 1.5 */ - const bool ver_1_1 = (ver_1_0 && - extensions->EXT_point_parameters); - - if (ver_1_1) { - return 11; - } else if (ver_1_0) { - return 10; - } else { - return 0; - } -} - -static GLuint compute_version_es2(const struct gl_extensions *extensions, const struct gl_constants *consts) { /* OpenGL ES 2.0 is derived from OpenGL 2.0 */ - const bool ver_2_0 = (extensions->ARB_texture_cube_map && - extensions->EXT_blend_color && - extensions->EXT_blend_func_separate && - extensions->EXT_blend_minmax && - extensions->ARB_vertex_shader && + const bool ver_2_0 = (extensions->ARB_vertex_shader && extensions->ARB_fragment_shader && extensions->ARB_texture_non_power_of_two && extensions->EXT_blend_equation_separate); @@ -534,12 +501,14 @@ compute_version_es2(const struct gl_extensions *extensions, extensions->EXT_texture_sRGB && extensions->EXT_transform_feedback && extensions->ARB_draw_instanced && + extensions->ARB_instanced_arrays && extensions->ARB_uniform_buffer_object && extensions->EXT_texture_snorm && (extensions->NV_primitive_restart || consts->PrimitiveRestartFixedIndex) && extensions->OES_depth_texture_cube_map && - extensions->EXT_texture_type_2_10_10_10_REV); + extensions->EXT_texture_type_2_10_10_10_REV && + consts->MaxColorAttachments >= 4); const bool es31_compute_shader = consts->MaxComputeWorkGroupInvocations >= 128 && consts->Program[MESA_SHADER_COMPUTE].MaxShaderStorageBlocks && @@ -566,7 +535,7 @@ compute_version_es2(const struct gl_extensions *extensions, extensions->ARB_shader_image_load_store && extensions->ARB_shader_image_size && extensions->ARB_shader_storage_buffer_object && - + extensions->EXT_color_buffer_float && extensions->EXT_draw_buffers2 && extensions->KHR_blend_equation_advanced && extensions->KHR_robustness && @@ -578,7 +547,6 @@ compute_version_es2(const struct gl_extensions *extensions, extensions->OES_primitive_bounding_box && extensions->OES_sample_variables && extensions->ARB_tessellation_shader && - extensions->ARB_texture_border_clamp && extensions->OES_texture_buffer && extensions->OES_texture_cube_map_array && extensions->ARB_texture_stencil8); @@ -611,7 +579,7 @@ _mesa_get_version(const struct gl_extensions *extensions, case API_OPENGL_CORE: return compute_version(extensions, consts, api); case API_OPENGLES: - return compute_version_es1(extensions); + return 11; case API_OPENGLES2: return compute_version_es2(extensions, consts); } @@ -682,7 +650,7 @@ _mesa_compute_version(struct gl_context *ctx) } done: - if (ctx->API == API_OPENGL_COMPAT && ctx->Version >= 31) + if (_mesa_is_desktop_gl_compat(ctx) && ctx->Version >= 31) ctx->Extensions.ARB_compatibility = GL_TRUE; /* Precompute valid primitive types for faster draw time validation. */ @@ -695,7 +663,7 @@ done: (1 << GL_TRIANGLE_STRIP) | (1 << GL_TRIANGLE_FAN); - if (ctx->API == API_OPENGL_COMPAT) { + if (_mesa_is_desktop_gl_compat(ctx)) { ctx->SupportedPrimMask |= (1 << GL_QUADS) | (1 << GL_QUAD_STRIP) | (1 << GL_POLYGON); @@ -711,6 +679,16 @@ done: if (_mesa_has_tessellation(ctx)) ctx->SupportedPrimMask |= 1 << GL_PATCHES; + /* Appendix F.2 of the OpenGL ES 3.0 spec says: + * + * "OpenGL ES 3.0 requires that all cube map filtering be + * seamless. OpenGL ES 2.0 specified that a single cube map face be + * selected and used for filtering." + * + * Now that we know our version, enable seamless filtering for GLES3 only. + */ + ctx->Texture.CubeMapSeamless = _mesa_is_gles3(ctx); + /* First time initialization. */ _mesa_update_valid_to_render_state(ctx); } @@ -719,13 +697,28 @@ done: void _mesa_get_driver_uuid(struct gl_context *ctx, GLint *uuid) { - ctx->Driver.GetDriverUuid(ctx, (char*) uuid); + struct pipe_screen *screen = ctx->pipe->screen; + assert(GL_UUID_SIZE_EXT >= PIPE_UUID_SIZE); + memset(uuid, 0, GL_UUID_SIZE_EXT); + screen->get_driver_uuid(screen, (char *)uuid); } void _mesa_get_device_uuid(struct gl_context *ctx, GLint *uuid) { - ctx->Driver.GetDeviceUuid(ctx, (char*) uuid); + struct pipe_screen *screen = ctx->pipe->screen; + assert(GL_UUID_SIZE_EXT >= PIPE_UUID_SIZE); + memset(uuid, 0, GL_UUID_SIZE_EXT); + screen->get_device_uuid(screen, (char *)uuid); +} + +void +_mesa_get_device_luid(struct gl_context *ctx, GLint *luid) +{ + struct pipe_screen *screen = ctx->pipe->screen; + assert(GL_LUID_SIZE_EXT >= PIPE_LUID_SIZE); + memset(luid, 0, GL_UUID_SIZE_EXT); + screen->get_device_luid(screen, (char *)luid); } /** @@ -777,14 +770,13 @@ _mesa_get_shading_language_version(const struct gl_context *ctx, GLSL_VERSION(""); /* GLSL es */ - if ((ctx->API == API_OPENGLES2 && ctx->Version >= 32) || - ctx->Extensions.ARB_ES3_2_compatibility) + if (_mesa_is_gles32(ctx) || ctx->Extensions.ARB_ES3_2_compatibility) GLSL_VERSION("320 es"); if (_mesa_is_gles31(ctx) || ctx->Extensions.ARB_ES3_1_compatibility) GLSL_VERSION("310 es"); if (_mesa_is_gles3(ctx) || ctx->Extensions.ARB_ES3_compatibility) GLSL_VERSION("300 es"); - if (ctx->API == API_OPENGLES2 || ctx->Extensions.ARB_ES2_compatibility) + if (_mesa_is_gles2(ctx) || ctx->Extensions.ARB_ES2_compatibility) GLSL_VERSION("100"); #undef GLSL_VERSION diff --git a/src/mesa/main/version.h b/src/mesa/main/version.h index 4469509c08e..cdfe7fc4946 100644 --- a/src/mesa/main/version.h +++ b/src/mesa/main/version.h @@ -28,7 +28,7 @@ #define VERSION_H #include <stdbool.h> -#include "glheader.h" +#include "util/glheader.h" #include "menums.h" struct gl_context; @@ -58,6 +58,9 @@ _mesa_get_driver_uuid(struct gl_context *ctx, GLint *uuid); extern void _mesa_get_device_uuid(struct gl_context *ctx, GLint *uuid); +extern void +_mesa_get_device_luid(struct gl_context *ctx, GLint *luid); + extern int _mesa_get_shading_language_version(const struct gl_context *ctx, int index, diff --git a/src/mesa/main/viewport.c b/src/mesa/main/viewport.c index de9687eb071..9b31eb9ca1e 100644 --- a/src/mesa/main/viewport.c +++ b/src/mesa/main/viewport.c @@ -34,6 +34,10 @@ #include "macros.h" #include "mtypes.h" #include "viewport.h" +#include "api_exec_decl.h" + +#include "state_tracker/st_manager.h" +#include "state_tracker/st_context.h" static void clamp_viewport(struct gl_context *ctx, GLfloat *x, GLfloat *y, @@ -71,9 +75,8 @@ set_viewport_no_notify(struct gl_context *ctx, unsigned idx, ctx->ViewportArray[idx].Height == height) return; - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewViewport ? 0 : _NEW_VIEWPORT, - GL_VIEWPORT_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewViewport; + FLUSH_VERTICES(ctx, 0, GL_VIEWPORT_BIT); + ctx->NewDriverState |= ST_NEW_VIEWPORT; ctx->ViewportArray[idx].X = x; ctx->ViewportArray[idx].Width = width; @@ -113,8 +116,8 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei width, for (unsigned i = 0; i < ctx->Const.MaxViewports; i++) set_viewport_no_notify(ctx, i, input.X, input.Y, input.Width, input.Height); - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); + if (ctx->invalidate_on_gl_viewport) + st_manager_invalidate_drawables(ctx); } /** @@ -166,8 +169,8 @@ _mesa_set_viewport(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y, clamp_viewport(ctx, &x, &y, &width, &height); set_viewport_no_notify(ctx, idx, x, y, width, height); - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); + if (ctx->invalidate_on_gl_viewport) + st_manager_invalidate_drawables(ctx); } static void @@ -182,8 +185,8 @@ viewport_array(struct gl_context *ctx, GLuint first, GLsizei count, inputs[i].Width, inputs[i].Height); } - if (ctx->Driver.Viewport) - ctx->Driver.Viewport(ctx); + if (ctx->invalidate_on_gl_viewport) + st_manager_invalidate_drawables(ctx); } void GLAPIENTRY @@ -294,7 +297,7 @@ set_depth_range_no_notify(struct gl_context *ctx, unsigned idx, /* The depth range is needed by program state constants. */ FLUSH_VERTICES(ctx, _NEW_VIEWPORT, GL_VIEWPORT_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewViewport; + ctx->NewDriverState |= ST_NEW_VIEWPORT; ctx->ViewportArray[idx].Near = SATURATE(nearval); ctx->ViewportArray[idx].Far = SATURATE(farval); @@ -305,9 +308,6 @@ _mesa_set_depth_range(struct gl_context *ctx, unsigned idx, GLclampd nearval, GLclampd farval) { set_depth_range_no_notify(ctx, idx, nearval, farval); - - if (ctx->Driver.DepthRange) - ctx->Driver.DepthRange(ctx); } /** @@ -340,10 +340,6 @@ _mesa_DepthRange(GLclampd nearval, GLclampd farval) */ for (i = 0; i < ctx->Const.MaxViewports; i++) set_depth_range_no_notify(ctx, i, nearval, farval); - - if (ctx->Driver.DepthRange) { - ctx->Driver.DepthRange(ctx); - } } void GLAPIENTRY @@ -366,9 +362,6 @@ depth_range_arrayv(struct gl_context *ctx, GLuint first, GLsizei count, { for (GLsizei i = 0; i < count; i++) set_depth_range_no_notify(ctx, i + first, inputs[i].Near, inputs[i].Far); - - if (ctx->Driver.DepthRange) - ctx->Driver.DepthRange(ctx); } void GLAPIENTRY @@ -419,9 +412,6 @@ _mesa_DepthRangeArrayfvOES(GLuint first, GLsizei count, const GLfloat *v) for (i = 0; i < count; i++) set_depth_range_no_notify(ctx, i + first, v[i * 2], v[i * 2 + 1]); - - if (ctx->Driver.DepthRange) - ctx->Driver.DepthRange(ctx); } /** @@ -520,28 +510,18 @@ clip_control(struct gl_context *ctx, GLenum origin, GLenum depth, bool no_error) } /* Affects transform state and the viewport transform */ - FLUSH_VERTICES(ctx, ctx->DriverFlags.NewClipControl ? 0 : - _NEW_TRANSFORM | _NEW_VIEWPORT, GL_TRANSFORM_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewClipControl; + FLUSH_VERTICES(ctx, 0, GL_TRANSFORM_BIT); + ctx->NewDriverState |= ST_NEW_VIEWPORT | ST_NEW_RASTERIZER; if (ctx->Transform.ClipOrigin != origin) { ctx->Transform.ClipOrigin = origin; /* Affects the winding order of the front face. */ - if (ctx->DriverFlags.NewPolygonState) - ctx->NewDriverState |= ctx->DriverFlags.NewPolygonState; - else - ctx->NewState |= _NEW_POLYGON; - - if (ctx->Driver.FrontFace) - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + ctx->NewDriverState |= ST_NEW_RASTERIZER; } if (ctx->Transform.ClipDepthMode != depth) { ctx->Transform.ClipDepthMode = depth; - - if (ctx->Driver.DepthRange) - ctx->Driver.DepthRange(ctx); } } @@ -620,8 +600,7 @@ subpixel_precision_bias(struct gl_context *ctx, GLuint xbits, GLuint ybits) ctx->SubpixelPrecisionBias[0] = xbits; ctx->SubpixelPrecisionBias[1] = ybits; - ctx->NewDriverState |= - ctx->DriverFlags.NewNvConservativeRasterizationParams; + ctx->NewDriverState |= ST_NEW_RASTERIZER; } void GLAPIENTRY @@ -677,7 +656,7 @@ set_viewport_swizzle(struct gl_context *ctx, GLuint index, return; FLUSH_VERTICES(ctx, _NEW_VIEWPORT, GL_VIEWPORT_BIT); - ctx->NewDriverState |= ctx->DriverFlags.NewViewport; + ctx->NewDriverState |= ST_NEW_VIEWPORT; viewport->SwizzleX = swizzlex; viewport->SwizzleY = swizzley; diff --git a/src/mesa/main/viewport.h b/src/mesa/main/viewport.h index 655873d4774..dac493a0649 100644 --- a/src/mesa/main/viewport.h +++ b/src/mesa/main/viewport.h @@ -27,65 +27,14 @@ #ifndef VIEWPORT_H #define VIEWPORT_H -#include "glheader.h" +#include "util/glheader.h" struct gl_context; -void GLAPIENTRY -_mesa_Viewport_no_error(GLint x, GLint y, GLsizei width, GLsizei height); - -extern void GLAPIENTRY -_mesa_Viewport(GLint x, GLint y, GLsizei width, GLsizei height); - -void GLAPIENTRY -_mesa_ViewportArrayv_no_error(GLuint first, GLsizei count, const GLfloat * v); - -extern void GLAPIENTRY -_mesa_ViewportArrayv(GLuint first, GLsizei count, const GLfloat * v); - -void GLAPIENTRY -_mesa_ViewportIndexedf_no_error(GLuint index, GLfloat x, GLfloat y, GLfloat w, - GLfloat h); - -extern void GLAPIENTRY -_mesa_ViewportIndexedf(GLuint index, GLfloat x, GLfloat y, GLfloat w, GLfloat h); - -void GLAPIENTRY -_mesa_ViewportIndexedfv_no_error(GLuint index, const GLfloat * v); - -extern void GLAPIENTRY -_mesa_ViewportIndexedfv(GLuint index, const GLfloat * v); - extern void _mesa_set_viewport(struct gl_context *ctx, unsigned idx, GLfloat x, GLfloat y, GLfloat width, GLfloat height); - -extern void GLAPIENTRY -_mesa_DepthRange(GLclampd nearval, GLclampd farval); - -extern void GLAPIENTRY -_mesa_DepthRangef(GLclampf nearval, GLclampf farval); - -void GLAPIENTRY -_mesa_DepthRangeArrayv_no_error(GLuint first, GLsizei count, - const GLclampd * v); - -extern void GLAPIENTRY -_mesa_DepthRangeArrayv(GLuint first, GLsizei count, const GLclampd * v); - -extern void GLAPIENTRY -_mesa_DepthRangeArrayfvOES(GLuint first, GLsizei count, const GLfloat * v); - -void GLAPIENTRY -_mesa_DepthRangeIndexed_no_error(GLuint index, GLclampd n, GLclampd f); - -extern void GLAPIENTRY -_mesa_DepthRangeIndexed(GLuint index, GLclampd n, GLclampd f); - -extern void GLAPIENTRY -_mesa_DepthRangeIndexedfOES(GLuint index, GLfloat n, GLfloat f); - extern void _mesa_set_depth_range(struct gl_context *ctx, unsigned idx, GLclampd nearval, GLclampd farval); @@ -93,31 +42,8 @@ _mesa_set_depth_range(struct gl_context *ctx, unsigned idx, extern void _mesa_init_viewport(struct gl_context *ctx); - -void GLAPIENTRY -_mesa_ClipControl_no_error(GLenum origin, GLenum depth); - -extern void GLAPIENTRY -_mesa_ClipControl(GLenum origin, GLenum depth); - extern void _mesa_get_viewport_xform(struct gl_context *ctx, unsigned i, float scale[3], float translate[3]); -extern void GLAPIENTRY -_mesa_SubpixelPrecisionBiasNV_no_error(GLuint xbits, GLuint ybits); - -extern void GLAPIENTRY -_mesa_SubpixelPrecisionBiasNV(GLuint xbits, GLuint ybits); - -extern void GLAPIENTRY -_mesa_ViewportSwizzleNV_no_error(GLuint index, - GLenum swizzlex, GLenum swizzley, - GLenum swizzlez, GLenum swizzlew); - -extern void GLAPIENTRY -_mesa_ViewportSwizzleNV(GLuint index, - GLenum swizzlex, GLenum swizzley, - GLenum swizzlez, GLenum swizzlew); - #endif diff --git a/src/mesa/main/vtxfmt.c b/src/mesa/main/vtxfmt.c deleted file mode 100644 index d2e75d2b0c2..00000000000 --- a/src/mesa/main/vtxfmt.c +++ /dev/null @@ -1,525 +0,0 @@ -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: - * Keith Whitwell <keithw@vmware.com> Gareth Hughes - */ - -#include "glheader.h" -#include "api_arrayelt.h" -#include "context.h" - -#include "mtypes.h" -#include "vtxfmt.h" -#include "eval.h" -#include "dlist.h" -#include "main/dispatch.h" -#include "vbo/vbo.h" - - -/** - * Copy the functions found in the GLvertexformat object into the - * dispatch table. - */ -static void -install_vtxfmt(struct gl_context *ctx, struct _glapi_table *tab, - const GLvertexformat *vfmt) -{ - assert(ctx->Version > 0); - - if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { - SET_Color4f(tab, vfmt->Color4f); - } - - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_install_arrayelt_vtxfmt(tab, vfmt); - SET_Color3f(tab, vfmt->Color3f); - SET_Color3fv(tab, vfmt->Color3fv); - SET_Color4fv(tab, vfmt->Color4fv); - SET_EdgeFlag(tab, vfmt->EdgeFlag); - } - - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_install_eval_vtxfmt(tab, vfmt); - } - - if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { - SET_Materialfv(tab, vfmt->Materialfv); - SET_MultiTexCoord4fARB(tab, vfmt->MultiTexCoord4fARB); - SET_Normal3f(tab, vfmt->Normal3f); - } - - if (ctx->API == API_OPENGL_COMPAT) { - SET_FogCoordfEXT(tab, vfmt->FogCoordfEXT); - SET_FogCoordfvEXT(tab, vfmt->FogCoordfvEXT); - SET_Indexf(tab, vfmt->Indexf); - SET_Indexfv(tab, vfmt->Indexfv); - SET_MultiTexCoord1fARB(tab, vfmt->MultiTexCoord1fARB); - SET_MultiTexCoord1fvARB(tab, vfmt->MultiTexCoord1fvARB); - SET_MultiTexCoord2fARB(tab, vfmt->MultiTexCoord2fARB); - SET_MultiTexCoord2fvARB(tab, vfmt->MultiTexCoord2fvARB); - SET_MultiTexCoord3fARB(tab, vfmt->MultiTexCoord3fARB); - SET_MultiTexCoord3fvARB(tab, vfmt->MultiTexCoord3fvARB); - SET_MultiTexCoord4fvARB(tab, vfmt->MultiTexCoord4fvARB); - SET_Normal3fv(tab, vfmt->Normal3fv); - } - - if (ctx->API == API_OPENGL_COMPAT) { - SET_SecondaryColor3fEXT(tab, vfmt->SecondaryColor3fEXT); - SET_SecondaryColor3fvEXT(tab, vfmt->SecondaryColor3fvEXT); - SET_TexCoord1f(tab, vfmt->TexCoord1f); - SET_TexCoord1fv(tab, vfmt->TexCoord1fv); - SET_TexCoord2f(tab, vfmt->TexCoord2f); - SET_TexCoord2fv(tab, vfmt->TexCoord2fv); - SET_TexCoord3f(tab, vfmt->TexCoord3f); - SET_TexCoord3fv(tab, vfmt->TexCoord3fv); - SET_TexCoord4f(tab, vfmt->TexCoord4f); - SET_TexCoord4fv(tab, vfmt->TexCoord4fv); - SET_Vertex2f(tab, vfmt->Vertex2f); - SET_Vertex2fv(tab, vfmt->Vertex2fv); - SET_Vertex3f(tab, vfmt->Vertex3f); - SET_Vertex3fv(tab, vfmt->Vertex3fv); - SET_Vertex4f(tab, vfmt->Vertex4f); - SET_Vertex4fv(tab, vfmt->Vertex4fv); - } - - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_install_dlist_vtxfmt(tab, vfmt); /* glCallList / glCallLists */ - - SET_Begin(tab, vfmt->Begin); - SET_End(tab, vfmt->End); - SET_PrimitiveRestartNV(tab, vfmt->PrimitiveRestartNV); - } - - /* Originally for GL_NV_vertex_program, this is now only used by dlist.c */ - if (ctx->API == API_OPENGL_COMPAT) { - SET_VertexAttrib1fNV(tab, vfmt->VertexAttrib1fNV); - SET_VertexAttrib1fvNV(tab, vfmt->VertexAttrib1fvNV); - SET_VertexAttrib2fNV(tab, vfmt->VertexAttrib2fNV); - SET_VertexAttrib2fvNV(tab, vfmt->VertexAttrib2fvNV); - SET_VertexAttrib3fNV(tab, vfmt->VertexAttrib3fNV); - SET_VertexAttrib3fvNV(tab, vfmt->VertexAttrib3fvNV); - SET_VertexAttrib4fNV(tab, vfmt->VertexAttrib4fNV); - SET_VertexAttrib4fvNV(tab, vfmt->VertexAttrib4fvNV); - } - - if (ctx->API != API_OPENGLES) { - SET_VertexAttrib1fARB(tab, vfmt->VertexAttrib1fARB); - SET_VertexAttrib1fvARB(tab, vfmt->VertexAttrib1fvARB); - SET_VertexAttrib2fARB(tab, vfmt->VertexAttrib2fARB); - SET_VertexAttrib2fvARB(tab, vfmt->VertexAttrib2fvARB); - SET_VertexAttrib3fARB(tab, vfmt->VertexAttrib3fARB); - SET_VertexAttrib3fvARB(tab, vfmt->VertexAttrib3fvARB); - SET_VertexAttrib4fARB(tab, vfmt->VertexAttrib4fARB); - SET_VertexAttrib4fvARB(tab, vfmt->VertexAttrib4fvARB); - } - - /* GL_EXT_gpu_shader4 / OpenGL 3.0 */ - if (_mesa_is_desktop_gl(ctx)) { - SET_VertexAttribI1iEXT(tab, vfmt->VertexAttribI1i); - SET_VertexAttribI2iEXT(tab, vfmt->VertexAttribI2i); - SET_VertexAttribI3iEXT(tab, vfmt->VertexAttribI3i); - SET_VertexAttribI2ivEXT(tab, vfmt->VertexAttribI2iv); - SET_VertexAttribI3ivEXT(tab, vfmt->VertexAttribI3iv); - - SET_VertexAttribI1uiEXT(tab, vfmt->VertexAttribI1ui); - SET_VertexAttribI2uiEXT(tab, vfmt->VertexAttribI2ui); - SET_VertexAttribI3uiEXT(tab, vfmt->VertexAttribI3ui); - SET_VertexAttribI2uivEXT(tab, vfmt->VertexAttribI2uiv); - SET_VertexAttribI3uivEXT(tab, vfmt->VertexAttribI3uiv); - } - - if (_mesa_is_desktop_gl(ctx) || _mesa_is_gles3(ctx)) { - SET_VertexAttribI4iEXT(tab, vfmt->VertexAttribI4i); - SET_VertexAttribI4ivEXT(tab, vfmt->VertexAttribI4iv); - SET_VertexAttribI4uiEXT(tab, vfmt->VertexAttribI4ui); - SET_VertexAttribI4uivEXT(tab, vfmt->VertexAttribI4uiv); - } - - if (ctx->API == API_OPENGL_COMPAT) { - /* GL_ARB_vertex_type_10_10_10_2_rev / GL 3.3 */ - SET_VertexP2ui(tab, vfmt->VertexP2ui); - SET_VertexP2uiv(tab, vfmt->VertexP2uiv); - SET_VertexP3ui(tab, vfmt->VertexP3ui); - SET_VertexP3uiv(tab, vfmt->VertexP3uiv); - SET_VertexP4ui(tab, vfmt->VertexP4ui); - SET_VertexP4uiv(tab, vfmt->VertexP4uiv); - - SET_TexCoordP1ui(tab, vfmt->TexCoordP1ui); - SET_TexCoordP1uiv(tab, vfmt->TexCoordP1uiv); - SET_TexCoordP2ui(tab, vfmt->TexCoordP2ui); - SET_TexCoordP2uiv(tab, vfmt->TexCoordP2uiv); - SET_TexCoordP3ui(tab, vfmt->TexCoordP3ui); - SET_TexCoordP3uiv(tab, vfmt->TexCoordP3uiv); - SET_TexCoordP4ui(tab, vfmt->TexCoordP4ui); - SET_TexCoordP4uiv(tab, vfmt->TexCoordP4uiv); - - SET_MultiTexCoordP1ui(tab, vfmt->MultiTexCoordP1ui); - SET_MultiTexCoordP2ui(tab, vfmt->MultiTexCoordP2ui); - SET_MultiTexCoordP3ui(tab, vfmt->MultiTexCoordP3ui); - SET_MultiTexCoordP4ui(tab, vfmt->MultiTexCoordP4ui); - SET_MultiTexCoordP1uiv(tab, vfmt->MultiTexCoordP1uiv); - SET_MultiTexCoordP2uiv(tab, vfmt->MultiTexCoordP2uiv); - SET_MultiTexCoordP3uiv(tab, vfmt->MultiTexCoordP3uiv); - SET_MultiTexCoordP4uiv(tab, vfmt->MultiTexCoordP4uiv); - - SET_NormalP3ui(tab, vfmt->NormalP3ui); - SET_NormalP3uiv(tab, vfmt->NormalP3uiv); - - SET_ColorP3ui(tab, vfmt->ColorP3ui); - SET_ColorP4ui(tab, vfmt->ColorP4ui); - SET_ColorP3uiv(tab, vfmt->ColorP3uiv); - SET_ColorP4uiv(tab, vfmt->ColorP4uiv); - - SET_SecondaryColorP3ui(tab, vfmt->SecondaryColorP3ui); - SET_SecondaryColorP3uiv(tab, vfmt->SecondaryColorP3uiv); - - /* GL_NV_half_float */ - SET_Vertex2hNV(tab, vfmt->Vertex2hNV); - SET_Vertex2hvNV(tab, vfmt->Vertex2hvNV); - SET_Vertex3hNV(tab, vfmt->Vertex3hNV); - SET_Vertex3hvNV(tab, vfmt->Vertex3hvNV); - SET_Vertex4hNV(tab, vfmt->Vertex4hNV); - SET_Vertex4hvNV(tab, vfmt->Vertex4hvNV); - SET_Normal3hNV(tab, vfmt->Normal3hNV); - SET_Normal3hvNV(tab, vfmt->Normal3hvNV); - SET_Color3hNV(tab, vfmt->Color3hNV); - SET_Color3hvNV(tab, vfmt->Color4hvNV); - SET_Color4hNV(tab, vfmt->Color4hNV); - SET_Color4hvNV(tab, vfmt->Color3hvNV); - SET_TexCoord1hNV(tab, vfmt->TexCoord1hNV); - SET_TexCoord1hvNV(tab, vfmt->TexCoord1hvNV); - SET_TexCoord2hNV(tab, vfmt->TexCoord2hNV); - SET_TexCoord2hvNV(tab, vfmt->TexCoord2hvNV); - SET_TexCoord3hNV(tab, vfmt->TexCoord3hNV); - SET_TexCoord3hvNV(tab, vfmt->TexCoord3hvNV); - SET_TexCoord4hNV(tab, vfmt->TexCoord4hNV); - SET_TexCoord4hvNV(tab, vfmt->TexCoord4hvNV); - SET_MultiTexCoord1hNV(tab, vfmt->MultiTexCoord1hNV); - SET_MultiTexCoord1hvNV(tab, vfmt->MultiTexCoord1hvNV); - SET_MultiTexCoord2hNV(tab, vfmt->MultiTexCoord2hNV); - SET_MultiTexCoord2hvNV(tab, vfmt->MultiTexCoord2hvNV); - SET_MultiTexCoord3hNV(tab, vfmt->MultiTexCoord3hNV); - SET_MultiTexCoord3hvNV(tab, vfmt->MultiTexCoord3hvNV); - SET_MultiTexCoord4hNV(tab, vfmt->MultiTexCoord4hNV); - SET_MultiTexCoord4hvNV(tab, vfmt->MultiTexCoord4hvNV); - SET_VertexAttrib1hNV(tab, vfmt->VertexAttrib1hNV); - SET_VertexAttrib2hNV(tab, vfmt->VertexAttrib2hNV); - SET_VertexAttrib3hNV(tab, vfmt->VertexAttrib3hNV); - SET_VertexAttrib4hNV(tab, vfmt->VertexAttrib4hNV); - SET_VertexAttrib1hvNV(tab, vfmt->VertexAttrib1hvNV); - SET_VertexAttrib2hvNV(tab, vfmt->VertexAttrib2hvNV); - SET_VertexAttrib3hvNV(tab, vfmt->VertexAttrib3hvNV); - SET_VertexAttrib4hvNV(tab, vfmt->VertexAttrib4hvNV); - SET_VertexAttribs1hvNV(tab, vfmt->VertexAttribs1hvNV); - SET_VertexAttribs2hvNV(tab, vfmt->VertexAttribs2hvNV); - SET_VertexAttribs3hvNV(tab, vfmt->VertexAttribs3hvNV); - SET_VertexAttribs4hvNV(tab, vfmt->VertexAttribs4hvNV); - SET_FogCoordhNV(tab, vfmt->FogCoordhNV); - SET_FogCoordhvNV(tab, vfmt->FogCoordhvNV); - SET_SecondaryColor3hNV(tab, vfmt->SecondaryColor3hNV); - SET_SecondaryColor3hvNV(tab, vfmt->SecondaryColor3hvNV); - } - - if (_mesa_is_desktop_gl(ctx)) { - SET_VertexAttribP1ui(tab, vfmt->VertexAttribP1ui); - SET_VertexAttribP2ui(tab, vfmt->VertexAttribP2ui); - SET_VertexAttribP3ui(tab, vfmt->VertexAttribP3ui); - SET_VertexAttribP4ui(tab, vfmt->VertexAttribP4ui); - - SET_VertexAttribP1uiv(tab, vfmt->VertexAttribP1uiv); - SET_VertexAttribP2uiv(tab, vfmt->VertexAttribP2uiv); - SET_VertexAttribP3uiv(tab, vfmt->VertexAttribP3uiv); - SET_VertexAttribP4uiv(tab, vfmt->VertexAttribP4uiv); - - /* GL_ARB_bindless_texture */ - SET_VertexAttribL1ui64ARB(tab, vfmt->VertexAttribL1ui64ARB); - SET_VertexAttribL1ui64vARB(tab, vfmt->VertexAttribL1ui64vARB); - } - - if (_mesa_is_desktop_gl(ctx)) { - /* GL_ARB_vertex_attrib_64bit */ - SET_VertexAttribL1d(tab, vfmt->VertexAttribL1d); - SET_VertexAttribL2d(tab, vfmt->VertexAttribL2d); - SET_VertexAttribL3d(tab, vfmt->VertexAttribL3d); - SET_VertexAttribL4d(tab, vfmt->VertexAttribL4d); - - SET_VertexAttribL1dv(tab, vfmt->VertexAttribL1dv); - SET_VertexAttribL2dv(tab, vfmt->VertexAttribL2dv); - SET_VertexAttribL3dv(tab, vfmt->VertexAttribL3dv); - SET_VertexAttribL4dv(tab, vfmt->VertexAttribL4dv); - } - - if (ctx->API != API_OPENGL_CORE && ctx->API != API_OPENGLES2) { - SET_Color4ub(tab, vfmt->Color4ub); - SET_Materialf(tab, vfmt->Materialf); - } - if (ctx->API == API_OPENGL_COMPAT) { - SET_Color3b(tab, vfmt->Color3b); - SET_Color3d(tab, vfmt->Color3d); - SET_Color3i(tab, vfmt->Color3i); - SET_Color3s(tab, vfmt->Color3s); - SET_Color3ui(tab, vfmt->Color3ui); - SET_Color3us(tab, vfmt->Color3us); - SET_Color3ub(tab, vfmt->Color3ub); - SET_Color4b(tab, vfmt->Color4b); - SET_Color4d(tab, vfmt->Color4d); - SET_Color4i(tab, vfmt->Color4i); - SET_Color4s(tab, vfmt->Color4s); - SET_Color4ui(tab, vfmt->Color4ui); - SET_Color4us(tab, vfmt->Color4us); - SET_Color3bv(tab, vfmt->Color3bv); - SET_Color3dv(tab, vfmt->Color3dv); - SET_Color3iv(tab, vfmt->Color3iv); - SET_Color3sv(tab, vfmt->Color3sv); - SET_Color3uiv(tab, vfmt->Color3uiv); - SET_Color3usv(tab, vfmt->Color3usv); - SET_Color3ubv(tab, vfmt->Color3ubv); - SET_Color4bv(tab, vfmt->Color4bv); - SET_Color4dv(tab, vfmt->Color4dv); - SET_Color4iv(tab, vfmt->Color4iv); - SET_Color4sv(tab, vfmt->Color4sv); - SET_Color4uiv(tab, vfmt->Color4uiv); - SET_Color4usv(tab, vfmt->Color4usv); - SET_Color4ubv(tab, vfmt->Color4ubv); - - SET_SecondaryColor3b(tab, vfmt->SecondaryColor3b); - SET_SecondaryColor3d(tab, vfmt->SecondaryColor3d); - SET_SecondaryColor3i(tab, vfmt->SecondaryColor3i); - SET_SecondaryColor3s(tab, vfmt->SecondaryColor3s); - SET_SecondaryColor3ui(tab, vfmt->SecondaryColor3ui); - SET_SecondaryColor3us(tab, vfmt->SecondaryColor3us); - SET_SecondaryColor3ub(tab, vfmt->SecondaryColor3ub); - SET_SecondaryColor3bv(tab, vfmt->SecondaryColor3bv); - SET_SecondaryColor3dv(tab, vfmt->SecondaryColor3dv); - SET_SecondaryColor3iv(tab, vfmt->SecondaryColor3iv); - SET_SecondaryColor3sv(tab, vfmt->SecondaryColor3sv); - SET_SecondaryColor3uiv(tab, vfmt->SecondaryColor3uiv); - SET_SecondaryColor3usv(tab, vfmt->SecondaryColor3usv); - SET_SecondaryColor3ubv(tab, vfmt->SecondaryColor3ubv); - - SET_EdgeFlagv(tab, vfmt->EdgeFlagv); - - SET_Indexd(tab, vfmt->Indexd); - SET_Indexi(tab, vfmt->Indexi); - SET_Indexs(tab, vfmt->Indexs); - SET_Indexub(tab, vfmt->Indexub); - SET_Indexdv(tab, vfmt->Indexdv); - SET_Indexiv(tab, vfmt->Indexiv); - SET_Indexsv(tab, vfmt->Indexsv); - SET_Indexubv(tab, vfmt->Indexubv); - SET_Normal3b(tab, vfmt->Normal3b); - SET_Normal3d(tab, vfmt->Normal3d); - SET_Normal3i(tab, vfmt->Normal3i); - SET_Normal3s(tab, vfmt->Normal3s); - SET_Normal3bv(tab, vfmt->Normal3bv); - SET_Normal3dv(tab, vfmt->Normal3dv); - SET_Normal3iv(tab, vfmt->Normal3iv); - SET_Normal3sv(tab, vfmt->Normal3sv); - SET_TexCoord1d(tab, vfmt->TexCoord1d); - SET_TexCoord1i(tab, vfmt->TexCoord1i); - SET_TexCoord1s(tab, vfmt->TexCoord1s); - SET_TexCoord2d(tab, vfmt->TexCoord2d); - SET_TexCoord2s(tab, vfmt->TexCoord2s); - SET_TexCoord2i(tab, vfmt->TexCoord2i); - SET_TexCoord3d(tab, vfmt->TexCoord3d); - SET_TexCoord3i(tab, vfmt->TexCoord3i); - SET_TexCoord3s(tab, vfmt->TexCoord3s); - SET_TexCoord4d(tab, vfmt->TexCoord4d); - SET_TexCoord4i(tab, vfmt->TexCoord4i); - SET_TexCoord4s(tab, vfmt->TexCoord4s); - SET_TexCoord1dv(tab, vfmt->TexCoord1dv); - SET_TexCoord1iv(tab, vfmt->TexCoord1iv); - SET_TexCoord1sv(tab, vfmt->TexCoord1sv); - SET_TexCoord2dv(tab, vfmt->TexCoord2dv); - SET_TexCoord2iv(tab, vfmt->TexCoord2iv); - SET_TexCoord2sv(tab, vfmt->TexCoord2sv); - SET_TexCoord3dv(tab, vfmt->TexCoord3dv); - SET_TexCoord3iv(tab, vfmt->TexCoord3iv); - SET_TexCoord3sv(tab, vfmt->TexCoord3sv); - SET_TexCoord4dv(tab, vfmt->TexCoord4dv); - SET_TexCoord4iv(tab, vfmt->TexCoord4iv); - SET_TexCoord4sv(tab, vfmt->TexCoord4sv); - SET_Vertex2d(tab, vfmt->Vertex2d); - SET_Vertex2i(tab, vfmt->Vertex2i); - SET_Vertex2s(tab, vfmt->Vertex2s); - SET_Vertex3d(tab, vfmt->Vertex3d); - SET_Vertex3i(tab, vfmt->Vertex3i); - SET_Vertex3s(tab, vfmt->Vertex3s); - SET_Vertex4d(tab, vfmt->Vertex4d); - SET_Vertex4i(tab, vfmt->Vertex4i); - SET_Vertex4s(tab, vfmt->Vertex4s); - SET_Vertex2dv(tab, vfmt->Vertex2dv); - SET_Vertex2iv(tab, vfmt->Vertex2iv); - SET_Vertex2sv(tab, vfmt->Vertex2sv); - SET_Vertex3dv(tab, vfmt->Vertex3dv); - SET_Vertex3iv(tab, vfmt->Vertex3iv); - SET_Vertex3sv(tab, vfmt->Vertex3sv); - SET_Vertex4dv(tab, vfmt->Vertex4dv); - SET_Vertex4iv(tab, vfmt->Vertex4iv); - SET_Vertex4sv(tab, vfmt->Vertex4sv); - SET_MultiTexCoord1d(tab, vfmt->MultiTexCoord1d); - SET_MultiTexCoord1dv(tab, vfmt->MultiTexCoord1dv); - SET_MultiTexCoord1i(tab, vfmt->MultiTexCoord1i); - SET_MultiTexCoord1iv(tab, vfmt->MultiTexCoord1iv); - SET_MultiTexCoord1s(tab, vfmt->MultiTexCoord1s); - SET_MultiTexCoord1sv(tab, vfmt->MultiTexCoord1sv); - SET_MultiTexCoord2d(tab, vfmt->MultiTexCoord2d); - SET_MultiTexCoord2dv(tab, vfmt->MultiTexCoord2dv); - SET_MultiTexCoord2i(tab, vfmt->MultiTexCoord2i); - SET_MultiTexCoord2iv(tab, vfmt->MultiTexCoord2iv); - SET_MultiTexCoord2s(tab, vfmt->MultiTexCoord2s); - SET_MultiTexCoord2sv(tab, vfmt->MultiTexCoord2sv); - SET_MultiTexCoord3d(tab, vfmt->MultiTexCoord3d); - SET_MultiTexCoord3dv(tab, vfmt->MultiTexCoord3dv); - SET_MultiTexCoord3i(tab, vfmt->MultiTexCoord3i); - SET_MultiTexCoord3iv(tab, vfmt->MultiTexCoord3iv); - SET_MultiTexCoord3s(tab, vfmt->MultiTexCoord3s); - SET_MultiTexCoord3sv(tab, vfmt->MultiTexCoord3sv); - SET_MultiTexCoord4d(tab, vfmt->MultiTexCoord4d); - SET_MultiTexCoord4dv(tab, vfmt->MultiTexCoord4dv); - SET_MultiTexCoord4i(tab, vfmt->MultiTexCoord4i); - SET_MultiTexCoord4iv(tab, vfmt->MultiTexCoord4iv); - SET_MultiTexCoord4s(tab, vfmt->MultiTexCoord4s); - SET_MultiTexCoord4sv(tab, vfmt->MultiTexCoord4sv); - SET_EvalCoord2dv(tab, vfmt->EvalCoord2dv); - SET_EvalCoord2d(tab, vfmt->EvalCoord2d); - SET_EvalCoord1dv(tab, vfmt->EvalCoord1dv); - SET_EvalCoord1d(tab, vfmt->EvalCoord1d); - SET_Materiali(tab, vfmt->Materiali); - SET_Materialiv(tab, vfmt->Materialiv); - SET_FogCoordd(tab, vfmt->FogCoordd); - SET_FogCoorddv(tab, vfmt->FogCoorddv); - - SET_VertexAttrib1sNV(tab, vfmt->VertexAttrib1sNV); - SET_VertexAttrib1dNV(tab, vfmt->VertexAttrib1dNV); - SET_VertexAttrib2sNV(tab, vfmt->VertexAttrib2sNV); - SET_VertexAttrib2dNV(tab, vfmt->VertexAttrib2dNV); - SET_VertexAttrib3sNV(tab, vfmt->VertexAttrib3sNV); - SET_VertexAttrib3dNV(tab, vfmt->VertexAttrib3dNV); - SET_VertexAttrib4sNV(tab, vfmt->VertexAttrib4sNV); - SET_VertexAttrib4dNV(tab, vfmt->VertexAttrib4dNV); - SET_VertexAttrib4ubNV(tab, vfmt->VertexAttrib4ubNV); - SET_VertexAttrib1svNV(tab, vfmt->VertexAttrib1svNV); - SET_VertexAttrib1dvNV(tab, vfmt->VertexAttrib1dvNV); - SET_VertexAttrib2svNV(tab, vfmt->VertexAttrib2svNV); - SET_VertexAttrib2dvNV(tab, vfmt->VertexAttrib2dvNV); - SET_VertexAttrib3svNV(tab, vfmt->VertexAttrib3svNV); - SET_VertexAttrib3dvNV(tab, vfmt->VertexAttrib3dvNV); - SET_VertexAttrib4svNV(tab, vfmt->VertexAttrib4svNV); - SET_VertexAttrib4dvNV(tab, vfmt->VertexAttrib4dvNV); - SET_VertexAttrib4ubvNV(tab, vfmt->VertexAttrib4ubvNV); - SET_VertexAttribs1svNV(tab, vfmt->VertexAttribs1svNV); - SET_VertexAttribs1fvNV(tab, vfmt->VertexAttribs1fvNV); - SET_VertexAttribs1dvNV(tab, vfmt->VertexAttribs1dvNV); - SET_VertexAttribs2svNV(tab, vfmt->VertexAttribs2svNV); - SET_VertexAttribs2fvNV(tab, vfmt->VertexAttribs2fvNV); - SET_VertexAttribs2dvNV(tab, vfmt->VertexAttribs2dvNV); - SET_VertexAttribs3svNV(tab, vfmt->VertexAttribs3svNV); - SET_VertexAttribs3fvNV(tab, vfmt->VertexAttribs3fvNV); - SET_VertexAttribs3dvNV(tab, vfmt->VertexAttribs3dvNV); - SET_VertexAttribs4svNV(tab, vfmt->VertexAttribs4svNV); - SET_VertexAttribs4fvNV(tab, vfmt->VertexAttribs4fvNV); - SET_VertexAttribs4dvNV(tab, vfmt->VertexAttribs4dvNV); - SET_VertexAttribs4ubvNV(tab, vfmt->VertexAttribs4ubvNV); - } - - if (_mesa_is_desktop_gl(ctx)) { - SET_VertexAttrib1s(tab, vfmt->VertexAttrib1s); - SET_VertexAttrib1d(tab, vfmt->VertexAttrib1d); - SET_VertexAttrib2s(tab, vfmt->VertexAttrib2s); - SET_VertexAttrib2d(tab, vfmt->VertexAttrib2d); - SET_VertexAttrib3s(tab, vfmt->VertexAttrib3s); - SET_VertexAttrib3d(tab, vfmt->VertexAttrib3d); - SET_VertexAttrib4s(tab, vfmt->VertexAttrib4s); - SET_VertexAttrib4d(tab, vfmt->VertexAttrib4d); - SET_VertexAttrib1sv(tab, vfmt->VertexAttrib1sv); - SET_VertexAttrib1dv(tab, vfmt->VertexAttrib1dv); - SET_VertexAttrib2sv(tab, vfmt->VertexAttrib2sv); - SET_VertexAttrib2dv(tab, vfmt->VertexAttrib2dv); - SET_VertexAttrib3sv(tab, vfmt->VertexAttrib3sv); - SET_VertexAttrib3dv(tab, vfmt->VertexAttrib3dv); - SET_VertexAttrib4sv(tab, vfmt->VertexAttrib4sv); - SET_VertexAttrib4dv(tab, vfmt->VertexAttrib4dv); - SET_VertexAttrib4Nub(tab, vfmt->VertexAttrib4Nub); - SET_VertexAttrib4Nubv(tab, vfmt->VertexAttrib4Nubv); - SET_VertexAttrib4bv(tab, vfmt->VertexAttrib4bv); - SET_VertexAttrib4iv(tab, vfmt->VertexAttrib4iv); - SET_VertexAttrib4ubv(tab, vfmt->VertexAttrib4ubv); - SET_VertexAttrib4usv(tab, vfmt->VertexAttrib4usv); - SET_VertexAttrib4uiv(tab, vfmt->VertexAttrib4uiv); - SET_VertexAttrib4Nbv(tab, vfmt->VertexAttrib4Nbv); - SET_VertexAttrib4Nsv(tab, vfmt->VertexAttrib4Nsv); - SET_VertexAttrib4Nusv(tab, vfmt->VertexAttrib4Nusv); - SET_VertexAttrib4Niv(tab, vfmt->VertexAttrib4Niv); - SET_VertexAttrib4Nuiv(tab, vfmt->VertexAttrib4Nuiv); - - /* GL_EXT_gpu_shader4, GL 3.0 */ - SET_VertexAttribI1iv(tab, vfmt->VertexAttribI1iv); - SET_VertexAttribI1uiv(tab, vfmt->VertexAttribI1uiv); - SET_VertexAttribI4bv(tab, vfmt->VertexAttribI4bv); - SET_VertexAttribI4sv(tab, vfmt->VertexAttribI4sv); - SET_VertexAttribI4ubv(tab, vfmt->VertexAttribI4ubv); - SET_VertexAttribI4usv(tab, vfmt->VertexAttribI4usv); - } -} - - -/** - * Install per-vertex functions into the API dispatch table for execution. - */ -void -_mesa_install_exec_vtxfmt(struct gl_context *ctx, const GLvertexformat *vfmt) -{ - install_vtxfmt(ctx, ctx->Exec, vfmt); - if (ctx->BeginEnd) - install_vtxfmt(ctx, ctx->BeginEnd, vfmt); -} - - -/** - * Install per-vertex functions into the API dispatch table for display - * list compilation. - */ -void -_mesa_install_save_vtxfmt(struct gl_context *ctx, const GLvertexformat *vfmt) -{ - if (_mesa_is_desktop_gl(ctx)) - install_vtxfmt(ctx, ctx->Save, vfmt); -} - - -/** - * Install VBO vtxfmt functions. - * - * This function depends on ctx->Version. - */ -void -_mesa_initialize_vbo_vtxfmt(struct gl_context *ctx) -{ - _vbo_install_exec_vtxfmt(ctx); - if (ctx->API == API_OPENGL_COMPAT) { - _mesa_install_save_vtxfmt(ctx, &ctx->ListState.ListVtxfmt); - } -} - diff --git a/src/mesa/main/vtxfmt.h b/src/mesa/main/vtxfmt.h deleted file mode 100644 index 20fc4667019..00000000000 --- a/src/mesa/main/vtxfmt.h +++ /dev/null @@ -1,52 +0,0 @@ -/** - * \file vtxfmt.h - * - * \author Keith Whitwell <keithw@vmware.com> - * \author Gareth Hughes - */ - -/* - * Mesa 3-D graphics library - * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - */ - - -#ifndef _VTXFMT_H_ -#define _VTXFMT_H_ - -#include "dd.h" - -#ifdef __cplusplus -extern "C" { -#endif - -struct gl_context; - -extern void _mesa_install_exec_vtxfmt( struct gl_context *ctx, const GLvertexformat *vfmt ); -extern void _mesa_install_save_vtxfmt( struct gl_context *ctx, const GLvertexformat *vfmt ); -extern void _mesa_initialize_vbo_vtxfmt(struct gl_context *ctx); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif /* _VTXFMT_H_ */ |