Use D3DX to copy between renderable texture surfaces.

TRAC #16118 Signed-off-by: Daniel Koch Author: Nicolas Capens git-svn-id: https://angleproject.googlecode.com/svn/trunk@598 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 549bdefe
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 0 #define MINOR_VERSION 0
#define BUILD_VERSION 0 #define BUILD_VERSION 0
#define BUILD_REVISION 594 #define BUILD_REVISION 598
#define STRINGIFY(x) #x #define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x) #define MACRO_STRINGIFY(x) STRINGIFY(x)
......
...@@ -957,66 +957,77 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL ...@@ -957,66 +957,77 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
return true; return true;
} }
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
void Texture::copyNonRenderable(Image *image, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget) void Texture::copyToImage(Image *image, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
{ {
if (!image->surface)
{
createSurface(image);
if (!image->surface)
{
ERR("Failed to create an image surface.");
return error(GL_OUT_OF_MEMORY);
}
}
IDirect3DDevice9 *device = getDevice(); IDirect3DDevice9 *device = getDevice();
IDirect3DSurface9 *surface = NULL; IDirect3DSurface9 *renderTargetData = NULL;
D3DSURFACE_DESC description; D3DSURFACE_DESC description;
renderTarget->GetDesc(&description); renderTarget->GetDesc(&description);
HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &surface, NULL); HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL);
if (!SUCCEEDED(result)) if (FAILED(result))
{ {
ERR("Could not create matching destination surface."); ERR("Could not create matching destination surface.");
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
result = device->GetRenderTargetData(renderTarget, surface); result = device->GetRenderTargetData(renderTarget, renderTargetData);
if (!SUCCEEDED(result)) if (FAILED(result))
{ {
ERR("GetRenderTargetData unexpectedly failed."); ERR("GetRenderTargetData unexpectedly failed.");
surface->Release(); renderTargetData->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
D3DLOCKED_RECT sourceLock = {0};
RECT sourceRect = transformPixelRect(x, y, width, height, description.Height); RECT sourceRect = transformPixelRect(x, y, width, height, description.Height);
result = surface->LockRect(&sourceLock, &sourceRect, 0); int destYOffset = transformPixelYOffset(yoffset, height, image->height);
RECT destRect = {xoffset, destYOffset, xoffset + width, destYOffset + height};
if (image->isRenderable())
{
result = D3DXLoadSurfaceFromSurface(image->surface, NULL, &destRect, renderTargetData, NULL, &sourceRect, D3DX_FILTER_BOX, 0);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to lock the source surface (rectangle might be invalid)."); ERR("Copying surfaces unexpectedly failed.");
surface->UnlockRect(); renderTargetData->Release();
surface->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
if (!image->surface)
{
createSurface(image);
} }
else
{
D3DLOCKED_RECT sourceLock = {0};
result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0);
if (image->surface == NULL) if (FAILED(result))
{ {
ERR("Failed to create an image surface."); ERR("Failed to lock the source surface (rectangle might be invalid).");
surface->UnlockRect(); renderTargetData->Release();
surface->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
D3DLOCKED_RECT destLock = {0}; D3DLOCKED_RECT destLock = {0};
int destYOffset = transformPixelYOffset(yoffset, height, image->height);
RECT destRect = {xoffset, destYOffset, xoffset + width, destYOffset + height};
result = image->surface->LockRect(&destLock, &destRect, 0); result = image->surface->LockRect(&destLock, &destRect, 0);
if (FAILED(result)) if (FAILED(result))
{ {
ERR("Failed to lock the destination surface (rectangle might be invalid)."); ERR("Failed to lock the destination surface (rectangle might be invalid).");
surface->UnlockRect(); renderTargetData->UnlockRect();
surface->Release(); renderTargetData->Release();
return error(GL_OUT_OF_MEMORY); return error(GL_OUT_OF_MEMORY);
} }
...@@ -1117,14 +1128,16 @@ void Texture::copyNonRenderable(Image *image, GLint xoffset, GLint yoffset, GLin ...@@ -1117,14 +1128,16 @@ void Texture::copyNonRenderable(Image *image, GLint xoffset, GLint yoffset, GLin
default: default:
UNREACHABLE(); UNREACHABLE();
} }
image->dirty = true;
mDirtyImage = true;
} }
image->surface->UnlockRect(); image->surface->UnlockRect();
surface->UnlockRect(); renderTargetData->UnlockRect();
surface->Release(); }
renderTargetData->Release();
image->dirty = true;
mDirtyImage = true;
} }
IDirect3DBaseTexture9 *Texture::getTexture() IDirect3DBaseTexture9 *Texture::getTexture()
...@@ -1357,7 +1370,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei ...@@ -1357,7 +1370,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
if (!mImageArray[level].isRenderable()) if (!mImageArray[level].isRenderable())
{ {
copyNonRenderable(&mImageArray[level], 0, 0, x, y, width, height, renderTarget); copyToImage(&mImageArray[level], 0, 0, x, y, width, height, renderTarget);
} }
else else
{ {
...@@ -1404,7 +1417,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo ...@@ -1404,7 +1417,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
if (!mImageArray[level].isRenderable() || (!mTexture && !isComplete())) if (!mImageArray[level].isRenderable() || (!mTexture && !isComplete()))
{ {
copyNonRenderable(&mImageArray[level], xoffset, yoffset, x, y, width, height, renderTarget); copyToImage(&mImageArray[level], xoffset, yoffset, x, y, width, height, renderTarget);
} }
else else
{ {
...@@ -2199,7 +2212,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint ...@@ -2199,7 +2212,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
if (!mImageArray[faceindex][level].isRenderable()) if (!mImageArray[faceindex][level].isRenderable())
{ {
copyNonRenderable(&mImageArray[faceindex][level], 0, 0, x, y, width, height, renderTarget); copyToImage(&mImageArray[faceindex][level], 0, 0, x, y, width, height, renderTarget);
} }
else else
{ {
...@@ -2265,7 +2278,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi ...@@ -2265,7 +2278,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
if (!mImageArray[faceindex][level].isRenderable() || (!mTexture && !isComplete())) if (!mImageArray[faceindex][level].isRenderable() || (!mTexture && !isComplete()))
{ {
copyNonRenderable(&mImageArray[faceindex][level], 0, 0, x, y, width, height, renderTarget); copyToImage(&mImageArray[faceindex][level], 0, 0, x, y, width, height, renderTarget);
} }
else else
{ {
......
...@@ -105,7 +105,7 @@ class Texture : public RefCountObject ...@@ -105,7 +105,7 @@ class Texture : public RefCountObject
bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image); bool subImage(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLint unpackAlignment, const void *pixels, Image *image);
void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image); void setCompressedImage(GLsizei imageSize, const void *pixels, Image *image);
bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image); bool subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *pixels, Image *image);
void copyNonRenderable(Image *image, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget); void copyToImage(Image *image, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const; GLint creationLevels(GLsizei width, GLsizei height, GLint maxlevel) const;
GLint creationLevels(GLsizei size, GLint maxlevel) const; GLint creationLevels(GLsizei size, GLint maxlevel) 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