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 ...@@ -502,56 +502,12 @@ GLint Texture::creationLevels(GLsizei size) const
return creationLevels(size, size); return creationLevels(size, size);
} }
int Texture::levelCount()
{
return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0;
}
Blit *Texture::getBlitter() Blit *Texture::getBlitter()
{ {
Context *context = getContext(); Context *context = getContext();
return context->getBlitter(); 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) Texture2D::Texture2D(GLuint id) : Texture(id)
{ {
mTexStorage = NULL; mTexStorage = NULL;
...@@ -961,11 +917,6 @@ bool Texture2D::isDepth(GLint level) const ...@@ -961,11 +917,6 @@ bool Texture2D::isDepth(GLint level) const
return IsDepthTexture(getInternalFormat(level)); return IsDepthTexture(getInternalFormat(level));
} }
IDirect3DBaseTexture9 *Texture2D::getBaseTexture() const
{
return mTexStorage ? mTexStorage->getBaseTexture() : NULL;
}
// Constructs a native texture resource from the texture images // Constructs a native texture resource from the texture images
void Texture2D::createTexture() void Texture2D::createTexture()
{ {
...@@ -1026,23 +977,11 @@ void Texture2D::convertToRenderTarget() ...@@ -1026,23 +977,11 @@ void Texture2D::convertToRenderTarget()
if (mTexStorage != NULL) if (mTexStorage != NULL)
{ {
int levels = levelCount(); if (!TextureStorage2D::copyToRenderTarget(newTexStorage, mTexStorage))
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; delete newTexStorage;
if (source) source->Release();
if (dest) dest->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
if (source) source->Release();
if (dest) dest->Release();
}
} }
} }
...@@ -1164,6 +1103,11 @@ IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target) ...@@ -1164,6 +1103,11 @@ IDirect3DSurface9 *Texture2D::getDepthStencil(GLenum target)
return mTexStorage->getSurfaceLevel(0, false); return mTexStorage->getSurfaceLevel(0, false);
} }
int Texture2D::levelCount()
{
return mTexStorage ? mTexStorage->levelCount() - getLodOffset() : 0;
}
TextureStorage *Texture2D::getStorage(bool renderTarget) TextureStorage *Texture2D::getStorage(bool renderTarget)
{ {
if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget())) if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget()))
...@@ -1438,11 +1382,6 @@ bool TextureCubeMap::isCompressed(GLenum target, GLint level) const ...@@ -1438,11 +1382,6 @@ bool TextureCubeMap::isCompressed(GLenum target, GLint level) const
return IsCompressed(getInternalFormat(target, level)); 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 // Constructs a native texture resource from the texture images, or returns an existing one
void TextureCubeMap::createTexture() void TextureCubeMap::createTexture()
{ {
...@@ -1507,26 +1446,11 @@ void TextureCubeMap::convertToRenderTarget() ...@@ -1507,26 +1446,11 @@ void TextureCubeMap::convertToRenderTarget()
if (mTexStorage != NULL) if (mTexStorage != NULL)
{ {
int levels = levelCount(); if (!TextureStorageCubeMap::copyToRenderTarget(newTexStorage, mTexStorage))
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()))
{ {
delete newTexStorage; delete newTexStorage;
if (source) source->Release();
if (dest) dest->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
if (source) source->Release();
if (dest) dest->Release();
}
}
} }
} }
...@@ -1819,6 +1743,11 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target) ...@@ -1819,6 +1743,11 @@ IDirect3DSurface9 *TextureCubeMap::getRenderTarget(GLenum target)
return mTexStorage->getCubeMapSurface(target, 0, false); return mTexStorage->getCubeMapSurface(target, 0, false);
} }
int TextureCubeMap::levelCount()
{
return mTexStorage ? mTexStorage->levelCount() - getLodOffset() : 0;
}
TextureStorage *TextureCubeMap::getStorage(bool renderTarget) TextureStorage *TextureCubeMap::getStorage(bool renderTarget)
{ {
if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget())) if (!mTexStorage || (renderTarget && !mTexStorage->isRenderTarget()))
......
...@@ -111,16 +111,14 @@ class Texture : public RefCountObject ...@@ -111,16 +111,14 @@ class Texture : public RefCountObject
GLint creationLevels(GLsizei width, GLsizei height) const; GLint creationLevels(GLsizei width, GLsizei height) const;
GLint creationLevels(GLsizei size) const; GLint creationLevels(GLsizei size) const;
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual void createTexture() = 0; virtual void createTexture() = 0;
virtual void updateTexture() = 0; virtual void updateTexture() = 0;
virtual void convertToRenderTarget() = 0; virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0; virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
int levelCount(); virtual int levelCount() = 0;
static Blit *getBlitter(); static Blit *getBlitter();
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
SamplerState mSamplerState; SamplerState mSamplerState;
bool mDirtyParameters; bool mDirtyParameters;
...@@ -175,11 +173,11 @@ class Texture2D : public Texture ...@@ -175,11 +173,11 @@ class Texture2D : public Texture
friend class RenderbufferTexture2D; friend class RenderbufferTexture2D;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual IDirect3DSurface9 *getDepthStencil(GLenum target); virtual IDirect3DSurface9 *getDepthStencil(GLenum target);
virtual int levelCount();
private: private:
DISALLOW_COPY_AND_ASSIGN(Texture2D); DISALLOW_COPY_AND_ASSIGN(Texture2D);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture(); virtual void createTexture();
virtual void updateTexture(); virtual void updateTexture();
virtual void convertToRenderTarget(); virtual void convertToRenderTarget();
...@@ -248,11 +246,11 @@ class TextureCubeMap : public Texture ...@@ -248,11 +246,11 @@ class TextureCubeMap : public Texture
protected: protected:
friend class RenderbufferTextureCubeMap; friend class RenderbufferTextureCubeMap;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target); virtual IDirect3DSurface9 *getRenderTarget(GLenum target);
virtual int levelCount();
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureCubeMap); DISALLOW_COPY_AND_ASSIGN(TextureCubeMap);
virtual IDirect3DBaseTexture9 *getBaseTexture() const;
virtual void createTexture(); virtual void createTexture();
virtual void updateTexture(); virtual void updateTexture();
virtual void convertToRenderTarget(); virtual void convertToRenderTarget();
......
...@@ -153,6 +153,50 @@ int TextureStorage::getLodOffset() const ...@@ -153,6 +153,50 @@ int TextureStorage::getLodOffset() const
return mLodOffset; 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()) TextureStorage2D::TextureStorage2D(renderer::SwapChain *swapchain) : TextureStorage(D3DUSAGE_RENDERTARGET), mRenderTargetSerial(RenderbufferStorage::issueSerial())
{ {
IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture(); IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture();
...@@ -189,6 +233,31 @@ TextureStorage2D::~TextureStorage2D() ...@@ -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. // Increments refcount on surface.
// caller must Release() the returned surface // caller must Release() the returned surface
IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty) IDirect3DSurface9 *TextureStorage2D::getSurfaceLevel(int level, bool dirty)
...@@ -251,6 +320,34 @@ TextureStorageCubeMap::~TextureStorageCubeMap() ...@@ -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. // Increments refcount on surface.
// caller must Release() the returned surface // caller must Release() the returned surface
IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty) IDirect3DSurface9 *TextureStorageCubeMap::getCubeMapSurface(GLenum faceTarget, int level, bool dirty)
......
...@@ -44,8 +44,11 @@ class TextureStorage ...@@ -44,8 +44,11 @@ class TextureStorage
virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0; virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
int getLodOffset() const; int getLodOffset() const;
int levelCount();
protected: protected:
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
int mLodOffset; int mLodOffset;
private: private:
...@@ -68,6 +71,8 @@ class TextureStorage2D : public TextureStorage ...@@ -68,6 +71,8 @@ class TextureStorage2D : public TextureStorage
virtual ~TextureStorage2D(); virtual ~TextureStorage2D();
static bool copyToRenderTarget(TextureStorage2D *dest, TextureStorage2D *source);
IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty);
virtual IDirect3DBaseTexture9 *getBaseTexture() const; virtual IDirect3DBaseTexture9 *getBaseTexture() const;
...@@ -87,6 +92,8 @@ class TextureStorageCubeMap : public TextureStorage ...@@ -87,6 +92,8 @@ class TextureStorageCubeMap : public TextureStorage
virtual ~TextureStorageCubeMap(); virtual ~TextureStorageCubeMap();
static bool copyToRenderTarget(TextureStorageCubeMap *dest, TextureStorageCubeMap *source);
IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty);
virtual IDirect3DBaseTexture9 *getBaseTexture() const; 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