From c234d0b25f622a7bdd3c40bc72fdbd59d8494c7c Mon Sep 17 00:00:00 2001 From: Eric Anholt Date: Thu, 5 Aug 2010 17:00:12 -0700 Subject: [PATCH] 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 --- src/mesa/program/ir_to_mesa.cpp | 47 +++++++++++++++++++++++++++++++-------- src/mesa/program/prog_parameter.c | 7 +++--- src/mesa/program/prog_parameter.h | 2 +- 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 66b1a2f9d9a..d8a13220ae2 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 ddbfe95c152..fa5deaf127d 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 cc3378ae201..1860f312879 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, -- 2.11.0