summaryrefslogtreecommitdiffstats
path: root/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp')
-rw-r--r--src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp410
1 files changed, 279 insertions, 131 deletions
diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
index 2ac8ee3a29..36f2bd0db8 100644
--- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
+++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp
@@ -7,6 +7,8 @@
// Blit9.cpp: Surface copy utility class.
#include "libANGLE/renderer/d3d/d3d9/Blit9.h"
+
+#include "libANGLE/renderer/d3d/TextureD3D.h"
#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h"
#include "libANGLE/renderer/d3d/d3d9/formatutils9.h"
#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h"
@@ -20,27 +22,34 @@ namespace
{
// Precompiled shaders
#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/standardvs.h"
-#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/flipyvs.h"
#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/passthroughps.h"
#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminancepremultps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/luminanceunmultps.h"
#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskpremultps.h"
+#include "libANGLE/renderer/d3d/d3d9/shaders/compiled/componentmaskunmultps.h"
-const BYTE* const g_shaderCode[] =
-{
+const BYTE *const g_shaderCode[] = {
g_vs20_standardvs,
- g_vs20_flipyvs,
g_ps20_passthroughps,
g_ps20_luminanceps,
- g_ps20_componentmaskps
+ g_ps20_luminancepremultps,
+ g_ps20_luminanceunmultps,
+ g_ps20_componentmaskps,
+ g_ps20_componentmaskpremultps,
+ g_ps20_componentmaskunmultps,
};
-const size_t g_shaderSize[] =
-{
+const size_t g_shaderSize[] = {
sizeof(g_vs20_standardvs),
- sizeof(g_vs20_flipyvs),
sizeof(g_ps20_passthroughps),
sizeof(g_ps20_luminanceps),
- sizeof(g_ps20_componentmaskps)
+ sizeof(g_ps20_luminancepremultps),
+ sizeof(g_ps20_luminanceunmultps),
+ sizeof(g_ps20_componentmaskps),
+ sizeof(g_ps20_componentmaskpremultps),
+ sizeof(g_ps20_componentmaskunmultps),
};
}
@@ -50,11 +59,11 @@ namespace rx
Blit9::Blit9(Renderer9 *renderer)
: mRenderer(renderer),
mGeometryLoaded(false),
- mQuadVertexBuffer(NULL),
- mQuadVertexDeclaration(NULL),
- mSavedStateBlock(NULL),
- mSavedRenderTarget(NULL),
- mSavedDepthStencil(NULL)
+ mQuadVertexBuffer(nullptr),
+ mQuadVertexDeclaration(nullptr),
+ mSavedStateBlock(nullptr),
+ mSavedRenderTarget(nullptr),
+ mSavedDepthStencil(nullptr)
{
memset(mCompiledShaders, 0, sizeof(mCompiledShaders));
}
@@ -75,7 +84,7 @@ gl::Error Blit9::initialize()
{
if (mGeometryLoaded)
{
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
static const float quad[] =
@@ -88,22 +97,25 @@ gl::Error Blit9::initialize()
IDirect3DDevice9 *device = mRenderer->getDevice();
- HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL);
+ HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0,
+ D3DPOOL_DEFAULT, &mQuadVertexBuffer, nullptr);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal blit vertex shader, result: 0x%X.", result);
+ return gl::OutOfMemory() << "Failed to create internal blit vertex shader, "
+ << gl::FmtHR(result);
}
- void *lockPtr = NULL;
+ void *lockPtr = nullptr;
result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0);
- if (FAILED(result) || lockPtr == NULL)
+ if (FAILED(result) || lockPtr == nullptr)
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(mQuadVertexBuffer);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex shader, result: 0x%X.", result);
+ return gl::OutOfMemory() << "Failed to lock internal blit vertex shader, "
+ << gl::FmtHR(result);
}
memcpy(lockPtr, quad, sizeof(quad));
@@ -121,11 +133,12 @@ gl::Error Blit9::initialize()
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(mQuadVertexBuffer);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal blit vertex declaration, result: 0x%X.", result);
+ return gl::OutOfMemory() << "Failed to lock internal blit vertex declaration, "
+ << gl::FmtHR(result);
}
mGeometryLoaded = true;
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
template <class D3DShaderType>
@@ -137,7 +150,7 @@ gl::Error Blit9::setShader(ShaderId source, const char *profile,
D3DShaderType *shader = nullptr;
- if (mCompiledShaders[source] != NULL)
+ if (mCompiledShaders[source] != nullptr)
{
shader = static_cast<D3DShaderType*>(mCompiledShaders[source]);
}
@@ -145,23 +158,17 @@ gl::Error Blit9::setShader(ShaderId source, const char *profile,
{
const BYTE* shaderCode = g_shaderCode[source];
size_t shaderSize = g_shaderSize[source];
-
- gl::Error error = (mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize, &shader);
- if (error.isError())
- {
- return error;
- }
-
+ ANGLE_TRY((mRenderer->*createShader)(reinterpret_cast<const DWORD*>(shaderCode), shaderSize, &shader));
mCompiledShaders[source] = shader;
}
HRESULT hr = (device->*setShader)(shader);
if (FAILED(hr))
{
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to set shader for blit operation, result: 0x%X.", hr);
+ return gl::OutOfMemory() << "Failed to set shader for blit operation, " << gl::FmtHR(hr);
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
gl::Error Blit9::setVertexShader(ShaderId shader)
@@ -188,20 +195,20 @@ RECT Blit9::getSurfaceRect(IDirect3DSurface9 *surface) const
return rect;
}
+gl::Extents Blit9::getSurfaceSize(IDirect3DSurface9 *surface) const
+{
+ D3DSURFACE_DESC desc;
+ surface->GetDesc(&desc);
+
+ return gl::Extents(desc.Width, desc.Height, 1);
+}
+
gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
{
- gl::Error error = initialize();
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(initialize());
- IDirect3DTexture9 *texture = NULL;
- error = copySurfaceToTexture(source, getSurfaceRect(source), &texture);
- if (error.isError())
- {
- return error;
- }
+ IDirect3DBaseTexture9 *texture = nullptr;
+ ANGLE_TRY(copySurfaceToTexture(source, getSurfaceRect(source), &texture));
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -210,14 +217,15 @@ gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
device->SetTexture(0, texture);
device->SetRenderTarget(0, dest);
- setVertexShader(SHADER_VS_STANDARD);
- setPixelShader(SHADER_PS_PASSTHROUGH);
+ ANGLE_TRY(setVertexShader(SHADER_VS_STANDARD));
+ ANGLE_TRY(setPixelShader(SHADER_PS_PASSTHROUGH));
setCommonBlitState();
device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR);
device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR);
- setViewport(getSurfaceRect(dest), gl::Offset(0, 0, 0));
+ setViewportAndShaderConstants(getSurfaceRect(source), getSurfaceSize(source),
+ getSurfaceRect(dest), false);
render();
@@ -225,34 +233,32 @@ gl::Error Blit9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest)
restoreState();
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
-gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level)
+gl::Error Blit9::copy2D(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLint level)
{
- gl::Error error = initialize();
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(initialize());
const gl::FramebufferAttachment *colorbuffer = framebuffer->getColorbuffer(0);
ASSERT(colorbuffer);
RenderTarget9 *renderTarget9 = nullptr;
- error = colorbuffer->getRenderTarget(&renderTarget9);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget9));
ASSERT(renderTarget9);
IDirect3DSurface9 *source = renderTarget9->getSurface();
ASSERT(source);
- IDirect3DSurface9 *destSurface = NULL;
+ IDirect3DSurface9 *destSurface = nullptr;
TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
- error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, true, &destSurface);
+ gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_2D, level, true, &destSurface);
if (error.isError())
{
SafeRelease(source);
@@ -260,7 +266,8 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe
}
ASSERT(destSurface);
- gl::Error result = copy(source, sourceRect, destFormat, destOffset, destSurface);
+ gl::Error result =
+ copy(source, nullptr, sourceRect, destFormat, destOffset, destSurface, false, false, false);
SafeRelease(destSurface);
SafeRelease(source);
@@ -268,7 +275,14 @@ gl::Error Blit9::copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRe
return result;
}
-gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level)
+gl::Error Blit9::copyCube(const gl::Context *context,
+ const gl::Framebuffer *framebuffer,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLenum target,
+ GLint level)
{
gl::Error error = initialize();
if (error.isError())
@@ -280,7 +294,7 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source
ASSERT(colorbuffer);
RenderTarget9 *renderTarget9 = nullptr;
- error = colorbuffer->getRenderTarget(&renderTarget9);
+ error = colorbuffer->getRenderTarget(context, &renderTarget9);
if (error.isError())
{
return error;
@@ -290,9 +304,9 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source
IDirect3DSurface9 *source = renderTarget9->getSurface();
ASSERT(source);
- IDirect3DSurface9 *destSurface = NULL;
+ IDirect3DSurface9 *destSurface = nullptr;
TextureStorage9 *storage9 = GetAs<TextureStorage9>(storage);
- error = storage9->getSurfaceLevel(target, level, true, &destSurface);
+ error = storage9->getSurfaceLevel(context, target, level, true, &destSurface);
if (error.isError())
{
SafeRelease(source);
@@ -300,7 +314,8 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source
}
ASSERT(destSurface);
- gl::Error result = copy(source, sourceRect, destFormat, destOffset, destSurface);
+ gl::Error result =
+ copy(source, nullptr, sourceRect, destFormat, destOffset, destSurface, false, false, false);
SafeRelease(destSurface);
SafeRelease(source);
@@ -308,9 +323,69 @@ gl::Error Blit9::copyCube(const gl::Framebuffer *framebuffer, const RECT &source
return result;
}
-gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest)
+gl::Error Blit9::copyTexture(const gl::Context *context,
+ const gl::Texture *source,
+ GLint sourceLevel,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ TextureStorage *storage,
+ GLenum destTarget,
+ GLint destLevel,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
+{
+ ANGLE_TRY(initialize());
+
+ const TextureD3D *sourceD3D = GetImplAs<TextureD3D>(source);
+
+ TextureStorage *sourceStorage = nullptr;
+ ANGLE_TRY(const_cast<TextureD3D *>(sourceD3D)->getNativeTexture(context, &sourceStorage));
+
+ TextureStorage9_2D *sourceStorage9 = GetAs<TextureStorage9_2D>(sourceStorage);
+ ASSERT(sourceStorage9);
+
+ TextureStorage9 *destStorage9 = GetAs<TextureStorage9>(storage);
+ ASSERT(destStorage9);
+
+ ASSERT(sourceLevel == 0);
+ IDirect3DBaseTexture9 *sourceTexture = nullptr;
+ ANGLE_TRY(sourceStorage9->getBaseTexture(context, &sourceTexture));
+
+ IDirect3DSurface9 *sourceSurface = nullptr;
+ ANGLE_TRY(
+ sourceStorage9->getSurfaceLevel(context, GL_TEXTURE_2D, sourceLevel, true, &sourceSurface));
+
+ IDirect3DSurface9 *destSurface = nullptr;
+ gl::Error error =
+ destStorage9->getSurfaceLevel(context, destTarget, destLevel, true, &destSurface);
+ if (error.isError())
+ {
+ SafeRelease(sourceSurface);
+ return error;
+ }
+
+ error = copy(sourceSurface, sourceTexture, sourceRect, destFormat, destOffset, destSurface,
+ flipY, premultiplyAlpha, unmultiplyAlpha);
+
+ SafeRelease(sourceSurface);
+ SafeRelease(destSurface);
+
+ return error;
+}
+
+gl::Error Blit9::copy(IDirect3DSurface9 *source,
+ IDirect3DBaseTexture9 *sourceTexture,
+ const RECT &sourceRect,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ IDirect3DSurface9 *dest,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
{
- ASSERT(source != NULL && dest != NULL);
+ ASSERT(source != nullptr && dest != nullptr);
IDirect3DDevice9 *device = mRenderer->getDevice();
@@ -319,8 +394,10 @@ gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum
source->GetDesc(&sourceDesc);
dest->GetDesc(&destDesc);
- if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET &&
- d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect
+ // Check if it's possible to use StetchRect
+ if (sourceDesc.Format == destDesc.Format && (destDesc.Usage & D3DUSAGE_RENDERTARGET) &&
+ d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat) && !flipY &&
+ premultiplyAlpha == unmultiplyAlpha)
{
RECT destRect = { destOffset.x, destOffset.y, destOffset.x + (sourceRect.right - sourceRect.left), destOffset.y + (sourceRect.bottom - sourceRect.top)};
HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT);
@@ -328,85 +405,135 @@ gl::Error Blit9::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit between textures, StretchRect result: 0x%X.", result);
+ return gl::OutOfMemory()
+ << "Failed to blit between textures, StretchRect " << gl::FmtHR(result);
}
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
else
{
- return formatConvert(source, sourceRect, destFormat, destOffset, dest);
- }
-}
+ IDirect3DBaseTexture9 *texture = sourceTexture;
+ RECT adjustedSourceRect = sourceRect;
+ gl::Extents sourceSize(sourceDesc.Width, sourceDesc.Height, 1);
-gl::Error Blit9::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest)
-{
- gl::Error error = initialize();
- if (error.isError())
- {
- return error;
- }
+ if (texture == nullptr)
+ {
+ ANGLE_TRY(copySurfaceToTexture(source, sourceRect, &texture));
+
+ // copySurfaceToTexture only copies in the sourceRect area of the source surface.
+ // Adjust sourceRect so that it is now covering the entire source texture
+ adjustedSourceRect.left = 0;
+ adjustedSourceRect.right = sourceRect.right - sourceRect.left;
+ adjustedSourceRect.top = 0;
+ adjustedSourceRect.bottom = sourceRect.bottom - sourceRect.top;
+
+ sourceSize.width = sourceRect.right - sourceRect.left;
+ sourceSize.height = sourceRect.bottom - sourceRect.top;
+ }
+ else
+ {
+ texture->AddRef();
+ }
+
+ gl::Error error = formatConvert(texture, adjustedSourceRect, sourceSize, destFormat,
+ destOffset, dest, flipY, premultiplyAlpha, unmultiplyAlpha);
+
+ SafeRelease(texture);
- IDirect3DTexture9 *texture = NULL;
- error = copySurfaceToTexture(source, sourceRect, &texture);
- if (error.isError())
- {
return error;
}
+}
+
+gl::Error Blit9::formatConvert(IDirect3DBaseTexture9 *source,
+ const RECT &sourceRect,
+ const gl::Extents &sourceSize,
+ GLenum destFormat,
+ const gl::Offset &destOffset,
+ IDirect3DSurface9 *dest,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
+{
+ ANGLE_TRY(initialize());
IDirect3DDevice9 *device = mRenderer->getDevice();
saveState();
- device->SetTexture(0, texture);
+ device->SetTexture(0, source);
device->SetRenderTarget(0, dest);
- setViewport(sourceRect, destOffset);
+ RECT destRect;
+ destRect.left = destOffset.x;
+ destRect.right = destOffset.x + (sourceRect.right - sourceRect.left);
+ destRect.top = destOffset.y;
+ destRect.bottom = destOffset.y + (sourceRect.bottom - sourceRect.top);
+
+ setViewportAndShaderConstants(sourceRect, sourceSize, destRect, flipY);
setCommonBlitState();
- error = setFormatConvertShaders(destFormat);
+ gl::Error error = setFormatConvertShaders(destFormat, flipY, premultiplyAlpha, unmultiplyAlpha);
if (!error.isError())
{
render();
}
- SafeRelease(texture);
-
restoreState();
return error;
}
-gl::Error Blit9::setFormatConvertShaders(GLenum destFormat)
+gl::Error Blit9::setFormatConvertShaders(GLenum destFormat,
+ bool flipY,
+ bool premultiplyAlpha,
+ bool unmultiplyAlpha)
{
- gl::Error error = setVertexShader(SHADER_VS_STANDARD);
- if (error.isError())
- {
- return error;
- }
+ ANGLE_TRY(setVertexShader(SHADER_VS_STANDARD));
switch (destFormat)
{
- default: UNREACHABLE();
case GL_RGBA:
case GL_BGRA_EXT:
case GL_RGB:
case GL_RG_EXT:
case GL_RED_EXT:
case GL_ALPHA:
- error = setPixelShader(SHADER_PS_COMPONENTMASK);
- break;
+ if (premultiplyAlpha == unmultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(SHADER_PS_COMPONENTMASK));
+ }
+ else if (premultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA));
+ }
+ else
+ {
+ ASSERT(unmultiplyAlpha);
+ ANGLE_TRY(setPixelShader(SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA));
+ }
+ break;
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
- error = setPixelShader(SHADER_PS_LUMINANCE);
- break;
- }
-
- if (error.isError())
- {
- return error;
+ if (premultiplyAlpha == unmultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(SHADER_PS_LUMINANCE));
+ }
+ else if (premultiplyAlpha)
+ {
+ ANGLE_TRY(setPixelShader(SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA));
+ }
+ else
+ {
+ ASSERT(unmultiplyAlpha);
+ ANGLE_TRY(setPixelShader(SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA));
+ }
+ break;
+
+ default:
+ UNREACHABLE();
}
enum { X = 0, Y = 1, Z = 2, W = 3 };
@@ -502,10 +629,12 @@ gl::Error Blit9::setFormatConvertShaders(GLenum destFormat)
mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst, 2);
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
-gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture)
+gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface,
+ const RECT &sourceRect,
+ IDirect3DBaseTexture9 **outTexture)
{
ASSERT(surface);
@@ -516,12 +645,15 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so
// Copy the render target into a texture
IDirect3DTexture9 *texture;
- HRESULT result = device->CreateTexture(sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1, D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, NULL);
+ HRESULT result = device->CreateTexture(
+ sourceRect.right - sourceRect.left, sourceRect.bottom - sourceRect.top, 1,
+ D3DUSAGE_RENDERTARGET, sourceDesc.Format, D3DPOOL_DEFAULT, &texture, nullptr);
if (FAILED(result))
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for blit, result: 0x%X.", result);
+ return gl::OutOfMemory() << "Failed to allocate internal texture for blit, "
+ << gl::FmtHR(result);
}
IDirect3DSurface9 *textureSurface;
@@ -531,11 +663,12 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(texture);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to query surface of internal blit texture, result: 0x%X.", result);
+ return gl::OutOfMemory() << "Failed to query surface of internal blit texture, "
+ << gl::FmtHR(result);
}
mRenderer->endScene();
- result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE);
+ result = device->StretchRect(surface, &sourceRect, textureSurface, nullptr, D3DTEXF_NONE);
SafeRelease(textureSurface);
@@ -543,35 +676,50 @@ gl::Error Blit9::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &so
{
ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY);
SafeRelease(texture);
- return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy between internal blit textures, result: 0x%X.", result);
+ return gl::OutOfMemory() << "Failed to copy between internal blit textures, "
+ << gl::FmtHR(result);
}
*outTexture = texture;
- return gl::Error(GL_NO_ERROR);
+ return gl::NoError();
}
-void Blit9::setViewport(const RECT &sourceRect, const gl::Offset &offset)
+void Blit9::setViewportAndShaderConstants(const RECT &sourceRect,
+ const gl::Extents &sourceSize,
+ const RECT &destRect,
+ bool flipY)
{
IDirect3DDevice9 *device = mRenderer->getDevice();
D3DVIEWPORT9 vp;
- vp.X = offset.x;
- vp.Y = offset.y;
- vp.Width = sourceRect.right - sourceRect.left;
- vp.Height = sourceRect.bottom - sourceRect.top;
+ vp.X = destRect.left;
+ vp.Y = destRect.top;
+ vp.Width = destRect.right - destRect.left;
+ vp.Height = destRect.bottom - destRect.top;
vp.MinZ = 0.0f;
vp.MaxZ = 1.0f;
device->SetViewport(&vp);
- float halfPixelAdjust[4] = { -1.0f/vp.Width, 1.0f/vp.Height, 0, 0 };
- device->SetVertexShaderConstantF(0, halfPixelAdjust, 1);
+ float vertexConstants[8] = {
+ // halfPixelAdjust
+ -1.0f / vp.Width, 1.0f / vp.Height, 0, 0,
+ // texcoordOffset
+ static_cast<float>(sourceRect.left) / sourceSize.width,
+ static_cast<float>(flipY ? sourceRect.bottom : sourceRect.top) / sourceSize.height,
+ static_cast<float>(sourceRect.right - sourceRect.left) / sourceSize.width,
+ static_cast<float>(flipY ? sourceRect.top - sourceRect.bottom
+ : sourceRect.bottom - sourceRect.top) /
+ sourceSize.height,
+ };
+
+ device->SetVertexShaderConstantF(0, vertexConstants, 2);
}
void Blit9::setCommonBlitState()
{
IDirect3DDevice9 *device = mRenderer->getDevice();
- device->SetDepthStencilSurface(NULL);
+ device->SetDepthStencilSurface(nullptr);
device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID);
device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE);
@@ -617,7 +765,7 @@ void Blit9::saveState()
device->GetDepthStencilSurface(&mSavedDepthStencil);
device->GetRenderTarget(0, &mSavedRenderTarget);
- if (mSavedStateBlock == NULL)
+ if (mSavedStateBlock == nullptr)
{
hr = device->BeginStateBlock();
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
@@ -626,9 +774,9 @@ void Blit9::saveState()
static const float dummyConst[8] = { 0 };
- device->SetVertexShader(NULL);
+ device->SetVertexShader(nullptr);
device->SetVertexShaderConstantF(0, dummyConst, 2);
- device->SetPixelShader(NULL);
+ device->SetPixelShader(nullptr);
device->SetPixelShaderConstantF(0, dummyConst, 2);
D3DVIEWPORT9 dummyVp;
@@ -641,7 +789,7 @@ void Blit9::saveState()
device->SetViewport(&dummyVp);
- device->SetTexture(0, NULL);
+ device->SetTexture(0, nullptr);
device->SetStreamSource(0, mQuadVertexBuffer, 0, 0);
@@ -651,9 +799,9 @@ void Blit9::saveState()
ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY);
}
- ASSERT(mSavedStateBlock != NULL);
+ ASSERT(mSavedStateBlock != nullptr);
- if (mSavedStateBlock != NULL)
+ if (mSavedStateBlock != nullptr)
{
hr = mSavedStateBlock->Capture();
ASSERT(SUCCEEDED(hr));
@@ -670,9 +818,9 @@ void Blit9::restoreState()
device->SetRenderTarget(0, mSavedRenderTarget);
SafeRelease(mSavedRenderTarget);
- ASSERT(mSavedStateBlock != NULL);
+ ASSERT(mSavedStateBlock != nullptr);
- if (mSavedStateBlock != NULL)
+ if (mSavedStateBlock != nullptr)
{
mSavedStateBlock->Apply();
}