diff options
author | marha <marha@users.sourceforge.net> | 2012-11-29 09:05:13 +0100 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2012-11-29 09:05:49 +0100 |
commit | 0831039c0d449a3b5874c12ee365a8d5d2be7b8c (patch) | |
tree | 4edb707b79145f619fefc18c2359659ca660612f /mesalib/src | |
parent | 6bc629065956c81d836bbdb12f5f580d8a3db8e5 (diff) | |
parent | d2d73da59e64acdc4718e4e6790a69d967bee875 (diff) | |
download | vcxsrv-0831039c0d449a3b5874c12ee365a8d5d2be7b8c.tar.gz vcxsrv-0831039c0d449a3b5874c12ee365a8d5d2be7b8c.tar.bz2 vcxsrv-0831039c0d449a3b5874c12ee365a8d5d2be7b8c.zip |
Merge remote-tracking branch 'origin/released'
* origin/released:
fontconfig xserver mesa git update 29 nov 2012
Conflicts:
xorg-server/dix/dispatch.c
xorg-server/hw/xwin/InitOutput.c
xorg-server/hw/xwin/ddraw.h
xorg-server/hw/xwin/glx/indirect.c
xorg-server/hw/xwin/winclipboardthread.c
xorg-server/hw/xwin/winclipboardxevents.c
xorg-server/hw/xwin/winengine.c
xorg-server/hw/xwin/winerror.c
xorg-server/hw/xwin/winglobals.c
xorg-server/hw/xwin/winkeybd.c
xorg-server/hw/xwin/winmultiwindowwm.c
xorg-server/hw/xwin/winmultiwindowwndproc.c
xorg-server/hw/xwin/winprocarg.c
xorg-server/hw/xwin/winwin32rootless.c
xorg-server/hw/xwin/winwindow.h
xorg-server/os/osinit.c
xorg-server/os/utils.c
Diffstat (limited to 'mesalib/src')
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_debug_memory.c | 82 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_format.c | 14 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_format.h | 5 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_format_pack.py | 2 | ||||
-rw-r--r-- | mesalib/src/gallium/auxiliary/util/u_rect.c | 9 | ||||
-rw-r--r-- | mesalib/src/glsl/glcpp/glcpp-lex.l | 6 | ||||
-rw-r--r-- | mesalib/src/glsl/glsl_parser.yy | 7 | ||||
-rw-r--r-- | mesalib/src/mesa/drivers/common/meta.c | 8 | ||||
-rw-r--r-- | mesalib/src/mesa/main/fbobject.c | 42 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderapi.c | 36 | ||||
-rw-r--r-- | mesalib/src/mesa/main/shaderobj.c | 2 | ||||
-rw-r--r-- | mesalib/src/mesa/main/texcompress_s3tc.c | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/main/transformfeedback.c | 4 | ||||
-rw-r--r-- | mesalib/src/mesa/state_tracker/st_manager.c | 15 | ||||
-rw-r--r-- | mesalib/src/mesa/vbo/vbo_attrib_tmp.h | 205 |
15 files changed, 323 insertions, 118 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_debug_memory.c b/mesalib/src/gallium/auxiliary/util/u_debug_memory.c index e24a8bc0b..4bf26a524 100644 --- a/mesalib/src/gallium/auxiliary/util/u_debug_memory.c +++ b/mesalib/src/gallium/auxiliary/util/u_debug_memory.c @@ -48,6 +48,16 @@ #define DEBUG_MEMORY_MAGIC 0x6e34090aU #define DEBUG_MEMORY_STACK 0 /* XXX: disabled until we have symbol lookup */ +/** + * Set to 1 to enable checking of freed blocks of memory. + * Basically, don't really deallocate freed memory; keep it in the list + * but mark it as freed and do extra checking in debug_memory_check(). + * This can detect some cases of use-after-free. But note that since we + * never really free anything this will use a lot of memory. + */ +#define DEBUG_FREED_MEMORY 0 +#define DEBUG_FREED_BYTE 0x33 + struct debug_memory_header { @@ -61,7 +71,10 @@ struct debug_memory_header struct debug_stack_frame backtrace[DEBUG_MEMORY_STACK]; #endif size_t size; - +#if DEBUG_FREED_MEMORY + boolean freed; /**< Is this a freed block? */ +#endif + unsigned magic; }; @@ -127,6 +140,9 @@ debug_malloc(const char *file, unsigned line, const char *function, hdr->function = function; hdr->size = size; hdr->magic = DEBUG_MEMORY_MAGIC; +#if DEBUG_FREED_MEMORY + hdr->freed = FALSE; +#endif #if DEBUG_MEMORY_STACK debug_backtrace_capture(hdr->backtrace, 0, DEBUG_MEMORY_STACK); @@ -169,6 +185,17 @@ debug_free(const char *file, unsigned line, const char *function, debug_assert(0); } +#if DEBUG_FREED_MEMORY + /* Check for double-free */ + assert(!hdr->freed); + /* Mark the block as freed but don't really free it */ + hdr->freed = TRUE; + /* Save file/line where freed */ + hdr->file = file; + hdr->line = line; + /* set freed memory to special value */ + memset(ptr, DEBUG_FREED_BYTE, hdr->size); +#else pipe_mutex_lock(list_mutex); LIST_DEL(&hdr->head); pipe_mutex_unlock(list_mutex); @@ -176,6 +203,7 @@ debug_free(const char *file, unsigned line, const char *function, ftr->magic = 0; os_free(hdr); +#endif } void * @@ -235,6 +263,9 @@ debug_realloc(const char *file, unsigned line, const char *function, new_hdr->function = old_hdr->function; new_hdr->size = new_size; new_hdr->magic = DEBUG_MEMORY_MAGIC; +#if DEBUG_FREED_MEMORY + new_hdr->freed = FALSE; +#endif new_ftr = footer_from_header(new_hdr); new_ftr->magic = DEBUG_MEMORY_MAGIC; @@ -314,3 +345,52 @@ debug_memory_end(unsigned long start_no) debug_printf("No memory leaks detected.\n"); } } + + +/** + * We can periodically call this from elsewhere to do a basic sanity + * check of the heap memory we've allocated. + */ +void +debug_memory_check(void) +{ + struct list_head *entry; + + entry = list.prev; + for (; entry != &list; entry = entry->prev) { + struct debug_memory_header *hdr; + struct debug_memory_footer *ftr; + const char *ptr; + + hdr = LIST_ENTRY(struct debug_memory_header, entry, head); + ftr = footer_from_header(hdr); + ptr = (const char *) data_from_header(hdr); + + if (hdr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: bad or corrupted memory %p\n", + hdr->file, hdr->line, hdr->function, ptr); + debug_assert(0); + } + + if (ftr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: buffer overflow %p\n", + hdr->file, hdr->line, hdr->function, ptr); + debug_assert(0); + } + +#if DEBUG_FREED_MEMORY + /* If this block is marked as freed, check that it hasn't been touched */ + if (hdr->freed) { + int i; + for (i = 0; i < hdr->size; i++) { + if (ptr[i] != DEBUG_FREED_BYTE) { + debug_printf("Memory error: byte %d of block at %p of size %d is 0x%x\n", + i, ptr, hdr->size, ptr[i]); + debug_printf("Block was freed at %s:%d\n", hdr->file, hdr->line); + } + assert(ptr[i] == DEBUG_FREED_BYTE); + } + } +#endif + } +} diff --git a/mesalib/src/gallium/auxiliary/util/u_format.c b/mesalib/src/gallium/auxiliary/util/u_format.c index f572a612e..ddce95601 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.c +++ b/mesalib/src/gallium/auxiliary/util/u_format.c @@ -147,9 +147,12 @@ util_format_is_array(const struct util_format_description *desc) } for (chan = 0; chan < desc->nr_channels; ++chan) { - if (desc->swizzle[chan] != chan) + if (desc->channel[chan].size != desc->channel[0].size) return FALSE; + if (desc->channel[chan].type == UTIL_FORMAT_TYPE_VOID && (chan + 1) == desc->nr_channels) + continue; + if (desc->channel[chan].type != desc->channel[0].type) return FALSE; @@ -158,9 +161,16 @@ util_format_is_array(const struct util_format_description *desc) if (desc->channel[chan].pure_integer != desc->channel[0].pure_integer) return FALSE; + } - if (desc->channel[chan].size != desc->channel[0].size) + if (desc->nr_channels == 4) { + if (desc->swizzle[3] < 3) return FALSE; + } else { + for (chan = 0; chan < desc->nr_channels; ++chan) { + if (desc->swizzle[chan] != chan) + return FALSE; + } } return TRUE; diff --git a/mesalib/src/gallium/auxiliary/util/u_format.h b/mesalib/src/gallium/auxiliary/util/u_format.h index a718389dd..25bfd234b 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format.h +++ b/mesalib/src/gallium/auxiliary/util/u_format.h @@ -592,7 +592,10 @@ util_format_is_pure_uint(enum pipe_format format); /** * Whether the format is a simple array format where all channels - * are of the same type and can be loaded from memory as a vector + * are of the same type and can be loaded from memory as a vector. + * + * If format is 4 channel it can be swizzled (eg BGRA) as long + * as the alpha is the 3rd channel. */ boolean util_format_is_array(const struct util_format_description *desc); diff --git a/mesalib/src/gallium/auxiliary/util/u_format_pack.py b/mesalib/src/gallium/auxiliary/util/u_format_pack.py index 0b3a890d5..565d059c3 100644 --- a/mesalib/src/gallium/auxiliary/util/u_format_pack.py +++ b/mesalib/src/gallium/auxiliary/util/u_format_pack.py @@ -383,7 +383,7 @@ def conversion_expr(src_channel, if dst_channel.norm or dst_channel.type == FIXED: dst_one = get_one(dst_channel) if dst_channel.size <= 23: - value = '(%s * 0x%x)' % (value, dst_one) + value = 'util_iround(%s * 0x%x)' % (value, dst_one) else: # bigger than single precision mantissa, use double value = '(%s * (double)0x%x)' % (value, dst_one) diff --git a/mesalib/src/gallium/auxiliary/util/u_rect.c b/mesalib/src/gallium/auxiliary/util/u_rect.c index 59bebbcb7..d00568f1f 100644 --- a/mesalib/src/gallium/auxiliary/util/u_rect.c +++ b/mesalib/src/gallium/auxiliary/util/u_rect.c @@ -144,11 +144,7 @@ util_fill_rect(ubyte * dst, dst += dst_stride; } break; - case 8: - case 12: - case 16: - case 24: - case 32: + default: for (i = 0; i < height; i++) { ubyte *row = dst; for (j = 0; j < width; j++) { @@ -158,8 +154,5 @@ util_fill_rect(ubyte * dst, dst += dst_stride; } break; - default: - assert(0); - break; } } diff --git a/mesalib/src/glsl/glcpp/glcpp-lex.l b/mesalib/src/glsl/glcpp/glcpp-lex.l index 783c54549..fd28711d1 100644 --- a/mesalib/src/glsl/glcpp/glcpp-lex.l +++ b/mesalib/src/glsl/glcpp/glcpp-lex.l @@ -120,7 +120,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? return SPACE; } -{HASH}version { +{HASH}version{HSPACE}+ { yylval->str = ralloc_strdup (yyextra, yytext); yyextra->space_tokens = 0; return HASH_VERSION; @@ -135,7 +135,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? return OTHER; } -{HASH}line { +{HASH}line{HSPACE}+ { return HASH_LINE; } @@ -158,7 +158,7 @@ HEXADECIMAL_INTEGER 0[xX][0-9a-fA-F]+[uU]? return HASH_IF; } -{HASH}elif { +{HASH}elif/[^_a-zA-Z0-9] { yyextra->lexing_if = 1; yyextra->space_tokens = 0; return HASH_ELIF; diff --git a/mesalib/src/glsl/glsl_parser.yy b/mesalib/src/glsl/glsl_parser.yy index a0665067d..407dbbeeb 100644 --- a/mesalib/src/glsl/glsl_parser.yy +++ b/mesalib/src/glsl/glsl_parser.yy @@ -238,6 +238,7 @@ static void yyerror(YYLTYPE *loc, _mesa_glsl_parse_state *st, const char *msg) %type <node> conditionopt %type <node> for_init_statement %type <for_rest_statement> for_rest_statement +%type <n> integer_constant %% translation_unit: @@ -1122,6 +1123,10 @@ layout_qualifier_id_list: } ; +integer_constant: + INTCONSTANT { $$ = $1; } + | UINTCONSTANT { $$ = $1; } + layout_qualifier_id: any_identifier { @@ -1191,7 +1196,7 @@ layout_qualifier_id: YYERROR; } } - | any_identifier '=' INTCONSTANT + | any_identifier '=' integer_constant { memset(& $$, 0, sizeof($$)); diff --git a/mesalib/src/mesa/drivers/common/meta.c b/mesalib/src/mesa/drivers/common/meta.c index 417dbd041..7d58281c1 100644 --- a/mesalib/src/mesa/drivers/common/meta.c +++ b/mesalib/src/mesa/drivers/common/meta.c @@ -684,9 +684,11 @@ _mesa_meta_begin(struct gl_context *ctx, GLbitfield state) _mesa_LoadIdentity(); _mesa_MatrixMode(GL_PROJECTION); _mesa_LoadIdentity(); - _mesa_Ortho(0.0, ctx->DrawBuffer->Width, - 0.0, ctx->DrawBuffer->Height, - -1.0, 1.0); + if (ctx->DrawBuffer->Initialized) { + _mesa_Ortho(0.0, ctx->DrawBuffer->Width, + 0.0, ctx->DrawBuffer->Height, + -1.0, 1.0); + } } if (state & MESA_META_CLIP) { diff --git a/mesalib/src/mesa/main/fbobject.c b/mesalib/src/mesa/main/fbobject.c index 223aef18d..891ec5dce 100644 --- a/mesalib/src/mesa/main/fbobject.c +++ b/mesalib/src/mesa/main/fbobject.c @@ -2799,11 +2799,41 @@ get_nongeneric_internalformat(GLenum format) } +static GLenum +get_linear_internalformat(GLenum format) +{ + switch (format) { + case GL_SRGB: + return GL_RGB; + + case GL_SRGB_ALPHA: + return GL_RGBA; + + case GL_SRGB8: + return GL_RGB8; + + case GL_SRGB8_ALPHA8: + return GL_RGBA8; + + case GL_SLUMINANCE: + return GL_LUMINANCE8; + + case GL_SLUMINANCE_ALPHA: + return GL_LUMINANCE8_ALPHA8; + + default: + return format; + } +} + + static GLboolean compatible_resolve_formats(const struct gl_renderbuffer *colorReadRb, const struct gl_renderbuffer *colorDrawRb) { - /* The simple case where we know the backing formats are the same. + GLenum readFormat, drawFormat; + + /* The simple case where we know the backing Mesa formats are the same. */ if (_mesa_get_srgb_format_linear(colorReadRb->Format) == _mesa_get_srgb_format_linear(colorDrawRb->Format)) { @@ -2817,9 +2847,15 @@ compatible_resolve_formats(const struct gl_renderbuffer *colorReadRb, * textures and get two entirely different Mesa formats like RGBA8888 and * ARGB8888. Drivers behaving like that should be able to cope with * non-matching formats by themselves, because it's not the user's fault. + * + * Blits between linear and sRGB formats are also allowed. */ - if (get_nongeneric_internalformat(colorReadRb->InternalFormat) == - get_nongeneric_internalformat(colorDrawRb->InternalFormat)) { + readFormat = get_nongeneric_internalformat(colorReadRb->InternalFormat); + drawFormat = get_nongeneric_internalformat(colorDrawRb->InternalFormat); + readFormat = get_linear_internalformat(readFormat); + drawFormat = get_linear_internalformat(drawFormat); + + if (readFormat == drawFormat) { return GL_TRUE; } diff --git a/mesalib/src/mesa/main/shaderapi.c b/mesalib/src/mesa/main/shaderapi.c index 727115015..5c0a923e4 100644 --- a/mesalib/src/mesa/main/shaderapi.c +++ b/mesalib/src/mesa/main/shaderapi.c @@ -180,25 +180,6 @@ validate_shader_target(const struct gl_context *ctx, GLenum type) } -/** - * Find the length of the longest transform feedback varying name - * which was specified with glTransformFeedbackVaryings(). - */ -static GLint -longest_feedback_varying_name(const struct gl_shader_program *shProg) -{ - GLuint i; - GLint max = 0; - for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { - GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]); - if (len > max) - max = len; - } - return max; -} - - - static GLboolean is_program(struct gl_context *ctx, GLuint name) { @@ -538,11 +519,24 @@ get_programiv(struct gl_context *ctx, GLuint program, GLenum pname, GLint *param break; *params = shProg->TransformFeedback.NumVarying; return; - case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: + case GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH: { + unsigned i; + GLint max_len = 0; if (!has_xfb) break; - *params = longest_feedback_varying_name(shProg) + 1; + + for (i = 0; i < shProg->TransformFeedback.NumVarying; i++) { + /* Add one for the terminating NUL character. + */ + const GLint len = strlen(shProg->TransformFeedback.VaryingNames[i]) + 1; + + if (len > max_len) + max_len = len; + } + + *params = max_len; return; + } case GL_TRANSFORM_FEEDBACK_BUFFER_MODE: if (!has_xfb) break; diff --git a/mesalib/src/mesa/main/shaderobj.c b/mesalib/src/mesa/main/shaderobj.c index 1706cac55..59daff5bf 100644 --- a/mesalib/src/mesa/main/shaderobj.c +++ b/mesalib/src/mesa/main/shaderobj.c @@ -247,6 +247,8 @@ _mesa_init_shader_program(struct gl_context *ctx, struct gl_shader_program *prog prog->Geom.InputType = GL_TRIANGLES; prog->Geom.OutputType = GL_TRIANGLE_STRIP; + prog->TransformFeedback.BufferMode = GL_INTERLEAVED_ATTRIBS; + prog->InfoLog = ralloc_strdup(prog, ""); } diff --git a/mesalib/src/mesa/main/texcompress_s3tc.c b/mesalib/src/mesa/main/texcompress_s3tc.c index 6476f118e..da7725964 100644 --- a/mesalib/src/mesa/main/texcompress_s3tc.c +++ b/mesalib/src/mesa/main/texcompress_s3tc.c @@ -362,7 +362,6 @@ static void fetch_texel_2d_rgb_dxt1(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLubyte *texel) { - (void) k; if (fetch_ext_rgb_dxt1) { GLint sliceOffset = k ? texImage->ImageOffsets[k] / 2 : 0; fetch_ext_rgb_dxt1(texImage->RowStride, @@ -391,7 +390,6 @@ static void fetch_texel_2d_rgba_dxt1(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLubyte *texel) { - (void) k; if (fetch_ext_rgba_dxt1) { GLint sliceOffset = k ? texImage->ImageOffsets[k] / 2 : 0; fetch_ext_rgba_dxt1(texImage->RowStride, @@ -420,7 +418,6 @@ static void fetch_texel_2d_rgba_dxt3(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLubyte *texel) { - (void) k; if (fetch_ext_rgba_dxt3) { GLint sliceOffset = k ? texImage->ImageOffsets[k] : 0; fetch_ext_rgba_dxt3(texImage->RowStride, @@ -449,7 +446,6 @@ static void fetch_texel_2d_rgba_dxt5(const struct swrast_texture_image *texImage, GLint i, GLint j, GLint k, GLubyte *texel) { - (void) k; if (fetch_ext_rgba_dxt5) { GLint sliceOffset = k ? texImage->ImageOffsets[k] : 0; fetch_ext_rgba_dxt5(texImage->RowStride, diff --git a/mesalib/src/mesa/main/transformfeedback.c b/mesalib/src/mesa/main/transformfeedback.c index e0dd4e886..22060c34c 100644 --- a/mesalib/src/mesa/main/transformfeedback.c +++ b/mesalib/src/mesa/main/transformfeedback.c @@ -622,14 +622,14 @@ _mesa_GetTransformFeedbackVarying(GLuint program, GLuint index, shProg = _mesa_lookup_shader_program(ctx, program); if (!shProg) { _mesa_error(ctx, GL_INVALID_VALUE, - "glGetTransformFeedbackVaryings(program=%u)", program); + "glGetTransformFeedbackVarying(program=%u)", program); return; } linked_xfb_info = &shProg->LinkedTransformFeedback; if (index >= (GLuint) linked_xfb_info->NumVarying) { _mesa_error(ctx, GL_INVALID_VALUE, - "glGetTransformFeedbackVaryings(index=%u)", index); + "glGetTransformFeedbackVarying(index=%u)", index); return; } diff --git a/mesalib/src/mesa/state_tracker/st_manager.c b/mesalib/src/mesa/state_tracker/st_manager.c index 88b886de8..5576a0d6c 100644 --- a/mesalib/src/mesa/state_tracker/st_manager.c +++ b/mesalib/src/mesa/state_tracker/st_manager.c @@ -624,6 +624,8 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, api = API_OPENGLES2; break; case ST_PROFILE_OPENGL_CORE: + api = API_OPENGL_CORE; + break; default: *error = ST_CONTEXT_ERROR_BAD_API; return NULL; @@ -644,16 +646,18 @@ st_api_create_context(struct st_api *stapi, struct st_manager *smapi, return NULL; } + if (attribs->flags & ST_CONTEXT_FLAG_DEBUG) + st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_DEBUG_BIT; + if (attribs->flags & ST_CONTEXT_FLAG_FORWARD_COMPATIBLE) + st->ctx->Const.ContextFlags |= GL_CONTEXT_FLAG_FORWARD_COMPATIBLE_BIT; + /* need to perform version check */ if (attribs->major > 1 || attribs->minor > 0) { _mesa_compute_version(st->ctx); - /* Is the actual version less than the requested version? Mesa can't - * yet enforce the added restrictions of a forward-looking context, so - * fail that too. + /* Is the actual version less than the requested version? */ - if (st->ctx->Version < attribs->major * 10 + attribs->minor - || (attribs->flags & ~ST_CONTEXT_FLAG_DEBUG) != 0) { + if (st->ctx->Version < attribs->major * 10 + attribs->minor) { *error = ST_CONTEXT_ERROR_BAD_VERSION; st_destroy_context(st); return NULL; @@ -884,6 +888,7 @@ static const struct st_api st_gl_api = { ST_API_OPENGL, #if FEATURE_GL ST_PROFILE_DEFAULT_MASK | + ST_PROFILE_OPENGL_CORE_MASK | #endif #if FEATURE_ES1 ST_PROFILE_OPENGL_ES1_MASK | diff --git a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h index 6bc53bab3..02c283da4 100644 --- a/mesalib/src/mesa/vbo/vbo_attrib_tmp.h +++ b/mesalib/src/mesa/vbo/vbo_attrib_tmp.h @@ -113,18 +113,54 @@ static inline float conv_i2_to_i(int i2) return (float)val.x; } -static inline float conv_i10_to_norm_float(int i10) +static inline float conv_i10_to_norm_float(const struct gl_context *ctx, int i10) { struct attr_bits_10 val; val.x = i10; - return (2.0F * (float)val.x + 1.0F) * (1.0F / 511.0F); -} -static inline float conv_i2_to_norm_float(int i2) + /* Traditionally, OpenGL has had two equations for converting from + * normalized fixed-point data to floating-point data. In the OpenGL 3.2 + * specification, these are equations 2.2 and 2.3, respectively: + * + * f = (2c + 1)/(2^b - 1). (2.2) + * + * Comments below this equation state: "In general, this representation is + * used for signed normalized fixed-point parameters in GL commands, such + * as vertex attribute values." Which is what we're doing here. + * + * f = max{c/(2^(b-1) - 1), -1.0} (2.3) + * + * Comments below this equation state: "In general, this representation is + * used for signed normalized fixed-point texture or floating point values." + * + * OpenGL 4.2+ and ES 3.0 remedy this and state that equation 2.3 (above) + * is used in every case. They remove equation 2.2 completely. + */ + if (_mesa_is_gles3(ctx) || + (ctx->API == API_OPENGL_CORE && ctx->Version >= 42)) { + /* Equation 2.3 above. */ + float f = ((float) val.x) / 511.0F; + return MAX2(f, -1.0); + } else { + /* Equation 2.2 above. */ + return (2.0F * (float)val.x + 1.0F) * (1.0F / 1023.0F); + } +} + +static inline float conv_i2_to_norm_float(const struct gl_context *ctx, int i2) { struct attr_bits_2 val; val.x = i2; - return (float)val.x; + + if (_mesa_is_gles3(ctx) || + (ctx->API == API_OPENGL_CORE && ctx->Version >= 42)) { + /* Equation 2.3 above. */ + float f = (float) val.x; + return MAX2(f, -1.0); + } else { + /* Equation 2.2 above. */ + return (2.0F * (float)val.x + 1.0F) * (1.0F / 3.0F); + } } #define ATTRI10_1( A, I10 ) ATTR( A, 1, GL_FLOAT, conv_i10_to_i((I10) & 0x3ff), 0, 0, 1 ) @@ -142,30 +178,30 @@ static inline float conv_i2_to_norm_float(int i2) conv_i2_to_i(((I10) >> 30) & 0x3)) -#define ATTRI10N_1( A, I10 ) ATTR( A, 1, GL_FLOAT, conv_i10_to_norm_float((I10) & 0x3ff), 0, 0, 1 ) -#define ATTRI10N_2( A, I10 ) ATTR( A, 2, GL_FLOAT, \ - conv_i10_to_norm_float((I10) & 0x3ff), \ - conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), 0, 1 ) -#define ATTRI10N_3( A, I10 ) ATTR( A, 3, GL_FLOAT, \ - conv_i10_to_norm_float((I10) & 0x3ff), \ - conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), \ - conv_i10_to_norm_float(((I10) >> 20) & 0x3ff), 1 ) -#define ATTRI10N_4( A, I10 ) ATTR( A, 4, GL_FLOAT, \ - conv_i10_to_norm_float((I10) & 0x3ff), \ - conv_i10_to_norm_float(((I10) >> 10) & 0x3ff), \ - conv_i10_to_norm_float(((I10) >> 20) & 0x3ff), \ - conv_i2_to_norm_float(((I10) >> 30) & 0x3)) - -#define ATTR_UI(val, type, normalized, attr, arg) do { \ +#define ATTRI10N_1(ctx, A, I10) ATTR(A, 1, GL_FLOAT, conv_i10_to_norm_float(ctx, (I10) & 0x3ff), 0, 0, 1 ) +#define ATTRI10N_2(ctx, A, I10) ATTR(A, 2, GL_FLOAT, \ + conv_i10_to_norm_float(ctx, (I10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((I10) >> 10) & 0x3ff), 0, 1 ) +#define ATTRI10N_3(ctx, A, I10) ATTR(A, 3, GL_FLOAT, \ + conv_i10_to_norm_float(ctx, (I10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((I10) >> 10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((I10) >> 20) & 0x3ff), 1 ) +#define ATTRI10N_4(ctx, A, I10) ATTR(A, 4, GL_FLOAT, \ + conv_i10_to_norm_float(ctx, (I10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((I10) >> 10) & 0x3ff), \ + conv_i10_to_norm_float(ctx, ((I10) >> 20) & 0x3ff), \ + conv_i2_to_norm_float(ctx, ((I10) >> 30) & 0x3)) + +#define ATTR_UI(ctx, val, type, normalized, attr, arg) do { \ if ((type) == GL_UNSIGNED_INT_2_10_10_10_REV) { \ if (normalized) { \ ATTRUI10N_##val((attr), (arg)); \ } else { \ ATTRUI10_##val((attr), (arg)); \ } \ - } else if ((type) == GL_INT_2_10_10_10_REV) { \ + } else if ((type) == GL_INT_2_10_10_10_REV) { \ if (normalized) { \ - ATTRI10N_##val((attr), (arg)); \ + ATTRI10N_##val(ctx, (attr), (arg)); \ } else { \ ATTRI10_##val((attr), (arg)); \ } \ @@ -173,11 +209,11 @@ static inline float conv_i2_to_norm_float(int i2) ERROR(GL_INVALID_VALUE); \ } while(0) -#define ATTR_UI_INDEX(val, type, normalized, index, arg) do { \ +#define ATTR_UI_INDEX(ctx, val, type, normalized, index, arg) do { \ if ((index) == 0) { \ - ATTR_UI(val, (type), normalized, 0, (arg)); \ + ATTR_UI(ctx, val, (type), normalized, 0, (arg)); \ } else if ((index) < MAX_VERTEX_GENERIC_ATTRIBS) { \ - ATTR_UI(val, (type), normalized, VBO_ATTRIB_GENERIC0 + (index), (arg)); \ + ATTR_UI(ctx, val, (type), normalized, VBO_ATTRIB_GENERIC0 + (index), (arg)); \ } else \ ERROR(GL_INVALID_VALUE); \ } while(0) @@ -799,103 +835,122 @@ TAG(VertexAttrib4fvNV)(GLuint index, const GLfloat * v) ATTR4FV(index, v); } +#define ERROR_IF_NOT_PACKED_TYPE(ctx, type, func) \ + if (type != GL_INT_2_10_10_10_REV && type != GL_UNSIGNED_INT_2_10_10_10_REV) { \ + _mesa_error(ctx, GL_INVALID_ENUM, "%s(type)", func); \ + return; \ + } static void GLAPIENTRY TAG(VertexP2ui)(GLenum type, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(2, type, 0, VBO_ATTRIB_POS, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP2ui"); + ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_POS, value); } static void GLAPIENTRY TAG(VertexP2uiv)(GLenum type, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(2, type, 0, VBO_ATTRIB_POS, value[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP2uiv"); + ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_POS, value[0]); } static void GLAPIENTRY TAG(VertexP3ui)(GLenum type, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 0, VBO_ATTRIB_POS, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP3ui"); + ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_POS, value); } static void GLAPIENTRY TAG(VertexP3uiv)(GLenum type, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 0, VBO_ATTRIB_POS, value[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP3uiv"); + ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_POS, value[0]); } static void GLAPIENTRY TAG(VertexP4ui)(GLenum type, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(4, type, 0, VBO_ATTRIB_POS, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP4ui"); + ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_POS, value); } static void GLAPIENTRY TAG(VertexP4uiv)(GLenum type, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(4, type, 0, VBO_ATTRIB_POS, value[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexP4uiv"); + ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_POS, value[0]); } static void GLAPIENTRY TAG(TexCoordP1ui)(GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(1, type, 0, VBO_ATTRIB_TEX0, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP1ui"); + ATTR_UI(ctx, 1, type, 0, VBO_ATTRIB_TEX0, coords); } static void GLAPIENTRY TAG(TexCoordP1uiv)(GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(1, type, 0, VBO_ATTRIB_TEX0, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP1uiv"); + ATTR_UI(ctx, 1, type, 0, VBO_ATTRIB_TEX0, coords[0]); } static void GLAPIENTRY TAG(TexCoordP2ui)(GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(2, type, 0, VBO_ATTRIB_TEX0, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP2ui"); + ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_TEX0, coords); } static void GLAPIENTRY TAG(TexCoordP2uiv)(GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(2, type, 0, VBO_ATTRIB_TEX0, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP2uiv"); + ATTR_UI(ctx, 2, type, 0, VBO_ATTRIB_TEX0, coords[0]); } static void GLAPIENTRY TAG(TexCoordP3ui)(GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 0, VBO_ATTRIB_TEX0, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP3ui"); + ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_TEX0, coords); } static void GLAPIENTRY TAG(TexCoordP3uiv)(GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 0, VBO_ATTRIB_TEX0, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP3uiv"); + ATTR_UI(ctx, 3, type, 0, VBO_ATTRIB_TEX0, coords[0]); } static void GLAPIENTRY TAG(TexCoordP4ui)(GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(4, type, 0, VBO_ATTRIB_TEX0, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP4ui"); + ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_TEX0, coords); } static void GLAPIENTRY TAG(TexCoordP4uiv)(GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(4, type, 0, VBO_ATTRIB_TEX0, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glTexCoordP4uiv"); + ATTR_UI(ctx, 4, type, 0, VBO_ATTRIB_TEX0, coords[0]); } static void GLAPIENTRY @@ -903,7 +958,8 @@ TAG(MultiTexCoordP1ui)(GLenum target, GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(1, type, 0, attr, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP1ui"); + ATTR_UI(ctx, 1, type, 0, attr, coords); } static void GLAPIENTRY @@ -911,7 +967,8 @@ TAG(MultiTexCoordP1uiv)(GLenum target, GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(1, type, 0, attr, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP1uiv"); + ATTR_UI(ctx, 1, type, 0, attr, coords[0]); } static void GLAPIENTRY @@ -919,7 +976,8 @@ TAG(MultiTexCoordP2ui)(GLenum target, GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(2, type, 0, attr, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP2ui"); + ATTR_UI(ctx, 2, type, 0, attr, coords); } static void GLAPIENTRY @@ -927,7 +985,8 @@ TAG(MultiTexCoordP2uiv)(GLenum target, GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(2, type, 0, attr, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP2uiv"); + ATTR_UI(ctx, 2, type, 0, attr, coords[0]); } static void GLAPIENTRY @@ -935,7 +994,8 @@ TAG(MultiTexCoordP3ui)(GLenum target, GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(3, type, 0, attr, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP3ui"); + ATTR_UI(ctx, 3, type, 0, attr, coords); } static void GLAPIENTRY @@ -943,7 +1003,8 @@ TAG(MultiTexCoordP3uiv)(GLenum target, GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(3, type, 0, attr, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP3uiv"); + ATTR_UI(ctx, 3, type, 0, attr, coords[0]); } static void GLAPIENTRY @@ -951,7 +1012,8 @@ TAG(MultiTexCoordP4ui)(GLenum target, GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(4, type, 0, attr, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP4ui"); + ATTR_UI(ctx, 4, type, 0, attr, coords); } static void GLAPIENTRY @@ -959,63 +1021,72 @@ TAG(MultiTexCoordP4uiv)(GLenum target, GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); GLuint attr = (target & 0x7) + VBO_ATTRIB_TEX0; - ATTR_UI(4, type, 0, attr, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glMultiTexCoordP4uiv"); + ATTR_UI(ctx, 4, type, 0, attr, coords[0]); } static void GLAPIENTRY TAG(NormalP3ui)(GLenum type, GLuint coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 1, VBO_ATTRIB_NORMAL, coords); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glNormalP3ui"); + ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_NORMAL, coords); } static void GLAPIENTRY TAG(NormalP3uiv)(GLenum type, const GLuint *coords) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 1, VBO_ATTRIB_NORMAL, coords[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glNormalP3uiv"); + ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_NORMAL, coords[0]); } static void GLAPIENTRY TAG(ColorP3ui)(GLenum type, GLuint color) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 1, VBO_ATTRIB_COLOR0, color); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP3ui"); + ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR0, color); } static void GLAPIENTRY TAG(ColorP3uiv)(GLenum type, const GLuint *color) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 1, VBO_ATTRIB_COLOR0, color[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP3uiv"); + ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR0, color[0]); } static void GLAPIENTRY TAG(ColorP4ui)(GLenum type, GLuint color) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(4, type, 1, VBO_ATTRIB_COLOR0, color); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP4ui"); + ATTR_UI(ctx, 4, type, 1, VBO_ATTRIB_COLOR0, color); } static void GLAPIENTRY TAG(ColorP4uiv)(GLenum type, const GLuint *color) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(4, type, 1, VBO_ATTRIB_COLOR0, color[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glColorP4uiv"); + ATTR_UI(ctx, 4, type, 1, VBO_ATTRIB_COLOR0, color[0]); } static void GLAPIENTRY TAG(SecondaryColorP3ui)(GLenum type, GLuint color) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 1, VBO_ATTRIB_COLOR1, color); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glSecondaryColorP3ui"); + ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR1, color); } static void GLAPIENTRY TAG(SecondaryColorP3uiv)(GLenum type, const GLuint *color) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI(3, type, 1, VBO_ATTRIB_COLOR1, color[0]); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glSecondaryColorP3uiv"); + ATTR_UI(ctx, 3, type, 1, VBO_ATTRIB_COLOR1, color[0]); } static void GLAPIENTRY @@ -1023,7 +1094,8 @@ TAG(VertexAttribP1ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(1, type, normalized, index, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP1ui"); + ATTR_UI_INDEX(ctx, 1, type, normalized, index, value); } static void GLAPIENTRY @@ -1031,7 +1103,8 @@ TAG(VertexAttribP2ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(2, type, normalized, index, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP2ui"); + ATTR_UI_INDEX(ctx, 2, type, normalized, index, value); } static void GLAPIENTRY @@ -1039,7 +1112,8 @@ TAG(VertexAttribP3ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(3, type, normalized, index, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP3ui"); + ATTR_UI_INDEX(ctx, 3, type, normalized, index, value); } static void GLAPIENTRY @@ -1047,7 +1121,8 @@ TAG(VertexAttribP4ui)(GLuint index, GLenum type, GLboolean normalized, GLuint value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(4, type, normalized, index, value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP4ui"); + ATTR_UI_INDEX(ctx, 4, type, normalized, index, value); } static void GLAPIENTRY @@ -1055,7 +1130,8 @@ TAG(VertexAttribP1uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(1, type, normalized, index, *value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP1uiv"); + ATTR_UI_INDEX(ctx, 1, type, normalized, index, *value); } static void GLAPIENTRY @@ -1063,7 +1139,8 @@ TAG(VertexAttribP2uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(2, type, normalized, index, *value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP2uiv"); + ATTR_UI_INDEX(ctx, 2, type, normalized, index, *value); } static void GLAPIENTRY @@ -1071,7 +1148,8 @@ TAG(VertexAttribP3uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(3, type, normalized, index, *value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP3uiv"); + ATTR_UI_INDEX(ctx, 3, type, normalized, index, *value); } static void GLAPIENTRY @@ -1079,7 +1157,8 @@ TAG(VertexAttribP4uiv)(GLuint index, GLenum type, GLboolean normalized, const GLuint *value) { GET_CURRENT_CONTEXT(ctx); - ATTR_UI_INDEX(4, type, normalized, index, *value); + ERROR_IF_NOT_PACKED_TYPE(ctx, type, "glVertexAttribP4uiv"); + ATTR_UI_INDEX(ctx, 4, type, normalized, index, *value); } |