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 MINOR_VERSION 0
#define BUILD_VERSION 0
#define BUILD_REVISION 594
#define BUILD_REVISION 598
#define STRINGIFY(x) #x
#define MACRO_STRINGIFY(x) STRINGIFY(x)
......
......@@ -957,66 +957,77 @@ bool Texture::subImageCompressed(GLint xoffset, GLint yoffset, GLsizei width, GL
return true;
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats
void Texture::copyNonRenderable(Image *image, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
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();
IDirect3DSurface9 *surface = NULL;
IDirect3DSurface9 *renderTargetData = NULL;
D3DSURFACE_DESC 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.");
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.");
surface->Release();
renderTargetData->Release();
return error(GL_OUT_OF_MEMORY);
}
D3DLOCKED_RECT sourceLock = {0};
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))
{
ERR("Failed to lock the source surface (rectangle might be invalid).");
surface->UnlockRect();
surface->Release();
ERR("Copying surfaces unexpectedly failed.");
renderTargetData->Release();
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.");
surface->UnlockRect();
surface->Release();
ERR("Failed to lock the source surface (rectangle might be invalid).");
renderTargetData->Release();
return error(GL_OUT_OF_MEMORY);
}
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);
if (FAILED(result))
{
ERR("Failed to lock the destination surface (rectangle might be invalid).");
surface->UnlockRect();
surface->Release();
renderTargetData->UnlockRect();
renderTargetData->Release();
return error(GL_OUT_OF_MEMORY);
}
......@@ -1117,14 +1128,16 @@ void Texture::copyNonRenderable(Image *image, GLint xoffset, GLint yoffset, GLin
default:
UNREACHABLE();
}
image->dirty = true;
mDirtyImage = true;
}
image->surface->UnlockRect();
surface->UnlockRect();
surface->Release();
renderTargetData->UnlockRect();
}
renderTargetData->Release();
image->dirty = true;
mDirtyImage = true;
}
IDirect3DBaseTexture9 *Texture::getTexture()
......@@ -1357,7 +1370,7 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
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
{
......@@ -1404,7 +1417,7 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
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
{
......@@ -2199,7 +2212,7 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
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
{
......@@ -2265,7 +2278,7 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
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
{
......
......@@ -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);
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);
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 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