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()
{
delete mTexStorage;
mTexStorage = NULL;
deleteImages();
}
void Texture2DArray::deleteImages()
{
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; ++level)
{
for (int layer = 0; layer < mLayerCounts[level]; ++layer)
......@@ -2238,6 +2244,8 @@ Texture2DArray::~Texture2DArray()
delete mImageArray[level][layer];
}
delete[] mImageArray[level];
mImageArray[level] = NULL;
mLayerCounts[level] = 0;
}
}
......@@ -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)
{
delete mTexStorage;
mTexStorage = new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), width, height, depth);
mImmutable = true;
deleteImages();
for (int level = 0; level < IMPLEMENTATION_MAX_TEXTURE_LEVELS; level++)
{
GLsizei levelWidth = std::max(width >> level, 1);
GLsizei levelHeight = std::max(height >> level, 1);
GLsizei levelWidth = std::max(1, width >> level);
GLsizei levelHeight = std::max(1, height >> level);
// Clear this level
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
delete mImageArray[level][layer];
}
delete[] mImageArray[level];
mImageArray[level] = NULL;
mLayerCounts[level] = 0;
mLayerCounts[level] = (level < levels ? depth : 0);
if (level < levels)
if (mLayerCounts[level] > 0)
{
// Create new images for this level
mImageArray[level] = new rx::Image*[depth]();
mLayerCounts[level] = depth;
mImageArray[level] = new rx::Image*[mLayerCounts[level]];
for (int layer = 0; layer < mLayerCounts[level]; layer++)
{
......@@ -2377,18 +2375,8 @@ void Texture2DArray::storage(GLsizei levels, GLenum internalformat, GLsizei widt
}
}
if (mTexStorage->isManaged())
{
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);
}
}
}
mImmutable = true;
setCompleteTexStorage(new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), width, height, depth));
}
void Texture2DArray::generateMipmaps()
......@@ -2585,34 +2573,49 @@ int Texture2DArray::levelCount()
void Texture2DArray::initializeStorage(bool renderTarget)
{
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
// Only initialize the first time this texture is used as a render target or shader resource
if (mTexStorage)
{
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);
GLenum internalformat = getBaseLevelInternalFormat();
bool createRenderTarget = (renderTarget || mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexStorage;
mTexStorage = new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, IsRenderTargetUsage(mUsage), width, height, depth);
setCompleteTexStorage(createCompleteStorage(createRenderTarget));
ASSERT(mTexStorage);
if (mTexStorage->isManaged())
{
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);
}
}
}
// flush image data to the storage
updateStorage();
}
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;
// We do not support managed 2D array storage, as managed storage is ES2/D3D9 only
ASSERT(!mTexStorage->isManaged());
}
void Texture2DArray::updateStorage()
......@@ -2645,38 +2648,25 @@ void Texture2DArray::updateStorageLevel(int level)
bool Texture2DArray::ensureRenderTarget()
{
if (mTexStorage && mTexStorage->isRenderTarget())
{
return true;
}
rx::TextureStorageInterface2DArray *newTexStorage = NULL;
GLsizei width = getBaseLevelWidth();
GLsizei height = getBaseLevelHeight();
GLsizei depth = getBaseLevelDepth();
initializeStorage(true);
if (width != 0 && height != 0 && depth != 0)
if (getBaseLevelWidth() > 0 && getBaseLevelHeight() > 0 && getBaseLevelDepth() > 0)
{
GLint levels = mTexStorage != NULL ? mTexStorage->levelCount() : creationLevels(width, height);
GLenum internalformat = getInternalFormat(0);
newTexStorage = new rx::TextureStorageInterface2DArray(mRenderer, levels, internalformat, true, width, height, depth);
if (mTexStorage != NULL)
ASSERT(mTexStorage);
if (!mTexStorage->isRenderTarget())
{
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);
}
setCompleteTexStorage(newRenderTargetStorage);
}
}
delete mTexStorage;
mTexStorage = newTexStorage;
mDirtyImages = true;
return (mTexStorage && mTexStorage->isRenderTarget());
}
......
......@@ -389,12 +389,16 @@ class Texture2DArray : public Texture
DISALLOW_COPY_AND_ASSIGN(Texture2DArray);
virtual void initializeStorage(bool renderTarget);
rx::TextureStorageInterface2DArray *createCompleteStorage(bool renderTarget) const;
void setCompleteTexStorage(rx::TextureStorageInterface2DArray *newCompleteTexStorage);
virtual void updateStorage();
virtual bool ensureRenderTarget();
virtual rx::TextureStorageInterface *getStorage(bool renderTarget);
virtual const rx::Image *getBaseLevelImage() const;
void deleteImages();
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);
......
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