Commit a141a075 by Alexis Hetu Committed by Alexis Hétu

Fixed sampler allocation

Instead of testing for the number of samplers used so far in the shader, the Program object was checking for the register index, which could have been larger or equal to MAX_VERTEX_TEXTURE_IMAGE_UNITS or MAX_TEXTURE_IMAGE_UNITS, making the shader compilation fail erroneously. Changed sampler arrays to maps in order to get the sampler data from the register index. Change-Id: Iba6cbf0dbbcdbd926f2670af4413710550e341a9 Reviewed-on: https://swiftshader-review.googlesource.com/15428Tested-by: 's avatarAlexis Hétu <sugoi@google.com> Reviewed-by: 's avatarNicolas Capens <nicolascapens@google.com>
parent 27da071d
...@@ -3074,15 +3074,16 @@ void Context::applyTextures(sw::SamplerType samplerType) ...@@ -3074,15 +3074,16 @@ void Context::applyTextures(sw::SamplerType samplerType)
{ {
Program *programObject = getCurrentProgram(); Program *programObject = getCurrentProgram();
int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS; // Range of samplers of given sampler type const std::map<int, es2::Program::Sampler> &samplerMap = programObject->getSamplerMap(samplerType);
for(int samplerIndex = 0; samplerIndex < samplerCount; samplerIndex++) int samplerIndex = 0;
for(auto sampler : samplerMap)
{ {
int textureUnit = programObject->getSamplerMapping(samplerType, samplerIndex); // OpenGL texture image unit index int textureUnit = sampler.second.logicalTextureUnit;
if(textureUnit != -1) if(textureUnit != -1)
{ {
TextureType textureType = programObject->getSamplerTextureType(samplerType, samplerIndex); TextureType textureType = programObject->getSamplerTextureType(samplerType, sampler.first);
Texture *texture = getSamplerTexture(textureUnit, textureType); Texture *texture = getSamplerTexture(textureUnit, textureType);
...@@ -3153,6 +3154,13 @@ void Context::applyTextures(sw::SamplerType samplerType) ...@@ -3153,6 +3154,13 @@ void Context::applyTextures(sw::SamplerType samplerType)
{ {
applyTexture(samplerType, samplerIndex, nullptr); applyTexture(samplerType, samplerIndex, nullptr);
} }
++samplerIndex;
}
int samplerCount = (samplerType == sw::SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : MAX_VERTEX_TEXTURE_IMAGE_UNITS;
for(; samplerIndex < samplerCount; ++samplerIndex)
{
applyTexture(samplerType, samplerIndex, nullptr);
} }
} }
......
...@@ -304,38 +304,9 @@ namespace es2 ...@@ -304,38 +304,9 @@ namespace es2
return attributeStream[attributeIndex]; return attributeStream[attributeIndex];
} }
// Returns the index of the texture image unit (0-19) corresponding to a sampler index (0-15 for the pixel shader and 0-3 for the vertex shader) const std::map<int, es2::Program::Sampler>& Program::getSamplerMap(sw::SamplerType type) const
GLint Program::getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex)
{ {
GLint logicalTextureUnit = -1; return (type == sw::SAMPLER_PIXEL) ? samplersPS : samplersVS;
switch(type)
{
case sw::SAMPLER_PIXEL:
ASSERT(samplerIndex < sizeof(samplersPS) / sizeof(samplersPS[0]));
if(samplersPS[samplerIndex].active)
{
logicalTextureUnit = samplersPS[samplerIndex].logicalTextureUnit;
}
break;
case sw::SAMPLER_VERTEX:
ASSERT(samplerIndex < sizeof(samplersVS) / sizeof(samplersVS[0]));
if(samplersVS[samplerIndex].active)
{
logicalTextureUnit = samplersVS[samplerIndex].logicalTextureUnit;
}
break;
default: UNREACHABLE(type);
}
if(logicalTextureUnit < MAX_COMBINED_TEXTURE_IMAGE_UNITS)
{
return logicalTextureUnit;
}
return -1;
} }
// Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader) // Returns the texture type for a given sampler type and index (0-15 for the pixel shader and 0-3 for the vertex shader)
...@@ -344,12 +315,8 @@ namespace es2 ...@@ -344,12 +315,8 @@ namespace es2
switch(type) switch(type)
{ {
case sw::SAMPLER_PIXEL: case sw::SAMPLER_PIXEL:
ASSERT(samplerIndex < sizeof(samplersPS)/sizeof(samplersPS[0]));
ASSERT(samplersPS[samplerIndex].active);
return samplersPS[samplerIndex].textureType; return samplersPS[samplerIndex].textureType;
case sw::SAMPLER_VERTEX: case sw::SAMPLER_VERTEX:
ASSERT(samplerIndex < sizeof(samplersVS)/sizeof(samplersVS[0]));
ASSERT(samplersVS[samplerIndex].active);
return samplersVS[samplerIndex].textureType; return samplersVS[samplerIndex].textureType;
default: UNREACHABLE(type); default: UNREACHABLE(type);
} }
...@@ -1709,10 +1676,8 @@ namespace es2 ...@@ -1709,10 +1676,8 @@ namespace es2
{ {
if(shader == GL_VERTEX_SHADER) if(shader == GL_VERTEX_SHADER)
{ {
if(index < MAX_VERTEX_TEXTURE_IMAGE_UNITS) if(samplersVS.size() < MAX_VERTEX_TEXTURE_IMAGE_UNITS)
{ {
samplersVS[index].active = true;
switch(type) switch(type)
{ {
default: UNREACHABLE(type); default: UNREACHABLE(type);
...@@ -1744,10 +1709,8 @@ namespace es2 ...@@ -1744,10 +1709,8 @@ namespace es2
} }
else if(shader == GL_FRAGMENT_SHADER) else if(shader == GL_FRAGMENT_SHADER)
{ {
if(index < MAX_TEXTURE_IMAGE_UNITS) if(samplersPS.size() < MAX_TEXTURE_IMAGE_UNITS)
{ {
samplersPS[index].active = true;
switch(type) switch(type)
{ {
default: UNREACHABLE(type); default: UNREACHABLE(type);
...@@ -2267,9 +2230,8 @@ namespace es2 ...@@ -2267,9 +2230,8 @@ namespace es2
{ {
unsigned int samplerIndex = targetUniform->psRegisterIndex + i; unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS) if(samplersPS.find(samplerIndex) != samplersPS.end())
{ {
ASSERT(samplersPS[samplerIndex].active);
samplersPS[samplerIndex].logicalTextureUnit = v[i]; samplersPS[samplerIndex].logicalTextureUnit = v[i];
} }
} }
...@@ -2281,9 +2243,8 @@ namespace es2 ...@@ -2281,9 +2243,8 @@ namespace es2
{ {
unsigned int samplerIndex = targetUniform->vsRegisterIndex + i; unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS) if(samplersVS.find(samplerIndex) != samplersVS.end())
{ {
ASSERT(samplersVS[samplerIndex].active);
samplersVS[samplerIndex].logicalTextureUnit = v[i]; samplersVS[samplerIndex].logicalTextureUnit = v[i];
} }
} }
...@@ -2369,9 +2330,8 @@ namespace es2 ...@@ -2369,9 +2330,8 @@ namespace es2
{ {
unsigned int samplerIndex = targetUniform->psRegisterIndex + i; unsigned int samplerIndex = targetUniform->psRegisterIndex + i;
if(samplerIndex < MAX_TEXTURE_IMAGE_UNITS) if(samplersPS.find(samplerIndex) != samplersPS.end())
{ {
ASSERT(samplersPS[samplerIndex].active);
samplersPS[samplerIndex].logicalTextureUnit = v[i]; samplersPS[samplerIndex].logicalTextureUnit = v[i];
} }
} }
...@@ -2383,9 +2343,8 @@ namespace es2 ...@@ -2383,9 +2343,8 @@ namespace es2
{ {
unsigned int samplerIndex = targetUniform->vsRegisterIndex + i; unsigned int samplerIndex = targetUniform->vsRegisterIndex + i;
if(samplerIndex < MAX_VERTEX_TEXTURE_IMAGE_UNITS) if(samplersVS.find(samplerIndex) != samplersVS.end())
{ {
ASSERT(samplersVS[samplerIndex].active);
samplersVS[samplerIndex].logicalTextureUnit = v[i]; samplersVS[samplerIndex].logicalTextureUnit = v[i];
} }
} }
...@@ -2510,15 +2469,8 @@ namespace es2 ...@@ -2510,15 +2469,8 @@ namespace es2
attributeStream[index] = -1; attributeStream[index] = -1;
} }
for(int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) samplersPS.clear();
{ samplersVS.clear();
samplersPS[index].active = false;
}
for(int index = 0; index < MAX_VERTEX_TEXTURE_IMAGE_UNITS; index++)
{
samplersVS[index].active = false;
}
while(!uniforms.empty()) while(!uniforms.empty())
{ {
...@@ -2934,73 +2886,67 @@ namespace es2 ...@@ -2934,73 +2886,67 @@ namespace es2
textureUnitType[i] = TEXTURE_UNKNOWN; textureUnitType[i] = TEXTURE_UNKNOWN;
} }
for(unsigned int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++) for(auto sampler : samplersPS)
{ {
if(samplersPS[i].active) unsigned int unit = sampler.second.logicalTextureUnit;
if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
{ {
unsigned int unit = samplersPS[i].logicalTextureUnit; if(logErrors)
{
appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
}
return false;
}
if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS) if(textureUnitType[unit] != TEXTURE_UNKNOWN)
{
if(sampler.second.textureType != textureUnitType[unit])
{ {
if(logErrors) if(logErrors)
{ {
appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS); appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
} }
return false; return false;
} }
}
else
{
textureUnitType[unit] = sampler.second.textureType;
}
}
if(textureUnitType[unit] != TEXTURE_UNKNOWN) for(auto sampler : samplersVS)
{ {
if(samplersPS[i].textureType != textureUnitType[unit]) unsigned int unit = sampler.second.logicalTextureUnit;
{
if(logErrors)
{
appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
}
return false; if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
} {
} if(logErrors)
else
{ {
textureUnitType[unit] = samplersPS[i].textureType; appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS);
} }
return false;
} }
}
for(unsigned int i = 0; i < MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) if(textureUnitType[unit] != TEXTURE_UNKNOWN)
{
if(samplersVS[i].active)
{ {
unsigned int unit = samplersVS[i].logicalTextureUnit; if(sampler.second.textureType != textureUnitType[unit])
if(unit >= MAX_COMBINED_TEXTURE_IMAGE_UNITS)
{ {
if(logErrors) if(logErrors)
{ {
appendToInfoLog("Sampler uniform (%d) exceeds MAX_COMBINED_TEXTURE_IMAGE_UNITS (%d)", unit, MAX_COMBINED_TEXTURE_IMAGE_UNITS); appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
} }
return false; return false;
} }
}
if(textureUnitType[unit] != TEXTURE_UNKNOWN) else
{ {
if(samplersVS[i].textureType != textureUnitType[unit]) textureUnitType[unit] = sampler.second.textureType;
{
if(logErrors)
{
appendToInfoLog("Samplers of conflicting types refer to the same texture image unit (%d).", unit);
}
return false;
}
}
else
{
textureUnitType[unit] = samplersVS[i].textureType;
}
} }
} }
......
...@@ -121,6 +121,12 @@ namespace es2 ...@@ -121,6 +121,12 @@ namespace es2
class Program class Program
{ {
public: public:
struct Sampler
{
GLint logicalTextureUnit;
TextureType textureType;
};
Program(ResourceManager *manager, GLuint handle); Program(ResourceManager *manager, GLuint handle);
~Program(); ~Program();
...@@ -136,7 +142,7 @@ namespace es2 ...@@ -136,7 +142,7 @@ namespace es2
GLint getAttributeLocation(const char *name); GLint getAttributeLocation(const char *name);
int getAttributeStream(int attributeIndex); int getAttributeStream(int attributeIndex);
GLint getSamplerMapping(sw::SamplerType type, unsigned int samplerIndex); const std::map<int, es2::Program::Sampler>& getSamplerMap(sw::SamplerType type) const;
TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex); TextureType getSamplerTextureType(sw::SamplerType type, unsigned int samplerIndex);
GLuint getUniformIndex(const std::string &name) const; GLuint getUniformIndex(const std::string &name) const;
...@@ -291,15 +297,8 @@ namespace es2 ...@@ -291,15 +297,8 @@ namespace es2
GLenum transformFeedbackBufferMode; GLenum transformFeedbackBufferMode;
size_t totalLinkedVaryingsComponents; size_t totalLinkedVaryingsComponents;
struct Sampler std::map<int, Sampler> samplersPS;
{ std::map<int, Sampler> samplersVS;
bool active;
GLint logicalTextureUnit;
TextureType textureType;
};
Sampler samplersPS[MAX_TEXTURE_IMAGE_UNITS];
Sampler samplersVS[MAX_VERTEX_TEXTURE_IMAGE_UNITS];
typedef std::vector<Uniform*> UniformArray; typedef std::vector<Uniform*> UniformArray;
UniformArray uniforms; UniformArray uniforms;
......
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