Alters the blitter's copy function so that you can pass a framebuffer to it directly.

TRAC #21910 Signed-off-by: Daniel Koch git-svn-id: https://angleproject.googlecode.com/svn/branches/dx11proto@1375 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 0ad830bf
......@@ -12,6 +12,7 @@
#include "libGLESv2/main.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/Framebuffer.h"
namespace
{
......@@ -209,9 +210,59 @@ bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
return true;
}
bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
bool Blit::copy(Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level)
{
// D3D9_REPLACE
IDirect3DSurface9 *source = framebuffer->getRenderTarget();
if (!source)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY, false);
}
IDirect3DSurface9 *destSurface = storage->getSurfaceLevel(level, true);
bool result = false;
if (destSurface)
{
result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
destSurface->Release();
}
source->Release();
return result;
}
bool Blit::copy(Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level)
{
// D3D9_REPLACE
IDirect3DSurface9 *source = framebuffer->getRenderTarget();
if (!source)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY, false);
}
IDirect3DSurface9 *destSurface = storage->getCubeMapSurface(target, level, true);
bool result = false;
if (destSurface)
{
result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface);
destSurface->Release();
}
source->Release();
return result;
}
bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest)
{
if (!dest)
{
return false;
}
IDirect3DDevice9 *device = mRenderer->getDevice();
D3DSURFACE_DESC sourceDesc;
......@@ -235,7 +286,6 @@ bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFo
{
return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest);
}
return true;
}
......
......@@ -32,7 +32,8 @@ class Blit
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
bool copy(Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorage2D *storage, GLint level);
bool copy(Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageCubeMap *storage, GLenum target, GLint level);
// Copy from source surface to dest surface.
// sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left)
......@@ -53,6 +54,7 @@ class Blit
bool setFormatConvertShaders(GLenum destFormat);
bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest);
IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect);
void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset);
void setCommonBlitState();
......
......@@ -510,20 +510,12 @@ void Texture2D::subImageCompressed(GLint level, GLint xoffset, GLint yoffset, GL
void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
IDirect3DSurface9 *renderTarget = source->getRenderTarget();
if (!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
GLint internalformat = ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(level, internalformat, width, height);
if (!mImageArray[level].isRenderableFormat())
{
mImageArray[level].copy(0, 0, x, y, width, height, renderTarget);
mImageArray[level].copy(0, 0, x, y, width, height, source);
mDirtyImages = true;
}
else
......@@ -542,18 +534,11 @@ void Texture2D::copyImage(GLint level, GLenum format, GLint x, GLint y, GLsizei
sourceRect.right = x + width;
sourceRect.top = y;
sourceRect.bottom = y + height;
IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level, true);
if (dest)
{
getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest);
dest->Release();
}
getBlitter()->copy(source, sourceRect, format, 0, 0, mTexStorage, level);
}
}
renderTarget->Release();
}
void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
......@@ -563,17 +548,9 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
return error(GL_INVALID_VALUE);
}
IDirect3DSurface9 *renderTarget = source->getRenderTarget();
if (!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
if (!mImageArray[level].isRenderableFormat() || (!mTexStorage && !isSamplerComplete()))
{
mImageArray[level].copy(xoffset, yoffset, x, y, width, height, renderTarget);
mImageArray[level].copy(xoffset, yoffset, x, y, width, height, source);
mDirtyImages = true;
}
else
......@@ -593,19 +570,11 @@ void Texture2D::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yo
sourceRect.top = y;
sourceRect.bottom = y + height;
IDirect3DSurface9 *dest = mTexStorage->getSurfaceLevel(level, true);
if (dest)
{
getBlitter()->copy(renderTarget, sourceRect,
gl::ExtractFormat(mImageArray[0].getInternalFormat()),
xoffset, yoffset, dest);
dest->Release();
}
getBlitter()->copy(source, sourceRect,
gl::ExtractFormat(mImageArray[0].getInternalFormat()),
xoffset, yoffset, mTexStorage, level);
}
}
renderTarget->Release();
}
void Texture2D::storage(GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height)
......@@ -1308,21 +1277,13 @@ void TextureCubeMap::redefineImage(int face, GLint level, GLint internalformat,
void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
IDirect3DSurface9 *renderTarget = source->getRenderTarget();
if (!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
unsigned int faceindex = faceIndex(target);
GLint internalformat = gl::ConvertSizedInternalFormat(format, GL_UNSIGNED_BYTE);
redefineImage(faceindex, level, internalformat, width, height);
if (!mImageArray[faceindex][level].isRenderableFormat())
{
mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget);
mImageArray[faceindex][level].copy(0, 0, x, y, width, height, source);
mDirtyImages = true;
}
else
......@@ -1344,17 +1305,10 @@ void TextureCubeMap::copyImage(GLenum target, GLint level, GLenum format, GLint
sourceRect.top = y;
sourceRect.bottom = y + height;
IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level, true);
getBlitter()->copy(source, sourceRect, format, 0, 0, mTexStorage, target, level);
if (dest)
{
getBlitter()->copy(renderTarget, sourceRect, format, 0, 0, dest);
dest->Release();
}
}
}
renderTarget->Release();
}
void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
......@@ -1366,19 +1320,11 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
return error(GL_INVALID_VALUE);
}
IDirect3DSurface9 *renderTarget = source->getRenderTarget();
if (!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
unsigned int faceindex = faceIndex(target);
if (!mImageArray[faceindex][level].isRenderableFormat() || (!mTexStorage && !isSamplerComplete()))
{
mImageArray[faceindex][level].copy(0, 0, x, y, width, height, renderTarget);
mImageArray[faceindex][level].copy(0, 0, x, y, width, height, source);
mDirtyImages = true;
}
else
......@@ -1398,17 +1344,10 @@ void TextureCubeMap::copySubImage(GLenum target, GLint level, GLint xoffset, GLi
sourceRect.top = y;
sourceRect.bottom = y + height;
IDirect3DSurface9 *dest = mTexStorage->getCubeMapSurface(target, level, true);
getBlitter()->copy(source, sourceRect, gl::ExtractFormat(mImageArray[0][0].getInternalFormat()), xoffset, yoffset, mTexStorage, target, level);
if (dest)
{
getBlitter()->copy(renderTarget, sourceRect, gl::ExtractFormat(mImageArray[0][0].getInternalFormat()), xoffset, yoffset, dest);
dest->Release();
}
}
}
renderTarget->Release();
}
void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size)
......
......@@ -15,6 +15,7 @@
#include "libGLESv2/mathutil.h"
#include "libGLESv2/utilities.h"
#include "libGLESv2/Texture.h"
#include "libGLESv2/Framebuffer.h"
namespace gl
{
......@@ -973,8 +974,16 @@ void Image::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsi
}
// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures
void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget)
void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source)
{
IDirect3DSurface9 *renderTarget = source->getRenderTarget();
if (!renderTarget)
{
ERR("Failed to retrieve the render target.");
return error(GL_OUT_OF_MEMORY);
}
IDirect3DDevice9 *device = getDisplay()->getRenderer()->getDevice(); // D3D9_REPLACE
IDirect3DSurface9 *renderTargetData = NULL;
D3DSURFACE_DESC description;
......@@ -985,6 +994,7 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
if (FAILED(result))
{
ERR("Could not create matching destination surface.");
renderTarget->Release();
return error(GL_OUT_OF_MEMORY);
}
......@@ -994,6 +1004,7 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
{
ERR("GetRenderTargetData unexpectedly failed.");
renderTargetData->Release();
renderTarget->Release();
return error(GL_OUT_OF_MEMORY);
}
......@@ -1007,6 +1018,7 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
{
ERR("Failed to lock the source surface (rectangle might be invalid).");
renderTargetData->Release();
renderTarget->Release();
return error(GL_OUT_OF_MEMORY);
}
......@@ -1018,6 +1030,7 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
ERR("Failed to lock the destination surface (rectangle might be invalid).");
renderTargetData->UnlockRect();
renderTargetData->Release();
renderTarget->Release();
return error(GL_OUT_OF_MEMORY);
}
......@@ -1192,6 +1205,7 @@ void Image::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width,
renderTargetData->UnlockRect();
renderTargetData->Release();
renderTarget->Release();
mDirty = true;
}
......
......@@ -20,6 +20,7 @@ namespace gl
{
class TextureStorage2D;
class TextureStorageCubeMap;
class Framebuffer;
class Image
{
......@@ -97,7 +98,7 @@ class Image
void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height,
const void *input);
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, IDirect3DSurface9 *renderTarget);
void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, Framebuffer *source);
private:
DISALLOW_COPY_AND_ASSIGN(Image);
......
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