aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesalib/src/gallium/auxiliary/util/u_blitter.c52
-rw-r--r--mesalib/src/glsl/ast.h2
-rw-r--r--mesalib/src/glsl/ast_to_hir.cpp6
-rw-r--r--mesalib/src/glsl/builtin_stubs.cpp77
-rw-r--r--mesalib/src/glsl/glcpp/glcpp.c243
-rw-r--r--mesalib/src/glsl/ir_function_detect_recursion.cpp4
-rw-r--r--mesalib/src/glsl/lower_jumps.cpp1
-rw-r--r--mesalib/src/glsl/opt_discard_simplification.cpp1
-rw-r--r--mesalib/src/glsl/opt_if_simplification.cpp189
-rw-r--r--mesalib/src/glsl/standalone_scaffolding.cpp1
-rw-r--r--mesalib/src/mesa/drivers/dri/common/depthtmp.h548
-rw-r--r--mesalib/src/mesa/drivers/dri/common/dri_util.c12
-rw-r--r--mesalib/src/mesa/drivers/dri/common/spantmp2.h20
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.c1532
-rw-r--r--mesalib/src/mesa/drivers/dri/common/utils.h221
-rw-r--r--mesalib/src/mesa/drivers/dri/swrast/swrast.c19
-rw-r--r--mesalib/src/mesa/main/extensions.c8
-rw-r--r--mesalib/src/mesa/main/nvprogram.c2
-rw-r--r--mesalib/src/mesa/main/nvprogram.h238
-rw-r--r--mesalib/src/mesa/main/teximage.h571
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp17
-rw-r--r--mesalib/src/mesa/program/nvvertparse.c2918
-rw-r--r--mesalib/src/mesa/state_tracker/st_extensions.c11
-rw-r--r--mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp33
-rw-r--r--mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c2
-rw-r--r--mesalib/src/mesa/swrast/s_spantemp.h449
-rw-r--r--pixman/configure.ac13
-rw-r--r--pixman/pixman/pixman-arm-neon-asm.S139
-rw-r--r--pixman/pixman/pixman-bits-image.c58
-rw-r--r--pixman/test/Makefile.am2
-rw-r--r--pixman/test/utils.c112
-rw-r--r--pixman/test/utils.h3
32 files changed, 3865 insertions, 3639 deletions
diff --git a/mesalib/src/gallium/auxiliary/util/u_blitter.c b/mesalib/src/gallium/auxiliary/util/u_blitter.c
index d8e46f07c..d69fb1a11 100644
--- a/mesalib/src/gallium/auxiliary/util/u_blitter.c
+++ b/mesalib/src/gallium/auxiliary/util/u_blitter.c
@@ -480,10 +480,11 @@ static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
unsigned level,
unsigned zslice,
unsigned x1, unsigned y1,
- unsigned x2, unsigned y2)
+ unsigned x2, unsigned y2,
+ boolean normalized)
{
int i;
- float r = zslice / (float)u_minify(src->depth0, level);
+ float r = normalized ? zslice / (float)u_minify(src->depth0, level) : zslice;
blitter_set_texcoords_2d(ctx, src, level, x1, y1, x2, y2);
@@ -491,6 +492,21 @@ static void blitter_set_texcoords_3d(struct blitter_context_priv *ctx,
ctx->vertices[i][1][2] = r; /*r*/
}
+static void blitter_set_texcoords_1d_array(struct blitter_context_priv *ctx,
+ struct pipe_resource *src,
+ unsigned level,
+ unsigned zslice,
+ unsigned x1, unsigned x2)
+{
+ int i;
+ float r = zslice;
+
+ blitter_set_texcoords_2d(ctx, src, level, x1, 0, x2, 0);
+
+ for (i = 0; i < 4; i++)
+ ctx->vertices[i][1][1] = r; /*r*/
+}
+
static void blitter_set_texcoords_cube(struct blitter_context_priv *ctx,
struct pipe_resource *src,
unsigned level, unsigned face,
@@ -576,6 +592,10 @@ pipe_tex_to_tgsi_tex(enum pipe_texture_target pipe_tex_target)
return TGSI_TEXTURE_3D;
case PIPE_TEXTURE_CUBE:
return TGSI_TEXTURE_CUBE;
+ case PIPE_TEXTURE_1D_ARRAY:
+ return TGSI_TEXTURE_1D_ARRAY;
+ case PIPE_TEXTURE_2D_ARRAY:
+ return TGSI_TEXTURE_2D_ARRAY;
default:
assert(0 && "unexpected texture target");
return TGSI_TEXTURE_UNKNOWN;
@@ -861,17 +881,31 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
break;
/* Draw the quad with the generic codepath. */
- case PIPE_TEXTURE_3D:
- case PIPE_TEXTURE_CUBE:
+ default:
/* Set texture coordinates. */
- if (src->target == PIPE_TEXTURE_3D)
+ switch (src->target) {
+ case PIPE_TEXTURE_1D_ARRAY:
+ blitter_set_texcoords_1d_array(ctx, src, srclevel, srcbox->y,
+ srcbox->x, srcbox->x + width);
+ break;
+
+ case PIPE_TEXTURE_2D_ARRAY:
+ case PIPE_TEXTURE_3D:
blitter_set_texcoords_3d(ctx, src, srclevel, srcbox->z,
srcbox->x, srcbox->y,
- srcbox->x + width, srcbox->y + height);
- else
+ srcbox->x + width, srcbox->y + height,
+ src->target == PIPE_TEXTURE_3D);
+ break;
+
+ case PIPE_TEXTURE_CUBE:
blitter_set_texcoords_cube(ctx, src, srclevel, srcbox->z,
srcbox->x, srcbox->y,
srcbox->x + width, srcbox->y + height);
+ break;
+
+ default:
+ assert(0);
+ }
/* Draw. */
blitter_set_rectangle(ctx, dstx, dsty, dstx+width, dsty+height, 0);
@@ -880,10 +914,6 @@ void util_blitter_copy_texture(struct blitter_context *blitter,
util_draw_vertex_buffer(ctx->base.pipe, NULL, ctx->vbuf, 0,
PIPE_PRIM_TRIANGLE_FAN, 4, 2);
break;
-
- default:
- assert(0);
- return;
}
blitter_restore_CSOs(ctx);
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index d1de22718..532347df4 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -372,7 +372,7 @@ struct ast_type_qualifier {
* \note
* This field is only valid if \c explicit_location is set.
*/
- unsigned location;
+ int location;
/**
* Return true if and only if an interpolation qualifier is present.
diff --git a/mesalib/src/glsl/ast_to_hir.cpp b/mesalib/src/glsl/ast_to_hir.cpp
index 777f190a4..484786c5f 100644
--- a/mesalib/src/glsl/ast_to_hir.cpp
+++ b/mesalib/src/glsl/ast_to_hir.cpp
@@ -3014,6 +3014,12 @@ ast_function::hir(exec_list *instructions,
const char *const name = identifier;
+ /* New functions are always added to the top-level IR instruction stream,
+ * so this instruction list pointer is ignored. See also emit_function
+ * (called below).
+ */
+ (void) instructions;
+
/* From page 21 (page 27 of the PDF) of the GLSL 1.20 spec,
*
* "Function declarations (prototypes) cannot occur inside of functions;
diff --git a/mesalib/src/glsl/builtin_stubs.cpp b/mesalib/src/glsl/builtin_stubs.cpp
index 4c360b832..dfa5d324e 100644
--- a/mesalib/src/glsl/builtin_stubs.cpp
+++ b/mesalib/src/glsl/builtin_stubs.cpp
@@ -1,38 +1,39 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include "glsl_parser_extras.h"
-
-/* A dummy file. When compiling prototypes, we don't care about builtins.
- * We really don't want to half-compile builtin_functions.cpp and fail, though.
- */
-void
-_mesa_glsl_release_functions(void)
-{
-}
-
-void
-_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state)
-{
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include "glsl_parser_extras.h"
+
+/* A dummy file. When compiling prototypes, we don't care about builtins.
+ * We really don't want to half-compile builtin_functions.cpp and fail, though.
+ */
+void
+_mesa_glsl_release_functions(void)
+{
+}
+
+void
+_mesa_glsl_initialize_functions(_mesa_glsl_parse_state *state)
+{
+ (void) state;
+}
diff --git a/mesalib/src/glsl/glcpp/glcpp.c b/mesalib/src/glsl/glcpp/glcpp.c
index 63eb061c2..e461a6502 100644
--- a/mesalib/src/glsl/glcpp/glcpp.c
+++ b/mesalib/src/glsl/glcpp/glcpp.c
@@ -1,121 +1,122 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <stdio.h>
-#include <string.h>
-#include <errno.h>
-#include "glcpp.h"
-#include "main/mtypes.h"
-#include "main/shaderobj.h"
-
-extern int yydebug;
-
-void
-_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
- struct gl_shader *sh)
-{
- *ptr = sh;
-}
-
-/* Read from fp until EOF and return a string of everything read.
- */
-static char *
-load_text_fp (void *ctx, FILE *fp)
-{
-#define CHUNK 4096
- char *text = NULL;
- size_t text_size = 0;
- size_t total_read = 0;
- size_t bytes;
-
- while (1) {
- if (total_read + CHUNK + 1 > text_size) {
- text_size = text_size ? text_size * 2 : CHUNK + 1;
- text = reralloc_size (ctx, text, text_size);
- if (text == NULL) {
- fprintf (stderr, "Out of memory\n");
- return NULL;
- }
- }
- bytes = fread (text + total_read, 1, CHUNK, fp);
- total_read += bytes;
-
- if (bytes < CHUNK) {
- break;
- }
- }
-
- text[total_read] = '\0';
-
- return text;
-}
-
-static char *
-load_text_file(void *ctx, const char *filename)
-{
- char *text;
- FILE *fp;
-
- if (filename == NULL || strcmp (filename, "-") == 0)
- return load_text_fp (ctx, stdin);
-
- fp = fopen (filename, "r");
- if (fp == NULL) {
- fprintf (stderr, "Failed to open file %s: %s\n",
- filename, strerror (errno));
- return NULL;
- }
-
- text = load_text_fp (ctx, fp);
-
- fclose(fp);
-
- return text;
-}
-
-int
-main (int argc, char *argv[])
-{
- char *filename = NULL;
- void *ctx = ralloc(NULL, void*);
- char *info_log = ralloc_strdup(ctx, "");
- const char *shader;
- int ret;
-
- if (argc) {
- filename = argv[1];
- }
-
- shader = load_text_file (ctx, filename);
- if (shader == NULL)
- return 1;
-
- ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
-
- printf("%s", shader);
- fprintf(stderr, "%s", info_log);
-
- ralloc_free(ctx);
-
- return ret;
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "glcpp.h"
+#include "main/mtypes.h"
+#include "main/shaderobj.h"
+
+extern int yydebug;
+
+void
+_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
+ struct gl_shader *sh)
+{
+ (void) ctx;
+ *ptr = sh;
+}
+
+/* Read from fp until EOF and return a string of everything read.
+ */
+static char *
+load_text_fp (void *ctx, FILE *fp)
+{
+#define CHUNK 4096
+ char *text = NULL;
+ size_t text_size = 0;
+ size_t total_read = 0;
+ size_t bytes;
+
+ while (1) {
+ if (total_read + CHUNK + 1 > text_size) {
+ text_size = text_size ? text_size * 2 : CHUNK + 1;
+ text = reralloc_size (ctx, text, text_size);
+ if (text == NULL) {
+ fprintf (stderr, "Out of memory\n");
+ return NULL;
+ }
+ }
+ bytes = fread (text + total_read, 1, CHUNK, fp);
+ total_read += bytes;
+
+ if (bytes < CHUNK) {
+ break;
+ }
+ }
+
+ text[total_read] = '\0';
+
+ return text;
+}
+
+static char *
+load_text_file(void *ctx, const char *filename)
+{
+ char *text;
+ FILE *fp;
+
+ if (filename == NULL || strcmp (filename, "-") == 0)
+ return load_text_fp (ctx, stdin);
+
+ fp = fopen (filename, "r");
+ if (fp == NULL) {
+ fprintf (stderr, "Failed to open file %s: %s\n",
+ filename, strerror (errno));
+ return NULL;
+ }
+
+ text = load_text_fp (ctx, fp);
+
+ fclose(fp);
+
+ return text;
+}
+
+int
+main (int argc, char *argv[])
+{
+ char *filename = NULL;
+ void *ctx = ralloc(NULL, void*);
+ char *info_log = ralloc_strdup(ctx, "");
+ const char *shader;
+ int ret;
+
+ if (argc) {
+ filename = argv[1];
+ }
+
+ shader = load_text_file (ctx, filename);
+ if (shader == NULL)
+ return 1;
+
+ ret = preprocess(ctx, &shader, &info_log, NULL, API_OPENGL);
+
+ printf("%s", shader);
+ fprintf(stderr, "%s", info_log);
+
+ ralloc_free(ctx);
+
+ return ret;
+}
diff --git a/mesalib/src/glsl/ir_function_detect_recursion.cpp b/mesalib/src/glsl/ir_function_detect_recursion.cpp
index 8f805bf1b..890bc455f 100644
--- a/mesalib/src/glsl/ir_function_detect_recursion.cpp
+++ b/mesalib/src/glsl/ir_function_detect_recursion.cpp
@@ -289,6 +289,8 @@ emit_errors_unlinked(const void *key, void *data, void *closure)
function *f = (function *) data;
YYLTYPE loc;
+ (void) key;
+
char *proto = prototype_string(f->sig->return_type,
f->sig->function_name(),
&f->sig->parameters);
@@ -308,6 +310,8 @@ emit_errors_linked(const void *key, void *data, void *closure)
(struct gl_shader_program *) closure;
function *f = (function *) data;
+ (void) key;
+
char *proto = prototype_string(f->sig->return_type,
f->sig->function_name(),
&f->sig->parameters);
diff --git a/mesalib/src/glsl/lower_jumps.cpp b/mesalib/src/glsl/lower_jumps.cpp
index 61874990a..92813f567 100644
--- a/mesalib/src/glsl/lower_jumps.cpp
+++ b/mesalib/src/glsl/lower_jumps.cpp
@@ -438,6 +438,7 @@ struct ir_lower_jumps_visitor : public ir_control_flow_visitor {
* satisfied, because discard statements can't contain other
* statements.
*/
+ (void) ir;
}
enum jump_strength get_jump_strength(ir_instruction* ir)
diff --git a/mesalib/src/glsl/opt_discard_simplification.cpp b/mesalib/src/glsl/opt_discard_simplification.cpp
index a19947ddd..ba4981bae 100644
--- a/mesalib/src/glsl/opt_discard_simplification.cpp
+++ b/mesalib/src/glsl/opt_discard_simplification.cpp
@@ -138,6 +138,7 @@ is_only_instruction(ir_discard *discard)
ir_visitor_status
discard_simplifier::visit_enter(ir_assignment *ir)
{
+ (void) ir;
return visit_continue_with_parent;
}
diff --git a/mesalib/src/glsl/opt_if_simplification.cpp b/mesalib/src/glsl/opt_if_simplification.cpp
index 2d8858e49..940dd08d5 100644
--- a/mesalib/src/glsl/opt_if_simplification.cpp
+++ b/mesalib/src/glsl/opt_if_simplification.cpp
@@ -1,94 +1,95 @@
-/*
- * Copyright © 2010 Intel Corporation
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file opt_if_simplification.cpp
- *
- * Moves constant branches of if statements out to the surrounding
- * instruction stream.
- */
-
-#include "ir.h"
-
-class ir_if_simplification_visitor : public ir_hierarchical_visitor {
-public:
- ir_if_simplification_visitor()
- {
- this->made_progress = false;
- }
-
- ir_visitor_status visit_leave(ir_if *);
- ir_visitor_status visit_enter(ir_assignment *);
-
- bool made_progress;
-};
-
-/* We only care about the top level "if" instructions, so don't
- * descend into expressions.
- */
-ir_visitor_status
-ir_if_simplification_visitor::visit_enter(ir_assignment *ir)
-{
- return visit_continue_with_parent;
-}
-
-bool
-do_if_simplification(exec_list *instructions)
-{
- ir_if_simplification_visitor v;
-
- v.run(instructions);
- return v.made_progress;
-}
-
-
-ir_visitor_status
-ir_if_simplification_visitor::visit_leave(ir_if *ir)
-{
- /* FINISHME: Ideally there would be a way to note that the condition results
- * FINISHME: in a constant before processing both of the other subtrees.
- * FINISHME: This can probably be done with some flags, but it would take
- * FINISHME: some work to get right.
- */
- ir_constant *condition_constant = ir->condition->constant_expression_value();
- if (condition_constant) {
- /* Move the contents of the one branch of the conditional
- * that matters out.
- */
- if (condition_constant->value.b[0]) {
- foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
- ir_instruction *then_ir = (ir_instruction *)then_iter.get();
- ir->insert_before(then_ir);
- }
- } else {
- foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
- ir_instruction *else_ir = (ir_instruction *)else_iter.get();
- ir->insert_before(else_ir);
- }
- }
- ir->remove();
- this->made_progress = true;
- }
-
- return visit_continue;
-}
+/*
+ * Copyright © 2010 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file opt_if_simplification.cpp
+ *
+ * Moves constant branches of if statements out to the surrounding
+ * instruction stream.
+ */
+
+#include "ir.h"
+
+class ir_if_simplification_visitor : public ir_hierarchical_visitor {
+public:
+ ir_if_simplification_visitor()
+ {
+ this->made_progress = false;
+ }
+
+ ir_visitor_status visit_leave(ir_if *);
+ ir_visitor_status visit_enter(ir_assignment *);
+
+ bool made_progress;
+};
+
+/* We only care about the top level "if" instructions, so don't
+ * descend into expressions.
+ */
+ir_visitor_status
+ir_if_simplification_visitor::visit_enter(ir_assignment *ir)
+{
+ (void) ir;
+ return visit_continue_with_parent;
+}
+
+bool
+do_if_simplification(exec_list *instructions)
+{
+ ir_if_simplification_visitor v;
+
+ v.run(instructions);
+ return v.made_progress;
+}
+
+
+ir_visitor_status
+ir_if_simplification_visitor::visit_leave(ir_if *ir)
+{
+ /* FINISHME: Ideally there would be a way to note that the condition results
+ * FINISHME: in a constant before processing both of the other subtrees.
+ * FINISHME: This can probably be done with some flags, but it would take
+ * FINISHME: some work to get right.
+ */
+ ir_constant *condition_constant = ir->condition->constant_expression_value();
+ if (condition_constant) {
+ /* Move the contents of the one branch of the conditional
+ * that matters out.
+ */
+ if (condition_constant->value.b[0]) {
+ foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
+ ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+ ir->insert_before(then_ir);
+ }
+ } else {
+ foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
+ ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+ ir->insert_before(else_ir);
+ }
+ }
+ ir->remove();
+ this->made_progress = true;
+ }
+
+ return visit_continue;
+}
diff --git a/mesalib/src/glsl/standalone_scaffolding.cpp b/mesalib/src/glsl/standalone_scaffolding.cpp
index bbd7bb913..72aa1e428 100644
--- a/mesalib/src/glsl/standalone_scaffolding.cpp
+++ b/mesalib/src/glsl/standalone_scaffolding.cpp
@@ -37,6 +37,7 @@ void
_mesa_reference_shader(struct gl_context *ctx, struct gl_shader **ptr,
struct gl_shader *sh)
{
+ (void) ctx;
*ptr = sh;
}
diff --git a/mesalib/src/mesa/drivers/dri/common/depthtmp.h b/mesalib/src/mesa/drivers/dri/common/depthtmp.h
index 8e751d7b2..c6e2bb75c 100644
--- a/mesalib/src/mesa/drivers/dri/common/depthtmp.h
+++ b/mesalib/src/mesa/drivers/dri/common/depthtmp.h
@@ -1,270 +1,278 @@
-
-/*
- * Notes:
- * 1. These functions plug into the gl_renderbuffer structure.
- * 2. The 'values' parameter always points to GLuint values, regardless of
- * the actual Z buffer depth.
- */
-
-
-#include "spantmp_common.h"
-
-#ifndef DBG
-#define DBG 0
-#endif
-
-#ifndef HAVE_HW_DEPTH_SPANS
-#define HAVE_HW_DEPTH_SPANS 0
-#endif
-
-#ifndef HAVE_HW_DEPTH_PIXELS
-#define HAVE_HW_DEPTH_PIXELS 0
-#endif
-
-static void TAG(WriteDepthSpan)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- const void *values,
- const GLubyte mask[] )
-{
- HW_WRITE_LOCK()
- {
- const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
- GLint x1;
- GLint n1;
- LOCAL_DEPTH_VARS;
-
- y = Y_FLIP( y );
-
-#if HAVE_HW_DEPTH_SPANS
- (void) x1; (void) n1;
-
- if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n",
- (int)n, (int)x );
-
- WRITE_DEPTH_SPAN();
-#else
- HW_CLIPLOOP()
- {
- GLint i = 0;
- CLIPSPAN( x, y, n, x1, n1, i );
-
- if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n",
- (int)i, (int)n1, (int)x1, mask );
-
- if ( mask ) {
- for ( ; n1>0 ; i++, x1++, n1-- ) {
- if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] );
- }
- } else {
- for ( ; n1>0 ; i++, x1++, n1-- ) {
- WRITE_DEPTH( x1, y, depth[i] );
- }
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_WRITE_UNLOCK();
-}
-
-
-#if HAVE_HW_DEPTH_SPANS
-/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */
-static void
-TAG(WriteMonoDepthSpan)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- const void *value, const GLubyte mask[] )
-{
- const GLuint depthVal = *((GLuint *) value);
- GLuint depths[MAX_WIDTH];
- GLuint i;
- for (i = 0; i < n; i++)
- depths[i] = depthVal;
- TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask);
-}
-#else
-static void TAG(WriteMonoDepthSpan)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- const void *value,
- const GLubyte mask[] )
-{
- HW_WRITE_LOCK()
- {
- const GLuint depth = *((GLuint *) value);
- GLint x1;
- GLint n1;
- LOCAL_DEPTH_VARS;
-
- y = Y_FLIP( y );
-
- HW_CLIPLOOP()
- {
- GLint i = 0;
- CLIPSPAN( x, y, n, x1, n1, i );
-
- if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
- __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth );
-
- if ( mask ) {
- for ( ; n1>0 ; i++, x1++, n1-- ) {
- if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
- }
- } else {
- for ( ; n1>0 ; x1++, n1-- ) {
- WRITE_DEPTH( x1, y, depth );
- }
- }
- }
- HW_ENDCLIPLOOP();
- }
- HW_WRITE_UNLOCK();
-}
-#endif
-
-
-static void TAG(WriteDepthPixels)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n,
- const GLint x[],
- const GLint y[],
- const void *values,
- const GLubyte mask[] )
-{
- HW_WRITE_LOCK()
- {
- const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
- GLuint i;
- LOCAL_DEPTH_VARS;
-
- if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" );
-
-#if HAVE_HW_DEPTH_PIXELS
- (void) i;
-
- WRITE_DEPTH_PIXELS();
-#else
- HW_CLIPLOOP()
- {
- if ( mask ) {
- for ( i = 0 ; i < n ; i++ ) {
- if ( mask[i] ) {
- const int fy = Y_FLIP( y[i] );
- if ( CLIPPIXEL( x[i], fy ) )
- WRITE_DEPTH( x[i], fy, depth[i] );
- }
- }
- }
- else {
- for ( i = 0 ; i < n ; i++ ) {
- const int fy = Y_FLIP( y[i] );
- if ( CLIPPIXEL( x[i], fy ) )
- WRITE_DEPTH( x[i], fy, depth[i] );
- }
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_WRITE_UNLOCK();
-}
-
-
-/* Read depth spans and pixels
- */
-static void TAG(ReadDepthSpan)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n, GLint x, GLint y,
- void *values )
-{
- HW_READ_LOCK()
- {
- VALUE_TYPE *depth = (VALUE_TYPE *) values;
- GLint x1, n1;
- LOCAL_DEPTH_VARS;
-
- y = Y_FLIP( y );
-
- if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" );
-
-#if HAVE_HW_DEPTH_SPANS
- (void) x1; (void) n1;
-
- READ_DEPTH_SPAN();
-#else
- HW_CLIPLOOP()
- {
- GLint i = 0;
- CLIPSPAN( x, y, n, x1, n1, i );
- for ( ; n1>0 ; i++, n1-- ) {
- READ_DEPTH( depth[i], x+i, y );
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_READ_UNLOCK();
-}
-
-static void TAG(ReadDepthPixels)( struct gl_context *ctx,
- struct gl_renderbuffer *rb,
- GLuint n,
- const GLint x[], const GLint y[],
- void *values )
-{
- HW_READ_LOCK()
- {
- VALUE_TYPE *depth = (VALUE_TYPE *) values;
- GLuint i;
- LOCAL_DEPTH_VARS;
-
- if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" );
-
-#if HAVE_HW_DEPTH_PIXELS
- (void) i;
-
- READ_DEPTH_PIXELS();
-#else
- HW_CLIPLOOP()
- {
- for ( i = 0 ; i < n ;i++ ) {
- int fy = Y_FLIP( y[i] );
- if ( CLIPPIXEL( x[i], fy ) )
- READ_DEPTH( depth[i], x[i], fy );
- }
- }
- HW_ENDCLIPLOOP();
-#endif
- }
- HW_READ_UNLOCK();
-}
-
-
-/**
- * Initialize the given renderbuffer's span routines to point to
- * the depth/z functions we generated above.
- */
-static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb)
-{
- rb->GetRow = TAG(ReadDepthSpan);
- rb->GetValues = TAG(ReadDepthPixels);
- rb->PutRow = TAG(WriteDepthSpan);
- rb->PutRowRGB = NULL;
- rb->PutMonoRow = TAG(WriteMonoDepthSpan);
- rb->PutValues = TAG(WriteDepthPixels);
- rb->PutMonoValues = NULL;
-}
-
-
-#if HAVE_HW_DEPTH_SPANS
-#undef WRITE_DEPTH_SPAN
-#undef WRITE_DEPTH_PIXELS
-#undef READ_DEPTH_SPAN
-#undef READ_DEPTH_PIXELS
-#else
-#undef WRITE_DEPTH
-#undef READ_DEPTH
-#endif
-#undef TAG
-#undef VALUE_TYPE
+
+/*
+ * Notes:
+ * 1. These functions plug into the gl_renderbuffer structure.
+ * 2. The 'values' parameter always points to GLuint values, regardless of
+ * the actual Z buffer depth.
+ */
+
+
+#include "spantmp_common.h"
+
+#ifndef DBG
+#define DBG 0
+#endif
+
+#ifndef HAVE_HW_DEPTH_SPANS
+#define HAVE_HW_DEPTH_SPANS 0
+#endif
+
+#ifndef HAVE_HW_DEPTH_PIXELS
+#define HAVE_HW_DEPTH_PIXELS 0
+#endif
+
+static void TAG(WriteDepthSpan)( struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLuint n, GLint x, GLint y,
+ const void *values,
+ const GLubyte mask[] )
+{
+ HW_WRITE_LOCK()
+ {
+ const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
+ GLint x1;
+ GLint n1;
+ LOCAL_DEPTH_VARS;
+
+ y = Y_FLIP( y );
+
+#if HAVE_HW_DEPTH_SPANS
+ (void) x1; (void) n1;
+
+ if ( DBG ) fprintf( stderr, "WriteDepthSpan 0..%d (x1 %d)\n",
+ (int)n, (int)x );
+
+ WRITE_DEPTH_SPAN();
+#else
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN( x, y, n, x1, n1, i );
+
+ if ( DBG ) fprintf( stderr, "WriteDepthSpan %d..%d (x1 %d) (mask %p)\n",
+ (int)i, (int)n1, (int)x1, mask );
+
+ if ( mask ) {
+ for ( ; n1>0 ; i++, x1++, n1-- ) {
+ if ( mask[i] ) WRITE_DEPTH( x1, y, depth[i] );
+ }
+ } else {
+ for ( ; n1>0 ; i++, x1++, n1-- ) {
+ WRITE_DEPTH( x1, y, depth[i] );
+ }
+ }
+ }
+ HW_ENDCLIPLOOP();
+#endif
+ }
+ HW_WRITE_UNLOCK();
+
+ (void) ctx;
+}
+
+
+#if HAVE_HW_DEPTH_SPANS
+/* implement MonoWriteDepthSpan() in terms of WriteDepthSpan() */
+static void
+TAG(WriteMonoDepthSpan)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint n, GLint x, GLint y,
+ const void *value, const GLubyte mask[] )
+{
+ const GLuint depthVal = *((GLuint *) value);
+ GLuint depths[MAX_WIDTH];
+ GLuint i;
+ for (i = 0; i < n; i++)
+ depths[i] = depthVal;
+ TAG(WriteDepthSpan)(ctx, rb, n, x, y, depths, mask);
+}
+#else
+static void TAG(WriteMonoDepthSpan)( struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLuint n, GLint x, GLint y,
+ const void *value,
+ const GLubyte mask[] )
+{
+ HW_WRITE_LOCK()
+ {
+ const GLuint depth = *((GLuint *) value);
+ GLint x1;
+ GLint n1;
+ LOCAL_DEPTH_VARS;
+
+ y = Y_FLIP( y );
+
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN( x, y, n, x1, n1, i );
+
+ if ( DBG ) fprintf( stderr, "%s %d..%d (x1 %d) = %u\n",
+ __FUNCTION__, (int)i, (int)n1, (int)x1, (GLuint)depth );
+
+ if ( mask ) {
+ for ( ; n1>0 ; i++, x1++, n1-- ) {
+ if ( mask[i] ) WRITE_DEPTH( x1, y, depth );
+ }
+ } else {
+ for ( ; n1>0 ; x1++, n1-- ) {
+ WRITE_DEPTH( x1, y, depth );
+ }
+ }
+ }
+ HW_ENDCLIPLOOP();
+ }
+ HW_WRITE_UNLOCK();
+
+ (void) ctx;
+}
+#endif
+
+
+static void TAG(WriteDepthPixels)( struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLuint n,
+ const GLint x[],
+ const GLint y[],
+ const void *values,
+ const GLubyte mask[] )
+{
+ HW_WRITE_LOCK()
+ {
+ const VALUE_TYPE *depth = (const VALUE_TYPE *) values;
+ GLuint i;
+ LOCAL_DEPTH_VARS;
+
+ if ( DBG ) fprintf( stderr, "WriteDepthPixels\n" );
+
+#if HAVE_HW_DEPTH_PIXELS
+ (void) i;
+
+ WRITE_DEPTH_PIXELS();
+#else
+ HW_CLIPLOOP()
+ {
+ if ( mask ) {
+ for ( i = 0 ; i < n ; i++ ) {
+ if ( mask[i] ) {
+ const int fy = Y_FLIP( y[i] );
+ if ( CLIPPIXEL( x[i], fy ) )
+ WRITE_DEPTH( x[i], fy, depth[i] );
+ }
+ }
+ }
+ else {
+ for ( i = 0 ; i < n ; i++ ) {
+ const int fy = Y_FLIP( y[i] );
+ if ( CLIPPIXEL( x[i], fy ) )
+ WRITE_DEPTH( x[i], fy, depth[i] );
+ }
+ }
+ }
+ HW_ENDCLIPLOOP();
+#endif
+ }
+ HW_WRITE_UNLOCK();
+
+ (void) ctx;
+}
+
+
+/* Read depth spans and pixels
+ */
+static void TAG(ReadDepthSpan)( struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLuint n, GLint x, GLint y,
+ void *values )
+{
+ HW_READ_LOCK()
+ {
+ VALUE_TYPE *depth = (VALUE_TYPE *) values;
+ GLint x1, n1;
+ LOCAL_DEPTH_VARS;
+
+ y = Y_FLIP( y );
+
+ if ( DBG ) fprintf( stderr, "ReadDepthSpan\n" );
+
+#if HAVE_HW_DEPTH_SPANS
+ (void) x1; (void) n1;
+
+ READ_DEPTH_SPAN();
+#else
+ HW_CLIPLOOP()
+ {
+ GLint i = 0;
+ CLIPSPAN( x, y, n, x1, n1, i );
+ for ( ; n1>0 ; i++, n1-- ) {
+ READ_DEPTH( depth[i], x+i, y );
+ }
+ }
+ HW_ENDCLIPLOOP();
+#endif
+ }
+ HW_READ_UNLOCK();
+}
+
+static void TAG(ReadDepthPixels)( struct gl_context *ctx,
+ struct gl_renderbuffer *rb,
+ GLuint n,
+ const GLint x[], const GLint y[],
+ void *values )
+{
+ HW_READ_LOCK()
+ {
+ VALUE_TYPE *depth = (VALUE_TYPE *) values;
+ GLuint i;
+ LOCAL_DEPTH_VARS;
+
+ if ( DBG ) fprintf( stderr, "ReadDepthPixels\n" );
+
+#if HAVE_HW_DEPTH_PIXELS
+ (void) i;
+
+ READ_DEPTH_PIXELS();
+#else
+ HW_CLIPLOOP()
+ {
+ for ( i = 0 ; i < n ;i++ ) {
+ int fy = Y_FLIP( y[i] );
+ if ( CLIPPIXEL( x[i], fy ) )
+ READ_DEPTH( depth[i], x[i], fy );
+ }
+ }
+ HW_ENDCLIPLOOP();
+#endif
+ }
+ HW_READ_UNLOCK();
+
+ (void) ctx;
+}
+
+
+/**
+ * Initialize the given renderbuffer's span routines to point to
+ * the depth/z functions we generated above.
+ */
+static void TAG(InitDepthPointers)(struct gl_renderbuffer *rb)
+{
+ rb->GetRow = TAG(ReadDepthSpan);
+ rb->GetValues = TAG(ReadDepthPixels);
+ rb->PutRow = TAG(WriteDepthSpan);
+ rb->PutRowRGB = NULL;
+ rb->PutMonoRow = TAG(WriteMonoDepthSpan);
+ rb->PutValues = TAG(WriteDepthPixels);
+ rb->PutMonoValues = NULL;
+}
+
+
+#if HAVE_HW_DEPTH_SPANS
+#undef WRITE_DEPTH_SPAN
+#undef WRITE_DEPTH_PIXELS
+#undef READ_DEPTH_SPAN
+#undef READ_DEPTH_PIXELS
+#else
+#undef WRITE_DEPTH
+#undef READ_DEPTH
+#endif
+#undef TAG
+#undef VALUE_TYPE
diff --git a/mesalib/src/mesa/drivers/dri/common/dri_util.c b/mesalib/src/mesa/drivers/dri/common/dri_util.c
index 82638fa72..6d6401934 100644
--- a/mesalib/src/mesa/drivers/dri/common/dri_util.c
+++ b/mesalib/src/mesa/drivers/dri/common/dri_util.c
@@ -418,6 +418,7 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config,
* supported either.
*/
(void) attrs;
+ (void) renderType;
pdp = malloc(sizeof *pdp);
if (!pdp) {
@@ -594,8 +595,10 @@ driDestroyContext(__DRIcontext *pcp)
/**
* Create the per-drawable private driver information.
*
- * \param render_type Type of rendering target. \c GLX_RGBA is the only
+ * \param render_type Type of rendering target. \c GLX_RGBA_TYPE is the only
* type likely to ever be supported for direct-rendering.
+ * However, \c GLX_RGBA_FLOAT_TYPE_ARB may eventually be
+ * supported by some drivers.
* \param shared Context with which to share textures, etc. or NULL
*
* \returns An opaque pointer to the per-context private information on
@@ -616,6 +619,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config,
__DRIcontext *pcp;
void * const shareCtx = (shared != NULL) ? shared->driverPrivate : NULL;
+ (void) render_type;
+
pcp = malloc(sizeof *pcp);
if (!pcp)
return NULL;
@@ -700,6 +705,9 @@ dri2CreateNewContext(__DRIscreen *screen, const __DRIconfig *config,
static int
driCopyContext(__DRIcontext *dest, __DRIcontext *src, unsigned long mask)
{
+ (void) dest;
+ (void) src;
+ (void) mask;
return GL_FALSE;
}
@@ -806,6 +814,8 @@ driCreateNewScreen(int scrn,
static const __DRIextension *emptyExtensionList[] = { NULL };
__DRIscreen *psp;
+ (void) loaderPrivate;
+
if (driDriverAPI.InitScreen == NULL)
return NULL;
diff --git a/mesalib/src/mesa/drivers/dri/common/spantmp2.h b/mesalib/src/mesa/drivers/dri/common/spantmp2.h
index abd79562f..83cfbb164 100644
--- a/mesalib/src/mesa/drivers/dri/common/spantmp2.h
+++ b/mesalib/src/mesa/drivers/dri/common/spantmp2.h
@@ -465,6 +465,8 @@ static void TAG(WriteRGBASpan)( struct gl_context *ctx,
GLuint n, GLint x, GLint y,
const void *values, const GLubyte mask[] )
{
+ (void) ctx;
+
HW_WRITE_LOCK()
{
const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
@@ -508,6 +510,8 @@ static void TAG(WriteRGBSpan)( struct gl_context *ctx,
GLuint n, GLint x, GLint y,
const void *values, const GLubyte mask[] )
{
+ (void) ctx;
+
HW_WRITE_LOCK()
{
const GLubyte (*rgb)[3] = (const GLubyte (*)[3]) values;
@@ -547,6 +551,8 @@ static void TAG(WriteRGBAPixels)( struct gl_context *ctx,
GLuint n, const GLint x[], const GLint y[],
const void *values, const GLubyte mask[] )
{
+ (void) ctx;
+
HW_WRITE_LOCK()
{
const GLubyte (*rgba)[4] = (const GLubyte (*)[4]) values;
@@ -593,6 +599,8 @@ static void TAG(WriteMonoRGBASpan)( struct gl_context *ctx,
GLuint n, GLint x, GLint y,
const void *value, const GLubyte mask[] )
{
+ (void) ctx;
+
HW_WRITE_LOCK()
{
const GLubyte *color = (const GLubyte *) value;
@@ -634,6 +642,8 @@ static void TAG(WriteMonoRGBAPixels)( struct gl_context *ctx,
const void *value,
const GLubyte mask[] )
{
+ (void) ctx;
+
HW_WRITE_LOCK()
{
const GLubyte *color = (const GLubyte *) value;
@@ -673,6 +683,8 @@ static void TAG(ReadRGBASpan)( struct gl_context *ctx,
struct gl_renderbuffer *rb,
GLuint n, GLint x, GLint y, void *values)
{
+ (void) ctx;
+
HW_READ_LOCK()
{
GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -713,6 +725,8 @@ static void TAG2(ReadRGBASpan,_MMX)( struct gl_context *ctx,
__asm__ __volatile__( "emms" );
#endif
+ (void) ctx;
+
HW_READ_LOCK()
{
GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -757,6 +771,8 @@ static void TAG2(ReadRGBASpan,_SSE2)( struct gl_context *ctx,
GLuint n, GLint x, GLint y,
void *values)
{
+ (void) ctx;
+
HW_READ_LOCK()
{
GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -799,6 +815,8 @@ static void TAG2(ReadRGBASpan,_SSE)( struct gl_context *ctx,
__asm__ __volatile__( "emms" );
#endif
+ (void) ctx;
+
HW_READ_LOCK()
{
GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
@@ -834,6 +852,8 @@ static void TAG(ReadRGBAPixels)( struct gl_context *ctx,
GLuint n, const GLint x[], const GLint y[],
void *values )
{
+ (void) ctx;
+
HW_READ_LOCK()
{
GLubyte (*rgba)[4] = (GLubyte (*)[4]) values;
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.c b/mesalib/src/mesa/drivers/dri/common/utils.c
index 539296d1a..54156d34a 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.c
+++ b/mesalib/src/mesa/drivers/dri/common/utils.c
@@ -1,823 +1,709 @@
-/*
- * (C) Copyright IBM Corporation 2002, 2004
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file utils.c
- * Utility functions for DRI drivers.
- *
- * \author Ian Romanick <idr@us.ibm.com>
- */
-
-#include <string.h>
-#include <stdlib.h>
-#include "main/mtypes.h"
-#include "main/cpuinfo.h"
-#include "main/extensions.h"
-#include "utils.h"
-
-
-/**
- * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
- * is set.
- *
- * Is called from the drivers.
- *
- * \param f \c printf like format string.
- */
-void
-__driUtilMessage(const char *f, ...)
-{
- va_list args;
-
- if (getenv("LIBGL_DEBUG")) {
- fprintf(stderr, "libGL: ");
- va_start(args, f);
- vfprintf(stderr, f, args);
- va_end(args);
- fprintf(stderr, "\n");
- }
-}
-
-
-unsigned
-driParseDebugString( const char * debug,
- const struct dri_debug_control * control )
-{
- unsigned flag;
-
-
- flag = 0;
- if ( debug != NULL ) {
- while( control->string != NULL ) {
- if ( !strcmp( debug, "all" ) ||
- strstr( debug, control->string ) != NULL ) {
- flag |= control->flag;
- }
-
- control++;
- }
- }
-
- return flag;
-}
-
-
-
-/**
- * Create the \c GL_RENDERER string for DRI drivers.
- *
- * Almost all DRI drivers use a \c GL_RENDERER string of the form:
- *
- * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
- *
- * Using the supplied chip name, driver data, and AGP speed, this function
- * creates the string.
- *
- * \param buffer Buffer to hold the \c GL_RENDERER string.
- * \param hardware_name Name of the hardware.
- * \param agp_mode AGP mode (speed).
- *
- * \returns
- * The length of the string stored in \c buffer. This does \b not include
- * the terminating \c NUL character.
- */
-unsigned
-driGetRendererString( char * buffer, const char * hardware_name,
- GLuint agp_mode )
-{
- unsigned offset;
- char *cpu;
-
- offset = sprintf( buffer, "Mesa DRI %s", hardware_name );
-
- /* Append any AGP-specific information.
- */
- switch ( agp_mode ) {
- case 1:
- case 2:
- case 4:
- case 8:
- offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
- break;
-
- default:
- break;
- }
-
- /* Append any CPU-specific information.
- */
- cpu = _mesa_get_cpu_string();
- if (cpu) {
- offset += sprintf(buffer + offset, " %s", cpu);
- free(cpu);
- }
-
- return offset;
-}
-
-
-
-
-#define need_GL_ARB_copy_buffer
-#define need_GL_ARB_draw_buffers
-#define need_GL_ARB_multisample
-#define need_GL_ARB_texture_compression
-#define need_GL_ARB_transpose_matrix
-#define need_GL_ARB_vertex_buffer_object
-#define need_GL_ARB_window_pos
-#define need_GL_EXT_compiled_vertex_array
-#define need_GL_EXT_multi_draw_arrays
-#define need_GL_EXT_polygon_offset
-#define need_GL_EXT_texture_object
-#define need_GL_EXT_vertex_array
-#define need_GL_IBM_multimode_draw_arrays
-#define need_GL_MESA_window_pos
-
-/* These are needed in *all* drivers because Mesa internally implements
- * certain functionality in terms of functions provided by these extensions.
- * For example, glBlendFunc is implemented by calling glBlendFuncSeparateEXT.
- */
-#define need_GL_EXT_blend_func_separate
-#define need_GL_NV_vertex_program
-
-#include "main/remap_helper.h"
-
-static const struct dri_extension all_mesa_extensions[] = {
- { "GL_ARB_copy_buffer", GL_ARB_copy_buffer_functions },
- { "GL_ARB_draw_buffers", GL_ARB_draw_buffers_functions },
- { "GL_ARB_multisample", GL_ARB_multisample_functions },
- { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions },
- { "GL_ARB_transpose_matrix", GL_ARB_transpose_matrix_functions },
- { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions},
- { "GL_ARB_window_pos", GL_ARB_window_pos_functions },
- { "GL_EXT_blend_func_separate", GL_EXT_blend_func_separate_functions },
- { "GL_EXT_compiled_vertex_array", GL_EXT_compiled_vertex_array_functions },
- { "GL_EXT_multi_draw_arrays", GL_EXT_multi_draw_arrays_functions },
- { "GL_EXT_polygon_offset", GL_EXT_polygon_offset_functions },
- { "GL_EXT_texture_object", GL_EXT_texture_object_functions },
- { "GL_EXT_vertex_array", GL_EXT_vertex_array_functions },
- { "GL_IBM_multimode_draw_arrays", GL_IBM_multimode_draw_arrays_functions },
- { "GL_MESA_window_pos", GL_MESA_window_pos_functions },
- { "GL_NV_vertex_program", GL_NV_vertex_program_functions },
- { NULL, NULL }
-};
-
-
-/**
- * Enable and map extensions supported by the driver.
- *
- * When ctx is NULL, extensions are not enabled, but their functions
- * are still mapped. When extensions_to_enable is NULL, all static
- * functions known to mesa core are mapped.
- *
- * \bug
- * ARB_imaging isn't handled properly. In Mesa, enabling ARB_imaging also
- * enables all the sub-extensions that are folded into it. This means that
- * we need to add entry-points (via \c driInitSingleExtension) for those
- * new functions here.
- */
-void driInitExtensions( struct gl_context * ctx,
- const struct dri_extension * extensions_to_enable,
- GLboolean enable_imaging )
-{
- static int first_time = 1;
- unsigned i;
-
- if ( first_time ) {
- first_time = 0;
- driInitExtensions( NULL, all_mesa_extensions, GL_FALSE );
- }
-
- if ( (ctx != NULL) && enable_imaging ) {
- _mesa_enable_imaging_extensions( ctx );
- }
-
- /* The caller is too lazy to list any extension */
- if ( extensions_to_enable == NULL ) {
- /* Map the static functions. Together with those mapped by remap
- * table, this should cover everything mesa core knows.
- */
- _mesa_map_static_functions();
- return;
- }
-
- for ( i = 0 ; extensions_to_enable[i].name != NULL ; i++ ) {
- driInitSingleExtension( ctx, & extensions_to_enable[i] );
- }
-}
-
-
-
-
-/**
- * Enable and map functions for a single extension
- *
- * \param ctx Context where extension is to be enabled.
- * \param ext Extension that is to be enabled.
- *
- * \sa driInitExtensions, _mesa_enable_extension, _mesa_map_function_array
- */
-void driInitSingleExtension( struct gl_context * ctx,
- const struct dri_extension * ext )
-{
- if ( ext->functions != NULL ) {
- _mesa_map_function_array(ext->functions);
- }
-
- if ( ctx != NULL ) {
- _mesa_enable_extension( ctx, ext->name );
- }
-}
-
-
-/**
- * Utility function used by drivers to test the verions of other components.
- *
- * \param driver_name Name of the driver. Used in error messages.
- * \param driActual Actual DRI version supplied __driCreateNewScreen.
- * \param driExpected Minimum DRI version required by the driver.
- * \param ddxActual Actual DDX version supplied __driCreateNewScreen.
- * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver.
- * \param drmActual Actual DRM version supplied __driCreateNewScreen.
- * \param drmExpected Minimum DRM version required by the driver.
- *
- * \returns \c GL_TRUE if all version requirements are met. Otherwise,
- * \c GL_FALSE is returned.
- *
- * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2
- *
- * \todo
- * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
- * function and \c driCheckDriDdxDrmVersions2 should be renamed.
- */
-GLboolean
-driCheckDriDdxDrmVersions3(const char * driver_name,
- const __DRIversion * driActual,
- const __DRIversion * driExpected,
- const __DRIversion * ddxActual,
- const __DRIutilversion2 * ddxExpected,
- const __DRIversion * drmActual,
- const __DRIversion * drmExpected)
-{
- static const char format[] = "%s DRI driver expected %s version %d.%d.x "
- "but got version %d.%d.%d\n";
- static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
- "but got version %d.%d.%d\n";
-
-
- /* Check the DRI version */
- if ( (driActual->major != driExpected->major)
- || (driActual->minor < driExpected->minor) ) {
- fprintf(stderr, format, driver_name, "DRI",
- driExpected->major, driExpected->minor,
- driActual->major, driActual->minor, driActual->patch);
- return GL_FALSE;
- }
-
- /* Check that the DDX driver version is compatible */
- if ( (ddxActual->major < ddxExpected->major_min)
- || (ddxActual->major > ddxExpected->major_max)
- || (ddxActual->minor < ddxExpected->minor) ) {
- fprintf(stderr, format2, driver_name, "DDX",
- ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
- ddxActual->major, ddxActual->minor, ddxActual->patch);
- return GL_FALSE;
- }
-
- /* Check that the DRM driver version is compatible */
- if ( (drmActual->major != drmExpected->major)
- || (drmActual->minor < drmExpected->minor) ) {
- fprintf(stderr, format, driver_name, "DRM",
- drmExpected->major, drmExpected->minor,
- drmActual->major, drmActual->minor, drmActual->patch);
- return GL_FALSE;
- }
-
- return GL_TRUE;
-}
-
-GLboolean
-driCheckDriDdxDrmVersions2(const char * driver_name,
- const __DRIversion * driActual,
- const __DRIversion * driExpected,
- const __DRIversion * ddxActual,
- const __DRIversion * ddxExpected,
- const __DRIversion * drmActual,
- const __DRIversion * drmExpected)
-{
- __DRIutilversion2 ddx_expected;
- ddx_expected.major_min = ddxExpected->major;
- ddx_expected.major_max = ddxExpected->major;
- ddx_expected.minor = ddxExpected->minor;
- ddx_expected.patch = ddxExpected->patch;
- return driCheckDriDdxDrmVersions3(driver_name, driActual,
- driExpected, ddxActual, & ddx_expected,
- drmActual, drmExpected);
-}
-
-GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
- GLint *x, GLint *y,
- GLsizei *width, GLsizei *height )
-{
- /* left clipping */
- if (*x < buffer->_Xmin) {
- *width -= (buffer->_Xmin - *x);
- *x = buffer->_Xmin;
- }
-
- /* right clipping */
- if (*x + *width > buffer->_Xmax)
- *width -= (*x + *width - buffer->_Xmax - 1);
-
- if (*width <= 0)
- return GL_FALSE;
-
- /* bottom clipping */
- if (*y < buffer->_Ymin) {
- *height -= (buffer->_Ymin - *y);
- *y = buffer->_Ymin;
- }
-
- /* top clipping */
- if (*y + *height > buffer->_Ymax)
- *height -= (*y + *height - buffer->_Ymax - 1);
-
- if (*height <= 0)
- return GL_FALSE;
-
- return GL_TRUE;
-}
-
-/**
- * Creates a set of \c struct gl_config that a driver will expose.
- *
- * A set of \c struct gl_config will be created based on the supplied
- * parameters. The number of modes processed will be 2 *
- * \c num_depth_stencil_bits * \c num_db_modes.
- *
- * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
- * \c db_modes, and \c visType into each \c struct gl_config element.
- * However, the meanings of \c fb_format and \c fb_type require further
- * explanation. The \c fb_format specifies which color components are in
- * each pixel and what the default order is. For example, \c GL_RGB specifies
- * that red, green, blue are available and red is in the "most significant"
- * position and blue is in the "least significant". The \c fb_type specifies
- * the bit sizes of each component and the actual ordering. For example, if
- * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
- * are the blue value, bits [10:5] are the green value, and bits [4:0] are
- * the red value.
- *
- * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
- * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
- * \c struct gl_config structure is \b identical to the \c GL_RGBA or
- * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
- * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
- * still uses 32-bits.
- *
- * If in doubt, look at the tables used in the function.
- *
- * \param ptr_to_modes Pointer to a pointer to a linked list of
- * \c struct gl_config. Upon completion, a pointer to
- * the next element to be process will be stored here.
- * If the function fails and returns \c GL_FALSE, this
- * value will be unmodified, but some elements in the
- * linked list may be modified.
- * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
- * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
- * \param fb_type Type of the pixels in the framebuffer. Currently only
- * \c GL_UNSIGNED_SHORT_5_6_5,
- * \c GL_UNSIGNED_SHORT_5_6_5_REV,
- * \c GL_UNSIGNED_INT_8_8_8_8, and
- * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
- * \param depth_bits Array of depth buffer sizes to be exposed.
- * \param stencil_bits Array of stencil buffer sizes to be exposed.
- * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
- * \c stencil_bits.
- * \param db_modes Array of buffer swap modes. If an element has a
- * value of \c GLX_NONE, then it represents a
- * single-buffered mode. Other valid values are
- * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
- * \c GLX_SWAP_UNDEFINED_OML. See the
- * GLX_OML_swap_method extension spec for more details.
- * \param num_db_modes Number of entries in \c db_modes.
- * \param msaa_samples Array of msaa sample count. 0 represents a visual
- * without a multisample buffer.
- * \param num_msaa_modes Number of entries in \c msaa_samples.
- * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
- * \c GLX_DIRECT_COLOR.
- *
- * \returns
- * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
- * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
- * \c fb_type).
- *
- * \todo
- * There is currently no way to support packed RGB modes (i.e., modes with
- * exactly 3 bytes per pixel) or floating-point modes. This could probably
- * be done by creating some new, private enums with clever names likes
- * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
- * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
- */
-__DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
- const uint8_t * depth_bits, const uint8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes,
- const uint8_t * msaa_samples, unsigned num_msaa_modes,
- GLboolean enable_accum)
-{
- static const uint8_t bits_table[4][4] = {
- /* R G B A */
- { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
- { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
- { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
- { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
- };
-
- static const uint32_t masks_table_rgb[6][4] = {
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
- { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
- { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
- };
-
- static const uint32_t masks_table_rgba[6][4] = {
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
- { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
- { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
- };
-
- static const uint32_t masks_table_bgr[6][4] = {
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
- { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
- { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
- };
-
- static const uint32_t masks_table_bgra[6][4] = {
- { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
- { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
- { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
- { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
- { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
- { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
- };
-
- static const uint8_t bytes_per_pixel[6] = {
- 1, /* 3_3_2 */
- 1, /* 2_3_3_REV */
- 2, /* 5_6_5 */
- 2, /* 5_6_5_REV */
- 4, /* 8_8_8_8 */
- 4 /* 8_8_8_8_REV */
- };
-
- const uint8_t * bits;
- const uint32_t * masks;
- int index;
- __DRIconfig **configs, **c;
- struct gl_config *modes;
- unsigned i, j, k, h;
- unsigned num_modes;
- unsigned num_accum_bits = (enable_accum) ? 2 : 1;
-
- switch ( fb_type ) {
- case GL_UNSIGNED_BYTE_3_3_2:
- index = 0;
- break;
- case GL_UNSIGNED_BYTE_2_3_3_REV:
- index = 1;
- break;
- case GL_UNSIGNED_SHORT_5_6_5:
- index = 2;
- break;
- case GL_UNSIGNED_SHORT_5_6_5_REV:
- index = 3;
- break;
- case GL_UNSIGNED_INT_8_8_8_8:
- index = 4;
- break;
- case GL_UNSIGNED_INT_8_8_8_8_REV:
- index = 5;
- break;
- default:
- fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
- __FUNCTION__, __LINE__, fb_type );
- return NULL;
- }
-
-
- /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
- * the _REV versions.
- *
- * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
- */
-
- switch ( fb_format ) {
- case GL_RGB:
- masks = masks_table_rgb[ index ];
- break;
-
- case GL_RGBA:
- masks = masks_table_rgba[ index ];
- break;
-
- case GL_BGR:
- masks = masks_table_bgr[ index ];
- break;
-
- case GL_BGRA:
- masks = masks_table_bgra[ index ];
- break;
-
- default:
- fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
- __FUNCTION__, __LINE__, fb_format );
- return NULL;
- }
-
- switch ( bytes_per_pixel[ index ] ) {
- case 1:
- bits = bits_table[0];
- break;
- case 2:
- bits = bits_table[1];
- break;
- default:
- bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
- ? bits_table[2]
- : bits_table[3];
- break;
- }
-
- num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
- configs = calloc(1, (num_modes + 1) * sizeof *configs);
- if (configs == NULL)
- return NULL;
-
- c = configs;
- for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
- for ( i = 0 ; i < num_db_modes ; i++ ) {
- for ( h = 0 ; h < num_msaa_modes; h++ ) {
- for ( j = 0 ; j < num_accum_bits ; j++ ) {
- *c = malloc (sizeof **c);
- modes = &(*c)->modes;
- c++;
-
- memset(modes, 0, sizeof *modes);
- modes->redBits = bits[0];
- modes->greenBits = bits[1];
- modes->blueBits = bits[2];
- modes->alphaBits = bits[3];
- modes->redMask = masks[0];
- modes->greenMask = masks[1];
- modes->blueMask = masks[2];
- modes->alphaMask = masks[3];
- modes->rgbBits = modes->redBits + modes->greenBits
- + modes->blueBits + modes->alphaBits;
-
- modes->accumRedBits = 16 * j;
- modes->accumGreenBits = 16 * j;
- modes->accumBlueBits = 16 * j;
- modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
- modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
-
- modes->stencilBits = stencil_bits[k];
- modes->depthBits = depth_bits[k];
-
- modes->transparentPixel = GLX_NONE;
- modes->transparentRed = GLX_DONT_CARE;
- modes->transparentGreen = GLX_DONT_CARE;
- modes->transparentBlue = GLX_DONT_CARE;
- modes->transparentAlpha = GLX_DONT_CARE;
- modes->transparentIndex = GLX_DONT_CARE;
- modes->rgbMode = GL_TRUE;
-
- if ( db_modes[i] == GLX_NONE ) {
- modes->doubleBufferMode = GL_FALSE;
- }
- else {
- modes->doubleBufferMode = GL_TRUE;
- modes->swapMethod = db_modes[i];
- }
-
- modes->samples = msaa_samples[h];
- modes->sampleBuffers = modes->samples ? 1 : 0;
-
-
- modes->haveAccumBuffer = ((modes->accumRedBits +
- modes->accumGreenBits +
- modes->accumBlueBits +
- modes->accumAlphaBits) > 0);
- modes->haveDepthBuffer = (modes->depthBits > 0);
- modes->haveStencilBuffer = (modes->stencilBits > 0);
-
- modes->bindToTextureRgb = GL_TRUE;
- modes->bindToTextureRgba = GL_TRUE;
- modes->bindToMipmapTexture = GL_FALSE;
- modes->bindToTextureTargets =
- __DRI_ATTRIB_TEXTURE_1D_BIT |
- __DRI_ATTRIB_TEXTURE_2D_BIT |
- __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
-
- modes->sRGBCapable = GL_FALSE;
- }
- }
- }
- }
- *c = NULL;
-
- return configs;
-}
-
-__DRIconfig **driConcatConfigs(__DRIconfig **a,
- __DRIconfig **b)
-{
- __DRIconfig **all;
- int i, j, index;
-
- i = 0;
- while (a[i] != NULL)
- i++;
- j = 0;
- while (b[j] != NULL)
- j++;
-
- all = malloc((i + j + 1) * sizeof *all);
- index = 0;
- for (i = 0; a[i] != NULL; i++)
- all[index++] = a[i];
- for (j = 0; b[j] != NULL; j++)
- all[index++] = b[j];
- all[index++] = NULL;
-
- free(a);
- free(b);
-
- return all;
-}
-
-#define __ATTRIB(attrib, field) \
- { attrib, offsetof(struct gl_config, field) }
-
-static const struct { unsigned int attrib, offset; } attribMap[] = {
- __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
- __ATTRIB(__DRI_ATTRIB_LEVEL, level),
- __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
- __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
- __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
- __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
- __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
- __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
- __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
- __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
- __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
- __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
- __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
- __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
- __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
- __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
- __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
- __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
- __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
- __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
- __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
- __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
- __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
- __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
-
- /* The struct field doesn't matter here, these are handled by the
- * switch in driGetConfigAttribIndex. We need them in the array
- * so the iterator includes them though.*/
- __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
- __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
- __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
-};
-
-#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
-
-
-/**
- * Return the value of a configuration attribute. The attribute is
- * indicated by the index.
- */
-static int
-driGetConfigAttribIndex(const __DRIconfig *config,
- unsigned int index, unsigned int *value)
-{
- switch (attribMap[index].attrib) {
- case __DRI_ATTRIB_RENDER_TYPE:
- /* no support for color index mode */
- *value = __DRI_ATTRIB_RGBA_BIT;
- break;
- case __DRI_ATTRIB_CONFIG_CAVEAT:
- if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
- *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
- else if (config->modes.visualRating == GLX_SLOW_CONFIG)
- *value = __DRI_ATTRIB_SLOW_BIT;
- else
- *value = 0;
- break;
- case __DRI_ATTRIB_SWAP_METHOD:
- /* XXX no return value??? */
- break;
-
- case __DRI_ATTRIB_FLOAT_MODE:
- /* this field is not int-sized */
- *value = config->modes.floatMode;
- break;
-
- default:
- /* any other int-sized field */
- *value = *(unsigned int *)
- ((char *) &config->modes + attribMap[index].offset);
-
- break;
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Get the value of a configuration attribute.
- * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens)
- * \param value returns the attribute's value
- * \return 1 for success, 0 for failure
- */
-int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value)
-{
- int i;
-
- for (i = 0; i < ARRAY_SIZE(attribMap); i++)
- if (attribMap[i].attrib == attrib)
- return driGetConfigAttribIndex(config, i, value);
-
- return GL_FALSE;
-}
-
-
-/**
- * Get a configuration attribute name and value, given an index.
- * \param index which field of the __DRIconfig to query
- * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens)
- * \param value returns the attribute's value
- * \return 1 for success, 0 for failure
- */
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value)
-{
- if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
- *attrib = attribMap[index].attrib;
- return driGetConfigAttribIndex(config, index, value);
- }
-
- return GL_FALSE;
-}
+/*
+ * (C) Copyright IBM Corporation 2002, 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file utils.c
+ * Utility functions for DRI drivers.
+ *
+ * \author Ian Romanick <idr@us.ibm.com>
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include "main/mtypes.h"
+#include "main/cpuinfo.h"
+#include "main/extensions.h"
+#include "utils.h"
+
+
+/**
+ * Print message to \c stderr if the \c LIBGL_DEBUG environment variable
+ * is set.
+ *
+ * Is called from the drivers.
+ *
+ * \param f \c printf like format string.
+ */
+void
+__driUtilMessage(const char *f, ...)
+{
+ va_list args;
+
+ if (getenv("LIBGL_DEBUG")) {
+ fprintf(stderr, "libGL: ");
+ va_start(args, f);
+ vfprintf(stderr, f, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ }
+}
+
+
+unsigned
+driParseDebugString( const char * debug,
+ const struct dri_debug_control * control )
+{
+ unsigned flag;
+
+
+ flag = 0;
+ if ( debug != NULL ) {
+ while( control->string != NULL ) {
+ if ( !strcmp( debug, "all" ) ||
+ strstr( debug, control->string ) != NULL ) {
+ flag |= control->flag;
+ }
+
+ control++;
+ }
+ }
+
+ return flag;
+}
+
+
+
+/**
+ * Create the \c GL_RENDERER string for DRI drivers.
+ *
+ * Almost all DRI drivers use a \c GL_RENDERER string of the form:
+ *
+ * "Mesa DRI <chip> <driver date> <AGP speed) <CPU information>"
+ *
+ * Using the supplied chip name, driver data, and AGP speed, this function
+ * creates the string.
+ *
+ * \param buffer Buffer to hold the \c GL_RENDERER string.
+ * \param hardware_name Name of the hardware.
+ * \param agp_mode AGP mode (speed).
+ *
+ * \returns
+ * The length of the string stored in \c buffer. This does \b not include
+ * the terminating \c NUL character.
+ */
+unsigned
+driGetRendererString( char * buffer, const char * hardware_name,
+ GLuint agp_mode )
+{
+ unsigned offset;
+ char *cpu;
+
+ offset = sprintf( buffer, "Mesa DRI %s", hardware_name );
+
+ /* Append any AGP-specific information.
+ */
+ switch ( agp_mode ) {
+ case 1:
+ case 2:
+ case 4:
+ case 8:
+ offset += sprintf( & buffer[ offset ], " AGP %ux", agp_mode );
+ break;
+
+ default:
+ break;
+ }
+
+ /* Append any CPU-specific information.
+ */
+ cpu = _mesa_get_cpu_string();
+ if (cpu) {
+ offset += sprintf(buffer + offset, " %s", cpu);
+ free(cpu);
+ }
+
+ return offset;
+}
+
+
+/**
+ * Utility function used by drivers to test the verions of other components.
+ *
+ * \param driver_name Name of the driver. Used in error messages.
+ * \param driActual Actual DRI version supplied __driCreateNewScreen.
+ * \param driExpected Minimum DRI version required by the driver.
+ * \param ddxActual Actual DDX version supplied __driCreateNewScreen.
+ * \param ddxExpected Minimum DDX minor and range of DDX major version required by the driver.
+ * \param drmActual Actual DRM version supplied __driCreateNewScreen.
+ * \param drmExpected Minimum DRM version required by the driver.
+ *
+ * \returns \c GL_TRUE if all version requirements are met. Otherwise,
+ * \c GL_FALSE is returned.
+ *
+ * \sa __driCreateNewScreen, driCheckDriDdxDrmVersions2
+ *
+ * \todo
+ * Now that the old \c driCheckDriDdxDrmVersions function is gone, this
+ * function and \c driCheckDriDdxDrmVersions2 should be renamed.
+ */
+GLboolean
+driCheckDriDdxDrmVersions3(const char * driver_name,
+ const __DRIversion * driActual,
+ const __DRIversion * driExpected,
+ const __DRIversion * ddxActual,
+ const __DRIutilversion2 * ddxExpected,
+ const __DRIversion * drmActual,
+ const __DRIversion * drmExpected)
+{
+ static const char format[] = "%s DRI driver expected %s version %d.%d.x "
+ "but got version %d.%d.%d\n";
+ static const char format2[] = "%s DRI driver expected %s version %d-%d.%d.x "
+ "but got version %d.%d.%d\n";
+
+
+ /* Check the DRI version */
+ if ( (driActual->major != driExpected->major)
+ || (driActual->minor < driExpected->minor) ) {
+ fprintf(stderr, format, driver_name, "DRI",
+ driExpected->major, driExpected->minor,
+ driActual->major, driActual->minor, driActual->patch);
+ return GL_FALSE;
+ }
+
+ /* Check that the DDX driver version is compatible */
+ if ( (ddxActual->major < ddxExpected->major_min)
+ || (ddxActual->major > ddxExpected->major_max)
+ || (ddxActual->minor < ddxExpected->minor) ) {
+ fprintf(stderr, format2, driver_name, "DDX",
+ ddxExpected->major_min, ddxExpected->major_max, ddxExpected->minor,
+ ddxActual->major, ddxActual->minor, ddxActual->patch);
+ return GL_FALSE;
+ }
+
+ /* Check that the DRM driver version is compatible */
+ if ( (drmActual->major != drmExpected->major)
+ || (drmActual->minor < drmExpected->minor) ) {
+ fprintf(stderr, format, driver_name, "DRM",
+ drmExpected->major, drmExpected->minor,
+ drmActual->major, drmActual->minor, drmActual->patch);
+ return GL_FALSE;
+ }
+
+ return GL_TRUE;
+}
+
+GLboolean
+driCheckDriDdxDrmVersions2(const char * driver_name,
+ const __DRIversion * driActual,
+ const __DRIversion * driExpected,
+ const __DRIversion * ddxActual,
+ const __DRIversion * ddxExpected,
+ const __DRIversion * drmActual,
+ const __DRIversion * drmExpected)
+{
+ __DRIutilversion2 ddx_expected;
+ ddx_expected.major_min = ddxExpected->major;
+ ddx_expected.major_max = ddxExpected->major;
+ ddx_expected.minor = ddxExpected->minor;
+ ddx_expected.patch = ddxExpected->patch;
+ return driCheckDriDdxDrmVersions3(driver_name, driActual,
+ driExpected, ddxActual, & ddx_expected,
+ drmActual, drmExpected);
+}
+
+GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
+ GLint *x, GLint *y,
+ GLsizei *width, GLsizei *height )
+{
+ /* left clipping */
+ if (*x < buffer->_Xmin) {
+ *width -= (buffer->_Xmin - *x);
+ *x = buffer->_Xmin;
+ }
+
+ /* right clipping */
+ if (*x + *width > buffer->_Xmax)
+ *width -= (*x + *width - buffer->_Xmax - 1);
+
+ if (*width <= 0)
+ return GL_FALSE;
+
+ /* bottom clipping */
+ if (*y < buffer->_Ymin) {
+ *height -= (buffer->_Ymin - *y);
+ *y = buffer->_Ymin;
+ }
+
+ /* top clipping */
+ if (*y + *height > buffer->_Ymax)
+ *height -= (*y + *height - buffer->_Ymax - 1);
+
+ if (*height <= 0)
+ return GL_FALSE;
+
+ return GL_TRUE;
+}
+
+/**
+ * Creates a set of \c struct gl_config that a driver will expose.
+ *
+ * A set of \c struct gl_config will be created based on the supplied
+ * parameters. The number of modes processed will be 2 *
+ * \c num_depth_stencil_bits * \c num_db_modes.
+ *
+ * For the most part, data is just copied from \c depth_bits, \c stencil_bits,
+ * \c db_modes, and \c visType into each \c struct gl_config element.
+ * However, the meanings of \c fb_format and \c fb_type require further
+ * explanation. The \c fb_format specifies which color components are in
+ * each pixel and what the default order is. For example, \c GL_RGB specifies
+ * that red, green, blue are available and red is in the "most significant"
+ * position and blue is in the "least significant". The \c fb_type specifies
+ * the bit sizes of each component and the actual ordering. For example, if
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV is specified with \c GL_RGB, bits [15:11]
+ * are the blue value, bits [10:5] are the green value, and bits [4:0] are
+ * the red value.
+ *
+ * One sublte issue is the combination of \c GL_RGB or \c GL_BGR and either
+ * of the \c GL_UNSIGNED_INT_8_8_8_8 modes. The resulting mask values in the
+ * \c struct gl_config structure is \b identical to the \c GL_RGBA or
+ * \c GL_BGRA case, except the \c alphaMask is zero. This means that, as
+ * far as this routine is concerned, \c GL_RGB with \c GL_UNSIGNED_INT_8_8_8_8
+ * still uses 32-bits.
+ *
+ * If in doubt, look at the tables used in the function.
+ *
+ * \param ptr_to_modes Pointer to a pointer to a linked list of
+ * \c struct gl_config. Upon completion, a pointer to
+ * the next element to be process will be stored here.
+ * If the function fails and returns \c GL_FALSE, this
+ * value will be unmodified, but some elements in the
+ * linked list may be modified.
+ * \param fb_format Format of the framebuffer. Currently only \c GL_RGB,
+ * \c GL_RGBA, \c GL_BGR, and \c GL_BGRA are supported.
+ * \param fb_type Type of the pixels in the framebuffer. Currently only
+ * \c GL_UNSIGNED_SHORT_5_6_5,
+ * \c GL_UNSIGNED_SHORT_5_6_5_REV,
+ * \c GL_UNSIGNED_INT_8_8_8_8, and
+ * \c GL_UNSIGNED_INT_8_8_8_8_REV are supported.
+ * \param depth_bits Array of depth buffer sizes to be exposed.
+ * \param stencil_bits Array of stencil buffer sizes to be exposed.
+ * \param num_depth_stencil_bits Number of entries in both \c depth_bits and
+ * \c stencil_bits.
+ * \param db_modes Array of buffer swap modes. If an element has a
+ * value of \c GLX_NONE, then it represents a
+ * single-buffered mode. Other valid values are
+ * \c GLX_SWAP_EXCHANGE_OML, \c GLX_SWAP_COPY_OML, and
+ * \c GLX_SWAP_UNDEFINED_OML. See the
+ * GLX_OML_swap_method extension spec for more details.
+ * \param num_db_modes Number of entries in \c db_modes.
+ * \param msaa_samples Array of msaa sample count. 0 represents a visual
+ * without a multisample buffer.
+ * \param num_msaa_modes Number of entries in \c msaa_samples.
+ * \param visType GLX visual type. Usually either \c GLX_TRUE_COLOR or
+ * \c GLX_DIRECT_COLOR.
+ *
+ * \returns
+ * \c GL_TRUE on success or \c GL_FALSE on failure. Currently the only
+ * cause of failure is a bad parameter (i.e., unsupported \c fb_format or
+ * \c fb_type).
+ *
+ * \todo
+ * There is currently no way to support packed RGB modes (i.e., modes with
+ * exactly 3 bytes per pixel) or floating-point modes. This could probably
+ * be done by creating some new, private enums with clever names likes
+ * \c GL_UNSIGNED_3BYTE_8_8_8, \c GL_4FLOAT_32_32_32_32,
+ * \c GL_4HALF_16_16_16_16, etc. We can cross that bridge when we come to it.
+ */
+__DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+ const uint8_t * depth_bits, const uint8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const GLenum * db_modes, unsigned num_db_modes,
+ const uint8_t * msaa_samples, unsigned num_msaa_modes,
+ GLboolean enable_accum)
+{
+ static const uint8_t bits_table[4][4] = {
+ /* R G B A */
+ { 3, 3, 2, 0 }, /* Any GL_UNSIGNED_BYTE_3_3_2 */
+ { 5, 6, 5, 0 }, /* Any GL_UNSIGNED_SHORT_5_6_5 */
+ { 8, 8, 8, 0 }, /* Any RGB with any GL_UNSIGNED_INT_8_8_8_8 */
+ { 8, 8, 8, 8 } /* Any RGBA with any GL_UNSIGNED_INT_8_8_8_8 */
+ };
+
+ static const uint32_t masks_table_rgb[6][4] = {
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
+ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x00000000 }, /* 8_8_8_8 */
+ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0x00000000 } /* 8_8_8_8_REV */
+ };
+
+ static const uint32_t masks_table_rgba[6][4] = {
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 3_3_2 */
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5 */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5_REV */
+ { 0xFF000000, 0x00FF0000, 0x0000FF00, 0x000000FF }, /* 8_8_8_8 */
+ { 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 }, /* 8_8_8_8_REV */
+ };
+
+ static const uint32_t masks_table_bgr[6][4] = {
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
+ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x00000000 }, /* 8_8_8_8 */
+ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0x00000000 }, /* 8_8_8_8_REV */
+ };
+
+ static const uint32_t masks_table_bgra[6][4] = {
+ { 0x00000007, 0x00000038, 0x000000C0, 0x00000000 }, /* 3_3_2 */
+ { 0x000000E0, 0x0000001C, 0x00000003, 0x00000000 }, /* 2_3_3_REV */
+ { 0x0000001F, 0x000007E0, 0x0000F800, 0x00000000 }, /* 5_6_5 */
+ { 0x0000F800, 0x000007E0, 0x0000001F, 0x00000000 }, /* 5_6_5_REV */
+ { 0x0000FF00, 0x00FF0000, 0xFF000000, 0x000000FF }, /* 8_8_8_8 */
+ { 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000 }, /* 8_8_8_8_REV */
+ };
+
+ static const uint8_t bytes_per_pixel[6] = {
+ 1, /* 3_3_2 */
+ 1, /* 2_3_3_REV */
+ 2, /* 5_6_5 */
+ 2, /* 5_6_5_REV */
+ 4, /* 8_8_8_8 */
+ 4 /* 8_8_8_8_REV */
+ };
+
+ const uint8_t * bits;
+ const uint32_t * masks;
+ int index;
+ __DRIconfig **configs, **c;
+ struct gl_config *modes;
+ unsigned i, j, k, h;
+ unsigned num_modes;
+ unsigned num_accum_bits = (enable_accum) ? 2 : 1;
+
+ switch ( fb_type ) {
+ case GL_UNSIGNED_BYTE_3_3_2:
+ index = 0;
+ break;
+ case GL_UNSIGNED_BYTE_2_3_3_REV:
+ index = 1;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5:
+ index = 2;
+ break;
+ case GL_UNSIGNED_SHORT_5_6_5_REV:
+ index = 3;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8:
+ index = 4;
+ break;
+ case GL_UNSIGNED_INT_8_8_8_8_REV:
+ index = 5;
+ break;
+ default:
+ fprintf( stderr, "[%s:%u] Unknown framebuffer type 0x%04x.\n",
+ __FUNCTION__, __LINE__, fb_type );
+ return NULL;
+ }
+
+
+ /* Valid types are GL_UNSIGNED_SHORT_5_6_5 and GL_UNSIGNED_INT_8_8_8_8 and
+ * the _REV versions.
+ *
+ * Valid formats are GL_RGBA, GL_RGB, and GL_BGRA.
+ */
+
+ switch ( fb_format ) {
+ case GL_RGB:
+ masks = masks_table_rgb[ index ];
+ break;
+
+ case GL_RGBA:
+ masks = masks_table_rgba[ index ];
+ break;
+
+ case GL_BGR:
+ masks = masks_table_bgr[ index ];
+ break;
+
+ case GL_BGRA:
+ masks = masks_table_bgra[ index ];
+ break;
+
+ default:
+ fprintf( stderr, "[%s:%u] Unknown framebuffer format 0x%04x.\n",
+ __FUNCTION__, __LINE__, fb_format );
+ return NULL;
+ }
+
+ switch ( bytes_per_pixel[ index ] ) {
+ case 1:
+ bits = bits_table[0];
+ break;
+ case 2:
+ bits = bits_table[1];
+ break;
+ default:
+ bits = ((fb_format == GL_RGB) || (fb_format == GL_BGR))
+ ? bits_table[2]
+ : bits_table[3];
+ break;
+ }
+
+ num_modes = num_depth_stencil_bits * num_db_modes * num_accum_bits * num_msaa_modes;
+ configs = calloc(1, (num_modes + 1) * sizeof *configs);
+ if (configs == NULL)
+ return NULL;
+
+ c = configs;
+ for ( k = 0 ; k < num_depth_stencil_bits ; k++ ) {
+ for ( i = 0 ; i < num_db_modes ; i++ ) {
+ for ( h = 0 ; h < num_msaa_modes; h++ ) {
+ for ( j = 0 ; j < num_accum_bits ; j++ ) {
+ *c = malloc (sizeof **c);
+ modes = &(*c)->modes;
+ c++;
+
+ memset(modes, 0, sizeof *modes);
+ modes->redBits = bits[0];
+ modes->greenBits = bits[1];
+ modes->blueBits = bits[2];
+ modes->alphaBits = bits[3];
+ modes->redMask = masks[0];
+ modes->greenMask = masks[1];
+ modes->blueMask = masks[2];
+ modes->alphaMask = masks[3];
+ modes->rgbBits = modes->redBits + modes->greenBits
+ + modes->blueBits + modes->alphaBits;
+
+ modes->accumRedBits = 16 * j;
+ modes->accumGreenBits = 16 * j;
+ modes->accumBlueBits = 16 * j;
+ modes->accumAlphaBits = (masks[3] != 0) ? 16 * j : 0;
+ modes->visualRating = (j == 0) ? GLX_NONE : GLX_SLOW_CONFIG;
+
+ modes->stencilBits = stencil_bits[k];
+ modes->depthBits = depth_bits[k];
+
+ modes->transparentPixel = GLX_NONE;
+ modes->transparentRed = GLX_DONT_CARE;
+ modes->transparentGreen = GLX_DONT_CARE;
+ modes->transparentBlue = GLX_DONT_CARE;
+ modes->transparentAlpha = GLX_DONT_CARE;
+ modes->transparentIndex = GLX_DONT_CARE;
+ modes->rgbMode = GL_TRUE;
+
+ if ( db_modes[i] == GLX_NONE ) {
+ modes->doubleBufferMode = GL_FALSE;
+ }
+ else {
+ modes->doubleBufferMode = GL_TRUE;
+ modes->swapMethod = db_modes[i];
+ }
+
+ modes->samples = msaa_samples[h];
+ modes->sampleBuffers = modes->samples ? 1 : 0;
+
+
+ modes->haveAccumBuffer = ((modes->accumRedBits +
+ modes->accumGreenBits +
+ modes->accumBlueBits +
+ modes->accumAlphaBits) > 0);
+ modes->haveDepthBuffer = (modes->depthBits > 0);
+ modes->haveStencilBuffer = (modes->stencilBits > 0);
+
+ modes->bindToTextureRgb = GL_TRUE;
+ modes->bindToTextureRgba = GL_TRUE;
+ modes->bindToMipmapTexture = GL_FALSE;
+ modes->bindToTextureTargets =
+ __DRI_ATTRIB_TEXTURE_1D_BIT |
+ __DRI_ATTRIB_TEXTURE_2D_BIT |
+ __DRI_ATTRIB_TEXTURE_RECTANGLE_BIT;
+
+ modes->sRGBCapable = GL_FALSE;
+ }
+ }
+ }
+ }
+ *c = NULL;
+
+ return configs;
+}
+
+__DRIconfig **driConcatConfigs(__DRIconfig **a,
+ __DRIconfig **b)
+{
+ __DRIconfig **all;
+ int i, j, index;
+
+ i = 0;
+ while (a[i] != NULL)
+ i++;
+ j = 0;
+ while (b[j] != NULL)
+ j++;
+
+ all = malloc((i + j + 1) * sizeof *all);
+ index = 0;
+ for (i = 0; a[i] != NULL; i++)
+ all[index++] = a[i];
+ for (j = 0; b[j] != NULL; j++)
+ all[index++] = b[j];
+ all[index++] = NULL;
+
+ free(a);
+ free(b);
+
+ return all;
+}
+
+#define __ATTRIB(attrib, field) \
+ { attrib, offsetof(struct gl_config, field) }
+
+static const struct { unsigned int attrib, offset; } attribMap[] = {
+ __ATTRIB(__DRI_ATTRIB_BUFFER_SIZE, rgbBits),
+ __ATTRIB(__DRI_ATTRIB_LEVEL, level),
+ __ATTRIB(__DRI_ATTRIB_RED_SIZE, redBits),
+ __ATTRIB(__DRI_ATTRIB_GREEN_SIZE, greenBits),
+ __ATTRIB(__DRI_ATTRIB_BLUE_SIZE, blueBits),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_SIZE, alphaBits),
+ __ATTRIB(__DRI_ATTRIB_DEPTH_SIZE, depthBits),
+ __ATTRIB(__DRI_ATTRIB_STENCIL_SIZE, stencilBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_RED_SIZE, accumRedBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_GREEN_SIZE, accumGreenBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_BLUE_SIZE, accumBlueBits),
+ __ATTRIB(__DRI_ATTRIB_ACCUM_ALPHA_SIZE, accumAlphaBits),
+ __ATTRIB(__DRI_ATTRIB_SAMPLE_BUFFERS, sampleBuffers),
+ __ATTRIB(__DRI_ATTRIB_SAMPLES, samples),
+ __ATTRIB(__DRI_ATTRIB_DOUBLE_BUFFER, doubleBufferMode),
+ __ATTRIB(__DRI_ATTRIB_STEREO, stereoMode),
+ __ATTRIB(__DRI_ATTRIB_AUX_BUFFERS, numAuxBuffers),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_TYPE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_INDEX_VALUE, transparentPixel),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_RED_VALUE, transparentRed),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_GREEN_VALUE, transparentGreen),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_BLUE_VALUE, transparentBlue),
+ __ATTRIB(__DRI_ATTRIB_TRANSPARENT_ALPHA_VALUE, transparentAlpha),
+ __ATTRIB(__DRI_ATTRIB_FLOAT_MODE, floatMode),
+ __ATTRIB(__DRI_ATTRIB_RED_MASK, redMask),
+ __ATTRIB(__DRI_ATTRIB_GREEN_MASK, greenMask),
+ __ATTRIB(__DRI_ATTRIB_BLUE_MASK, blueMask),
+ __ATTRIB(__DRI_ATTRIB_ALPHA_MASK, alphaMask),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_WIDTH, maxPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_HEIGHT, maxPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_MAX_PBUFFER_PIXELS, maxPbufferPixels),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_WIDTH, optimalPbufferWidth),
+ __ATTRIB(__DRI_ATTRIB_OPTIMAL_PBUFFER_HEIGHT, optimalPbufferHeight),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, swapMethod),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGB, bindToTextureRgb),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_RGBA, bindToTextureRgba),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE, bindToMipmapTexture),
+ __ATTRIB(__DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS, bindToTextureTargets),
+ __ATTRIB(__DRI_ATTRIB_YINVERTED, yInverted),
+ __ATTRIB(__DRI_ATTRIB_FRAMEBUFFER_SRGB_CAPABLE, sRGBCapable),
+
+ /* The struct field doesn't matter here, these are handled by the
+ * switch in driGetConfigAttribIndex. We need them in the array
+ * so the iterator includes them though.*/
+ __ATTRIB(__DRI_ATTRIB_RENDER_TYPE, level),
+ __ATTRIB(__DRI_ATTRIB_CONFIG_CAVEAT, level),
+ __ATTRIB(__DRI_ATTRIB_SWAP_METHOD, level)
+};
+
+#define ARRAY_SIZE(a) (sizeof (a) / sizeof ((a)[0]))
+
+
+/**
+ * Return the value of a configuration attribute. The attribute is
+ * indicated by the index.
+ */
+static int
+driGetConfigAttribIndex(const __DRIconfig *config,
+ unsigned int index, unsigned int *value)
+{
+ switch (attribMap[index].attrib) {
+ case __DRI_ATTRIB_RENDER_TYPE:
+ /* no support for color index mode */
+ *value = __DRI_ATTRIB_RGBA_BIT;
+ break;
+ case __DRI_ATTRIB_CONFIG_CAVEAT:
+ if (config->modes.visualRating == GLX_NON_CONFORMANT_CONFIG)
+ *value = __DRI_ATTRIB_NON_CONFORMANT_CONFIG;
+ else if (config->modes.visualRating == GLX_SLOW_CONFIG)
+ *value = __DRI_ATTRIB_SLOW_BIT;
+ else
+ *value = 0;
+ break;
+ case __DRI_ATTRIB_SWAP_METHOD:
+ /* XXX no return value??? */
+ break;
+
+ case __DRI_ATTRIB_FLOAT_MODE:
+ /* this field is not int-sized */
+ *value = config->modes.floatMode;
+ break;
+
+ default:
+ /* any other int-sized field */
+ *value = *(unsigned int *)
+ ((char *) &config->modes + attribMap[index].offset);
+
+ break;
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Get the value of a configuration attribute.
+ * \param attrib the attribute (one of the _DRI_ATTRIB_x tokens)
+ * \param value returns the attribute's value
+ * \return 1 for success, 0 for failure
+ */
+int
+driGetConfigAttrib(const __DRIconfig *config,
+ unsigned int attrib, unsigned int *value)
+{
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(attribMap); i++)
+ if (attribMap[i].attrib == attrib)
+ return driGetConfigAttribIndex(config, i, value);
+
+ return GL_FALSE;
+}
+
+
+/**
+ * Get a configuration attribute name and value, given an index.
+ * \param index which field of the __DRIconfig to query
+ * \param attrib returns the attribute name (one of the _DRI_ATTRIB_x tokens)
+ * \param value returns the attribute's value
+ * \return 1 for success, 0 for failure
+ */
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+ unsigned int *attrib, unsigned int *value)
+{
+ if (index >= 0 && index < ARRAY_SIZE(attribMap)) {
+ *attrib = attribMap[index].attrib;
+ return driGetConfigAttribIndex(config, index, value);
+ }
+
+ return GL_FALSE;
+}
diff --git a/mesalib/src/mesa/drivers/dri/common/utils.h b/mesalib/src/mesa/drivers/dri/common/utils.h
index 10fb23de9..100d0dd51 100644
--- a/mesalib/src/mesa/drivers/dri/common/utils.h
+++ b/mesalib/src/mesa/drivers/dri/common/utils.h
@@ -1,123 +1,98 @@
-/*
- * (C) Copyright IBM Corporation 2002, 2004
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * on the rights to use, copy, modify, merge, publish, distribute, sub
- * license, and/or sell copies of the Software, and to permit persons to whom
- * the Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the next
- * paragraph) shall be included in all copies or substantial portions of the
- * Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
- * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
- * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
- * USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Ian Romanick <idr@us.ibm.com>
- */
-
-#ifndef DRI_DEBUG_H
-#define DRI_DEBUG_H
-
-#include <GL/gl.h>
-#include <GL/internal/dri_interface.h>
-#include "main/context.h"
-#include "main/remap.h"
-
-typedef struct __DRIutilversionRec2 __DRIutilversion2;
-
-struct dri_debug_control {
- const char * string;
- unsigned flag;
-};
-
-/**
- * Description of the API for an extension to OpenGL.
- */
-struct dri_extension {
- /**
- * Name of the extension.
- */
- const char * name;
-
-
- /**
- * Pointer to a list of \c dri_extension_function structures. The list
- * is terminated by a structure with a \c NULL
- * \c dri_extension_function::strings pointer.
- */
- const struct gl_function_remap * functions;
-};
-
-/**
- * Used to store a version which includes a major range instead of a single
- * major version number.
- */
-struct __DRIutilversionRec2 {
- int major_min; /** min allowed Major version number. */
- int major_max; /** max allowed Major version number. */
- int minor; /**< Minor version number. */
- int patch; /**< Patch-level. */
-};
-
-extern void
-__driUtilMessage(const char *f, ...);
-
-extern unsigned driParseDebugString( const char * debug,
- const struct dri_debug_control * control );
-
-extern unsigned driGetRendererString( char * buffer,
- const char * hardware_name, GLuint agp_mode );
-
-extern void driInitExtensions( struct gl_context * ctx,
- const struct dri_extension * card_extensions, GLboolean enable_imaging );
-
-extern void driInitSingleExtension( struct gl_context * ctx,
- const struct dri_extension * ext );
-
-extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name,
- const __DRIversion * driActual, const __DRIversion * driExpected,
- const __DRIversion * ddxActual, const __DRIversion * ddxExpected,
- const __DRIversion * drmActual, const __DRIversion * drmExpected);
-
-extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
- const __DRIversion * driActual, const __DRIversion * driExpected,
- const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
- const __DRIversion * drmActual, const __DRIversion * drmExpected);
-
-extern GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
- GLint *x, GLint *y,
- GLsizei *width, GLsizei *height );
-
-struct __DRIconfigRec {
- struct gl_config modes;
-};
-
-extern __DRIconfig **
-driCreateConfigs(GLenum fb_format, GLenum fb_type,
- const uint8_t * depth_bits, const uint8_t * stencil_bits,
- unsigned num_depth_stencil_bits,
- const GLenum * db_modes, unsigned num_db_modes,
- const uint8_t * msaa_samples, unsigned num_msaa_modes,
- GLboolean enable_accum);
-
-__DRIconfig **driConcatConfigs(__DRIconfig **a,
- __DRIconfig **b);
-
-int
-driGetConfigAttrib(const __DRIconfig *config,
- unsigned int attrib, unsigned int *value);
-int
-driIndexConfigAttrib(const __DRIconfig *config, int index,
- unsigned int *attrib, unsigned int *value);
-
-#endif /* DRI_DEBUG_H */
+/*
+ * (C) Copyright IBM Corporation 2002, 2004
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * on the rights to use, copy, modify, merge, publish, distribute, sub
+ * license, and/or sell copies of the Software, and to permit persons to whom
+ * the Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * VA LINUX SYSTEM, IBM AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
+ * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
+ * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
+ * USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Ian Romanick <idr@us.ibm.com>
+ */
+
+#ifndef DRI_DEBUG_H
+#define DRI_DEBUG_H
+
+#include <GL/gl.h>
+#include <GL/internal/dri_interface.h>
+#include "main/context.h"
+
+typedef struct __DRIutilversionRec2 __DRIutilversion2;
+
+struct dri_debug_control {
+ const char * string;
+ unsigned flag;
+};
+
+/**
+ * Used to store a version which includes a major range instead of a single
+ * major version number.
+ */
+struct __DRIutilversionRec2 {
+ int major_min; /** min allowed Major version number. */
+ int major_max; /** max allowed Major version number. */
+ int minor; /**< Minor version number. */
+ int patch; /**< Patch-level. */
+};
+
+extern void
+__driUtilMessage(const char *f, ...);
+
+extern unsigned driParseDebugString( const char * debug,
+ const struct dri_debug_control * control );
+
+extern unsigned driGetRendererString( char * buffer,
+ const char * hardware_name, GLuint agp_mode );
+
+extern GLboolean driCheckDriDdxDrmVersions2(const char * driver_name,
+ const __DRIversion * driActual, const __DRIversion * driExpected,
+ const __DRIversion * ddxActual, const __DRIversion * ddxExpected,
+ const __DRIversion * drmActual, const __DRIversion * drmExpected);
+
+extern GLboolean driCheckDriDdxDrmVersions3(const char * driver_name,
+ const __DRIversion * driActual, const __DRIversion * driExpected,
+ const __DRIversion * ddxActual, const __DRIutilversion2 * ddxExpected,
+ const __DRIversion * drmActual, const __DRIversion * drmExpected);
+
+extern GLboolean driClipRectToFramebuffer( const struct gl_framebuffer *buffer,
+ GLint *x, GLint *y,
+ GLsizei *width, GLsizei *height );
+
+struct __DRIconfigRec {
+ struct gl_config modes;
+};
+
+extern __DRIconfig **
+driCreateConfigs(GLenum fb_format, GLenum fb_type,
+ const uint8_t * depth_bits, const uint8_t * stencil_bits,
+ unsigned num_depth_stencil_bits,
+ const GLenum * db_modes, unsigned num_db_modes,
+ const uint8_t * msaa_samples, unsigned num_msaa_modes,
+ GLboolean enable_accum);
+
+__DRIconfig **driConcatConfigs(__DRIconfig **a,
+ __DRIconfig **b);
+
+int
+driGetConfigAttrib(const __DRIconfig *config,
+ unsigned int attrib, unsigned int *value);
+int
+driIndexConfigAttrib(const __DRIconfig *config, int index,
+ unsigned int *attrib, unsigned int *value);
+
+#endif /* DRI_DEBUG_H */
diff --git a/mesalib/src/mesa/drivers/dri/swrast/swrast.c b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
index 719b406ec..6c94947a0 100644
--- a/mesalib/src/mesa/drivers/dri/swrast/swrast.c
+++ b/mesalib/src/mesa/drivers/dri/swrast/swrast.c
@@ -135,6 +135,9 @@ swrastFillInModes(__DRIscreen *psp,
uint8_t stencil_bits_array[4];
uint8_t msaa_samples_array[1];
+ (void) psp;
+ (void) have_back_buffer;
+
depth_bits_array[0] = 0;
depth_bits_array[1] = 0;
depth_bits_array[2] = depth_bits;
@@ -215,6 +218,7 @@ static void
dri_destroy_screen(__DRIscreen * sPriv)
{
TRACE;
+ (void) sPriv;
}
@@ -278,6 +282,9 @@ swrast_alloc_front_storage(struct gl_context *ctx, struct gl_renderbuffer *rb,
TRACE;
+ (void) ctx;
+ (void) internalFormat;
+
rb->Data = NULL;
rb->Width = width;
rb->Height = height;
@@ -376,6 +383,9 @@ dri_create_buffer(__DRIscreen * sPriv,
TRACE;
+ (void) sPriv;
+ (void) isPixmap;
+
drawable = CALLOC_STRUCT(dri_drawable);
if (drawable == NULL)
goto drawable_fail;
@@ -537,6 +547,10 @@ viewport(struct gl_context *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
struct gl_framebuffer *draw = ctx->WinSysDrawBuffer;
struct gl_framebuffer *read = ctx->WinSysReadBuffer;
+ (void) x;
+ (void) y;
+ (void) w;
+ (void) h;
swrast_check_and_update_window_size(ctx, draw);
swrast_check_and_update_window_size(ctx, read);
}
@@ -609,9 +623,6 @@ InitExtensionsES2(struct gl_context *ctx)
{
int i;
- /* Can't use driInitExtensions() since it uses extensions from
- * main/remap_helper.h when called the first time. */
-
for (i = 0; es2_extensions[i]; i++)
_mesa_enable_extension(ctx, es2_extensions[i]);
}
@@ -681,8 +692,6 @@ dri_create_context(gl_api api,
_mesa_enable_1_5_extensions(mesaCtx);
_mesa_enable_2_0_extensions(mesaCtx);
_mesa_enable_2_1_extensions(mesaCtx);
-
- driInitExtensions( mesaCtx, NULL, GL_FALSE );
break;
case API_OPENGLES:
_mesa_enable_1_3_extensions(mesaCtx);
diff --git a/mesalib/src/mesa/main/extensions.c b/mesalib/src/mesa/main/extensions.c
index 1903a503c..9cec15b58 100644
--- a/mesalib/src/mesa/main/extensions.c
+++ b/mesalib/src/mesa/main/extensions.c
@@ -37,6 +37,8 @@
#include "mfeatures.h"
#include "mtypes.h"
+#define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
+
enum {
DISABLE = 0,
GL = 1 << API_OPENGL,
@@ -769,11 +771,11 @@ get_extension_override( struct gl_context *ctx )
if (env_const == NULL) {
/* Return the empty string rather than NULL. This simplifies the logic
* of client functions. */
- return calloc(1, sizeof(char));
+ return calloc(4, sizeof(char));
}
/* extra_exts: List of unrecognized extensions. */
- extra_exts = calloc(strlen(env_const), sizeof(char));
+ extra_exts = calloc(ALIGN(strlen(env_const) + 2, 4), sizeof(char));
/* Copy env_const because strtok() is destructive. */
env = strdup(env_const);
@@ -907,7 +909,7 @@ _mesa_make_extension_string(struct gl_context *ctx)
if (extra_extensions != NULL)
length += 1 + strlen(extra_extensions); /* +1 for space */
- exts = (char *) calloc(length + 1, sizeof(char));
+ exts = (char *) calloc(ALIGN(length + 1, 4), sizeof(char));
if (exts == NULL) {
free(extra_extensions);
return NULL;
diff --git a/mesalib/src/mesa/main/nvprogram.c b/mesalib/src/mesa/main/nvprogram.c
index 7ff7645b7..a0e89b10f 100644
--- a/mesalib/src/mesa/main/nvprogram.c
+++ b/mesalib/src/mesa/main/nvprogram.c
@@ -560,7 +560,7 @@ _mesa_emit_nv_temp_initialization(struct gl_context *ctx,
}
void
-_mesa_setup_nv_temporary_count(struct gl_context *ctx, struct gl_program *program)
+_mesa_setup_nv_temporary_count(struct gl_program *program)
{
GLuint i;
diff --git a/mesalib/src/mesa/main/nvprogram.h b/mesalib/src/mesa/main/nvprogram.h
index 3d12b4e33..fc579a9fe 100644
--- a/mesalib/src/mesa/main/nvprogram.h
+++ b/mesalib/src/mesa/main/nvprogram.h
@@ -1,119 +1,119 @@
-/*
- * Mesa 3-D graphics library
- * Version: 5.1
- *
- * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- *
- * Authors:
- * Brian Paul
- */
-
-
-#ifndef NVPROGRAM_H
-#define NVPROGRAM_H
-
-#include "glheader.h"
-
-struct gl_context;
-struct gl_program;
-
-extern void GLAPIENTRY
-_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
-
-extern GLboolean GLAPIENTRY
-_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
-
-extern void GLAPIENTRY
-_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
-
-extern void GLAPIENTRY
-_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
-
-extern void GLAPIENTRY
-_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLsizei num,
- const GLdouble *params);
-
-extern void GLAPIENTRY
-_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLsizei num,
- const GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
-
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
- GLfloat x, GLfloat y, GLfloat z, GLfloat w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
- const float v[]);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
- GLdouble x, GLdouble y, GLdouble z, GLdouble w);
-
-extern void GLAPIENTRY
-_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
- const double v[]);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
- GLfloat *params);
-
-extern void GLAPIENTRY
-_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
- GLdouble *params);
-
-extern void
-_mesa_setup_nv_temporary_count(struct gl_context *ctx, struct gl_program *program);
-
-extern void
-_mesa_emit_nv_temp_initialization(struct gl_context *ctx,
- struct gl_program *program);
-
-#endif
+/*
+ * Mesa 3-D graphics library
+ * Version: 5.1
+ *
+ * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Authors:
+ * Brian Paul
+ */
+
+
+#ifndef NVPROGRAM_H
+#define NVPROGRAM_H
+
+#include "glheader.h"
+
+struct gl_context;
+struct gl_program;
+
+extern void GLAPIENTRY
+_mesa_ExecuteProgramNV(GLenum target, GLuint id, const GLfloat *params);
+
+extern GLboolean GLAPIENTRY
+_mesa_AreProgramsResidentNV(GLsizei n, const GLuint *ids, GLboolean *residences);
+
+extern void GLAPIENTRY
+_mesa_RequestResidentProgramsNV(GLsizei n, const GLuint *ids);
+
+extern void GLAPIENTRY
+_mesa_GetProgramParameterfvNV(GLenum target, GLuint index, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramParameterdvNV(GLenum target, GLuint index, GLenum pname, GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramivNV(GLuint id, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramStringNV(GLuint id, GLenum pname, GLubyte *program);
+
+extern void GLAPIENTRY
+_mesa_GetTrackMatrixivNV(GLenum target, GLuint address, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribdvNV(GLuint index, GLenum pname, GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribfvNV(GLuint index, GLenum pname, GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribivNV(GLuint index, GLenum pname, GLint *params);
+
+extern void GLAPIENTRY
+_mesa_GetVertexAttribPointervNV(GLuint index, GLenum pname, GLvoid **pointer);
+
+extern void GLAPIENTRY
+_mesa_LoadProgramNV(GLenum target, GLuint id, GLsizei len, const GLubyte *program);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameters4dvNV(GLenum target, GLuint index, GLsizei num,
+ const GLdouble *params);
+
+extern void GLAPIENTRY
+_mesa_ProgramParameters4fvNV(GLenum target, GLuint index, GLsizei num,
+ const GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_TrackMatrixNV(GLenum target, GLuint address, GLenum matrix, GLenum transform);
+
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4fNV(GLuint id, GLsizei len, const GLubyte *name,
+ GLfloat x, GLfloat y, GLfloat z, GLfloat w);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4fvNV(GLuint id, GLsizei len, const GLubyte *name,
+ const float v[]);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4dNV(GLuint id, GLsizei len, const GLubyte *name,
+ GLdouble x, GLdouble y, GLdouble z, GLdouble w);
+
+extern void GLAPIENTRY
+_mesa_ProgramNamedParameter4dvNV(GLuint id, GLsizei len, const GLubyte *name,
+ const double v[]);
+
+extern void GLAPIENTRY
+_mesa_GetProgramNamedParameterfvNV(GLuint id, GLsizei len, const GLubyte *name,
+ GLfloat *params);
+
+extern void GLAPIENTRY
+_mesa_GetProgramNamedParameterdvNV(GLuint id, GLsizei len, const GLubyte *name,
+ GLdouble *params);
+
+extern void
+_mesa_setup_nv_temporary_count(struct gl_program *program);
+
+extern void
+_mesa_emit_nv_temp_initialization(struct gl_context *ctx,
+ struct gl_program *program);
+
+#endif
diff --git a/mesalib/src/mesa/main/teximage.h b/mesalib/src/mesa/main/teximage.h
index b59961eaf..8ef1d4560 100644
--- a/mesalib/src/mesa/main/teximage.h
+++ b/mesalib/src/mesa/main/teximage.h
@@ -1,285 +1,286 @@
-/**
- * \file teximage.h
- * Texture images manipulation functions.
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 6.5
- *
- * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef TEXIMAGE_H
-#define TEXIMAGE_H
-
-
-#include "mtypes.h"
-#include "formats.h"
-
-
-extern void *
-_mesa_alloc_texmemory(GLsizei bytes);
-
-extern void
-_mesa_free_texmemory(void *m);
-
-
-/** \name Internal functions */
-/*@{*/
-
-extern GLint
-_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat );
-
-
-extern GLboolean
-_mesa_is_proxy_texture(GLenum target);
-
-
-extern struct gl_texture_image *
-_mesa_new_texture_image( struct gl_context *ctx );
-
-
-extern void
-_mesa_delete_texture_image( struct gl_context *ctx,
- struct gl_texture_image *teximage );
-
-extern void
-_mesa_free_texture_image_data( struct gl_context *ctx,
- struct gl_texture_image *texImage );
-
-
-extern void
-_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
- struct gl_texture_image *img,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum internalFormat,
- gl_format format);
-
-
-extern gl_format
-_mesa_choose_texture_format(struct gl_context *ctx,
- struct gl_texture_object *texObj,
- GLenum target, GLint level,
- GLenum internalFormat, GLenum format, GLenum type);
-
-
-extern void
-_mesa_clear_texture_image(struct gl_context *ctx,
- struct gl_texture_image *texImage);
-
-
-extern void
-_mesa_set_tex_image(struct gl_texture_object *tObj,
- GLenum target, GLint level,
- struct gl_texture_image *texImage);
-
-
-extern struct gl_texture_object *
-_mesa_select_tex_object(struct gl_context *ctx,
- const struct gl_texture_unit *texUnit,
- GLenum target);
-
-extern struct gl_texture_object *
-_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target);
-
-
-extern struct gl_texture_image *
-_mesa_select_tex_image(struct gl_context *ctx,
- const struct gl_texture_object *texObj,
- GLenum target, GLint level);
-
-
-extern struct gl_texture_image *
-_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
- GLenum target, GLint level);
-
-
-extern struct gl_texture_image *
-_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level);
-
-
-extern GLint
-_mesa_max_texture_levels(struct gl_context *ctx, GLenum target);
-
-
-extern GLboolean
-_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
- GLint internalFormat, GLenum format, GLenum type,
- GLint width, GLint height, GLint depth, GLint border);
-
-
-extern GLuint
-_mesa_tex_target_to_face(GLenum target);
-
-extern GLint
-_mesa_get_texture_dimensions(GLenum target);
-
-/**
- * Lock a texture for updating. See also _mesa_lock_context_textures().
- */
-static INLINE void
-_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
- ctx->Shared->TextureStateStamp++;
- (void) texObj;
-}
-
-static INLINE void
-_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
-{
- _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
-}
-
-/*@}*/
-
-
-/** \name API entry point functions */
-/*@{*/
-
-extern void GLAPIENTRY
-_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
- GLsizei width, GLsizei height, GLsizei depth, GLint border,
- GLenum format, GLenum type, const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
- GLsizei width, GLsizei height, GLsizei depth,
- GLint border, GLenum format, GLenum type,
- const GLvoid *pixels );
-
-extern void GLAPIENTRY
-_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image );
-
-extern void GLAPIENTRY
-_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
- GLsizei width,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexSubImage2D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLsizei width, GLsizei height,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_TexSubImage3D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLsizei width, GLsizei height, GLsizei depth,
- GLenum format, GLenum type,
- const GLvoid *pixels );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
- GLint x, GLint y, GLsizei width, GLint border );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexImage2D( GLenum target, GLint level,
- GLenum internalformat, GLint x, GLint y,
- GLsizei width, GLsizei height, GLint border );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
- GLint x, GLint y, GLsizei width );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage2D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset,
- GLint x, GLint y, GLsizei width, GLsizei height );
-
-
-extern void GLAPIENTRY
-_mesa_CopyTexSubImage3D( GLenum target, GLint level,
- GLint xoffset, GLint yoffset, GLint zoffset,
- GLint x, GLint y, GLsizei width, GLsizei height );
-
-
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
- GLint border, GLsizei imageSize,
- const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
- GLsizei height, GLint border, GLsizei imageSize,
- const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
- GLenum internalformat, GLsizei width,
- GLsizei height, GLsizei depth, GLint border,
- GLsizei imageSize, const GLvoid *data);
-
-#ifdef VMS
-#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR
-#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR
-#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR
-#endif
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
- GLsizei width, GLenum format,
- GLsizei imageSize, const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLsizei width, GLsizei height,
- GLenum format, GLsizei imageSize,
- const GLvoid *data);
-
-extern void GLAPIENTRY
-_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
- GLint yoffset, GLint zoffset, GLsizei width,
- GLsizei height, GLsizei depth, GLenum format,
- GLsizei imageSize, const GLvoid *data);
-
-
-extern void GLAPIENTRY
-_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
-
-
-/*@}*/
-
-#endif
+/**
+ * \file teximage.h
+ * Texture images manipulation functions.
+ */
+
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5
+ *
+ * Copyright (C) 1999-2005 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+#ifndef TEXIMAGE_H
+#define TEXIMAGE_H
+
+
+#include "mtypes.h"
+#include "formats.h"
+
+
+extern void *
+_mesa_alloc_texmemory(GLsizei bytes);
+
+extern void
+_mesa_free_texmemory(void *m);
+
+
+/** \name Internal functions */
+/*@{*/
+
+extern GLint
+_mesa_base_tex_format( struct gl_context *ctx, GLint internalFormat );
+
+
+extern GLboolean
+_mesa_is_proxy_texture(GLenum target);
+
+
+extern struct gl_texture_image *
+_mesa_new_texture_image( struct gl_context *ctx );
+
+
+extern void
+_mesa_delete_texture_image( struct gl_context *ctx,
+ struct gl_texture_image *teximage );
+
+extern void
+_mesa_free_texture_image_data( struct gl_context *ctx,
+ struct gl_texture_image *texImage );
+
+
+extern void
+_mesa_init_teximage_fields(struct gl_context *ctx, GLenum target,
+ struct gl_texture_image *img,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum internalFormat,
+ gl_format format);
+
+
+extern gl_format
+_mesa_choose_texture_format(struct gl_context *ctx,
+ struct gl_texture_object *texObj,
+ GLenum target, GLint level,
+ GLenum internalFormat, GLenum format, GLenum type);
+
+
+extern void
+_mesa_clear_texture_image(struct gl_context *ctx,
+ struct gl_texture_image *texImage);
+
+
+extern void
+_mesa_set_tex_image(struct gl_texture_object *tObj,
+ GLenum target, GLint level,
+ struct gl_texture_image *texImage);
+
+
+extern struct gl_texture_object *
+_mesa_select_tex_object(struct gl_context *ctx,
+ const struct gl_texture_unit *texUnit,
+ GLenum target);
+
+extern struct gl_texture_object *
+_mesa_get_current_tex_object(struct gl_context *ctx, GLenum target);
+
+
+extern struct gl_texture_image *
+_mesa_select_tex_image(struct gl_context *ctx,
+ const struct gl_texture_object *texObj,
+ GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_tex_image(struct gl_context *ctx, struct gl_texture_object *texObj,
+ GLenum target, GLint level);
+
+
+extern struct gl_texture_image *
+_mesa_get_proxy_tex_image(struct gl_context *ctx, GLenum target, GLint level);
+
+
+extern GLint
+_mesa_max_texture_levels(struct gl_context *ctx, GLenum target);
+
+
+extern GLboolean
+_mesa_test_proxy_teximage(struct gl_context *ctx, GLenum target, GLint level,
+ GLint internalFormat, GLenum format, GLenum type,
+ GLint width, GLint height, GLint depth, GLint border);
+
+
+extern GLuint
+_mesa_tex_target_to_face(GLenum target);
+
+extern GLint
+_mesa_get_texture_dimensions(GLenum target);
+
+/**
+ * Lock a texture for updating. See also _mesa_lock_context_textures().
+ */
+static INLINE void
+_mesa_lock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ _glthread_LOCK_MUTEX(ctx->Shared->TexMutex);
+ ctx->Shared->TextureStateStamp++;
+ (void) texObj;
+}
+
+static INLINE void
+_mesa_unlock_texture(struct gl_context *ctx, struct gl_texture_object *texObj)
+{
+ (void) texObj;
+ _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex);
+}
+
+/*@}*/
+
+
+/** \name API entry point functions */
+/*@{*/
+
+extern void GLAPIENTRY
+_mesa_TexImage1D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage2D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage3D( GLenum target, GLint level, GLint internalformat,
+ GLsizei width, GLsizei height, GLsizei depth, GLint border,
+ GLenum format, GLenum type, const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexImage3DEXT( GLenum target, GLint level, GLenum internalformat,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLint border, GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+extern void GLAPIENTRY
+_mesa_EGLImageTargetTexture2DOES( GLenum target, GLeglImageOES image );
+
+extern void GLAPIENTRY
+_mesa_TexSubImage1D( GLenum target, GLint level, GLint xoffset,
+ GLsizei width,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLsizei width, GLsizei height,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_TexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLsizei width, GLsizei height, GLsizei depth,
+ GLenum format, GLenum type,
+ const GLvoid *pixels );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexImage1D( GLenum target, GLint level, GLenum internalformat,
+ GLint x, GLint y, GLsizei width, GLint border );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexImage2D( GLenum target, GLint level,
+ GLenum internalformat, GLint x, GLint y,
+ GLsizei width, GLsizei height, GLint border );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage1D( GLenum target, GLint level, GLint xoffset,
+ GLint x, GLint y, GLsizei width );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage2D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+extern void GLAPIENTRY
+_mesa_CopyTexSubImage3D( GLenum target, GLint level,
+ GLint xoffset, GLint yoffset, GLint zoffset,
+ GLint x, GLint y, GLsizei width, GLsizei height );
+
+
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage1DARB(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLint border, GLsizei imageSize,
+ const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage2DARB(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLint border, GLsizei imageSize,
+ const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexImage3DARB(GLenum target, GLint level,
+ GLenum internalformat, GLsizei width,
+ GLsizei height, GLsizei depth, GLint border,
+ GLsizei imageSize, const GLvoid *data);
+
+#ifdef VMS
+#define _mesa_CompressedTexSubImage1DARB _mesa_CompressedTexSubImage1DAR
+#define _mesa_CompressedTexSubImage2DARB _mesa_CompressedTexSubImage2DAR
+#define _mesa_CompressedTexSubImage3DARB _mesa_CompressedTexSubImage3DAR
+#endif
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage1DARB(GLenum target, GLint level, GLint xoffset,
+ GLsizei width, GLenum format,
+ GLsizei imageSize, const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage2DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLsizei width, GLsizei height,
+ GLenum format, GLsizei imageSize,
+ const GLvoid *data);
+
+extern void GLAPIENTRY
+_mesa_CompressedTexSubImage3DARB(GLenum target, GLint level, GLint xoffset,
+ GLint yoffset, GLint zoffset, GLsizei width,
+ GLsizei height, GLsizei depth, GLenum format,
+ GLsizei imageSize, const GLvoid *data);
+
+
+extern void GLAPIENTRY
+_mesa_TexBuffer(GLenum target, GLenum internalFormat, GLuint buffer);
+
+
+/*@}*/
+
+#endif
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 9813c4ae8..69a84de39 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -2156,6 +2156,8 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
break;
}
+ const glsl_type *sampler_type = ir->sampler->type;
+
if (ir->projector) {
if (opcode == OPCODE_TEX) {
/* Slot the projector in as the last component of the coord. */
@@ -2187,6 +2189,9 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
tmp_src = get_temp(glsl_type::vec4_type);
dst_reg tmp_dst = dst_reg(tmp_src);
+ /* Projective division not allowed for array samplers. */
+ assert(!sampler_type->sampler_array);
+
tmp_dst.writemask = WRITEMASK_Z;
emit(ir, OPCODE_MOV, tmp_dst, this->result);
@@ -2211,7 +2216,15 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
* coord.
*/
ir->shadow_comparitor->accept(this);
- coord_dst.writemask = WRITEMASK_Z;
+
+ /* XXX This will need to be updated for cubemap array samplers. */
+ if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
+ sampler_type->sampler_array) {
+ coord_dst.writemask = WRITEMASK_W;
+ } else {
+ coord_dst.writemask = WRITEMASK_Z;
+ }
+
emit(ir, OPCODE_MOV, coord_dst, this->result);
coord_dst.writemask = WRITEMASK_XYZW;
}
@@ -2235,8 +2248,6 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
this->shader_program,
this->prog);
- const glsl_type *sampler_type = ir->sampler->type;
-
switch (sampler_type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D:
inst->tex_target = (sampler_type->sampler_array)
diff --git a/mesalib/src/mesa/program/nvvertparse.c b/mesalib/src/mesa/program/nvvertparse.c
index 8f7199a99..91fe2c48b 100644
--- a/mesalib/src/mesa/program/nvvertparse.c
+++ b/mesalib/src/mesa/program/nvvertparse.c
@@ -1,1459 +1,1459 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.2
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-/**
- * \file nvvertparse.c
- * NVIDIA vertex program parser.
- * \author Brian Paul
- */
-
-/*
- * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
- *
- * Portions of this software may use or implement intellectual
- * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
- * any and all warranties with respect to such intellectual property,
- * including any use thereof or modifications thereto.
- */
-
-#include "main/glheader.h"
-#include "main/context.h"
-#include "main/imports.h"
-#include "main/nvprogram.h"
-#include "nvvertparse.h"
-#include "prog_instruction.h"
-#include "prog_parameter.h"
-#include "prog_print.h"
-#include "program.h"
-
-
-/**
- * Current parsing state. This structure is passed among the parsing
- * functions and keeps track of the current parser position and various
- * program attributes.
- */
-struct parse_state {
- struct gl_context *ctx;
- const GLubyte *start;
- const GLubyte *pos;
- const GLubyte *curLine;
- GLboolean isStateProgram;
- GLboolean isPositionInvariant;
- GLboolean isVersion1_1;
- GLbitfield inputsRead;
- GLbitfield outputsWritten;
- GLboolean anyProgRegsWritten;
- GLboolean indirectRegisterFiles;
- GLuint numInst; /* number of instructions parsed */
-};
-
-
-/*
- * Called whenever we find an error during parsing.
- */
-static void
-record_error(struct parse_state *parseState, const char *msg, int lineNo)
-{
-#ifdef DEBUG
- GLint line, column;
- const GLubyte *lineStr;
- lineStr = _mesa_find_line_column(parseState->start,
- parseState->pos, &line, &column);
- _mesa_debug(parseState->ctx,
- "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
- lineNo, line, column, (char *) lineStr, msg);
- free((void *) lineStr);
-#else
- (void) lineNo;
-#endif
-
- /* Check that no error was already recorded. Only record the first one. */
- if (parseState->ctx->Program.ErrorString[0] == 0) {
- _mesa_set_program_error(parseState->ctx,
- parseState->pos - parseState->start,
- msg);
- }
-}
-
-
-#define RETURN_ERROR \
-do { \
- record_error(parseState, "Unexpected end of input.", __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR1(msg) \
-do { \
- record_error(parseState, msg, __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-#define RETURN_ERROR2(msg1, msg2) \
-do { \
- char err[1000]; \
- sprintf(err, "%s %s", msg1, msg2); \
- record_error(parseState, err, __LINE__); \
- return GL_FALSE; \
-} while(0)
-
-
-
-
-
-static GLboolean IsLetter(GLubyte b)
-{
- return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
-}
-
-
-static GLboolean IsDigit(GLubyte b)
-{
- return b >= '0' && b <= '9';
-}
-
-
-static GLboolean IsWhitespace(GLubyte b)
-{
- return b == ' ' || b == '\t' || b == '\n' || b == '\r';
-}
-
-
-/**
- * Starting at 'str' find the next token. A token can be an integer,
- * an identifier or punctuation symbol.
- * \return <= 0 we found an error, else, return number of characters parsed.
- */
-static GLint
-GetToken(struct parse_state *parseState, GLubyte *token)
-{
- const GLubyte *str = parseState->pos;
- GLint i = 0, j = 0;
-
- token[0] = 0;
-
- /* skip whitespace and comments */
- while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
- if (str[i] == '#') {
- /* skip comment */
- while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
- i++;
- }
- if (str[i] == '\n' || str[i] == '\r')
- parseState->curLine = str + i + 1;
- }
- else {
- /* skip whitespace */
- if (str[i] == '\n' || str[i] == '\r')
- parseState->curLine = str + i + 1;
- i++;
- }
- }
-
- if (str[i] == 0)
- return -i;
-
- /* try matching an integer */
- while (str[i] && IsDigit(str[i])) {
- token[j++] = str[i++];
- }
- if (j > 0 || !str[i]) {
- token[j] = 0;
- return i;
- }
-
- /* try matching an identifier */
- if (IsLetter(str[i])) {
- while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
- token[j++] = str[i++];
- }
- token[j] = 0;
- return i;
- }
-
- /* punctuation character */
- if (str[i]) {
- token[0] = str[i++];
- token[1] = 0;
- return i;
- }
-
- /* end of input */
- token[0] = 0;
- return i;
-}
-
-
-/**
- * Get next token from input stream and increment stream pointer past token.
- */
-static GLboolean
-Parse_Token(struct parse_state *parseState, GLubyte *token)
-{
- GLint i;
- i = GetToken(parseState, token);
- if (i <= 0) {
- parseState->pos += (-i);
- return GL_FALSE;
- }
- parseState->pos += i;
- return GL_TRUE;
-}
-
-
-/**
- * Get next token from input stream but don't increment stream pointer.
- */
-static GLboolean
-Peek_Token(struct parse_state *parseState, GLubyte *token)
-{
- GLint i, len;
- i = GetToken(parseState, token);
- if (i <= 0) {
- parseState->pos += (-i);
- return GL_FALSE;
- }
- len = (GLint) strlen((const char *) token);
- parseState->pos += (i - len);
- return GL_TRUE;
-}
-
-
-/**
- * Try to match 'pattern' as the next token after any whitespace/comments.
- * Advance the current parsing position only if we match the pattern.
- * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
- */
-static GLboolean
-Parse_String(struct parse_state *parseState, const char *pattern)
-{
- const GLubyte *m;
- GLint i;
-
- /* skip whitespace and comments */
- while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
- if (*parseState->pos == '#') {
- while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
- parseState->pos += 1;
- }
- if (*parseState->pos == '\n' || *parseState->pos == '\r')
- parseState->curLine = parseState->pos + 1;
- }
- else {
- /* skip whitespace */
- if (*parseState->pos == '\n' || *parseState->pos == '\r')
- parseState->curLine = parseState->pos + 1;
- parseState->pos += 1;
- }
- }
-
- /* Try to match the pattern */
- m = parseState->pos;
- for (i = 0; pattern[i]; i++) {
- if (*m != (GLubyte) pattern[i])
- return GL_FALSE;
- m += 1;
- }
- parseState->pos = m;
-
- return GL_TRUE; /* success */
-}
-
-
-/**********************************************************************/
-
-static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
- "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
- "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
-};
-
-static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
- "HPOS", "COL0", "COL1", "FOGC",
- "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7",
- "PSIZ", "BFC0", "BFC1", NULL
-};
-
-
-
-/**
- * Parse a temporary register: Rnn
- */
-static GLboolean
-Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
-{
- GLubyte token[100];
-
- /* Should be 'R##' */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] != 'R')
- RETURN_ERROR1("Expected R##");
-
- if (IsDigit(token[1])) {
- GLint reg = atoi((char *) (token + 1));
- if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
- RETURN_ERROR1("Bad temporary register name");
- *tempRegNum = reg;
- }
- else {
- RETURN_ERROR1("Bad temporary register name");
- }
-
- return GL_TRUE;
-}
-
-
-/**
- * Parse address register "A0.x"
- */
-static GLboolean
-Parse_AddrReg(struct parse_state *parseState)
-{
- /* match 'A0' */
- if (!Parse_String(parseState, "A0"))
- RETURN_ERROR;
-
- /* match '.' */
- if (!Parse_String(parseState, "."))
- RETURN_ERROR;
-
- /* match 'x' */
- if (!Parse_String(parseState, "x"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-/**
- * Parse absolute program parameter register "c[##]"
- */
-static GLboolean
-Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
-{
- GLubyte token[100];
-
- if (!Parse_String(parseState, "c"))
- RETURN_ERROR;
-
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (IsDigit(token[0])) {
- /* a numbered program parameter register */
- GLint reg = atoi((char *) token);
- if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
- RETURN_ERROR1("Bad program parameter number");
- *regNum = reg;
- }
- else {
- RETURN_ERROR;
- }
-
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
- GLubyte token[100];
-
- if (!Parse_String(parseState, "c"))
- RETURN_ERROR;
-
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (IsDigit(token[0])) {
- /* a numbered program parameter register */
- GLint reg;
- (void) Parse_Token(parseState, token);
- reg = atoi((char *) token);
- if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
- RETURN_ERROR1("Bad program parameter number");
- srcReg->File = PROGRAM_ENV_PARAM;
- srcReg->Index = reg;
- }
- else if (strcmp((const char *) token, "A0") == 0) {
- /* address register "A0.x" */
- if (!Parse_AddrReg(parseState))
- RETURN_ERROR;
-
- srcReg->RelAddr = GL_TRUE;
- srcReg->File = PROGRAM_ENV_PARAM;
- parseState->indirectRegisterFiles |= (1 << srcReg->File);
- /* Look for +/-N offset */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == '-' || token[0] == '+') {
- const GLubyte sign = token[0];
- (void) Parse_Token(parseState, token); /* consume +/- */
-
- /* an integer should be next */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (IsDigit(token[0])) {
- const GLint k = atoi((char *) token);
- if (sign == '-') {
- if (k > 64)
- RETURN_ERROR1("Bad address offset");
- srcReg->Index = -k;
- }
- else {
- if (k > 63)
- RETURN_ERROR1("Bad address offset");
- srcReg->Index = k;
- }
- }
- else {
- RETURN_ERROR;
- }
- }
- else {
- /* probably got a ']', catch it below */
- }
- }
- else {
- RETURN_ERROR;
- }
-
- /* Match closing ']' */
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-/**
- * Parse v[#] or v[<name>]
- */
-static GLboolean
-Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
-{
- GLubyte token[100];
- GLint j;
-
- /* Match 'v' */
- if (!Parse_String(parseState, "v"))
- RETURN_ERROR;
-
- /* Match '[' */
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- /* match number or named register */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (parseState->isStateProgram && token[0] != '0')
- RETURN_ERROR1("Only v[0] accessible in vertex state programs");
-
- if (IsDigit(token[0])) {
- GLint reg = atoi((char *) token);
- if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
- RETURN_ERROR1("Bad vertex attribute register name");
- *tempRegNum = reg;
- }
- else {
- for (j = 0; InputRegisters[j]; j++) {
- if (strcmp((const char *) token, InputRegisters[j]) == 0) {
- *tempRegNum = j;
- break;
- }
- }
- if (!InputRegisters[j]) {
- /* unknown input register label */
- RETURN_ERROR2("Bad register name", token);
- }
- }
-
- /* Match '[' */
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
-{
- GLubyte token[100];
- GLint start, j;
-
- /* Match 'o' */
- if (!Parse_String(parseState, "o"))
- RETURN_ERROR;
-
- /* Match '[' */
- if (!Parse_String(parseState, "["))
- RETURN_ERROR;
-
- /* Get output reg name */
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (parseState->isPositionInvariant)
- start = 1; /* skip HPOS register name */
- else
- start = 0;
-
- /* try to match an output register name */
- for (j = start; OutputRegisters[j]; j++) {
- if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
- *outputRegNum = j;
- break;
- }
- }
- if (!OutputRegisters[j])
- RETURN_ERROR1("Unrecognized output register name");
-
- /* Match ']' */
- if (!Parse_String(parseState, "]"))
- RETURN_ERROR1("Expected ]");
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
-{
- GLubyte token[100];
- GLint idx;
-
- /* Dst reg can be R<n> or o[n] */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == 'R') {
- /* a temporary register */
- dstReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- dstReg->Index = idx;
- }
- else if (!parseState->isStateProgram && token[0] == 'o') {
- /* an output register */
- dstReg->File = PROGRAM_OUTPUT;
- if (!Parse_OutputReg(parseState, &idx))
- RETURN_ERROR;
- dstReg->Index = idx;
- }
- else if (parseState->isStateProgram && token[0] == 'c' &&
- parseState->isStateProgram) {
- /* absolute program parameter register */
- /* Only valid for vertex state programs */
- dstReg->File = PROGRAM_ENV_PARAM;
- if (!Parse_AbsParamReg(parseState, &idx))
- RETURN_ERROR;
- dstReg->Index = idx;
- }
- else {
- RETURN_ERROR1("Bad destination register name");
- }
-
- /* Parse optional write mask */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == '.') {
- /* got a mask */
- GLint k = 0;
-
- if (!Parse_String(parseState, "."))
- RETURN_ERROR;
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- dstReg->WriteMask = 0;
-
- if (token[k] == 'x') {
- dstReg->WriteMask |= WRITEMASK_X;
- k++;
- }
- if (token[k] == 'y') {
- dstReg->WriteMask |= WRITEMASK_Y;
- k++;
- }
- if (token[k] == 'z') {
- dstReg->WriteMask |= WRITEMASK_Z;
- k++;
- }
- if (token[k] == 'w') {
- dstReg->WriteMask |= WRITEMASK_W;
- k++;
- }
- if (k == 0) {
- RETURN_ERROR1("Bad writemask character");
- }
- return GL_TRUE;
- }
- else {
- dstReg->WriteMask = WRITEMASK_XYZW;
- return GL_TRUE;
- }
-}
-
-
-static GLboolean
-Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
- GLubyte token[100];
- GLint idx;
-
- srcReg->RelAddr = GL_FALSE;
-
- /* check for '-' */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] == '-') {
- (void) Parse_String(parseState, "-");
- srcReg->Negate = NEGATE_XYZW;
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- }
- else {
- srcReg->Negate = NEGATE_NONE;
- }
-
- /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
- if (token[0] == 'R') {
- srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'c') {
- if (!Parse_ParamReg(parseState, srcReg))
- RETURN_ERROR;
- }
- else if (token[0] == 'v') {
- srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else {
- RETURN_ERROR2("Bad source register name", token);
- }
-
- /* init swizzle fields */
- srcReg->Swizzle = SWIZZLE_NOOP;
-
- /* Look for optional swizzle suffix */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] == '.') {
- (void) Parse_String(parseState, "."); /* consume . */
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[1] == 0) {
- /* single letter swizzle */
- if (token[0] == 'x')
- srcReg->Swizzle = SWIZZLE_XXXX;
- else if (token[0] == 'y')
- srcReg->Swizzle = SWIZZLE_YYYY;
- else if (token[0] == 'z')
- srcReg->Swizzle = SWIZZLE_ZZZZ;
- else if (token[0] == 'w')
- srcReg->Swizzle = SWIZZLE_WWWW;
- else
- RETURN_ERROR1("Expected x, y, z, or w");
- }
- else {
- /* 2, 3 or 4-component swizzle */
- GLint k;
-
- srcReg->Swizzle = 0;
-
- for (k = 0; token[k] && k < 5; k++) {
- if (token[k] == 'x')
- srcReg->Swizzle |= 0 << (k*3);
- else if (token[k] == 'y')
- srcReg->Swizzle |= 1 << (k*3);
- else if (token[k] == 'z')
- srcReg->Swizzle |= 2 << (k*3);
- else if (token[k] == 'w')
- srcReg->Swizzle |= 3 << (k*3);
- else
- RETURN_ERROR;
- }
- if (k >= 5)
- RETURN_ERROR;
- }
- }
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
-{
- GLubyte token[100];
- GLint idx;
-
- srcReg->RelAddr = GL_FALSE;
-
- /* check for '-' */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- if (token[0] == '-') {
- srcReg->Negate = NEGATE_XYZW;
- (void) Parse_String(parseState, "-"); /* consume '-' */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
- }
- else {
- srcReg->Negate = NEGATE_NONE;
- }
-
- /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
- if (token[0] == 'R') {
- srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'c') {
- if (!Parse_ParamReg(parseState, srcReg))
- RETURN_ERROR;
- }
- else if (token[0] == 'v') {
- srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else {
- RETURN_ERROR2("Bad source register name", token);
- }
-
- /* Look for .[xyzw] suffix */
- if (!Parse_String(parseState, "."))
- RETURN_ERROR;
-
- if (!Parse_Token(parseState, token))
- RETURN_ERROR;
-
- if (token[0] == 'x' && token[1] == 0) {
- srcReg->Swizzle = 0;
- }
- else if (token[0] == 'y' && token[1] == 0) {
- srcReg->Swizzle = 1;
- }
- else if (token[0] == 'z' && token[1] == 0) {
- srcReg->Swizzle = 2;
- }
- else if (token[0] == 'w' && token[1] == 0) {
- srcReg->Swizzle = 3;
- }
- else {
- RETURN_ERROR1("Bad scalar source suffix");
- }
-
- return GL_TRUE;
-}
-
-
-static GLint
-Parse_UnaryOpInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
- RETURN_ERROR1("ABS illegal for vertex program 1.0");
-
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_BiOpInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
- RETURN_ERROR1("DPH illegal for vertex program 1.0");
- if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
- RETURN_ERROR1("SUB illegal for vertex program 1.0");
-
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* first src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* second src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- /* make sure we don't reference more than one program parameter register */
- if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index)
- RETURN_ERROR1("Can't reference two program parameter registers");
-
- /* make sure we don't reference more than one vertex attribute register */
- if (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[1].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index)
- RETURN_ERROR1("Can't reference two vertex attribute registers");
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_TriOpInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* first src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* second src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* third src arg */
- if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- /* make sure we don't reference more than one program parameter register */
- if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
- (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
- (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
- inst->SrcReg[1].Index != inst->SrcReg[2].Index))
- RETURN_ERROR1("Can only reference one program register");
-
- /* make sure we don't reference more than one vertex attribute register */
- if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[1].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
- (inst->SrcReg[0].File == PROGRAM_INPUT &&
- inst->SrcReg[2].File == PROGRAM_INPUT &&
- inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
- (inst->SrcReg[1].File == PROGRAM_INPUT &&
- inst->SrcReg[2].File == PROGRAM_INPUT &&
- inst->SrcReg[1].Index != inst->SrcReg[2].Index))
- RETURN_ERROR1("Can only reference one input register");
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_ScalarInstruction(struct parse_state *parseState,
- struct prog_instruction *inst,
- enum prog_opcode opcode)
-{
- if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
- RETURN_ERROR1("RCC illegal for vertex program 1.0");
-
- inst->Opcode = opcode;
-
- /* dest reg */
- if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* first src arg */
- if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
- inst->Opcode = OPCODE_ARL;
-
- /* Make ARB_vp backends happy */
- inst->DstReg.File = PROGRAM_ADDRESS;
- inst->DstReg.WriteMask = WRITEMASK_X;
- inst->DstReg.Index = 0;
-
- /* dest A0 reg */
- if (!Parse_AddrReg(parseState))
- RETURN_ERROR;
-
- /* comma */
- if (!Parse_String(parseState, ","))
- RETURN_ERROR;
-
- /* parse src reg */
- if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
- RETURN_ERROR;
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
- GLubyte token[100];
-
- inst->Opcode = OPCODE_END;
-
- /* this should fail! */
- if (Parse_Token(parseState, token))
- RETURN_ERROR2("Unexpected token after END:", token);
- else
- return GL_TRUE;
-}
-
-
-/**
- * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
- * the vertex program developer.
- * The NV_vertex_program extension grammar is modified as follows:
- *
- * <instruction> ::= <ARL-instruction>
- * | ...
- * | <PRINT-instruction>
- *
- * <PRINT-instruction> ::= "PRINT" <string literal>
- * | "PRINT" <string literal> "," <srcReg>
- * | "PRINT" <string literal> "," <dstReg>
- */
-static GLboolean
-Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
-{
- const GLubyte *str;
- GLubyte *msg;
- GLuint len;
- GLubyte token[100];
- struct prog_src_register *srcReg = &inst->SrcReg[0];
- GLint idx;
-
- inst->Opcode = OPCODE_PRINT;
-
- /* The first argument is a literal string 'just like this' */
- if (!Parse_String(parseState, "'"))
- RETURN_ERROR;
-
- str = parseState->pos;
- for (len = 0; str[len] != '\''; len++) /* find closing quote */
- ;
- parseState->pos += len + 1;
- msg = (GLubyte*) malloc(len + 1);
-
- memcpy(msg, str, len);
- msg[len] = 0;
- inst->Data = msg;
-
- /* comma */
- if (Parse_String(parseState, ",")) {
-
- /* The second argument is a register name */
- if (!Peek_Token(parseState, token))
- RETURN_ERROR;
-
- srcReg->RelAddr = GL_FALSE;
- srcReg->Negate = NEGATE_NONE;
- srcReg->Swizzle = SWIZZLE_NOOP;
-
- /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
- * or an o[n] output register.
- */
- if (token[0] == 'R') {
- srcReg->File = PROGRAM_TEMPORARY;
- if (!Parse_TempReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'c') {
- srcReg->File = PROGRAM_ENV_PARAM;
- if (!Parse_ParamReg(parseState, srcReg))
- RETURN_ERROR;
- }
- else if (token[0] == 'v') {
- srcReg->File = PROGRAM_INPUT;
- if (!Parse_AttribReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else if (token[0] == 'o') {
- srcReg->File = PROGRAM_OUTPUT;
- if (!Parse_OutputReg(parseState, &idx))
- RETURN_ERROR;
- srcReg->Index = idx;
- }
- else {
- RETURN_ERROR2("Bad source register name", token);
- }
- }
- else {
- srcReg->File = PROGRAM_UNDEFINED;
- }
-
- /* semicolon */
- if (!Parse_String(parseState, ";"))
- RETURN_ERROR;
-
- return GL_TRUE;
-}
-
-
-static GLboolean
-Parse_OptionSequence(struct parse_state *parseState,
- struct prog_instruction program[])
-{
- (void) program;
- while (1) {
- if (!Parse_String(parseState, "OPTION"))
- return GL_TRUE; /* ok, not an OPTION statement */
- if (Parse_String(parseState, "NV_position_invariant")) {
- parseState->isPositionInvariant = GL_TRUE;
- }
- else {
- RETURN_ERROR1("unexpected OPTION statement");
- }
- if (!Parse_String(parseState, ";"))
- return GL_FALSE;
- }
-}
-
-
-static GLboolean
-Parse_InstructionSequence(struct parse_state *parseState,
- struct prog_instruction program[])
-{
- while (1) {
- struct prog_instruction *inst = program + parseState->numInst;
-
- /* Initialize the instruction */
- _mesa_init_instructions(inst, 1);
-
- if (Parse_String(parseState, "MOV")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "LIT")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "ABS")) {
- if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MUL")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "ADD")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DP3")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DP4")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DST")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MIN")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MAX")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "SLT")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "SGE")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "DPH")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "SUB")) {
- if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "MAD")) {
- if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "RCP")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "RSQ")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "EXP")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "LOG")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "RCC")) {
- if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "ARL")) {
- if (!Parse_AddressInstruction(parseState, inst))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "PRINT")) {
- if (!Parse_PrintInstruction(parseState, inst))
- RETURN_ERROR;
- }
- else if (Parse_String(parseState, "END")) {
- if (!Parse_EndInstruction(parseState, inst))
- RETURN_ERROR;
- else {
- parseState->numInst++;
- return GL_TRUE; /* all done */
- }
- }
- else {
- /* bad instruction name */
- RETURN_ERROR1("Unexpected token");
- }
-
- /* examine input/output registers */
- if (inst->DstReg.File == PROGRAM_OUTPUT)
- parseState->outputsWritten |= (1 << inst->DstReg.Index);
- else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
- parseState->anyProgRegsWritten = GL_TRUE;
-
- if (inst->SrcReg[0].File == PROGRAM_INPUT)
- parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
- if (inst->SrcReg[1].File == PROGRAM_INPUT)
- parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
- if (inst->SrcReg[2].File == PROGRAM_INPUT)
- parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
-
- parseState->numInst++;
-
- if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
- RETURN_ERROR1("Program too long");
- }
-
- RETURN_ERROR;
-}
-
-
-static GLboolean
-Parse_Program(struct parse_state *parseState,
- struct prog_instruction instBuffer[])
-{
- if (parseState->isVersion1_1) {
- if (!Parse_OptionSequence(parseState, instBuffer)) {
- return GL_FALSE;
- }
- }
- return Parse_InstructionSequence(parseState, instBuffer);
-}
-
-
-/**
- * Parse/compile the 'str' returning the compiled 'program'.
- * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos
- * indicates the position of the error in 'str'.
- */
-void
-_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget,
- const GLubyte *str, GLsizei len,
- struct gl_vertex_program *program)
-{
- struct parse_state parseState;
- struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
- struct prog_instruction *newInst;
- GLenum target;
- GLubyte *programString;
-
- /* Make a null-terminated copy of the program string */
- programString = (GLubyte *) MALLOC(len + 1);
- if (!programString) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- return;
- }
- memcpy(programString, str, len);
- programString[len] = 0;
-
- /* Get ready to parse */
- parseState.ctx = ctx;
- parseState.start = programString;
- parseState.isPositionInvariant = GL_FALSE;
- parseState.isVersion1_1 = GL_FALSE;
- parseState.numInst = 0;
- parseState.inputsRead = 0;
- parseState.outputsWritten = 0;
- parseState.anyProgRegsWritten = GL_FALSE;
- parseState.indirectRegisterFiles = 0x0;
-
- /* Reset error state */
- _mesa_set_program_error(ctx, -1, NULL);
-
- /* check the program header */
- if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
- target = GL_VERTEX_PROGRAM_NV;
- parseState.pos = programString + 7;
- parseState.isStateProgram = GL_FALSE;
- }
- else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
- target = GL_VERTEX_PROGRAM_NV;
- parseState.pos = programString + 7;
- parseState.isStateProgram = GL_FALSE;
- parseState.isVersion1_1 = GL_TRUE;
- }
- else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
- target = GL_VERTEX_STATE_PROGRAM_NV;
- parseState.pos = programString + 8;
- parseState.isStateProgram = GL_TRUE;
- }
- else {
- /* invalid header */
- ctx->Program.ErrorPos = 0;
- _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
- return;
- }
-
- /* make sure target and header match */
- if (target != dstTarget) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLoadProgramNV(target mismatch)");
- return;
- }
-
-
- if (Parse_Program(&parseState, instBuffer)) {
- gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
- int i;
-
- /* successful parse! */
-
- if (parseState.isStateProgram) {
- if (!parseState.anyProgRegsWritten) {
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLoadProgramNV(c[#] not written)");
- return;
- }
- }
- else {
- if (!parseState.isPositionInvariant &&
- !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
- /* bit 1 = HPOS register */
- _mesa_error(ctx, GL_INVALID_OPERATION,
- "glLoadProgramNV(HPOS not written)");
- return;
- }
- }
-
- /* copy the compiled instructions */
- assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
- newInst = _mesa_alloc_instructions(parseState.numInst);
- if (!newInst) {
- _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
- free(programString);
- return; /* out of memory */
- }
- _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
-
- /* install the program */
- program->Base.Target = target;
- if (program->Base.String) {
- free(program->Base.String);
- }
- program->Base.String = programString;
- program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
- if (program->Base.Instructions) {
- free(program->Base.Instructions);
- }
- program->Base.Instructions = newInst;
- program->Base.InputsRead = parseState.inputsRead;
- if (parseState.isPositionInvariant)
- program->Base.InputsRead |= VERT_BIT_POS;
- program->Base.NumInstructions = parseState.numInst;
- program->Base.OutputsWritten = parseState.outputsWritten;
- program->IsPositionInvariant = parseState.isPositionInvariant;
- program->IsNVProgram = GL_TRUE;
-
-#ifdef DEBUG_foo
- printf("--- glLoadProgramNV result ---\n");
- _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
- printf("------------------------------\n");
-#endif
-
- if (program->Base.Parameters)
- _mesa_free_parameter_list(program->Base.Parameters);
-
- program->Base.Parameters = _mesa_new_parameter_list ();
- program->Base.NumParameters = 0;
-
- program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles;
-
- state_tokens[0] = STATE_VERTEX_PROGRAM;
- state_tokens[1] = STATE_ENV;
- /* Add refs to all of the potential params, in order. If we want to not
- * upload everything, _mesa_layout_parameters is the answer.
- */
- for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
- GLint index;
- state_tokens[2] = i;
- index = _mesa_add_state_reference(program->Base.Parameters,
- state_tokens);
- assert(index == i);
- }
- program->Base.NumParameters = program->Base.Parameters->NumParameters;
-
- _mesa_setup_nv_temporary_count(ctx, &program->Base);
- _mesa_emit_nv_temp_initialization(ctx, &program->Base);
- }
- else {
- /* Error! */
- _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
- /* NOTE: _mesa_set_program_error would have been called already */
- /* GL_NV_vertex_program isn't supposed to set the error string
- * so we reset it here.
- */
- _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
- }
-}
-
-
-const char *
-_mesa_nv_vertex_input_register_name(GLuint i)
-{
- ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
- return InputRegisters[i];
-}
-
-
-const char *
-_mesa_nv_vertex_output_register_name(GLuint i)
-{
- ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
- return OutputRegisters[i];
-}
-
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.2
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file nvvertparse.c
+ * NVIDIA vertex program parser.
+ * \author Brian Paul
+ */
+
+/*
+ * Regarding GL_NV_vertex_program, GL_NV_vertex_program1_1:
+ *
+ * Portions of this software may use or implement intellectual
+ * property owned and licensed by NVIDIA Corporation. NVIDIA disclaims
+ * any and all warranties with respect to such intellectual property,
+ * including any use thereof or modifications thereto.
+ */
+
+#include "main/glheader.h"
+#include "main/context.h"
+#include "main/imports.h"
+#include "main/nvprogram.h"
+#include "nvvertparse.h"
+#include "prog_instruction.h"
+#include "prog_parameter.h"
+#include "prog_print.h"
+#include "program.h"
+
+
+/**
+ * Current parsing state. This structure is passed among the parsing
+ * functions and keeps track of the current parser position and various
+ * program attributes.
+ */
+struct parse_state {
+ struct gl_context *ctx;
+ const GLubyte *start;
+ const GLubyte *pos;
+ const GLubyte *curLine;
+ GLboolean isStateProgram;
+ GLboolean isPositionInvariant;
+ GLboolean isVersion1_1;
+ GLbitfield inputsRead;
+ GLbitfield outputsWritten;
+ GLboolean anyProgRegsWritten;
+ GLboolean indirectRegisterFiles;
+ GLuint numInst; /* number of instructions parsed */
+};
+
+
+/*
+ * Called whenever we find an error during parsing.
+ */
+static void
+record_error(struct parse_state *parseState, const char *msg, int lineNo)
+{
+#ifdef DEBUG
+ GLint line, column;
+ const GLubyte *lineStr;
+ lineStr = _mesa_find_line_column(parseState->start,
+ parseState->pos, &line, &column);
+ _mesa_debug(parseState->ctx,
+ "nvfragparse.c(%d): line %d, column %d:%s (%s)\n",
+ lineNo, line, column, (char *) lineStr, msg);
+ free((void *) lineStr);
+#else
+ (void) lineNo;
+#endif
+
+ /* Check that no error was already recorded. Only record the first one. */
+ if (parseState->ctx->Program.ErrorString[0] == 0) {
+ _mesa_set_program_error(parseState->ctx,
+ parseState->pos - parseState->start,
+ msg);
+ }
+}
+
+
+#define RETURN_ERROR \
+do { \
+ record_error(parseState, "Unexpected end of input.", __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+#define RETURN_ERROR1(msg) \
+do { \
+ record_error(parseState, msg, __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+#define RETURN_ERROR2(msg1, msg2) \
+do { \
+ char err[1000]; \
+ sprintf(err, "%s %s", msg1, msg2); \
+ record_error(parseState, err, __LINE__); \
+ return GL_FALSE; \
+} while(0)
+
+
+
+
+
+static GLboolean IsLetter(GLubyte b)
+{
+ return (b >= 'a' && b <= 'z') || (b >= 'A' && b <= 'Z');
+}
+
+
+static GLboolean IsDigit(GLubyte b)
+{
+ return b >= '0' && b <= '9';
+}
+
+
+static GLboolean IsWhitespace(GLubyte b)
+{
+ return b == ' ' || b == '\t' || b == '\n' || b == '\r';
+}
+
+
+/**
+ * Starting at 'str' find the next token. A token can be an integer,
+ * an identifier or punctuation symbol.
+ * \return <= 0 we found an error, else, return number of characters parsed.
+ */
+static GLint
+GetToken(struct parse_state *parseState, GLubyte *token)
+{
+ const GLubyte *str = parseState->pos;
+ GLint i = 0, j = 0;
+
+ token[0] = 0;
+
+ /* skip whitespace and comments */
+ while (str[i] && (IsWhitespace(str[i]) || str[i] == '#')) {
+ if (str[i] == '#') {
+ /* skip comment */
+ while (str[i] && (str[i] != '\n' && str[i] != '\r')) {
+ i++;
+ }
+ if (str[i] == '\n' || str[i] == '\r')
+ parseState->curLine = str + i + 1;
+ }
+ else {
+ /* skip whitespace */
+ if (str[i] == '\n' || str[i] == '\r')
+ parseState->curLine = str + i + 1;
+ i++;
+ }
+ }
+
+ if (str[i] == 0)
+ return -i;
+
+ /* try matching an integer */
+ while (str[i] && IsDigit(str[i])) {
+ token[j++] = str[i++];
+ }
+ if (j > 0 || !str[i]) {
+ token[j] = 0;
+ return i;
+ }
+
+ /* try matching an identifier */
+ if (IsLetter(str[i])) {
+ while (str[i] && (IsLetter(str[i]) || IsDigit(str[i]))) {
+ token[j++] = str[i++];
+ }
+ token[j] = 0;
+ return i;
+ }
+
+ /* punctuation character */
+ if (str[i]) {
+ token[0] = str[i++];
+ token[1] = 0;
+ return i;
+ }
+
+ /* end of input */
+ token[0] = 0;
+ return i;
+}
+
+
+/**
+ * Get next token from input stream and increment stream pointer past token.
+ */
+static GLboolean
+Parse_Token(struct parse_state *parseState, GLubyte *token)
+{
+ GLint i;
+ i = GetToken(parseState, token);
+ if (i <= 0) {
+ parseState->pos += (-i);
+ return GL_FALSE;
+ }
+ parseState->pos += i;
+ return GL_TRUE;
+}
+
+
+/**
+ * Get next token from input stream but don't increment stream pointer.
+ */
+static GLboolean
+Peek_Token(struct parse_state *parseState, GLubyte *token)
+{
+ GLint i, len;
+ i = GetToken(parseState, token);
+ if (i <= 0) {
+ parseState->pos += (-i);
+ return GL_FALSE;
+ }
+ len = (GLint) strlen((const char *) token);
+ parseState->pos += (i - len);
+ return GL_TRUE;
+}
+
+
+/**
+ * Try to match 'pattern' as the next token after any whitespace/comments.
+ * Advance the current parsing position only if we match the pattern.
+ * \return GL_TRUE if pattern is matched, GL_FALSE otherwise.
+ */
+static GLboolean
+Parse_String(struct parse_state *parseState, const char *pattern)
+{
+ const GLubyte *m;
+ GLint i;
+
+ /* skip whitespace and comments */
+ while (IsWhitespace(*parseState->pos) || *parseState->pos == '#') {
+ if (*parseState->pos == '#') {
+ while (*parseState->pos && (*parseState->pos != '\n' && *parseState->pos != '\r')) {
+ parseState->pos += 1;
+ }
+ if (*parseState->pos == '\n' || *parseState->pos == '\r')
+ parseState->curLine = parseState->pos + 1;
+ }
+ else {
+ /* skip whitespace */
+ if (*parseState->pos == '\n' || *parseState->pos == '\r')
+ parseState->curLine = parseState->pos + 1;
+ parseState->pos += 1;
+ }
+ }
+
+ /* Try to match the pattern */
+ m = parseState->pos;
+ for (i = 0; pattern[i]; i++) {
+ if (*m != (GLubyte) pattern[i])
+ return GL_FALSE;
+ m += 1;
+ }
+ parseState->pos = m;
+
+ return GL_TRUE; /* success */
+}
+
+
+/**********************************************************************/
+
+static const char *InputRegisters[MAX_NV_VERTEX_PROGRAM_INPUTS + 1] = {
+ "OPOS", "WGHT", "NRML", "COL0", "COL1", "FOGC", "6", "7",
+ "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7", NULL
+};
+
+static const char *OutputRegisters[MAX_NV_VERTEX_PROGRAM_OUTPUTS + 1] = {
+ "HPOS", "COL0", "COL1", "FOGC",
+ "TEX0", "TEX1", "TEX2", "TEX3", "TEX4", "TEX5", "TEX6", "TEX7",
+ "PSIZ", "BFC0", "BFC1", NULL
+};
+
+
+
+/**
+ * Parse a temporary register: Rnn
+ */
+static GLboolean
+Parse_TempReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+ GLubyte token[100];
+
+ /* Should be 'R##' */
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+ if (token[0] != 'R')
+ RETURN_ERROR1("Expected R##");
+
+ if (IsDigit(token[1])) {
+ GLint reg = atoi((char *) (token + 1));
+ if (reg >= MAX_NV_VERTEX_PROGRAM_TEMPS)
+ RETURN_ERROR1("Bad temporary register name");
+ *tempRegNum = reg;
+ }
+ else {
+ RETURN_ERROR1("Bad temporary register name");
+ }
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Parse address register "A0.x"
+ */
+static GLboolean
+Parse_AddrReg(struct parse_state *parseState)
+{
+ /* match 'A0' */
+ if (!Parse_String(parseState, "A0"))
+ RETURN_ERROR;
+
+ /* match '.' */
+ if (!Parse_String(parseState, "."))
+ RETURN_ERROR;
+
+ /* match 'x' */
+ if (!Parse_String(parseState, "x"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Parse absolute program parameter register "c[##]"
+ */
+static GLboolean
+Parse_AbsParamReg(struct parse_state *parseState, GLint *regNum)
+{
+ GLubyte token[100];
+
+ if (!Parse_String(parseState, "c"))
+ RETURN_ERROR;
+
+ if (!Parse_String(parseState, "["))
+ RETURN_ERROR;
+
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (IsDigit(token[0])) {
+ /* a numbered program parameter register */
+ GLint reg = atoi((char *) token);
+ if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
+ RETURN_ERROR1("Bad program parameter number");
+ *regNum = reg;
+ }
+ else {
+ RETURN_ERROR;
+ }
+
+ if (!Parse_String(parseState, "]"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ParamReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+ GLubyte token[100];
+
+ if (!Parse_String(parseState, "c"))
+ RETURN_ERROR;
+
+ if (!Parse_String(parseState, "["))
+ RETURN_ERROR;
+
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (IsDigit(token[0])) {
+ /* a numbered program parameter register */
+ GLint reg;
+ (void) Parse_Token(parseState, token);
+ reg = atoi((char *) token);
+ if (reg >= MAX_NV_VERTEX_PROGRAM_PARAMS)
+ RETURN_ERROR1("Bad program parameter number");
+ srcReg->File = PROGRAM_ENV_PARAM;
+ srcReg->Index = reg;
+ }
+ else if (strcmp((const char *) token, "A0") == 0) {
+ /* address register "A0.x" */
+ if (!Parse_AddrReg(parseState))
+ RETURN_ERROR;
+
+ srcReg->RelAddr = GL_TRUE;
+ srcReg->File = PROGRAM_ENV_PARAM;
+ parseState->indirectRegisterFiles |= (1 << srcReg->File);
+ /* Look for +/-N offset */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (token[0] == '-' || token[0] == '+') {
+ const GLubyte sign = token[0];
+ (void) Parse_Token(parseState, token); /* consume +/- */
+
+ /* an integer should be next */
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (IsDigit(token[0])) {
+ const GLint k = atoi((char *) token);
+ if (sign == '-') {
+ if (k > 64)
+ RETURN_ERROR1("Bad address offset");
+ srcReg->Index = -k;
+ }
+ else {
+ if (k > 63)
+ RETURN_ERROR1("Bad address offset");
+ srcReg->Index = k;
+ }
+ }
+ else {
+ RETURN_ERROR;
+ }
+ }
+ else {
+ /* probably got a ']', catch it below */
+ }
+ }
+ else {
+ RETURN_ERROR;
+ }
+
+ /* Match closing ']' */
+ if (!Parse_String(parseState, "]"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+/**
+ * Parse v[#] or v[<name>]
+ */
+static GLboolean
+Parse_AttribReg(struct parse_state *parseState, GLint *tempRegNum)
+{
+ GLubyte token[100];
+ GLint j;
+
+ /* Match 'v' */
+ if (!Parse_String(parseState, "v"))
+ RETURN_ERROR;
+
+ /* Match '[' */
+ if (!Parse_String(parseState, "["))
+ RETURN_ERROR;
+
+ /* match number or named register */
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (parseState->isStateProgram && token[0] != '0')
+ RETURN_ERROR1("Only v[0] accessible in vertex state programs");
+
+ if (IsDigit(token[0])) {
+ GLint reg = atoi((char *) token);
+ if (reg >= MAX_NV_VERTEX_PROGRAM_INPUTS)
+ RETURN_ERROR1("Bad vertex attribute register name");
+ *tempRegNum = reg;
+ }
+ else {
+ for (j = 0; InputRegisters[j]; j++) {
+ if (strcmp((const char *) token, InputRegisters[j]) == 0) {
+ *tempRegNum = j;
+ break;
+ }
+ }
+ if (!InputRegisters[j]) {
+ /* unknown input register label */
+ RETURN_ERROR2("Bad register name", token);
+ }
+ }
+
+ /* Match '[' */
+ if (!Parse_String(parseState, "]"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OutputReg(struct parse_state *parseState, GLint *outputRegNum)
+{
+ GLubyte token[100];
+ GLint start, j;
+
+ /* Match 'o' */
+ if (!Parse_String(parseState, "o"))
+ RETURN_ERROR;
+
+ /* Match '[' */
+ if (!Parse_String(parseState, "["))
+ RETURN_ERROR;
+
+ /* Get output reg name */
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (parseState->isPositionInvariant)
+ start = 1; /* skip HPOS register name */
+ else
+ start = 0;
+
+ /* try to match an output register name */
+ for (j = start; OutputRegisters[j]; j++) {
+ if (strcmp((const char *) token, OutputRegisters[j]) == 0) {
+ *outputRegNum = j;
+ break;
+ }
+ }
+ if (!OutputRegisters[j])
+ RETURN_ERROR1("Unrecognized output register name");
+
+ /* Match ']' */
+ if (!Parse_String(parseState, "]"))
+ RETURN_ERROR1("Expected ]");
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_MaskedDstReg(struct parse_state *parseState, struct prog_dst_register *dstReg)
+{
+ GLubyte token[100];
+ GLint idx;
+
+ /* Dst reg can be R<n> or o[n] */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (token[0] == 'R') {
+ /* a temporary register */
+ dstReg->File = PROGRAM_TEMPORARY;
+ if (!Parse_TempReg(parseState, &idx))
+ RETURN_ERROR;
+ dstReg->Index = idx;
+ }
+ else if (!parseState->isStateProgram && token[0] == 'o') {
+ /* an output register */
+ dstReg->File = PROGRAM_OUTPUT;
+ if (!Parse_OutputReg(parseState, &idx))
+ RETURN_ERROR;
+ dstReg->Index = idx;
+ }
+ else if (parseState->isStateProgram && token[0] == 'c' &&
+ parseState->isStateProgram) {
+ /* absolute program parameter register */
+ /* Only valid for vertex state programs */
+ dstReg->File = PROGRAM_ENV_PARAM;
+ if (!Parse_AbsParamReg(parseState, &idx))
+ RETURN_ERROR;
+ dstReg->Index = idx;
+ }
+ else {
+ RETURN_ERROR1("Bad destination register name");
+ }
+
+ /* Parse optional write mask */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (token[0] == '.') {
+ /* got a mask */
+ GLint k = 0;
+
+ if (!Parse_String(parseState, "."))
+ RETURN_ERROR;
+
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ dstReg->WriteMask = 0;
+
+ if (token[k] == 'x') {
+ dstReg->WriteMask |= WRITEMASK_X;
+ k++;
+ }
+ if (token[k] == 'y') {
+ dstReg->WriteMask |= WRITEMASK_Y;
+ k++;
+ }
+ if (token[k] == 'z') {
+ dstReg->WriteMask |= WRITEMASK_Z;
+ k++;
+ }
+ if (token[k] == 'w') {
+ dstReg->WriteMask |= WRITEMASK_W;
+ k++;
+ }
+ if (k == 0) {
+ RETURN_ERROR1("Bad writemask character");
+ }
+ return GL_TRUE;
+ }
+ else {
+ dstReg->WriteMask = WRITEMASK_XYZW;
+ return GL_TRUE;
+ }
+}
+
+
+static GLboolean
+Parse_SwizzleSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+ GLubyte token[100];
+ GLint idx;
+
+ srcReg->RelAddr = GL_FALSE;
+
+ /* check for '-' */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+ if (token[0] == '-') {
+ (void) Parse_String(parseState, "-");
+ srcReg->Negate = NEGATE_XYZW;
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+ }
+ else {
+ srcReg->Negate = NEGATE_NONE;
+ }
+
+ /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
+ if (token[0] == 'R') {
+ srcReg->File = PROGRAM_TEMPORARY;
+ if (!Parse_TempReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else if (token[0] == 'c') {
+ if (!Parse_ParamReg(parseState, srcReg))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'v') {
+ srcReg->File = PROGRAM_INPUT;
+ if (!Parse_AttribReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else {
+ RETURN_ERROR2("Bad source register name", token);
+ }
+
+ /* init swizzle fields */
+ srcReg->Swizzle = SWIZZLE_NOOP;
+
+ /* Look for optional swizzle suffix */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+ if (token[0] == '.') {
+ (void) Parse_String(parseState, "."); /* consume . */
+
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (token[1] == 0) {
+ /* single letter swizzle */
+ if (token[0] == 'x')
+ srcReg->Swizzle = SWIZZLE_XXXX;
+ else if (token[0] == 'y')
+ srcReg->Swizzle = SWIZZLE_YYYY;
+ else if (token[0] == 'z')
+ srcReg->Swizzle = SWIZZLE_ZZZZ;
+ else if (token[0] == 'w')
+ srcReg->Swizzle = SWIZZLE_WWWW;
+ else
+ RETURN_ERROR1("Expected x, y, z, or w");
+ }
+ else {
+ /* 2, 3 or 4-component swizzle */
+ GLint k;
+
+ srcReg->Swizzle = 0;
+
+ for (k = 0; token[k] && k < 5; k++) {
+ if (token[k] == 'x')
+ srcReg->Swizzle |= 0 << (k*3);
+ else if (token[k] == 'y')
+ srcReg->Swizzle |= 1 << (k*3);
+ else if (token[k] == 'z')
+ srcReg->Swizzle |= 2 << (k*3);
+ else if (token[k] == 'w')
+ srcReg->Swizzle |= 3 << (k*3);
+ else
+ RETURN_ERROR;
+ }
+ if (k >= 5)
+ RETURN_ERROR;
+ }
+ }
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarSrcReg(struct parse_state *parseState, struct prog_src_register *srcReg)
+{
+ GLubyte token[100];
+ GLint idx;
+
+ srcReg->RelAddr = GL_FALSE;
+
+ /* check for '-' */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+ if (token[0] == '-') {
+ srcReg->Negate = NEGATE_XYZW;
+ (void) Parse_String(parseState, "-"); /* consume '-' */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+ }
+ else {
+ srcReg->Negate = NEGATE_NONE;
+ }
+
+ /* Src reg can be R<n>, c[n], c[n +/- offset], or a named vertex attrib */
+ if (token[0] == 'R') {
+ srcReg->File = PROGRAM_TEMPORARY;
+ if (!Parse_TempReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else if (token[0] == 'c') {
+ if (!Parse_ParamReg(parseState, srcReg))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'v') {
+ srcReg->File = PROGRAM_INPUT;
+ if (!Parse_AttribReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else {
+ RETURN_ERROR2("Bad source register name", token);
+ }
+
+ /* Look for .[xyzw] suffix */
+ if (!Parse_String(parseState, "."))
+ RETURN_ERROR;
+
+ if (!Parse_Token(parseState, token))
+ RETURN_ERROR;
+
+ if (token[0] == 'x' && token[1] == 0) {
+ srcReg->Swizzle = 0;
+ }
+ else if (token[0] == 'y' && token[1] == 0) {
+ srcReg->Swizzle = 1;
+ }
+ else if (token[0] == 'z' && token[1] == 0) {
+ srcReg->Swizzle = 2;
+ }
+ else if (token[0] == 'w' && token[1] == 0) {
+ srcReg->Swizzle = 3;
+ }
+ else {
+ RETURN_ERROR1("Bad scalar source suffix");
+ }
+
+ return GL_TRUE;
+}
+
+
+static GLint
+Parse_UnaryOpInstruction(struct parse_state *parseState,
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
+{
+ if (opcode == OPCODE_ABS && !parseState->isVersion1_1)
+ RETURN_ERROR1("ABS illegal for vertex program 1.0");
+
+ inst->Opcode = opcode;
+
+ /* dest reg */
+ if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* src arg */
+ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_BiOpInstruction(struct parse_state *parseState,
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
+{
+ if (opcode == OPCODE_DPH && !parseState->isVersion1_1)
+ RETURN_ERROR1("DPH illegal for vertex program 1.0");
+ if (opcode == OPCODE_SUB && !parseState->isVersion1_1)
+ RETURN_ERROR1("SUB illegal for vertex program 1.0");
+
+ inst->Opcode = opcode;
+
+ /* dest reg */
+ if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* first src arg */
+ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* second src arg */
+ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
+ RETURN_ERROR;
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ /* make sure we don't reference more than one program parameter register */
+ if (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[0].Index != inst->SrcReg[1].Index)
+ RETURN_ERROR1("Can't reference two program parameter registers");
+
+ /* make sure we don't reference more than one vertex attribute register */
+ if (inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[1].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index != inst->SrcReg[1].Index)
+ RETURN_ERROR1("Can't reference two vertex attribute registers");
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_TriOpInstruction(struct parse_state *parseState,
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
+{
+ inst->Opcode = opcode;
+
+ /* dest reg */
+ if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* first src arg */
+ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* second src arg */
+ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[1]))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* third src arg */
+ if (!Parse_SwizzleSrcReg(parseState, &inst->SrcReg[2]))
+ RETURN_ERROR;
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ /* make sure we don't reference more than one program parameter register */
+ if ((inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
+ (inst->SrcReg[0].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
+ (inst->SrcReg[1].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[2].File == PROGRAM_ENV_PARAM &&
+ inst->SrcReg[1].Index != inst->SrcReg[2].Index))
+ RETURN_ERROR1("Can only reference one program register");
+
+ /* make sure we don't reference more than one vertex attribute register */
+ if ((inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[1].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index != inst->SrcReg[1].Index) ||
+ (inst->SrcReg[0].File == PROGRAM_INPUT &&
+ inst->SrcReg[2].File == PROGRAM_INPUT &&
+ inst->SrcReg[0].Index != inst->SrcReg[2].Index) ||
+ (inst->SrcReg[1].File == PROGRAM_INPUT &&
+ inst->SrcReg[2].File == PROGRAM_INPUT &&
+ inst->SrcReg[1].Index != inst->SrcReg[2].Index))
+ RETURN_ERROR1("Can only reference one input register");
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_ScalarInstruction(struct parse_state *parseState,
+ struct prog_instruction *inst,
+ enum prog_opcode opcode)
+{
+ if (opcode == OPCODE_RCC && !parseState->isVersion1_1)
+ RETURN_ERROR1("RCC illegal for vertex program 1.0");
+
+ inst->Opcode = opcode;
+
+ /* dest reg */
+ if (!Parse_MaskedDstReg(parseState, &inst->DstReg))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* first src arg */
+ if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_AddressInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+ inst->Opcode = OPCODE_ARL;
+
+ /* Make ARB_vp backends happy */
+ inst->DstReg.File = PROGRAM_ADDRESS;
+ inst->DstReg.WriteMask = WRITEMASK_X;
+ inst->DstReg.Index = 0;
+
+ /* dest A0 reg */
+ if (!Parse_AddrReg(parseState))
+ RETURN_ERROR;
+
+ /* comma */
+ if (!Parse_String(parseState, ","))
+ RETURN_ERROR;
+
+ /* parse src reg */
+ if (!Parse_ScalarSrcReg(parseState, &inst->SrcReg[0]))
+ RETURN_ERROR;
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_EndInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+ GLubyte token[100];
+
+ inst->Opcode = OPCODE_END;
+
+ /* this should fail! */
+ if (Parse_Token(parseState, token))
+ RETURN_ERROR2("Unexpected token after END:", token);
+ else
+ return GL_TRUE;
+}
+
+
+/**
+ * The PRINT instruction is Mesa-specific and is meant as a debugging aid for
+ * the vertex program developer.
+ * The NV_vertex_program extension grammar is modified as follows:
+ *
+ * <instruction> ::= <ARL-instruction>
+ * | ...
+ * | <PRINT-instruction>
+ *
+ * <PRINT-instruction> ::= "PRINT" <string literal>
+ * | "PRINT" <string literal> "," <srcReg>
+ * | "PRINT" <string literal> "," <dstReg>
+ */
+static GLboolean
+Parse_PrintInstruction(struct parse_state *parseState, struct prog_instruction *inst)
+{
+ const GLubyte *str;
+ GLubyte *msg;
+ GLuint len;
+ GLubyte token[100];
+ struct prog_src_register *srcReg = &inst->SrcReg[0];
+ GLint idx;
+
+ inst->Opcode = OPCODE_PRINT;
+
+ /* The first argument is a literal string 'just like this' */
+ if (!Parse_String(parseState, "'"))
+ RETURN_ERROR;
+
+ str = parseState->pos;
+ for (len = 0; str[len] != '\''; len++) /* find closing quote */
+ ;
+ parseState->pos += len + 1;
+ msg = (GLubyte*) malloc(len + 1);
+
+ memcpy(msg, str, len);
+ msg[len] = 0;
+ inst->Data = msg;
+
+ /* comma */
+ if (Parse_String(parseState, ",")) {
+
+ /* The second argument is a register name */
+ if (!Peek_Token(parseState, token))
+ RETURN_ERROR;
+
+ srcReg->RelAddr = GL_FALSE;
+ srcReg->Negate = NEGATE_NONE;
+ srcReg->Swizzle = SWIZZLE_NOOP;
+
+ /* Register can be R<n>, c[n], c[n +/- offset], a named vertex attrib,
+ * or an o[n] output register.
+ */
+ if (token[0] == 'R') {
+ srcReg->File = PROGRAM_TEMPORARY;
+ if (!Parse_TempReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else if (token[0] == 'c') {
+ srcReg->File = PROGRAM_ENV_PARAM;
+ if (!Parse_ParamReg(parseState, srcReg))
+ RETURN_ERROR;
+ }
+ else if (token[0] == 'v') {
+ srcReg->File = PROGRAM_INPUT;
+ if (!Parse_AttribReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else if (token[0] == 'o') {
+ srcReg->File = PROGRAM_OUTPUT;
+ if (!Parse_OutputReg(parseState, &idx))
+ RETURN_ERROR;
+ srcReg->Index = idx;
+ }
+ else {
+ RETURN_ERROR2("Bad source register name", token);
+ }
+ }
+ else {
+ srcReg->File = PROGRAM_UNDEFINED;
+ }
+
+ /* semicolon */
+ if (!Parse_String(parseState, ";"))
+ RETURN_ERROR;
+
+ return GL_TRUE;
+}
+
+
+static GLboolean
+Parse_OptionSequence(struct parse_state *parseState,
+ struct prog_instruction program[])
+{
+ (void) program;
+ while (1) {
+ if (!Parse_String(parseState, "OPTION"))
+ return GL_TRUE; /* ok, not an OPTION statement */
+ if (Parse_String(parseState, "NV_position_invariant")) {
+ parseState->isPositionInvariant = GL_TRUE;
+ }
+ else {
+ RETURN_ERROR1("unexpected OPTION statement");
+ }
+ if (!Parse_String(parseState, ";"))
+ return GL_FALSE;
+ }
+}
+
+
+static GLboolean
+Parse_InstructionSequence(struct parse_state *parseState,
+ struct prog_instruction program[])
+{
+ while (1) {
+ struct prog_instruction *inst = program + parseState->numInst;
+
+ /* Initialize the instruction */
+ _mesa_init_instructions(inst, 1);
+
+ if (Parse_String(parseState, "MOV")) {
+ if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_MOV))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "LIT")) {
+ if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_LIT))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "ABS")) {
+ if (!Parse_UnaryOpInstruction(parseState, inst, OPCODE_ABS))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "MUL")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MUL))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "ADD")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_ADD))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "DP3")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP3))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "DP4")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DP4))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "DST")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DST))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "MIN")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MIN))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "MAX")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_MAX))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "SLT")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SLT))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "SGE")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SGE))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "DPH")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_DPH))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "SUB")) {
+ if (!Parse_BiOpInstruction(parseState, inst, OPCODE_SUB))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "MAD")) {
+ if (!Parse_TriOpInstruction(parseState, inst, OPCODE_MAD))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "RCP")) {
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCP))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "RSQ")) {
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RSQ))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "EXP")) {
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_EXP))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "LOG")) {
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_LOG))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "RCC")) {
+ if (!Parse_ScalarInstruction(parseState, inst, OPCODE_RCC))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "ARL")) {
+ if (!Parse_AddressInstruction(parseState, inst))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "PRINT")) {
+ if (!Parse_PrintInstruction(parseState, inst))
+ RETURN_ERROR;
+ }
+ else if (Parse_String(parseState, "END")) {
+ if (!Parse_EndInstruction(parseState, inst))
+ RETURN_ERROR;
+ else {
+ parseState->numInst++;
+ return GL_TRUE; /* all done */
+ }
+ }
+ else {
+ /* bad instruction name */
+ RETURN_ERROR1("Unexpected token");
+ }
+
+ /* examine input/output registers */
+ if (inst->DstReg.File == PROGRAM_OUTPUT)
+ parseState->outputsWritten |= (1 << inst->DstReg.Index);
+ else if (inst->DstReg.File == PROGRAM_ENV_PARAM)
+ parseState->anyProgRegsWritten = GL_TRUE;
+
+ if (inst->SrcReg[0].File == PROGRAM_INPUT)
+ parseState->inputsRead |= (1 << inst->SrcReg[0].Index);
+ if (inst->SrcReg[1].File == PROGRAM_INPUT)
+ parseState->inputsRead |= (1 << inst->SrcReg[1].Index);
+ if (inst->SrcReg[2].File == PROGRAM_INPUT)
+ parseState->inputsRead |= (1 << inst->SrcReg[2].Index);
+
+ parseState->numInst++;
+
+ if (parseState->numInst >= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS)
+ RETURN_ERROR1("Program too long");
+ }
+
+ RETURN_ERROR;
+}
+
+
+static GLboolean
+Parse_Program(struct parse_state *parseState,
+ struct prog_instruction instBuffer[])
+{
+ if (parseState->isVersion1_1) {
+ if (!Parse_OptionSequence(parseState, instBuffer)) {
+ return GL_FALSE;
+ }
+ }
+ return Parse_InstructionSequence(parseState, instBuffer);
+}
+
+
+/**
+ * Parse/compile the 'str' returning the compiled 'program'.
+ * ctx->Program.ErrorPos will be -1 if successful. Otherwise, ErrorPos
+ * indicates the position of the error in 'str'.
+ */
+void
+_mesa_parse_nv_vertex_program(struct gl_context *ctx, GLenum dstTarget,
+ const GLubyte *str, GLsizei len,
+ struct gl_vertex_program *program)
+{
+ struct parse_state parseState;
+ struct prog_instruction instBuffer[MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS];
+ struct prog_instruction *newInst;
+ GLenum target;
+ GLubyte *programString;
+
+ /* Make a null-terminated copy of the program string */
+ programString = (GLubyte *) MALLOC(len + 1);
+ if (!programString) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+ return;
+ }
+ memcpy(programString, str, len);
+ programString[len] = 0;
+
+ /* Get ready to parse */
+ parseState.ctx = ctx;
+ parseState.start = programString;
+ parseState.isPositionInvariant = GL_FALSE;
+ parseState.isVersion1_1 = GL_FALSE;
+ parseState.numInst = 0;
+ parseState.inputsRead = 0;
+ parseState.outputsWritten = 0;
+ parseState.anyProgRegsWritten = GL_FALSE;
+ parseState.indirectRegisterFiles = 0x0;
+
+ /* Reset error state */
+ _mesa_set_program_error(ctx, -1, NULL);
+
+ /* check the program header */
+ if (strncmp((const char *) programString, "!!VP1.0", 7) == 0) {
+ target = GL_VERTEX_PROGRAM_NV;
+ parseState.pos = programString + 7;
+ parseState.isStateProgram = GL_FALSE;
+ }
+ else if (strncmp((const char *) programString, "!!VP1.1", 7) == 0) {
+ target = GL_VERTEX_PROGRAM_NV;
+ parseState.pos = programString + 7;
+ parseState.isStateProgram = GL_FALSE;
+ parseState.isVersion1_1 = GL_TRUE;
+ }
+ else if (strncmp((const char *) programString, "!!VSP1.0", 8) == 0) {
+ target = GL_VERTEX_STATE_PROGRAM_NV;
+ parseState.pos = programString + 8;
+ parseState.isStateProgram = GL_TRUE;
+ }
+ else {
+ /* invalid header */
+ ctx->Program.ErrorPos = 0;
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV(bad header)");
+ return;
+ }
+
+ /* make sure target and header match */
+ if (target != dstTarget) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glLoadProgramNV(target mismatch)");
+ return;
+ }
+
+
+ if (Parse_Program(&parseState, instBuffer)) {
+ gl_state_index state_tokens[STATE_LENGTH] = {0, 0, 0, 0, 0};
+ int i;
+
+ /* successful parse! */
+
+ if (parseState.isStateProgram) {
+ if (!parseState.anyProgRegsWritten) {
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glLoadProgramNV(c[#] not written)");
+ return;
+ }
+ }
+ else {
+ if (!parseState.isPositionInvariant &&
+ !(parseState.outputsWritten & (1 << VERT_RESULT_HPOS))) {
+ /* bit 1 = HPOS register */
+ _mesa_error(ctx, GL_INVALID_OPERATION,
+ "glLoadProgramNV(HPOS not written)");
+ return;
+ }
+ }
+
+ /* copy the compiled instructions */
+ assert(parseState.numInst <= MAX_NV_VERTEX_PROGRAM_INSTRUCTIONS);
+ newInst = _mesa_alloc_instructions(parseState.numInst);
+ if (!newInst) {
+ _mesa_error(ctx, GL_OUT_OF_MEMORY, "glLoadProgramNV");
+ free(programString);
+ return; /* out of memory */
+ }
+ _mesa_copy_instructions(newInst, instBuffer, parseState.numInst);
+
+ /* install the program */
+ program->Base.Target = target;
+ if (program->Base.String) {
+ free(program->Base.String);
+ }
+ program->Base.String = programString;
+ program->Base.Format = GL_PROGRAM_FORMAT_ASCII_ARB;
+ if (program->Base.Instructions) {
+ free(program->Base.Instructions);
+ }
+ program->Base.Instructions = newInst;
+ program->Base.InputsRead = parseState.inputsRead;
+ if (parseState.isPositionInvariant)
+ program->Base.InputsRead |= VERT_BIT_POS;
+ program->Base.NumInstructions = parseState.numInst;
+ program->Base.OutputsWritten = parseState.outputsWritten;
+ program->IsPositionInvariant = parseState.isPositionInvariant;
+ program->IsNVProgram = GL_TRUE;
+
+#ifdef DEBUG_foo
+ printf("--- glLoadProgramNV result ---\n");
+ _mesa_fprint_program_opt(stdout, &program->Base, PROG_PRINT_NV, 0);
+ printf("------------------------------\n");
+#endif
+
+ if (program->Base.Parameters)
+ _mesa_free_parameter_list(program->Base.Parameters);
+
+ program->Base.Parameters = _mesa_new_parameter_list ();
+ program->Base.NumParameters = 0;
+
+ program->Base.IndirectRegisterFiles = parseState.indirectRegisterFiles;
+
+ state_tokens[0] = STATE_VERTEX_PROGRAM;
+ state_tokens[1] = STATE_ENV;
+ /* Add refs to all of the potential params, in order. If we want to not
+ * upload everything, _mesa_layout_parameters is the answer.
+ */
+ for (i = 0; i < MAX_NV_VERTEX_PROGRAM_PARAMS; i++) {
+ GLint index;
+ state_tokens[2] = i;
+ index = _mesa_add_state_reference(program->Base.Parameters,
+ state_tokens);
+ assert(index == i);
+ }
+ program->Base.NumParameters = program->Base.Parameters->NumParameters;
+
+ _mesa_setup_nv_temporary_count(&program->Base);
+ _mesa_emit_nv_temp_initialization(ctx, &program->Base);
+ }
+ else {
+ /* Error! */
+ _mesa_error(ctx, GL_INVALID_OPERATION, "glLoadProgramNV");
+ /* NOTE: _mesa_set_program_error would have been called already */
+ /* GL_NV_vertex_program isn't supposed to set the error string
+ * so we reset it here.
+ */
+ _mesa_set_program_error(ctx, ctx->Program.ErrorPos, NULL);
+ }
+}
+
+
+const char *
+_mesa_nv_vertex_input_register_name(GLuint i)
+{
+ ASSERT(i < MAX_NV_VERTEX_PROGRAM_INPUTS);
+ return InputRegisters[i];
+}
+
+
+const char *
+_mesa_nv_vertex_output_register_name(GLuint i)
+{
+ ASSERT(i < MAX_NV_VERTEX_PROGRAM_OUTPUTS);
+ return OutputRegisters[i];
+}
+
diff --git a/mesalib/src/mesa/state_tracker/st_extensions.c b/mesalib/src/mesa/state_tracker/st_extensions.c
index a41e9e872..0ad9e1286 100644
--- a/mesalib/src/mesa/state_tracker/st_extensions.c
+++ b/mesalib/src/mesa/state_tracker/st_extensions.c
@@ -85,6 +85,9 @@ void st_init_limits(struct st_context *st)
c->MaxTextureRectSize
= _min(1 << (c->MaxTextureLevels - 1), MAX_TEXTURE_RECT_SIZE);
+ c->MaxArrayTextureLayers
+ = screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS);
+
c->MaxTextureImageUnits
= _min(screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS),
MAX_TEXTURE_IMAGE_UNITS);
@@ -170,6 +173,12 @@ void st_init_limits(struct st_context *st)
/* raise MaxParameters if native support is higher */
pc->MaxParameters = MAX2(pc->MaxParameters, pc->MaxNativeParameters);
+ /* Gallium doesn't really care about local vs. env parameters so use the
+ * same limits.
+ */
+ pc->MaxLocalParams = pc->MaxParameters;
+ pc->MaxEnvParams = pc->MaxParameters;
+
options->EmitNoNoise = TRUE;
/* TODO: make these more fine-grained if anyone needs it */
@@ -499,7 +508,7 @@ void st_init_extensions(struct st_context *st)
}
/* GL_EXT_texture_array */
- if (screen->get_param(screen, PIPE_CAP_ARRAY_TEXTURES)) {
+ if (screen->get_param(screen, PIPE_CAP_MAX_TEXTURE_ARRAY_LAYERS) > 1) {
ctx->Extensions.EXT_texture_array = GL_TRUE;
ctx->Extensions.MESA_texture_array = GL_TRUE;
}
diff --git a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
index 9394bea00..892169822 100644
--- a/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
+++ b/mesalib/src/mesa/state_tracker/st_glsl_to_tgsi.cpp
@@ -519,7 +519,7 @@ glsl_to_tgsi_visitor::emit(ir_instruction *ir, unsigned op,
inst->function = NULL;
- if (op == TGSI_OPCODE_ARL)
+ if (op == TGSI_OPCODE_ARL || op == TGSI_OPCODE_UARL)
this->num_address_regs = 1;
/* Update indirect addressing status used by TGSI */
@@ -746,16 +746,12 @@ void
glsl_to_tgsi_visitor::emit_arl(ir_instruction *ir,
st_dst_reg dst, st_src_reg src0)
{
- st_src_reg tmp = get_temp(glsl_type::float_type);
+ int op = TGSI_OPCODE_ARL;
- if (src0.type == GLSL_TYPE_INT)
- emit(NULL, TGSI_OPCODE_I2F, st_dst_reg(tmp), src0);
- else if (src0.type == GLSL_TYPE_UINT)
- emit(NULL, TGSI_OPCODE_U2F, st_dst_reg(tmp), src0);
- else
- tmp = src0;
-
- emit(NULL, TGSI_OPCODE_ARL, dst, tmp);
+ if (src0.type == GLSL_TYPE_INT || src0.type == GLSL_TYPE_UINT)
+ op = TGSI_OPCODE_UARL;
+
+ emit(NULL, op, dst, src0);
}
/**
@@ -2558,6 +2554,8 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
break;
}
+ const glsl_type *sampler_type = ir->sampler->type;
+
if (ir->projector) {
if (opcode == TGSI_OPCODE_TEX) {
/* Slot the projector in as the last component of the coord. */
@@ -2589,6 +2587,9 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
tmp_src = get_temp(glsl_type::vec4_type);
st_dst_reg tmp_dst = st_dst_reg(tmp_src);
+ /* Projective division not allowed for array samplers. */
+ assert(!sampler_type->sampler_array);
+
tmp_dst.writemask = WRITEMASK_Z;
emit(ir, TGSI_OPCODE_MOV, tmp_dst, this->result);
@@ -2613,7 +2614,15 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
* coord.
*/
ir->shadow_comparitor->accept(this);
- coord_dst.writemask = WRITEMASK_Z;
+
+ /* XXX This will need to be updated for cubemap array samplers. */
+ if (sampler_type->sampler_dimensionality == GLSL_SAMPLER_DIM_2D &&
+ sampler_type->sampler_array) {
+ coord_dst.writemask = WRITEMASK_W;
+ } else {
+ coord_dst.writemask = WRITEMASK_Z;
+ }
+
emit(ir, TGSI_OPCODE_MOV, coord_dst, this->result);
coord_dst.writemask = WRITEMASK_XYZW;
}
@@ -2651,8 +2660,6 @@ glsl_to_tgsi_visitor::visit(ir_texture *ir)
inst->tex_offsets[0].SwizzleZ = GET_SWZ(offset.swizzle, 2);
}
- const glsl_type *sampler_type = ir->sampler->type;
-
switch (sampler_type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D:
inst->tex_target = (sampler_type->sampler_array)
diff --git a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
index f4263c64c..b4111b00d 100644
--- a/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
+++ b/mesalib/src/mesa/state_tracker/st_mesa_to_tgsi.c
@@ -276,6 +276,8 @@ translate_texture_target( GLuint textarget,
case TEXTURE_1D_INDEX: return TGSI_TEXTURE_SHADOW1D;
case TEXTURE_2D_INDEX: return TGSI_TEXTURE_SHADOW2D;
case TEXTURE_RECT_INDEX: return TGSI_TEXTURE_SHADOWRECT;
+ case TEXTURE_1D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW1D_ARRAY;
+ case TEXTURE_2D_ARRAY_INDEX: return TGSI_TEXTURE_SHADOW2D_ARRAY;
default: break;
}
}
diff --git a/mesalib/src/mesa/swrast/s_spantemp.h b/mesalib/src/mesa/swrast/s_spantemp.h
index 125d19638..517c2eb3f 100644
--- a/mesalib/src/mesa/swrast/s_spantemp.h
+++ b/mesalib/src/mesa/swrast/s_spantemp.h
@@ -1,221 +1,228 @@
-/*
- * Mesa 3-D graphics library
- * Version: 6.5.1
- *
- * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included
- * in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-/*
- * Templates for the span/pixel-array write/read functions called via
- * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
- * and PutMonoValues functions.
- *
- * Define the following macros before including this file:
- * NAME(BASE) to generate the function name (i.e. add prefix or suffix)
- * RB_TYPE the renderbuffer DataType
- * SPAN_VARS to declare any local variables
- * INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel
- * INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel
- * STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer
- * FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer
- *
- * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
- * for the pixels to be stored. This is useful when dithering and probably
- * ignored otherwise.
- */
-
-#include "main/macros.h"
-
-
-#if !defined(RB_COMPONENTS)
-#define RB_COMPONENTS 4
-#endif
-
-
-static void
-NAME(get_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y, void *values )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- for (i = 0; i < count; i++) {
- FETCH_PIXEL(dest[i], pixel);
- INC_PIXEL_PTR(pixel);
- }
- (void) rb;
-}
-
-
-static void
-NAME(get_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[], void *values )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- for (i = 0; i < count; i++) {
- INIT_PIXEL_PTR(pixel, x[i], y[i]);
- FETCH_PIXEL(dest[i], pixel);
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y,
- const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- if (mask) {
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- STORE_PIXEL(pixel, x + i, y, src[i]);
- }
- INC_PIXEL_PTR(pixel);
- }
- }
- else {
- for (i = 0; i < count; i++) {
- STORE_PIXEL(pixel, x + i, y, src[i]);
- INC_PIXEL_PTR(pixel);
- }
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_row_rgb)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y,
- const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- for (i = 0; i < count; i++) {
- if (!mask || mask[i]) {
-#ifdef STORE_PIXEL_RGB
- STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
-#else
- STORE_PIXEL(pixel, x + i, y, src[i]);
-#endif
- }
- INC_PIXEL_PTR(pixel);
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_mono_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, GLint x, GLint y,
- const void *value, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE *src = (const RB_TYPE *) value;
- GLuint i;
- INIT_PIXEL_PTR(pixel, x, y);
- if (mask) {
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- STORE_PIXEL(pixel, x + i, y, src);
- }
- INC_PIXEL_PTR(pixel);
- }
- }
- else {
- for (i = 0; i < count; i++) {
- STORE_PIXEL(pixel, x + i, y, src);
- INC_PIXEL_PTR(pixel);
- }
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *values, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
- GLuint i;
- ASSERT(mask);
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- INIT_PIXEL_PTR(pixel, x[i], y[i]);
- STORE_PIXEL(pixel, x[i], y[i], src[i]);
- }
- }
- (void) rb;
-}
-
-
-static void
-NAME(put_mono_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
- GLuint count, const GLint x[], const GLint y[],
- const void *value, const GLubyte mask[] )
-{
-#ifdef SPAN_VARS
- SPAN_VARS
-#endif
- const RB_TYPE *src = (const RB_TYPE *) value;
- GLuint i;
- ASSERT(mask);
- for (i = 0; i < count; i++) {
- if (mask[i]) {
- INIT_PIXEL_PTR(pixel, x[i], y[i]);
- STORE_PIXEL(pixel, x[i], y[i], src);
- }
- }
- (void) rb;
-}
-
-
-#undef NAME
-#undef RB_TYPE
-#undef RB_COMPONENTS
-#undef SPAN_VARS
-#undef INIT_PIXEL_PTR
-#undef INC_PIXEL_PTR
-#undef STORE_PIXEL
-#undef STORE_PIXEL_RGB
-#undef FETCH_PIXEL
+/*
+ * Mesa 3-D graphics library
+ * Version: 6.5.1
+ *
+ * Copyright (C) 1999-2006 Brian Paul All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included
+ * in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+
+/*
+ * Templates for the span/pixel-array write/read functions called via
+ * the gl_renderbuffer's GetRow, GetValues, PutRow, PutMonoRow, PutValues
+ * and PutMonoValues functions.
+ *
+ * Define the following macros before including this file:
+ * NAME(BASE) to generate the function name (i.e. add prefix or suffix)
+ * RB_TYPE the renderbuffer DataType
+ * SPAN_VARS to declare any local variables
+ * INIT_PIXEL_PTR(P, X, Y) to initialize a pointer to a pixel
+ * INC_PIXEL_PTR(P) to increment a pixel pointer by one pixel
+ * STORE_PIXEL(DST, X, Y, VALUE) to store pixel values in buffer
+ * FETCH_PIXEL(DST, SRC) to fetch pixel values from buffer
+ *
+ * Note that in the STORE_PIXEL macros, we also pass in the (X,Y) coordinates
+ * for the pixels to be stored. This is useful when dithering and probably
+ * ignored otherwise.
+ */
+
+#include "main/macros.h"
+
+
+#if !defined(RB_COMPONENTS)
+#define RB_COMPONENTS 4
+#endif
+
+
+static void
+NAME(get_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y, void *values )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+ GLuint i;
+ INIT_PIXEL_PTR(pixel, x, y);
+ for (i = 0; i < count; i++) {
+ FETCH_PIXEL(dest[i], pixel);
+ INC_PIXEL_PTR(pixel);
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+static void
+NAME(get_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[], void *values )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ RB_TYPE (*dest)[RB_COMPONENTS] = (RB_TYPE (*)[RB_COMPONENTS]) values;
+ GLuint i;
+ for (i = 0; i < count; i++) {
+ INIT_PIXEL_PTR(pixel, x[i], y[i]);
+ FETCH_PIXEL(dest[i], pixel);
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+static void
+NAME(put_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y,
+ const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+ GLuint i;
+ INIT_PIXEL_PTR(pixel, x, y);
+ if (mask) {
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+ }
+ INC_PIXEL_PTR(pixel);
+ }
+ }
+ else {
+ for (i = 0; i < count; i++) {
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+ INC_PIXEL_PTR(pixel);
+ }
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+static void
+NAME(put_row_rgb)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y,
+ const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE (*src)[3] = (const RB_TYPE (*)[3]) values;
+ GLuint i;
+ INIT_PIXEL_PTR(pixel, x, y);
+ for (i = 0; i < count; i++) {
+ if (!mask || mask[i]) {
+#ifdef STORE_PIXEL_RGB
+ STORE_PIXEL_RGB(pixel, x + i, y, src[i]);
+#else
+ STORE_PIXEL(pixel, x + i, y, src[i]);
+#endif
+ }
+ INC_PIXEL_PTR(pixel);
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+static void
+NAME(put_mono_row)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, GLint x, GLint y,
+ const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE *src = (const RB_TYPE *) value;
+ GLuint i;
+ INIT_PIXEL_PTR(pixel, x, y);
+ if (mask) {
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ STORE_PIXEL(pixel, x + i, y, src);
+ }
+ INC_PIXEL_PTR(pixel);
+ }
+ }
+ else {
+ for (i = 0; i < count; i++) {
+ STORE_PIXEL(pixel, x + i, y, src);
+ INC_PIXEL_PTR(pixel);
+ }
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+static void
+NAME(put_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *values, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE (*src)[RB_COMPONENTS] = (const RB_TYPE (*)[RB_COMPONENTS]) values;
+ GLuint i;
+ ASSERT(mask);
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ INIT_PIXEL_PTR(pixel, x[i], y[i]);
+ STORE_PIXEL(pixel, x[i], y[i], src[i]);
+ }
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+static void
+NAME(put_mono_values)( struct gl_context *ctx, struct gl_renderbuffer *rb,
+ GLuint count, const GLint x[], const GLint y[],
+ const void *value, const GLubyte mask[] )
+{
+#ifdef SPAN_VARS
+ SPAN_VARS
+#endif
+ const RB_TYPE *src = (const RB_TYPE *) value;
+ GLuint i;
+ ASSERT(mask);
+ for (i = 0; i < count; i++) {
+ if (mask[i]) {
+ INIT_PIXEL_PTR(pixel, x[i], y[i]);
+ STORE_PIXEL(pixel, x[i], y[i], src);
+ }
+ }
+ (void) rb;
+ (void) ctx;
+}
+
+
+#undef NAME
+#undef RB_TYPE
+#undef RB_COMPONENTS
+#undef SPAN_VARS
+#undef INIT_PIXEL_PTR
+#undef INC_PIXEL_PTR
+#undef STORE_PIXEL
+#undef STORE_PIXEL_RGB
+#undef FETCH_PIXEL
diff --git a/pixman/configure.ac b/pixman/configure.ac
index 4c62102be..21613e135 100644
--- a/pixman/configure.ac
+++ b/pixman/configure.ac
@@ -54,7 +54,7 @@ AC_PREREQ([2.57])
m4_define([pixman_major], 0)
m4_define([pixman_minor], 23)
-m4_define([pixman_micro], 3)
+m4_define([pixman_micro], 5)
m4_define([pixman_version],[pixman_major.pixman_minor.pixman_micro])
@@ -801,6 +801,17 @@ fi
AC_MSG_RESULT($support_for_attribute_constructor)
AC_SUBST(TOOLCHAIN_SUPPORTS_ATTRIBUTE_CONSTRUCTOR)
+dnl ==================
+dnl libpng
+
+AC_CHECK_LIB([png], [png_write_info], [have_libpng=yes], [have_libpng=no])
+
+if test x$have_libpng = xyes; then
+ AC_DEFINE([HAVE_LIBPNG], [1], [Whether we have libpng])
+fi
+
+AC_SUBST(HAVE_LIBPNG)
+
AC_OUTPUT([pixman-1.pc
pixman-1-uninstalled.pc
Makefile
diff --git a/pixman/pixman/pixman-arm-neon-asm.S b/pixman/pixman/pixman-arm-neon-asm.S
index 3dc14d79d..3fcd07dc3 100644
--- a/pixman/pixman/pixman-arm-neon-asm.S
+++ b/pixman/pixman/pixman-arm-neon-asm.S
@@ -706,13 +706,55 @@ generate_composite_function_single_scanline \
/******************************************************************************/
-/* TODO: expand macros and do better instructions scheduling */
+.macro pixman_composite_over_n_8888_process_pixblock_head
+ /* deinterleaved source pixels in {d0, d1, d2, d3} */
+ /* inverted alpha in {d24} */
+ /* destination pixels in {d4, d5, d6, d7} */
+ vmull.u8 q8, d24, d4
+ vmull.u8 q9, d24, d5
+ vmull.u8 q10, d24, d6
+ vmull.u8 q11, d24, d7
+.endm
+
+.macro pixman_composite_over_n_8888_process_pixblock_tail
+ vrshr.u16 q14, q8, #8
+ vrshr.u16 q15, q9, #8
+ vrshr.u16 q2, q10, #8
+ vrshr.u16 q3, q11, #8
+ vraddhn.u16 d28, q14, q8
+ vraddhn.u16 d29, q15, q9
+ vraddhn.u16 d30, q2, q10
+ vraddhn.u16 d31, q3, q11
+ vqadd.u8 q14, q0, q14
+ vqadd.u8 q15, q1, q15
+.endm
+
.macro pixman_composite_over_n_8888_process_pixblock_tail_head
- pixman_composite_over_8888_8888_process_pixblock_tail
+ vrshr.u16 q14, q8, #8
+ vrshr.u16 q15, q9, #8
+ vrshr.u16 q2, q10, #8
+ vrshr.u16 q3, q11, #8
+ vraddhn.u16 d28, q14, q8
+ vraddhn.u16 d29, q15, q9
+ vraddhn.u16 d30, q2, q10
+ vraddhn.u16 d31, q3, q11
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
- vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
- pixman_composite_over_8888_8888_process_pixblock_head
- cache_preload 8, 8
+ vqadd.u8 q14, q0, q14
+ PF add PF_X, PF_X, #8
+ PF tst PF_CTL, #0x0F
+ PF addne PF_X, PF_X, #8
+ PF subne PF_CTL, PF_CTL, #1
+ vqadd.u8 q15, q1, q15
+ PF cmp PF_X, ORIG_W
+ vmull.u8 q8, d24, d4
+ PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
+ vmull.u8 q9, d24, d5
+ PF subge PF_X, PF_X, ORIG_W
+ vmull.u8 q10, d24, d6
+ PF subges PF_CTL, PF_CTL, #0x10
+ vmull.u8 q11, d24, d7
+ PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
.endm
.macro pixman_composite_over_n_8888_init
@@ -722,6 +764,7 @@ generate_composite_function_single_scanline \
vdup.8 d1, d3[1]
vdup.8 d2, d3[2]
vdup.8 d3, d3[3]
+ vmvn.8 d24, d3 /* get inverted alpha */
.endm
generate_composite_function \
@@ -1183,49 +1226,83 @@ generate_composite_function \
/* mask is in d24 (d25, d26, d27 are unused) */
/* in */
- vmull.u8 q0, d24, d8
- vmull.u8 q1, d24, d9
- vmull.u8 q6, d24, d10
- vmull.u8 q7, d24, d11
- vrshr.u16 q10, q0, #8
- vrshr.u16 q11, q1, #8
- vrshr.u16 q12, q6, #8
- vrshr.u16 q13, q7, #8
- vraddhn.u16 d0, q0, q10
- vraddhn.u16 d1, q1, q11
- vraddhn.u16 d2, q6, q12
- vraddhn.u16 d3, q7, q13
- vmvn.8 d24, d3 /* get inverted alpha */
+ vmull.u8 q6, d24, d8
+ vmull.u8 q7, d24, d9
+ vmull.u8 q8, d24, d10
+ vmull.u8 q9, d24, d11
+ vrshr.u16 q10, q6, #8
+ vrshr.u16 q11, q7, #8
+ vrshr.u16 q12, q8, #8
+ vrshr.u16 q13, q9, #8
+ vraddhn.u16 d0, q6, q10
+ vraddhn.u16 d1, q7, q11
+ vraddhn.u16 d2, q8, q12
+ vraddhn.u16 d3, q9, q13
+ vmvn.8 d25, d3 /* get inverted alpha */
/* source: d0 - blue, d1 - green, d2 - red, d3 - alpha */
/* destination: d4 - blue, d5 - green, d6 - red, d7 - alpha */
/* now do alpha blending */
- vmull.u8 q8, d24, d4
- vmull.u8 q9, d24, d5
- vmull.u8 q10, d24, d6
- vmull.u8 q11, d24, d7
+ vmull.u8 q8, d25, d4
+ vmull.u8 q9, d25, d5
+ vmull.u8 q10, d25, d6
+ vmull.u8 q11, d25, d7
.endm
.macro pixman_composite_over_n_8_8888_process_pixblock_tail
vrshr.u16 q14, q8, #8
vrshr.u16 q15, q9, #8
- vrshr.u16 q12, q10, #8
- vrshr.u16 q13, q11, #8
+ vrshr.u16 q6, q10, #8
+ vrshr.u16 q7, q11, #8
vraddhn.u16 d28, q14, q8
vraddhn.u16 d29, q15, q9
- vraddhn.u16 d30, q12, q10
- vraddhn.u16 d31, q13, q11
+ vraddhn.u16 d30, q6, q10
+ vraddhn.u16 d31, q7, q11
vqadd.u8 q14, q0, q14
vqadd.u8 q15, q1, q15
.endm
-/* TODO: expand macros and do better instructions scheduling */
.macro pixman_composite_over_n_8_8888_process_pixblock_tail_head
- pixman_composite_over_n_8_8888_process_pixblock_tail
- vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ vrshr.u16 q14, q8, #8
vld4.8 {d4, d5, d6, d7}, [DST_R, :128]!
+ vrshr.u16 q15, q9, #8
fetch_mask_pixblock
- cache_preload 8, 8
- pixman_composite_over_n_8_8888_process_pixblock_head
+ vrshr.u16 q6, q10, #8
+ PF add PF_X, PF_X, #8
+ vrshr.u16 q7, q11, #8
+ PF tst PF_CTL, #0x0F
+ vraddhn.u16 d28, q14, q8
+ PF addne PF_X, PF_X, #8
+ vraddhn.u16 d29, q15, q9
+ PF subne PF_CTL, PF_CTL, #1
+ vraddhn.u16 d30, q6, q10
+ PF cmp PF_X, ORIG_W
+ vraddhn.u16 d31, q7, q11
+ PF pld, [PF_DST, PF_X, lsl #dst_bpp_shift]
+ vmull.u8 q6, d24, d8
+ PF pld, [PF_MASK, PF_X, lsl #mask_bpp_shift]
+ vmull.u8 q7, d24, d9
+ PF subge PF_X, PF_X, ORIG_W
+ vmull.u8 q8, d24, d10
+ PF subges PF_CTL, PF_CTL, #0x10
+ vmull.u8 q9, d24, d11
+ PF ldrgeb DUMMY, [PF_DST, DST_STRIDE, lsl #dst_bpp_shift]!
+ vqadd.u8 q14, q0, q14
+ PF ldrgeb DUMMY, [PF_MASK, MASK_STRIDE, lsl #mask_bpp_shift]!
+ vqadd.u8 q15, q1, q15
+ vrshr.u16 q10, q6, #8
+ vrshr.u16 q11, q7, #8
+ vrshr.u16 q12, q8, #8
+ vrshr.u16 q13, q9, #8
+ vraddhn.u16 d0, q6, q10
+ vraddhn.u16 d1, q7, q11
+ vraddhn.u16 d2, q8, q12
+ vraddhn.u16 d3, q9, q13
+ vst4.8 {d28, d29, d30, d31}, [DST_W, :128]!
+ vmvn.8 d25, d3
+ vmull.u8 q8, d25, d4
+ vmull.u8 q9, d25, d5
+ vmull.u8 q10, d25, d6
+ vmull.u8 q11, d25, d7
.endm
.macro pixman_composite_over_n_8_8888_init
diff --git a/pixman/pixman/pixman-bits-image.c b/pixman/pixman/pixman-bits-image.c
index f540c76e1..f382c65ad 100644
--- a/pixman/pixman/pixman-bits-image.c
+++ b/pixman/pixman/pixman-bits-image.c
@@ -935,17 +935,16 @@ MAKE_FETCHERS (reflect_r5g6b5, r5g6b5, PIXMAN_REPEAT_REFLECT)
MAKE_FETCHERS (normal_r5g6b5, r5g6b5, PIXMAN_REPEAT_NORMAL)
static void
-bits_image_fetch_solid_32 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * buffer,
- const uint32_t * mask)
+replicate_pixel_32 (bits_image_t * bits,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer)
{
uint32_t color;
uint32_t *end;
- color = image->bits.fetch_pixel_32 (&image->bits, 0, 0);
+ color = bits->fetch_pixel_32 (bits, x, y);
end = buffer + width;
while (buffer < end)
@@ -953,18 +952,17 @@ bits_image_fetch_solid_32 (pixman_image_t * image,
}
static void
-bits_image_fetch_solid_64 (pixman_image_t * image,
- int x,
- int y,
- int width,
- uint32_t * b,
- const uint32_t * unused)
+replicate_pixel_64 (bits_image_t * bits,
+ int x,
+ int y,
+ int width,
+ uint32_t * b)
{
uint64_t color;
uint64_t *buffer = (uint64_t *)b;
uint64_t *end;
- color = image->bits.fetch_pixel_64 (&image->bits, 0, 0);
+ color = bits->fetch_pixel_64 (bits, x, y);
end = buffer + width;
while (buffer < end)
@@ -972,6 +970,28 @@ bits_image_fetch_solid_64 (pixman_image_t * image,
}
static void
+bits_image_fetch_solid_32 (pixman_image_t * image,
+ int x,
+ int y,
+ int width,
+ uint32_t * buffer,
+ const uint32_t * mask)
+{
+ replicate_pixel_32 (&image->bits, 0, 0, width, buffer);
+}
+
+static void
+bits_image_fetch_solid_64 (pixman_image_t * image,
+ int x,
+ int y,
+ int width,
+ uint32_t * b,
+ const uint32_t * unused)
+{
+ replicate_pixel_64 (&image->bits, 0, 0, width, b);
+}
+
+static void
bits_image_fetch_untransformed_repeat_none (bits_image_t *image,
pixman_bool_t wide,
int x,
@@ -1031,6 +1051,16 @@ bits_image_fetch_untransformed_repeat_normal (bits_image_t *image,
while (y >= image->height)
y -= image->height;
+ if (image->width == 1)
+ {
+ if (wide)
+ replicate_pixel_64 (image, 0, y, width, buffer);
+ else
+ replicate_pixel_32 (image, 0, y, width, buffer);
+
+ return;
+ }
+
while (width)
{
while (x < 0)
diff --git a/pixman/test/Makefile.am b/pixman/test/Makefile.am
index 9f61fc9e4..52ef8ad96 100644
--- a/pixman/test/Makefile.am
+++ b/pixman/test/Makefile.am
@@ -1,6 +1,6 @@
AM_CFLAGS = @OPENMP_CFLAGS@
AM_LDFLAGS = @OPENMP_CFLAGS@ @TESTPROGS_EXTRA_LDFLAGS@
-LDADD = $(top_builddir)/pixman/libpixman-1.la -lm
+LDADD = $(top_builddir)/pixman/libpixman-1.la -lm -lpng
INCLUDES = -I$(top_srcdir)/pixman -I$(top_builddir)/pixman
TESTPROGRAMS = \
diff --git a/pixman/test/utils.c b/pixman/test/utils.c
index 44188ea90..adabd75dd 100644
--- a/pixman/test/utils.c
+++ b/pixman/test/utils.c
@@ -21,6 +21,10 @@
#include <fenv.h>
#endif
+#ifdef HAVE_LIBPNG
+#include <png.h>
+#endif
+
/* Random number seed
*/
@@ -335,6 +339,114 @@ make_random_bytes (int n_bytes)
return bytes;
}
+#ifdef HAVE_LIBPNG
+
+static void
+pngify_pixels (uint32_t *pixels, int n_pixels)
+{
+ int i;
+
+ for (i = 0; i < n_pixels; ++i)
+ {
+ uint32_t p = pixels[i];
+ uint8_t *out = (uint8_t *)&(pixels[i]);
+ uint8_t a, r, g, b;
+
+ a = (p & 0xff000000) >> 24;
+ r = (p & 0x00ff0000) >> 16;
+ g = (p & 0x0000ff00) >> 8;
+ b = (p & 0x000000ff) >> 0;
+
+ if (a != 0)
+ {
+ r = (r * 255) / a;
+ g = (g * 255) / a;
+ b = (b * 255) / a;
+ }
+
+ *out++ = r;
+ *out++ = g;
+ *out++ = b;
+ *out++ = a;
+ }
+}
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+ int width = pixman_image_get_width (image);
+ int height = pixman_image_get_height (image);
+ int stride = width * 4;
+ uint32_t *data = malloc (height * stride);
+ pixman_image_t *copy;
+ png_struct *write_struct;
+ png_info *info_struct;
+ pixman_bool_t result = FALSE;
+ FILE *f = fopen (filename, "wb");
+ png_bytep *row_pointers;
+ int i;
+
+ if (!f)
+ return FALSE;
+
+ row_pointers = malloc (height * sizeof (png_bytep));
+
+ copy = pixman_image_create_bits (
+ PIXMAN_a8r8g8b8, width, height, data, stride);
+
+ pixman_image_composite32 (
+ PIXMAN_OP_SRC, image, NULL, copy, 0, 0, 0, 0, 0, 0, width, height);
+
+ pngify_pixels (data, height * width);
+
+ for (i = 0; i < height; ++i)
+ row_pointers[i] = (png_bytep)(data + i * width);
+
+ if (!(write_struct = png_create_write_struct (
+ PNG_LIBPNG_VER_STRING, NULL, NULL, NULL)))
+ goto out1;
+
+ if (!(info_struct = png_create_info_struct (write_struct)))
+ goto out2;
+
+ png_init_io (write_struct, f);
+
+ png_set_IHDR (write_struct, info_struct, width, height,
+ 8, PNG_COLOR_TYPE_RGB_ALPHA,
+ PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE,
+ PNG_FILTER_TYPE_BASE);
+
+ png_write_info (write_struct, info_struct);
+
+ png_write_image (write_struct, row_pointers);
+
+ png_write_end (write_struct, NULL);
+
+ result = TRUE;
+
+out2:
+ png_destroy_write_struct (&write_struct, &info_struct);
+
+out1:
+ if (fclose (f) != 0)
+ result = FALSE;
+
+ pixman_image_unref (copy);
+ free (row_pointers);
+ free (data);
+ return result;
+}
+
+#else /* no libpng */
+
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename)
+{
+ return FALSE;
+}
+
+#endif
+
/*
* A function, which can be used as a core part of the test programs,
* intended to detect various problems with the help of fuzzing input
diff --git a/pixman/test/utils.h b/pixman/test/utils.h
index f0c9c300c..3790483db 100644
--- a/pixman/test/utils.h
+++ b/pixman/test/utils.h
@@ -105,6 +105,9 @@ fail_after (int seconds, const char *msg);
/* If possible, enable traps for floating point exceptions */
void enable_fp_exceptions(void);
+pixman_bool_t
+write_png (pixman_image_t *image, const char *filename);
+
/* A pair of macros which can help to detect corruption of
* floating point registers after a function call. This may
* happen if _mm_empty() call is forgotten in MMX/SSE2 fast