Updated Renderbuffers, Textures and TextureStorageInterface to be aware of render targets which are based on miplevels and layers other than zero.
TRAC #23470
Signed-off-by: Jamie Madill
Signed-off-by: Shannon Woods
Author: Geoff Lang
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index cf247fc..425dee9 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -73,6 +73,16 @@
return mTarget;
}
+void Texture::addProxyRef(const Renderbuffer *proxy)
+{
+ mRenderbufferProxies.addRef(proxy);
+}
+
+void Texture::releaseProxy(const Renderbuffer *proxy)
+{
+ mRenderbufferProxies.release(proxy);
+}
+
// Returns true on successful filter state update (valid enum parameter)
bool Texture::setMinFilter(GLenum filter)
{
@@ -330,12 +340,6 @@
return texture ? texture->getTextureSerial() : 0;
}
-unsigned int Texture::getRenderTargetSerial(GLenum target)
-{
- rx::TextureStorageInterface *texture = getStorage(true);
- return texture ? texture->getRenderTargetSerial(target) : 0;
-}
-
bool Texture::isImmutable() const
{
return mImmutable;
@@ -369,8 +373,6 @@
{
mTexStorage = NULL;
mSurface = NULL;
- mColorbufferProxy = NULL;
- mProxyRefs = 0;
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
@@ -380,8 +382,6 @@
Texture2D::~Texture2D()
{
- mColorbufferProxy = NULL;
-
delete mTexStorage;
mTexStorage = NULL;
@@ -397,23 +397,6 @@
}
}
-// We need to maintain a count of references to renderbuffers acting as
-// proxies for this texture, so that we do not attempt to use a pointer
-// to a renderbuffer proxy which has been deleted.
-void Texture2D::addProxyRef(const Renderbuffer *proxy)
-{
- mProxyRefs++;
-}
-
-void Texture2D::releaseProxy(const Renderbuffer *proxy)
-{
- if (mProxyRefs > 0)
- mProxyRefs--;
-
- if (mProxyRefs == 0)
- mColorbufferProxy = NULL;
-}
-
GLsizei Texture2D::getWidth(GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -919,25 +902,30 @@
}
}
-Renderbuffer *Texture2D::getRenderbuffer(GLenum target)
+Renderbuffer *Texture2D::getRenderbuffer(GLint level)
{
- if (target != GL_TEXTURE_2D)
+ Renderbuffer *renderBuffer = mRenderbufferProxies.get(level, 0);
+ if (!renderBuffer)
{
- return gl::error(GL_INVALID_OPERATION, (Renderbuffer *)NULL);
+ renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2D(this, level));
+ mRenderbufferProxies.add(level, 0, renderBuffer);
}
- if (mColorbufferProxy == NULL)
- {
- mColorbufferProxy = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2D(this, target));
- }
-
- return mColorbufferProxy;
+ return renderBuffer;
}
-rx::RenderTarget *Texture2D::getRenderTarget(GLenum target)
+unsigned int Texture2D::getRenderTargetSerial(GLint level)
{
- ASSERT(target == GL_TEXTURE_2D);
+ if (!mTexStorage || !mTexStorage->isRenderTarget())
+ {
+ convertToRenderTarget();
+ }
+ return mTexStorage ? mTexStorage->getRenderTargetSerial(level) : 0;
+}
+
+rx::RenderTarget *Texture2D::getRenderTarget(GLint level)
+{
// ensure the underlying texture is created
if (getStorage(true) == NULL)
{
@@ -945,20 +933,18 @@
}
updateTexture();
-
+
// ensure this is NOT a depth texture
- if (isDepth(0))
+ if (isDepth(level))
{
return NULL;
}
- return mTexStorage->getRenderTarget();
+ return mTexStorage->getRenderTarget(level);
}
-rx::RenderTarget *Texture2D::getDepthStencil(GLenum target)
+rx::RenderTarget *Texture2D::getDepthSencil(GLint level)
{
- ASSERT(target == GL_TEXTURE_2D);
-
// ensure the underlying texture is created
if (getStorage(true) == NULL)
{
@@ -968,11 +954,12 @@
updateTexture();
// ensure this is actually a depth texture
- if (!isDepth(0))
+ if (!isDepth(level))
{
return NULL;
}
- return mTexStorage->getRenderTarget();
+
+ return mTexStorage->getRenderTarget(level);
}
int Texture2D::levelCount()
@@ -1002,9 +989,6 @@
mTexStorage = NULL;
for (int i = 0; i < 6; i++)
{
- mFaceProxies[i] = NULL;
- mFaceProxyRefs[i] = 0;
-
for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
{
mImageArray[i][j] = renderer->createImage();
@@ -1016,8 +1000,6 @@
{
for (int i = 0; i < 6; i++)
{
- mFaceProxies[i] = NULL;
-
for (int j = 0; j < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++j)
{
delete mImageArray[i][j];
@@ -1028,35 +1010,6 @@
mTexStorage = NULL;
}
-// We need to maintain a count of references to renderbuffers acting as
-// proxies for this texture, so that the texture is not deleted while
-// proxy references still exist. If the reference count drops to zero,
-// we set our proxy pointer NULL, so that a new attempt at referencing
-// will cause recreation.
-void TextureCubeMap::addProxyRef(const Renderbuffer *proxy)
-{
- for (int i = 0; i < 6; i++)
- {
- if (mFaceProxies[i] == proxy)
- mFaceProxyRefs[i]++;
- }
-}
-
-void TextureCubeMap::releaseProxy(const Renderbuffer *proxy)
-{
- for (int i = 0; i < 6; i++)
- {
- if (mFaceProxies[i] == proxy)
- {
- if (mFaceProxyRefs[i] > 0)
- mFaceProxyRefs[i]--;
-
- if (mFaceProxyRefs[i] == 0)
- mFaceProxies[i] = NULL;
- }
- }
-}
-
GLsizei TextureCubeMap::getWidth(GLenum target, GLint level) const
{
if (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS)
@@ -1288,6 +1241,11 @@
return IsFormatCompressed(getInternalFormat(target, level), mRenderer->getCurrentClientVersion());
}
+bool TextureCubeMap::isDepth(GLenum target, GLint level) const
+{
+ return GetDepthBits(getInternalFormat(target, level), mRenderer->getCurrentClientVersion()) > 0;
+}
+
// Constructs a native texture resource from the texture images, or returns an existing one
void TextureCubeMap::createTexture()
{
@@ -1596,7 +1554,7 @@
}
}
-Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target)
+Renderbuffer *TextureCubeMap::getRenderbuffer(GLenum target, GLint level)
{
if (!IsCubemapTextureTarget(target))
{
@@ -1605,15 +1563,27 @@
unsigned int face = faceIndex(target);
- if (mFaceProxies[face] == NULL)
+ Renderbuffer *renderBuffer = mRenderbufferProxies.get(level, face);
+ if (!renderBuffer)
{
- mFaceProxies[face] = new Renderbuffer(mRenderer, id(), new RenderbufferTextureCubeMap(this, target));
+ renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTextureCubeMap(this, target, level));
+ mRenderbufferProxies.add(level, face, renderBuffer);
}
- return mFaceProxies[face];
+ return renderBuffer;
}
-rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target)
+unsigned int TextureCubeMap::getRenderTargetSerial(GLenum faceTarget, GLint level)
+{
+ if (!mTexStorage || !mTexStorage->isRenderTarget())
+ {
+ convertToRenderTarget();
+ }
+
+ return mTexStorage ? mTexStorage->getRenderTargetSerial(faceTarget, level) : 0;
+}
+
+rx::RenderTarget *TextureCubeMap::getRenderTarget(GLenum target, GLint level)
{
ASSERT(IsCubemapTextureTarget(target));
@@ -1624,8 +1594,35 @@
}
updateTexture();
-
- return mTexStorage->getRenderTarget(target);
+
+ // ensure this is NOT a depth texture
+ if (isDepth(target, level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(target, level);
+}
+
+rx::RenderTarget *TextureCubeMap::getDepthStencil(GLenum target, GLint level)
+{
+ ASSERT(IsCubemapTextureTarget(target));
+
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is a depth texture
+ if (!isDepth(target, level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(target, level);
}
int TextureCubeMap::levelCount()
@@ -1653,8 +1650,6 @@
Texture3D::Texture3D(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_3D)
{
mTexStorage = NULL;
- mColorbufferProxy = NULL;
- mProxyRefs = 0;
for (int i = 0; i < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++i)
{
@@ -1664,8 +1659,6 @@
Texture3D::~Texture3D()
{
- mColorbufferProxy = NULL;
-
delete mTexStorage;
mTexStorage = NULL;
@@ -1675,20 +1668,6 @@
}
}
-void Texture3D::addProxyRef(const Renderbuffer *proxy)
-{
- mProxyRefs++;
-}
-
-void Texture3D::releaseProxy(const Renderbuffer *proxy)
-{
- if (mProxyRefs > 0)
- mProxyRefs--;
-
- if (mProxyRefs == 0)
- mColorbufferProxy = NULL;
-}
-
GLsizei Texture3D::getWidth(GLint level) const
{
return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS) ? mImageArray[level]->getWidth() : 0;
@@ -1958,10 +1937,27 @@
return true;
}
-Renderbuffer *Texture3D::getRenderbuffer(GLenum target)
+Renderbuffer *Texture3D::getRenderbuffer(GLint level, GLint layer)
{
- UNIMPLEMENTED();
- return NULL;
+ Renderbuffer *renderBuffer = mRenderbufferProxies.get(level, layer);
+ if (!renderBuffer)
+ {
+ UNIMPLEMENTED();
+ //renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture3DLayer(this, level, layer));
+ //mRenderbufferProxies.add(level, 0, renderBuffer);
+ }
+
+ return renderBuffer;
+}
+
+unsigned int Texture3D::getRenderTargetSerial(GLint level, GLint layer)
+{
+ if (!mTexStorage || !mTexStorage->isRenderTarget())
+ {
+ convertToRenderTarget();
+ }
+
+ return mTexStorage ? mTexStorage->getRenderTargetSerial(level, layer) : 0;
}
int Texture3D::levelCount()
@@ -2049,10 +2045,42 @@
mDirtyImages = true;
}
-rx::RenderTarget *Texture3D::getRenderTarget(GLenum target)
+rx::RenderTarget *Texture3D::getRenderTarget(GLint level, GLint layer)
{
- UNIMPLEMENTED();
- return NULL;
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is NOT a depth texture
+ if (isDepth(level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(level, layer);
+}
+
+rx::RenderTarget *Texture3D::getDepthStencil(GLint level, GLint layer)
+{
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is a depth texture
+ if (!isDepth(level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(level, layer);
}
rx::TextureStorageInterface *Texture3D::getStorage(bool renderTarget)
@@ -2119,8 +2147,6 @@
Texture2DArray::Texture2DArray(rx::Renderer *renderer, GLuint id) : Texture(renderer, id, GL_TEXTURE_2D_ARRAY)
{
mTexStorage = NULL;
- mColorbufferProxy = NULL;
- mProxyRefs = 0;
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
{
@@ -2131,8 +2157,6 @@
Texture2DArray::~Texture2DArray()
{
- mColorbufferProxy = NULL;
-
delete mTexStorage;
mTexStorage = NULL;
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
@@ -2145,20 +2169,6 @@
}
}
-void Texture2DArray::addProxyRef(const Renderbuffer *proxy)
-{
- mProxyRefs++;
-}
-
-void Texture2DArray::releaseProxy(const Renderbuffer *proxy)
-{
- if (mProxyRefs > 0)
- mProxyRefs--;
-
- if (mProxyRefs == 0)
- mColorbufferProxy = NULL;
-}
-
GLsizei Texture2DArray::getWidth(GLint level) const
{
return (level < IMPLEMENTATION_MAX_TEXTURE_LEVELS && mLayerCounts[level] > 0) ? mImageArray[level][0]->getWidth() : 0;
@@ -2475,10 +2485,27 @@
return true;
}
-Renderbuffer *Texture2DArray::getRenderbuffer(GLenum target)
+Renderbuffer *Texture2DArray::getRenderbuffer(GLint level, GLint layer)
{
- UNIMPLEMENTED();
- return NULL;
+ Renderbuffer *renderBuffer = mRenderbufferProxies.get(level, layer);
+ if (!renderBuffer)
+ {
+ UNIMPLEMENTED();
+ //renderBuffer = new Renderbuffer(mRenderer, id(), new RenderbufferTexture2DArrayLayer(this, level, layer));
+ //mRenderbufferProxies.add(level, 0, renderBuffer);
+ }
+
+ return renderBuffer;
+}
+
+unsigned int Texture2DArray::getRenderTargetSerial( GLint level, GLint layer )
+{
+ if (!mTexStorage || !mTexStorage->isRenderTarget())
+ {
+ convertToRenderTarget();
+ }
+
+ return mTexStorage ? mTexStorage->getRenderTargetSerial(level, layer) : 0;
}
int Texture2DArray::levelCount()
@@ -2571,10 +2598,42 @@
mDirtyImages = true;
}
-rx::RenderTarget *Texture2DArray::getRenderTarget(GLenum target)
+rx::RenderTarget *Texture2DArray::getRenderTarget(GLint level, GLint layer)
{
- UNIMPLEMENTED();
- return NULL;
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is NOT a depth texture
+ if (isDepth(level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(level, layer);
+}
+
+rx::RenderTarget *Texture2DArray::getDepthStencil(GLint level, GLint layer)
+{
+ // ensure the underlying texture is created
+ if (getStorage(true) == NULL)
+ {
+ return NULL;
+ }
+
+ updateTexture();
+
+ // ensure this is a depth texture
+ if (!isDepth(level))
+ {
+ return NULL;
+ }
+
+ return mTexStorage->getRenderTarget(level, layer);
}
rx::TextureStorageInterface *Texture2DArray::getStorage(bool renderTarget)