Moves copyToRenderTarget operation into texture storage object.
TRAC #21910
Signed-off-by: Daniel Koch
Author: Shannon Woods
git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1373 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/libGLESv2/Texture.cpp b/src/libGLESv2/Texture.cpp
index 555590b..a23fcdc 100644
--- a/src/libGLESv2/Texture.cpp
+++ b/src/libGLESv2/Texture.cpp
@@ -502,56 +502,12 @@
return creationLevels(size, size);
}
-int Texture::levelCount()
-{
- return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
-}
-
Blit *Texture::getBlitter()
{
Context *context = getContext();
return context->getBlitter();
}
-bool Texture::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
-{
- if (source && dest)
- {
- HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
- renderer::Renderer9 *renderer = getDisplay()->getRenderer();
- IDirect3DDevice9 *device = renderer->getDevice(); // D3D9_REPLACE
-
- if (fromManaged)
- {
- D3DSURFACE_DESC desc;
- source->GetDesc(&desc);
-
- IDirect3DSurface9 *surf = 0;
- result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
-
- if (SUCCEEDED(result))
- {
- Image::CopyLockableSurfaces(surf, source);
- result = device->UpdateSurface(surf, NULL, dest, NULL);
- surf->Release();
- }
- }
- else
- {
- renderer->endScene();
- result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
- }
-
- if (FAILED(result))
- {
- ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return false;
- }
- }
-
- return true;
-}
-
Texture2D::Texture2D(GLuint id) : Texture(id)
{
mTexStorage = NULL;
@@ -961,11 +917,6 @@
return IsDepthTexture(getInternalFormat(level));
}
-IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const
-{
- return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
-}
-
// Constructs a native texture resource from the texture images
void Texture2D::createTexture()
{
@@ -1026,22 +977,10 @@
if (mTexStorage != NULL)
{
- int levels = levelCount();
- for (int i = 0; i < levels; i++)
- {
- IDirect3DSurface9 *source = mTexStorage->getSurfaceLevel(i, false);
- IDirect3DSurface9 *dest = newTexStorage->getSurfaceLevel(i, true);
-
- if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
- {
- delete newTexStorage;
- if (source) source->Release();
- if (dest) dest->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- if (source) source->Release();
- if (dest) dest->Release();
+ if (!TextureStorage2D::copyToRenderTarget(newTexStorage, mTexStorage))
+ {
+ delete newTexStorage;
+ return error(GL_OUT_OF_MEMORY);
}
}
}
@@ -1164,6 +1103,11 @@
return mTexStorage->getSurfaceLevel(0, false);
}
+int Texture2D::levelCount()
+{
+ return mTexStorage ? mTexStorage->levelCount() - getLodOffset() : 0;
+}
+
TextureStorage *Texture2D::getStorage(bool renderTarget)
{
if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget()))
@@ -1438,11 +1382,6 @@
return IsCompressed(getInternalFormat(target, level));
}
-IDirect3DBaseTexture9 *TextureCubeMap::getBaseTexture() const
-{
- return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
-}
-
// Constructs a native texture resource from the texture images, or returns an existing one
void TextureCubeMap::createTexture()
{
@@ -1507,25 +1446,10 @@
if (mTexStorage != NULL)
{
- int levels = levelCount();
- for (int f = 0; f < 6; f++)
+ if (!TextureStorageCubeMap::copyToRenderTarget(newTexStorage, mTexStorage))
{
- for (int i = 0; i < levels; i++)
- {
- IDirect3DSurface9 *source = mTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
- IDirect3DSurface9 *dest = newTexStorage->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
-
- if (!copyToRenderTarget(dest, source, mTexStorage->isManaged()))
- {
- delete newTexStorage;
- if (source) source->Release();
- if (dest) dest->Release();
- return error(GL_OUT_OF_MEMORY);
- }
-
- if (source) source->Release();
- if (dest) dest->Release();
- }
+ delete newTexStorage;
+ return error(GL_OUT_OF_MEMORY);
}
}
}
@@ -1819,6 +1743,11 @@
return mTexStorage->getCubeMapSurface(target, 0, false);
}
+int TextureCubeMap::levelCount()
+{
+ return mTexStorage ? mTexStorage->levelCount() - getLodOffset() : 0;
+}
+
TextureStorage *TextureCubeMap::getStorage(bool renderTarget)
{
if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget()))
diff --git a/src/libGLESv2/Texture.h b/src/libGLESv2/Texture.h
index 02c8652..0efedfa 100644
--- a/src/libGLESv2/Texture.h
+++ b/src/libGLESv2/Texture.h
@@ -111,16 +111,14 @@
GLint creationLevels(GLsizei width, GLsizei height) const;
GLint creationLevels(GLsizei size) const;
- virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual void createTexture() = 0;
virtual void updateTexture() = 0;
virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
- int levelCount();
+ virtual int levelCount() = 0;
static Blit *getBlitter();
- static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
SamplerState mSamplerState;
bool mDirtyParameters;
@@ -175,11 +173,11 @@
friend class RenderbufferTexture2D;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
+ virtual int levelCount();
private:
DISALLOW_COPY_AND_ASSIGN(Texture2D);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
@@ -248,11 +246,11 @@
protected:
friend class RenderbufferTextureCubeMap;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
+ virtual int levelCount();
private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
- virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture();
virtual void updateTexture();
virtual void convertToRenderTarget();
diff --git a/src/libGLESv2/renderer/TextureStorage.cpp b/src/libGLESv2/renderer/TextureStorage.cpp
index 2b10ae8..a2afc3c 100644
--- a/src/libGLESv2/renderer/TextureStorage.cpp
+++ b/src/libGLESv2/renderer/TextureStorage.cpp
@@ -153,6 +153,50 @@
return mLodOffset;
}
+int TextureStorage::levelCount()
+{
+ return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
+}
+
+bool TextureStorage::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
+{
+ if (source && dest)
+ {
+ HRESULT result = D3DERR_OUTOFVIDEOMEMORY;
+ renderer::Renderer9 *renderer = getDisplay()->getRenderer();
+ IDirect3DDevice9 *device = renderer->getDevice(); // D3D9_REPLACE
+
+ if (fromManaged)
+ {
+ D3DSURFACE_DESC desc;
+ source->GetDesc(&desc);
+
+ IDirect3DSurface9 *surf = 0;
+ result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL);
+
+ if (SUCCEEDED(result))
+ {
+ Image::CopyLockableSurfaces(surf, source);
+ result = device->UpdateSurface(surf, NULL, dest, NULL);
+ surf->Release();
+ }
+ }
+ else
+ {
+ renderer->endScene();
+ result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
+ }
+
+ if (FAILED(result))
+ {
+ ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
+ return false;
+ }
+ }
+
+ return true;
+}
+
TextureStorage2D::TextureStorage2D(renderer::SwapChain *swapchain) : TextureStorage(D3DUSAGE_RENDERTARGET), mRenderTargetSerial(RenderbufferStorage::issueSerial())
{
IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
@@ -189,6 +233,31 @@
}
}
+bool TextureStorage2D::copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source)
+{
+ bool result = false;
+
+ if (source && dest)
+ {
+ int levels = source->levelCount();
+ for (int i = 0; i < levels; ++i)
+ {
+ IDirect3DSurface9 *srcSurf = source->getSurfaceLevel(i, false);
+ IDirect3DSurface9 *dstSurf = dest->getSurfaceLevel(i, false);
+
+ result = TextureStorage::copyToRenderTarget(dstSurf, srcSurf, source->isManaged());
+
+ if (srcSurf) srcSurf->Release();
+ if (dstSurf) dstSurf->Release();
+
+ if (!result)
+ return false;
+ }
+ }
+
+ return result;
+}
+
// Increments refcount on surface.
// caller must Release() the returned surface
IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty)
@@ -251,6 +320,34 @@
}
}
+bool TextureStorageCubeMap::copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source)
+{
+ bool result = false;
+
+ if (source && dest)
+ {
+ int levels = source->levelCount();
+ for (int f = 0; f < 6; f++)
+ {
+ for (int i = 0; i < levels; i++)
+ {
+ IDirect3DSurface9 *srcSurf = source->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false);
+ IDirect3DSurface9 *dstSurf = dest->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true);
+
+ result = TextureStorage::copyToRenderTarget(dstSurf, srcSurf, source->isManaged());
+
+ if (srcSurf) srcSurf->Release();
+ if (dstSurf) dstSurf->Release();
+
+ if (!result)
+ return false;
+ }
+ }
+ }
+
+ return result;
+}
+
// Increments refcount on surface.
// caller must Release() the returned surface
IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
diff --git a/src/libGLESv2/renderer/TextureStorage.h b/src/libGLESv2/renderer/TextureStorage.h
index f0f1a0a..31782e6 100644
--- a/src/libGLESv2/renderer/TextureStorage.h
+++ b/src/libGLESv2/renderer/TextureStorage.h
@@ -44,8 +44,11 @@
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
int getLodOffset() const;
+ int levelCount();
protected:
+ static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
+
int mLodOffset;
private:
@@ -68,6 +71,8 @@
virtual ~TextureStorage2D();
+ static bool copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source);
+
IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
@@ -87,6 +92,8 @@
virtual ~TextureStorageCubeMap();
+ static bool copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source);
+
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;