diff options
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.cpp | 410 |
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(); } |