Select texture type based on program usage.

TRAC #11410 Add Program::getSamplerType() and internal machinery to track the reported sampler uniforms. Make State::samplerTexture into a 2D array with a dimension for sampler type. Context::applyTextures queries the sampler type and asks for the right texture. Author: Andrew Lewycky Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/trunk@25 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 9efa6f6b
...@@ -64,6 +64,14 @@ enum ...@@ -64,6 +64,14 @@ enum
// Because indices are accessed internally, we convert them to a common format. // Because indices are accessed internally, we convert them to a common format.
typedef unsigned short Index; typedef unsigned short Index;
enum SamplerType
{
SAMPLER_2D,
SAMPLER_CUBE,
SAMPLER_TYPE_COUNT
};
struct Color struct Color
{ {
float red; float red;
...@@ -170,7 +178,7 @@ struct State ...@@ -170,7 +178,7 @@ struct State
GLuint currentProgram; GLuint currentProgram;
AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS]; AttributeState vertexAttribute[MAX_VERTEX_ATTRIBS];
GLuint samplerTexture[MAX_TEXTURE_IMAGE_UNITS]; GLuint samplerTexture[SAMPLER_TYPE_COUNT][MAX_TEXTURE_IMAGE_UNITS];
unsigned int startIndex; unsigned int startIndex;
}; };
...@@ -231,7 +239,7 @@ class Context : public State ...@@ -231,7 +239,7 @@ class Context : public State
Program *getCurrentProgram(); Program *getCurrentProgram();
Texture2D *getTexture2D(); Texture2D *getTexture2D();
TextureCubeMap *getTextureCubeMap(); TextureCubeMap *getTextureCubeMap();
Texture *getSamplerTexture(unsigned int sampler); Texture *getSamplerTexture(unsigned int sampler, SamplerType type);
Framebuffer *getFramebuffer(); Framebuffer *getFramebuffer();
bool applyRenderTarget(bool ignoreViewport); bool applyRenderTarget(bool ignoreViewport);
......
...@@ -115,9 +115,12 @@ Context::Context(const egl::Config *config) ...@@ -115,9 +115,12 @@ Context::Context(const egl::Config *config)
bindFramebuffer(0); bindFramebuffer(0);
bindRenderbuffer(0); bindRenderbuffer(0);
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{ {
samplerTexture[sampler] = 0; for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
{
samplerTexture[type][sampler] = 0;
}
} }
currentProgram = 0; currentProgram = 0;
...@@ -458,7 +461,7 @@ void Context::bindTexture2D(GLuint texture) ...@@ -458,7 +461,7 @@ void Context::bindTexture2D(GLuint texture)
texture2D = texture; texture2D = texture;
samplerTexture[activeSampler] = texture; samplerTexture[SAMPLER_2D][activeSampler] = texture;
} }
void Context::bindTextureCubeMap(GLuint texture) void Context::bindTextureCubeMap(GLuint texture)
...@@ -477,7 +480,7 @@ void Context::bindTextureCubeMap(GLuint texture) ...@@ -477,7 +480,7 @@ void Context::bindTextureCubeMap(GLuint texture)
textureCubeMap = texture; textureCubeMap = texture;
samplerTexture[activeSampler] = texture; samplerTexture[SAMPLER_CUBE][activeSampler] = texture;
} }
void Context::bindFramebuffer(GLuint framebuffer) void Context::bindFramebuffer(GLuint framebuffer)
...@@ -718,9 +721,9 @@ TextureCubeMap *Context::getTextureCubeMap() ...@@ -718,9 +721,9 @@ TextureCubeMap *Context::getTextureCubeMap()
return (TextureCubeMap*)getTexture(textureCubeMap); return (TextureCubeMap*)getTexture(textureCubeMap);
} }
Texture *Context::getSamplerTexture(unsigned int sampler) Texture *Context::getSamplerTexture(unsigned int sampler, SamplerType type)
{ {
return getTexture(samplerTexture[sampler]); return getTexture(samplerTexture[type][sampler]);
} }
Framebuffer *Context::getFramebuffer() Framebuffer *Context::getFramebuffer()
...@@ -1051,11 +1054,13 @@ void Context::applyTextures() ...@@ -1051,11 +1054,13 @@ void Context::applyTextures()
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
{ {
unsigned int textureUnit = programObject->getSamplerMapping(sampler); int textureUnit = programObject->getSamplerMapping(sampler);
Texture *texture = getSamplerTexture(textureUnit); if (textureUnit != -1)
if (texture && texture->isComplete())
{ {
SamplerType textureType = programObject->getSamplerType(sampler);
Texture *texture = getSamplerTexture(textureUnit, textureType);
GLenum wrapS = texture->getWrapS(); GLenum wrapS = texture->getWrapS();
GLenum wrapT = texture->getWrapT(); GLenum wrapT = texture->getWrapT();
GLenum minFilter = texture->getMinFilter(); GLenum minFilter = texture->getMinFilter();
...@@ -1072,6 +1077,10 @@ void Context::applyTextures() ...@@ -1072,6 +1077,10 @@ void Context::applyTextures()
device->SetTexture(sampler, texture->getTexture()); device->SetTexture(sampler, texture->getTexture());
} }
else
{
device->SetTexture(sampler, NULL);
}
} }
} }
...@@ -1637,11 +1646,14 @@ void Context::detachTexture(GLuint texture) ...@@ -1637,11 +1646,14 @@ void Context::detachTexture(GLuint texture)
// If a texture object is deleted, it is as if all texture units which are bound to that texture object are // If a texture object is deleted, it is as if all texture units which are bound to that texture object are
// rebound to texture object zero // rebound to texture object zero
for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++) for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{ {
if (samplerTexture[sampler] == texture) for (int sampler = 0; sampler < MAX_TEXTURE_IMAGE_UNITS; sampler++)
{ {
samplerTexture[sampler] = 0; if (samplerTexture[type][sampler] == texture)
{
samplerTexture[type][sampler] = 0;
}
} }
} }
......
...@@ -164,12 +164,22 @@ int Program::getInputMapping(int attributeIndex) ...@@ -164,12 +164,22 @@ int Program::getInputMapping(int attributeIndex)
// index referenced in the compiled HLSL shader // index referenced in the compiled HLSL shader
GLint Program::getSamplerMapping(unsigned int samplerIndex) GLint Program::getSamplerMapping(unsigned int samplerIndex)
{ {
if (samplerIndex < MAX_TEXTURE_IMAGE_UNITS) assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
if (mSamplers[samplerIndex].active)
{ {
return mSamplerMapping[samplerIndex]; return mSamplers[samplerIndex].logicalTextureUnit;
} }
return 0; return -1;
}
SamplerType Program::getSamplerType(unsigned int samplerIndex)
{
assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
assert(mSamplers[samplerIndex].active);
return mSamplers[samplerIndex].type;
} }
GLint Program::getUniformLocation(const char *name) GLint Program::getUniformLocation(const char *name)
...@@ -434,6 +444,11 @@ void Program::link() ...@@ -434,6 +444,11 @@ void Program::link()
return; return;
} }
for (int i = 0; i < MAX_TEXTURE_IMAGE_UNITS; i++)
{
mSamplers[i].active = false;
}
if (!linkUniforms(mConstantTablePS)) if (!linkUniforms(mConstantTablePS))
{ {
return; return;
...@@ -515,6 +530,17 @@ bool Program::linkUniforms(ID3DXConstantTable *constantTable) ...@@ -515,6 +530,17 @@ bool Program::linkUniforms(ID3DXConstantTable *constantTable)
// Returns true if succesful (uniform not already defined) // Returns true if succesful (uniform not already defined)
bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name) bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT_DESC &constantDescription, std::string name)
{ {
if (constantDescription.RegisterSet == D3DXRS_SAMPLER)
{
unsigned int samplerIndex = constantDescription.RegisterIndex;
assert(samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]));
mSamplers[samplerIndex].active = true;
mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D;
mSamplers[samplerIndex].logicalTextureUnit = 0;
}
switch(constantDescription.Class) switch(constantDescription.Class)
{ {
case D3DXPC_STRUCT: case D3DXPC_STRUCT:
...@@ -858,7 +884,8 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -858,7 +884,8 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
{ {
if (samplerIndex >= 0 && samplerIndex < MAX_TEXTURE_IMAGE_UNITS) if (samplerIndex >= 0 && samplerIndex < MAX_TEXTURE_IMAGE_UNITS)
{ {
mSamplerMapping[samplerIndex] = mappedSampler; ASSERT(mSamplers[samplerIndex].active);
mSamplers[samplerIndex].logicalTextureUnit = mappedSampler;
} }
} }
} }
...@@ -935,7 +962,7 @@ void Program::unlink(bool destroy) ...@@ -935,7 +962,7 @@ void Program::unlink(bool destroy)
for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++) for (int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; index++)
{ {
mSamplerMapping[index] = 0; mSamplers[index].active = false;
} }
while (!mUniforms.empty()) while (!mUniforms.empty())
......
...@@ -65,6 +65,7 @@ class Program ...@@ -65,6 +65,7 @@ class Program
int getInputMapping(int attributeIndex); int getInputMapping(int attributeIndex);
GLint getSamplerMapping(unsigned int samplerIndex); GLint getSamplerMapping(unsigned int samplerIndex);
SamplerType getSamplerType(unsigned int samplerIndex);
GLint getUniformLocation(const char *name); GLint getUniformLocation(const char *name);
bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v); bool setUniform1fv(GLint location, GLsizei count, const GLfloat *v);
...@@ -115,7 +116,14 @@ class Program ...@@ -115,7 +116,14 @@ class Program
char *mAttributeName[MAX_VERTEX_ATTRIBS]; char *mAttributeName[MAX_VERTEX_ATTRIBS];
int mInputMapping[MAX_VERTEX_ATTRIBS]; int mInputMapping[MAX_VERTEX_ATTRIBS];
GLint mSamplerMapping[MAX_TEXTURE_IMAGE_UNITS]; struct Sampler
{
bool active;
GLint logicalTextureUnit;
SamplerType type;
};
Sampler mSamplers[MAX_TEXTURE_IMAGE_UNITS];
typedef std::vector<Uniform*> UniformArray; typedef std::vector<Uniform*> UniformArray;
UniformArray mUniforms; UniformArray mUniforms;
......
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