aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/glsl
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2014-11-29 16:13:30 +0100
committermarha <marha@users.sourceforge.net>2014-11-29 16:13:30 +0100
commit7147e58c389cffeb930bdd8e3a2fdfc5d5bb3a0c (patch)
treee5b941fdff86328a065c46582ba53e0cc73c8576 /mesalib/src/glsl
parent0dbe845b2f4ba08924d6fcb9634d09dc3dde13d6 (diff)
parenta1011d63ffb5cc4f41bf0f4622ee3f1493d419d9 (diff)
downloadvcxsrv-7147e58c389cffeb930bdd8e3a2fdfc5d5bb3a0c.tar.gz
vcxsrv-7147e58c389cffeb930bdd8e3a2fdfc5d5bb3a0c.tar.bz2
vcxsrv-7147e58c389cffeb930bdd8e3a2fdfc5d5bb3a0c.zip
Merge remote-tracking branch 'origin/released'
Conflicts: xorg-server/dix/dispatch.c xorg-server/hw/xwin/ddraw.h xorg-server/hw/xwin/glx/glshim.c xorg-server/hw/xwin/winclipboard/xevents.c xorg-server/hw/xwin/windialogs.c xorg-server/hw/xwin/winmultiwindowshape.c xorg-server/hw/xwin/winmultiwindowwindow.c xorg-server/hw/xwin/winprefslex.l xorg-server/hw/xwin/winshadddnl.c xorg-server/hw/xwin/winshadgdi.c xorg-server/hw/xwin/winwndproc.c xorg-server/mi/miarc.c xorg-server/os/connection.c
Diffstat (limited to 'mesalib/src/glsl')
-rw-r--r--mesalib/src/glsl/Makefile.sources4
-rw-r--r--mesalib/src/glsl/ast.h29
-rw-r--r--mesalib/src/glsl/glsl_lexer.ll23
-rw-r--r--mesalib/src/glsl/glsl_parser_extras.cpp10
-rw-r--r--mesalib/src/glsl/glsl_types.cpp59
-rw-r--r--mesalib/src/glsl/glsl_types.h33
-rwxr-xr-xmesalib/src/glsl/ir.cpp48
-rw-r--r--mesalib/src/glsl/ir.h30
-rw-r--r--mesalib/src/glsl/ir_optimization.h1
-rw-r--r--mesalib/src/glsl/ir_reader.cpp2
-rw-r--r--mesalib/src/glsl/ir_uniform.h6
-rw-r--r--mesalib/src/glsl/link_uniforms.cpp50
-rw-r--r--mesalib/src/glsl/linker.cpp44
-rw-r--r--mesalib/src/glsl/list.h21
-rw-r--r--mesalib/src/glsl/loop_unroll.cpp13
-rw-r--r--mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp111
-rw-r--r--mesalib/src/glsl/main.cpp10
-rw-r--r--mesalib/src/glsl/opt_algebraic.cpp49
-rw-r--r--mesalib/src/glsl/opt_cse.cpp9
-rw-r--r--mesalib/src/glsl/s_expression.cpp2
-rw-r--r--mesalib/src/glsl/s_expression.h2
-rw-r--r--mesalib/src/glsl/strtod.c79
-rw-r--r--mesalib/src/glsl/strtod.h46
23 files changed, 369 insertions, 312 deletions
diff --git a/mesalib/src/glsl/Makefile.sources b/mesalib/src/glsl/Makefile.sources
index 0c55327d6..676fa0d7a 100644
--- a/mesalib/src/glsl/Makefile.sources
+++ b/mesalib/src/glsl/Makefile.sources
@@ -59,6 +59,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/loop_controls.cpp \
$(GLSL_SRCDIR)/loop_unroll.cpp \
$(GLSL_SRCDIR)/lower_clip_distance.cpp \
+ $(GLSL_SRCDIR)/lower_const_arrays_to_uniforms.cpp \
$(GLSL_SRCDIR)/lower_discard.cpp \
$(GLSL_SRCDIR)/lower_discard_flow.cpp \
$(GLSL_SRCDIR)/lower_if_to_cond_assign.cpp \
@@ -104,8 +105,7 @@ LIBGLSL_FILES = \
$(GLSL_SRCDIR)/opt_swizzle_swizzle.cpp \
$(GLSL_SRCDIR)/opt_tree_grafting.cpp \
$(GLSL_SRCDIR)/opt_vectorize.cpp \
- $(GLSL_SRCDIR)/s_expression.cpp \
- $(GLSL_SRCDIR)/strtod.c
+ $(GLSL_SRCDIR)/s_expression.cpp
# glsl_compiler
diff --git a/mesalib/src/glsl/ast.h b/mesalib/src/glsl/ast.h
index 83dfafd75..deb8c7a7f 100644
--- a/mesalib/src/glsl/ast.h
+++ b/mesalib/src/glsl/ast.h
@@ -644,19 +644,6 @@ class ast_declarator_list;
class ast_struct_specifier : public ast_node {
public:
- /**
- * \brief Make a shallow copy of an ast_struct_specifier.
- *
- * Use only if the objects are allocated from the same context and will not
- * be modified. Zeros the inherited ast_node's fields.
- */
- ast_struct_specifier(const ast_struct_specifier& that):
- ast_node(), name(that.name), declarations(that.declarations),
- is_declaration(that.is_declaration)
- {
- /* empty */
- }
-
ast_struct_specifier(const char *identifier,
ast_declarator_list *declarator_list);
virtual void print(void) const;
@@ -674,22 +661,6 @@ public:
class ast_type_specifier : public ast_node {
public:
- /**
- * \brief Make a shallow copy of an ast_type_specifier, specifying array
- * fields.
- *
- * Use only if the objects are allocated from the same context and will not
- * be modified. Zeros the inherited ast_node's fields.
- */
- ast_type_specifier(const ast_type_specifier *that,
- ast_array_specifier *array_specifier)
- : ast_node(), type_name(that->type_name), structure(that->structure),
- array_specifier(array_specifier),
- default_precision(that->default_precision)
- {
- /* empty */
- }
-
/** Construct a type specifier from a type name */
ast_type_specifier(const char *name)
: type_name(name), structure(NULL), array_specifier(NULL),
diff --git a/mesalib/src/glsl/glsl_lexer.ll b/mesalib/src/glsl/glsl_lexer.ll
index e66a93591..57c46be84 100644
--- a/mesalib/src/glsl/glsl_lexer.ll
+++ b/mesalib/src/glsl/glsl_lexer.ll
@@ -23,7 +23,7 @@
*/
#include <ctype.h>
#include <limits.h>
-#include "strtod.h"
+#include "util/strtod.h"
#include "ast.h"
#include "glsl_parser_extras.h"
#include "glsl_parser.h"
@@ -450,24 +450,11 @@ layout {
return LITERAL_INTEGER(8);
}
-[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = glsl_strtof(yytext, NULL);
- return FLOATCONSTANT;
- }
-\.[0-9]+([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = glsl_strtof(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+\.([eE][+-]?[0-9]+)?[fF]? {
- yylval->real = glsl_strtof(yytext, NULL);
- return FLOATCONSTANT;
- }
+[0-9]+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? |
+\.[0-9]+([eE][+-]?[0-9]+)?[fF]? |
+[0-9]+\.([eE][+-]?[0-9]+)?[fF]? |
[0-9]+[eE][+-]?[0-9]+[fF]? {
- yylval->real = glsl_strtof(yytext, NULL);
- return FLOATCONSTANT;
- }
-[0-9]+[fF] {
- yylval->real = glsl_strtof(yytext, NULL);
+ yylval->real = _mesa_strtof(yytext, NULL);
return FLOATCONSTANT;
}
diff --git a/mesalib/src/glsl/glsl_parser_extras.cpp b/mesalib/src/glsl/glsl_parser_extras.cpp
index 79f849465..27e3301e2 100644
--- a/mesalib/src/glsl/glsl_parser_extras.cpp
+++ b/mesalib/src/glsl/glsl_parser_extras.cpp
@@ -1350,9 +1350,15 @@ ast_struct_specifier::ast_struct_specifier(const char *identifier,
ast_declarator_list *declarator_list)
{
if (identifier == NULL) {
+ static mtx_t mutex = _MTX_INITIALIZER_NP;
static unsigned anon_count = 1;
- identifier = ralloc_asprintf(this, "#anon_struct_%04x", anon_count);
- anon_count++;
+ unsigned count;
+
+ mtx_lock(&mutex);
+ count = anon_count++;
+ mtx_unlock(&mutex);
+
+ identifier = ralloc_asprintf(this, "#anon_struct_%04x", count);
}
name = identifier;
this->declarations.push_degenerate_list_at_head(&declarator_list->link);
diff --git a/mesalib/src/glsl/glsl_types.cpp b/mesalib/src/glsl/glsl_types.cpp
index c11d86482..5f9919348 100644
--- a/mesalib/src/glsl/glsl_types.cpp
+++ b/mesalib/src/glsl/glsl_types.cpp
@@ -29,6 +29,7 @@ extern "C" {
#include "program/hash_table.h"
}
+mtx_t glsl_type::mutex = _MTX_INITIALIZER_NP;
hash_table *glsl_type::array_types = NULL;
hash_table *glsl_type::record_types = NULL;
hash_table *glsl_type::interface_types = NULL;
@@ -53,9 +54,14 @@ glsl_type::glsl_type(GLenum gl_type,
vector_elements(vector_elements), matrix_columns(matrix_columns),
length(0)
{
+ mtx_lock(&glsl_type::mutex);
+
init_ralloc_type_ctx();
assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
+
+ mtx_unlock(&glsl_type::mutex);
+
/* Neither dimension is zero or both dimensions are zero.
*/
assert((vector_elements == 0) == (matrix_columns == 0));
@@ -71,9 +77,14 @@ glsl_type::glsl_type(GLenum gl_type, glsl_base_type base_type,
sampler_array(array), sampler_type(type), interface_packing(0),
length(0)
{
+ mtx_lock(&glsl_type::mutex);
+
init_ralloc_type_ctx();
assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
+
+ mtx_unlock(&glsl_type::mutex);
+
memset(& fields, 0, sizeof(fields));
if (base_type == GLSL_TYPE_SAMPLER) {
@@ -95,11 +106,14 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
{
unsigned int i;
+ mtx_lock(&glsl_type::mutex);
+
init_ralloc_type_ctx();
assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
this->fields.structure = ralloc_array(this->mem_ctx,
glsl_struct_field, length);
+
for (i = 0; i < length; i++) {
this->fields.structure[i].type = fields[i].type;
this->fields.structure[i].name = ralloc_strdup(this->fields.structure,
@@ -110,6 +124,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
}
+
+ mtx_unlock(&glsl_type::mutex);
}
glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
@@ -123,6 +139,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
{
unsigned int i;
+ mtx_lock(&glsl_type::mutex);
+
init_ralloc_type_ctx();
assert(name != NULL);
this->name = ralloc_strdup(this->mem_ctx, name);
@@ -138,6 +156,8 @@ glsl_type::glsl_type(const glsl_struct_field *fields, unsigned num_fields,
this->fields.structure[i].sample = fields[i].sample;
this->fields.structure[i].matrix_layout = fields[i].matrix_layout;
}
+
+ mtx_unlock(&glsl_type::mutex);
}
@@ -285,6 +305,8 @@ const glsl_type *glsl_type::get_scalar_type() const
void
_mesa_glsl_release_types(void)
{
+ mtx_lock(&glsl_type::mutex);
+
if (glsl_type::array_types != NULL) {
hash_table_dtor(glsl_type::array_types);
glsl_type::array_types = NULL;
@@ -294,6 +316,8 @@ _mesa_glsl_release_types(void)
hash_table_dtor(glsl_type::record_types);
glsl_type::record_types = NULL;
}
+
+ mtx_unlock(&glsl_type::mutex);
}
@@ -302,7 +326,7 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
sampler_dimensionality(0), sampler_shadow(0), sampler_array(0),
sampler_type(0), interface_packing(0),
vector_elements(0), matrix_columns(0),
- name(NULL), length(length)
+ length(length), name(NULL)
{
this->fields.array = array;
/* Inherit the gl type of the base. The GL type is used for
@@ -316,7 +340,10 @@ glsl_type::glsl_type(const glsl_type *array, unsigned length) :
* NUL.
*/
const unsigned name_length = strlen(array->name) + 10 + 3;
+
+ mtx_lock(&glsl_type::mutex);
char *const n = (char *) ralloc_size(this->mem_ctx, name_length);
+ mtx_unlock(&glsl_type::mutex);
if (length == 0)
snprintf(n, name_length, "%s[]", array->name);
@@ -452,12 +479,6 @@ glsl_type::get_instance(unsigned base_type, unsigned rows, unsigned columns)
const glsl_type *
glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
{
-
- if (array_types == NULL) {
- array_types = hash_table_ctor(64, hash_table_string_hash,
- hash_table_string_compare);
- }
-
/* Generate a name using the base type pointer in the key. This is
* done because the name of the base type may not be unique across
* shaders. For example, two shaders may have different record types
@@ -466,9 +487,19 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
char key[128];
snprintf(key, sizeof(key), "%p[%u]", (void *) base, array_size);
+ mtx_lock(&glsl_type::mutex);
+
+ if (array_types == NULL) {
+ array_types = hash_table_ctor(64, hash_table_string_hash,
+ hash_table_string_compare);
+ }
+
const glsl_type *t = (glsl_type *) hash_table_find(array_types, key);
+
if (t == NULL) {
+ mtx_unlock(&glsl_type::mutex);
t = new glsl_type(base, array_size);
+ mtx_lock(&glsl_type::mutex);
hash_table_insert(array_types, (void *) t, ralloc_strdup(mem_ctx, key));
}
@@ -477,6 +508,8 @@ glsl_type::get_array_instance(const glsl_type *base, unsigned array_size)
assert(t->length == array_size);
assert(t->fields.array == base);
+ mtx_unlock(&glsl_type::mutex);
+
return t;
}
@@ -575,13 +608,17 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
{
const glsl_type key(fields, num_fields, name);
+ mtx_lock(&glsl_type::mutex);
+
if (record_types == NULL) {
record_types = hash_table_ctor(64, record_key_hash, record_key_compare);
}
const glsl_type *t = (glsl_type *) hash_table_find(record_types, & key);
if (t == NULL) {
+ mtx_unlock(&glsl_type::mutex);
t = new glsl_type(fields, num_fields, name);
+ mtx_lock(&glsl_type::mutex);
hash_table_insert(record_types, (void *) t, t);
}
@@ -590,6 +627,8 @@ glsl_type::get_record_instance(const glsl_struct_field *fields,
assert(t->length == num_fields);
assert(strcmp(t->name, name) == 0);
+ mtx_unlock(&glsl_type::mutex);
+
return t;
}
@@ -602,13 +641,17 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
{
const glsl_type key(fields, num_fields, packing, block_name);
+ mtx_lock(&glsl_type::mutex);
+
if (interface_types == NULL) {
interface_types = hash_table_ctor(64, record_key_hash, record_key_compare);
}
const glsl_type *t = (glsl_type *) hash_table_find(interface_types, & key);
if (t == NULL) {
+ mtx_unlock(&glsl_type::mutex);
t = new glsl_type(fields, num_fields, packing, block_name);
+ mtx_lock(&glsl_type::mutex);
hash_table_insert(interface_types, (void *) t, t);
}
@@ -617,6 +660,8 @@ glsl_type::get_interface_instance(const glsl_struct_field *fields,
assert(t->length == num_fields);
assert(strcmp(t->name, block_name) == 0);
+ mtx_unlock(&glsl_type::mutex);
+
return t;
}
diff --git a/mesalib/src/glsl/glsl_types.h b/mesalib/src/glsl/glsl_types.h
index eeb14c274..474b12914 100644
--- a/mesalib/src/glsl/glsl_types.h
+++ b/mesalib/src/glsl/glsl_types.h
@@ -122,16 +122,18 @@ struct glsl_type {
* easier to just ralloc_free 'mem_ctx' (or any of its ancestors). */
static void* operator new(size_t size)
{
- if (glsl_type::mem_ctx == NULL) {
- glsl_type::mem_ctx = ralloc_context(NULL);
- assert(glsl_type::mem_ctx != NULL);
- }
+ mtx_lock(&glsl_type::mutex);
+
+ /* mem_ctx should have been created by the static members */
+ assert(glsl_type::mem_ctx != NULL);
void *type;
type = ralloc_size(glsl_type::mem_ctx, size);
assert(type != NULL);
+ mtx_unlock(&glsl_type::mutex);
+
return type;
}
@@ -139,7 +141,9 @@ struct glsl_type {
* ralloc_free in that case. */
static void operator delete(void *type)
{
+ mtx_lock(&glsl_type::mutex);
ralloc_free(type);
+ mtx_unlock(&glsl_type::mutex);
}
/**
@@ -149,18 +153,11 @@ struct glsl_type {
* these will be 0.
*/
/*@{*/
- unsigned vector_elements:3; /**< 1, 2, 3, or 4 vector elements. */
- unsigned matrix_columns:3; /**< 1, 2, 3, or 4 matrix columns. */
+ uint8_t vector_elements; /**< 1, 2, 3, or 4 vector elements. */
+ uint8_t matrix_columns; /**< 1, 2, 3, or 4 matrix columns. */
/*@}*/
/**
- * Name of the data type
- *
- * Will never be \c NULL.
- */
- const char *name;
-
- /**
* For \c GLSL_TYPE_ARRAY, this is the length of the array. For
* \c GLSL_TYPE_STRUCT or \c GLSL_TYPE_INTERFACE, it is the number of
* elements in the structure and the number of values pointed to by
@@ -169,6 +166,13 @@ struct glsl_type {
unsigned length;
/**
+ * Name of the data type
+ *
+ * Will never be \c NULL.
+ */
+ const char *name;
+
+ /**
* Subtype of composite data types.
*/
union {
@@ -618,6 +622,9 @@ struct glsl_type {
bool record_compare(const glsl_type *b) const;
private:
+
+ static mtx_t mutex;
+
/**
* ralloc context for all glsl_type allocations
*
diff --git a/mesalib/src/glsl/ir.cpp b/mesalib/src/glsl/ir.cpp
index 5907854f6..f6aeb6158 100755
--- a/mesalib/src/glsl/ir.cpp
+++ b/mesalib/src/glsl/ir.cpp
@@ -46,11 +46,6 @@ bool ir_rvalue::is_negative_one() const
return false;
}
-bool ir_rvalue::is_basis() const
-{
- return false;
-}
-
/**
* Modify the swizzle make to move one component to another
*
@@ -1191,49 +1186,6 @@ ir_constant::is_negative_one() const
}
bool
-ir_constant::is_basis() const
-{
- if (!this->type->is_scalar() && !this->type->is_vector())
- return false;
-
- if (this->type->is_boolean())
- return false;
-
- unsigned ones = 0;
- for (unsigned c = 0; c < this->type->vector_elements; c++) {
- switch (this->type->base_type) {
- case GLSL_TYPE_FLOAT:
- if (this->value.f[c] == 1.0)
- ones++;
- else if (this->value.f[c] != 0.0)
- return false;
- break;
- case GLSL_TYPE_INT:
- if (this->value.i[c] == 1)
- ones++;
- else if (this->value.i[c] != 0)
- return false;
- break;
- case GLSL_TYPE_UINT:
- if (int(this->value.u[c]) == 1)
- ones++;
- else if (int(this->value.u[c]) != 0)
- return false;
- break;
- default:
- /* The only other base types are structures, arrays, samplers, and
- * booleans. Samplers cannot be constants, and the others should
- * have been filtered out above.
- */
- assert(!"Should not get here.");
- return false;
- }
- }
-
- return ones == 1;
-}
-
-bool
ir_constant::is_uint16_constant() const
{
if (!type->is_integer())
diff --git a/mesalib/src/glsl/ir.h b/mesalib/src/glsl/ir.h
index 90c443c3d..a0f48b2af 100644
--- a/mesalib/src/glsl/ir.h
+++ b/mesalib/src/glsl/ir.h
@@ -251,8 +251,7 @@ public:
* for vector and scalar types that have all elements set to the value
* zero (or \c false for booleans).
*
- * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one,
- * ir_constant::is_basis
+ * \sa ir_constant::has_value, ir_rvalue::is_one, ir_rvalue::is_negative_one
*/
virtual bool is_zero() const;
@@ -264,8 +263,7 @@ public:
* for vector and scalar types that have all elements set to the value
* one (or \c true for booleans).
*
- * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one,
- * ir_constant::is_basis
+ * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_negative_one
*/
virtual bool is_one() const;
@@ -278,25 +276,10 @@ public:
* negative one. For boolean types, the result is always \c false.
*
* \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one
- * ir_constant::is_basis
*/
virtual bool is_negative_one() const;
/**
- * Determine if an r-value is a basis vector
- *
- * The base implementation of this function always returns \c false. The
- * \c ir_constant class over-rides this function to return \c true \b only
- * for vector and scalar types that have one element set to the value one,
- * and the other elements set to the value zero. For boolean types, the
- * result is always \c false.
- *
- * \sa ir_constant::has_value, ir_rvalue::is_zero, ir_rvalue::is_one,
- * is_constant::is_negative_one
- */
- virtual bool is_basis() const;
-
- /**
* Determine if an r-value is an unsigned integer constant which can be
* stored in 16 bits.
*
@@ -359,6 +342,12 @@ enum ir_var_declaration_type {
* re-declared by the shader.
*/
ir_var_declared_implicitly,
+
+ /**
+ * Variable is implicitly generated by the compiler and should not be
+ * visible via the API.
+ */
+ ir_var_hidden,
};
/**
@@ -2257,7 +2246,7 @@ public:
* Determine whether a constant has the same value as another constant
*
* \sa ir_constant::is_zero, ir_constant::is_one,
- * ir_constant::is_negative_one, ir_constant::is_basis
+ * ir_constant::is_negative_one
*/
bool has_value(const ir_constant *) const;
@@ -2270,7 +2259,6 @@ public:
virtual bool is_zero() const;
virtual bool is_one() const;
virtual bool is_negative_one() const;
- virtual bool is_basis() const;
/**
* Return true for constants that could be stored as 16-bit unsigned values.
diff --git a/mesalib/src/glsl/ir_optimization.h b/mesalib/src/glsl/ir_optimization.h
index e25857ac5..34e0b4b94 100644
--- a/mesalib/src/glsl/ir_optimization.h
+++ b/mesalib/src/glsl/ir_optimization.h
@@ -114,6 +114,7 @@ bool lower_noise(exec_list *instructions);
bool lower_variable_index_to_cond_assign(exec_list *instructions,
bool lower_input, bool lower_output, bool lower_temp, bool lower_uniform);
bool lower_quadop_vector(exec_list *instructions, bool dont_lower_swz);
+bool lower_const_arrays_to_uniforms(exec_list *instructions);
bool lower_clip_distance(gl_shader *shader);
void lower_output_reads(exec_list *instructions);
bool lower_packing_builtins(exec_list *instructions, int op_mask);
diff --git a/mesalib/src/glsl/ir_reader.cpp b/mesalib/src/glsl/ir_reader.cpp
index ae00e7934..fd318c046 100644
--- a/mesalib/src/glsl/ir_reader.cpp
+++ b/mesalib/src/glsl/ir_reader.cpp
@@ -972,7 +972,7 @@ ir_reader::read_texture(s_expression *expr)
op = ir_query_levels;
} else if (MATCH(expr, other_pattern)) {
op = ir_texture::get_opcode(tag->value());
- if (op == -1)
+ if (op == (ir_texture_opcode) -1)
return NULL;
} else {
ir_read_error(NULL, "unexpected texture pattern %s", tag->value());
diff --git a/mesalib/src/glsl/ir_uniform.h b/mesalib/src/glsl/ir_uniform.h
index b9ecf7cdd..21b5d05c1 100644
--- a/mesalib/src/glsl/ir_uniform.h
+++ b/mesalib/src/glsl/ir_uniform.h
@@ -175,6 +175,12 @@ struct gl_uniform_storage {
* arrays this is the first element in the array.
*/
unsigned remap_location;
+
+ /**
+ * This is a compiler-generated uniform that should not be advertised
+ * via the API.
+ */
+ bool hidden;
};
#ifdef __cplusplus
diff --git a/mesalib/src/glsl/link_uniforms.cpp b/mesalib/src/glsl/link_uniforms.cpp
index f613abc99..a77b5868a 100644
--- a/mesalib/src/glsl/link_uniforms.cpp
+++ b/mesalib/src/glsl/link_uniforms.cpp
@@ -585,6 +585,8 @@ private:
this->uniforms[id].driver_storage = NULL;
this->uniforms[id].storage = this->values;
this->uniforms[id].atomic_buffer_index = -1;
+ this->uniforms[id].hidden =
+ current_var->data.how_declared == ir_var_hidden;
if (this->ubo_block_index != -1) {
this->uniforms[id].block_index = this->ubo_block_index;
@@ -806,6 +808,50 @@ link_set_image_access_qualifiers(struct gl_shader_program *prog)
}
}
+/**
+ * Sort the array of uniform storage so that the non-hidden uniforms are first
+ *
+ * This function sorts the list "in place." This is important because some of
+ * the storage accessible from \c uniforms has \c uniforms as its \c ralloc
+ * context. If \c uniforms is freed, some other storage will also be freed.
+ */
+static unsigned
+move_hidden_uniforms_to_end(struct gl_shader_program *prog,
+ struct gl_uniform_storage *uniforms,
+ unsigned num_elements)
+{
+ struct gl_uniform_storage *sorted_uniforms =
+ ralloc_array(prog, struct gl_uniform_storage, num_elements);
+ unsigned hidden_uniforms = 0;
+ unsigned j = 0;
+
+ /* Add the non-hidden uniforms. */
+ for (unsigned i = 0; i < num_elements; i++) {
+ if (!uniforms[i].hidden)
+ sorted_uniforms[j++] = uniforms[i];
+ }
+
+ /* Add and count the hidden uniforms. */
+ for (unsigned i = 0; i < num_elements; i++) {
+ if (uniforms[i].hidden) {
+ sorted_uniforms[j++] = uniforms[i];
+ hidden_uniforms++;
+ }
+ }
+
+ assert(prog->UniformHash != NULL);
+ prog->UniformHash->clear();
+ for (unsigned i = 0; i < num_elements; i++) {
+ if (sorted_uniforms[i].name != NULL)
+ prog->UniformHash->put(i, sorted_uniforms[i].name);
+ }
+
+ memcpy(uniforms, sorted_uniforms, sizeof(uniforms[0]) * num_elements);
+ ralloc_free(sorted_uniforms);
+
+ return hidden_uniforms;
+}
+
void
link_assign_uniform_locations(struct gl_shader_program *prog,
unsigned int boolean_true)
@@ -926,6 +972,9 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
sizeof(prog->_LinkedShaders[i]->SamplerTargets));
}
+ const unsigned hidden_uniforms =
+ move_hidden_uniforms_to_end(prog, uniforms, num_user_uniforms);
+
/* Reserve all the explicit locations of the active uniforms. */
for (unsigned i = 0; i < num_user_uniforms; i++) {
if (uniforms[i].remap_location != UNMAPPED_UNIFORM_LOC) {
@@ -977,6 +1026,7 @@ link_assign_uniform_locations(struct gl_shader_program *prog,
#endif
prog->NumUserUniformStorage = num_user_uniforms;
+ prog->NumHiddenUniforms = hidden_uniforms;
prog->UniformStorage = uniforms;
link_set_image_access_qualifiers(prog);
diff --git a/mesalib/src/glsl/linker.cpp b/mesalib/src/glsl/linker.cpp
index 2d31801d3..de6b1fb9f 100644
--- a/mesalib/src/glsl/linker.cpp
+++ b/mesalib/src/glsl/linker.cpp
@@ -642,7 +642,7 @@ validate_geometry_shader_emissions(struct gl_context *ctx,
emit_vertex.run(prog->_LinkedShaders[MESA_SHADER_GEOMETRY]->ir);
if (emit_vertex.error()) {
linker_error(prog, "Invalid call %s(%d). Accepted values for the "
- "stream parameter are in the range [0, %d].",
+ "stream parameter are in the range [0, %d].\n",
emit_vertex.error_func(),
emit_vertex.error_stream(),
ctx->Const.MaxVertexStreams - 1);
@@ -676,7 +676,7 @@ validate_geometry_shader_emissions(struct gl_context *ctx,
*/
if (prog->Geom.UsesStreams && prog->Geom.OutputType != GL_POINTS) {
linker_error(prog, "EmitStreamVertex(n) and EndStreamPrimitive(n) "
- "with n>0 requires point output");
+ "with n>0 requires point output\n");
}
}
}
@@ -808,7 +808,7 @@ cross_validate_globals(struct gl_shader_program *prog,
linker_error(prog,
"All redeclarations of gl_FragDepth in all "
"fragment shaders in a single program must have "
- "the same set of qualifiers.");
+ "the same set of qualifiers.\n");
}
if (var->data.used && layout_differs) {
@@ -817,7 +817,7 @@ cross_validate_globals(struct gl_shader_program *prog,
"qualifier in any fragment shader, it must be "
"redeclared with the same layout qualifier in "
"all fragment shaders that have assignments to "
- "gl_FragDepth");
+ "gl_FragDepth\n");
}
}
@@ -948,7 +948,7 @@ interstage_cross_validate_uniform_blocks(struct gl_shader_program *prog)
&sh->UniformBlocks[j]);
if (index == -1) {
- linker_error(prog, "uniform block `%s' has mismatching definitions",
+ linker_error(prog, "uniform block `%s' has mismatching definitions\n",
sh->UniformBlocks[j].Name);
return false;
}
@@ -1635,7 +1635,7 @@ link_intrastage_shaders(void *mem_ctx,
if ((other_sig != NULL) && other_sig->is_defined
&& !other_sig->is_builtin()) {
- linker_error(prog, "function `%s' is multiply defined",
+ linker_error(prog, "function `%s' is multiply defined\n",
f->name);
return NULL;
}
@@ -2086,7 +2086,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
if (attr + slots > max_index) {
linker_error(prog,
"insufficient contiguous locations "
- "available for %s `%s' %d %d %d", string,
+ "available for %s `%s' %d %d %d\n", string,
var->name, used_locations, use_mask, attr);
return false;
}
@@ -2155,7 +2155,7 @@ assign_attribute_or_color_locations(gl_shader_program *prog,
linker_error(prog,
"insufficient contiguous locations "
- "available for %s `%s'",
+ "available for %s `%s'\n",
string, to_assign[i].var->name);
return false;
}
@@ -2257,7 +2257,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
continue;
if (sh->num_samplers > ctx->Const.Program[i].MaxTextureImageUnits) {
- linker_error(prog, "Too many %s shader texture samplers",
+ linker_error(prog, "Too many %s shader texture samplers\n",
_mesa_shader_stage_to_string(i));
}
@@ -2271,7 +2271,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
_mesa_shader_stage_to_string(i));
} else {
linker_error(prog, "Too many %s shader default uniform block "
- "components",
+ "components\n",
_mesa_shader_stage_to_string(i));
}
}
@@ -2284,7 +2284,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
"this is non-portable out-of-spec behavior\n",
_mesa_shader_stage_to_string(i));
} else {
- linker_error(prog, "Too many %s shader uniform components",
+ linker_error(prog, "Too many %s shader uniform components\n",
_mesa_shader_stage_to_string(i));
}
}
@@ -2302,7 +2302,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
}
if (total_uniform_blocks > ctx->Const.MaxCombinedUniformBlocks) {
- linker_error(prog, "Too many combined uniform blocks (%d/%d)",
+ linker_error(prog, "Too many combined uniform blocks (%d/%d)\n",
prog->NumUniformBlocks,
ctx->Const.MaxCombinedUniformBlocks);
} else {
@@ -2310,7 +2310,7 @@ check_resources(struct gl_context *ctx, struct gl_shader_program *prog)
const unsigned max_uniform_blocks =
ctx->Const.Program[i].MaxUniformBlocks;
if (blocks[i] > max_uniform_blocks) {
- linker_error(prog, "Too many %s uniform blocks (%d/%d)",
+ linker_error(prog, "Too many %s uniform blocks (%d/%d)\n",
_mesa_shader_stage_to_string(i),
blocks[i],
max_uniform_blocks);
@@ -2338,7 +2338,7 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
if (sh) {
if (sh->NumImages > ctx->Const.Program[i].MaxImageUniforms)
- linker_error(prog, "Too many %s shader image uniforms",
+ linker_error(prog, "Too many %s shader image uniforms\n",
_mesa_shader_stage_to_string(i));
total_image_units += sh->NumImages;
@@ -2354,11 +2354,11 @@ check_image_resources(struct gl_context *ctx, struct gl_shader_program *prog)
}
if (total_image_units > ctx->Const.MaxCombinedImageUniforms)
- linker_error(prog, "Too many combined image uniforms");
+ linker_error(prog, "Too many combined image uniforms\n");
if (total_image_units + fragment_outputs >
ctx->Const.MaxCombinedImageUnitsAndFragmentOutputs)
- linker_error(prog, "Too many combined image uniforms and fragment outputs");
+ linker_error(prog, "Too many combined image uniforms and fragment outputs\n");
}
@@ -2382,7 +2382,7 @@ reserve_explicit_locations(struct gl_shader_program *prog,
max_loc + 1);
if (!prog->UniformRemapTable) {
- linker_error(prog, "Out of memory during linking.");
+ linker_error(prog, "Out of memory during linking.\n");
return false;
}
@@ -2411,8 +2411,8 @@ reserve_explicit_locations(struct gl_shader_program *prog,
* or linker error will be generated."
*/
linker_error(prog,
- "location qualifier for uniform %s overlaps"
- "previously used location",
+ "location qualifier for uniform %s overlaps "
+ "previously used location\n",
var->name);
return false;
}
@@ -2447,7 +2447,7 @@ check_explicit_uniform_locations(struct gl_context *ctx,
string_to_uint_map *uniform_map = new string_to_uint_map;
if (!uniform_map) {
- linker_error(prog, "Out of memory during linking.");
+ linker_error(prog, "Out of memory during linking.\n");
return;
}
@@ -2678,6 +2678,8 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
&ctx->Const.ShaderCompilerOptions[i],
ctx->Const.NativeIntegers))
;
+
+ lower_const_arrays_to_uniforms(prog->_LinkedShaders[i]->ir);
}
/* Check and validate stream emissions in geometry shaders */
@@ -2719,7 +2721,7 @@ link_shaders(struct gl_context *ctx, struct gl_shader_program *prog)
*/
if (first == MESA_SHADER_FRAGMENT) {
linker_error(prog, "Transform feedback varyings specified, but "
- "no vertex or geometry shader is present.");
+ "no vertex or geometry shader is present.\n");
goto done;
}
diff --git a/mesalib/src/glsl/list.h b/mesalib/src/glsl/list.h
index b40764cae..bebe17fcf 100644
--- a/mesalib/src/glsl/list.h
+++ b/mesalib/src/glsl/list.h
@@ -529,6 +529,27 @@ exec_node_insert_list_before(struct exec_node *n, struct exec_list *before)
exec_list_make_empty(before);
}
+static inline void
+exec_list_validate(const struct exec_list *list)
+{
+ const struct exec_node *node;
+
+ assert(list->head->prev == (const struct exec_node *) &list->head);
+ assert(list->tail == NULL);
+ assert(list->tail_pred->next == (const struct exec_node *) &list->tail);
+
+ /* We could try to use one of the interators below for this but they all
+ * either require C++ or assume the exec_node is embedded in a structure
+ * which is not the case for this function.
+ */
+ for (node = exec_list_get_head_const(list);
+ !exec_node_is_tail_sentinel(node);
+ node = exec_node_get_next_const(node)) {
+ assert(node->next->prev == node);
+ assert(node->prev->next == node);
+ }
+}
+
#ifdef __cplusplus
inline void exec_list::make_empty()
{
diff --git a/mesalib/src/glsl/loop_unroll.cpp b/mesalib/src/glsl/loop_unroll.cpp
index ce795f6cd..635e1dd99 100644
--- a/mesalib/src/glsl/loop_unroll.cpp
+++ b/mesalib/src/glsl/loop_unroll.cpp
@@ -64,6 +64,7 @@ class loop_unroll_count : public ir_hierarchical_visitor {
public:
int nodes;
bool unsupported_variable_indexing;
+ bool array_indexed_by_induction_var_with_exact_iterations;
/* If there are nested loops, the node count will be inaccurate. */
bool nested_loop;
@@ -74,6 +75,7 @@ public:
nodes = 0;
nested_loop = false;
unsupported_variable_indexing = false;
+ array_indexed_by_induction_var_with_exact_iterations = false;
run(list);
}
@@ -112,6 +114,14 @@ public:
ir_variable *array = ir->array->variable_referenced();
loop_variable *lv = ls->get(ir->array_index->variable_referenced());
if (array && lv && lv->is_induction_var()) {
+ /* If an array is indexed by a loop induction variable, and the
+ * array size is exactly the number of loop iterations, this is
+ * probably a simple for-loop trying to access each element in
+ * turn; the application may expect it to be unrolled.
+ */
+ if (int(array->type->length) == ls->limiting_terminator->iterations)
+ array_indexed_by_induction_var_with_exact_iterations = true;
+
switch (array->data.mode) {
case ir_var_auto:
case ir_var_temporary:
@@ -314,7 +324,8 @@ loop_unroll_visitor::visit_leave(ir_loop *ir)
bool loop_too_large =
count.nested_loop || count.nodes * iterations > max_iterations * 5;
- if (loop_too_large && !count.unsupported_variable_indexing)
+ if (loop_too_large && !count.unsupported_variable_indexing &&
+ !count.array_indexed_by_induction_var_with_exact_iterations)
return visit_continue;
/* Note: the limiting terminator contributes 1 to ls->num_loop_jumps.
diff --git a/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp b/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp
new file mode 100644
index 000000000..2243f479a
--- /dev/null
+++ b/mesalib/src/glsl/lower_const_arrays_to_uniforms.cpp
@@ -0,0 +1,111 @@
+/*
+ * Copyright © 2014 Intel Corporation
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+/**
+ * \file lower_const_arrays_to_uniforms.cpp
+ *
+ * Lower constant arrays to uniform arrays.
+ *
+ * Some driver backends (such as i965 and nouveau) don't handle constant arrays
+ * gracefully, instead treating them as ordinary writable temporary arrays.
+ * Since arrays can be large, this often means spilling them to scratch memory,
+ * which usually involves a large number of instructions.
+ *
+ * This must be called prior to link_set_uniform_initializers(); we need the
+ * linker to process our new uniform's constant initializer.
+ *
+ * This should be called after optimizations, since those can result in
+ * splitting and removing arrays that are indexed by constant expressions.
+ */
+#include "ir.h"
+#include "ir_visitor.h"
+#include "ir_rvalue_visitor.h"
+#include "glsl_types.h"
+
+namespace {
+class lower_const_array_visitor : public ir_rvalue_visitor {
+public:
+ lower_const_array_visitor(exec_list *insts)
+ {
+ instructions = insts;
+ progress = false;
+ index = 0;
+ }
+
+ bool run()
+ {
+ visit_list_elements(this, instructions);
+ return progress;
+ }
+
+ void handle_rvalue(ir_rvalue **rvalue);
+
+private:
+ exec_list *instructions;
+ bool progress;
+ unsigned index;
+};
+
+void
+lower_const_array_visitor::handle_rvalue(ir_rvalue **rvalue)
+{
+ if (!*rvalue)
+ return;
+
+ ir_dereference_array *dra = (*rvalue)->as_dereference_array();
+ if (!dra)
+ return;
+
+ ir_constant *con = dra->array->as_constant();
+ if (!con || !con->type->is_array())
+ return;
+
+ void *mem_ctx = ralloc_parent(con);
+
+ char *uniform_name = ralloc_asprintf(mem_ctx, "constarray__%d", index++);
+
+ ir_variable *uni =
+ new(mem_ctx) ir_variable(con->type, uniform_name, ir_var_uniform);
+ uni->constant_initializer = con;
+ uni->constant_value = con;
+ uni->data.has_initializer = true;
+ uni->data.how_declared = ir_var_hidden;
+ uni->data.read_only = true;
+ /* Assume the whole thing is accessed. */
+ uni->data.max_array_access = uni->type->length - 1;
+ instructions->push_head(uni);
+
+ ir_dereference_variable *varref = new(mem_ctx) ir_dereference_variable(uni);
+ *rvalue = new(mem_ctx) ir_dereference_array(varref, dra->array_index);
+
+ progress = true;
+}
+
+} /* anonymous namespace */
+
+bool
+lower_const_arrays_to_uniforms(exec_list *instructions)
+{
+ lower_const_array_visitor v(instructions);
+ return v.run();
+}
diff --git a/mesalib/src/glsl/main.cpp b/mesalib/src/glsl/main.cpp
index 79e943831..432643707 100644
--- a/mesalib/src/glsl/main.cpp
+++ b/mesalib/src/glsl/main.cpp
@@ -46,6 +46,7 @@
#include "glsl_parser_extras.h"
#include "ir_optimization.h"
#include "program.h"
+#include "program/hash_table.h"
#include "loop_analysis.h"
#include "standalone_scaffolding.h"
@@ -368,6 +369,11 @@ main(int argc, char **argv)
assert(whole_program != NULL);
whole_program->InfoLog = ralloc_strdup(whole_program, "");
+ /* Created just to avoid segmentation faults */
+ whole_program->AttributeBindings = new string_to_uint_map;
+ whole_program->FragDataBindings = new string_to_uint_map;
+ whole_program->FragDataIndexBindings = new string_to_uint_map;
+
for (/* empty */; argc > optind; optind++) {
whole_program->Shaders =
reralloc(whole_program, whole_program->Shaders,
@@ -426,6 +432,10 @@ main(int argc, char **argv)
for (unsigned i = 0; i < MESA_SHADER_STAGES; i++)
ralloc_free(whole_program->_LinkedShaders[i]);
+ delete whole_program->AttributeBindings;
+ delete whole_program->FragDataBindings;
+ delete whole_program->FragDataIndexBindings;
+
ralloc_free(whole_program);
_mesa_glsl_release_types();
_mesa_glsl_release_builtin_functions();
diff --git a/mesalib/src/glsl/opt_algebraic.cpp b/mesalib/src/glsl/opt_algebraic.cpp
index 0cdb8ecfc..430f5cb97 100644
--- a/mesalib/src/glsl/opt_algebraic.cpp
+++ b/mesalib/src/glsl/opt_algebraic.cpp
@@ -105,12 +105,6 @@ is_vec_negative_one(ir_constant *ir)
}
static inline bool
-is_vec_basis(ir_constant *ir)
-{
- return (ir == NULL) ? false : ir->is_basis();
-}
-
-static inline bool
is_valid_vec_const(ir_constant *ir)
{
if (ir == NULL)
@@ -537,21 +531,34 @@ ir_algebraic_visitor::handle_expression(ir_expression *ir)
if (is_vec_zero(op_const[0]) || is_vec_zero(op_const[1]))
return ir_constant::zero(mem_ctx, ir->type);
- if (is_vec_basis(op_const[0])) {
- unsigned component = 0;
- for (unsigned c = 0; c < op_const[0]->type->vector_elements; c++) {
- if (op_const[0]->value.f[c] == 1.0)
- component = c;
- }
- return new(mem_ctx) ir_swizzle(ir->operands[1], component, 0, 0, 0, 1);
- }
- if (is_vec_basis(op_const[1])) {
- unsigned component = 0;
- for (unsigned c = 0; c < op_const[1]->type->vector_elements; c++) {
- if (op_const[1]->value.f[c] == 1.0)
- component = c;
- }
- return new(mem_ctx) ir_swizzle(ir->operands[0], component, 0, 0, 0, 1);
+ for (int i = 0; i < 2; i++) {
+ if (!op_const[i])
+ continue;
+
+ unsigned components[4] = { 0 }, count = 0;
+
+ for (unsigned c = 0; c < op_const[i]->type->vector_elements; c++) {
+ if (op_const[i]->value.f[c] == 0.0)
+ continue;
+
+ components[count] = c;
+ count++;
+ }
+
+ /* No channels had zero values; bail. */
+ if (count >= op_const[i]->type->vector_elements)
+ break;
+
+ ir_expression_operation op = count == 1 ?
+ ir_binop_mul : ir_binop_dot;
+
+ /* Swizzle both operands to remove the channels that were zero. */
+ return new(mem_ctx)
+ ir_expression(op, glsl_type::float_type,
+ new(mem_ctx) ir_swizzle(ir->operands[0],
+ components, count),
+ new(mem_ctx) ir_swizzle(ir->operands[1],
+ components, count));
}
break;
diff --git a/mesalib/src/glsl/opt_cse.cpp b/mesalib/src/glsl/opt_cse.cpp
index 9c96835dd..b0b67f496 100644
--- a/mesalib/src/glsl/opt_cse.cpp
+++ b/mesalib/src/glsl/opt_cse.cpp
@@ -194,6 +194,8 @@ is_cse_candidate_visitor::visit(ir_dereference_variable *ir)
if (ir->var->data.read_only) {
return visit_continue;
} else {
+ if (debug)
+ printf("CSE: non-candidate: var %s is not read only\n", ir->var->name);
ok = false;
return visit_stop;
}
@@ -220,8 +222,11 @@ is_cse_candidate(ir_rvalue *ir)
/* Our temporary variable assignment generation isn't ready to handle
* anything bigger than a vector.
*/
- if (!ir->type->is_vector() && !ir->type->is_scalar())
+ if (!ir->type->is_vector() && !ir->type->is_scalar()) {
+ if (debug)
+ printf("CSE: non-candidate: not a vector/scalar\n");
return false;
+ }
/* Only handle expressions and textures currently. We may want to extend
* to variable-index array dereferences at some point.
@@ -231,6 +236,8 @@ is_cse_candidate(ir_rvalue *ir)
case ir_type_texture:
break;
default:
+ if (debug)
+ printf("CSE: non-candidate: not an expression/texture\n");
return false;
}
diff --git a/mesalib/src/glsl/s_expression.cpp b/mesalib/src/glsl/s_expression.cpp
index 1a28e1d52..2928a4db8 100644
--- a/mesalib/src/glsl/s_expression.cpp
+++ b/mesalib/src/glsl/s_expression.cpp
@@ -73,7 +73,7 @@ read_atom(void *ctx, const char *&src, char *&symbol_buffer)
} else {
// Check if the atom is a number.
char *float_end = NULL;
- float f = glsl_strtof(src, &float_end);
+ float f = _mesa_strtof(src, &float_end);
if (float_end != src) {
char *int_end = NULL;
int i = strtol(src, &int_end, 10);
diff --git a/mesalib/src/glsl/s_expression.h b/mesalib/src/glsl/s_expression.h
index 642af19b4..1d4753530 100644
--- a/mesalib/src/glsl/s_expression.h
+++ b/mesalib/src/glsl/s_expression.h
@@ -27,7 +27,7 @@
#define S_EXPRESSION_H
#include "main/core.h" /* for Elements */
-#include "strtod.h"
+#include "util/strtod.h"
#include "list.h"
/* Type-safe downcasting macros (also safe to pass NULL) */
diff --git a/mesalib/src/glsl/strtod.c b/mesalib/src/glsl/strtod.c
deleted file mode 100644
index 5d4346b5a..000000000
--- a/mesalib/src/glsl/strtod.c
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#include <stdlib.h>
-
-#ifdef _GNU_SOURCE
-#include <locale.h>
-#ifdef __APPLE__
-#include <xlocale.h>
-#endif
-#endif
-
-#include "strtod.h"
-
-
-
-/**
- * Wrapper around strtod which uses the "C" locale so the decimal
- * point is always '.'
- */
-double
-glsl_strtod(const char *s, char **end)
-{
-#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
- !defined(__HAIKU__) && !defined(__UCLIBC__)
- static locale_t loc = NULL;
- if (!loc) {
- loc = newlocale(LC_CTYPE_MASK, "C", NULL);
- }
- return strtod_l(s, end, loc);
-#else
- return strtod(s, end);
-#endif
-}
-
-
-/**
- * Wrapper around strtof which uses the "C" locale so the decimal
- * point is always '.'
- */
-float
-glsl_strtof(const char *s, char **end)
-{
-#if defined(_GNU_SOURCE) && !defined(__CYGWIN__) && !defined(__FreeBSD__) && \
- !defined(__HAIKU__) && !defined(__UCLIBC__)
- static locale_t loc = NULL;
- if (!loc) {
- loc = newlocale(LC_CTYPE_MASK, "C", NULL);
- }
- return strtof_l(s, end, loc);
-#elif _XOPEN_SOURCE >= 600 || _ISOC99_SOURCE
- return strtof(s, end);
-#else
- return (float) strtod(s, end);
-#endif
-}
diff --git a/mesalib/src/glsl/strtod.h b/mesalib/src/glsl/strtod.h
deleted file mode 100644
index ad847dbb0..000000000
--- a/mesalib/src/glsl/strtod.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2010 VMware, Inc.
- * All Rights Reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sub license, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
- * IN NO EVENT SHALL VMWARE AND/OR ITS SUPPLIERS BE LIABLE FOR
- * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
- * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- */
-
-
-#ifndef STRTOD_H
-#define STRTOD_H
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-extern double
-glsl_strtod(const char *s, char **end);
-
-extern float
-glsl_strtof(const char *s, char **end);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-
-#endif