Use the texture surfaces as image surfaces when managed.

TRAC #14743 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@875 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 59580a3d
...@@ -30,8 +30,16 @@ namespace gl ...@@ -30,8 +30,16 @@ namespace gl
unsigned int TextureStorage::mCurrentTextureSerial = 1; unsigned int TextureStorage::mCurrentTextureSerial = 1;
Image::Image() Image::Image()
: mWidth(0), mHeight(0), mDirty(false), mSurface(NULL), mFormat(GL_NONE), mType(GL_UNSIGNED_BYTE)
{ {
mWidth = 0;
mHeight = 0;
mFormat = GL_NONE;
mType = GL_UNSIGNED_BYTE;
mSurface = NULL;
mDirty = false;
mManaged = false;
} }
Image::~Image() Image::~Image()
...@@ -216,6 +224,40 @@ IDirect3DSurface9 *Image::getSurface() ...@@ -216,6 +224,40 @@ IDirect3DSurface9 *Image::getSurface()
return mSurface; return mSurface;
} }
void Image::setManagedSurface(IDirect3DSurface9 *surface)
{
if (mSurface)
{
D3DXLoadSurfaceFromSurface(surface, NULL, NULL, mSurface, NULL, NULL, D3DX_FILTER_BOX, 0);
mSurface->Release();
}
mSurface = surface;
mManaged = true;
}
void Image::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height)
{
IDirect3DSurface9 *sourceSurface = getSurface();
if (sourceSurface != destSurface)
{
RECT rect = transformPixelRect(xoffset, yoffset, width, height, mHeight);
if (mManaged)
{
HRESULT result = D3DXLoadSurfaceFromSurface(destSurface, NULL, &rect, sourceSurface, NULL, &rect, D3DX_FILTER_BOX, 0);
ASSERT(SUCCEEDED(result));
}
else
{
POINT point = {rect.left, rect.top};
HRESULT result = getDevice()->UpdateSurface(sourceSurface, &rect, destSurface, &point);
ASSERT(SUCCEEDED(result));
}
}
}
// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input
// into the target pixel rectangle at output with outputPitch bytes in between each line. // into the target pixel rectangle at output with outputPitch bytes in between each line.
void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, void Image::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
...@@ -1200,7 +1242,8 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, ...@@ -1200,7 +1242,8 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
mDirty = true; mDirty = true;
} }
TextureStorage::TextureStorage(bool renderable) : mIsRenderable(renderable), mTextureSerial(issueTextureSerial()) TextureStorage::TextureStorage(bool renderable)
: mRenderable(renderable), mManaged(getDisplay()->getBufferPool(renderable) == D3DPOOL_MANAGED), mTextureSerial(issueTextureSerial())
{ {
} }
...@@ -1210,7 +1253,12 @@ TextureStorage::~TextureStorage() ...@@ -1210,7 +1253,12 @@ TextureStorage::~TextureStorage()
bool TextureStorage::isRenderable() const bool TextureStorage::isRenderable() const
{ {
return mIsRenderable; return mRenderable;
}
bool TextureStorage::isManaged() const
{
return mManaged;
} }
unsigned int TextureStorage::getTextureSerial() const unsigned int TextureStorage::getTextureSerial() const
...@@ -1241,12 +1289,6 @@ Texture::~Texture() ...@@ -1241,12 +1289,6 @@ Texture::~Texture()
{ {
} }
Blit *Texture::getBlitter()
{
Context *context = getContext();
return context->getBlitter();
}
// Returns true on successful filter state update (valid enum parameter) // Returns true on successful filter state update (valid enum parameter)
bool Texture::setMinFilter(GLenum filter) bool Texture::setMinFilter(GLenum filter)
{ {
...@@ -1557,6 +1599,41 @@ int Texture::levelCount() const ...@@ -1557,6 +1599,41 @@ int Texture::levelCount() const
return getBaseTexture() ? getBaseTexture()->GetLevelCount() : 0; return getBaseTexture() ? getBaseTexture()->GetLevelCount() : 0;
} }
Blit *Texture::getBlitter()
{
Context *context = getContext();
return context->getBlitter();
}
bool Texture::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged)
{
if (source && dest)
{
HRESULT result;
if (fromManaged)
{
result = D3DXLoadSurfaceFromSurface(dest, NULL, NULL, source, NULL, NULL, D3DX_FILTER_BOX, 0);
}
else
{
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = display->getDevice();
display->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(IDirect3DTexture9 *surfaceTexture) : TextureStorage(true), mRenderTargetSerial(RenderbufferStorage::issueSerial()) TextureStorage2D::TextureStorage2D(IDirect3DTexture9 *surfaceTexture) : TextureStorage(true), mRenderTargetSerial(RenderbufferStorage::issueSerial())
{ {
mTexture = surfaceTexture; mTexture = surfaceTexture;
...@@ -1748,15 +1825,9 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi ...@@ -1748,15 +1825,9 @@ void Texture2D::commitRect(GLint level, GLint xoffset, GLint yoffset, GLsizei wi
if (destLevel) if (destLevel)
{ {
Image *image = &mImageArray[level]; Image *image = &mImageArray[level];
image->updateSurface(destLevel, xoffset, yoffset, width, height);
RECT sourceRect = transformPixelRect(xoffset, yoffset, width, height, image->getHeight());
POINT destPoint = {sourceRect.left, sourceRect.top};
HRESULT result = getDevice()->UpdateSurface(image->getSurface(), &sourceRect, destLevel, &destPoint);
ASSERT(SUCCEEDED(result));
destLevel->Release(); destLevel->Release();
image->markClean(); image->markClean();
} }
} }
...@@ -2005,9 +2076,21 @@ void Texture2D::createTexture() ...@@ -2005,9 +2076,21 @@ void Texture2D::createTexture()
GLsizei height = mImageArray[0].getHeight(); GLsizei height = mImageArray[0].getHeight();
GLint levels = creationLevels(width, height); GLint levels = creationLevels(width, height);
D3DFORMAT format = mImageArray[0].getD3DFormat(); D3DFORMAT format = mImageArray[0].getD3DFormat();
bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexture; delete mTexture;
mTexture = new TextureStorage2D(levels, format, width, height, mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); mTexture = new TextureStorage2D(levels, format, width, height, renderable);
if (mTexture->isManaged())
{
int levels = levelCount();
for (int level = 0; level < levels; level++)
{
IDirect3DSurface9 *surface = mTexture->getSurfaceLevel(level);
mImageArray[level].setManagedSurface(surface);
}
}
mDirtyImages = true; mDirtyImages = true;
} }
...@@ -2042,31 +2125,19 @@ void Texture2D::convertToRenderTarget() ...@@ -2042,31 +2125,19 @@ void Texture2D::convertToRenderTarget()
if (mTexture != NULL) if (mTexture != NULL)
{ {
egl::Display *display = getDisplay();
IDirect3DDevice9 *device = display->getDevice();
int levels = levelCount(); int levels = levelCount();
for (int i = 0; i < levels; i++) for (int i = 0; i < levels; i++)
{ {
IDirect3DSurface9 *source = mTexture->getSurfaceLevel(i); IDirect3DSurface9 *source = mTexture->getSurfaceLevel(i);
IDirect3DSurface9 *dest = newTexture->getSurfaceLevel(i); IDirect3DSurface9 *dest = newTexture->getSurfaceLevel(i);
if (source && dest) if (!copyToRenderTarget(dest, source, mTexture->isManaged()))
{
display->endScene();
HRESULT result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
if (FAILED(result))
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
delete newTexture; delete newTexture;
source->Release(); source->Release();
dest->Release(); dest->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
}
if (source) source->Release(); if (source) source->Release();
if (dest) dest->Release(); if (dest) dest->Release();
...@@ -2314,15 +2385,9 @@ void TextureCubeMap::commitRect(int face, GLint level, GLint xoffset, GLint yoff ...@@ -2314,15 +2385,9 @@ void TextureCubeMap::commitRect(int face, GLint level, GLint xoffset, GLint yoff
if (destLevel != NULL) if (destLevel != NULL)
{ {
Image *image = &mImageArray[face][level]; Image *image = &mImageArray[face][level];
image->updateSurface(destLevel, xoffset, yoffset, width, height);
RECT sourceRect = transformPixelRect(xoffset, yoffset, width, height, image->getHeight());
POINT destPoint = {sourceRect.left, sourceRect.top};
HRESULT result = getDevice()->UpdateSurface(image->getSurface(), &sourceRect, destLevel, &destPoint);
ASSERT(SUCCEEDED(result));
destLevel->Release(); destLevel->Release();
image->markClean(); image->markClean();
} }
} }
...@@ -2453,9 +2518,24 @@ void TextureCubeMap::createTexture() ...@@ -2453,9 +2518,24 @@ void TextureCubeMap::createTexture()
GLsizei size = mImageArray[0][0].getWidth(); GLsizei size = mImageArray[0][0].getWidth();
GLint levels = creationLevels(size, 0); GLint levels = creationLevels(size, 0);
D3DFORMAT format = mImageArray[0][0].getD3DFormat(); D3DFORMAT format = mImageArray[0][0].getD3DFormat();
bool renderable = (mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE);
delete mTexture; delete mTexture;
mTexture = new TextureStorageCubeMap(levels, format, size, mUsage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE); mTexture = new TextureStorageCubeMap(levels, format, size, renderable);
if (mTexture->isManaged())
{
int levels = levelCount();
for (int face = 0; face < 6; face++)
{
for (int level = 0; level < levels; level++)
{
IDirect3DSurface9 *surface = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level);
mImageArray[face][level].setManagedSurface(surface);
}
}
}
mDirtyImages = true; mDirtyImages = true;
} }
...@@ -2502,22 +2582,13 @@ void TextureCubeMap::convertToRenderTarget() ...@@ -2502,22 +2582,13 @@ void TextureCubeMap::convertToRenderTarget()
IDirect3DSurface9 *source = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i); IDirect3DSurface9 *source = mTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
IDirect3DSurface9 *dest = newTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i); IDirect3DSurface9 *dest = newTexture->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i);
if (source && dest) if (!copyToRenderTarget(dest, source, mTexture->isManaged()))
{
display->endScene();
HRESULT result = device->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE);
if (FAILED(result))
{ {
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
delete newTexture; delete newTexture;
source->Release(); source->Release();
dest->Release(); dest->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
}
if (source) source->Release(); if (source) source->Release();
if (dest) dest->Release(); if (dest) dest->Release();
......
...@@ -66,6 +66,9 @@ class Image ...@@ -66,6 +66,9 @@ class Image
bool isDirty() const {return mSurface && mDirty;} bool isDirty() const {return mSurface && mDirty;}
IDirect3DSurface9 *getSurface(); IDirect3DSurface9 *getSurface();
void setManagedSurface(IDirect3DSurface9 *surface);
void updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height);
void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type, void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum type,
GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const; GLint unpackAlignment, const void *input, std::size_t outputPitch, void *output) const;
...@@ -131,6 +134,7 @@ class Image ...@@ -131,6 +134,7 @@ class Image
GLenum mType; GLenum mType;
bool mDirty; bool mDirty;
bool mManaged;
IDirect3DSurface9 *mSurface; IDirect3DSurface9 *mSurface;
}; };
...@@ -143,13 +147,15 @@ class TextureStorage ...@@ -143,13 +147,15 @@ class TextureStorage
virtual ~TextureStorage(); virtual ~TextureStorage();
bool isRenderable() const; bool isRenderable() const;
bool isManaged() const;
unsigned int getTextureSerial() const; unsigned int getTextureSerial() const;
virtual unsigned int getRenderTargetSerial(GLenum target) const = 0; virtual unsigned int getRenderTargetSerial(GLenum target) const = 0;
private: private:
DISALLOW_COPY_AND_ASSIGN(TextureStorage); DISALLOW_COPY_AND_ASSIGN(TextureStorage);
const bool mIsRenderable; const bool mRenderable;
const bool mManaged;
const unsigned int mTextureSerial; const unsigned int mTextureSerial;
static unsigned int issueTextureSerial(); static unsigned int issueTextureSerial();
...@@ -220,10 +226,11 @@ class Texture : public RefCountObject ...@@ -220,10 +226,11 @@ class Texture : public RefCountObject
virtual void convertToRenderTarget() = 0; virtual void convertToRenderTarget() = 0;
virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0; virtual IDirect3DSurface9 *getRenderTarget(GLenum target) = 0;
Blit *getBlitter();
int levelCount() const; int levelCount() const;
static Blit *getBlitter();
static bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged);
GLenum mMinFilter; GLenum mMinFilter;
GLenum mMagFilter; GLenum mMagFilter;
GLenum mWrapS; GLenum mWrapS;
......
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