diff options
Diffstat (limited to 'mesalib/src/mesa/main')
22 files changed, 567 insertions, 334 deletions
diff --git a/mesalib/src/mesa/main/api_arrayelt.c b/mesalib/src/mesa/main/api_arrayelt.c index 05cbc0f1f..ebeba8883 100644 --- a/mesalib/src/mesa/main/api_arrayelt.c +++ b/mesalib/src/mesa/main/api_arrayelt.c @@ -43,18 +43,21 @@ #include "macros.h" #include "mtypes.h" #include "main/dispatch.h" +#include "varray.h" typedef void (GLAPIENTRY *array_func)( const void * ); typedef struct { - const struct gl_client_array *array; + const struct gl_vertex_attrib_array *array; + const struct gl_vertex_buffer_binding *binding; int offset; } AEarray; typedef void (GLAPIENTRY *attrib_func)( GLuint indx, const void *data ); typedef struct { - const struct gl_client_array *array; + const struct gl_vertex_attrib_array *array; + const struct gl_vertex_buffer_binding *binding; attrib_func func; GLuint index; } AEattrib; @@ -1470,18 +1473,6 @@ check_vbo(AEcontext *actx, struct gl_buffer_object *vbo) } -static inline void -update_derived_client_arrays(struct gl_context *ctx) -{ - struct gl_vertex_array_object *vao = ctx->Array.VAO; - - if (vao->NewArrays) { - _mesa_update_vao_client_arrays(ctx, vao); - vao->NewArrays = 0; - } -} - - /** * Make a list of per-vertex functions to call for each glArrayElement call. * These functions access the array data (i.e. glVertex, glColor, glNormal, @@ -1500,67 +1491,81 @@ _ae_update_state(struct gl_context *ctx) actx->nr_vbos = 0; /* conventional vertex arrays */ - if (vao->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_COLOR_INDEX]; + if (vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR_INDEX]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = IndexFuncs[TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } - if (vao->_VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_EDGEFLAG]; + + if (vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_EDGEFLAG]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = _gloffset_EdgeFlagv; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } - if (vao->_VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_NORMAL]; + + if (vao->VertexAttrib[VERT_ATTRIB_NORMAL].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_NORMAL]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = NormalFuncs[TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } - if (vao->_VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_COLOR0]; + + if (vao->VertexAttrib[VERT_ATTRIB_COLOR0].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR0]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = ColorFuncs[aa->array->Size-3][TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } - if (vao->_VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_COLOR1]; + + if (vao->VertexAttrib[VERT_ATTRIB_COLOR1].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_COLOR1]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = SecondaryColorFuncs[TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } - if (vao->_VertexAttrib[VERT_ATTRIB_FOG].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_FOG]; + + if (vao->VertexAttrib[VERT_ATTRIB_FOG].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_FOG]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = FogCoordFuncs[TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - struct gl_client_array *attribArray = - &vao->_VertexAttrib[VERT_ATTRIB_TEX(i)]; + struct gl_vertex_attrib_array *attribArray = + &vao->VertexAttrib[VERT_ATTRIB_TEX(i)]; if (attribArray->Enabled) { /* NOTE: we use generic glVertexAttribNV functions here. * If we ever remove GL_NV_vertex_program this will have to change. */ at->array = attribArray; + at->binding = &vao->VertexBinding[attribArray->VertexBinding]; ASSERT(!at->array->Normalized); at->func = AttribFuncsNV[at->array->Normalized] [at->array->Size-1] [TYPE_IDX(at->array->Type)]; at->index = VERT_ATTRIB_TEX0 + i; - check_vbo(actx, at->array->BufferObj); + check_vbo(actx, at->binding->BufferObj); at++; } } /* generic vertex attribute arrays */ for (i = 1; i < VERT_ATTRIB_GENERIC_MAX; i++) { /* skip zero! */ - struct gl_client_array *attribArray = - &vao->_VertexAttrib[VERT_ATTRIB_GENERIC(i)]; + struct gl_vertex_attrib_array *attribArray = + &vao->VertexAttrib[VERT_ATTRIB_GENERIC(i)]; if (attribArray->Enabled) { GLint intOrNorm; at->array = attribArray; + at->binding = &vao->VertexBinding[attribArray->VertexBinding]; /* Note: we can't grab the _glapi_Dispatch->VertexAttrib1fvNV * function pointer here (for float arrays) since the pointer may * change from one execution of _ae_ArrayElement() to @@ -1578,26 +1583,28 @@ _ae_update_state(struct gl_context *ctx) [TYPE_IDX(at->array->Type)]; at->index = i; - check_vbo(actx, at->array->BufferObj); + check_vbo(actx, at->binding->BufferObj); at++; } } /* finally, vertex position */ - if (vao->_VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) { + if (vao->VertexAttrib[VERT_ATTRIB_GENERIC0].Enabled) { /* Use glVertex(v) instead of glVertexAttrib(0, v) to be sure it's * issued as the last (provoking) attribute). */ - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_GENERIC0]; + aa->array = &vao->VertexAttrib[VERT_ATTRIB_GENERIC0]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; assert(aa->array->Size >= 2); /* XXX fix someday? */ aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } - else if (vao->_VertexAttrib[VERT_ATTRIB_POS].Enabled) { - aa->array = &vao->_VertexAttrib[VERT_ATTRIB_POS]; + else if (vao->VertexAttrib[VERT_ATTRIB_POS].Enabled) { + aa->array = &vao->VertexAttrib[VERT_ATTRIB_POS]; + aa->binding = &vao->VertexBinding[aa->array->VertexBinding]; aa->offset = VertexFuncs[aa->array->Size-2][TYPE_IDX(aa->array->Type)]; - check_vbo(actx, aa->array->BufferObj); + check_vbo(actx, aa->binding->BufferObj); aa++; } @@ -1625,8 +1632,6 @@ _ae_map_vbos(struct gl_context *ctx) if (actx->mapped_vbos) return; - update_derived_client_arrays(ctx); - if (actx->NewState) _ae_update_state(ctx); @@ -1679,8 +1684,6 @@ _ae_ArrayElement(GLint elt) const struct _glapi_table * const disp = GET_DISPATCH(); GLboolean do_map; - update_derived_client_arrays(ctx); - /* If PrimitiveRestart is enabled and the index is the RestartIndex * then we call PrimitiveRestartNV and return. */ @@ -1703,18 +1706,18 @@ _ae_ArrayElement(GLint elt) /* emit generic attribute elements */ for (at = actx->attribs; at->func; at++) { const GLubyte *src - = ADD_POINTERS(at->array->BufferObj->Mappings[MAP_INTERNAL].Pointer, - at->array->Ptr) - + elt * at->array->StrideB; + = ADD_POINTERS(at->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer, + _mesa_vertex_attrib_address(at->array, at->binding)) + + elt * at->binding->Stride; at->func(at->index, src); } /* emit conventional arrays elements */ for (aa = actx->arrays; aa->offset != -1 ; aa++) { const GLubyte *src - = ADD_POINTERS(aa->array->BufferObj->Mappings[MAP_INTERNAL].Pointer, - aa->array->Ptr) - + elt * aa->array->StrideB; + = ADD_POINTERS(aa->binding->BufferObj->Mappings[MAP_INTERNAL].Pointer, + _mesa_vertex_attrib_address(aa->array, aa->binding)) + + elt * aa->binding->Stride; CALL_by_offset(disp, (array_func), aa->offset, ((const void *) src)); } diff --git a/mesalib/src/mesa/main/clear.c b/mesalib/src/mesa/main/clear.c index 9df1f5e09..cf93418d1 100644 --- a/mesalib/src/mesa/main/clear.c +++ b/mesalib/src/mesa/main/clear.c @@ -180,11 +180,6 @@ _mesa_Clear( GLbitfield mask ) return; } - if (ctx->DrawBuffer->Width == 0 || ctx->DrawBuffer->Height == 0 || - ctx->DrawBuffer->_Xmin >= ctx->DrawBuffer->_Xmax || - ctx->DrawBuffer->_Ymin >= ctx->DrawBuffer->_Ymax) - return; - if (ctx->RasterDiscard) return; diff --git a/mesalib/src/mesa/main/context.c b/mesalib/src/mesa/main/context.c index 8eb426d59..244e63ede 100644 --- a/mesalib/src/mesa/main/context.c +++ b/mesalib/src/mesa/main/context.c @@ -396,6 +396,8 @@ one_time_init( struct gl_context *ctx ) assert( sizeof(GLint) == 4 ); assert( sizeof(GLuint) == 4 ); + _mesa_one_time_init_extension_overrides(); + _mesa_get_cpu_features(); for (i = 0; i < 256; i++) { @@ -610,6 +612,10 @@ _mesa_init_constants(struct gl_context *ctx) ctx->Const.MaxUniformBlockSize = 16384; ctx->Const.UniformBufferOffsetAlignment = 1; + /* GL_ARB_explicit_uniform_location, GL_MAX_UNIFORM_LOCATIONS */ + ctx->Const.MaxUserAssignableUniformLocations = + 4 * MESA_SHADER_STAGES * MAX_UNIFORMS; + for (i = 0; i < MESA_SHADER_STAGES; i++) init_program_limits(ctx, i, &ctx->Const.Program[i]); diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c index c2ff7e3b7..25e3dab4f 100644 --- a/mesalib/src/mesa/main/extensions.c +++ b/mesalib/src/mesa/main/extensions.c @@ -37,6 +37,11 @@ #include "macros.h" #include "mtypes.h" +struct gl_extensions _mesa_extension_override_enables; +struct gl_extensions _mesa_extension_override_disables; +static char *extra_extensions = NULL; +static char *cant_disable_extensions = NULL; + enum { DISABLE = 0, GLL = 1 << API_OPENGL_COMPAT, /* GL Legacy / Compatibility */ @@ -86,6 +91,7 @@ static const struct extension extension_table[] = { { "GL_ARB_buffer_storage", o(ARB_buffer_storage), GL, 2013 }, { "GL_ARB_clear_buffer_object", o(dummy_true), GL, 2012 }, { "GL_ARB_color_buffer_float", o(ARB_color_buffer_float), GL, 2004 }, + { "GL_ARB_compressed_texture_pixel_storage", o(dummy_true), GL, 2011 }, { "GL_ARB_compute_shader", o(ARB_compute_shader), GL, 2012 }, { "GL_ARB_copy_buffer", o(dummy_true), GL, 2008 }, { "GL_ARB_conservative_depth", o(ARB_conservative_depth), GL, 2011 }, @@ -99,7 +105,9 @@ static const struct extension extension_table[] = { { "GL_ARB_draw_indirect", o(ARB_draw_indirect), GLC, 2010 }, { "GL_ARB_draw_instanced", o(ARB_draw_instanced), GL, 2008 }, { "GL_ARB_explicit_attrib_location", o(ARB_explicit_attrib_location), GL, 2009 }, + { "GL_ARB_explicit_uniform_location", o(ARB_explicit_uniform_location), GL, 2012 }, { "GL_ARB_fragment_coord_conventions", o(ARB_fragment_coord_conventions), GL, 2009 }, + { "GL_ARB_fragment_layer_viewport", o(ARB_fragment_layer_viewport), GLC, 2012 }, { "GL_ARB_fragment_program", o(ARB_fragment_program), GLL, 2002 }, { "GL_ARB_fragment_program_shadow", o(ARB_fragment_program_shadow), GLL, 2003 }, { "GL_ARB_fragment_shader", o(ARB_fragment_shader), GL, 2002 }, @@ -388,6 +396,31 @@ name_to_offset(const char* name) return 0; } +/** + * Overrides extensions in \c ctx based on the values in + * _mesa_extension_override_enables and _mesa_extension_override_disables. + */ +static void +override_extensions_in_context(struct gl_context *ctx) +{ + const struct extension *i; + const GLboolean *enables = + (GLboolean*) &_mesa_extension_override_enables; + const GLboolean *disables = + (GLboolean*) &_mesa_extension_override_disables; + GLboolean *ctx_ext = (GLboolean*)&ctx->Extensions; + + for (i = extension_table; i->name != 0; ++i) { + size_t offset = i->offset; + assert(!enables[offset] || !disables[offset]); + if (enables[offset]) { + ctx_ext[offset] = 1; + } else if (disables[offset]) { + ctx_ext[offset] = 0; + } + } +} + /** * Enable all extensions suitable for a software-only renderer. @@ -473,34 +506,19 @@ _mesa_enable_sw_extensions(struct gl_context *ctx) /** * Either enable or disable the named extension. - * \return GL_TRUE for success, GL_FALSE if invalid extension name + * \return offset of extensions withint `ext' or 0 if extension is not known */ -static GLboolean -set_extension( struct gl_context *ctx, const char *name, GLboolean state ) +static size_t +set_extension(struct gl_extensions *ext, const char *name, GLboolean state) { size_t offset; - if (ctx->Extensions.String) { - /* The string was already queried - can't change it now! */ - _mesa_problem(ctx, "Trying to enable/disable extension after " - "glGetString(GL_EXTENSIONS): %s", name); - return GL_FALSE; - } - offset = name_to_offset(name); - if (offset == 0) { - _mesa_problem(ctx, "Trying to enable/disable unknown extension %s", - name); - return GL_FALSE; - } else if (offset == o(dummy_true) && state == GL_FALSE) { - _mesa_problem(ctx, "Trying to disable a permanently enabled extension: " - "%s", name); - return GL_FALSE; - } else { - GLboolean *base = (GLboolean *) &ctx->Extensions; - base[offset] = state; - return GL_TRUE; + if (offset != 0 && (offset != o(dummy_true) || state != GL_FALSE)) { + ((GLboolean *) ext)[offset] = state; } + + return offset; } /** @@ -513,32 +531,80 @@ set_extension( struct gl_context *ctx, const char *name, GLboolean state ) * - Enable recognized extension names that are not prefixed. * - Collect unrecognized extension names in a new string. * + * \c MESA_EXTENSION_OVERRIDE was previously parsed during + * _mesa_one_time_init_extension_overrides. We just use the results of that + * parsing in this function. + * * \return Space-separated list of unrecognized extension names (which must * be freed). Does not return \c NULL. */ static char * get_extension_override( struct gl_context *ctx ) { + override_extensions_in_context(ctx); + + if (cant_disable_extensions != NULL) { + _mesa_problem(ctx, + "Trying to disable permanently enabled extensions: %s", + cant_disable_extensions); + } + + if (extra_extensions == NULL) { + return calloc(1, sizeof(char)); + } else { + _mesa_problem(ctx, "Trying to enable unknown extensions: %s", + extra_extensions); + return strdup(extra_extensions); + } +} + + +/** + * \brief Free extra_extensions and cant_disable_extensions strings + * + * These strings are allocated early during the first context creation by + * _mesa_one_time_init_extension_overrides. + */ +static void +free_unknown_extensions_strings(void) +{ + free(extra_extensions); + free(cant_disable_extensions); +} + + +/** + * \brief Initialize extension override tables. + * + * This should be called one time early during first context initialization. + */ +void +_mesa_one_time_init_extension_overrides(void) +{ const char *env_const = _mesa_getenv("MESA_EXTENSION_OVERRIDE"); char *env; char *ext; - char *extra_exts; int len; + size_t offset; + + atexit(free_unknown_extensions_strings); + + memset(&_mesa_extension_override_enables, 0, sizeof(struct gl_extensions)); + memset(&_mesa_extension_override_disables, 0, sizeof(struct gl_extensions)); if (env_const == NULL) { - /* Return the empty string rather than NULL. This simplifies the logic - * of client functions. */ - return calloc(4, sizeof(char)); + return; } /* extra_exts: List of unrecognized extensions. */ - extra_exts = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char)); + extra_extensions = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char)); + cant_disable_extensions = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char)); /* Copy env_const because strtok() is destructive. */ env = strdup(env_const); for (ext = strtok(env, " "); ext != NULL; ext = strtok(NULL, " ")) { int enable; - int recognized; + bool recognized; switch (ext[0]) { case '+': enable = 1; @@ -552,21 +618,43 @@ get_extension_override( struct gl_context *ctx ) enable = 1; break; } - recognized = set_extension(ctx, ext, enable); + + offset = set_extension(&_mesa_extension_override_enables, ext, enable); + if (offset != 0 && (offset != o(dummy_true) || enable != GL_FALSE)) { + ((GLboolean *) &_mesa_extension_override_disables)[offset] = !enable; + recognized = true; + } else { + recognized = false; + } + if (!recognized) { - strcat(extra_exts, ext); - strcat(extra_exts, " "); + if (enable) { + strcat(extra_extensions, ext); + strcat(extra_extensions, " "); + } else if (offset == o(dummy_true)) { + strcat(cant_disable_extensions, ext); + strcat(cant_disable_extensions, " "); + } } } free(env); - /* Remove trailing space. */ - len = strlen(extra_exts); - if (len > 0 && extra_exts[len - 1] == ' ') - extra_exts[len - 1] = '\0'; - - return extra_exts; + /* Remove trailing space, and free if unused. */ + len = strlen(extra_extensions); + if (len == 0) { + free(extra_extensions); + extra_extensions = NULL; + } else if (extra_extensions[len - 1] == ' ') { + extra_extensions[len - 1] = '\0'; + } + len = strlen(cant_disable_extensions); + if (len == 0) { + free(cant_disable_extensions); + cant_disable_extensions = NULL; + } else if (cant_disable_extensions[len - 1] == ' ') { + cant_disable_extensions[len - 1] = '\0'; + } } diff --git a/mesalib/src/mesa/main/extensions.h b/mesalib/src/mesa/main/extensions.h index a8cc2a41e..3a404d2e0 100644 --- a/mesalib/src/mesa/main/extensions.h +++ b/mesalib/src/mesa/main/extensions.h @@ -39,9 +39,12 @@ #include "glheader.h" 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_init_extensions(struct gl_context *ctx); extern GLubyte *_mesa_make_extension_string(struct gl_context *ctx); @@ -52,4 +55,7 @@ _mesa_get_extension_count(struct gl_context *ctx); extern const GLubyte * _mesa_get_enabled_extension(struct gl_context *ctx, GLuint index); +extern struct gl_extensions _mesa_extension_override_enables; +extern struct gl_extensions _mesa_extension_override_disables; + #endif diff --git a/mesalib/src/mesa/main/ff_fragment_shader.cpp b/mesalib/src/mesa/main/ff_fragment_shader.cpp index 8c360970f..211583738 100644 --- a/mesalib/src/mesa/main/ff_fragment_shader.cpp +++ b/mesalib/src/mesa/main/ff_fragment_shader.cpp @@ -877,14 +877,15 @@ emit_texenv(texenv_fragment_program *p, GLuint unit) shift = new(p->mem_ctx) ir_constant((float)(1 << rgb_shift)); } else { - float const_data[4] = { - float(1 << rgb_shift), - float(1 << rgb_shift), - float(1 << rgb_shift), - float(1 << alpha_shift) - }; - shift = new(p->mem_ctx) ir_constant(glsl_type::vec4_type, - (ir_constant_data *)const_data); + 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)); diff --git a/mesalib/src/mesa/main/get.c b/mesalib/src/mesa/main/get.c index 9b56edb74..0e2d8f687 100644 --- a/mesalib/src/mesa/main/get.c +++ b/mesalib/src/mesa/main/get.c @@ -278,11 +278,6 @@ static const int extra_flush_current[] = { EXTRA_END }; -static const int extra_EXT_texture_integer[] = { - EXT(EXT_texture_integer), - EXTRA_END -}; - static const int extra_EXT_texture_integer_and_new_buffers[] = { EXT(EXT_texture_integer), EXTRA_NEW_BUFFERS, @@ -395,6 +390,7 @@ EXTRA_EXT(ARB_compute_shader); EXTRA_EXT(ARB_gpu_shader5); EXTRA_EXT2(ARB_transform_feedback3, ARB_gpu_shader5); EXTRA_EXT(INTEL_performance_query); +EXTRA_EXT(ARB_explicit_uniform_location); static const int extra_ARB_color_buffer_float_or_glcore[] = { diff --git a/mesalib/src/mesa/main/get_hash_params.py b/mesalib/src/mesa/main/get_hash_params.py index c7a6e02af..d45962d95 100644 --- a/mesalib/src/mesa/main/get_hash_params.py +++ b/mesalib/src/mesa/main/get_hash_params.py @@ -480,6 +480,7 @@ descriptor=[ [ "MAX_LIST_NESTING", "CONST(MAX_LIST_NESTING), NO_EXTRA" ], [ "MAX_NAME_STACK_DEPTH", "CONST(MAX_NAME_STACK_DEPTH), NO_EXTRA" ], [ "MAX_PIXEL_MAP_TABLE", "CONST(MAX_PIXEL_MAP_TABLE), NO_EXTRA" ], + [ "MAX_UNIFORM_LOCATIONS", "CONTEXT_INT(Const.MaxUserAssignableUniformLocations), extra_ARB_explicit_uniform_location" ], [ "NAME_STACK_DEPTH", "CONTEXT_INT(Select.NameStackDepth), NO_EXTRA" ], [ "PACK_LSB_FIRST", "CONTEXT_BOOL(Pack.LsbFirst), NO_EXTRA" ], [ "PACK_SWAP_BYTES", "CONTEXT_BOOL(Pack.SwapBytes), NO_EXTRA" ], @@ -541,6 +542,16 @@ descriptor=[ [ "ARRAY_ELEMENT_LOCK_FIRST_EXT", "CONTEXT_INT(Array.LockFirst), NO_EXTRA" ], [ "ARRAY_ELEMENT_LOCK_COUNT_EXT", "CONTEXT_INT(Array.LockCount), NO_EXTRA" ], +# GL_ARB_compressed_texture_pixel_storage + [ "UNPACK_COMPRESSED_BLOCK_WIDTH", "CONTEXT_INT(Unpack.CompressedBlockWidth), NO_EXTRA" ], + [ "UNPACK_COMPRESSED_BLOCK_HEIGHT", "CONTEXT_INT(Unpack.CompressedBlockHeight), NO_EXTRA" ], + [ "UNPACK_COMPRESSED_BLOCK_DEPTH", "CONTEXT_INT(Unpack.CompressedBlockDepth), NO_EXTRA" ], + [ "UNPACK_COMPRESSED_BLOCK_SIZE", "CONTEXT_INT(Unpack.CompressedBlockSize), NO_EXTRA" ], + [ "PACK_COMPRESSED_BLOCK_WIDTH", "CONTEXT_INT(Pack.CompressedBlockWidth), NO_EXTRA" ], + [ "PACK_COMPRESSED_BLOCK_HEIGHT", "CONTEXT_INT(Pack.CompressedBlockHeight), NO_EXTRA" ], + [ "PACK_COMPRESSED_BLOCK_DEPTH", "CONTEXT_INT(Pack.CompressedBlockDepth), NO_EXTRA" ], + [ "PACK_COMPRESSED_BLOCK_SIZE", "CONTEXT_INT(Pack.CompressedBlockSize), NO_EXTRA" ], + # GL_ARB_transpose_matrix [ "TRANSPOSE_MODELVIEW_MATRIX_ARB", "CONTEXT_MATRIX_T(ModelviewMatrixStack), NO_EXTRA" ], [ "TRANSPOSE_PROJECTION_MATRIX_ARB", "CONTEXT_MATRIX_T(ProjectionMatrixStack.Top), NO_EXTRA" ], diff --git a/mesalib/src/mesa/main/glformats.c b/mesalib/src/mesa/main/glformats.c index 9bb341cc0..aee336e12 100644 --- a/mesalib/src/mesa/main/glformats.c +++ b/mesalib/src/mesa/main/glformats.c @@ -458,36 +458,6 @@ _mesa_is_enum_format_integer(GLenum format) } -/** - * Test if the given type is an integer (non-normalized) format. - */ -GLboolean -_mesa_is_type_integer(GLenum type) -{ - switch (type) { - case GL_INT: - case GL_UNSIGNED_INT: - case GL_SHORT: - case GL_UNSIGNED_SHORT: - case GL_BYTE: - case GL_UNSIGNED_BYTE: - return GL_TRUE; - default: - return GL_FALSE; - } -} - - -/** - * Test if the given format or type is an integer (non-normalized) format. - */ -extern GLboolean -_mesa_is_enum_format_or_type_integer(GLenum format, GLenum type) -{ - return _mesa_is_enum_format_integer(format) || _mesa_is_type_integer(type); -} - - GLboolean _mesa_is_type_unsigned(GLenum type) { diff --git a/mesalib/src/mesa/main/glformats.h b/mesalib/src/mesa/main/glformats.h index af1089931..ccbce2dab 100644 --- a/mesalib/src/mesa/main/glformats.h +++ b/mesalib/src/mesa/main/glformats.h @@ -54,9 +54,6 @@ extern GLint _mesa_bytes_per_vertex_attrib(GLint comps, GLenum type); extern GLboolean -_mesa_is_type_integer(GLenum type); - -extern GLboolean _mesa_is_type_unsigned(GLenum type); extern GLboolean @@ -69,9 +66,6 @@ extern GLboolean _mesa_is_enum_format_signed_int(GLenum format); extern GLboolean -_mesa_is_enum_format_or_type_integer(GLenum format, GLenum type); - -extern GLboolean _mesa_is_color_format(GLenum format); extern GLboolean diff --git a/mesalib/src/mesa/main/mtypes.h b/mesalib/src/mesa/main/mtypes.h index 917d071a2..4762d9616 100644 --- a/mesalib/src/mesa/main/mtypes.h +++ b/mesalib/src/mesa/main/mtypes.h @@ -1502,6 +1502,10 @@ struct gl_pixelstore_attrib 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 */ }; @@ -2172,7 +2176,7 @@ struct gl_geometry_program GLenum InputType; /**< GL_POINTS, GL_LINES, GL_LINES_ADJACENCY_ARB, GL_TRIANGLES, or GL_TRIANGLES_ADJACENCY_ARB */ GLenum OutputType; /**< GL_POINTS, GL_LINE_STRIP or GL_TRIANGLE_STRIP */ - GLboolean UsesEndPrimitive; + bool UsesEndPrimitive; }; @@ -2675,7 +2679,7 @@ struct gl_shader_program GLboolean UsesClipDistance; GLuint ClipDistanceArraySize; /**< Size of the gl_ClipDistance array, or 0 if not present. */ - GLboolean UsesEndPrimitive; + bool UsesEndPrimitive; } Geom; /** Vertex shader state */ @@ -3319,6 +3323,11 @@ struct gl_constants GLuint UniformBufferOffsetAlignment; /** @} */ + /** + * GL_ARB_explicit_uniform_location + */ + GLuint MaxUserAssignableUniformLocations; + /** GL_ARB_geometry_shader4 */ GLuint MaxGeometryOutputVertices; GLuint MaxGeometryTotalOutputComponents; @@ -3511,11 +3520,13 @@ struct gl_extensions 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_object; GLboolean ARB_explicit_attrib_location; + GLboolean ARB_explicit_uniform_location; GLboolean ARB_geometry_shader4; GLboolean ARB_gpu_shader5; GLboolean ARB_half_float_vertex; diff --git a/mesalib/src/mesa/main/performance_monitor.c b/mesalib/src/mesa/main/performance_monitor.c index 9d1a6b4d8..c26eda4c6 100644 --- a/mesalib/src/mesa/main/performance_monitor.c +++ b/mesalib/src/mesa/main/performance_monitor.c @@ -164,19 +164,6 @@ counterid_to_index(GLuint counterid) return counterid - 1; } -static inline GLuint -index_to_counterid(GLuint index) -{ - return index + 1; -} - -static inline bool -counterid_valid(const struct gl_perf_monitor_group *group_obj, - GLuint counterid) -{ - return get_counter(group_obj, counterid_to_index(counterid)) != NULL; -} - /*****************************************************************************/ void GLAPIENTRY diff --git a/mesalib/src/mesa/main/pixelstore.c b/mesalib/src/mesa/main/pixelstore.c index 0f55bc304..05f6583a4 100644 --- a/mesalib/src/mesa/main/pixelstore.c +++ b/mesalib/src/mesa/main/pixelstore.c @@ -45,176 +45,165 @@ _mesa_PixelStorei( GLenum pname, GLint param ) case GL_PACK_SWAP_BYTES: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; - if (param == (GLint)ctx->Pack.SwapBytes) - return; ctx->Pack.SwapBytes = param ? GL_TRUE : GL_FALSE; - break; + break; case GL_PACK_LSB_FIRST: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; - if (param == (GLint)ctx->Pack.LsbFirst) - return; ctx->Pack.LsbFirst = param ? GL_TRUE : GL_FALSE; - break; + break; case GL_PACK_ROW_LENGTH: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Pack.RowLength == param) - return; - ctx->Pack.RowLength = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Pack.RowLength = param; + break; case GL_PACK_IMAGE_HEIGHT: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Pack.ImageHeight == param) - return; - ctx->Pack.ImageHeight = param; + if (param<0) + goto invalid_value_error; + ctx->Pack.ImageHeight = param; break; case GL_PACK_SKIP_PIXELS: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Pack.SkipPixels == param) - return; - ctx->Pack.SkipPixels = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Pack.SkipPixels = param; + break; case GL_PACK_SKIP_ROWS: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Pack.SkipRows == param) - return; - ctx->Pack.SkipRows = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Pack.SkipRows = param; + break; case GL_PACK_SKIP_IMAGES: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Pack.SkipImages == param) - return; - ctx->Pack.SkipImages = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Pack.SkipImages = param; + break; case GL_PACK_ALIGNMENT: - if (param!=1 && param!=2 && param!=4 && param!=8) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Pack.Alignment == param) - return; - ctx->Pack.Alignment = param; - break; + if (param!=1 && param!=2 && param!=4 && param!=8) + goto invalid_value_error; + ctx->Pack.Alignment = param; + break; case GL_PACK_INVERT_MESA: - if (!_mesa_is_desktop_gl(ctx)) + if (!_mesa_is_desktop_gl(ctx) || !ctx->Extensions.MESA_pack_invert) goto invalid_enum_error; - if (!ctx->Extensions.MESA_pack_invert) { - _mesa_error( ctx, GL_INVALID_ENUM, "glPixelstore(pname)" ); - return; - } - if (ctx->Pack.Invert == param) - return; ctx->Pack.Invert = param; break; + case GL_PACK_COMPRESSED_BLOCK_WIDTH: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Pack.CompressedBlockWidth = param; + break; + case GL_PACK_COMPRESSED_BLOCK_HEIGHT: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Pack.CompressedBlockHeight = param; + break; + case GL_PACK_COMPRESSED_BLOCK_DEPTH: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Pack.CompressedBlockDepth = param; + break; + case GL_PACK_COMPRESSED_BLOCK_SIZE: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Pack.CompressedBlockSize = param; + break; case GL_UNPACK_SWAP_BYTES: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; - if (param == (GLint)ctx->Unpack.SwapBytes) - return; - if ((GLint)ctx->Unpack.SwapBytes == param) - return; - ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE; + ctx->Unpack.SwapBytes = param ? GL_TRUE : GL_FALSE; break; case GL_UNPACK_LSB_FIRST: if (!_mesa_is_desktop_gl(ctx)) goto invalid_enum_error; - if (param == (GLint)ctx->Unpack.LsbFirst) - return; - if ((GLint)ctx->Unpack.LsbFirst == param) - return; - ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; - break; + ctx->Unpack.LsbFirst = param ? GL_TRUE : GL_FALSE; + break; case GL_UNPACK_ROW_LENGTH: if (ctx->API == API_OPENGLES) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Unpack.RowLength == param) - return; - ctx->Unpack.RowLength = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Unpack.RowLength = param; + break; case GL_UNPACK_IMAGE_HEIGHT: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Unpack.ImageHeight == param) - return; - - ctx->Unpack.ImageHeight = param; + if (param<0) + goto invalid_value_error; + ctx->Unpack.ImageHeight = param; break; case GL_UNPACK_SKIP_PIXELS: if (ctx->API == API_OPENGLES) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Unpack.SkipPixels == param) - return; - ctx->Unpack.SkipPixels = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Unpack.SkipPixels = param; + break; case GL_UNPACK_SKIP_ROWS: if (ctx->API == API_OPENGLES) goto invalid_enum_error; - if (param<0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Unpack.SkipRows == param) - return; - ctx->Unpack.SkipRows = param; - break; + if (param<0) + goto invalid_value_error; + ctx->Unpack.SkipRows = param; + break; case GL_UNPACK_SKIP_IMAGES: if (!_mesa_is_desktop_gl(ctx) && !_mesa_is_gles3(ctx)) goto invalid_enum_error; - if (param < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); - return; - } - if (ctx->Unpack.SkipImages == param) - return; - ctx->Unpack.SkipImages = param; - break; + if (param < 0) + goto invalid_value_error; + ctx->Unpack.SkipImages = param; + break; case GL_UNPACK_ALIGNMENT: - if (param!=1 && param!=2 && param!=4 && param!=8) { - _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore" ); - return; - } - if (ctx->Unpack.Alignment == param) - return; - ctx->Unpack.Alignment = param; - break; + if (param!=1 && param!=2 && param!=4 && param!=8) + goto invalid_value_error; + ctx->Unpack.Alignment = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_WIDTH: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Unpack.CompressedBlockWidth = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_HEIGHT: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Unpack.CompressedBlockHeight = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_DEPTH: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Unpack.CompressedBlockDepth = param; + break; + case GL_UNPACK_COMPRESSED_BLOCK_SIZE: + if (!_mesa_is_desktop_gl(ctx)) + goto invalid_enum_error; + if (param<0) + goto invalid_value_error; + ctx->Unpack.CompressedBlockSize = param; + break; default: goto invalid_enum_error; } @@ -224,6 +213,10 @@ _mesa_PixelStorei( GLenum pname, GLint param ) invalid_enum_error: _mesa_error( ctx, GL_INVALID_ENUM, "glPixelStore" ); return; + +invalid_value_error: + _mesa_error( ctx, GL_INVALID_VALUE, "glPixelStore(param)" ); + return; } @@ -251,6 +244,10 @@ _mesa_init_pixelstore( struct gl_context *ctx ) 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, ctx->Shared->NullBufferObj); ctx->Unpack.Alignment = 4; @@ -262,6 +259,10 @@ _mesa_init_pixelstore( struct gl_context *ctx ) 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, ctx->Shared->NullBufferObj); diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 28739daeb..2ec2444da 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -1392,7 +1392,7 @@ _mesa_LinkProgram(GLhandleARB programObj) static GLcharARB * read_shader(const char *fname) { - const int max = 50*1000; + int shader_size = 0; FILE *f = fopen(fname, "r"); GLcharARB *buffer, *shader; int len; @@ -1401,8 +1401,19 @@ read_shader(const char *fname) return NULL; } - buffer = malloc(max); - len = fread(buffer, 1, max, f); + /* allocate enough room for the entire shader */ + fseek(f, 0, SEEK_END); + shader_size = ftell(f); + rewind(f); + assert(shader_size); + + /* add one for terminating zero */ + shader_size++; + + buffer = malloc(shader_size); + assert(buffer); + + len = fread(buffer, 1, shader_size, f); buffer[len] = 0; fclose(f); diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index b0f0bfa91..c6e852c87 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -248,6 +248,7 @@ _mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog prog->Geom.VerticesOut = 0; prog->Geom.InputType = GL_TRIANGLES; prog->Geom.OutputType = GL_TRIANGLE_STRIP; + prog->Geom.UsesEndPrimitive = false; prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS; diff --git a/mesalib/src/mesa/main/texgetimage.c b/mesalib/src/mesa/main/texgetimage.c index 1ac707d13..8c0d3a18e 100644 --- a/mesalib/src/mesa/main/texgetimage.c +++ b/mesalib/src/mesa/main/texgetimage.c @@ -43,6 +43,7 @@ #include "texcompress.h" #include "texgetimage.h" #include "teximage.h" +#include "texstore.h" @@ -686,56 +687,62 @@ _mesa_get_compressed_teximage(struct gl_context *ctx, struct gl_texture_image *texImage, GLvoid *img) { - const GLuint row_stride = - _mesa_format_row_stride(texImage->TexFormat, texImage->Width); - GLuint i; - GLubyte *src; - GLint srcRowStride; + const GLuint dimensions = + _mesa_get_texture_dimensions(texImage->TexObject->Target); + struct compressed_pixelstore store; + GLuint i, slice; + GLubyte *dest; + + _mesa_compute_compressed_pixelstore(dimensions, texImage, + texImage->Width, texImage->Height, + texImage->Depth, + &ctx->Pack, + &store); if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { /* pack texture image into a PBO */ - GLubyte *buf = (GLubyte *) + dest = (GLubyte *) ctx->Driver.MapBufferRange(ctx, 0, ctx->Pack.BufferObj->Size, GL_MAP_WRITE_BIT, ctx->Pack.BufferObj, MAP_INTERNAL); - if (!buf) { + if (!dest) { /* out of memory or other unexpected error */ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage(map PBO failed)"); return; } - img = ADD_POINTERS(buf, img); + dest = ADD_POINTERS(dest, img); + } else { + dest = img; } - /* map src texture buffer */ - ctx->Driver.MapTextureImage(ctx, texImage, 0, - 0, 0, texImage->Width, texImage->Height, - GL_MAP_READ_BIT, &src, &srcRowStride); + dest += store.SkipBytes; - if (src) { - /* no pixelstore or pixel transfer, but respect stride */ + for (slice = 0; slice < store.CopySlices; slice++) { + GLint srcRowStride; + GLubyte *src; - if (row_stride == srcRowStride) { - const GLuint size = _mesa_format_image_size(texImage->TexFormat, - texImage->Width, - texImage->Height, - texImage->Depth); - memcpy(img, src, size); - } - else { - GLuint bw, bh; - _mesa_get_format_block_size(texImage->TexFormat, &bw, &bh); - for (i = 0; i < (texImage->Height + bh - 1) / bh; i++) { - memcpy((GLubyte *)img + i * row_stride, - (GLubyte *)src + i * srcRowStride, - row_stride); + /* map src texture buffer */ + ctx->Driver.MapTextureImage(ctx, texImage, 0, + 0, 0, texImage->Width, texImage->Height, + GL_MAP_READ_BIT, &src, &srcRowStride); + + if (src) { + + for (i = 0; i < store.CopyRowsPerSlice; i++) { + memcpy(dest, src, store.CopyBytesPerRow); + dest += store.TotalBytesPerRow; + src += srcRowStride; } - } - ctx->Driver.UnmapTextureImage(ctx, texImage, 0); - } - else { - _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage"); + ctx->Driver.UnmapTextureImage(ctx, texImage, 0); + + /* Advance to next slice */ + dest += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice); + + } else { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGetCompresssedTexImage"); + } } if (_mesa_is_bufferobj(ctx->Pack.BufferObj)) { @@ -963,7 +970,7 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, struct gl_texture_object *texObj; struct gl_texture_image *texImage; const GLint maxLevels = _mesa_max_texture_levels(ctx, target); - GLuint compressedSize; + GLuint compressedSize, dimensions; if (!legal_getteximage_target(ctx, target)) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)", @@ -1004,6 +1011,14 @@ getcompressedteximage_error_check(struct gl_context *ctx, GLenum target, texImage->Height, texImage->Depth); + /* Check for invalid pixel storage modes */ + dimensions = _mesa_get_texture_dimensions(texImage->TexObject->Target); + if (!_mesa_compressed_texture_pixel_storage_error_check(ctx, dimensions, + &ctx->Pack, + "glGetCompressedTexImageARB")) { + return GL_TRUE; + } + if (!_mesa_is_bufferobj(ctx->Pack.BufferObj)) { /* do bounds checking on writing to client memory */ if (clientMemSize < (GLsizei) compressedSize) { diff --git a/mesalib/src/mesa/main/teximage.c b/mesalib/src/mesa/main/teximage.c index 845ba8014..cab29c35d 100644 --- a/mesalib/src/mesa/main/teximage.c +++ b/mesalib/src/mesa/main/teximage.c @@ -2242,6 +2242,36 @@ texture_error_check( struct gl_context *ctx, } +bool +_mesa_compressed_texture_pixel_storage_error_check(struct gl_context *ctx, + GLint dimensions, + struct gl_pixelstore_attrib *packing, + const char *caller) +{ + if (!_mesa_is_desktop_gl(ctx) || !packing->CompressedBlockSize) + return true; + + if (packing->CompressedBlockWidth && packing->SkipPixels % packing->CompressedBlockWidth) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(skip-pixels %% block-width)", caller); + return false; + } + + if (dimensions > 1 && packing->CompressedBlockHeight && packing->SkipRows % packing->CompressedBlockHeight) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(skip-rows %% block-height)", caller); + return false; + } + + if (dimensions > 2 && packing->CompressedBlockDepth && packing->SkipImages % packing->CompressedBlockDepth) { + _mesa_error(ctx, GL_INVALID_OPERATION, + "%s(skip-images %% block-depth)", caller); + return false; + } + + return true; +} + /** * Error checking for glCompressedTexImage[123]D(). * Note that the width, height and depth values are not fully error checked @@ -2343,6 +2373,13 @@ compressed_texture_error_check(struct gl_context *ctx, GLint dimensions, goto error; } + /* Check for invalid pixel storage modes */ + if (!_mesa_compressed_texture_pixel_storage_error_check(ctx, dimensions, + &ctx->Unpack, + "glCompressedTexImage")) { + return GL_FALSE; + } + /* check image size in bytes */ if (expectedSize != imageSize) { /* Per GL_ARB_texture_compression: GL_INVALID_VALUE is generated [...] @@ -3844,7 +3881,7 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } if (!targetOK) { - _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexImage%uD(target)", + _mesa_error(ctx, GL_INVALID_ENUM, "glCompressedTexSubImage%uD(target)", dims); return GL_TRUE; } @@ -3857,14 +3894,22 @@ compressed_subtexture_error_check(struct gl_context *ctx, GLint dims, } if (level < 0 || level >= _mesa_max_texture_levels(ctx, target)) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage%uD(level=%d)", + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(level=%d)", dims, level); return GL_TRUE; } + /* Check for invalid pixel storage modes */ + if (!_mesa_compressed_texture_pixel_storage_error_check(ctx, dims, + &ctx->Unpack, + "glCompressedTexSubImage")) { + return GL_FALSE; + } + + expectedSize = compressed_tex_size(width, height, depth, format); if (expectedSize != imageSize) { - _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexImage%uD(size=%d)", + _mesa_error(ctx, GL_INVALID_VALUE, "glCompressedTexSubImage%uD(size=%d)", dims, imageSize); return GL_TRUE; } diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h index 51d94d17e..dd1504b40 100644 --- a/mesalib/src/mesa/main/teximage.h +++ b/mesalib/src/mesa/main/teximage.h @@ -326,6 +326,12 @@ _mesa_TexStorage3DMultisample(GLenum target, GLsizei samples, GLsizei height, GLsizei depth, GLboolean fixedsamplelocations); +bool +_mesa_compressed_texture_pixel_storage_error_check(struct gl_context *ctx, + GLint dimensions, + struct gl_pixelstore_attrib *packing, + const char *caller); + /*@}*/ #ifdef __cplusplus diff --git a/mesalib/src/mesa/main/texstore.c b/mesalib/src/mesa/main/texstore.c index 764214669..cb81f3fde 100644 --- a/mesalib/src/mesa/main/texstore.c +++ b/mesalib/src/mesa/main/texstore.c @@ -4195,6 +4195,61 @@ _mesa_store_compressed_teximage(struct gl_context *ctx, GLuint dims, } +void +_mesa_compute_compressed_pixelstore(GLuint dims, struct gl_texture_image *texImage, + GLsizei width, GLsizei height, GLsizei depth, + const struct gl_pixelstore_attrib *packing, + struct compressed_pixelstore *store) +{ + GLuint bw, bh; + const mesa_format texFormat = texImage->TexFormat; + + _mesa_get_format_block_size(texFormat, &bw, &bh); + + store->SkipBytes = 0; + store->TotalBytesPerRow = store->CopyBytesPerRow = + _mesa_format_row_stride(texFormat, width); + store->TotalRowsPerSlice = store->CopyRowsPerSlice = + (height + bh - 1) / bh; + store->CopySlices = depth; + + if (packing->CompressedBlockWidth && + packing->CompressedBlockSize) { + + bw = packing->CompressedBlockWidth; + + if (packing->RowLength) { + store->TotalBytesPerRow = packing->CompressedBlockSize * + (packing->RowLength + bw - 1) / bw; + } + + store->SkipBytes += packing->SkipPixels * packing->CompressedBlockSize / bw; + } + + if (dims > 1 && packing->CompressedBlockHeight && + packing->CompressedBlockSize) { + + bh = packing->CompressedBlockHeight; + + store->SkipBytes += packing->SkipRows * store->TotalBytesPerRow / bh; + store->CopyRowsPerSlice = (height + bh - 1) / bh; /* rows in blocks */ + + if (packing->ImageHeight) { + store->TotalRowsPerSlice = (packing->ImageHeight + bh - 1) / bh; + } + } + + if (dims > 2 && packing->CompressedBlockDepth && + packing->CompressedBlockSize) { + + int bd = packing->CompressedBlockDepth; + + store->SkipBytes += packing->SkipImages * store->TotalBytesPerRow * + store->TotalRowsPerSlice / bd; + } +} + + /** * Fallback for Driver.CompressedTexSubImage() */ @@ -4206,20 +4261,19 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, GLenum format, GLsizei imageSize, const GLvoid *data) { - GLint bytesPerRow, dstRowStride, srcRowStride; - GLint i, rows; + struct compressed_pixelstore store; + GLint dstRowStride; + GLint i, slice; GLubyte *dstMap; const GLubyte *src; - const mesa_format texFormat = texImage->TexFormat; - GLuint bw, bh; - GLint slice; if (dims == 1) { _mesa_problem(ctx, "Unexpected 1D compressed texsubimage call"); return; } - _mesa_get_format_block_size(texFormat, &bw, &bh); + _mesa_compute_compressed_pixelstore(dims, texImage, width, height, depth, + &ctx->Unpack, &store); /* get pointer to src pixels (may be in a pbo which we'll map here) */ data = _mesa_validate_pbo_compressed_teximage(ctx, dims, imageSize, data, @@ -4228,10 +4282,9 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, if (!data) return; - srcRowStride = _mesa_format_row_stride(texFormat, width); - src = (const GLubyte *) data; + src = (const GLubyte *) data + store.SkipBytes; - for (slice = 0; slice < depth; slice++) { + for (slice = 0; slice < store.CopySlices; slice++) { /* Map dest texture buffer */ ctx->Driver.MapTextureImage(ctx, texImage, slice + zoffset, xoffset, yoffset, width, height, @@ -4239,17 +4292,18 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, &dstMap, &dstRowStride); if (dstMap) { - bytesPerRow = srcRowStride; /* bytes per row of blocks */ - rows = (height + bh - 1) / bh; /* rows in blocks */ /* copy rows of blocks */ - for (i = 0; i < rows; i++) { - memcpy(dstMap, src, bytesPerRow); + for (i = 0; i < store.CopyRowsPerSlice; i++) { + memcpy(dstMap, src, store.CopyBytesPerRow); dstMap += dstRowStride; - src += srcRowStride; + src += store.TotalBytesPerRow; } ctx->Driver.UnmapTextureImage(ctx, texImage, slice + zoffset); + + /* advance to next slice */ + src += store.TotalBytesPerRow * (store.TotalRowsPerSlice - store.CopyRowsPerSlice); } else { _mesa_error(ctx, GL_OUT_OF_MEMORY, "glCompressedTexSubImage%uD", diff --git a/mesalib/src/mesa/main/texstore.h b/mesalib/src/mesa/main/texstore.h index 490f9f5e0..c4cfffde6 100644 --- a/mesalib/src/mesa/main/texstore.h +++ b/mesalib/src/mesa/main/texstore.h @@ -132,4 +132,21 @@ _mesa_store_compressed_texsubimage(struct gl_context *ctx, GLuint dims, GLsizei imageSize, const GLvoid *data); +struct compressed_pixelstore { + int SkipBytes; + int CopyBytesPerRow; + int CopyRowsPerSlice; + int TotalBytesPerRow; + int TotalRowsPerSlice; + int CopySlices; +}; + + +extern void +_mesa_compute_compressed_pixelstore(GLuint dims, struct gl_texture_image *texImage, + GLsizei width, GLsizei height, GLsizei depth, + const struct gl_pixelstore_attrib *packing, + struct compressed_pixelstore *store); + + #endif diff --git a/mesalib/src/mesa/main/uniform_query.cpp b/mesalib/src/mesa/main/uniform_query.cpp index 5f1af0873..480bc6f16 100644 --- a/mesalib/src/mesa/main/uniform_query.cpp +++ b/mesalib/src/mesa/main/uniform_query.cpp @@ -253,6 +253,21 @@ validate_uniform_parameters(struct gl_context *ctx, return false; } + /* If the driver storage pointer in remap table is -1, we ignore silently. + * + * GL_ARB_explicit_uniform_location spec says: + * "What happens if Uniform* is called with an explicitly defined + * uniform location, but that uniform is deemed inactive by the + * linker? + * + * RESOLVED: The call is ignored for inactive uniform variables and + * no error is generated." + * + */ + if (shProg->UniformRemapTable[location] == + INACTIVE_UNIFORM_EXPLICIT_LOCATION) + return false; + _mesa_uniform_split_location_offset(shProg, location, loc, array_index); if (shProg->UniformStorage[*loc].array_elements == 0 && count > 1) { diff --git a/mesalib/src/mesa/main/uniforms.c b/mesalib/src/mesa/main/uniforms.c index 1daade428..f450173af 100644 --- a/mesalib/src/mesa/main/uniforms.c +++ b/mesalib/src/mesa/main/uniforms.c @@ -112,7 +112,7 @@ _mesa_uniform_attach_driver_storage(struct gl_uniform_storage *uni, uni->driver_storage[uni->num_driver_storage].element_stride = element_stride; uni->driver_storage[uni->num_driver_storage].vector_stride = vector_stride; - uni->driver_storage[uni->num_driver_storage].format = (uint8_t) format; + uni->driver_storage[uni->num_driver_storage].format = format; uni->driver_storage[uni->num_driver_storage].data = data; uni->num_driver_storage++; |