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
bool OutputASM::isSamplerRegister(TIntermTyped *operand)
{
return operand && isSamplerRegister(operand->getType());
}
bool OutputASM::isSamplerRegister(const TType &type)
{
// A sampler register's qualifiers can be:
// - EvqUniform: The sampler uniform is used as is in the code (default case).
// - 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,
// 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)
{
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
}
......@@ -1510,6 +1515,10 @@ namespace glsl
parameter.rel.deterministic = true;
}
}
else if(binary->getOp() == EOpIndexDirectStruct)
{
parameter.index += right->getAsConstantUnion()->getIConst(0);
}
else UNREACHABLE();
}
}
......@@ -2141,33 +2150,17 @@ namespace glsl
int OutputASM::samplerRegister(TIntermTyped *sampler)
{
const TType &type = sampler->getType();
ASSERT(IsSampler(type.getBasicType()));
ASSERT(IsSampler(sampler->getType().getBasicType()));
TIntermSymbol *symbol = sampler->getAsSymbolNode();
TIntermBinary *binary = sampler->getAsBinaryNode();
if(symbol)
{
int index = lookup(samplers, sampler);
if(index == -1)
{
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++)
{
shader->declareSampler(index + i);
}
}
return index;
return samplerRegister(symbol);
}
else if(binary)
{
ASSERT(binary->getOp() == EOpIndexDirect || binary->getOp() == EOpIndexIndirect);
ASSERT(binary->getOp() == EOpIndexDirect || binary->getOp() == EOpIndexIndirect || binary->getOp() == EOpIndexDirectStruct);
return samplerRegister(binary->getLeft()); // Index added later
}
......@@ -2176,6 +2169,27 @@ namespace glsl
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);
if(index == -1)
{
index = allocate(samplers, sampler);
if(sampler->getQualifier() == EvqUniform)
{
const char *name = sampler->getSymbol().c_str();
declareUniform(type, name, index);
}
}
return index;
}
int OutputASM::lookup(VariableArray &list, TIntermTyped *variable)
{
for(unsigned int i = 0; i < list.size(); i++)
......@@ -2276,6 +2290,14 @@ namespace glsl
if(!structure)
{
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
{
......
......@@ -170,6 +170,7 @@ namespace glsl
int uniformRegister(TIntermTyped *uniform);
int attributeRegister(TIntermTyped *attribute);
int samplerRegister(TIntermTyped *sampler);
int samplerRegister(TIntermSymbol *sampler);
typedef std::vector<TIntermTyped*> VariableArray;
......@@ -185,6 +186,7 @@ namespace glsl
static int dim2(TIntermNode *m);
static unsigned int loopCount(TIntermLoop *node);
static bool isSamplerRegister(TIntermTyped *operand);
static bool isSamplerRegister(const TType &type);
Shader *const shaderObject;
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