glsl: support sampler arrays.

This commit is contained in:
Alan Hourihane 2009-01-13 23:54:46 +00:00
parent f883c14560
commit 8373347c05
3 changed files with 50 additions and 12 deletions

View file

@ -4254,10 +4254,14 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
slang_ir_storage *store = NULL;
int dbg = 0;
const GLenum datatype = _slang_gltype_from_specifier(&var->type.specifier);
const GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
const GLint size = _slang_sizeof_type_specifier(&var->type.specifier);
const GLint arrayLen = _slang_array_length(var);
const GLint totalSize = _slang_array_size(size, arrayLen);
GLint texIndex = sampler_to_texture_index(var->type.specifier.type);
/* check for sampler2D arrays */
if (texIndex == -1 && var->type.specifier._array)
texIndex = sampler_to_texture_index(var->type.specifier._array->type);
if (texIndex != -1) {
/* This is a texture sampler variable...
@ -4271,15 +4275,36 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
}
#if FEATURE_es2_glsl /* XXX should use FEATURE_texture_rect */
/* disallow rect samplers */
if (var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECT ||
var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECTSHADOW) {
if ((var->type.specifier._array &&
(var->type.specifier._array->type == SLANG_SPEC_SAMPLER2DRECT ||
var->type.specifier._array->type == SLANG_SPEC_SAMPLER2DRECTSHADOW)) ||
(var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECT ||
var->type.specifier.type == SLANG_SPEC_SAMPLER2DRECTSHADOW)) {
slang_info_log_error(A->log, "invalid sampler type for '%s'", varName);
return GL_FALSE;
}
#endif
{
const GLuint swizzle = _slang_var_swizzle(totalSize, 0);
GLint sampNum = _mesa_add_sampler(prog->Parameters, varName, datatype);
store = _slang_new_ir_storage(PROGRAM_SAMPLER, sampNum, texIndex);
store = _slang_new_ir_storage_swz(PROGRAM_SAMPLER, sampNum,
totalSize, swizzle);
/* If we have a sampler array, then we need to allocate the
* additional samplers to ensure we don't allocate them elsewhere.
* We can't directly use _mesa_add_sampler() as that checks the
* varName and gets a match, so we call _mesa_add_parameter()
* directly and use the last sampler number for the call above.
*/
if (arrayLen > 0) {
GLint a = arrayLen - 1;
GLint i;
for (i = 0; i < a; i++) {
GLfloat value = (GLfloat)(i + sampNum + 1);
(void) _mesa_add_parameter(prog->Parameters, PROGRAM_SAMPLER,
varName, 1, datatype, &value, NULL, 0x0);
}
}
}
if (dbg) printf("SAMPLER ");
}

View file

@ -1271,6 +1271,20 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
opcode = OPCODE_TXP;
}
if (n->Children[0]->Opcode == IR_ELEMENT) {
/* array is the sampler (a uniform which'll indicate the texture unit) */
assert(n->Children[0]->Children[0]->Store);
assert(n->Children[0]->Children[0]->Store->File == PROGRAM_SAMPLER);
emit(emitInfo, n->Children[0]);
n->Children[0]->Var = n->Children[0]->Children[0]->Var;
} else {
/* this is the sampler (a uniform which'll indicate the texture unit) */
assert(n->Children[0]->Store);
assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
}
/* emit code for the texcoord operand */
(void) emit(emitInfo, n->Children[1]);
@ -1286,9 +1300,6 @@ emit_tex(slang_emit_info *emitInfo, slang_ir_node *n)
NULL,
NULL);
/* Child[0] is the sampler (a uniform which'll indicate the texture unit) */
assert(n->Children[0]->Store);
assert(n->Children[0]->Store->File == PROGRAM_SAMPLER);
/* Store->Index is the sampler index */
assert(n->Children[0]->Store->Index >= 0);
/* Store->Size is the texture target */

View file

@ -282,12 +282,14 @@ link_uniform_vars(GLcontext *ctx,
for (i = 0; i < prog->NumInstructions; i++) {
struct prog_instruction *inst = prog->Instructions + i;
if (_mesa_is_tex_instruction(inst->Opcode)) {
/*
printf("====== remap sampler from %d to %d\n",
inst->Sampler, map[ inst->Sampler ]);
*/
/* here, texUnit is really samplerUnit */
const GLint oldSampNum = inst->TexSrcUnit;
#if 0
printf("====== remap sampler from %d to %d\n",
inst->TexSrcUnit, samplerMap[ inst->TexSrcUnit ]);
#endif
/* here, texUnit is really samplerUnit */
if (oldSampNum < Elements(samplerMap)) {
const GLuint newSampNum = samplerMap[oldSampNum];
inst->TexSrcUnit = newSampNum;