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
parent 9d4346f0
......@@ -502,56 +502,12 @@ GLint Texture::creationLevels(GLsizei size) const
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 @@ bool Texture2D::isDepth(GLint level) const
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,23 +977,11 @@ void Texture2D::convertToRenderTarget()
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()))
if (!TextureStorage2D::copyToRenderTarget(newTexStorage, mTexStorage))
{
delete newTexStorage;
if (source) source->Release();
if (dest) dest->Release();
return error(GL_OUT_OF_MEMORY);
}
if (source) source->Release();
if (dest) dest->Release();
}
}
}
......@@ -1164,6 +1103,11 @@ IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target)
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 @@ bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
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,26 +1446,11 @@ void TextureCubeMap::convertToRenderTarget()
if (mTexStorage != NULL)
{
int levels = levelCount();
for (int f = 0; f < 6; f++)
{
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()))
if (!TextureStorageCubeMap::copyToRenderTarget(newTexStorage, mTexStorage))
{
delete newTexStorage;
if (source) source->Release();
if (dest) dest->Release();
return error(GL_OUT_OF_MEMORY);
}
if (source) source->Release();
if (dest) dest->Release();
}
}
}
}
......@@ -1819,6 +1743,11 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
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()))
......
......@@ -111,16 +111,14 @@ class Texture : public RefCountObject
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 @@ class Texture2D : public Texture
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 @@ class TextureCubeMap : public Texture
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();
......
......@@ -153,6 +153,50 @@ int TextureStorage::getLodOffset() const
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 @@ TextureStorage2D::~TextureStorage2D()
}
}
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 @@ TextureStorageCubeMap::~TextureStorageCubeMap()
}
}
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)
......
......@@ -44,8 +44,11 @@ class TextureStorage
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 @@ class TextureStorage2D : public TextureStorage
virtual ~TextureStorage2D();
static bool copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source);
IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
......@@ -87,6 +92,8 @@ class TextureStorageCubeMap : public TextureStorage
virtual ~TextureStorageCubeMap();
static bool copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source);
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
......
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