summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Anholt <eric@anholt.net>2010-08-05 17:00:12 -0700
committerEric Anholt <eric@anholt.net>2010-08-06 00:51:42 -0700
commitc234d0b25f622a7bdd3c40bc72fdbd59d8494c7c (patch)
tree4fd283b320db75af56053dd5d8bad3894fa7f306
parent199c441239762eec86b3cb4b558aef486907a8b6 (diff)
ir_to_mesa: Add support for sampler arrays.
Support for samplers in general is still incomplete -- anything in a uniform struct will still be broken. But that doesn't appear to be any different from master. Fixes: glsl-fs-uniform-sampler-array.shader_test
-rw-r--r--src/mesa/program/ir_to_mesa.cpp47
-rw-r--r--src/mesa/program/prog_parameter.c7
-rw-r--r--src/mesa/program/prog_parameter.h2
3 files changed, 43 insertions, 13 deletions
diff --git a/src/mesa/program/ir_to_mesa.cpp b/src/mesa/program/ir_to_mesa.cpp
index 66b1a2f9d9..d8a13220ae 100644
--- a/src/mesa/program/ir_to_mesa.cpp
+++ b/src/mesa/program/ir_to_mesa.cpp
@@ -1398,10 +1398,19 @@ ir_to_mesa_visitor::visit(ir_dereference_variable *ir)
break;
/* FINISHME: Fix up uniform name for arrays and things */
- if (ir->var->type->base_type == GLSL_TYPE_SAMPLER) {
+ if (ir->var->type->base_type == GLSL_TYPE_SAMPLER ||
+ (ir->var->type->base_type == GLSL_TYPE_ARRAY &&
+ ir->var->type->fields.array->base_type == GLSL_TYPE_SAMPLER)) {
+ int array_length;
+
+ if (ir->var->type->base_type == GLSL_TYPE_ARRAY)
+ array_length = ir->var->type->length;
+ else
+ array_length = 1;
int sampler = _mesa_add_sampler(this->prog->Parameters,
ir->var->name,
- ir->var->type->gl_type);
+ ir->var->type->gl_type,
+ array_length);
set_sampler_location(ir->var, sampler);
entry = new(mem_ctx) variable_storage(ir->var, PROGRAM_SAMPLER,
@@ -2035,22 +2044,42 @@ ir_to_mesa_visitor::visit(ir_texture *ir)
if (ir->shadow_comparitor)
inst->tex_shadow = GL_TRUE;
- ir_dereference_variable *sampler = ir->sampler->as_dereference_variable();
- assert(sampler); /* FINISHME: sampler arrays */
+ ir_variable *sampler = ir->sampler->variable_referenced();
+
/* generate the mapping, remove when we generate storage at
* declaration time
*/
- sampler->accept(this);
+ ir->sampler->accept(this);
+
+ inst->sampler = get_sampler_location(sampler);
+
+ ir_dereference_array *sampler_array = ir->sampler->as_dereference_array();
+ if (sampler_array) {
+ ir_constant *array_index =
+ sampler_array->array_index->constant_expression_value();
+
+ /* GLSL 1.10 and 1.20 allowed variable sampler array indices,
+ * while GLSL 1.30 requires that the array indices be constant
+ * integer expressions. We don't expect any driver to actually
+ * work with a really variable array index, and in 1.20 all that
+ * would work would be an unrolled loop counter, so assert that
+ * we ended up with a constant at least..
+ */
+ assert(array_index);
+ inst->sampler += array_index->value.i[0];
+ }
- inst->sampler = get_sampler_location(sampler->var);
+ const glsl_type *sampler_type = sampler->type;
+ while (sampler_type->base_type == GLSL_TYPE_ARRAY)
+ sampler_type = sampler_type->fields.array;
- switch (sampler->type->sampler_dimensionality) {
+ switch (sampler_type->sampler_dimensionality) {
case GLSL_SAMPLER_DIM_1D:
- inst->tex_target = (sampler->type->sampler_array)
+ inst->tex_target = (sampler_type->sampler_array)
? TEXTURE_1D_ARRAY_INDEX : TEXTURE_1D_INDEX;
break;
case GLSL_SAMPLER_DIM_2D:
- inst->tex_target = (sampler->type->sampler_array)
+ inst->tex_target = (sampler_type->sampler_array)
? TEXTURE_2D_ARRAY_INDEX : TEXTURE_2D_INDEX;
break;
case GLSL_SAMPLER_DIM_3D:
diff --git a/src/mesa/program/prog_parameter.c b/src/mesa/program/prog_parameter.c
index ddbfe95c15..fa5deaf127 100644
--- a/src/mesa/program/prog_parameter.c
+++ b/src/mesa/program/prog_parameter.c
@@ -344,18 +344,19 @@ _mesa_use_uniform(struct gl_program_parameter_list *paramList,
*/
GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
- const char *name, GLenum datatype)
+ const char *name, GLenum datatype, int array_length)
{
GLint i = _mesa_lookup_parameter_index(paramList, -1, name);
if (i >= 0 && paramList->Parameters[i].Type == PROGRAM_SAMPLER) {
- ASSERT(paramList->Parameters[i].Size == 1);
+ ASSERT(paramList->Parameters[i].Size == 4 * array_length);
ASSERT(paramList->Parameters[i].DataType == datatype);
/* already in list */
return (GLint) paramList->ParameterValues[i][0];
}
else {
GLuint i;
- const GLint size = 1; /* a sampler is basically a texture unit number */
+ /* One integer texture unit number goes in each parameter location. */
+ const GLint size = 4 * array_length;
GLfloat value[4];
GLint numSamplers = 0;
for (i = 0; i < paramList->NumParameters; i++) {
diff --git a/src/mesa/program/prog_parameter.h b/src/mesa/program/prog_parameter.h
index cc3378ae20..1860f31287 100644
--- a/src/mesa/program/prog_parameter.h
+++ b/src/mesa/program/prog_parameter.h
@@ -142,7 +142,7 @@ _mesa_use_uniform(struct gl_program_parameter_list *paramList,
extern GLint
_mesa_add_sampler(struct gl_program_parameter_list *paramList,
- const char *name, GLenum datatype);
+ const char *name, GLenum datatype, int array_length);
extern GLint
_mesa_add_varying(struct gl_program_parameter_list *paramList,