aboutsummaryrefslogtreecommitdiff
path: root/mesalib/src/mesa/program
diff options
context:
space:
mode:
Diffstat (limited to 'mesalib/src/mesa/program')
-rw-r--r--mesalib/src/mesa/program/hash_table.c39
-rw-r--r--mesalib/src/mesa/program/hash_table.h99
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp16
-rw-r--r--mesalib/src/mesa/program/prog_execute.c14
-rw-r--r--mesalib/src/mesa/program/prog_parameter.c22
-rw-r--r--mesalib/src/mesa/program/prog_parameter.h6
-rw-r--r--mesalib/src/mesa/program/prog_statevars.c7
-rw-r--r--mesalib/src/mesa/program/program.c10
-rw-r--r--mesalib/src/mesa/program/program.h18
-rw-r--r--mesalib/src/mesa/program/sampler.cpp17
-rw-r--r--mesalib/src/mesa/program/string_to_uint_map.cpp42
11 files changed, 201 insertions, 89 deletions
diff --git a/mesalib/src/mesa/program/hash_table.c b/mesalib/src/mesa/program/hash_table.c
index 877a9e2ff..dc8563a33 100644
--- a/mesalib/src/mesa/program/hash_table.c
+++ b/mesalib/src/mesa/program/hash_table.c
@@ -108,8 +108,8 @@ hash_table_clear(struct hash_table *ht)
}
-void *
-hash_table_find(struct hash_table *ht, const void *key)
+static struct hash_node *
+get_node(struct hash_table *ht, const void *key)
{
const unsigned hash_value = (*ht->hash)(key);
const unsigned bucket = hash_value % ht->num_buckets;
@@ -119,13 +119,20 @@ hash_table_find(struct hash_table *ht, const void *key)
struct hash_node *hn = (struct hash_node *) node;
if ((*ht->compare)(hn->key, key) == 0) {
- return hn->data;
+ return hn;
}
}
return NULL;
}
+void *
+hash_table_find(struct hash_table *ht, const void *key)
+{
+ struct hash_node *hn = get_node(ht, key);
+
+ return (hn == NULL) ? NULL : hn->data;
+}
void
hash_table_insert(struct hash_table *ht, void *data, const void *key)
@@ -143,21 +150,39 @@ hash_table_insert(struct hash_table *ht, void *data, const void *key)
}
void
-hash_table_remove(struct hash_table *ht, const void *key)
+hash_table_replace(struct hash_table *ht, void *data, const void *key)
{
const unsigned hash_value = (*ht->hash)(key);
const unsigned bucket = hash_value % ht->num_buckets;
struct node *node;
+ struct hash_node *hn;
foreach(node, & ht->buckets[bucket]) {
- struct hash_node *hn = (struct hash_node *) node;
+ hn = (struct hash_node *) node;
if ((*ht->compare)(hn->key, key) == 0) {
- remove_from_list(node);
- free(node);
+ hn->data = data;
return;
}
}
+
+ hn = calloc(1, sizeof(*hn));
+
+ hn->data = data;
+ hn->key = key;
+
+ insert_at_head(& ht->buckets[bucket], & hn->link);
+}
+
+void
+hash_table_remove(struct hash_table *ht, const void *key)
+{
+ struct node *node = (struct node *) get_node(ht, key);
+ if (node != NULL) {
+ remove_from_list(node);
+ free(node);
+ return;
+ }
}
void
diff --git a/mesalib/src/mesa/program/hash_table.h b/mesalib/src/mesa/program/hash_table.h
index e715bb1cc..bfe221b24 100644
--- a/mesalib/src/mesa/program/hash_table.h
+++ b/mesalib/src/mesa/program/hash_table.h
@@ -31,7 +31,13 @@
#ifndef HASH_TABLE_H
#define HASH_TABLE_H
+#include <string.h>
+#include <stdint.h>
+#include <limits.h>
+#include <assert.h>
+
struct hash_table;
+struct string_to_uint_map;
typedef unsigned (*hash_func_t)(const void *key);
typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
@@ -88,11 +94,31 @@ extern void *hash_table_find(struct hash_table *ht, const void *key);
/**
* Add an element to a hash table
+ *
+ * \warning
+ * If \c key is already in the hash table, it will be added again. Future
+ * calls to \c hash_table_find and \c hash_table_remove will return or remove,
+ * repsectively, the most recently added instance of \c key.
+ *
+ * \sa hash_table_replace
*/
extern void hash_table_insert(struct hash_table *ht, void *data,
const void *key);
/**
+ * Add an element to a hash table with replacement
+ *
+ * \warning
+ * If \c key is already in the hash table, \c data will \b replace the most
+ * recently inserted \c data (see the warning in \c hash_table_insert) for
+ * that key.
+ *
+ * \sa hash_table_insert
+ */
+extern void hash_table_replace(struct hash_table *ht, void *data,
+ const void *key);
+
+/**
* Remove a specific element from a hash table.
*/
extern void hash_table_remove(struct hash_table *ht, const void *key);
@@ -151,7 +177,78 @@ hash_table_call_foreach(struct hash_table *ht,
void *closure),
void *closure);
+struct string_to_uint_map *
+string_to_uint_map_ctor();
+
+void
+string_to_uint_map_dtor(struct string_to_uint_map *);
+
+
#ifdef __cplusplus
}
-#endif
+
+/**
+ * Map from a string (name) to an unsigned integer value
+ *
+ * \note
+ * Because of the way this class interacts with the \c hash_table
+ * implementation, values of \c UINT_MAX cannot be stored in the map.
+ */
+struct string_to_uint_map {
+public:
+ string_to_uint_map()
+ {
+ this->ht = hash_table_ctor(0, hash_table_string_hash,
+ hash_table_string_compare);
+ }
+
+ ~string_to_uint_map()
+ {
+ hash_table_dtor(this->ht);
+ }
+
+ /**
+ * Get the value associated with a particular key
+ *
+ * \return
+ * If \c key is found in the map, \c true is returned. Otherwise \c false
+ * is returned.
+ *
+ * \note
+ * If \c key is not found in the table, \c value is not modified.
+ */
+ bool get(unsigned &value, const char *key)
+ {
+ const intptr_t v =
+ (intptr_t) hash_table_find(this->ht, (const void *) key);
+
+ if (v == 0)
+ return false;
+
+ value = (unsigned)(v - 1);
+ return true;
+ }
+
+ void put(unsigned value, const char *key)
+ {
+ /* The low-level hash table structure returns NULL if key is not in the
+ * hash table. However, users of this map might want to store zero as a
+ * valid value in the table. Bias the value by +1 so that a
+ * user-specified zero is stored as 1. This enables ::get to tell the
+ * difference between a user-specified zero (returned as 1 by
+ * hash_table_find) and the key not in the table (returned as 0 by
+ * hash_table_find).
+ *
+ * The net effect is that we can't store UINT_MAX in the table. This is
+ * because UINT_MAX+1 = 0.
+ */
+ assert(value != UINT_MAX);
+ hash_table_replace(ht, (void *) (intptr_t) (value + 1), key);
+ }
+
+private:
+ struct hash_table *ht;
+};
+
+#endif /* __cplusplus */
#endif /* HASH_TABLE_H */
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index c5b71b3f0..2e1b8fba3 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -1261,8 +1261,11 @@ ir_to_mesa_visitor::visit(ir_expression *ir)
break;
case ir_binop_div:
assert(!"not reached: should be handled by ir_div_to_mul_rcp");
+ break;
case ir_binop_mod:
- assert(!"ir_binop_mod should have been converted to b * fract(a/b)");
+ /* Floating point should be lowered by MOD_TO_FRACT in the compiler. */
+ assert(ir->type->is_integer());
+ emit(ir, OPCODE_MUL, result_dst, op[0], op[1]);
break;
case ir_binop_less:
@@ -1556,14 +1559,6 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
entry = new(mem_ctx) variable_storage(var,
PROGRAM_INPUT,
var->location);
- if (this->prog->Target == GL_VERTEX_PROGRAM_ARB &&
- var->location >= VERT_ATTRIB_GENERIC0) {
- _mesa_add_attribute(this->prog->Attributes,
- var->name,
- _mesa_sizeof_glsl_type(var->type->gl_type),
- var->type->gl_type,
- var->location - VERT_ATTRIB_GENERIC0);
- }
break;
case ir_var_out:
assert(var->location != -1);
@@ -3045,8 +3040,6 @@ get_mesa_program(struct gl_context *ctx,
if (!prog)
return NULL;
prog->Parameters = _mesa_new_parameter_list();
- prog->Varying = _mesa_new_parameter_list();
- prog->Attributes = _mesa_new_parameter_list();
v.ctx = ctx;
v.prog = prog;
v.shader_program = shader_program;
@@ -3434,7 +3427,6 @@ _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog)
}
}
- prog->Varying = _mesa_new_parameter_list();
_mesa_reference_vertprog(ctx, &prog->VertexProgram, NULL);
_mesa_reference_fragprog(ctx, &prog->FragmentProgram, NULL);
_mesa_reference_geomprog(ctx, &prog->GeometryProgram, NULL);
diff --git a/mesalib/src/mesa/program/prog_execute.c b/mesalib/src/mesa/program/prog_execute.c
index 77f842a16..848c2fec1 100644
--- a/mesalib/src/mesa/program/prog_execute.c
+++ b/mesalib/src/mesa/program/prog_execute.c
@@ -84,7 +84,7 @@ static const GLfloat ZeroVec[4] = { 0.0F, 0.0F, 0.0F, 0.0F };
* Return TRUE for +0 and other positive values, FALSE otherwise.
* Used for RCC opcode.
*/
-static INLINE GLboolean
+static inline GLboolean
positive(float x)
{
fi_type fi;
@@ -100,7 +100,7 @@ positive(float x)
* Return a pointer to the 4-element float vector specified by the given
* source register.
*/
-static INLINE const GLfloat *
+static inline const GLfloat *
get_src_register_pointer(const struct prog_src_register *source,
const struct gl_program_machine *machine)
{
@@ -176,7 +176,7 @@ get_src_register_pointer(const struct prog_src_register *source,
* Return a pointer to the 4-element float vector specified by the given
* destination register.
*/
-static INLINE GLfloat *
+static inline GLfloat *
get_dst_register_pointer(const struct prog_dst_register *dest,
struct gl_program_machine *machine)
{
@@ -383,7 +383,7 @@ fetch_vector1ui(const struct prog_src_register *source,
/**
* Fetch texel from texture. Use partial derivatives when possible.
*/
-static INLINE void
+static inline void
fetch_texel(struct gl_context *ctx,
const struct gl_program_machine *machine,
const struct prog_instruction *inst,
@@ -413,7 +413,7 @@ fetch_texel(struct gl_context *ctx,
/**
* Test value against zero and return GT, LT, EQ or UN if NaN.
*/
-static INLINE GLuint
+static inline GLuint
generate_cc(float value)
{
if (value != value)
@@ -430,7 +430,7 @@ generate_cc(float value)
* Test if the ccMaskRule is satisfied by the given condition code.
* Used to mask destination writes according to the current condition code.
*/
-static INLINE GLboolean
+static inline GLboolean
test_cc(GLuint condCode, GLuint ccMaskRule)
{
switch (ccMaskRule) {
@@ -451,7 +451,7 @@ test_cc(GLuint condCode, GLuint ccMaskRule)
* Evaluate the 4 condition codes against a predicate and return GL_TRUE
* or GL_FALSE to indicate result.
*/
-static INLINE GLboolean
+static inline GLboolean
eval_condition(const struct gl_program_machine *machine,
const struct prog_instruction *inst)
{
diff --git a/mesalib/src/mesa/program/prog_parameter.c b/mesalib/src/mesa/program/prog_parameter.c
index 49b3ffbdd..2018fa520 100644
--- a/mesalib/src/mesa/program/prog_parameter.c
+++ b/mesalib/src/mesa/program/prog_parameter.c
@@ -640,28 +640,6 @@ _mesa_combine_parameter_lists(const struct gl_program_parameter_list *listA,
}
-
-/**
- * Find longest name of all uniform parameters in list.
- */
-GLuint
-_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
- gl_register_file type)
-{
- GLuint i, maxLen = 0;
- if (!list)
- return 0;
- for (i = 0; i < list->NumParameters; i++) {
- if (list->Parameters[i].Type == type) {
- GLuint len = strlen(list->Parameters[i].Name);
- if (len > maxLen)
- maxLen = len;
- }
- }
- return maxLen;
-}
-
-
/**
* Count the number of parameters in the last that match the given type.
*/
diff --git a/mesalib/src/mesa/program/prog_parameter.h b/mesalib/src/mesa/program/prog_parameter.h
index 4c2773a62..a6793d0d8 100644
--- a/mesalib/src/mesa/program/prog_parameter.h
+++ b/mesalib/src/mesa/program/prog_parameter.h
@@ -114,7 +114,7 @@ extern struct gl_program_parameter_list *
_mesa_combine_parameter_lists(const struct gl_program_parameter_list *a,
const struct gl_program_parameter_list *b);
-static INLINE GLuint
+static inline GLuint
_mesa_num_parameters(const struct gl_program_parameter_list *list)
{
return list ? list->NumParameters : 0;
@@ -174,10 +174,6 @@ _mesa_lookup_parameter_constant(const struct gl_program_parameter_list *list,
GLint *posOut, GLuint *swizzleOut);
extern GLuint
-_mesa_longest_parameter_name(const struct gl_program_parameter_list *list,
- gl_register_file type);
-
-extern GLuint
_mesa_num_parameters_of_type(const struct gl_program_parameter_list *list,
gl_register_file type);
diff --git a/mesalib/src/mesa/program/prog_statevars.c b/mesalib/src/mesa/program/prog_statevars.c
index 6aa2409e8..f34a6d360 100644
--- a/mesalib/src/mesa/program/prog_statevars.c
+++ b/mesalib/src/mesa/program/prog_statevars.c
@@ -664,10 +664,13 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH])
{
switch (state[0]) {
case STATE_MATERIAL:
+ case STATE_LIGHTPROD:
+ case STATE_LIGHTMODEL_SCENECOLOR:
+ /* these can be effected by glColor when colormaterial mode is used */
+ return _NEW_LIGHT | _NEW_CURRENT_ATTRIB;
+
case STATE_LIGHT:
case STATE_LIGHTMODEL_AMBIENT:
- case STATE_LIGHTMODEL_SCENECOLOR:
- case STATE_LIGHTPROD:
return _NEW_LIGHT;
case STATE_TEXGEN:
diff --git a/mesalib/src/mesa/program/program.c b/mesalib/src/mesa/program/program.c
index ecff2344a..4d6c60b9d 100644
--- a/mesalib/src/mesa/program/program.c
+++ b/mesalib/src/mesa/program/program.c
@@ -394,12 +394,6 @@ _mesa_delete_program(struct gl_context *ctx, struct gl_program *prog)
if (prog->Parameters) {
_mesa_free_parameter_list(prog->Parameters);
}
- if (prog->Varying) {
- _mesa_free_parameter_list(prog->Varying);
- }
- if (prog->Attributes) {
- _mesa_free_parameter_list(prog->Attributes);
- }
free(prog);
}
@@ -522,10 +516,6 @@ _mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog)
if (prog->Parameters)
clone->Parameters = _mesa_clone_parameter_list(prog->Parameters);
memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
- if (prog->Varying)
- clone->Varying = _mesa_clone_parameter_list(prog->Varying);
- if (prog->Attributes)
- clone->Attributes = _mesa_clone_parameter_list(prog->Attributes);
memcpy(clone->LocalParams, prog->LocalParams, sizeof(clone->LocalParams));
clone->IndirectRegisterFiles = prog->IndirectRegisterFiles;
clone->NumInstructions = prog->NumInstructions;
diff --git a/mesalib/src/mesa/program/program.h b/mesalib/src/mesa/program/program.h
index 0f32a6af7..9cd1780b8 100644
--- a/mesalib/src/mesa/program/program.h
+++ b/mesalib/src/mesa/program/program.h
@@ -93,7 +93,7 @@ _mesa_reference_program_(struct gl_context *ctx,
struct gl_program **ptr,
struct gl_program *prog);
-static INLINE void
+static inline void
_mesa_reference_program(struct gl_context *ctx,
struct gl_program **ptr,
struct gl_program *prog)
@@ -102,7 +102,7 @@ _mesa_reference_program(struct gl_context *ctx,
_mesa_reference_program_(ctx, ptr, prog);
}
-static INLINE void
+static inline void
_mesa_reference_vertprog(struct gl_context *ctx,
struct gl_vertex_program **ptr,
struct gl_vertex_program *prog)
@@ -111,7 +111,7 @@ _mesa_reference_vertprog(struct gl_context *ctx,
(struct gl_program *) prog);
}
-static INLINE void
+static inline void
_mesa_reference_fragprog(struct gl_context *ctx,
struct gl_fragment_program **ptr,
struct gl_fragment_program *prog)
@@ -120,7 +120,7 @@ _mesa_reference_fragprog(struct gl_context *ctx,
(struct gl_program *) prog);
}
-static INLINE void
+static inline void
_mesa_reference_geomprog(struct gl_context *ctx,
struct gl_geometry_program **ptr,
struct gl_geometry_program *prog)
@@ -132,21 +132,21 @@ _mesa_reference_geomprog(struct gl_context *ctx,
extern struct gl_program *
_mesa_clone_program(struct gl_context *ctx, const struct gl_program *prog);
-static INLINE struct gl_vertex_program *
+static inline struct gl_vertex_program *
_mesa_clone_vertex_program(struct gl_context *ctx,
const struct gl_vertex_program *prog)
{
return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base);
}
-static INLINE struct gl_geometry_program *
+static inline struct gl_geometry_program *
_mesa_clone_geometry_program(struct gl_context *ctx,
const struct gl_geometry_program *prog)
{
return (struct gl_geometry_program *) _mesa_clone_program(ctx, &prog->Base);
}
-static INLINE struct gl_fragment_program *
+static inline struct gl_fragment_program *
_mesa_clone_fragment_program(struct gl_context *ctx,
const struct gl_fragment_program *prog)
{
@@ -185,7 +185,7 @@ _mesa_postprocess_program(struct gl_context *ctx, struct gl_program *prog);
/* keep these in the same order as TGSI_PROCESSOR_* */
-static INLINE GLuint
+static inline GLuint
_mesa_program_target_to_index(GLenum v)
{
switch(v)
@@ -202,7 +202,7 @@ _mesa_program_target_to_index(GLenum v)
}
}
-static INLINE GLenum
+static inline GLenum
_mesa_program_index_to_target(GLuint i)
{
GLenum enums[MESA_SHADER_TYPES] = {
diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp
index e8d34c670..3b459d59c 100644
--- a/mesalib/src/mesa/program/sampler.cpp
+++ b/mesalib/src/mesa/program/sampler.cpp
@@ -26,6 +26,7 @@
#include "ir.h"
#include "glsl_types.h"
#include "ir_visitor.h"
+#include "../glsl/program.h"
extern "C" {
#include "main/compiler.h"
@@ -33,18 +34,6 @@ extern "C" {
#include "program/prog_parameter.h"
}
-static void fail_link(struct gl_shader_program *prog, const char *fmt, ...) PRINTFLIKE(2, 3);
-
-static void fail_link(struct gl_shader_program *prog, const char *fmt, ...)
-{
- va_list args;
- va_start(args, fmt);
- ralloc_vasprintf_append(&prog->InfoLog, fmt, args);
- va_end(args);
-
- prog->LinkStatus = GL_FALSE;
-}
-
class get_sampler_name : public ir_hierarchical_visitor
{
public:
@@ -125,8 +114,8 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler,
getname.name);
if (index < 0) {
- fail_link(shader_program,
- "failed to find sampler named %s.\n", getname.name);
+ linker_error(shader_program,
+ "failed to find sampler named %s.\n", getname.name);
return 0;
}
diff --git a/mesalib/src/mesa/program/string_to_uint_map.cpp b/mesalib/src/mesa/program/string_to_uint_map.cpp
new file mode 100644
index 000000000..cfa73abe0
--- /dev/null
+++ b/mesalib/src/mesa/program/string_to_uint_map.cpp
@@ -0,0 +1,42 @@
+/*
+ * Copyright © 2011 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 string_to_uint_map.cpp
+ * \brief Dumb wrapprs so that C code can create and destroy maps.
+ *
+ * \author Ian Romanick <ian.d.romanick@intel.com>
+ */
+#include "hash_table.h"
+
+extern "C" struct string_to_uint_map *
+string_to_uint_map_ctor()
+{
+ return new string_to_uint_map;
+}
+
+extern "C" void
+string_to_uint_map_dtor(struct string_to_uint_map *map)
+{
+ delete map;
+}