Commit cdd2924e by Nicolas Capens

Fix supporting samplers in structs passed down as function arguments.

Bug 19354873 Change-Id: Ic21a36eefcdef4d9fcce1952fa15425da8858200 Reviewed-on: https://swiftshader-review.googlesource.com/2260Tested-by: 's avatarNicolas Capens <capn@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <capn@google.com>
parent 8fb3b484
...@@ -1280,17 +1280,22 @@ namespace glsl ...@@ -1280,17 +1280,22 @@ namespace glsl
bool OutputASM::isSamplerRegister(TIntermTyped *operand) bool OutputASM::isSamplerRegister(TIntermTyped *operand)
{ {
return operand && isSamplerRegister(operand->getType());
}
bool OutputASM::isSamplerRegister(const TType &type)
{
// A sampler register's qualifiers can be: // A sampler register's qualifiers can be:
// - EvqUniform: The sampler uniform is used as is in the code (default case). // - EvqUniform: The sampler uniform is used as is in the code (default case).
// - EvqTemporary: The sampler is indexed. It's still a sampler register. // - EvqTemporary: The sampler is indexed. It's still a sampler register.
// - EvqIn (and other similar types): The sampler has been passed as a function argument. At this point, // - EvqIn (and other similar types): The sampler has been passed as a function argument. At this point,
// the sampler has been copied and is no longer a sampler register. // the sampler has been copied and is no longer a sampler register.
return IsSampler(operand->getBasicType()) && (operand->getQualifier() == EvqUniform || operand->getQualifier() == EvqTemporary); return IsSampler(type.getBasicType()) && (type.getQualifier() == EvqUniform || type.getQualifier() == EvqTemporary);
} }
Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, int index) Instruction *OutputASM::emit(sw::Shader::Opcode op, TIntermTyped *dst, TIntermNode *src0, TIntermNode *src1, TIntermNode *src2, int index)
{ {
if(dst && isSamplerRegister(dst)) if(isSamplerRegister(dst))
{ {
op = sw::Shader::OPCODE_NULL; // Can't assign to a sampler, but this is hit when indexing sampler arrays op = sw::Shader::OPCODE_NULL; // Can't assign to a sampler, but this is hit when indexing sampler arrays
} }
...@@ -1510,6 +1515,10 @@ namespace glsl ...@@ -1510,6 +1515,10 @@ namespace glsl
parameter.rel.deterministic = true; parameter.rel.deterministic = true;
} }
} }
else if(binary->getOp() == EOpIndexDirectStruct)
{
parameter.index += right->getAsConstantUnion()->getIConst(0);
}
else UNREACHABLE(); else UNREACHABLE();
} }
} }
...@@ -2141,40 +2150,45 @@ namespace glsl ...@@ -2141,40 +2150,45 @@ namespace glsl
int OutputASM::samplerRegister(TIntermTyped *sampler) int OutputASM::samplerRegister(TIntermTyped *sampler)
{ {
const TType &type = sampler->getType(); ASSERT(IsSampler(sampler->getType().getBasicType()));
ASSERT(IsSampler(type.getBasicType()));
TIntermSymbol *symbol = sampler->getAsSymbolNode(); TIntermSymbol *symbol = sampler->getAsSymbolNode();
TIntermBinary *binary = sampler->getAsBinaryNode(); TIntermBinary *binary = sampler->getAsBinaryNode();
if(symbol) if(symbol)
{ {
return samplerRegister(symbol);
}
else if(binary)
{
ASSERT(binary->getOp() == EOpIndexDirect || binary->getOp() == EOpIndexIndirect || binary->getOp() == EOpIndexDirectStruct);
return samplerRegister(binary->getLeft()); // Index added later
}
else UNREACHABLE();
return 0;
}
int OutputASM::samplerRegister(TIntermSymbol *sampler)
{
const TType &type = sampler->getType();
ASSERT(IsSampler(type.getBasicType()) || type.getStruct()); // Structures can contain samplers
int index = lookup(samplers, sampler); int index = lookup(samplers, sampler);
if(index == -1) if(index == -1)
{ {
index = allocate(samplers, sampler); index = allocate(samplers, sampler);
ActiveUniforms &activeUniforms = shaderObject->activeUniforms;
const char *name = symbol->getSymbol().c_str();
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name, sampler->getArraySize(), index));
for(int i = 0; i < sampler->totalRegisterCount(); i++) if(sampler->getQualifier() == EvqUniform)
{ {
shader->declareSampler(index + i); const char *name = sampler->getSymbol().c_str();
declareUniform(type, name, index);
} }
} }
return index; return index;
} }
else if(binary)
{
ASSERT(binary->getOp() == EOpIndexDirect || binary->getOp() == EOpIndexIndirect);
return samplerRegister(binary->getLeft()); // Index added later
}
else UNREACHABLE();
return 0;
}
int OutputASM::lookup(VariableArray &list, TIntermTyped *variable) int OutputASM::lookup(VariableArray &list, TIntermTyped *variable)
{ {
...@@ -2276,6 +2290,14 @@ namespace glsl ...@@ -2276,6 +2290,14 @@ namespace glsl
if(!structure) if(!structure)
{ {
activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index)); activeUniforms.push_back(Uniform(glVariableType(type), glVariablePrecision(type), name.c_str(), type.getArraySize(), index));
if(isSamplerRegister(type))
{
for(int i = 0; i < type.totalRegisterCount(); i++)
{
shader->declareSampler(index + i);
}
}
} }
else else
{ {
......
...@@ -170,6 +170,7 @@ namespace glsl ...@@ -170,6 +170,7 @@ namespace glsl
int uniformRegister(TIntermTyped *uniform); int uniformRegister(TIntermTyped *uniform);
int attributeRegister(TIntermTyped *attribute); int attributeRegister(TIntermTyped *attribute);
int samplerRegister(TIntermTyped *sampler); int samplerRegister(TIntermTyped *sampler);
int samplerRegister(TIntermSymbol *sampler);
typedef std::vector<TIntermTyped*> VariableArray; typedef std::vector<TIntermTyped*> VariableArray;
...@@ -185,6 +186,7 @@ namespace glsl ...@@ -185,6 +186,7 @@ namespace glsl
static int dim2(TIntermNode *m); static int dim2(TIntermNode *m);
static unsigned int loopCount(TIntermLoop *node); static unsigned int loopCount(TIntermLoop *node);
static bool isSamplerRegister(TIntermTyped *operand); static bool isSamplerRegister(TIntermTyped *operand);
static bool isSamplerRegister(const TType &type);
Shader *const shaderObject; Shader *const shaderObject;
sw::Shader *shader; sw::Shader *shader;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment