Minimizes texture state changes

TRAC #12203 Signed-off-by: Nicolas Capens Signed-off-by: Daniel Koch Author: Shannon Woods git-svn-id: https://angleproject.googlecode.com/svn/trunk@267 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 41d8dd85
...@@ -1993,6 +1993,7 @@ void Context::applyShaders() ...@@ -1993,6 +1993,7 @@ void Context::applyShaders()
if (programObject->getSerial() != mAppliedProgram) if (programObject->getSerial() != mAppliedProgram)
{ {
programObject->dirtyAllUniforms(); programObject->dirtyAllUniforms();
programObject->dirtyAllSamplers();
mAppliedProgram = programObject->getSerial(); mAppliedProgram = programObject->getSerial();
} }
...@@ -2014,33 +2015,42 @@ void Context::applyTextures() ...@@ -2014,33 +2015,42 @@ void Context::applyTextures()
Texture *texture = getSamplerTexture(textureUnit, textureType); Texture *texture = getSamplerTexture(textureUnit, textureType);
if (texture->isComplete()) if (programObject->isSamplerDirty(sampler) || texture->isDirty())
{ {
GLenum wrapS = texture->getWrapS(); if (texture->isComplete())
GLenum wrapT = texture->getWrapT(); {
GLenum minFilter = texture->getMinFilter(); GLenum wrapS = texture->getWrapS();
GLenum magFilter = texture->getMagFilter(); GLenum wrapT = texture->getWrapT();
GLenum minFilter = texture->getMinFilter();
GLenum magFilter = texture->getMagFilter();
device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS)); device->SetSamplerState(sampler, D3DSAMP_ADDRESSU, es2dx::ConvertTextureWrap(wrapS));
device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT)); device->SetSamplerState(sampler, D3DSAMP_ADDRESSV, es2dx::ConvertTextureWrap(wrapT));
device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter)); device->SetSamplerState(sampler, D3DSAMP_MAGFILTER, es2dx::ConvertMagFilter(magFilter));
D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter;
es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter); es2dx::ConvertMinFilter(minFilter, &d3dMinFilter, &d3dMipFilter);
device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter); device->SetSamplerState(sampler, D3DSAMP_MINFILTER, d3dMinFilter);
device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter); device->SetSamplerState(sampler, D3DSAMP_MIPFILTER, d3dMipFilter);
device->SetTexture(sampler, texture->getTexture()); device->SetTexture(sampler, texture->getTexture());
} }
else else
{ {
device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture()); device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture());
}
} }
programObject->setSamplerDirty(sampler, false);
} }
else else
{ {
device->SetTexture(sampler, NULL); if (programObject->isSamplerDirty(sampler))
} {
device->SetTexture(sampler, NULL);
programObject->setSamplerDirty(sampler, false);
}
}
} }
} }
......
...@@ -206,6 +206,26 @@ SamplerType Program::getSamplerType(unsigned int samplerIndex) ...@@ -206,6 +206,26 @@ SamplerType Program::getSamplerType(unsigned int samplerIndex)
return mSamplers[samplerIndex].type; return mSamplers[samplerIndex].type;
} }
bool Program::isSamplerDirty(unsigned int samplerIndex) const
{
if (samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]))
{
return mSamplers[samplerIndex].dirty;
}
else UNREACHABLE();
return false;
}
void Program::setSamplerDirty(unsigned int samplerIndex, bool dirty)
{
if (samplerIndex < sizeof(mSamplers)/sizeof(mSamplers[0]))
{
mSamplers[samplerIndex].dirty = dirty;
}
else UNREACHABLE();
}
GLint Program::getUniformLocation(const char *name) GLint Program::getUniformLocation(const char *name)
{ {
std::string nameStr(name); std::string nameStr(name);
...@@ -868,6 +888,14 @@ void Program::dirtyAllUniforms() ...@@ -868,6 +888,14 @@ void Program::dirtyAllUniforms()
} }
} }
void Program::dirtyAllSamplers()
{
for (unsigned int index = 0; index < MAX_TEXTURE_IMAGE_UNITS; ++index)
{
mSamplers[index].dirty = true;
}
}
// Applies all the uniforms set for this program object to the Direct3D 9 device // Applies all the uniforms set for this program object to the Direct3D 9 device
void Program::applyUniforms() void Program::applyUniforms()
{ {
...@@ -1248,6 +1276,7 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT ...@@ -1248,6 +1276,7 @@ bool Program::defineUniform(const D3DXHANDLE &constantHandle, const D3DXCONSTANT
mSamplers[samplerIndex].active = true; mSamplers[samplerIndex].active = true;
mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D; mSamplers[samplerIndex].type = (constantDescription.Type == D3DXPT_SAMPLERCUBE) ? SAMPLER_CUBE : SAMPLER_2D;
mSamplers[samplerIndex].logicalTextureUnit = 0; mSamplers[samplerIndex].logicalTextureUnit = 0;
mSamplers[samplerIndex].dirty = true;
} }
switch(constantDescription.Class) switch(constantDescription.Class)
...@@ -1792,6 +1821,7 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v) ...@@ -1792,6 +1821,7 @@ bool Program::applyUniform1iv(GLint location, GLsizei count, const GLint *v)
{ {
ASSERT(mSamplers[samplerIndex].active); ASSERT(mSamplers[samplerIndex].active);
mSamplers[samplerIndex].logicalTextureUnit = mappedSampler; mSamplers[samplerIndex].logicalTextureUnit = mappedSampler;
mSamplers[samplerIndex].dirty = true;
} }
} }
} }
...@@ -2001,6 +2031,7 @@ void Program::unlink(bool destroy) ...@@ -2001,6 +2031,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++)
{ {
mSamplers[index].active = false; mSamplers[index].active = false;
mSamplers[index].dirty = true;
} }
while (!mUniforms.empty()) while (!mUniforms.empty())
......
...@@ -66,8 +66,12 @@ class Program ...@@ -66,8 +66,12 @@ class Program
GLuint getAttributeLocation(const char *name); GLuint getAttributeLocation(const char *name);
int getSemanticIndex(int attributeIndex); int getSemanticIndex(int attributeIndex);
void dirtyAllSamplers();
GLint getSamplerMapping(unsigned int samplerIndex); GLint getSamplerMapping(unsigned int samplerIndex);
SamplerType getSamplerType(unsigned int samplerIndex); SamplerType getSamplerType(unsigned int samplerIndex);
bool isSamplerDirty(unsigned int samplerIndex) const;
void setSamplerDirty(unsigned int samplerIndex, bool dirty);
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);
...@@ -185,6 +189,7 @@ class Program ...@@ -185,6 +189,7 @@ class Program
bool active; bool active;
GLint logicalTextureUnit; GLint logicalTextureUnit;
SamplerType type; SamplerType type;
bool dirty;
}; };
Sampler mSamplers[MAX_TEXTURE_IMAGE_UNITS]; Sampler mSamplers[MAX_TEXTURE_IMAGE_UNITS];
......
...@@ -40,6 +40,7 @@ Texture::Texture(Context *context) : mContext(context) ...@@ -40,6 +40,7 @@ Texture::Texture(Context *context) : mContext(context)
mWrapT = GL_REPEAT; mWrapT = GL_REPEAT;
mDirtyMetaData = true; mDirtyMetaData = true;
mDirty = true;
mIsRenderable = false; mIsRenderable = false;
} }
...@@ -63,8 +64,14 @@ bool Texture::setMinFilter(GLenum filter) ...@@ -63,8 +64,14 @@ bool Texture::setMinFilter(GLenum filter)
case GL_LINEAR_MIPMAP_NEAREST: case GL_LINEAR_MIPMAP_NEAREST:
case GL_NEAREST_MIPMAP_LINEAR: case GL_NEAREST_MIPMAP_LINEAR:
case GL_LINEAR_MIPMAP_LINEAR: case GL_LINEAR_MIPMAP_LINEAR:
mMinFilter = filter; {
return true; if (mMinFilter != filter)
{
mMinFilter = filter;
mDirty = true;
}
return true;
}
default: default:
return false; return false;
} }
...@@ -77,8 +84,14 @@ bool Texture::setMagFilter(GLenum filter) ...@@ -77,8 +84,14 @@ bool Texture::setMagFilter(GLenum filter)
{ {
case GL_NEAREST: case GL_NEAREST:
case GL_LINEAR: case GL_LINEAR:
mMagFilter = filter; {
return true; if (mMagFilter != filter)
{
mMagFilter = filter;
mDirty = true;
}
return true;
}
default: default:
return false; return false;
} }
...@@ -92,8 +105,14 @@ bool Texture::setWrapS(GLenum wrap) ...@@ -92,8 +105,14 @@ bool Texture::setWrapS(GLenum wrap)
case GL_REPEAT: case GL_REPEAT:
case GL_CLAMP_TO_EDGE: case GL_CLAMP_TO_EDGE:
case GL_MIRRORED_REPEAT: case GL_MIRRORED_REPEAT:
mWrapS = wrap; {
return true; if (mWrapS != wrap)
{
mWrapS = wrap;
mDirty = true;
}
return true;
}
default: default:
return false; return false;
} }
...@@ -107,8 +126,14 @@ bool Texture::setWrapT(GLenum wrap) ...@@ -107,8 +126,14 @@ bool Texture::setWrapT(GLenum wrap)
case GL_REPEAT: case GL_REPEAT:
case GL_CLAMP_TO_EDGE: case GL_CLAMP_TO_EDGE:
case GL_MIRRORED_REPEAT: case GL_MIRRORED_REPEAT:
mWrapT = wrap; {
return true; if (mWrapT != wrap)
{
mWrapT = wrap;
mDirty = true;
}
return true;
}
default: default:
return false; return false;
} }
...@@ -352,6 +377,11 @@ IDirect3DBaseTexture9 *Texture::getTexture() ...@@ -352,6 +377,11 @@ IDirect3DBaseTexture9 *Texture::getTexture()
return mBaseTexture; return mBaseTexture;
} }
bool Texture::isDirty() const
{
return (mDirty || mDirtyMetaData || dirtyImageData());
}
// Returns the top-level texture surface as a render target // Returns the top-level texture surface as a render target
void Texture::needRenderTarget() void Texture::needRenderTarget()
{ {
...@@ -384,6 +414,7 @@ void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable) ...@@ -384,6 +414,7 @@ void Texture::pushTexture(IDirect3DBaseTexture9 *newTexture, bool renderable)
mBaseTexture = newTexture; mBaseTexture = newTexture;
mDirtyMetaData = false; mDirtyMetaData = false;
mIsRenderable = renderable; mIsRenderable = renderable;
mDirty = true;
} }
......
...@@ -63,6 +63,8 @@ class Texture ...@@ -63,6 +63,8 @@ class Texture
virtual void generateMipmaps() = 0; virtual void generateMipmaps() = 0;
bool isDirty() const;
protected: protected:
class TextureColorbufferProxy; class TextureColorbufferProxy;
friend class TextureColorbufferProxy; friend class TextureColorbufferProxy;
...@@ -134,6 +136,8 @@ class Texture ...@@ -134,6 +136,8 @@ class Texture
bool mDirtyMetaData; bool mDirtyMetaData;
bool mIsRenderable; bool mIsRenderable;
bool mDirty;
void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, void loadImageData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const; GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
}; };
......
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