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.h17
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.cpp115
-rw-r--r--mesalib/src/mesa/program/ir_to_mesa.h20
-rw-r--r--mesalib/src/mesa/program/prog_parameter.h9
-rw-r--r--mesalib/src/mesa/program/prog_statevars.h11
-rw-r--r--mesalib/src/mesa/program/prog_uniform.c103
-rw-r--r--mesalib/src/mesa/program/prog_uniform.h85
-rw-r--r--mesalib/src/mesa/program/sampler.cpp12
8 files changed, 149 insertions, 223 deletions
diff --git a/mesalib/src/mesa/program/hash_table.h b/mesalib/src/mesa/program/hash_table.h
index 9ec4e40e8..e1c234ea4 100644
--- a/mesalib/src/mesa/program/hash_table.h
+++ b/mesalib/src/mesa/program/hash_table.h
@@ -38,16 +38,17 @@
#include <assert.h>
#include <unistd.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);
-
#ifdef __cplusplus
extern "C" {
#endif
+struct hash_table;
+
+typedef unsigned (*hash_func_t)(const void *key);
+typedef int (*hash_compare_func_t)(const void *key1, const void *key2);
+
/**
* Hash table constructor
*
@@ -215,6 +216,14 @@ public:
}
/**
+ * Remove all mappings from this map.
+ */
+ void clear()
+ {
+ hash_table_clear(this->ht);
+ }
+
+ /**
* Get the value associated with a particular key
*
* \return
diff --git a/mesalib/src/mesa/program/ir_to_mesa.cpp b/mesalib/src/mesa/program/ir_to_mesa.cpp
index 3c2eb5707..1b8b48e53 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.cpp
+++ b/mesalib/src/mesa/program/ir_to_mesa.cpp
@@ -35,6 +35,7 @@
#include "ir_visitor.h"
#include "ir_print_visitor.h"
#include "ir_expression_flattening.h"
+#include "ir_uniform.h"
#include "glsl_types.h"
#include "glsl_parser_extras.h"
#include "../glsl/program.h"
@@ -53,7 +54,6 @@ extern "C" {
#include "program/prog_optimize.h"
#include "program/prog_print.h"
#include "program/program.h"
-#include "program/prog_uniform.h"
#include "program/prog_parameter.h"
#include "program/sampler.h"
}
@@ -2597,17 +2597,17 @@ class add_uniform_to_shader : public uniform_field_visitor {
public:
add_uniform_to_shader(struct gl_shader_program *shader_program,
struct gl_program_parameter_list *params)
- : shader_program(shader_program), params(params), next_sampler(0)
+ : shader_program(shader_program), params(params)
{
/* empty */
}
- int process(ir_variable *var)
+ void process(ir_variable *var)
{
this->idx = -1;
this->uniform_field_visitor::process(var);
- return this->idx;
+ var->location = this->idx;
}
private:
@@ -2615,7 +2615,6 @@ private:
struct gl_shader_program *shader_program;
struct gl_program_parameter_list *params;
- int next_sampler;
int idx;
};
@@ -2648,8 +2647,20 @@ add_uniform_to_shader::visit_field(const glsl_type *type, const char *name)
* store in ParameterValues[].
*/
if (file == PROGRAM_SAMPLER) {
+ unsigned location;
+ const bool found =
+ this->shader_program->UniformHash->get(location,
+ params->Parameters[index].Name);
+ assert(found);
+
+ if (!found)
+ return;
+
+ struct gl_uniform_storage *storage =
+ &this->shader_program->UniformStorage[location];
+
for (unsigned int j = 0; j < size / 4; j++)
- params->ParameterValues[index + j][0].f = this->next_sampler++;
+ params->ParameterValues[index + j][0].f = storage->sampler + j;
}
}
@@ -2684,16 +2695,77 @@ _mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
|| (strncmp(var->name, "gl_", 3) == 0))
continue;
- int loc = add.process(var);
+ add.process(var);
+ }
+}
- /* The location chosen in the Parameters list here (returned from
- * _mesa_add_parameter) has to match what the linker chose.
- */
- if (var->location != loc) {
- linker_error(shader_program,
- "Allocation of uniform `%s' to target failed "
- "(%d vs %d)\n",
- var->name, loc, var->location);
+void
+_mesa_associate_uniform_storage(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params)
+{
+ /* After adding each uniform to the parameter list, connect the storage for
+ * the parameter with the tracking structure used by the API for the
+ * uniform.
+ */
+ unsigned last_location = unsigned(~0);
+ for (unsigned i = 0; i < params->NumParameters; i++) {
+ if (params->Parameters[i].Type != PROGRAM_UNIFORM)
+ continue;
+
+ unsigned location;
+ const bool found =
+ shader_program->UniformHash->get(location, params->Parameters[i].Name);
+ assert(found);
+
+ if (!found)
+ continue;
+
+ if (location != last_location) {
+ struct gl_uniform_storage *storage =
+ &shader_program->UniformStorage[location];
+ enum gl_uniform_driver_format format = uniform_native;
+
+ unsigned columns = 0;
+ switch (storage->type->base_type) {
+ case GLSL_TYPE_UINT:
+ assert(ctx->Const.NativeIntegers);
+ format = uniform_native;
+ columns = 1;
+ break;
+ case GLSL_TYPE_INT:
+ format =
+ (ctx->Const.NativeIntegers) ? uniform_native : uniform_int_float;
+ columns = 1;
+ break;
+ case GLSL_TYPE_FLOAT:
+ format = uniform_native;
+ columns = storage->type->matrix_columns;
+ break;
+ case GLSL_TYPE_BOOL:
+ if (ctx->Const.NativeIntegers) {
+ format = (ctx->Const.UniformBooleanTrue == 1)
+ ? uniform_bool_int_0_1 : uniform_bool_int_0_not0;
+ } else {
+ format = uniform_bool_float;
+ }
+ columns = 1;
+ break;
+ case GLSL_TYPE_SAMPLER:
+ format = uniform_native;
+ columns = 1;
+ break;
+ default:
+ assert(!"Should not get here.");
+ break;
+ }
+
+ _mesa_uniform_attach_driver_storage(storage,
+ 4 * sizeof(float) * columns,
+ 4 * sizeof(float),
+ format,
+ &params->ParameterValues[i]);
+ last_location = location;
}
}
}
@@ -2759,12 +2831,12 @@ set_uniform_initializer(struct gl_context *ctx, void *mem_ctx,
element_type->matrix_columns,
element_type->vector_elements,
loc, 1, GL_FALSE, (GLfloat *)values);
- loc += element_type->matrix_columns;
} else {
_mesa_uniform(ctx, shader_program, loc, element_type->matrix_columns,
values, element_type->gl_type);
- loc += type_size(element_type);
}
+
+ loc++;
}
}
@@ -3211,6 +3283,15 @@ get_mesa_program(struct gl_context *ctx,
_mesa_optimize_program(ctx, prog);
}
+ /* This has to be done last. Any operation that can cause
+ * prog->ParameterValues to get reallocated (e.g., anything that adds a
+ * program constant) has to happen before creating this linkage.
+ */
+ _mesa_associate_uniform_storage(ctx, shader_program, prog->Parameters);
+ if (!shader_program->LinkStatus) {
+ goto fail_exit;
+ }
+
return prog;
fail_exit:
diff --git a/mesalib/src/mesa/program/ir_to_mesa.h b/mesalib/src/mesa/program/ir_to_mesa.h
index d046b0fcf..aa053d9c8 100644
--- a/mesalib/src/mesa/program/ir_to_mesa.h
+++ b/mesalib/src/mesa/program/ir_to_mesa.h
@@ -21,28 +21,34 @@
* DEALINGS IN THE SOFTWARE.
*/
-#include "main/glheader.h"
+#pragma once
-struct gl_context;
-struct gl_shader;
-struct gl_shader_program;
+#include "main/glheader.h"
#ifdef __cplusplus
extern "C" {
#endif
+struct gl_context;
+struct gl_shader;
+struct gl_shader_program;
+
void _mesa_glsl_compile_shader(struct gl_context *ctx, struct gl_shader *sh);
void _mesa_glsl_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
GLboolean _mesa_ir_compile_shader(struct gl_context *ctx, struct gl_shader *shader);
GLboolean _mesa_ir_link_shader(struct gl_context *ctx, struct gl_shader_program *prog);
-#ifdef __cplusplus
-}
-
void
_mesa_generate_parameters_list_for_uniforms(struct gl_shader_program
*shader_program,
struct gl_shader *sh,
struct gl_program_parameter_list
*params);
+void
+_mesa_associate_uniform_storage(struct gl_context *ctx,
+ struct gl_shader_program *shader_program,
+ struct gl_program_parameter_list *params);
+
+#ifdef __cplusplus
+}
#endif
diff --git a/mesalib/src/mesa/program/prog_parameter.h b/mesalib/src/mesa/program/prog_parameter.h
index a6793d0d8..3c6dc8cf9 100644
--- a/mesalib/src/mesa/program/prog_parameter.h
+++ b/mesalib/src/mesa/program/prog_parameter.h
@@ -35,6 +35,11 @@
#include "prog_statevars.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
/**
* Program parameter flags
*/
@@ -178,4 +183,8 @@ _mesa_num_parameters_of_type(const struct gl_program_parameter_list *list,
gl_register_file type);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* PROG_PARAMETER_H */
diff --git a/mesalib/src/mesa/program/prog_statevars.h b/mesalib/src/mesa/program/prog_statevars.h
index 04af3f4cf..8b731e12b 100644
--- a/mesalib/src/mesa/program/prog_statevars.h
+++ b/mesalib/src/mesa/program/prog_statevars.h
@@ -25,8 +25,15 @@
#ifndef PROG_STATEVARS_H
#define PROG_STATEVARS_H
+
#include "main/glheader.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
struct gl_context;
struct gl_program_parameter_list;
@@ -145,4 +152,8 @@ extern void
_mesa_load_tracked_matrices(struct gl_context *ctx);
+#ifdef __cplusplus
+}
+#endif
+
#endif /* PROG_STATEVARS_H */
diff --git a/mesalib/src/mesa/program/prog_uniform.c b/mesalib/src/mesa/program/prog_uniform.c
deleted file mode 100644
index d0b25e5c5..000000000
--- a/mesalib/src/mesa/program/prog_uniform.c
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 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 prog_uniform.c
- * Shader uniform functions.
- * \author Brian Paul
- */
-
-#include "main/imports.h"
-#include "main/mtypes.h"
-#include "prog_uniform.h"
-
-
-struct gl_uniform_list *
-_mesa_new_uniform_list(void)
-{
- return CALLOC_STRUCT(gl_uniform_list);
-}
-
-
-void
-_mesa_free_uniform_list(struct gl_uniform_list *list)
-{
- GLuint i;
-
- if (!list)
- return;
-
- for (i = 0; i < list->NumUniforms; i++) {
- free((void *) list->Uniforms[i].Name);
- }
- free(list->Uniforms);
- free(list);
-}
-
-
-/**
- * Return the location/index of the named uniform in the uniform list,
- * or -1 if not found.
- */
-GLint
-_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name)
-{
- GLuint i;
- for (i = 0; list && i < list->NumUniforms; i++) {
- if (!strcmp(list->Uniforms[i].Name, name)) {
- return i;
- }
- }
- return -1;
-}
-
-
-GLint
-_mesa_longest_uniform_name(const struct gl_uniform_list *list)
-{
- GLint max = 0;
- GLuint i;
- for (i = 0; list && i < list->NumUniforms; i++) {
- GLint len = (GLint) strlen(list->Uniforms[i].Name);
- if (len > max)
- max = len;
- }
- return max;
-}
-
-
-void
-_mesa_print_uniforms(const struct gl_uniform_list *list)
-{
- GLuint i;
- printf("Uniform list %p:\n", (void *) list);
- for (i = 0; i < list->NumUniforms; i++) {
- printf("%d: %s %d %d %d\n",
- i,
- list->Uniforms[i].Name,
- list->Uniforms[i].VertPos,
- list->Uniforms[i].FragPos,
- list->Uniforms[i].GeomPos);
- }
-}
diff --git a/mesalib/src/mesa/program/prog_uniform.h b/mesalib/src/mesa/program/prog_uniform.h
deleted file mode 100644
index 83cd30780..000000000
--- a/mesalib/src/mesa/program/prog_uniform.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Mesa 3-D graphics library
- * Version: 7.1
- *
- * Copyright (C) 1999-2008 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 prog_uniform.c
- * Shader uniform functions.
- * \author Brian Paul
- */
-
-#ifndef PROG_UNIFORM_H
-#define PROG_UNIFORM_H
-
-#include "main/glheader.h"
-
-
-/**
- * Shader program uniform variable.
- * The glGetUniformLocation() and glUniform() commands will use this
- * information.
- * Note that a uniform such as "binormal" might be used in both the
- * vertex shader and the fragment shader. When glUniform() is called to
- * set the uniform's value, it must be updated in both the vertex and
- * fragment shaders. The uniform may be in different locations in the
- * two shaders so we keep track of that here.
- */
-struct gl_uniform
-{
- const char *Name; /**< Null-terminated string */
- GLint VertPos;
- GLint FragPos;
- GLint GeomPos;
- GLboolean Initialized; /**< For debug. Has this uniform been set? */
- const struct glsl_type *Type;
-};
-
-
-/**
- * List of gl_uniforms
- */
-struct gl_uniform_list
-{
- GLuint Size; /**< allocated size of Uniforms array */
- GLuint NumUniforms; /**< number of uniforms in the array */
- struct gl_uniform *Uniforms; /**< Array [Size] */
-};
-
-
-extern struct gl_uniform_list *
-_mesa_new_uniform_list(void);
-
-extern void
-_mesa_free_uniform_list(struct gl_uniform_list *list);
-
-extern GLint
-_mesa_lookup_uniform(const struct gl_uniform_list *list, const char *name);
-
-extern GLint
-_mesa_longest_uniform_name(const struct gl_uniform_list *list);
-
-extern void
-_mesa_print_uniforms(const struct gl_uniform_list *list);
-
-
-#endif /* PROG_UNIFORM_H */
diff --git a/mesalib/src/mesa/program/sampler.cpp b/mesalib/src/mesa/program/sampler.cpp
index 3b459d59c..e3641aaa9 100644
--- a/mesalib/src/mesa/program/sampler.cpp
+++ b/mesalib/src/mesa/program/sampler.cpp
@@ -27,6 +27,8 @@
#include "glsl_types.h"
#include "ir_visitor.h"
#include "../glsl/program.h"
+#include "program/hash_table.h"
+#include "ir_uniform.h"
extern "C" {
#include "main/compiler.h"
@@ -110,17 +112,13 @@ _mesa_get_sampler_uniform_value(class ir_dereference *sampler,
sampler->accept(&getname);
- GLint index = _mesa_lookup_parameter_index(prog->Parameters, -1,
- getname.name);
-
- if (index < 0) {
+ unsigned location;
+ if (!shader_program->UniformHash->get(location, getname.name)) {
linker_error(shader_program,
"failed to find sampler named %s.\n", getname.name);
return 0;
}
- index += getname.offset;
-
- return prog->Parameters->ParameterValues[index][0].f;
+ return shader_program->UniformStorage[location].sampler + getname.offset;
}
}