aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src')
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_debug_memory.c82
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format.c14
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format.h5
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_format_pack.py2
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_rect.c9
-rw-r--r--mesalib/src/glsl/glcpp/glcpp-lex.l6
-rw-r--r--mesalib/src/glsl/glsl_parser.yy7
-rw-r--r--mesalib/src/mesa/drivers/common/meta.c8
-rw-r--r--mesalib/src/mesa/main/fbobject.c42
-rw-r--r--mesalib/src/mesa/main/shaderapi.c36
-rw-r--r--mesalib/src/mesa/main/shaderobj.c2
-rw-r--r--mesalib/src/mesa/main/texcompress_s3tc.c4
-rw-r--r--mesalib/src/mesa/main/transformfeedback.c4
-rw-r--r--mesalib/src/mesa/state_tracker/st_manager.c15
-rw-r--r--mesalib/src/mesa/vbo/vbo_attrib_tmp.h205
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);
}