mesa: glsl: fix linking of varying vars which are arrays
This commit is contained in:
@@ -3727,6 +3727,8 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
||||
if (dbg) printf("UNIFORM (sz %d) ", totalSize);
|
||||
}
|
||||
else if (var->type.qualifier == SLANG_QUAL_VARYING) {
|
||||
const GLint totalSize = array_size(size, var->array_len);
|
||||
|
||||
/* varyings must be float, vec or mat */
|
||||
if (!_slang_type_is_float_vec_mat(var->type.specifier.type) &&
|
||||
var->type.specifier.type != SLANG_SPEC_ARRAY) {
|
||||
@@ -3744,10 +3746,10 @@ _slang_codegen_global_variable(slang_assemble_ctx *A, slang_variable *var,
|
||||
|
||||
if (prog) {
|
||||
/* user-defined varying */
|
||||
GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, size);
|
||||
GLint varyingLoc = _mesa_add_varying(prog->Varying, varName, totalSize);
|
||||
GLuint swizzle = _slang_var_swizzle(size, 0);
|
||||
store = _slang_new_ir_storage_swz(PROGRAM_VARYING, varyingLoc,
|
||||
size, swizzle);
|
||||
totalSize, swizzle);
|
||||
}
|
||||
else {
|
||||
/* pre-defined varying, like gl_Color or gl_TexCoord */
|
||||
|
||||
@@ -42,6 +42,20 @@
|
||||
#include "slang_link.h"
|
||||
|
||||
|
||||
/**
|
||||
* Record a linking error.
|
||||
*/
|
||||
static void
|
||||
link_error(struct gl_shader_program *shProg, const char *msg)
|
||||
{
|
||||
if (shProg->InfoLog) {
|
||||
_mesa_free(shProg->InfoLog);
|
||||
}
|
||||
shProg->InfoLog = _mesa_strdup(msg);
|
||||
shProg->LinkStatus = GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Linking varying vars involves rearranging varying vars so that the
|
||||
@@ -52,7 +66,6 @@ static GLboolean
|
||||
link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
||||
{
|
||||
GLuint *map, i, firstVarying, newFile;
|
||||
GLbitfield varsWritten, varsRead;
|
||||
|
||||
map = (GLuint *) malloc(prog->Varying->NumParameters * sizeof(GLuint));
|
||||
if (!map)
|
||||
@@ -60,14 +73,13 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
||||
|
||||
for (i = 0; i < prog->Varying->NumParameters; i++) {
|
||||
/* see if this varying is in the linked varying list */
|
||||
const struct gl_program_parameter *var
|
||||
= prog->Varying->Parameters + i;
|
||||
|
||||
const struct gl_program_parameter *var = prog->Varying->Parameters + i;
|
||||
GLint j = _mesa_lookup_parameter_index(shProg->Varying, -1, var->Name);
|
||||
if (j >= 0) {
|
||||
/* already in list, check size */
|
||||
if (var->Size != shProg->Varying->Parameters[j].Size) {
|
||||
/* error */
|
||||
link_error(shProg, "mismatched varying variable types");
|
||||
return GL_FALSE;
|
||||
}
|
||||
}
|
||||
@@ -75,9 +87,19 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
||||
/* not already in linked list */
|
||||
j = _mesa_add_varying(shProg->Varying, var->Name, var->Size);
|
||||
}
|
||||
ASSERT(j >= 0);
|
||||
|
||||
map[i] = j;
|
||||
/* map varying[i] to varying[j].
|
||||
* Note: the loop here takes care of arrays or large (sz>4) vars.
|
||||
*/
|
||||
{
|
||||
GLint sz = var->Size;
|
||||
while (sz > 0) {
|
||||
/*printf("Link varying from %d to %d\n", i, j);*/
|
||||
map[i++] = j++;
|
||||
sz -= 4;
|
||||
}
|
||||
i--; /* go back one */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -96,9 +118,6 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
||||
newFile = PROGRAM_INPUT;
|
||||
}
|
||||
|
||||
/* keep track of which varying vars we read and write */
|
||||
varsWritten = varsRead = 0x0;
|
||||
|
||||
/* OK, now scan the program/shader instructions looking for varying vars,
|
||||
* replacing the old index with the new index.
|
||||
*/
|
||||
@@ -109,30 +128,22 @@ link_varying_vars(struct gl_shader_program *shProg, struct gl_program *prog)
|
||||
if (inst->DstReg.File == PROGRAM_VARYING) {
|
||||
inst->DstReg.File = newFile;
|
||||
inst->DstReg.Index = map[ inst->DstReg.Index ] + firstVarying;
|
||||
varsWritten |= (1 << inst->DstReg.Index);
|
||||
}
|
||||
|
||||
for (j = 0; j < 3; j++) {
|
||||
if (inst->SrcReg[j].File == PROGRAM_VARYING) {
|
||||
inst->SrcReg[j].File = newFile;
|
||||
inst->SrcReg[j].Index = map[ inst->SrcReg[j].Index ] + firstVarying;
|
||||
varsRead |= (1 << inst->SrcReg[j].Index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (prog->Target == GL_VERTEX_PROGRAM_ARB) {
|
||||
prog->OutputsWritten |= varsWritten;
|
||||
/*printf("VERT OUTPUTS: 0x%x \n", varsWritten);*/
|
||||
}
|
||||
else {
|
||||
assert(prog->Target == GL_FRAGMENT_PROGRAM_ARB);
|
||||
prog->InputsRead |= varsRead;
|
||||
/*printf("FRAG INPUTS: 0x%x\n", varsRead);*/
|
||||
}
|
||||
|
||||
free(map);
|
||||
|
||||
/* these will get recomputed before linking is completed */
|
||||
prog->InputsRead = 0x0;
|
||||
prog->OutputsWritten = 0x0;
|
||||
|
||||
return GL_TRUE;
|
||||
}
|
||||
|
||||
@@ -381,21 +392,6 @@ fragment_program(struct gl_program *prog)
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Record a linking error.
|
||||
*/
|
||||
static void
|
||||
link_error(struct gl_shader_program *shProg, const char *msg)
|
||||
{
|
||||
if (shProg->InfoLog) {
|
||||
_mesa_free(shProg->InfoLog);
|
||||
}
|
||||
shProg->InfoLog = _mesa_strdup(msg);
|
||||
shProg->LinkStatus = GL_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Shader linker. Currently:
|
||||
*
|
||||
@@ -478,10 +474,14 @@ _slang_link(GLcontext *ctx,
|
||||
}
|
||||
|
||||
/* link varying vars */
|
||||
if (shProg->VertexProgram)
|
||||
link_varying_vars(shProg, &shProg->VertexProgram->Base);
|
||||
if (shProg->FragmentProgram)
|
||||
link_varying_vars(shProg, &shProg->FragmentProgram->Base);
|
||||
if (shProg->VertexProgram) {
|
||||
if (!link_varying_vars(shProg, &shProg->VertexProgram->Base))
|
||||
return;
|
||||
}
|
||||
if (shProg->FragmentProgram) {
|
||||
if (!link_varying_vars(shProg, &shProg->FragmentProgram->Base))
|
||||
return;
|
||||
}
|
||||
|
||||
/* link uniform vars */
|
||||
if (shProg->VertexProgram)
|
||||
|
||||
Reference in New Issue
Block a user