Commit 884a4626 by Jamie Madill

Refactor storage management in Texture2DArray.

TRAC #23976 Signed-off-by: Geoff Lang Signed-off-by: Shannon Woods
parent e664e206
...@@ -2231,6 +2231,12 @@ Texture2DArray::~Texture2DArray() ...@@ -2231,6 +2231,12 @@ Texture2DArray::~Texture2DArray()
{ {
delete mTexStorage; delete mTexStorage;
mTexStorage = NULL; mTexStorage = NULL;
deleteImages();
}
void Texture2DArray::deleteImages()
{
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level) for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
{ {
for (int layer = 0; layer < mLayerCounts[level]; ++layer) for (int layer = 0; layer < mLayerCounts[level]; ++layer)
...@@ -2238,6 +2244,8 @@ Texture2DArray::~Texture2DArray() ...@@ -2238,6 +2244,8 @@ Texture2DArray::~Texture2DArray()
delete mImageArray[level][layer]; delete mImageArray[level][layer];
} }
delete[] mImageArray[level]; delete[] mImageArray[level];
mImageArray[level] = NULL;
mLayerCounts[level] = 0;
} }
} }
...@@ -2344,29 +2352,19 @@ void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffse ...@@ -2344,29 +2352,19 @@ void Texture2DArray::subImageCompressed(GLint level, GLint xoffset, GLint yoffse
void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth) void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth)
{ {
delete mTexStorage; deleteImages();
mTexStorage = new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), width, height, depth);
mImmutable = true;
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++) for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{ {
GLsizei levelWidth = std::max(width >> level, 1); GLsizei levelWidth = std::max(1, width >> level);
GLsizei levelHeight = std::max(height >> level, 1); GLsizei levelHeight = std::max(1, height >> level);
// Clear this level mLayerCounts[level] = (level < levels ? depth : 0);
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
delete mImageArray[level][layer];
}
delete[] mImageArray[level];
mImageArray[level] = NULL;
mLayerCounts[level] = 0;
if (level < levels) if (mLayerCounts[level] > 0)
{ {
// Create new images for this level // Create new images for this level
mImageArray[level] = new rx::Image*[depth](); mImageArray[level] = new rx::Image*[mLayerCounts[level]];
mLayerCounts[level] = depth;
for (int layer = 0; layer < mLayerCounts[level]; layer++) for (int layer = 0; layer < mLayerCounts[level]; layer++)
{ {
...@@ -2377,18 +2375,8 @@ void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei widt ...@@ -2377,18 +2375,8 @@ void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei widt
} }
} }
if (mTexStorage->isManaged()) mImmutable = true;
{ setCompleteTexStorage(new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), width, height, depth));
int levels = levelCount();
for (int level = 0; level < levels; level++)
{
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
mImageArray[level][layer]->setManagedSurface(mTexStorage, layer, level);
}
}
}
} }
void Texture2DArray::generateMipmaps() void Texture2DArray::generateMipmaps()
...@@ -2585,34 +2573,49 @@ int Texture2DArray::levelCount() ...@@ -2585,34 +2573,49 @@ int Texture2DArray::levelCount()
void Texture2DArray::initializeStorage(bool renderTarget) void Texture2DArray::initializeStorage(bool renderTarget)
{ {
GLsizei width = getBaseLevelWidth(); // Only initialize the first time this texture is used as a render target or shader resource
GLsizei height = getBaseLevelHeight(); if (mTexStorage)
GLsizei depth = getBaseLevelDepth(); {
return;
}
if (width <= 0 || height <= 0 || depth <= 0) // do not attempt to create storage for nonexistant data
if (!isLevelComplete(0))
{ {
return; // do not attempt to create native textures for nonexistant data return;
} }
GLint levels = creationLevels(width, height); bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
GLenum internalformat = getBaseLevelInternalFormat();
delete mTexStorage; setCompleteTexStorage(createCompleteStorage(createRenderTarget));
mTexStorage = new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), width, height, depth); ASSERT(mTexStorage);
if (mTexStorage->isManaged()) // flush image data to the storage
{ updateStorage();
int levels = levelCount(); }
for (int level = 0; level < levels; level++)
{
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
mImageArray[level][layer]->setManagedSurface(mTexStorage, layer, level);
}
}
}
rx::TextureStorageInterface2DArray *Texture2DArray::createCompleteStorage(bool renderTarget) const
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
ASSERT(width > 0 && height > 0 && depth > 0);
// use existing storage level count, when previously specified by TexStorage*D
GLint levels = (mTexStorage ? mTexStorage->levelCount() : creationLevels(width, height));
return new rx::TextureStorageInterface2DArray(mRenderer, levels, getBaseLevelInternalFormat(), renderTarget, width, height, depth);
}
void Texture2DArray::setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage)
{
SafeDelete(mTexStorage);
mTexStorage = newCompleteTexStorage;
mDirtyImages = true; mDirtyImages = true;
// We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
ASSERT(!mTexStorage->isManaged());
} }
void Texture2DArray::updateStorage() void Texture2DArray::updateStorage()
...@@ -2645,38 +2648,25 @@ void Texture2DArray::updateStorageLevel(int level) ...@@ -2645,38 +2648,25 @@ void Texture2DArray::updateStorageLevel(int level)
bool Texture2DArray::ensureRenderTarget() bool Texture2DArray::ensureRenderTarget()
{ {
if (mTexStorage && mTexStorage->isRenderTarget()) initializeStorage(true);
{
return true;
}
rx::TextureStorageInterface2DArray *newTexStorage = NULL;
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
if (width != 0 && height != 0 && depth != 0) if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
{ {
GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(width, height); ASSERT(mTexStorage);
GLenum internalformat = getInternalFormat(0); if (!mTexStorage->isRenderTarget())
newTexStorage = new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, true, width, height, depth);
if (mTexStorage != NULL)
{ {
if (!mRenderer->copyToRenderTarget(newTexStorage, mTexStorage)) rx::TextureStorageInterface2DArray *newRenderTargetStorage = createCompleteStorage(true);
if (!mRenderer->copyToRenderTarget(newRenderTargetStorage, mTexStorage))
{ {
delete newTexStorage; delete newRenderTargetStorage;
return gl::error(GL_OUT_OF_MEMORY, false); return gl::error(GL_OUT_OF_MEMORY, false);
} }
setCompleteTexStorage(newRenderTargetStorage);
} }
} }
delete mTexStorage;
mTexStorage = newTexStorage;
mDirtyImages = true;
return (mTexStorage && mTexStorage->isRenderTarget()); return (mTexStorage && mTexStorage->isRenderTarget());
} }
......
...@@ -389,12 +389,16 @@ class Texture2DArray : public Texture ...@@ -389,12 +389,16 @@ class Texture2DArray : public Texture
DISALLOW_COPY_AND_ASSIGN(Texture2DArray); DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
virtual void initializeStorage(bool renderTarget); virtual void initializeStorage(bool renderTarget);
rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage);
virtual void updateStorage(); virtual void updateStorage();
virtual bool ensureRenderTarget(); virtual bool ensureRenderTarget();
virtual rx::TextureStorageInterface *getStorage(bool renderTarget); virtual rx::TextureStorageInterface *getStorage(bool renderTarget);
virtual const rx::Image *getBaseLevelImage() const; virtual const rx::Image *getBaseLevelImage() const;
void deleteImages();
void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth); void redefineImage(GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth);
void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height); void commitRect(GLint level, GLint xoffset, GLint yoffset, GLint layerTarget, GLsizei width, GLsizei height);
......
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