Handle sampling from incomplete textures

TRAC #11321 Context owns incomplete textures of each texture type. Also fix completeness determination: check minfilter to see if mipmapping is on. Author: Andrew Lewycky Signed-off-by: Shannon Woods Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/trunk@26 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 416485fb
...@@ -276,6 +276,8 @@ class Context : public State ...@@ -276,6 +276,8 @@ class Context : public State
void detachFramebuffer(GLuint framebuffer); void detachFramebuffer(GLuint framebuffer);
void detachRenderbuffer(GLuint renderbuffer); void detachRenderbuffer(GLuint renderbuffer);
Texture *getIncompleteTexture(SamplerType type);
const egl::Config *const mConfig; const egl::Config *const mConfig;
Texture2D *mTexture2DZero; Texture2D *mTexture2DZero;
...@@ -306,6 +308,8 @@ class Context : public State ...@@ -306,6 +308,8 @@ class Context : public State
BufferBackEnd *mBufferBackEnd; BufferBackEnd *mBufferBackEnd;
VertexDataManager *mVertexDataManager; VertexDataManager *mVertexDataManager;
Texture *mIncompleteTextures[SAMPLER_TYPE_COUNT];
// Recorded errors // Recorded errors
bool mInvalidEnum; bool mInvalidEnum;
bool mInvalidValue; bool mInvalidValue;
......
...@@ -123,6 +123,11 @@ Context::Context(const egl::Config *config) ...@@ -123,6 +123,11 @@ Context::Context(const egl::Config *config)
} }
} }
for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
mIncompleteTextures[type] = NULL;
}
currentProgram = 0; currentProgram = 0;
mBufferBackEnd = NULL; mBufferBackEnd = NULL;
...@@ -139,6 +144,11 @@ Context::~Context() ...@@ -139,6 +144,11 @@ Context::~Context()
{ {
currentProgram = 0; currentProgram = 0;
for (int type = 0; type < SAMPLER_TYPE_COUNT; type++)
{
delete mIncompleteTextures[type];
}
delete mTexture2DZero; delete mTexture2DZero;
delete mTextureCubeMapZero; delete mTextureCubeMapZero;
...@@ -1061,21 +1071,28 @@ void Context::applyTextures() ...@@ -1061,21 +1071,28 @@ void Context::applyTextures()
Texture *texture = getSamplerTexture(textureUnit, textureType); Texture *texture = getSamplerTexture(textureUnit, textureType);
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
{
device->SetTexture(sampler, getIncompleteTexture(textureType)->getTexture());
}
} }
else else
{ {
...@@ -1705,6 +1722,50 @@ void Context::detachRenderbuffer(GLuint renderbuffer) ...@@ -1705,6 +1722,50 @@ void Context::detachRenderbuffer(GLuint renderbuffer)
framebuffer->detachRenderbuffer(renderbuffer); framebuffer->detachRenderbuffer(renderbuffer);
} }
} }
Texture *Context::getIncompleteTexture(SamplerType type)
{
Texture *t = mIncompleteTextures[type];
if (t == NULL)
{
static const GLubyte color[] = { 0, 0, 0, 255 };
switch (type)
{
default:
UNREACHABLE();
// default falls through to SAMPLER_2D
case SAMPLER_2D:
{
Texture2D *incomplete2d = new Texture2D;
incomplete2d->setImage(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
t = incomplete2d;
}
break;
case SAMPLER_CUBE:
{
TextureCubeMap *incompleteCube = new TextureCubeMap;
incompleteCube->setImagePosX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
incompleteCube->setImageNegX(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
incompleteCube->setImagePosY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
incompleteCube->setImageNegY(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
incompleteCube->setImagePosZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
incompleteCube->setImageNegZ(0, GL_RGBA, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, color);
t = incompleteCube;
}
break;
}
mIncompleteTextures[type] = t;
}
return t;
}
} }
extern "C" extern "C"
......
...@@ -391,7 +391,7 @@ bool Texture2D::isComplete() const ...@@ -391,7 +391,7 @@ bool Texture2D::isComplete() const
bool mipmapping; bool mipmapping;
switch (mMagFilter) switch (mMinFilter)
{ {
case GL_NEAREST: case GL_NEAREST:
case GL_LINEAR: case GL_LINEAR:
...@@ -562,7 +562,7 @@ bool TextureCubeMap::isComplete() const ...@@ -562,7 +562,7 @@ bool TextureCubeMap::isComplete() const
bool mipmapping; bool mipmapping;
switch (mMagFilter) switch (mMinFilter)
{ {
case GL_NEAREST: case GL_NEAREST:
case GL_LINEAR: case GL_LINEAR:
......
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