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