From 0a7aebadfbb3534284546aa3ca8612314c08f136 Mon Sep 17 00:00:00 2001 From: Miguel Costa Date: Tue, 26 Jun 2018 16:56:45 +0200 Subject: Update ANGLE to chromium/3280 Change-Id: I0802c0d7486f772d361f87a544d6c5af937f4ca1 Reviewed-by: Friedemann Kleint --- .../angle/src/libANGLE/renderer/d3d/d3d9/Blit9.cpp | 410 ++-- .../angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h | 84 +- .../src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp | 82 +- .../angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h | 46 +- .../src/libANGLE/renderer/d3d/d3d9/Context9.cpp | 303 +++ .../src/libANGLE/renderer/d3d/d3d9/Context9.h | 151 ++ .../libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h | 4 +- .../src/libANGLE/renderer/d3d/d3d9/Fence9.cpp | 19 +- .../angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h | 2 +- .../libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp | 201 +- .../src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h | 38 +- .../src/libANGLE/renderer/d3d/d3d9/Image9.cpp | 303 ++- .../angle/src/libANGLE/renderer/d3d/d3d9/Image9.h | 50 +- .../libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp | 33 +- .../src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h | 16 +- .../libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp | 39 + .../src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h | 35 + .../src/libANGLE/renderer/d3d/d3d9/Query9.cpp | 76 +- .../angle/src/libANGLE/renderer/d3d/d3d9/Query9.h | 20 +- .../libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp | 3 +- .../src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h | 6 +- .../src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp | 2164 ++++++++++++-------- .../src/libANGLE/renderer/d3d/d3d9/Renderer9.h | 407 ++-- .../src/libANGLE/renderer/d3d/d3d9/ShaderCache.h | 10 +- .../renderer/d3d/d3d9/ShaderExecutable9.cpp | 6 +- .../libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h | 2 +- .../libANGLE/renderer/d3d/d3d9/StateManager9.cpp | 98 +- .../src/libANGLE/renderer/d3d/d3d9/StateManager9.h | 13 +- .../src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp | 123 +- .../src/libANGLE/renderer/d3d/d3d9/SwapChain9.h | 30 +- .../libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp | 219 +- .../libANGLE/renderer/d3d/d3d9/TextureStorage9.h | 84 +- .../src/libANGLE/renderer/d3d/d3d9/VertexArray9.h | 24 +- .../libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp | 94 +- .../src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h | 18 +- .../renderer/d3d/d3d9/VertexDeclarationCache.cpp | 46 +- .../renderer/d3d/d3d9/VertexDeclarationCache.h | 1 + .../libANGLE/renderer/d3d/d3d9/formatutils9.cpp | 321 +-- .../src/libANGLE/renderer/d3d/d3d9/formatutils9.h | 26 +- .../libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp | 104 +- .../libANGLE/renderer/d3d/d3d9/renderer9_utils.h | 11 +- .../src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps | 34 + .../src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs | 18 +- 43 files changed, 3765 insertions(+), 2009 deletions(-) create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp create mode 100644 src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h (limited to 'src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9') 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 @@ -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(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(shaderCode), shaderSize, &shader); - if (error.isError()) - { - return error; - } - + ANGLE_TRY((mRenderer->*createShader)(reinterpret_cast(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(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(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(source); + + TextureStorage *sourceStorage = nullptr; + ANGLE_TRY(const_cast(sourceD3D)->getNativeTexture(context, &sourceStorage)); + + TextureStorage9_2D *sourceStorage9 = GetAs(sourceStorage); + ASSERT(sourceStorage9); + + TextureStorage9 *destStorage9 = GetAs(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(sourceRect.left) / sourceSize.width, + static_cast(flipY ? sourceRect.bottom : sourceRect.top) / sourceSize.height, + static_cast(sourceRect.right - sourceRect.left) / sourceSize.width, + static_cast(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(); } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h index 586abd2580..026874f8ae 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Blit9.h @@ -16,7 +16,10 @@ namespace gl { +class Context; class Framebuffer; +class Texture; +struct Extents; struct Offset; } @@ -35,13 +38,33 @@ class Blit9 : angle::NonCopyable // Copy from source surface to dest surface. // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - gl::Error copy2D(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLint level); - gl::Error copyCube(const gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level); - - // Copy from source surface to dest surface. - // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - // source is interpreted as RGBA and destFormat specifies the desired result format. For example, if destFormat = GL_RGB, the alpha channel will be forced to 0. - gl::Error formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest); + gl::Error copy2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level); + gl::Error 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 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); // 2x2 box filter sample from source to dest. // Requires that source is RGB(A) and dest has the same format as source. @@ -54,23 +77,56 @@ class Blit9 : angle::NonCopyable IDirect3DVertexBuffer9 *mQuadVertexBuffer; IDirect3DVertexDeclaration9 *mQuadVertexDeclaration; - gl::Error setFormatConvertShaders(GLenum destFormat); - - gl::Error copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, const gl::Offset &destOffset, IDirect3DSurface9 *dest); - gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect, IDirect3DTexture9 **outTexture); - void setViewport(const RECT &sourceRect, const gl::Offset &offset); + // Copy from source texture to dest surface. + // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) + // source is interpreted as RGBA and destFormat specifies the desired result format. For + // example, if destFormat = GL_RGB, the alpha channel will be forced to 0. + gl::Error formatConvert(IDirect3DBaseTexture9 *source, + const RECT &sourceRect, + const gl::Extents &sourceSize, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + gl::Error setFormatConvertShaders(GLenum destFormat, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + + gl::Error copy(IDirect3DSurface9 *source, + IDirect3DBaseTexture9 *sourceTexture, + const RECT &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + IDirect3DSurface9 *dest, + bool flipY, + bool premultiplyAlpha, + bool unmultiplyAlpha); + gl::Error copySurfaceToTexture(IDirect3DSurface9 *surface, + const RECT &sourceRect, + IDirect3DBaseTexture9 **outTexture); + void setViewportAndShaderConstants(const RECT &sourceRect, + const gl::Extents &sourceSize, + const RECT &destRect, + bool flipY); void setCommonBlitState(); RECT getSurfaceRect(IDirect3DSurface9 *surface) const; + gl::Extents getSurfaceSize(IDirect3DSurface9 *surface) const; // This enum is used to index mCompiledShaders and mShaderSource. enum ShaderId { SHADER_VS_STANDARD, - SHADER_VS_FLIPY, SHADER_PS_PASSTHROUGH, SHADER_PS_LUMINANCE, + SHADER_PS_LUMINANCE_PREMULTIPLY_ALPHA, + SHADER_PS_LUMINANCE_UNMULTIPLY_ALPHA, SHADER_PS_COMPONENTMASK, - SHADER_COUNT + SHADER_PS_COMPONENTMASK_PREMULTIPLY_ALPHA, + SHADER_PS_COMPONENTMASK_UNMULTIPLY_ALPHA, + SHADER_COUNT, }; // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown. diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp index 804b6971ce..dc308e7752 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.cpp @@ -12,23 +12,37 @@ namespace rx { -Buffer9::Buffer9(Renderer9 *renderer) - : BufferD3D(renderer), - mSize(0) -{} +Buffer9::Buffer9(const gl::BufferState &state, Renderer9 *renderer) + : BufferD3D(state, renderer), mSize(0) +{ +} Buffer9::~Buffer9() { mSize = 0; } -gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) +size_t Buffer9::getSize() const +{ + return mSize; +} + +bool Buffer9::supportsDirectBinding() const +{ + return false; +} + +gl::Error Buffer9::setData(const gl::Context *context, + gl::BufferBinding /*target*/, + const void *data, + size_t size, + gl::BufferUsage usage) { if (size > mMemory.size()) { if (!mMemory.resize(size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); + return gl::OutOfMemory() << "Failed to resize internal buffer."; } } @@ -38,25 +52,30 @@ gl::Error Buffer9::setData(const void* data, size_t size, GLenum usage) memcpy(mMemory.data(), data, size); } - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + updateD3DBufferUsage(context, usage); - updateD3DBufferUsage(usage); - return gl::Error(GL_NO_ERROR); + invalidateStaticData(context); + + return gl::NoError(); } -gl::Error Buffer9::getData(const uint8_t **outData) +gl::Error Buffer9::getData(const gl::Context *context, const uint8_t **outData) { *outData = mMemory.data(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) +gl::Error Buffer9::setSubData(const gl::Context *context, + gl::BufferBinding /*target*/, + const void *data, + size_t size, + size_t offset) { if (offset + size > mMemory.size()) { if (!mMemory.resize(offset + size)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to resize internal buffer."); + return gl::OutOfMemory() << "Failed to resize internal buffer."; } } @@ -66,46 +85,55 @@ gl::Error Buffer9::setSubData(const void* data, size_t size, size_t offset) memcpy(mMemory.data() + offset, data, size); } - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Buffer9::copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size) +gl::Error Buffer9::copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) { // Note: this method is currently unreachable - Buffer9* sourceBuffer = GetAs(source); + Buffer9 *sourceBuffer = GetAs(source); ASSERT(sourceBuffer); memcpy(mMemory.data() + destOffset, sourceBuffer->mMemory.data() + sourceOffset, size); - invalidateStaticData(D3D_BUFFER_INVALIDATE_WHOLE_CACHE); + invalidateStaticData(context); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // We do not support buffer mapping in D3D9 -gl::Error Buffer9::map(GLenum access, GLvoid **mapPtr) +gl::Error Buffer9::map(const gl::Context *context, GLenum access, void **mapPtr) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Buffer9::mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr) +gl::Error Buffer9::mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Buffer9::unmap(GLboolean *result) +gl::Error Buffer9::unmap(const gl::Context *context, GLboolean *result) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -void Buffer9::markTransformFeedbackUsage() +gl::Error Buffer9::markTransformFeedbackUsage(const gl::Context *context) { UNREACHABLE(); + return gl::InternalError(); } -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h index 44a524ba28..960b2a2474 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Buffer9.h @@ -20,28 +20,44 @@ class Renderer9; class Buffer9 : public BufferD3D { public: - Buffer9(Renderer9 *renderer); - virtual ~Buffer9(); + Buffer9(const gl::BufferState &state, Renderer9 *renderer); + ~Buffer9() override; // BufferD3D implementation - virtual size_t getSize() const { return mSize; } - virtual bool supportsDirectBinding() const { return false; } - gl::Error getData(const uint8_t **outData) override; + size_t getSize() const override; + bool supportsDirectBinding() const override; + gl::Error getData(const gl::Context *context, const uint8_t **outData) override; // BufferImpl implementation - virtual gl::Error setData(const void* data, size_t size, GLenum usage); - virtual gl::Error setSubData(const void* data, size_t size, size_t offset); - virtual gl::Error copySubData(BufferImpl* source, GLintptr sourceOffset, GLintptr destOffset, GLsizeiptr size); - virtual gl::Error map(GLenum access, GLvoid **mapPtr); - virtual gl::Error mapRange(size_t offset, size_t length, GLbitfield access, GLvoid **mapPtr); - virtual gl::Error unmap(GLboolean *result); - virtual void markTransformFeedbackUsage(); + gl::Error setData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + gl::BufferUsage usage) override; + gl::Error setSubData(const gl::Context *context, + gl::BufferBinding target, + const void *data, + size_t size, + size_t offset) override; + gl::Error copySubData(const gl::Context *context, + BufferImpl *source, + GLintptr sourceOffset, + GLintptr destOffset, + GLsizeiptr size) override; + gl::Error map(const gl::Context *context, GLenum access, void **mapPtr) override; + gl::Error mapRange(const gl::Context *context, + size_t offset, + size_t length, + GLbitfield access, + void **mapPtr) override; + gl::Error unmap(const gl::Context *context, GLboolean *result) override; + gl::Error markTransformFeedbackUsage(const gl::Context *context) override; private: - MemoryBuffer mMemory; + angle::MemoryBuffer mMemory; size_t mSize; }; -} +} // namespace rx -#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ +#endif // LIBANGLE_RENDERER_D3D_D3D9_BUFFER9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp new file mode 100644 index 0000000000..1b9874cc20 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.cpp @@ -0,0 +1,303 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context9: +// D3D9-specific functionality associated with a GL Context. +// + +#include "libANGLE/renderer/d3d/d3d9/Context9.h" + +#include "common/string_utils.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/SamplerD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/Buffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Fence9.h" +#include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Query9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/StateManager9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" + +namespace rx +{ + +Context9::Context9(const gl::ContextState &state, Renderer9 *renderer) + : ContextImpl(state), mRenderer(renderer) +{ +} + +Context9::~Context9() +{ +} + +gl::Error Context9::initialize() +{ + return gl::NoError(); +} + +CompilerImpl *Context9::createCompiler() +{ + return new CompilerD3D(SH_HLSL_3_0_OUTPUT); +} + +ShaderImpl *Context9::createShader(const gl::ShaderState &data) +{ + return new ShaderD3D(data, mRenderer->getWorkarounds(), mRenderer->getNativeExtensions()); +} + +ProgramImpl *Context9::createProgram(const gl::ProgramState &data) +{ + return new ProgramD3D(data, mRenderer); +} + +FramebufferImpl *Context9::createFramebuffer(const gl::FramebufferState &data) +{ + return new Framebuffer9(data, mRenderer); +} + +TextureImpl *Context9::createTexture(const gl::TextureState &state) +{ + switch (state.getTarget()) + { + case GL_TEXTURE_2D: + return new TextureD3D_2D(state, mRenderer); + case GL_TEXTURE_CUBE_MAP: + return new TextureD3D_Cube(state, mRenderer); + case GL_TEXTURE_EXTERNAL_OES: + return new TextureD3D_External(state, mRenderer); + default: + UNREACHABLE(); + } + return nullptr; +} + +RenderbufferImpl *Context9::createRenderbuffer() +{ + return new RenderbufferD3D(mRenderer); +} + +BufferImpl *Context9::createBuffer(const gl::BufferState &state) +{ + return new Buffer9(state, mRenderer); +} + +VertexArrayImpl *Context9::createVertexArray(const gl::VertexArrayState &data) +{ + return new VertexArray9(data); +} + +QueryImpl *Context9::createQuery(GLenum type) +{ + return new Query9(mRenderer, type); +} + +FenceNVImpl *Context9::createFenceNV() +{ + return new FenceNV9(mRenderer); +} + +SyncImpl *Context9::createSync() +{ + // D3D9 doesn't support ES 3.0 and its sync objects. + UNREACHABLE(); + return nullptr; +} + +TransformFeedbackImpl *Context9::createTransformFeedback(const gl::TransformFeedbackState &state) +{ + UNREACHABLE(); + return nullptr; +} + +SamplerImpl *Context9::createSampler(const gl::SamplerState &state) +{ + return new SamplerD3D(state); +} + +ProgramPipelineImpl *Context9::createProgramPipeline(const gl::ProgramPipelineState &data) +{ + UNREACHABLE(); + return nullptr; +} + +std::vector Context9::createPaths(GLsizei) +{ + return std::vector(); +} + +gl::Error Context9::flush(const gl::Context *context) +{ + return mRenderer->flush(); +} + +gl::Error Context9::finish(const gl::Context *context) +{ + return mRenderer->finish(); +} + +gl::Error Context9::drawArrays(const gl::Context *context, GLenum mode, GLint first, GLsizei count) +{ + return mRenderer->genericDrawArrays(context, mode, first, count, 0); +} + +gl::Error Context9::drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) +{ + return mRenderer->genericDrawArrays(context, mode, first, count, instanceCount); +} + +gl::Error Context9::drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, 0); +} + +gl::Error Context9::drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, instances); +} + +gl::Error Context9::drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) +{ + return mRenderer->genericDrawElements(context, mode, count, type, indices, 0); +} + +gl::Error Context9::drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) +{ + UNREACHABLE(); + return gl::InternalError() << "D3D9 doesn't support ES 3.1 DrawArraysIndirect API"; +} + +gl::Error Context9::drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) +{ + UNREACHABLE(); + return gl::InternalError() << "D3D9 doesn't support ES 3.1 DrawElementsIndirect API"; +} + +GLenum Context9::getResetStatus() +{ + return mRenderer->getResetStatus(); +} + +std::string Context9::getVendorString() const +{ + return mRenderer->getVendorString(); +} + +std::string Context9::getRendererDescription() const +{ + return mRenderer->getRendererDescription(); +} + +void Context9::insertEventMarker(GLsizei length, const char *marker) +{ + auto optionalString = angle::WidenString(static_cast(length), marker); + if (optionalString.valid()) + { + mRenderer->getAnnotator()->setMarker(optionalString.value().data()); + } +} + +void Context9::pushGroupMarker(GLsizei length, const char *marker) +{ + auto optionalString = angle::WidenString(static_cast(length), marker); + if (optionalString.valid()) + { + mRenderer->getAnnotator()->beginEvent(optionalString.value().data()); + } +} + +void Context9::popGroupMarker() +{ + mRenderer->getAnnotator()->endEvent(); +} + +void Context9::pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) +{ + // Fall through to the EXT_debug_marker functions + pushGroupMarker(length, message); +} + +void Context9::popDebugGroup() +{ + // Fall through to the EXT_debug_marker functions + popGroupMarker(); +} + +void Context9::syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) +{ + mRenderer->getStateManager()->syncState(mState.getState(), dirtyBits); +} + +GLint Context9::getGPUDisjoint() +{ + return mRenderer->getGPUDisjoint(); +} + +GLint64 Context9::getTimestamp() +{ + return mRenderer->getTimestamp(); +} + +void Context9::onMakeCurrent(const gl::Context *context) +{ +} + +const gl::Caps &Context9::getNativeCaps() const +{ + return mRenderer->getNativeCaps(); +} + +const gl::TextureCapsMap &Context9::getNativeTextureCaps() const +{ + return mRenderer->getNativeTextureCaps(); +} + +const gl::Extensions &Context9::getNativeExtensions() const +{ + return mRenderer->getNativeExtensions(); +} + +const gl::Limitations &Context9::getNativeLimitations() const +{ + return mRenderer->getNativeLimitations(); +} + +gl::Error Context9::dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) +{ + UNREACHABLE(); + return gl::InternalError() << "D3D9 doesn't support ES 3.1 DispatchCompute API"; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h new file mode 100644 index 0000000000..d681bfde89 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Context9.h @@ -0,0 +1,151 @@ +// +// Copyright 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// +// Context9: +// D3D9-specific functionality associated with a GL Context. +// + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ + +#include "libANGLE/renderer/ContextImpl.h" + +namespace rx +{ +class Renderer9; + +class Context9 : public ContextImpl +{ + public: + Context9(const gl::ContextState &state, Renderer9 *renderer); + ~Context9() override; + + gl::Error initialize() override; + + // Shader creation + CompilerImpl *createCompiler() override; + ShaderImpl *createShader(const gl::ShaderState &data) override; + ProgramImpl *createProgram(const gl::ProgramState &data) override; + + // Framebuffer creation + FramebufferImpl *createFramebuffer(const gl::FramebufferState &data) override; + + // Texture creation + TextureImpl *createTexture(const gl::TextureState &state) override; + + // Renderbuffer creation + RenderbufferImpl *createRenderbuffer() override; + + // Buffer creation + BufferImpl *createBuffer(const gl::BufferState &state) override; + + // Vertex Array creation + VertexArrayImpl *createVertexArray(const gl::VertexArrayState &data) override; + + // Query and Fence creation + QueryImpl *createQuery(GLenum type) override; + FenceNVImpl *createFenceNV() override; + SyncImpl *createSync() override; + + // Transform Feedback creation + TransformFeedbackImpl *createTransformFeedback( + const gl::TransformFeedbackState &state) override; + + // Sampler object creation + SamplerImpl *createSampler(const gl::SamplerState &state) override; + + // Program Pipeline object creation + ProgramPipelineImpl *createProgramPipeline(const gl::ProgramPipelineState &data) override; + + // Path object creation + std::vector createPaths(GLsizei) override; + + // Flush and finish. + gl::Error flush(const gl::Context *context) override; + gl::Error finish(const gl::Context *context) override; + + // Drawing methods. + gl::Error drawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count) override; + gl::Error drawArraysInstanced(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instanceCount) override; + + gl::Error drawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices) override; + gl::Error drawElementsInstanced(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) override; + gl::Error drawRangeElements(const gl::Context *context, + GLenum mode, + GLuint start, + GLuint end, + GLsizei count, + GLenum type, + const void *indices) override; + gl::Error drawArraysIndirect(const gl::Context *context, + GLenum mode, + const void *indirect) override; + gl::Error drawElementsIndirect(const gl::Context *context, + GLenum mode, + GLenum type, + const void *indirect) override; + + // Device loss + GLenum getResetStatus() override; + + // Vendor and description strings. + std::string getVendorString() const override; + std::string getRendererDescription() const override; + + // EXT_debug_marker + void insertEventMarker(GLsizei length, const char *marker) override; + void pushGroupMarker(GLsizei length, const char *marker) override; + void popGroupMarker() override; + + // KHR_debug + void pushDebugGroup(GLenum source, GLuint id, GLsizei length, const char *message) override; + void popDebugGroup() override; + + // State sync with dirty bits. + void syncState(const gl::Context *context, const gl::State::DirtyBits &dirtyBits) override; + + // Disjoint timer queries + GLint getGPUDisjoint() override; + GLint64 getTimestamp() override; + + // Context switching + void onMakeCurrent(const gl::Context *context) override; + + // Caps queries + const gl::Caps &getNativeCaps() const override; + const gl::TextureCapsMap &getNativeTextureCaps() const override; + const gl::Extensions &getNativeExtensions() const override; + const gl::Limitations &getNativeLimitations() const override; + + gl::Error dispatchCompute(const gl::Context *context, + GLuint numGroupsX, + GLuint numGroupsY, + GLuint numGroupsZ) override; + + Renderer9 *getRenderer() const { return mRenderer; } + + private: + Renderer9 *mRenderer; +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_CONTEXT9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h index 54e3bb9490..b28008335f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h @@ -9,12 +9,12 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_DEBUGANNOTATOR9_H_ -#include "common/debug.h" +#include "libANGLE/LoggingAnnotator.h" namespace rx { -class DebugAnnotator9 : public gl::DebugAnnotator +class DebugAnnotator9 : public angle::LoggingAnnotator { public: DebugAnnotator9() {} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp index 3300681277..bff3881655 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.cpp @@ -13,10 +13,7 @@ namespace rx { -FenceNV9::FenceNV9(Renderer9 *renderer) - : FenceNVImpl(), - mRenderer(renderer), - mQuery(NULL) +FenceNV9::FenceNV9(Renderer9 *renderer) : FenceNVImpl(), mRenderer(renderer), mQuery(nullptr) { } @@ -41,10 +38,10 @@ gl::Error FenceNV9::set(GLenum condition) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(mQuery); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to end event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to end event query, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error FenceNV9::test(GLboolean *outFinished) @@ -66,7 +63,7 @@ gl::Error FenceNV9::finish() Sleep(0); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error FenceNV9::testHelper(bool flushCommandBuffer, GLboolean *outFinished) @@ -74,21 +71,21 @@ gl::Error FenceNV9::testHelper(bool flushCommandBuffer, GLboolean *outFinished) ASSERT(mQuery); DWORD getDataFlags = (flushCommandBuffer ? D3DGETDATA_FLUSH : 0); - HRESULT result = mQuery->GetData(NULL, 0, getDataFlags); + HRESULT result = mQuery->GetData(nullptr, 0, getDataFlags); if (d3d9::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Device was lost while querying result of an event query."); + return gl::OutOfMemory() << "Device was lost while querying result of an event query."; } else if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get query data, " << gl::FmtHR(result); } ASSERT(result == S_OK || result == S_FALSE); *outFinished = ((result == S_OK) ? GL_TRUE : GL_FALSE); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h index 200ac68d27..de0ff20774 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Fence9.h @@ -10,7 +10,7 @@ #define LIBANGLE_RENDERER_D3D_D3D9_FENCE9_H_ #include "libANGLE/renderer/FenceNVImpl.h" -#include "libANGLE/renderer/FenceSyncImpl.h" +#include "libANGLE/renderer/SyncImpl.h" namespace rx { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp index 9c269a8565..dff12e03f8 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.cpp @@ -7,21 +7,25 @@ // Framebuffer9.cpp: Implements the Framebuffer9 class. #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" -#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" -#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" -#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/formatutils.h" + +#include "libANGLE/Context.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Texture.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/ContextImpl.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" +#include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" +#include "libANGLE/renderer/d3d/d3d9/Renderer9.h" +#include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" +#include "libANGLE/renderer/renderer_utils.h" namespace rx { -Framebuffer9::Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer) +Framebuffer9::Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer) : FramebufferD3D(data, renderer), mRenderer(renderer) { ASSERT(mRenderer != nullptr); @@ -31,66 +35,61 @@ Framebuffer9::~Framebuffer9() { } -gl::Error Framebuffer9::discard(size_t, const GLenum *) +gl::Error Framebuffer9::discard(const gl::Context *context, size_t, const GLenum *) { // Extension not implemented in D3D9 renderer UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::invalidate(size_t, const GLenum *) +gl::Error Framebuffer9::invalidate(const gl::Context *context, size_t, const GLenum *) { // Shouldn't ever reach here in D3D9 UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::invalidateSub(size_t, const GLenum *, const gl::Rectangle &) +gl::Error Framebuffer9::invalidateSub(const gl::Context *context, + size_t, + const GLenum *, + const gl::Rectangle &) { // Shouldn't ever reach here in D3D9 UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::clear(const gl::Data &data, const ClearParameters &clearParams) +gl::Error Framebuffer9::clearImpl(const gl::Context *context, const ClearParameters &clearParams) { - const gl::FramebufferAttachment *colorAttachment = mData.getColorAttachment(0); - const gl::FramebufferAttachment *depthStencilAttachment = mData.getDepthOrStencilAttachment(); + const gl::FramebufferAttachment *colorAttachment = mState.getColorAttachment(0); + const gl::FramebufferAttachment *depthStencilAttachment = mState.getDepthOrStencilAttachment(); - gl::Error error = mRenderer->applyRenderTarget(colorAttachment, depthStencilAttachment); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mRenderer->applyRenderTarget(context, colorAttachment, depthStencilAttachment)); - float nearZ = data.state->getNearPlane(); - float farZ = data.state->getFarPlane(); - mRenderer->setViewport(data.caps, data.state->getViewport(), nearZ, farZ, GL_TRIANGLES, - data.state->getRasterizerState().frontFace, true); + const gl::State &glState = context->getGLState(); + float nearZ = glState.getNearPlane(); + float farZ = glState.getFarPlane(); + mRenderer->setViewport(glState.getViewport(), nearZ, farZ, GL_TRIANGLES, + glState.getRasterizerState().frontFace, true); - mRenderer->setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); + mRenderer->setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); - return mRenderer->clear(clearParams, colorAttachment, depthStencilAttachment); + return mRenderer->clear(context, clearParams, colorAttachment, depthStencilAttachment); } -gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, +gl::Error Framebuffer9::readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const + uint8_t *pixels) { - ASSERT(pack.pixelBuffer.get() == nullptr); - - const gl::FramebufferAttachment *colorbuffer = mData.getColorAttachment(0); + const gl::FramebufferAttachment *colorbuffer = mState.getColorAttachment(0); ASSERT(colorbuffer); RenderTarget9 *renderTarget = nullptr; - gl::Error error = colorbuffer->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(colorbuffer->getRenderTarget(context, &renderTarget)); ASSERT(renderTarget); IDirect3DSurface9 *surface = renderTarget->getSurface(); @@ -103,7 +102,8 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, { UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "ReadPixels is unimplemented for multisampled framebuffer attachments."); + return gl::OutOfMemory() + << "ReadPixels is unimplemented for multisampled framebuffer attachments."; } IDirect3DDevice9 *device = mRenderer->getDevice(); @@ -135,7 +135,7 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal texture for ReadPixels."); + return gl::OutOfMemory() << "Failed to allocate internal texture for ReadPixels."; } } @@ -157,13 +157,13 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, UNREACHABLE(); } - return gl::Error(GL_OUT_OF_MEMORY, "Failed to read internal render target data."); + return gl::OutOfMemory() << "Failed to read internal render target data."; } if (directToPixels) { SafeRelease(systemSurface); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } RECT rect; @@ -180,85 +180,42 @@ gl::Error Framebuffer9::readPixelsImpl(const gl::Rectangle &area, UNREACHABLE(); SafeRelease(systemSurface); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal render target."); + return gl::OutOfMemory() << "Failed to lock internal render target."; } - uint8_t *source; - int inputPitch; - if (pack.reverseRowOrder) - { - source = reinterpret_cast(lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); - inputPitch = -lock.Pitch; - } - else - { - source = reinterpret_cast(lock.pBits); - inputPitch = lock.Pitch; - } + uint8_t *source = reinterpret_cast(lock.pBits); + int inputPitch = lock.Pitch; const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); - const gl::InternalFormat &sourceFormatInfo = gl::GetInternalFormatInfo(d3dFormatInfo.internalFormat); - if (sourceFormatInfo.format == format && sourceFormatInfo.type == type) - { - // Direct copy possible - for (int y = 0; y < rect.bottom - rect.top; y++) - { - memcpy(pixels + y * outputPitch, source + y * inputPitch, (rect.right - rect.left) * sourceFormatInfo.pixelBytes); - } - } - else - { - const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); - ColorCopyFunction fastCopyFunc = sourceD3DFormatInfo.getFastCopyFunction(format, type); - - GLenum sizedDestInternalFormat = gl::GetSizedInternalFormat(format, type); - const gl::InternalFormat &destFormatInfo = gl::GetInternalFormatInfo(sizedDestInternalFormat); - - if (fastCopyFunc) - { - // Fast copy is possible through some special function - for (int y = 0; y < rect.bottom - rect.top; y++) - { - for (int x = 0; x < rect.right - rect.left; x++) - { - uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; + gl::FormatType formatType(format, type); - fastCopyFunc(src, dest); - } - } - } - else - { - ColorReadFunction colorReadFunction = sourceD3DFormatInfo.colorReadFunction; - ColorWriteFunction colorWriteFunction = GetColorWriteFunction(format, type); + PackPixelsParams packParams; + packParams.area.x = rect.left; + packParams.area.y = rect.top; + packParams.area.width = rect.right - rect.left; + packParams.area.height = rect.bottom - rect.top; + packParams.format = format; + packParams.type = type; + packParams.outputPitch = static_cast(outputPitch); + packParams.pack = pack; - uint8_t temp[sizeof(gl::ColorF)]; - for (int y = 0; y < rect.bottom - rect.top; y++) - { - for (int x = 0; x < rect.right - rect.left; x++) - { - uint8_t *dest = pixels + y * outputPitch + x * destFormatInfo.pixelBytes; - const uint8_t *src = source + y * inputPitch + x * sourceFormatInfo.pixelBytes; - - // readFunc and writeFunc will be using the same type of color, CopyTexImage - // will not allow the copy otherwise. - colorReadFunction(src, temp); - colorWriteFunction(temp, dest); - } - } - } - } + PackPixels(packParams, d3dFormatInfo.info(), inputPitch, source, pixels); systemSurface->UnlockRect(); SafeRelease(systemSurface); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) +gl::Error Framebuffer9::blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) { ASSERT(filter == GL_NEAREST); @@ -273,18 +230,18 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl ASSERT(readBuffer); RenderTarget9 *readRenderTarget = nullptr; - gl::Error error = readBuffer->getRenderTarget(&readRenderTarget); + gl::Error error = readBuffer->getRenderTarget(context, &readRenderTarget); if (error.isError()) { return error; } ASSERT(readRenderTarget); - const gl::FramebufferAttachment *drawBuffer = mData.getColorAttachment(0); + const gl::FramebufferAttachment *drawBuffer = mState.getColorAttachment(0); ASSERT(drawBuffer); RenderTarget9 *drawRenderTarget = nullptr; - error = drawBuffer->getRenderTarget(&drawRenderTarget); + error = drawBuffer->getRenderTarget(context, &drawRenderTarget); if (error.isError()) { return error; @@ -389,7 +346,7 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); + return gl::OutOfMemory() << "Internal blit failed, StretchRect " << gl::FmtHR(result); } } @@ -399,18 +356,18 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl ASSERT(readBuffer); RenderTarget9 *readDepthStencil = nullptr; - gl::Error error = readBuffer->getRenderTarget(&readDepthStencil); + gl::Error error = readBuffer->getRenderTarget(context, &readDepthStencil); if (error.isError()) { return error; } ASSERT(readDepthStencil); - const gl::FramebufferAttachment *drawBuffer = mData.getDepthOrStencilAttachment(); + const gl::FramebufferAttachment *drawBuffer = mState.getDepthOrStencilAttachment(); ASSERT(drawBuffer); RenderTarget9 *drawDepthStencil = nullptr; - error = drawBuffer->getRenderTarget(&drawDepthStencil); + error = drawBuffer->getRenderTarget(context, &drawDepthStencil); if (error.isError()) { return error; @@ -431,18 +388,24 @@ gl::Error Framebuffer9::blit(const gl::Rectangle &sourceArea, const gl::Rectangl if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal blit failed, StretchRect returned 0x%X.", result); + return gl::OutOfMemory() << "Internal blit failed, StretchRect " << gl::FmtHR(result); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } GLenum Framebuffer9::getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const { RenderTarget9 *renderTarget9 = GetAs(renderTarget); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(renderTarget9->getD3DFormat()); - return d3dFormatInfo.internalFormat; + return d3dFormatInfo.info().glInternalFormat; } +gl::Error Framebuffer9::getSamplePosition(size_t index, GLfloat *xy) const +{ + UNREACHABLE(); + return gl::InternalError() << "getSamplePosition is unsupported to d3d9."; } + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h index fe12079ae0..d2b46435ee 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Framebuffer9.h @@ -18,26 +18,40 @@ class Renderer9; class Framebuffer9 : public FramebufferD3D { public: - Framebuffer9(const gl::Framebuffer::Data &data, Renderer9 *renderer); - virtual ~Framebuffer9(); + Framebuffer9(const gl::FramebufferState &data, Renderer9 *renderer); + ~Framebuffer9() override; - gl::Error discard(size_t count, const GLenum *attachments) override; - gl::Error invalidate(size_t count, const GLenum *attachments) override; - gl::Error invalidateSub(size_t count, const GLenum *attachments, const gl::Rectangle &area) override; + gl::Error discard(const gl::Context *context, size_t count, const GLenum *attachments) override; + gl::Error invalidate(const gl::Context *context, + size_t count, + const GLenum *attachments) override; + gl::Error invalidateSub(const gl::Context *context, + size_t count, + const GLenum *attachments, + const gl::Rectangle &area) override; + + gl::Error getSamplePosition(size_t index, GLfloat *xy) const override; private: - gl::Error clear(const gl::Data &data, const ClearParameters &clearParams) override; + gl::Error clearImpl(const gl::Context *context, const ClearParameters &clearParams) override; - gl::Error readPixelsImpl(const gl::Rectangle &area, + gl::Error readPixelsImpl(const gl::Context *context, + const gl::Rectangle &area, GLenum format, GLenum type, size_t outputPitch, const gl::PixelPackState &pack, - uint8_t *pixels) const override; - - gl::Error blit(const gl::Rectangle &sourceArea, const gl::Rectangle &destArea, const gl::Rectangle *scissor, - bool blitRenderTarget, bool blitDepth, bool blitStencil, GLenum filter, - const gl::Framebuffer *sourceFramebuffer) override; + uint8_t *pixels) override; + + gl::Error blitImpl(const gl::Context *context, + const gl::Rectangle &sourceArea, + const gl::Rectangle &destArea, + const gl::Rectangle *scissor, + bool blitRenderTarget, + bool blitDepth, + bool blitStencil, + GLenum filter, + const gl::Framebuffer *sourceFramebuffer) override; GLenum getRenderTargetImplementationFormat(RenderTargetD3D *renderTarget) const override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp index fec7e3e19d..179629b362 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.cpp @@ -24,8 +24,8 @@ namespace rx Image9::Image9(Renderer9 *renderer) { - mSurface = NULL; - mRenderer = NULL; + mSurface = nullptr; + mRenderer = nullptr; mD3DPool = D3DPOOL_SYSTEMMEM; mD3DFormat = D3DFMT_UNKNOWN; @@ -45,7 +45,9 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the source surface description for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to query the source surface description for mipmap generation, " + << gl::FmtHR(result); } D3DSURFACE_DESC sourceDesc; @@ -53,7 +55,9 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to query the destination surface description for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to query the destination surface description for mipmap generation, " + << gl::FmtHR(result); } ASSERT(sourceDesc.Format == destDesc.Format); @@ -61,23 +65,25 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); - ASSERT(d3dFormatInfo.mipGenerationFunction != NULL); + ASSERT(d3dFormatInfo.info().mipGenerationFunction != nullptr); D3DLOCKED_RECT sourceLocked = {0}; - result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); + result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock the source surface for mipmap generation, " + << gl::FmtHR(result); } D3DLOCKED_RECT destLocked = {0}; - result = destSurface->LockRect(&destLocked, NULL, 0); + result = destSurface->LockRect(&destLocked, nullptr, 0); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { sourceSurface->UnlockRect(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the destination surface for mipmap generation, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock the destination surface for mipmap generation, " + << gl::FmtHR(result); } const uint8_t *sourceData = reinterpret_cast(sourceLocked.pBits); @@ -85,40 +91,29 @@ gl::Error Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 ASSERT(sourceData && destData); - d3dFormatInfo.mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, sourceLocked.Pitch, 0, - destData, destLocked.Pitch, 0); + d3dFormatInfo.info().mipGenerationFunction(sourceDesc.Width, sourceDesc.Height, 1, sourceData, + sourceLocked.Pitch, 0, destData, destLocked.Pitch, + 0); destSurface->UnlockRect(); sourceSurface->UnlockRect(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Image9::generateMipmap(Image9 *dest, Image9 *source) { - IDirect3DSurface9 *sourceSurface = NULL; - gl::Error error = source->getSurface(&sourceSurface); - if (error.isError()) - { - return error; - } + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(source->getSurface(&sourceSurface)); - IDirect3DSurface9 *destSurface = NULL; - error = dest->getSurface(&destSurface); - if (error.isError()) - { - return error; - } + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(dest->getSurface(&destSurface)); - error = generateMip(destSurface, sourceSurface); - if (error.isError()) - { - return error; - } + ANGLE_TRY(generateMip(destSurface, sourceSurface)); dest->markDirty(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) @@ -128,17 +123,17 @@ gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface HRESULT result; - result = source->LockRect(&sourceLock, NULL, 0); + result = source->LockRect(&sourceLock, nullptr, 0); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock source surface for copy, " << gl::FmtHR(result); } - result = dest->LockRect(&destLock, NULL, 0); + result = dest->LockRect(&destLock, nullptr, 0); if (FAILED(result)) { source->UnlockRect(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock source surface for copy, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock source surface for copy, " << gl::FmtHR(result); } ASSERT(sourceLock.pBits && destLock.pBits); @@ -161,7 +156,85 @@ gl::Error Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface source->UnlockRect(); dest->UnlockRect(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +// static +gl::Error Image9::CopyImage(const gl::Context *context, + Image9 *dest, + Image9 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + IDirect3DSurface9 *sourceSurface = nullptr; + ANGLE_TRY(source->getSurface(&sourceSurface)); + + IDirect3DSurface9 *destSurface = nullptr; + ANGLE_TRY(dest->getSurface(&destSurface)); + + D3DSURFACE_DESC destDesc; + HRESULT result = destSurface->GetDesc(&destDesc); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() + << "Failed to query the source surface description for mipmap generation, " + << gl::FmtHR(result); + } + const d3d9::D3DFormat &destD3DFormatInfo = d3d9::GetD3DFormatInfo(destDesc.Format); + + D3DSURFACE_DESC sourceDesc; + result = sourceSurface->GetDesc(&sourceDesc); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() + << "Failed to query the destination surface description for mipmap generation, " + << gl::FmtHR(result); + } + const d3d9::D3DFormat &sourceD3DFormatInfo = d3d9::GetD3DFormatInfo(sourceDesc.Format); + + D3DLOCKED_RECT sourceLocked = {0}; + result = sourceSurface->LockRect(&sourceLocked, nullptr, D3DLOCK_READONLY); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() << "Failed to lock the source surface for CopyImage, " + << gl::FmtHR(result); + } + + D3DLOCKED_RECT destLocked = {0}; + result = destSurface->LockRect(&destLocked, nullptr, 0); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + sourceSurface->UnlockRect(); + return gl::OutOfMemory() << "Failed to lock the destination surface for CopyImage, " + << gl::FmtHR(result); + } + + const uint8_t *sourceData = reinterpret_cast(sourceLocked.pBits) + + sourceRect.x * sourceD3DFormatInfo.pixelBytes + + sourceRect.y * sourceLocked.Pitch; + uint8_t *destData = reinterpret_cast(destLocked.pBits) + + destOffset.x * destD3DFormatInfo.pixelBytes + + destOffset.y * destLocked.Pitch; + ASSERT(sourceData && destData); + + CopyImageCHROMIUM(sourceData, sourceLocked.Pitch, sourceD3DFormatInfo.pixelBytes, + sourceD3DFormatInfo.info().colorReadFunction, destData, destLocked.Pitch, + destD3DFormatInfo.pixelBytes, destD3DFormatInfo.info().colorWriteFunction, + gl::GetUnsizedFormat(dest->getInternalFormat()), + destD3DFormatInfo.info().componentType, sourceRect.width, sourceRect.height, + unpackFlipY, unpackPremultiplyAlpha, unpackUnmultiplyAlpha); + + destSurface->UnlockRect(); + sourceSurface->UnlockRect(); + + return gl::NoError(); } bool Image9::redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) @@ -189,7 +262,7 @@ bool Image9::redefine(GLenum target, GLenum internalformat, const gl::Extents &s mRenderable = (d3d9FormatInfo.renderFormat != D3DFMT_UNKNOWN); SafeRelease(mSurface); - mDirty = (d3d9FormatInfo.dataInitializerFunction != NULL); + mDirty = (d3d9FormatInfo.dataInitializerFunction != nullptr); return true; } @@ -201,11 +274,11 @@ gl::Error Image9::createSurface() { if (mSurface) { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - IDirect3DTexture9 *newTexture = NULL; - IDirect3DSurface9 *newSurface = NULL; + IDirect3DTexture9 *newTexture = nullptr; + IDirect3DSurface9 *newSurface = nullptr; const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; const D3DFORMAT d3dFormat = getD3DFormat(); @@ -218,20 +291,20 @@ gl::Error Image9::createSurface() IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat, - poolToUse, &newTexture, NULL); + HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, + d3dFormat, poolToUse, &newTexture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create image surface, " << gl::FmtHR(result); } newTexture->GetSurfaceLevel(levelToFetch, &newSurface); SafeRelease(newTexture); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); - if (d3dFormatInfo.dataInitializerFunction != NULL) + if (d3dFormatInfo.dataInitializerFunction != nullptr) { RECT entireRect; entireRect.left = 0; @@ -244,7 +317,7 @@ gl::Error Image9::createSurface() ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock image surface, " << gl::FmtHR(result); } d3dFormatInfo.dataInitializerFunction(mWidth, mHeight, 1, reinterpret_cast(lockedRect.pBits), @@ -254,7 +327,7 @@ gl::Error Image9::createSurface() ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to unlock image surface, " << gl::FmtHR(result); } } } @@ -263,7 +336,7 @@ gl::Error Image9::createSurface() mDirty = false; mD3DPool = poolToUse; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect) @@ -280,13 +353,13 @@ gl::Error Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT &rect) ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock image surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to lock image surface, " << gl::FmtHR(result); } mDirty = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Image9::unlock() @@ -294,7 +367,6 @@ void Image9::unlock() if (mSurface) { HRESULT result = mSurface->UnlockRect(); - UNUSED_ASSERTION_VARIABLE(result); ASSERT(SUCCEEDED(result)); } } @@ -312,7 +384,9 @@ bool Image9::isDirty() const { // Make sure to that this image is marked as dirty even if the staging texture hasn't been created yet // if initialization is required before use. - return (mSurface || d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != NULL) && mDirty; + return (mSurface || + d3d9::GetTextureFormatInfo(mInternalFormat).dataInitializerFunction != nullptr) && + mDirty; } gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) @@ -324,14 +398,16 @@ gl::Error Image9::getSurface(IDirect3DSurface9 **outSurface) } *outSurface = mSurface; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) +gl::Error Image9::setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) { - IDirect3DSurface9 *surface = NULL; + IDirect3DSurface9 *surface = nullptr; TextureStorage9 *storage9 = GetAs(storage); - gl::Error error = storage9->getSurfaceLevel(GL_TEXTURE_2D, level, false, &surface); + gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_2D, level, false, &surface); if (error.isError()) { return error; @@ -339,12 +415,15 @@ gl::Error Image9::setManagedSurface2D(TextureStorage *storage, int level) return setManagedSurface(surface); } -gl::Error Image9::setManagedSurfaceCube(TextureStorage *storage, int face, int level) +gl::Error Image9::setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) { - IDirect3DSurface9 *surface = NULL; + IDirect3DSurface9 *surface = nullptr; TextureStorage9 *storage9 = GetAs(storage); - gl::Error error = - storage9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false, &surface); + gl::Error error = storage9->getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, + level, false, &surface); if (error.isError()) { return error; @@ -374,10 +453,13 @@ gl::Error Image9::setManagedSurface(IDirect3DSurface9 *surface) mD3DPool = desc.Pool; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion) +gl::Error Image9::copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) { gl::Error error = createSurface(); if (error.isError()) @@ -387,11 +469,12 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i TextureStorage9 *storage9 = GetAs(storage); - IDirect3DSurface9 *destSurface = NULL; + IDirect3DSurface9 *destSurface = nullptr; if (index.type == GL_TEXTURE_2D) { - error = storage9->getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, true, &destSurface); + error = + storage9->getSurfaceLevel(context, GL_TEXTURE_2D, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -400,7 +483,7 @@ gl::Error Image9::copyToStorage(TextureStorage *storage, const gl::ImageIndex &i else { ASSERT(gl::IsCubeMapTextureTarget(index.type)); - error = storage9->getSurfaceLevel(index.type, index.mipIndex, true, &destSurface); + error = storage9->getSurfaceLevel(context, index.type, index.mipIndex, true, &destSurface); if (error.isError()) { return error; @@ -417,7 +500,7 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &a ASSERT(area.width > 0 && area.height > 0 && area.depth == 1); ASSERT(destSurface); - IDirect3DSurface9 *sourceSurface = NULL; + IDirect3DSurface9 *sourceSurface = nullptr; gl::Error error = getSurface(&sourceSurface); if (error.isError()) { @@ -442,19 +525,22 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &a sourceSurface->GetDesc(&desc); IDirect3DSurface9 *surf = 0; - HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &surf, nullptr); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal CreateOffscreenPlainSurface call failed, result: 0x%X.", result); + return gl::OutOfMemory() + << "Internal CreateOffscreenPlainSurface call failed, " << gl::FmtHR(result); } - copyLockableSurfaces(surf, sourceSurface); + auto err = copyLockableSurfaces(surf, sourceSurface); result = device->UpdateSurface(surf, &rect, destSurface, &point); SafeRelease(surf); + ANGLE_TRY(err); ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result); + return gl::OutOfMemory() << "Internal UpdateSurface call failed, " << gl::FmtHR(result); } } else @@ -464,27 +550,36 @@ gl::Error Image9::copyToSurface(IDirect3DSurface9 *destSurface, const gl::Box &a ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal UpdateSurface call failed, result: 0x%X.", result); + return gl::OutOfMemory() << "Internal UpdateSurface call failed, " << gl::FmtHR(result); } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input // into the target pixel rectangle. -gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input) +gl::Error Image9::loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) { // 3D textures are not supported by the D3D9 backend. ASSERT(area.z == 0 && area.depth == 1); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - GLsizei inputRowPitch = formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength); - GLsizei inputSkipBytes = formatInfo.computeSkipPixels(inputRowPitch, 0, unpack.skipImages, - unpack.skipRows, unpack.skipPixels); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLuint inputRowPitch = 0; + ANGLE_TRY_RESULT( + formatInfo.computeRowPitch(type, area.width, unpack.alignment, unpack.rowLength), + inputRowPitch); + ASSERT(!applySkipImages); + ASSERT(unpack.skipPixels == 0); + ASSERT(unpack.skipRows == 0); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); - ASSERT(d3dFormatInfo.loadFunction != NULL); + ASSERT(d3dFormatInfo.loadFunction != nullptr); RECT lockRect = { @@ -500,31 +595,34 @@ gl::Error Image9::loadData(const gl::Box &area, const gl::PixelUnpackState &unpa } d3dFormatInfo.loadFunction(area.width, area.height, area.depth, - reinterpret_cast(input) + inputSkipBytes, - inputRowPitch, 0, reinterpret_cast(locked.pBits), - locked.Pitch, 0); + reinterpret_cast(input), inputRowPitch, 0, + reinterpret_cast(locked.pBits), locked.Pitch, 0); unlock(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) +gl::Error Image9::loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) { // 3D textures are not supported by the D3D9 backend. ASSERT(area.z == 0 && area.depth == 1); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(mInternalFormat); - GLsizei inputRowPitch = formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0); - GLsizei inputDepthPitch = - formatInfo.computeDepthPitch(GL_UNSIGNED_BYTE, area.width, area.height, 1, 0, 0); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(mInternalFormat); + GLsizei inputRowPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeRowPitch(GL_UNSIGNED_BYTE, area.width, 1, 0), inputRowPitch); + GLsizei inputDepthPitch = 0; + ANGLE_TRY_RESULT(formatInfo.computeDepthPitch(area.height, 0, inputDepthPitch), + inputDepthPitch); const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(mInternalFormat); ASSERT(area.x % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockWidth == 0); ASSERT(area.y % d3d9::GetD3DFormatInfo(d3d9FormatInfo.texFormat).blockHeight == 0); - ASSERT(d3d9FormatInfo.loadFunction != NULL); + ASSERT(d3d9FormatInfo.loadFunction != nullptr); RECT lockRect = { @@ -545,7 +643,7 @@ gl::Error Image9::loadCompressedData(const gl::Box &area, const void *input) unlock(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } // This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures @@ -565,16 +663,19 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, IDirect3DDevice9 *device = mRenderer->getDevice(); - IDirect3DSurface9 *renderTargetData = NULL; + IDirect3DSurface9 *renderTargetData = nullptr; D3DSURFACE_DESC description; surface->GetDesc(&description); - HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); + HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, + description.Format, D3DPOOL_SYSTEMMEM, + &renderTargetData, nullptr); if (FAILED(result)) { SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "Could not create matching destination surface, result: 0x%X.", result); + return gl::OutOfMemory() << "Could not create matching destination surface, " + << gl::FmtHR(result); } result = device->GetRenderTargetData(surface, renderTargetData); @@ -583,7 +684,8 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, { SafeRelease(renderTargetData); SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "GetRenderTargetData unexpectedly failed, result: 0x%X.", result); + return gl::OutOfMemory() << "GetRenderTargetData unexpectedly failed, " + << gl::FmtHR(result); } int width = sourceArea.width; @@ -599,7 +701,9 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, { SafeRelease(renderTargetData); SafeRelease(surface); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock the source surface (rectangle might be invalid), result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to lock the source surface (rectangle might be invalid), " + << gl::FmtHR(result); } D3DLOCKED_RECT destLock = {0}; @@ -776,13 +880,15 @@ gl::Error Image9::copyFromRTInternal(const gl::Offset &destOffset, SafeRelease(surface); mDirty = true; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Image9::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) +gl::Error Image9::copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) { RenderTargetD3D *renderTarget = nullptr; - gl::Error error = source->getRenderTarget(imageIndex, &renderTarget); + gl::Error error = source->getRenderTarget(context, imageIndex, &renderTarget); if (error.isError()) { return error; @@ -792,15 +898,16 @@ gl::Error Image9::copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureSt return copyFromRTInternal(gl::Offset(), sourceArea, renderTarget); } -gl::Error Image9::copyFromFramebuffer(const gl::Offset &destOffset, +gl::Error Image9::copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) { const gl::FramebufferAttachment *srcAttachment = source->getReadColorbuffer(); ASSERT(srcAttachment); - RenderTargetD3D *renderTarget = NULL; - gl::Error error = srcAttachment->getRenderTarget(&renderTarget); + RenderTargetD3D *renderTarget = nullptr; + gl::Error error = srcAttachment->getRenderTarget(context, &renderTarget); if (error.isError()) { return error; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h index 91448cc849..01c60dc4fb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Image9.h @@ -26,27 +26,53 @@ class Image9 : public ImageD3D { public: Image9(Renderer9 *renderer); - ~Image9(); + ~Image9() override; static gl::Error generateMipmap(Image9 *dest, Image9 *source); static gl::Error generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); static gl::Error copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); + static gl::Error CopyImage(const gl::Context *context, + Image9 *dest, + Image9 *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha); bool redefine(GLenum target, GLenum internalformat, const gl::Extents &size, bool forceRelease) override; D3DFORMAT getD3DFormat() const; - virtual bool isDirty() const; - - virtual gl::Error setManagedSurface2D(TextureStorage *storage, int level); - virtual gl::Error setManagedSurfaceCube(TextureStorage *storage, int face, int level); - virtual gl::Error copyToStorage(TextureStorage *storage, const gl::ImageIndex &index, const gl::Box ®ion); - - virtual gl::Error loadData(const gl::Box &area, const gl::PixelUnpackState &unpack, GLenum type, const void *input); - virtual gl::Error loadCompressedData(const gl::Box &area, const void *input); - - gl::Error copyFromTexStorage(const gl::ImageIndex &imageIndex, TextureStorage *source) override; - gl::Error copyFromFramebuffer(const gl::Offset &destOffset, + bool isDirty() const override; + + gl::Error setManagedSurface2D(const gl::Context *context, + TextureStorage *storage, + int level) override; + gl::Error setManagedSurfaceCube(const gl::Context *context, + TextureStorage *storage, + int face, + int level) override; + gl::Error copyToStorage(const gl::Context *context, + TextureStorage *storage, + const gl::ImageIndex &index, + const gl::Box ®ion) override; + + gl::Error loadData(const gl::Context *context, + const gl::Box &area, + const gl::PixelUnpackState &unpack, + GLenum type, + const void *input, + bool applySkipImages) override; + gl::Error loadCompressedData(const gl::Context *context, + const gl::Box &area, + const void *input) override; + + gl::Error copyFromTexStorage(const gl::Context *context, + const gl::ImageIndex &imageIndex, + TextureStorage *source) override; + gl::Error copyFromFramebuffer(const gl::Context *context, + const gl::Offset &destOffset, const gl::Rectangle &sourceArea, const gl::Framebuffer *source) override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp index 97c7f72136..df86331766 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.cpp @@ -14,7 +14,7 @@ namespace rx IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) { - mIndexBuffer = NULL; + mIndexBuffer = nullptr; mBufferSize = 0; mIndexType = 0; mDynamic = false; @@ -40,7 +40,7 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo } else if (indexType == GL_UNSIGNED_INT) { - ASSERT(mRenderer->getRendererExtensions().elementIndexUint); + ASSERT(mRenderer->getNativeExtensions().elementIndexUint); format = D3DFMT_INDEX32; } else UNREACHABLE(); @@ -54,7 +54,8 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal index buffer of size, %lu.", bufferSize); + return gl::OutOfMemory() + << "Failed to allocate internal index buffer of size " << bufferSize; } } @@ -62,43 +63,43 @@ gl::Error IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bo mIndexType = indexType; mDynamic = dynamic; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) { if (!mIndexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; - void *mapPtr = NULL; + void *mapPtr = nullptr; HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to lock internal index buffer, " << gl::FmtHR(result); } *outMappedMemory = mapPtr; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error IndexBuffer9::unmapBuffer() { if (!mIndexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } HRESULT result = mIndexBuffer->Unlock(); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to unlock internal index buffer, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } GLenum IndexBuffer9::getIndexType() const @@ -119,7 +120,7 @@ gl::Error IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) } else { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -127,7 +128,7 @@ gl::Error IndexBuffer9::discard() { if (!mIndexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal index buffer is not initialized."); + return gl::OutOfMemory() << "Internal index buffer is not initialized."; } void *dummy; @@ -136,16 +137,16 @@ gl::Error IndexBuffer9::discard() result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to lock internal index buffer, " << gl::FmtHR(result); } result = mIndexBuffer->Unlock(); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal index buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to unlock internal index buffer, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } D3DFORMAT IndexBuffer9::getIndexFormat() const diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h index ba03ba703f..5921d2a859 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/IndexBuffer9.h @@ -19,18 +19,18 @@ class IndexBuffer9 : public IndexBuffer { public: explicit IndexBuffer9(Renderer9 *const renderer); - virtual ~IndexBuffer9(); + ~IndexBuffer9() override; - virtual gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + gl::Error initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) override; - virtual gl::Error mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual gl::Error unmapBuffer(); + gl::Error mapBuffer(unsigned int offset, unsigned int size, void **outMappedMemory) override; + gl::Error unmapBuffer() override; - virtual GLenum getIndexType() const; - virtual unsigned int getBufferSize() const; - virtual gl::Error setSize(unsigned int bufferSize, GLenum indexType); + GLenum getIndexType() const override; + unsigned int getBufferSize() const override; + gl::Error setSize(unsigned int bufferSize, GLenum indexType) override; - virtual gl::Error discard(); + gl::Error discard() override; D3DFORMAT getIndexFormat() const; IDirect3DIndexBuffer9 *getBuffer() const; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp new file mode 100644 index 0000000000..388b8aa168 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.cpp @@ -0,0 +1,39 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow9.cpp: Defines NativeWindow9, a class for managing and +// performing operations on an EGLNativeWindowType for the D3D9 renderer. + +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" + +namespace rx +{ +NativeWindow9::NativeWindow9(EGLNativeWindowType window) : NativeWindowD3D(window) +{ +} + +bool NativeWindow9::initialize() +{ + return true; +} + +bool NativeWindow9::getClientRect(LPRECT rect) const +{ + return GetClientRect(getNativeWindow(), rect) == TRUE; +} + +bool NativeWindow9::isIconic() const +{ + return IsIconic(getNativeWindow()) == TRUE; +} + +// static +bool NativeWindow9::IsValidNativeWindow(EGLNativeWindowType window) +{ + return IsWindow(window) == TRUE; +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h new file mode 100644 index 0000000000..a56b08dc81 --- /dev/null +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/NativeWindow9.h @@ -0,0 +1,35 @@ +// +// Copyright (c) 2016 The ANGLE Project Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. +// + +// NativeWindow9.h: Defines NativeWindow9, a class for managing and +// performing operations on an EGLNativeWindowType for the D3D9 renderer. + +#ifndef LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ +#define LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ + +#include "common/debug.h" +#include "common/platform.h" + +#include "libANGLE/renderer/d3d/NativeWindowD3D.h" + +namespace rx +{ + +class NativeWindow9 : public NativeWindowD3D +{ + public: + explicit NativeWindow9(EGLNativeWindowType window); + + bool initialize() override; + bool getClientRect(LPRECT rect) const override; + bool isIconic() const override; + + static bool IsValidNativeWindow(EGLNativeWindowType window); +}; + +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_NATIVEWINDOW9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp index c826abf81c..4ba053e6bd 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.cpp @@ -19,7 +19,7 @@ Query9::Query9(Renderer9 *renderer, GLenum type) mResult(GL_FALSE), mQueryFinished(false), mRenderer(renderer), - mQuery(NULL) + mQuery(nullptr) { } @@ -30,23 +30,27 @@ Query9::~Query9() gl::Error Query9::begin() { - if (mQuery == NULL) + D3DQUERYTYPE d3dQueryType = gl_d3d9::ConvertQueryType(getType()); + if (mQuery == nullptr) { - HRESULT result = mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery); + HRESULT result = mRenderer->getDevice()->CreateQuery(d3dQueryType, &mQuery); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal query creation failed, result: 0x%X.", result); + return gl::OutOfMemory() << "Internal query creation failed, " << gl::FmtHR(result); } } - HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); - ASSERT(SUCCEEDED(result)); - if (FAILED(result)) + if (d3dQueryType != D3DQUERYTYPE_EVENT) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to begin internal query, result: 0x%X.", result); + HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); + ASSERT(SUCCEEDED(result)); + if (FAILED(result)) + { + return gl::OutOfMemory() << "Failed to begin internal query, " << gl::FmtHR(result); + } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::end() @@ -57,19 +61,19 @@ gl::Error Query9::end() ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to end internal query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to end internal query, " << gl::FmtHR(result); } mQueryFinished = false; mResult = GL_FALSE; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::queryCounter() { UNIMPLEMENTED(); - return gl::Error(GL_INVALID_OPERATION, "Unimplemented"); + return gl::InternalError() << "Unimplemented"; } template @@ -91,7 +95,7 @@ gl::Error Query9::getResultBase(T *params) ASSERT(mQueryFinished); *params = static_cast(mResult); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::getResult(GLint *params) @@ -124,7 +128,7 @@ gl::Error Query9::isResultAvailable(bool *available) *available = mQueryFinished; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Query9::testQuery() @@ -133,38 +137,52 @@ gl::Error Query9::testQuery() { ASSERT(mQuery); - DWORD numPixels = 0; - - HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); - if (hres == S_OK) + HRESULT result = S_OK; + switch (getType()) { - mQueryFinished = true; + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + { + DWORD numPixels = 0; + result = mQuery->GetData(&numPixels, sizeof(numPixels), D3DGETDATA_FLUSH); + if (result == S_OK) + { + mQueryFinished = true; + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + } + break; + } - switch (getType()) + case GL_COMMANDS_COMPLETED_CHROMIUM: { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + BOOL completed = FALSE; + result = mQuery->GetData(&completed, sizeof(completed), D3DGETDATA_FLUSH); + if (result == S_OK) + { + mQueryFinished = true; + mResult = (completed == TRUE) ? GL_TRUE : GL_FALSE; + } break; + } - default: + default: UNREACHABLE(); break; - } } - else if (d3d9::isDeviceLostError(hres)) + + if (d3d9::isDeviceLostError(result)) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + return gl::OutOfMemory() << "Failed to test get query result, device is lost."; } else if (mRenderer->testDeviceLost()) { mRenderer->notifyDeviceLost(); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to test get query result, device is lost."); + return gl::OutOfMemory() << "Failed to test get query result, device is lost."; } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h index 9d17711a00..6c7c22f096 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Query9.h @@ -19,16 +19,16 @@ class Query9 : public QueryImpl { public: Query9(Renderer9 *renderer, GLenum type); - virtual ~Query9(); - - virtual gl::Error begin(); - virtual gl::Error end(); - virtual gl::Error queryCounter(); - virtual gl::Error getResult(GLint *params); - virtual gl::Error getResult(GLuint *params); - virtual gl::Error getResult(GLint64 *params); - virtual gl::Error getResult(GLuint64 *params); - virtual gl::Error isResultAvailable(bool *available); + ~Query9() override; + + gl::Error begin() override; + gl::Error end() override; + gl::Error queryCounter() override; + gl::Error getResult(GLint *params) override; + gl::Error getResult(GLuint *params) override; + gl::Error getResult(GLint64 *params) override; + gl::Error getResult(GLuint64 *params) override; + gl::Error isResultAvailable(bool *available) override; private: gl::Error testQuery(); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp index 419bff1f63..3e54c27f43 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.cpp @@ -130,7 +130,8 @@ GLsizei SurfaceRenderTarget9::getDepth() const GLenum SurfaceRenderTarget9::getInternalFormat() const { - return (mDepth ? mSwapChain->GetDepthBufferInternalFormat() : mSwapChain->GetRenderTargetInternalFormat()); + return (mDepth ? mSwapChain->getDepthBufferInternalFormat() + : mSwapChain->getRenderTargetInternalFormat()); } GLsizei SurfaceRenderTarget9::getSamples() const diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h index f19c54de7b..bb3b5a4ee4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/RenderTarget9.h @@ -21,7 +21,7 @@ class RenderTarget9 : public RenderTargetD3D { public: RenderTarget9() { } - virtual ~RenderTarget9() { } + ~RenderTarget9() override {} // Retrieve the texture that backs this render target, may be null for swap chain render // targets. virtual IDirect3DBaseTexture9 *getTexture() const = 0; @@ -43,7 +43,7 @@ class TextureRenderTarget9 : public RenderTarget9 GLsizei height, GLsizei depth, GLsizei samples); - virtual ~TextureRenderTarget9(); + ~TextureRenderTarget9() override; GLsizei getWidth() const override; GLsizei getHeight() const override; @@ -74,7 +74,7 @@ class SurfaceRenderTarget9 : public RenderTarget9 { public: SurfaceRenderTarget9(SwapChain9 *swapChain, bool depth); - virtual ~SurfaceRenderTarget9(); + ~SurfaceRenderTarget9() override; GLsizei getWidth() const override; GLsizei getHeight() const override; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp index 6bb975b0e4..75c6298868 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.cpp @@ -8,51 +8,51 @@ #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include #include +#include #include "common/utilities.h" -#include "libANGLE/angletypes.h" #include "libANGLE/Buffer.h" +#include "libANGLE/Context.h" #include "libANGLE/Display.h" -#include "libANGLE/features.h" -#include "libANGLE/formatutils.h" #include "libANGLE/Framebuffer.h" #include "libANGLE/FramebufferAttachment.h" #include "libANGLE/Program.h" #include "libANGLE/Renderbuffer.h" +#include "libANGLE/State.h" +#include "libANGLE/Surface.h" +#include "libANGLE/Texture.h" +#include "libANGLE/angletypes.h" +#include "libANGLE/features.h" +#include "libANGLE/formatutils.h" +#include "libANGLE/renderer/d3d/CompilerD3D.h" +#include "libANGLE/renderer/d3d/DeviceD3D.h" +#include "libANGLE/renderer/d3d/FramebufferD3D.h" +#include "libANGLE/renderer/d3d/IndexDataManager.h" +#include "libANGLE/renderer/d3d/ProgramD3D.h" +#include "libANGLE/renderer/d3d/RenderbufferD3D.h" +#include "libANGLE/renderer/d3d/ShaderD3D.h" +#include "libANGLE/renderer/d3d/SurfaceD3D.h" +#include "libANGLE/renderer/d3d/TextureD3D.h" #include "libANGLE/renderer/d3d/d3d9/Blit9.h" #include "libANGLE/renderer/d3d/d3d9/Buffer9.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" #include "libANGLE/renderer/d3d/d3d9/Fence9.h" -#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/Framebuffer9.h" #include "libANGLE/renderer/d3d/d3d9/Image9.h" #include "libANGLE/renderer/d3d/d3d9/IndexBuffer9.h" +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" #include "libANGLE/renderer/d3d/d3d9/Query9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h" #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" #include "libANGLE/renderer/d3d/d3d9/TextureStorage9.h" #include "libANGLE/renderer/d3d/d3d9/VertexArray9.h" #include "libANGLE/renderer/d3d/d3d9/VertexBuffer9.h" -#include "libANGLE/renderer/d3d/CompilerD3D.h" -#include "libANGLE/renderer/d3d/DeviceD3D.h" -#include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/d3d/IndexDataManager.h" -#include "libANGLE/renderer/d3d/ProgramD3D.h" -#include "libANGLE/renderer/d3d/RenderbufferD3D.h" -#include "libANGLE/renderer/d3d/ShaderD3D.h" -#include "libANGLE/renderer/d3d/SurfaceD3D.h" -#include "libANGLE/renderer/d3d/TextureD3D.h" -#include "libANGLE/renderer/d3d/TransformFeedbackD3D.h" -#include "libANGLE/State.h" -#include "libANGLE/Surface.h" -#include "libANGLE/Texture.h" +#include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" #include "third_party/trace_event/trace_event.h" - - #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 #endif @@ -69,69 +69,69 @@ namespace rx enum { MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256, - MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32, - MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224, - MAX_VARYING_VECTORS_SM2 = 8, - MAX_VARYING_VECTORS_SM3 = 10, + MAX_PIXEL_CONSTANT_VECTORS_SM2 = 32, + MAX_PIXEL_CONSTANT_VECTORS_SM3 = 224, + MAX_VARYING_VECTORS_SM2 = 8, + MAX_VARYING_VECTORS_SM3 = 10, MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 }; Renderer9::Renderer9(egl::Display *display) : RendererD3D(display), mStateManager(this) { - mD3d9Module = NULL; + mD3d9Module = nullptr; - mD3d9 = NULL; - mD3d9Ex = NULL; - mDevice = NULL; - mDeviceEx = NULL; - mDeviceWindow = NULL; - mBlit = NULL; + mD3d9 = nullptr; + mD3d9Ex = nullptr; + mDevice = nullptr; + mDeviceEx = nullptr; + mDeviceWindow = nullptr; + mBlit = nullptr; mAdapter = D3DADAPTER_DEFAULT; const egl::AttributeMap &attributes = display->getAttributeMap(); - EGLint requestedDeviceType = attributes.get(EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, - EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE); + EGLint requestedDeviceType = static_cast(attributes.get( + EGL_PLATFORM_ANGLE_DEVICE_TYPE_ANGLE, EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE)); switch (requestedDeviceType) { - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: - mDeviceType = D3DDEVTYPE_HAL; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_HARDWARE_ANGLE: + mDeviceType = D3DDEVTYPE_HAL; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: - mDeviceType = D3DDEVTYPE_REF; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_REFERENCE_ANGLE: + mDeviceType = D3DDEVTYPE_REF; + break; - case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: - mDeviceType = D3DDEVTYPE_NULLREF; - break; + case EGL_PLATFORM_ANGLE_DEVICE_TYPE_NULL_ANGLE: + mDeviceType = D3DDEVTYPE_NULLREF; + break; - default: - UNREACHABLE(); + default: + UNREACHABLE(); } - mMaskedClearSavedState = NULL; + mMaskedClearSavedState = nullptr; - mVertexDataManager = NULL; - mIndexDataManager = NULL; - mLineLoopIB = NULL; - mCountingIB = NULL; + mVertexDataManager = nullptr; + mIndexDataManager = nullptr; + mLineLoopIB = nullptr; + mCountingIB = nullptr; mMaxNullColorbufferLRU = 0; for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { mNullColorbufferCache[i].lruCount = 0; - mNullColorbufferCache[i].width = 0; - mNullColorbufferCache[i].height = 0; - mNullColorbufferCache[i].buffer = NULL; + mNullColorbufferCache[i].width = 0; + mNullColorbufferCache[i].height = 0; + mNullColorbufferCache[i].buffer = nullptr; } - mAppliedVertexShader = NULL; - mAppliedPixelShader = NULL; + mAppliedVertexShader = nullptr; + mAppliedPixelShader = nullptr; mAppliedProgramSerial = 0; - initializeDebugAnnotator(); + gl::InitializeDebugAnnotations(&mAnnotator); mEGLDevice = nullptr; } @@ -154,6 +154,10 @@ void Renderer9::release() { RendererD3D::cleanup(); + gl::UninitializeDebugAnnotations(); + + mTranslatedAttribCache.clear(); + releaseDeviceResources(); SafeDelete(mEGLDevice); @@ -167,10 +171,10 @@ void Renderer9::release() if (mDeviceWindow) { DestroyWindow(mDeviceWindow); - mDeviceWindow = NULL; + mDeviceWindow = nullptr; } - mD3d9Module = NULL; + mD3d9Module = nullptr; } egl::Error Renderer9::initialize() @@ -178,22 +182,25 @@ egl::Error Renderer9::initialize() TRACE_EVENT0("gpu.angle", "GetModuleHandle_d3d9"); mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); - if (mD3d9Module == NULL) + if (mD3d9Module == nullptr) { - return egl::Error(EGL_NOT_INITIALIZED, D3D9_INIT_MISSING_DEP, "No D3D9 module found."); + return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "No D3D9 module found."; } - typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); - Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); + typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **); + Direct3DCreate9ExFunc Direct3DCreate9ExPtr = + reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); // Use Direct3D9Ex if available. Among other things, this version is less // inclined to report a lost context, for example when the user switches - // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are available. - if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + // desktop. Direct3D9Ex is available in Windows Vista and later if suitable drivers are + // available. + if (ANGLE_D3D9EX == ANGLE_ENABLED && Direct3DCreate9ExPtr && + SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) { TRACE_EVENT0("gpu.angle", "D3d9Ex_QueryInterface"); ASSERT(mD3d9Ex); - mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); + mD3d9Ex->QueryInterface(__uuidof(IDirect3D9), reinterpret_cast(&mD3d9)); ASSERT(mD3d9); } else @@ -204,12 +211,13 @@ egl::Error Renderer9::initialize() if (!mD3d9) { - return egl::Error(EGL_NOT_INITIALIZED, D3D9_INIT_MISSING_DEP, "Could not create D3D9 device."); + return egl::EglNotInitialized(D3D9_INIT_MISSING_DEP) << "Could not create D3D9 device."; } if (mDisplay->getNativeDisplayId() != nullptr) { - // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to + // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context + // corresponds to } HRESULT result; @@ -226,13 +234,14 @@ egl::Error Renderer9::initialize() } else if (result == D3DERR_NOTAVAILABLE) { - Sleep(100); // Give the driver some time to initialize/recover + Sleep(100); // Give the driver some time to initialize/recover } - else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, D3DERR_INVALIDDEVICE, or another error we can't recover from + else if (FAILED(result)) // D3DERR_OUTOFVIDEOMEMORY, E_OUTOFMEMORY, + // D3DERR_INVALIDDEVICE, or another error we can't recover + // from { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_OTHER_ERROR, - "Failed to get device caps: Error code 0x%x\n", result); + return egl::EglNotInitialized(D3D9_INIT_OTHER_ERROR) + << "Failed to get device caps, " << gl::FmtHR(result); } } } @@ -245,18 +254,17 @@ egl::Error Renderer9::initialize() if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(minShaderModel, 0)) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_UNSUPPORTED_VERSION, - "Renderer does not support PS %u.%u.aborting!", minShaderModel, 0); + return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_VERSION) + << "Renderer does not support PS " << minShaderModel << ".0, aborting!"; } - // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture to a render target texture is not supported. - // This is required by Texture2D::ensureRenderTarget. + // When DirectX9 is running with an older DirectX8 driver, a StretchRect from a regular texture + // to a render target texture is not supported. This is required by + // Texture2D::ensureRenderTarget. if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) { - return egl::Error(EGL_NOT_INITIALIZED, - D3D9_INIT_UNSUPPORTED_STRETCHRECT, - "Renderer does not support StretctRect from textures."); + return egl::EglNotInitialized(D3D9_INIT_UNSUPPORTED_STRETCHRECT) + << "Renderer does not support StretctRect from textures."; } { @@ -265,43 +273,52 @@ egl::Error Renderer9::initialize() } static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); - static const TCHAR className[] = TEXT("STATIC"); + static const TCHAR className[] = TEXT("STATIC"); { TRACE_EVENT0("gpu.angle", "CreateWindowEx"); - mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + mDeviceWindow = + CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, + 1, HWND_MESSAGE, nullptr, GetModuleHandle(nullptr), nullptr); } D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; + DWORD behaviorFlags = + D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES | D3DCREATE_MULTITHREADED; { TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice"); - result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, &presentParameters, &mDevice); + result = mD3d9->CreateDevice( + mAdapter, mDeviceType, mDeviceWindow, + behaviorFlags | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_PUREDEVICE, + &presentParameters, &mDevice); } if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DEVICELOST) { - return egl::Error(EGL_BAD_ALLOC, D3D9_INIT_OUT_OF_MEMORY, - "CreateDevice failed: device lost of out of memory"); + return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY) + << "CreateDevice failed: device lost of out of memory"; } if (FAILED(result)) { TRACE_EVENT0("gpu.angle", "D3d9_CreateDevice2"); - result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, &presentParameters, &mDevice); + result = mD3d9->CreateDevice(mAdapter, mDeviceType, mDeviceWindow, + behaviorFlags | D3DCREATE_SOFTWARE_VERTEXPROCESSING, + &presentParameters, &mDevice); if (FAILED(result)) { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST); - return egl::Error(EGL_BAD_ALLOC, D3D9_INIT_OUT_OF_MEMORY, - "CreateDevice2 failed: device lost, not available, or of out of memory"); + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || + result == D3DERR_NOTAVAILABLE || result == D3DERR_DEVICELOST); + return egl::EglBadAlloc(D3D9_INIT_OUT_OF_MEMORY) + << "CreateDevice2 failed: device lost, not available, or of out of memory"; } } if (mD3d9Ex) { TRACE_EVENT0("gpu.angle", "mDevice_QueryInterface"); - result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**)&mDeviceEx); + result = mDevice->QueryInterface(__uuidof(IDirect3DDevice9Ex), (void **)&mDeviceEx); ASSERT(SUCCEEDED(result)); } @@ -318,18 +335,19 @@ egl::Error Renderer9::initialize() // Only Direct3D 10 ready devices support all the necessary vertex texture formats. // We test this using D3D9 by checking support for the R16F format. mVertexTextureSupport = mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, - D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)); + SUCCEEDED(mD3d9->CheckDeviceFormat( + mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_QUERY_VERTEXTEXTURE, D3DRTYPE_TEXTURE, D3DFMT_R16F)); - initializeDevice(); + ANGLE_TRY(initializeDevice()); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } // do any one-time device initialization // NOTE: this is also needed after a device lost/reset // to reset the scene status and ensure the default states are reset. -void Renderer9::initializeDevice() +egl::Error Renderer9::initializeDevice() { // Permanent non-default states mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); @@ -337,14 +355,14 @@ void Renderer9::initializeDevice() if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) { - mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize); + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD &)mDeviceCaps.MaxPointSize); } else { - mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f } - const gl::Caps &rendererCaps = getRendererCaps(); + const gl::Caps &rendererCaps = getNativeCaps(); mCurVertexSamplerStates.resize(rendererCaps.maxVertexTextureImageUnits); mCurPixelSamplerStates.resize(rendererCaps.maxTextureImageUnits); @@ -358,50 +376,55 @@ void Renderer9::initializeDevice() ASSERT(!mBlit); mBlit = new Blit9(this); - mBlit->initialize(); + ANGLE_TRY(mBlit->initialize()); ASSERT(!mVertexDataManager && !mIndexDataManager); mVertexDataManager = new VertexDataManager(this); - mIndexDataManager = new IndexDataManager(this, getRendererClass()); + mIndexDataManager = new IndexDataManager(this); + + if (mVertexDataManager->initialize().isError()) + { + return egl::EglBadAlloc() << "Error initializing VertexDataManager"; + } + + mTranslatedAttribCache.resize(getNativeCaps().maxVertexAttributes); + + mStateManager.initialize(); - // TODO(jmadill): use context caps, and place in common D3D location - mTranslatedAttribCache.resize(getRendererCaps().maxVertexAttributes); + return egl::NoError(); } D3DPRESENT_PARAMETERS Renderer9::getDefaultPresentParameters() { D3DPRESENT_PARAMETERS presentParameters = {0}; - // The default swap chain is never actually used. Surface will create a new swap chain with the proper parameters. + // The default swap chain is never actually used. Surface will create a new swap chain with the + // proper parameters. presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - presentParameters.BackBufferCount = 1; - presentParameters.BackBufferFormat = D3DFMT_UNKNOWN; - presentParameters.BackBufferWidth = 1; - presentParameters.BackBufferHeight = 1; + presentParameters.BackBufferCount = 1; + presentParameters.BackBufferFormat = D3DFMT_UNKNOWN; + presentParameters.BackBufferWidth = 1; + presentParameters.BackBufferHeight = 1; presentParameters.EnableAutoDepthStencil = FALSE; - presentParameters.Flags = 0; - presentParameters.hDeviceWindow = mDeviceWindow; - presentParameters.MultiSampleQuality = 0; - presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; - presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; - presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; - presentParameters.Windowed = TRUE; + presentParameters.Flags = 0; + presentParameters.hDeviceWindow = mDeviceWindow; + presentParameters.MultiSampleQuality = 0; + presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; + presentParameters.PresentationInterval = D3DPRESENT_INTERVAL_DEFAULT; + presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + presentParameters.Windowed = TRUE; return presentParameters; } -egl::ConfigSet Renderer9::generateConfigs() const +egl::ConfigSet Renderer9::generateConfigs() { - static const GLenum colorBufferFormats[] = - { - GL_BGR5_A1_ANGLEX, - GL_BGRA8_EXT, - GL_RGB565, + static const GLenum colorBufferFormats[] = { + GL_BGR5_A1_ANGLEX, GL_BGRA8_EXT, GL_RGB565, }; - static const GLenum depthStencilBufferFormats[] = - { + static const GLenum depthStencilBufferFormats[] = { GL_NONE, GL_DEPTH_COMPONENT32_OES, GL_DEPTH24_STENCIL8_OES, @@ -409,8 +432,8 @@ egl::ConfigSet Renderer9::generateConfigs() const GL_DEPTH_COMPONENT16, }; - const gl::Caps &rendererCaps = getRendererCaps(); - const gl::TextureCapsMap &rendererTextureCaps = getRendererTextureCaps(); + const gl::Caps &rendererCaps = getNativeCaps(); + const gl::TextureCapsMap &rendererTextureCaps = getNativeTextureCaps(); D3DDISPLAYMODE currentDisplayMode; mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); @@ -449,56 +472,72 @@ egl::ConfigSet Renderer9::generateConfigs() const for (size_t formatIndex = 0; formatIndex < ArraySize(colorBufferFormats); formatIndex++) { GLenum colorBufferInternalFormat = colorBufferFormats[formatIndex]; - const gl::TextureCaps &colorBufferFormatCaps = rendererTextureCaps.get(colorBufferInternalFormat); + const gl::TextureCaps &colorBufferFormatCaps = + rendererTextureCaps.get(colorBufferInternalFormat); if (colorBufferFormatCaps.renderable) { - for (size_t depthStencilIndex = 0; depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++) + for (size_t depthStencilIndex = 0; + depthStencilIndex < ArraySize(depthStencilBufferFormats); depthStencilIndex++) { - GLenum depthStencilBufferInternalFormat = depthStencilBufferFormats[depthStencilIndex]; - const gl::TextureCaps &depthStencilBufferFormatCaps = rendererTextureCaps.get(depthStencilBufferInternalFormat); - if (depthStencilBufferFormatCaps.renderable || depthStencilBufferInternalFormat == GL_NONE) + GLenum depthStencilBufferInternalFormat = + depthStencilBufferFormats[depthStencilIndex]; + const gl::TextureCaps &depthStencilBufferFormatCaps = + rendererTextureCaps.get(depthStencilBufferInternalFormat); + if (depthStencilBufferFormatCaps.renderable || + depthStencilBufferInternalFormat == GL_NONE) { - const gl::InternalFormat &colorBufferFormatInfo = gl::GetInternalFormatInfo(colorBufferInternalFormat); - const gl::InternalFormat &depthStencilBufferFormatInfo = gl::GetInternalFormatInfo(depthStencilBufferInternalFormat); - const d3d9::TextureFormat &d3d9ColorBufferFormatInfo = d3d9::GetTextureFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &colorBufferFormatInfo = + gl::GetSizedInternalFormatInfo(colorBufferInternalFormat); + const gl::InternalFormat &depthStencilBufferFormatInfo = + gl::GetSizedInternalFormatInfo(depthStencilBufferInternalFormat); + const d3d9::TextureFormat &d3d9ColorBufferFormatInfo = + d3d9::GetTextureFormatInfo(colorBufferInternalFormat); egl::Config config; config.renderTargetFormat = colorBufferInternalFormat; config.depthStencilFormat = depthStencilBufferInternalFormat; - config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; - config.redSize = colorBufferFormatInfo.redBits; - config.greenSize = colorBufferFormatInfo.greenBits; - config.blueSize = colorBufferFormatInfo.blueBits; - config.luminanceSize = colorBufferFormatInfo.luminanceBits; - config.alphaSize = colorBufferFormatInfo.alphaBits; - config.alphaMaskSize = 0; - config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB); - config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || colorBufferFormatInfo.format == GL_BGRA_EXT); + config.bufferSize = colorBufferFormatInfo.pixelBytes * 8; + config.redSize = colorBufferFormatInfo.redBits; + config.greenSize = colorBufferFormatInfo.greenBits; + config.blueSize = colorBufferFormatInfo.blueBits; + config.luminanceSize = colorBufferFormatInfo.luminanceBits; + config.alphaSize = colorBufferFormatInfo.alphaBits; + config.alphaMaskSize = 0; + config.bindToTextureRGB = (colorBufferFormatInfo.format == GL_RGB); + config.bindToTextureRGBA = (colorBufferFormatInfo.format == GL_RGBA || + colorBufferFormatInfo.format == GL_BGRA_EXT); config.colorBufferType = EGL_RGB_BUFFER; // Mark as slow if blits to the back-buffer won't be straight forward - config.configCaveat = (currentDisplayMode.Format == d3d9ColorBufferFormatInfo.renderFormat) ? EGL_NONE : EGL_SLOW_CONFIG; - config.configID = static_cast(configs.size() + 1); - config.conformant = EGL_OPENGL_ES2_BIT; - config.depthSize = depthStencilBufferFormatInfo.depthBits; - config.level = 0; + config.configCaveat = + (currentDisplayMode.Format == d3d9ColorBufferFormatInfo.renderFormat) + ? EGL_NONE + : EGL_SLOW_CONFIG; + config.configID = static_cast(configs.size() + 1); + config.conformant = EGL_OPENGL_ES2_BIT; + config.depthSize = depthStencilBufferFormatInfo.depthBits; + config.level = 0; config.matchNativePixmap = EGL_NONE; - config.maxPBufferWidth = rendererCaps.max2DTextureSize; - config.maxPBufferHeight = rendererCaps.max2DTextureSize; - config.maxPBufferPixels = rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; - config.maxSwapInterval = maxSwapInterval; - config.minSwapInterval = minSwapInterval; + config.maxPBufferWidth = rendererCaps.max2DTextureSize; + config.maxPBufferHeight = rendererCaps.max2DTextureSize; + config.maxPBufferPixels = + rendererCaps.max2DTextureSize * rendererCaps.max2DTextureSize; + config.maxSwapInterval = maxSwapInterval; + config.minSwapInterval = minSwapInterval; config.nativeRenderable = EGL_FALSE; - config.nativeVisualID = 0; + config.nativeVisualID = 0; config.nativeVisualType = EGL_NONE; - config.renderableType = EGL_OPENGL_ES2_BIT; - config.sampleBuffers = 0; // FIXME: enumerate multi-sampling - config.samples = 0; - config.stencilSize = depthStencilBufferFormatInfo.stencilBits; - config.surfaceType = EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; - config.transparentType = EGL_NONE; - config.transparentRedValue = 0; + config.renderableType = EGL_OPENGL_ES2_BIT; + config.sampleBuffers = 0; // FIXME: enumerate multi-sampling + config.samples = 0; + config.stencilSize = depthStencilBufferFormatInfo.stencilBits; + config.surfaceType = + EGL_PBUFFER_BIT | EGL_WINDOW_BIT | EGL_SWAP_BEHAVIOR_PRESERVED_BIT; + config.transparentType = EGL_NONE; + config.transparentRedValue = 0; config.transparentGreenValue = 0; - config.transparentBlueValue = 0; + config.transparentBlueValue = 0; + config.colorComponentType = gl_egl::GLComponentTypeToEGLColorComponentType( + colorBufferFormatInfo.componentType); configs.add(config); } @@ -519,13 +558,12 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) outExtensions->d3dShareHandleClientBuffer = true; outExtensions->surfaceD3DTexture2DShareHandle = true; } + outExtensions->d3dTextureClientBuffer = true; outExtensions->querySurfacePointer = true; outExtensions->windowFixedSize = true; outExtensions->postSubBuffer = true; - outExtensions->createContext = true; outExtensions->deviceQuery = true; - outExtensions->createContextNoError = true; outExtensions->image = true; outExtensions->imageBase = true; @@ -533,6 +571,14 @@ void Renderer9::generateDisplayExtensions(egl::DisplayExtensions *outExtensions) outExtensions->glRenderbufferImage = true; outExtensions->flexibleSurfaceCompatibility = true; + + // Contexts are virtualized so textures can be shared globally + outExtensions->displayTextureShareGroup = true; + + // D3D9 can be used without an output surface + outExtensions->surfacelessContext = true; + + outExtensions->robustResourceInitialization = true; } void Renderer9::startScene() @@ -540,7 +586,8 @@ void Renderer9::startScene() if (!mSceneStarted) { long result = mDevice->BeginScene(); - if (SUCCEEDED(result)) { + if (SUCCEEDED(result)) + { // This is defensive checking against the device being // lost at unexpected times. mSceneStarted = true; @@ -561,8 +608,8 @@ void Renderer9::endScene() gl::Error Renderer9::flush() { - IDirect3DQuery9* query = NULL; - gl::Error error = allocateEventQuery(&query); + IDirect3DQuery9 *query = nullptr; + gl::Error error = allocateEventQuery(&query); if (error.isError()) { return error; @@ -572,11 +619,11 @@ gl::Error Renderer9::flush() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to issue event query, " << gl::FmtHR(result); } // Grab the query data once - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); freeEventQuery(query); if (FAILED(result)) { @@ -585,16 +632,16 @@ gl::Error Renderer9::flush() notifyDeviceLost(); } - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer9::finish() { - IDirect3DQuery9* query = NULL; - gl::Error error = allocateEventQuery(&query); + IDirect3DQuery9 *query = nullptr; + gl::Error error = allocateEventQuery(&query); if (error.isError()) { return error; @@ -604,11 +651,11 @@ gl::Error Renderer9::finish() if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to issue event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to issue event query, " << gl::FmtHR(result); } // Grab the query data once - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); if (FAILED(result)) { if (d3d9::isDeviceLostError(result)) @@ -617,7 +664,7 @@ gl::Error Renderer9::finish() } freeEventQuery(query); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } // Loop until the query completes @@ -626,7 +673,7 @@ gl::Error Renderer9::finish() // Keep polling, but allow other threads to do something useful first ScheduleYield(); - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + result = query->GetData(nullptr, 0, D3DGETDATA_FLUSH); // explicitly check for device loss // some drivers seem to return S_FALSE even if the device is lost @@ -644,34 +691,146 @@ gl::Error Renderer9::finish() } freeEventQuery(query); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get event query data, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get event query data, " << gl::FmtHR(result); } - } freeEventQuery(query); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +bool Renderer9::isValidNativeWindow(EGLNativeWindowType window) const +{ + return NativeWindow9::IsValidNativeWindow(window); +} + +NativeWindowD3D *Renderer9::createNativeWindow(EGLNativeWindowType window, + const egl::Config *, + const egl::AttributeMap &) const +{ + return new NativeWindow9(window); } -SwapChainD3D *Renderer9::createSwapChain(NativeWindow nativeWindow, +SwapChainD3D *Renderer9::createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) + EGLint orientation, + EGLint samples) { - return new SwapChain9(this, nativeWindow, shareHandle, backBufferFormat, depthBufferFormat, - orientation); + return new SwapChain9(this, GetAs(nativeWindow), shareHandle, d3dTexture, + backBufferFormat, depthBufferFormat, orientation); } -CompilerImpl *Renderer9::createCompiler() +egl::Error Renderer9::getD3DTextureInfo(const egl::Config *config, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const { - return new CompilerD3D(SH_HLSL_3_0_OUTPUT); + IDirect3DTexture9 *texture = nullptr; + if (FAILED(d3dTexture->QueryInterface(&texture))) + { + return egl::EglBadParameter() << "Client buffer is not a IDirect3DTexture9"; + } + + IDirect3DDevice9 *textureDevice = nullptr; + texture->GetDevice(&textureDevice); + if (textureDevice != mDevice) + { + SafeRelease(texture); + return egl::EglBadParameter() << "Texture's device does not match."; + } + SafeRelease(textureDevice); + + D3DSURFACE_DESC desc; + texture->GetLevelDesc(0, &desc); + SafeRelease(texture); + + if (width) + { + *width = static_cast(desc.Width); + } + if (height) + { + *height = static_cast(desc.Height); + } + + // From table egl.restrictions in EGL_ANGLE_d3d_texture_client_buffer. + switch (desc.Format) + { + case D3DFMT_R8G8B8: + case D3DFMT_A8R8G8B8: + case D3DFMT_A16B16G16R16F: + case D3DFMT_A32B32G32R32F: + break; + + default: + return egl::EglBadParameter() + << "Unknown client buffer texture format: " << desc.Format; + } + + if (fboFormat) + { + const auto &d3dFormatInfo = d3d9::GetD3DFormatInfo(desc.Format); + ASSERT(d3dFormatInfo.info().id != angle::Format::ID::NONE); + *fboFormat = d3dFormatInfo.info().fboImplementationInternalFormat; + } + + return egl::NoError(); +} + +egl::Error Renderer9::validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const +{ + if (shareHandle == nullptr) + { + return egl::EglBadParameter() << "NULL share handle."; + } + + EGLint width = attribs.getAsInt(EGL_WIDTH, 0); + EGLint height = attribs.getAsInt(EGL_HEIGHT, 0); + ASSERT(width != 0 && height != 0); + + const d3d9::TextureFormat &backBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(config->renderTargetFormat); + + IDirect3DTexture9 *texture = nullptr; + HRESULT result = mDevice->CreateTexture(width, height, 1, D3DUSAGE_RENDERTARGET, + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, + &texture, &shareHandle); + if (FAILED(result)) + { + return egl::EglBadParameter() << "Failed to open share handle, " << gl::FmtHR(result); + } + + DWORD levelCount = texture->GetLevelCount(); + + D3DSURFACE_DESC desc; + texture->GetLevelDesc(0, &desc); + SafeRelease(texture); + + if (levelCount != 1 || desc.Width != static_cast(width) || + desc.Height != static_cast(height) || + desc.Format != backBufferd3dFormatInfo.texFormat) + { + return egl::EglBadParameter() << "Invalid texture parameters in share handle texture."; + } + + return egl::NoError(); +} + +ContextImpl *Renderer9::createContext(const gl::ContextState &state) +{ + return new Context9(state, this); } void *Renderer9::getD3DDevice() { - return reinterpret_cast(mDevice); + return reinterpret_cast(mDevice); } gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) @@ -682,7 +841,7 @@ gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate event query, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to allocate event query, " << gl::FmtHR(result); } } else @@ -691,10 +850,10 @@ gl::Error Renderer9::allocateEventQuery(IDirect3DQuery9 **outQuery) mEventQueryPool.pop_back(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void Renderer9::freeEventQuery(IDirect3DQuery9* query) +void Renderer9::freeEventQuery(IDirect3DQuery9 *query) { if (mEventQueryPool.size() > 1000) { @@ -706,20 +865,26 @@ void Renderer9::freeEventQuery(IDirect3DQuery9* query) } } -gl::Error Renderer9::createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader) +gl::Error Renderer9::createVertexShader(const DWORD *function, + size_t length, + IDirect3DVertexShader9 **outShader) { return mVertexShaderCache.create(function, length, outShader); } -gl::Error Renderer9::createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader) +gl::Error Renderer9::createPixelShader(const DWORD *function, + size_t length, + IDirect3DPixelShader9 **outShader) { return mPixelShaderCache.create(function, length, outShader); } -HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer) +HRESULT Renderer9::createVertexBuffer(UINT Length, + DWORD Usage, + IDirect3DVertexBuffer9 **ppVertexBuffer) { D3DPOOL Pool = getBufferPool(Usage); - return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL); + return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, nullptr); } VertexBuffer *Renderer9::createVertexBuffer() @@ -727,10 +892,13 @@ VertexBuffer *Renderer9::createVertexBuffer() return new VertexBuffer9(this); } -HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer) +HRESULT Renderer9::createIndexBuffer(UINT Length, + DWORD Usage, + D3DFORMAT Format, + IDirect3DIndexBuffer9 **ppIndexBuffer) { D3DPOOL Pool = getBufferPool(Usage); - return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL); + return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, nullptr); } IndexBuffer *Renderer9::createIndexBuffer() @@ -738,36 +906,13 @@ IndexBuffer *Renderer9::createIndexBuffer() return new IndexBuffer9(this); } -BufferImpl *Renderer9::createBuffer() -{ - return new Buffer9(this); -} - -VertexArrayImpl *Renderer9::createVertexArray(const gl::VertexArray::Data &data) -{ - return new VertexArray9(data); -} - -QueryImpl *Renderer9::createQuery(GLenum type) -{ - return new Query9(this, type); -} - -FenceNVImpl *Renderer9::createFenceNV() -{ - return new FenceNV9(this); -} - -FenceSyncImpl *Renderer9::createFenceSync() +StreamProducerImpl *Renderer9::createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) { - // Renderer9 doesn't support ES 3.0 and its sync objects. + // Streams are not supported under D3D9 UNREACHABLE(); - return NULL; -} - -TransformFeedbackImpl* Renderer9::createTransformFeedback() -{ - return new TransformFeedbackD3D(); + return nullptr; } bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const @@ -776,22 +921,24 @@ bool Renderer9::supportsFastCopyBufferToTexture(GLenum internalFormat) const return false; } -gl::Error Renderer9::fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea) +gl::Error Renderer9::fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) { // Pixel buffer objects are not supported in D3D9, since D3D9 is ES2-only and PBOs are ES3. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); -} - -gl::Error Renderer9::generateSwizzle(gl::Texture *texture) -{ - // Swizzled textures are not available in ES2 or D3D9 - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &samplerState) +gl::Error Renderer9::setSamplerState(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &samplerState) { CurSamplerState &appliedSampler = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates[index] : mCurVertexSamplerStates[index]; @@ -800,11 +947,7 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur TextureD3D *textureD3D = GetImplAs(texture); TextureStorage *storage = nullptr; - gl::Error error = textureD3D->getNativeTexture(&storage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(textureD3D->getNativeTexture(context, &storage)); // Storage should exist, texture should be complete ASSERT(storage); @@ -815,12 +958,16 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur memcmp(&samplerState, &appliedSampler, sizeof(gl::SamplerState)) != 0) { int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; + int d3dSampler = index + d3dSamplerOffset; - mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSU, + gl_d3d9::ConvertTextureWrap(samplerState.wrapS)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_ADDRESSV, + gl_d3d9::ConvertTextureWrap(samplerState.wrapT)); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); + mDevice->SetSamplerState( + d3dSampler, D3DSAMP_MAGFILTER, + gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; float lodBias; @@ -830,52 +977,50 @@ gl::Error Renderer9::setSamplerState(gl::SamplerType type, int index, gl::Textur mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, baseLevel); mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPMAPLODBIAS, static_cast(lodBias)); - if (getRendererExtensions().textureFilterAnisotropic) + if (getNativeExtensions().textureFilterAnisotropic) { - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); + DWORD maxAnisotropy = + std::min(mDeviceCaps.MaxAnisotropy, static_cast(samplerState.maxAnisotropy)); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, maxAnisotropy); } } - appliedSampler.forceSet = false; + appliedSampler.forceSet = false; appliedSampler.samplerState = samplerState; - appliedSampler.baseLevel = baseLevel; + appliedSampler.baseLevel = baseLevel; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +gl::Error Renderer9::setTexture(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture) { - int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; - IDirect3DBaseTexture9 *d3dTexture = NULL; - bool forceSetTexture = false; + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; + IDirect3DBaseTexture9 *d3dTexture = nullptr; + bool forceSetTexture = false; - std::vector &appliedTextures = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; + std::vector &appliedTextures = + (type == gl::SAMPLER_PIXEL) ? mCurPixelTextures : mCurVertexTextures; if (texture) { TextureD3D *textureImpl = GetImplAs(texture); TextureStorage *texStorage = nullptr; - gl::Error error = textureImpl->getNativeTexture(&texStorage); - if (error.isError()) - { - return error; - } + ANGLE_TRY(textureImpl->getNativeTexture(context, &texStorage)); // Texture should be complete and have a storage ASSERT(texStorage); TextureStorage9 *storage9 = GetAs(texStorage); - error = storage9->getBaseTexture(&d3dTexture); - if (error.isError()) - { - return error; - } + ANGLE_TRY(storage9->getBaseTexture(context, &d3dTexture)); // If we get NULL back from getBaseTexture here, something went wrong // in the texture class and we're unexpectedly missing the d3d texture - ASSERT(d3dTexture != NULL); + ASSERT(d3dTexture != nullptr); forceSetTexture = textureImpl->hasDirtyImages(); textureImpl->resetDirty(); @@ -888,60 +1033,50 @@ gl::Error Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *te appliedTextures[index] = reinterpret_cast(d3dTexture); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::setUniformBuffers(const gl::Data &/*data*/, - const std::vector &/*vertexUniformBuffers*/, - const std::vector &/*fragmentUniformBuffers*/) +gl::Error Renderer9::updateState(const gl::Context *context, GLenum drawMode) { - // No effect in ES2/D3D9 - return gl::Error(GL_NO_ERROR); -} + const auto &glState = context->getGLState(); -void Renderer9::syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) -{ - mStateManager.syncState(state, bitmask); -} - -gl::Error Renderer9::updateState(const gl::Data &data, GLenum drawMode) -{ // Applies the render target surface, depth stencil surface, viewport rectangle and // scissor rectangle to the renderer - const gl::Framebuffer *framebufferObject = data.state->getDrawFramebuffer(); - ASSERT(framebufferObject && framebufferObject->checkStatus(data) == GL_FRAMEBUFFER_COMPLETE); + gl::Framebuffer *framebuffer = glState.getDrawFramebuffer(); + ASSERT(framebuffer && !framebuffer->hasAnyDirtyBit() && framebuffer->cachedComplete()); - gl::Error error = applyRenderTarget(framebufferObject); - if (error.isError()) - { - return error; - } + ANGLE_TRY(applyRenderTarget(context, framebuffer)); // Setting viewport state - setViewport(data.caps, data.state->getViewport(), data.state->getNearPlane(), - data.state->getFarPlane(), drawMode, data.state->getRasterizerState().frontFace, - false); + setViewport(glState.getViewport(), glState.getNearPlane(), glState.getFarPlane(), drawMode, + glState.getRasterizerState().frontFace, false); // Setting scissors state - setScissorRectangle(data.state->getScissor(), data.state->isScissorTestEnabled()); + setScissorRectangle(glState.getScissor(), glState.isScissorTestEnabled()); // Setting blend, depth stencil, and rasterizer states - int samples = framebufferObject->getSamples(data); - gl::RasterizerState rasterizer = data.state->getRasterizerState(); + // Since framebuffer->getSamples will return the original samples which may be different with + // the sample counts that we set in render target view, here we use renderTarget->getSamples to + // get the actual samples. + GLsizei samples = 0; + const gl::FramebufferAttachment *firstColorAttachment = framebuffer->getFirstColorbuffer(); + if (firstColorAttachment) + { + ASSERT(firstColorAttachment->isAttached()); + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(firstColorAttachment->getRenderTarget(context, &renderTarget)); + samples = renderTarget->getSamples(); + } + gl::RasterizerState rasterizer = glState.getRasterizerState(); rasterizer.pointDrawMode = (drawMode == GL_POINTS); rasterizer.multiSample = (samples != 0); - unsigned int mask = GetBlendSampleMask(data, samples); - error = setBlendDepthRasterStates(data, mask); - - if (error.isError()) - { - return error; - } + unsigned int mask = GetBlendSampleMask(glState, samples); + ANGLE_TRY(setBlendDepthRasterStates(context, mask)); mStateManager.resetDirtyBits(); - return error; + return gl::NoError(); } void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) @@ -949,71 +1084,85 @@ void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) mStateManager.setScissorState(scissor, enabled); } -gl::Error Renderer9::setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode) +gl::Error Renderer9::setBlendDepthRasterStates(const gl::Context *context, GLenum drawMode) { - int samples = glData.state->getDrawFramebuffer()->getSamples(glData); - gl::RasterizerState rasterizer = glData.state->getRasterizerState(); + const auto &glState = context->getGLState(); + gl::Framebuffer *drawFramebuffer = glState.getDrawFramebuffer(); + ASSERT(!drawFramebuffer->hasAnyDirtyBit()); + // Since framebuffer->getSamples will return the original samples which may be different with + // the sample counts that we set in render target view, here we use renderTarget->getSamples to + // get the actual samples. + GLsizei samples = 0; + const gl::FramebufferAttachment *firstColorAttachment = drawFramebuffer->getFirstColorbuffer(); + if (firstColorAttachment) + { + ASSERT(firstColorAttachment->isAttached()); + RenderTarget9 *renderTarget = nullptr; + ANGLE_TRY(firstColorAttachment->getRenderTarget(context, &renderTarget)); + samples = renderTarget->getSamples(); + } + gl::RasterizerState rasterizer = glState.getRasterizerState(); rasterizer.pointDrawMode = (drawMode == GL_POINTS); rasterizer.multiSample = (samples != 0); - unsigned int mask = GetBlendSampleMask(glData, samples); - return mStateManager.setBlendDepthRasterStates(*glData.state, mask); + unsigned int mask = GetBlendSampleMask(glState, samples); + return mStateManager.setBlendDepthRasterStates(glState, mask); } -void Renderer9::setViewport(const gl::Caps *caps, - const gl::Rectangle &viewport, +void Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport) { - mStateManager.setViewportState(caps, viewport, zNear, zFar, drawMode, frontFace, - ignoreViewport); + mStateManager.setViewportState(viewport, zNear, zFar, drawMode, frontFace, ignoreViewport); } bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count, bool usesPointSize) { switch (mode) { - case GL_POINTS: - mPrimitiveType = D3DPT_POINTLIST; - mPrimitiveCount = count; - break; - case GL_LINES: - mPrimitiveType = D3DPT_LINELIST; - mPrimitiveCount = count / 2; - break; - case GL_LINE_LOOP: - mPrimitiveType = D3DPT_LINESTRIP; - mPrimitiveCount = count - 1; // D3D doesn't support line loops, so we draw the last line separately - break; - case GL_LINE_STRIP: - mPrimitiveType = D3DPT_LINESTRIP; - mPrimitiveCount = count - 1; - break; - case GL_TRIANGLES: - mPrimitiveType = D3DPT_TRIANGLELIST; - mPrimitiveCount = count / 3; - break; - case GL_TRIANGLE_STRIP: - mPrimitiveType = D3DPT_TRIANGLESTRIP; - mPrimitiveCount = count - 2; - break; - case GL_TRIANGLE_FAN: - mPrimitiveType = D3DPT_TRIANGLEFAN; - mPrimitiveCount = count - 2; - break; - default: - UNREACHABLE(); - return false; + case GL_POINTS: + mPrimitiveType = D3DPT_POINTLIST; + mPrimitiveCount = count; + break; + case GL_LINES: + mPrimitiveType = D3DPT_LINELIST; + mPrimitiveCount = count / 2; + break; + case GL_LINE_LOOP: + mPrimitiveType = D3DPT_LINESTRIP; + mPrimitiveCount = + count - 1; // D3D doesn't support line loops, so we draw the last line separately + break; + case GL_LINE_STRIP: + mPrimitiveType = D3DPT_LINESTRIP; + mPrimitiveCount = count - 1; + break; + case GL_TRIANGLES: + mPrimitiveType = D3DPT_TRIANGLELIST; + mPrimitiveCount = count / 3; + break; + case GL_TRIANGLE_STRIP: + mPrimitiveType = D3DPT_TRIANGLESTRIP; + mPrimitiveCount = count - 2; + break; + case GL_TRIANGLE_FAN: + mPrimitiveType = D3DPT_TRIANGLEFAN; + mPrimitiveCount = count - 2; + break; + default: + UNREACHABLE(); + return false; } return mPrimitiveCount > 0; } - -gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer) +gl::Error Renderer9::getNullColorbuffer(const gl::Context *context, + const gl::FramebufferAttachment *depthbuffer, + const gl::FramebufferAttachment **outColorBuffer) { ASSERT(depthbuffer); @@ -1022,25 +1171,28 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu // search cached nullcolorbuffers for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { - if (mNullColorbufferCache[i].buffer != NULL && + if (mNullColorbufferCache[i].buffer != nullptr && mNullColorbufferCache[i].width == size.width && mNullColorbufferCache[i].height == size.height) { mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; - *outColorBuffer = mNullColorbufferCache[i].buffer; - return gl::Error(GL_NO_ERROR); + *outColorBuffer = mNullColorbufferCache[i].buffer; + return gl::NoError(); } } - gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(createRenderbuffer(), 0); - gl::Error error = nullRenderbuffer->setStorage(GL_NONE, size.width, size.height); + auto *implFactory = context->getImplementation(); + + gl::Renderbuffer *nullRenderbuffer = new gl::Renderbuffer(implFactory->createRenderbuffer(), 0); + gl::Error error = nullRenderbuffer->setStorage(context, GL_NONE, size.width, size.height); if (error.isError()) { SafeDelete(nullRenderbuffer); return error; } - gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment(GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer); + gl::FramebufferAttachment *nullbuffer = new gl::FramebufferAttachment( + context, GL_RENDERBUFFER, GL_NONE, gl::ImageIndex::MakeInvalid(), nullRenderbuffer); // add nullbuffer to the cache NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; @@ -1053,46 +1205,38 @@ gl::Error Renderer9::getNullColorbuffer(const gl::FramebufferAttachment *depthbu } delete oldest->buffer; - oldest->buffer = nullbuffer; + oldest->buffer = nullbuffer; oldest->lruCount = ++mMaxNullColorbufferLRU; oldest->width = size.width; oldest->height = size.height; *outColorBuffer = nullbuffer; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, +gl::Error Renderer9::applyRenderTarget(const gl::Context *context, + const gl::FramebufferAttachment *colorAttachment, const gl::FramebufferAttachment *depthStencilAttachment) { const gl::FramebufferAttachment *renderAttachment = colorAttachment; - gl::Error error(GL_NO_ERROR); // if there is no color attachment we must synthesize a NULL colorattachment // to keep the D3D runtime happy. This should only be possible if depth texturing. if (renderAttachment == nullptr) { - error = getNullColorbuffer(depthStencilAttachment, &renderAttachment); - if (error.isError()) - { - return error; - } + ANGLE_TRY(getNullColorbuffer(context, depthStencilAttachment, &renderAttachment)); } ASSERT(renderAttachment != nullptr); - size_t renderTargetWidth = 0; - size_t renderTargetHeight = 0; + size_t renderTargetWidth = 0; + size_t renderTargetHeight = 0; D3DFORMAT renderTargetFormat = D3DFMT_UNKNOWN; RenderTarget9 *renderTarget = nullptr; - error = renderAttachment->getRenderTarget(&renderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(renderAttachment->getRenderTarget(context, &renderTarget)); ASSERT(renderTarget); - bool renderTargetChanged = false; + bool renderTargetChanged = false; unsigned int renderTargetSerial = renderTarget->getSerial(); if (renderTargetSerial != mAppliedRenderTargetSerial) { @@ -1103,24 +1247,20 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mDevice->SetRenderTarget(0, renderTargetSurface); SafeRelease(renderTargetSurface); - renderTargetWidth = renderTarget->getWidth(); + renderTargetWidth = renderTarget->getWidth(); renderTargetHeight = renderTarget->getHeight(); renderTargetFormat = renderTarget->getD3DFormat(); mAppliedRenderTargetSerial = renderTargetSerial; - renderTargetChanged = true; + renderTargetChanged = true; } RenderTarget9 *depthStencilRenderTarget = nullptr; - unsigned int depthStencilSerial = 0; + unsigned int depthStencilSerial = 0; if (depthStencilAttachment != nullptr) { - error = depthStencilAttachment->getRenderTarget(&depthStencilRenderTarget); - if (error.isError()) - { - return error; - } + ANGLE_TRY(depthStencilAttachment->getRenderTarget(context, &depthStencilRenderTarget)); ASSERT(depthStencilRenderTarget); depthStencilSerial = depthStencilRenderTarget->getSerial(); @@ -1128,7 +1268,7 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt if (depthStencilSerial != mAppliedDepthStencilSerial || !mDepthStencilInitialized) { - unsigned int depthSize = 0; + unsigned int depthSize = 0; unsigned int stencilSize = 0; // Apply the depth stencil on the device @@ -1140,19 +1280,19 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mDevice->SetDepthStencilSurface(depthStencilSurface); SafeRelease(depthStencilSurface); - depthSize = depthStencilAttachment->getDepthSize(); + depthSize = depthStencilAttachment->getDepthSize(); stencilSize = depthStencilAttachment->getStencilSize(); } else { - mDevice->SetDepthStencilSurface(NULL); + mDevice->SetDepthStencilSurface(nullptr); } mStateManager.updateDepthSizeIfChanged(mDepthStencilInitialized, depthSize); mStateManager.updateStencilSizeIfChanged(mDepthStencilInitialized, stencilSize); mAppliedDepthStencilSerial = depthStencilSerial; - mDepthStencilInitialized = true; + mDepthStencilInitialized = true; } if (renderTargetChanged || !mRenderTargetDescInitialized) @@ -1163,83 +1303,84 @@ gl::Error Renderer9::applyRenderTarget(const gl::FramebufferAttachment *colorAtt mRenderTargetDescInitialized = true; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::applyRenderTarget(const gl::Framebuffer *framebuffer) +gl::Error Renderer9::applyRenderTarget(const gl::Context *context, + const gl::Framebuffer *framebuffer) { - return applyRenderTarget(framebuffer->getColorbuffer(0), framebuffer->getDepthOrStencilbuffer()); + return applyRenderTarget(context, framebuffer->getColorbuffer(0), + framebuffer->getDepthOrStencilbuffer()); } -gl::Error Renderer9::applyVertexBuffer(const gl::State &state, +gl::Error Renderer9::applyVertexBuffer(const gl::Context *context, GLenum mode, GLint first, GLsizei count, GLsizei instances, TranslatedIndexData * /*indexInfo*/) { - gl::Error error = mVertexDataManager->prepareVertexData(state, first, count, &mTranslatedAttribCache, instances); + const gl::State &state = context->getGLState(); + gl::Error error = mVertexDataManager->prepareVertexData(context, first, count, + &mTranslatedAttribCache, instances); if (error.isError()) { return error; } - return mVertexDeclarationCache.applyDeclaration(mDevice, mTranslatedAttribCache, state.getProgram(), instances, &mRepeatDraw); + return mVertexDeclarationCache.applyDeclaration( + mDevice, mTranslatedAttribCache, state.getProgram(), first, instances, &mRepeatDraw); } // Applies the indices and element array bindings to the Direct3D 9 device -gl::Error Renderer9::applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, +gl::Error Renderer9::applyIndexBuffer(const gl::Context *context, + const void *indices, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) { - gl::VertexArray *vao = data.state->getVertexArray(); + gl::VertexArray *vao = context->getGLState().getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); - gl::Error error = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, - indexInfo, false); - if (error.isError()) - { - return error; - } + const auto &lazyIndexRange = context->getParams(); + + GLenum dstType = GetIndexTranslationDestType(type, lazyIndexRange, false); + + ANGLE_TRY(mIndexDataManager->prepareIndexData(context, type, dstType, count, elementArrayBuffer, + indices, indexInfo)); // Directly binding the storage buffer is not supported for d3d9 - ASSERT(indexInfo->storage == NULL); + ASSERT(indexInfo->storage == nullptr); if (indexInfo->serial != mAppliedIBSerial) { - IndexBuffer9* indexBuffer = GetAs(indexInfo->indexBuffer); + IndexBuffer9 *indexBuffer = GetAs(indexInfo->indexBuffer); mDevice->SetIndices(indexBuffer->getBuffer()); mAppliedIBSerial = indexInfo->serial; } - return gl::Error(GL_NO_ERROR); -} - -void Renderer9::applyTransformFeedbackBuffers(const gl::State& state) -{ - ASSERT(!state.isTransformFeedbackActiveUnpaused()); + return gl::NoError(); } -gl::Error Renderer9::drawArraysImpl(const gl::Data &data, +gl::Error Renderer9::drawArraysImpl(const gl::Context *context, GLenum mode, + GLint startVertex, GLsizei count, GLsizei instances) { - ASSERT(!data.state->isTransformFeedbackActiveUnpaused()); + ASSERT(!context->getGLState().isTransformFeedbackActiveUnpaused()); startScene(); if (mode == GL_LINE_LOOP) { - return drawLineLoop(count, GL_NONE, NULL, 0, NULL); + return drawLineLoop(context, count, GL_NONE, nullptr, 0, nullptr); } else if (instances > 0) { - StaticIndexBufferInterface *countingIB = NULL; - gl::Error error = getCountingIB(count, &countingIB); + StaticIndexBufferInterface *countingIB = nullptr; + gl::Error error = getCountingIB(count, &countingIB); if (error.isError()) { return error; @@ -1258,60 +1399,73 @@ gl::Error Renderer9::drawArraysImpl(const gl::Data &data, mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } - else // Regular case + else // Regular case { mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } -gl::Error Renderer9::drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, +gl::Error Renderer9::drawElementsImpl(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, - GLsizei /*instances*/) + const void *indices, + GLsizei instances) { + TranslatedIndexData indexInfo; + + ANGLE_TRY(applyIndexBuffer(context, indices, count, mode, type, &indexInfo)); + + const auto &lazyIndexRange = context->getParams(); + const gl::IndexRange &indexRange = lazyIndexRange.getIndexRange().value(); + size_t vertexCount = indexRange.vertexCount(); + ANGLE_TRY(applyVertexBuffer(context, mode, static_cast(indexRange.start), + static_cast(vertexCount), instances, &indexInfo)); + startScene(); - int minIndex = static_cast(indexInfo.indexRange.start); + int minIndex = static_cast(indexRange.start); - gl::VertexArray *vao = data.state->getVertexArray(); + gl::VertexArray *vao = context->getGLState().getVertexArray(); gl::Buffer *elementArrayBuffer = vao->getElementArrayBuffer().get(); if (mode == GL_POINTS) { - return drawIndexedPoints(count, type, indices, minIndex, elementArrayBuffer); + return drawIndexedPoints(context, count, type, indices, minIndex, elementArrayBuffer); } else if (mode == GL_LINE_LOOP) { - return drawLineLoop(count, type, indices, minIndex, elementArrayBuffer); + return drawLineLoop(context, count, type, indices, minIndex, elementArrayBuffer); } else { - size_t vertexCount = indexInfo.indexRange.vertexCount(); for (int i = 0; i < mRepeatDraw; i++) { mDevice->DrawIndexedPrimitive(mPrimitiveType, -minIndex, minIndex, static_cast(vertexCount), indexInfo.startIndex, mPrimitiveCount); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } -gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawLineLoop(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer) { // Get the raw indices for an indexed draw if (type != GL_NONE && elementArrayBuffer) { - BufferD3D *storage = GetImplAs(elementArrayBuffer); - intptr_t offset = reinterpret_cast(indices); - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); + BufferD3D *storage = GetImplAs(elementArrayBuffer); + intptr_t offset = reinterpret_cast(indices); + const uint8_t *bufferData = nullptr; + gl::Error error = storage->getData(context, &bufferData); if (error.isError()) { return error; @@ -1321,12 +1475,13 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi unsigned int startIndex = 0; - if (getRendererExtensions().elementIndexUint) + if (getNativeExtensions().elementIndexUint) { if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); + gl::Error error = + mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT); if (error.isError()) { SafeDelete(mLineLoopIB); @@ -1337,60 +1492,64 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi // Checked by Renderer9::applyPrimitiveType ASSERT(count >= 0); - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) + if (static_cast(count) + 1 > + (std::numeric_limits::max() / sizeof(unsigned int))) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::OutOfMemory() << "Failed to create a 32-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required."; } - const unsigned int spaceNeeded = (static_cast(count)+1) * sizeof(unsigned int); + const unsigned int spaceNeeded = + (static_cast(count) + 1) * sizeof(unsigned int); gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); if (error.isError()) { return error; } - void* mappedMemory = NULL; + void *mappedMemory = nullptr; unsigned int offset = 0; - error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); + error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); if (error.isError()) { return error; } - startIndex = static_cast(offset) / 4; - unsigned int *data = reinterpret_cast(mappedMemory); + startIndex = static_cast(offset) / 4; + unsigned int *data = reinterpret_cast(mappedMemory); switch (type) { - case GL_NONE: // Non-indexed draw - for (int i = 0; i < count; i++) - { - data[i] = i; - } - data[count] = 0; - break; - case GL_UNSIGNED_BYTE: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_SHORT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_INT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - default: UNREACHABLE(); + case GL_NONE: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = i; + } + data[count] = 0; + break; + case GL_UNSIGNED_BYTE: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_SHORT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_INT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + default: + UNREACHABLE(); } error = mLineLoopIB->unmapBuffer(); @@ -1404,7 +1563,8 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi if (!mLineLoopIB) { mLineLoopIB = new StreamingIndexBufferInterface(this); - gl::Error error = mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); + gl::Error error = + mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT); if (error.isError()) { SafeDelete(mLineLoopIB); @@ -1415,19 +1575,22 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi // Checked by Renderer9::applyPrimitiveType ASSERT(count >= 0); - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned short))) + if (static_cast(count) + 1 > + (std::numeric_limits::max() / sizeof(unsigned short))) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::OutOfMemory() << "Failed to create a 16-bit looping index buffer for " + "GL_LINE_LOOP, too many indices required."; } - const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned short); + const unsigned int spaceNeeded = + (static_cast(count) + 1) * sizeof(unsigned short); gl::Error error = mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); if (error.isError()) { return error; } - void* mappedMemory = NULL; + void *mappedMemory = nullptr; unsigned int offset; error = mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset); if (error.isError()) @@ -1435,40 +1598,41 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi return error; } - startIndex = static_cast(offset) / 2; - unsigned short *data = reinterpret_cast(mappedMemory); + startIndex = static_cast(offset) / 2; + unsigned short *data = reinterpret_cast(mappedMemory); switch (type) { - case GL_NONE: // Non-indexed draw - for (int i = 0; i < count; i++) - { - data[i] = static_cast(i); - } - data[count] = 0; - break; - case GL_UNSIGNED_BYTE: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_SHORT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(indices)[i]; - } - data[count] = static_cast(indices)[0]; - break; - case GL_UNSIGNED_INT: - for (int i = 0; i < count; i++) - { - data[i] = static_cast(static_cast(indices)[i]); - } - data[count] = static_cast(static_cast(indices)[0]); - break; - default: UNREACHABLE(); + case GL_NONE: // Non-indexed draw + for (int i = 0; i < count; i++) + { + data[i] = static_cast(i); + } + data[count] = 0; + break; + case GL_UNSIGNED_BYTE: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_SHORT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(indices)[i]; + } + data[count] = static_cast(indices)[0]; + break; + case GL_UNSIGNED_INT: + for (int i = 0; i < count; i++) + { + data[i] = static_cast(static_cast(indices)[i]); + } + data[count] = static_cast(static_cast(indices)[0]); + break; + default: + UNREACHABLE(); } error = mLineLoopIB->unmapBuffer(); @@ -1488,22 +1652,31 @@ gl::Error Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indi mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } template -static gl::Error drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) +static gl::Error drawPoints(IDirect3DDevice9 *device, + GLsizei count, + const void *indices, + int minIndex) { for (int i = 0; i < count; i++) { - unsigned int indexValue = static_cast(static_cast(indices)[i]) - minIndex; + unsigned int indexValue = + static_cast(static_cast(indices)[i]) - minIndex; device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +gl::Error Renderer9::drawIndexedPoints(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer) { // Drawing index point lists is unsupported in d3d9, fall back to a regular DrawPrimitive call // for each individual point. This call is not expected to happen often. @@ -1511,10 +1684,10 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid if (elementArrayBuffer) { BufferD3D *storage = GetImplAs(elementArrayBuffer); - intptr_t offset = reinterpret_cast(indices); + intptr_t offset = reinterpret_cast(indices); - const uint8_t *bufferData = NULL; - gl::Error error = storage->getData(&bufferData); + const uint8_t *bufferData = nullptr; + gl::Error error = storage->getData(context, &bufferData); if (error.isError()) { return error; @@ -1525,17 +1698,22 @@ gl::Error Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid switch (type) { - case GL_UNSIGNED_BYTE: return drawPoints(mDevice, count, indices, minIndex); - case GL_UNSIGNED_SHORT: return drawPoints(mDevice, count, indices, minIndex); - case GL_UNSIGNED_INT: return drawPoints(mDevice, count, indices, minIndex); - default: UNREACHABLE(); return gl::Error(GL_INVALID_OPERATION); + case GL_UNSIGNED_BYTE: + return drawPoints(mDevice, count, indices, minIndex); + case GL_UNSIGNED_SHORT: + return drawPoints(mDevice, count, indices, minIndex); + case GL_UNSIGNED_INT: + return drawPoints(mDevice, count, indices, minIndex); + default: + UNREACHABLE(); + return gl::InternalError(); } } gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **outIB) { // Update the counting index buffer if it is not large enough or has not been created yet. - if (count <= 65536) // 16-bit indices + if (count <= 65536) // 16-bit indices { const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned short); @@ -1543,29 +1721,21 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou { SafeDelete(mCountingIB); mCountingIB = new StaticIndexBufferInterface(this); - mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT); + ANGLE_TRY(mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)); - void *mappedMemory = NULL; - gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); - if (error.isError()) - { - return error; - } + void *mappedMemory = nullptr; + ANGLE_TRY(mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, nullptr)); - unsigned short *data = reinterpret_cast(mappedMemory); + unsigned short *data = reinterpret_cast(mappedMemory); for (size_t i = 0; i < count; i++) { data[i] = static_cast(i); } - error = mCountingIB->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mCountingIB->unmapBuffer()); } } - else if (getRendererExtensions().elementIndexUint) + else if (getNativeExtensions().elementIndexUint) { const unsigned int spaceNeeded = static_cast(count) * sizeof(unsigned int); @@ -1573,59 +1743,53 @@ gl::Error Renderer9::getCountingIB(size_t count, StaticIndexBufferInterface **ou { SafeDelete(mCountingIB); mCountingIB = new StaticIndexBufferInterface(this); - mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT); + ANGLE_TRY(mCountingIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)); - void *mappedMemory = NULL; - gl::Error error = mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, NULL); - if (error.isError()) - { - return error; - } + void *mappedMemory = nullptr; + ANGLE_TRY(mCountingIB->mapBuffer(spaceNeeded, &mappedMemory, nullptr)); - unsigned int *data = reinterpret_cast(mappedMemory); + unsigned int *data = reinterpret_cast(mappedMemory); for (unsigned int i = 0; i < count; i++) { data[i] = i; } - error = mCountingIB->unmapBuffer(); - if (error.isError()) - { - return error; - } + ANGLE_TRY(mCountingIB->unmapBuffer()); } } else { - return gl::Error(GL_OUT_OF_MEMORY, "Could not create a counting index buffer for glDrawArraysInstanced."); + return gl::OutOfMemory() + << "Could not create a counting index buffer for glDrawArraysInstanced."; } *outIB = mCountingIB; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) +gl::Error Renderer9::applyShaders(const gl::Context *context, GLenum drawMode) { - ProgramD3D *programD3D = GetImplAs(data.state->getProgram()); - const auto &inputLayout = programD3D->getCachedInputLayout(); + const gl::State &state = context->getContextState().getState(); + // This method is called single-threaded. + ANGLE_TRY(ensureHLSLCompilerInitialized()); - ShaderExecutableD3D *vertexExe = NULL; - gl::Error error = programD3D->getVertexExecutableForInputLayout(inputLayout, &vertexExe, nullptr); - if (error.isError()) - { - return error; - } + ProgramD3D *programD3D = GetImplAs(state.getProgram()); + VertexArray9 *vao = GetImplAs(state.getVertexArray()); + programD3D->updateCachedInputLayout(vao->getCurrentStateSerial(), state); - const gl::Framebuffer *drawFramebuffer = data.state->getDrawFramebuffer(); - ShaderExecutableD3D *pixelExe = NULL; - error = programD3D->getPixelExecutableForFramebuffer(drawFramebuffer, &pixelExe); - if (error.isError()) - { - return error; - } + ShaderExecutableD3D *vertexExe = nullptr; + ANGLE_TRY(programD3D->getVertexExecutableForCachedInputLayout(&vertexExe, nullptr)); + + const gl::Framebuffer *drawFramebuffer = state.getDrawFramebuffer(); + programD3D->updateCachedOutputLayout(context, drawFramebuffer); + + ShaderExecutableD3D *pixelExe = nullptr; + ANGLE_TRY(programD3D->getPixelExecutableForCachedOutputLayout(&pixelExe, nullptr)); - IDirect3DVertexShader9 *vertexShader = (vertexExe ? GetAs(vertexExe)->getVertexShader() : nullptr); - IDirect3DPixelShader9 *pixelShader = (pixelExe ? GetAs(pixelExe)->getPixelShader() : nullptr); + IDirect3DVertexShader9 *vertexShader = + (vertexExe ? GetAs(vertexExe)->getVertexShader() : nullptr); + IDirect3DPixelShader9 *pixelShader = + (pixelExe ? GetAs(pixelExe)->getPixelShader() : nullptr); if (vertexShader != mAppliedVertexShader) { @@ -1652,25 +1816,39 @@ gl::Error Renderer9::applyShadersImpl(const gl::Data &data, GLenum /*drawMode*/) mAppliedProgramSerial = programSerial; } - return gl::Error(GL_NO_ERROR); + ANGLE_TRY(applyUniforms(programD3D)); + + // Driver uniforms + mStateManager.setShaderConstants(); + + return gl::NoError(); } -gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, - GLenum /*drawMode*/, - const std::vector &uniformArray) +gl::Error Renderer9::applyUniforms(ProgramD3D *programD3D) { + // Skip updates if we're not dirty. Note that D3D9 cannot have compute. + if (!programD3D->areVertexUniformsDirty() && !programD3D->areFragmentUniformsDirty()) + { + return gl::NoError(); + } + + const auto &uniformArray = programD3D->getD3DUniforms(); + for (const D3DUniform *targetUniform : uniformArray) { - if (!targetUniform->dirty) + // Built-in uniforms must be skipped. + if (!targetUniform->isReferencedByFragmentShader() && + !targetUniform->isReferencedByVertexShader()) continue; - GLfloat *f = (GLfloat *)targetUniform->data; - GLint *i = (GLint *)targetUniform->data; + const GLfloat *f = reinterpret_cast(targetUniform->firstNonNullData()); + const GLint *i = reinterpret_cast(targetUniform->firstNonNullData()); - switch (targetUniform->type) + switch (targetUniform->typeInfo.type) { case GL_SAMPLER_2D: case GL_SAMPLER_CUBE: + case GL_SAMPLER_EXTERNAL_OES: break; case GL_BOOL: case GL_BOOL_VEC2: @@ -1698,22 +1876,22 @@ gl::Error Renderer9::applyUniforms(const ProgramD3D &programD3D, } } - // Driver uniforms - mStateManager.setShaderConstants(); - - return gl::Error(GL_NO_ERROR); + programD3D->markUniformsClean(); + return gl::NoError(); } void Renderer9::applyUniformnfv(const D3DUniform *targetUniform, const GLfloat *v) { if (targetUniform->isReferencedByFragmentShader()) { - mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, targetUniform->registerCount); + mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, + targetUniform->registerCount); } if (targetUniform->isReferencedByVertexShader()) { - mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, targetUniform->registerCount); + mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, + targetUniform->registerCount); } } @@ -1730,7 +1908,7 @@ void Renderer9::applyUniformniv(const D3DUniform *targetUniform, const GLint *v) vector[i][3] = (GLfloat)v[4 * i + 3]; } - applyUniformnfv(targetUniform, (GLfloat*)vector); + applyUniformnfv(targetUniform, (GLfloat *)vector); } void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) @@ -1746,18 +1924,19 @@ void Renderer9::applyUniformnbv(const D3DUniform *targetUniform, const GLint *v) vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f; } - applyUniformnfv(targetUniform, (GLfloat*)vector); + applyUniformnfv(targetUniform, (GLfloat *)vector); } -gl::Error Renderer9::clear(const ClearParameters &clearParams, +gl::Error Renderer9::clear(const gl::Context *context, + const ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer) { - if (clearParams.colorClearType != GL_FLOAT) + if (clearParams.colorType != GL_FLOAT) { // Clearing buffers with non-float values is not supported by Renderer9 and ES 2.0 UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } bool clearColor = clearParams.clearColor[0]; @@ -1765,14 +1944,15 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, { if (clearParams.clearColor[i] != clearColor) { - // Clearing individual buffers other than buffer zero is not supported by Renderer9 and ES 2.0 + // Clearing individual buffers other than buffer zero is not supported by Renderer9 and + // ES 2.0 UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } } - float depth = gl::clamp01(clearParams.depthClearValue); - DWORD stencil = clearParams.stencilClearValue & 0x000000FF; + float depth = gl::clamp01(clearParams.depthValue); + DWORD stencil = clearParams.stencilValue & 0x000000FF; unsigned int stencilUnmasked = 0x0; if (clearParams.clearStencil && depthStencilBuffer->getStencilSize() > 0) @@ -1780,7 +1960,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, ASSERT(depthStencilBuffer != nullptr); RenderTargetD3D *stencilRenderTarget = nullptr; - gl::Error error = depthStencilBuffer->getRenderTarget(&stencilRenderTarget); + gl::Error error = depthStencilBuffer->getRenderTarget(context, &stencilRenderTarget); if (error.isError()) { return error; @@ -1789,21 +1969,23 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, RenderTarget9 *stencilRenderTarget9 = GetAs(stencilRenderTarget); ASSERT(stencilRenderTarget9); - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat()); + const d3d9::D3DFormat &d3dFormatInfo = + d3d9::GetD3DFormatInfo(stencilRenderTarget9->getD3DFormat()); stencilUnmasked = (0x1 << d3dFormatInfo.stencilBits) - 1; } - const bool needMaskedStencilClear = clearParams.clearStencil && - (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + const bool needMaskedStencilClear = + clearParams.clearStencil && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; bool needMaskedColorClear = false; - D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); + D3DCOLOR color = D3DCOLOR_ARGB(255, 0, 0, 0); if (clearColor) { ASSERT(colorBuffer != nullptr); - RenderTargetD3D *colorRenderTarget = NULL; - gl::Error error = colorBuffer->getRenderTarget(&colorRenderTarget); + RenderTargetD3D *colorRenderTarget = nullptr; + gl::Error error = colorBuffer->getRenderTarget(context, &colorRenderTarget); if (error.isError()) { return error; @@ -1812,17 +1994,27 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, RenderTarget9 *colorRenderTarget9 = GetAs(colorRenderTarget); ASSERT(colorRenderTarget9); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(colorBuffer->getInternalFormat()); - const d3d9::D3DFormat &d3dFormatInfo = d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat()); - - color = D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) ? 1.0f : clearParams.colorFClearValue.alpha), - gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) ? 0.0f : clearParams.colorFClearValue.red), - gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) ? 0.0f : clearParams.colorFClearValue.green), - gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) ? 0.0f : clearParams.colorFClearValue.blue)); - - if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || + const gl::InternalFormat &formatInfo = *colorBuffer->getFormat().info; + const d3d9::D3DFormat &d3dFormatInfo = + d3d9::GetD3DFormatInfo(colorRenderTarget9->getD3DFormat()); + + color = + D3DCOLOR_ARGB(gl::unorm<8>((formatInfo.alphaBits == 0 && d3dFormatInfo.alphaBits > 0) + ? 1.0f + : clearParams.colorF.alpha), + gl::unorm<8>((formatInfo.redBits == 0 && d3dFormatInfo.redBits > 0) + ? 0.0f + : clearParams.colorF.red), + gl::unorm<8>((formatInfo.greenBits == 0 && d3dFormatInfo.greenBits > 0) + ? 0.0f + : clearParams.colorF.green), + gl::unorm<8>((formatInfo.blueBits == 0 && d3dFormatInfo.blueBits > 0) + ? 0.0f + : clearParams.colorF.blue)); + + if ((formatInfo.redBits > 0 && !clearParams.colorMaskRed) || (formatInfo.greenBits > 0 && !clearParams.colorMaskGreen) || - (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || + (formatInfo.blueBits > 0 && !clearParams.colorMaskBlue) || (formatInfo.alphaBits > 0 && !clearParams.colorMaskAlpha)) { needMaskedColorClear = true; @@ -1835,7 +2027,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, // State which is altered in only some paths will be flagged dirty in the case that // that path is taken. HRESULT hr; - if (mMaskedClearSavedState == NULL) + if (mMaskedClearSavedState == nullptr) { hr = mDevice->BeginStateBlock(); ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); @@ -1850,10 +2042,10 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - mDevice->SetPixelShader(NULL); - mDevice->SetVertexShader(NULL); + mDevice->SetPixelShader(nullptr); + mDevice->SetVertexShader(nullptr); mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); - mDevice->SetStreamSource(0, NULL, 0, 0); + mDevice->SetStreamSource(0, nullptr, 0, 0); mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); @@ -1862,7 +2054,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { mDevice->SetStreamSourceFreq(i, 1); } @@ -1871,9 +2063,9 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); } - ASSERT(mMaskedClearSavedState != NULL); + ASSERT(mMaskedClearSavedState != nullptr); - if (mMaskedClearSavedState != NULL) + if (mMaskedClearSavedState != nullptr) { hr = mMaskedClearSavedState->Capture(); ASSERT(SUCCEEDED(hr)); @@ -1890,11 +2082,10 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, if (clearColor) { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, - gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, - clearParams.colorMaskGreen, - clearParams.colorMaskBlue, - clearParams.colorMaskAlpha)); + mDevice->SetRenderState( + D3DRS_COLORWRITEENABLE, + gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, clearParams.colorMaskGreen, + clearParams.colorMaskBlue, clearParams.colorMaskAlpha)); } else { @@ -1917,8 +2108,8 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); } - mDevice->SetPixelShader(NULL); - mDevice->SetVertexShader(NULL); + mDevice->SetPixelShader(nullptr); + mDevice->SetVertexShader(nullptr); mDevice->SetFVF(D3DFVF_XYZRHW); mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); @@ -1928,7 +2119,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) { mDevice->SetStreamSourceFreq(i, 1); } @@ -1936,7 +2127,7 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, int renderTargetWidth = mStateManager.getRenderTargetWidth(); int renderTargetHeight = mStateManager.getRenderTargetHeight(); - float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges quad[0][0] = -0.5f; quad[0][1] = renderTargetHeight - 0.5f; quad[0][2] = 0.0f; @@ -1964,10 +2155,10 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, { mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil); + mDevice->Clear(0, nullptr, D3DCLEAR_ZBUFFER, color, depth, stencil); } - if (mMaskedClearSavedState != NULL) + if (mMaskedClearSavedState != nullptr) { mMaskedClearSavedState->Apply(); } @@ -1988,17 +2179,17 @@ gl::Error Renderer9::clear(const ClearParameters &clearParams, dxClearFlags |= D3DCLEAR_STENCIL; } - mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil); + mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void Renderer9::markAllStateDirty() { - mAppliedRenderTargetSerial = 0; - mAppliedDepthStencilSerial = 0; - mDepthStencilInitialized = false; + mAppliedRenderTargetSerial = 0; + mAppliedDepthStencilSerial = 0; + mDepthStencilInitialized = false; mRenderTargetDescInitialized = false; mStateManager.forceSetRasterState(); @@ -2021,9 +2212,9 @@ void Renderer9::markAllStateDirty() mCurPixelTextures[i] = angle::DirtyPointer; } - mAppliedIBSerial = 0; - mAppliedVertexShader = NULL; - mAppliedPixelShader = NULL; + mAppliedIBSerial = 0; + mAppliedVertexShader = nullptr; + mAppliedPixelShader = nullptr; mAppliedProgramSerial = 0; mStateManager.forceSetDXUniformsState(); @@ -2051,6 +2242,10 @@ void Renderer9::releaseDeviceResources() for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) { + if (mNullColorbufferCache[i].buffer) + { + mNullColorbufferCache[i].buffer->detach(mDisplay->getProxyContext()); + } SafeDelete(mNullColorbufferCache[i].buffer); } } @@ -2059,19 +2254,7 @@ void Renderer9::releaseDeviceResources() bool Renderer9::testDeviceLost() { HRESULT status = getDeviceStatusCode(); - bool isLost = FAILED(status); - - if (isLost) - { - // ensure we note the device loss -- - // we'll probably get this done again by notifyDeviceLost - // but best to remember it! - // Note that we don't want to clear the device loss status here - // -- this needs to be done by resetDevice - mDeviceLost = true; - } - - return isLost; + return FAILED(status); } HRESULT Renderer9::getDeviceStatusCode() @@ -2080,7 +2263,7 @@ HRESULT Renderer9::getDeviceStatusCode() if (mDeviceEx) { - status = mDeviceEx->CheckDeviceState(NULL); + status = mDeviceEx->CheckDeviceState(nullptr); } else if (mDevice) { @@ -2096,16 +2279,16 @@ bool Renderer9::testDeviceResettable() // DEVICEREMOVED indicates the device has been stopped and must be recreated switch (getDeviceStatusCode()) { - case D3DERR_DEVICENOTRESET: - case D3DERR_DEVICEHUNG: - return true; - case D3DERR_DEVICELOST: - return (mDeviceEx != NULL); - case D3DERR_DEVICEREMOVED: - ASSERT(mDeviceEx != NULL); - return isRemovedDeviceResettable(); - default: - return false; + case D3DERR_DEVICENOTRESET: + case D3DERR_DEVICEHUNG: + return true; + case D3DERR_DEVICELOST: + return (mDeviceEx != nullptr); + case D3DERR_DEVICEREMOVED: + ASSERT(mDeviceEx != nullptr); + return isRemovedDeviceResettable(); + default: + return false; } } @@ -2115,12 +2298,12 @@ bool Renderer9::resetDevice() D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - HRESULT result = D3D_OK; - bool lost = testDeviceLost(); + HRESULT result = D3D_OK; + bool lost = testDeviceLost(); bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED); // Device Removed is a feature which is only present with D3D9Ex - ASSERT(mDeviceEx != NULL || !removedDevice); + ASSERT(mDeviceEx != nullptr || !removedDevice); for (int attempts = 3; lost && attempts > 0; attempts--) { @@ -2134,16 +2317,16 @@ bool Renderer9::resetDevice() } else if (mDeviceEx) { - Sleep(500); // Give the graphics driver some CPU time - result = mDeviceEx->ResetEx(&presentParameters, NULL); - lost = testDeviceLost(); + Sleep(500); // Give the graphics driver some CPU time + result = mDeviceEx->ResetEx(&presentParameters, nullptr); + lost = testDeviceLost(); } else { result = mDevice->TestCooperativeLevel(); while (result == D3DERR_DEVICELOST) { - Sleep(100); // Give the graphics driver some CPU time + Sleep(100); // Give the graphics driver some CPU time result = mDevice->TestCooperativeLevel(); } @@ -2157,13 +2340,13 @@ bool Renderer9::resetDevice() if (FAILED(result)) { - ERR("Reset/ResetEx failed multiple times: 0x%08X", result); + ERR() << "Reset/ResetEx failed multiple times, " << gl::FmtHR(result); return false; } if (removedDevice && lost) { - ERR("Device lost reset failed multiple times"); + ERR() << "Device lost reset failed multiple times"; return false; } @@ -2171,11 +2354,12 @@ bool Renderer9::resetDevice() if (!removedDevice) { // reset device defaults - initializeDevice(); + if (initializeDevice().isError()) + { + return false; + } } - mDeviceLost = false; - return true; } @@ -2184,15 +2368,16 @@ bool Renderer9::isRemovedDeviceResettable() const bool success = false; #if ANGLE_D3D9EX == ANGLE_ENABLED - IDirect3D9Ex *d3d9Ex = NULL; - typedef HRESULT (WINAPI *Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex**); - Direct3DCreate9ExFunc Direct3DCreate9ExPtr = reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); + IDirect3D9Ex *d3d9Ex = nullptr; + typedef HRESULT(WINAPI * Direct3DCreate9ExFunc)(UINT, IDirect3D9Ex **); + Direct3DCreate9ExFunc Direct3DCreate9ExPtr = + reinterpret_cast(GetProcAddress(mD3d9Module, "Direct3DCreate9Ex")); if (Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &d3d9Ex))) { D3DCAPS9 deviceCaps; HRESULT result = d3d9Ex->GetDeviceCaps(mAdapter, mDeviceType, &deviceCaps); - success = SUCCEEDED(result); + success = SUCCEEDED(result); } SafeRelease(d3d9Ex); @@ -2232,20 +2417,22 @@ std::string Renderer9::getRendererDescription() const rendererString << " Direct3D9"; } - rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_" << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion); - rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_" << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion); + rendererString << " vs_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.VertexShaderVersion) << "_" + << D3DSHADER_VERSION_MINOR(mDeviceCaps.VertexShaderVersion); + rendererString << " ps_" << D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion) << "_" + << D3DSHADER_VERSION_MINOR(mDeviceCaps.PixelShaderVersion); return rendererString.str(); } DeviceIdentifier Renderer9::getAdapterIdentifier() const { - DeviceIdentifier deviceIdentifier = { 0 }; - deviceIdentifier.VendorId = static_cast(mAdapterIdentifier.VendorId); - deviceIdentifier.DeviceId = static_cast(mAdapterIdentifier.DeviceId); - deviceIdentifier.SubSysId = static_cast(mAdapterIdentifier.SubSysId); - deviceIdentifier.Revision = static_cast(mAdapterIdentifier.Revision); - deviceIdentifier.FeatureLevel = 0; + DeviceIdentifier deviceIdentifier = {0}; + deviceIdentifier.VendorId = static_cast(mAdapterIdentifier.VendorId); + deviceIdentifier.DeviceId = static_cast(mAdapterIdentifier.DeviceId); + deviceIdentifier.SubSysId = static_cast(mAdapterIdentifier.SubSysId); + deviceIdentifier.Revision = static_cast(mAdapterIdentifier.Revision); + deviceIdentifier.FeatureLevel = 0; return deviceIdentifier; } @@ -2260,20 +2447,10 @@ unsigned int Renderer9::getReservedFragmentUniformVectors() const return d3d9_gl::GetReservedFragmentUniformVectors(); } -unsigned int Renderer9::getReservedVertexUniformBuffers() const -{ - return 0; -} - -unsigned int Renderer9::getReservedFragmentUniformBuffers() const -{ - return 0; -} - bool Renderer9::getShareHandleSupport() const { // PIX doesn't seem to support using share handles, so disable them. - return (mD3d9Ex != NULL) && !gl::DebugAnnotationsActive(); + return (mD3d9Ex != nullptr) && !gl::DebugAnnotationsActive(); } int Renderer9::getMajorShaderModel() const @@ -2298,7 +2475,7 @@ DWORD Renderer9::getCapsDeclTypes() const D3DPOOL Renderer9::getBufferPool(DWORD usage) const { - if (mD3d9Ex != NULL) + if (mD3d9Ex != nullptr) { return D3DPOOL_DEFAULT; } @@ -2313,66 +2490,126 @@ D3DPOOL Renderer9::getBufferPool(DWORD usage) const return D3DPOOL_DEFAULT; } -gl::Error Renderer9::copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { RECT rect; - rect.left = sourceRect.x; - rect.top = sourceRect.y; - rect.right = sourceRect.x + sourceRect.width; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copy2D(framebuffer, rect, destFormat, destOffset, storage, level); + return mBlit->copy2D(context, framebuffer, rect, destFormat, destOffset, storage, level); } -gl::Error Renderer9::copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level) +gl::Error Renderer9::copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) { RECT rect; - rect.left = sourceRect.x; - rect.top = sourceRect.y; - rect.right = sourceRect.x + sourceRect.width; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; rect.bottom = sourceRect.y + sourceRect.height; - return mBlit->copyCube(framebuffer, rect, destFormat, destOffset, storage, target, level); + return mBlit->copyCube(context, framebuffer, rect, destFormat, destOffset, storage, target, + level); } -gl::Error Renderer9::copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { // 3D textures are not available in the D3D9 backend. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error Renderer9::copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level) +gl::Error Renderer9::copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) { // 2D array textures are not available in the D3D9 backend. UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); +} + +gl::Error Renderer9::copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + RECT rect; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; + rect.bottom = sourceRect.y + sourceRect.height; + + return mBlit->copyTexture(context, source, sourceLevel, rect, destFormat, destOffset, storage, + destTarget, destLevel, unpackFlipY, unpackPremultiplyAlpha, + unpackUnmultiplyAlpha); } -gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT) +gl::Error Renderer9::copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) +{ + UNIMPLEMENTED(); + return gl::InternalError(); +} + +gl::Error Renderer9::createRenderTarget(int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) { const d3d9::TextureFormat &d3d9FormatInfo = d3d9::GetTextureFormatInfo(format); - const gl::TextureCaps &textureCaps = getRendererTextureCaps().get(format); - GLuint supportedSamples = textureCaps.getNearestSamples(samples); + const gl::TextureCaps &textureCaps = getNativeTextureCaps().get(format); + GLuint supportedSamples = textureCaps.getNearestSamples(samples); IDirect3DTexture9 *texture = nullptr; - IDirect3DSurface9 *renderTarget = NULL; + IDirect3DSurface9 *renderTarget = nullptr; if (width > 0 && height > 0) { bool requiresInitialization = false; - HRESULT result = D3DERR_INVALIDCALL; + HRESULT result = D3DERR_INVALIDCALL; - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(format); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(format); if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { - result = mDevice->CreateDepthStencilSurface(width, height, d3d9FormatInfo.renderFormat, - gl_d3d9::GetMultisampleType(supportedSamples), - 0, FALSE, &renderTarget, NULL); + result = mDevice->CreateDepthStencilSurface( + width, height, d3d9FormatInfo.renderFormat, + gl_d3d9::GetMultisampleType(supportedSamples), 0, FALSE, &renderTarget, nullptr); } else { @@ -2398,25 +2635,25 @@ gl::Error Renderer9::createRenderTarget(int width, int height, GLenum format, GL if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create render target, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create render target, " << gl::FmtHR(result); } if (requiresInitialization) { - // This format requires that the data be initialized before the render target can be used - // Unfortunately this requires a Get call on the d3d device but it is far better than having - // to mark the render target as lockable and copy data to the gpu. - IDirect3DSurface9 *prevRenderTarget = NULL; + // This format requires that the data be initialized before the render target can be + // used Unfortunately this requires a Get call on the d3d device but it is far better + // than having to mark the render target as lockable and copy data to the gpu. + IDirect3DSurface9 *prevRenderTarget = nullptr; mDevice->GetRenderTarget(0, &prevRenderTarget); mDevice->SetRenderTarget(0, renderTarget); - mDevice->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); + mDevice->Clear(0, nullptr, D3DCLEAR_TARGET, D3DCOLOR_RGBA(0, 0, 0, 255), 0.0f, 0); mDevice->SetRenderTarget(0, prevRenderTarget); } } *outRT = new TextureRenderTarget9(texture, 0, renderTarget, format, width, height, 1, supportedSamples); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) @@ -2424,7 +2661,7 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge ASSERT(source != nullptr); RenderTargetD3D *newRT = nullptr; - gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), + gl::Error error = createRenderTarget(source->getWidth(), source->getHeight(), source->getInternalFormat(), source->getSamples(), &newRT); if (error.isError()) { @@ -2439,31 +2676,16 @@ gl::Error Renderer9::createRenderTargetCopy(RenderTargetD3D *source, RenderTarge if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to copy render target, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to copy render target, " << gl::FmtHR(result); } *outRT = newRT; - return gl::Error(GL_NO_ERROR); -} - -FramebufferImpl *Renderer9::createFramebuffer(const gl::Framebuffer::Data &data) -{ - return new Framebuffer9(data, this); -} - -ShaderImpl *Renderer9::createShader(const gl::Shader::Data &data) -{ - return new ShaderD3D(data); + return gl::NoError(); } -ProgramImpl *Renderer9::createProgram(const gl::Program::Data &data) -{ - return new ProgramD3D(data, this); -} - -gl::Error Renderer9::loadExecutable(const void *function, +gl::Error Renderer9::loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) @@ -2473,10 +2695,10 @@ gl::Error Renderer9::loadExecutable(const void *function, switch (type) { - case SHADER_VERTEX: + case gl::SHADER_VERTEX: { - IDirect3DVertexShader9 *vshader = NULL; - gl::Error error = createVertexShader((DWORD*)function, length, &vshader); + IDirect3DVertexShader9 *vshader = nullptr; + gl::Error error = createVertexShader((DWORD *)function, length, &vshader); if (error.isError()) { return error; @@ -2484,10 +2706,10 @@ gl::Error Renderer9::loadExecutable(const void *function, *outExecutable = new ShaderExecutable9(function, length, vshader); } break; - case SHADER_PIXEL: + case gl::SHADER_FRAGMENT: { - IDirect3DPixelShader9 *pshader = NULL; - gl::Error error = createPixelShader((DWORD*)function, length, &pshader); + IDirect3DPixelShader9 *pshader = nullptr; + gl::Error error = createPixelShader((DWORD *)function, length, &pshader); if (error.isError()) { return error; @@ -2495,41 +2717,45 @@ gl::Error Renderer9::loadExecutable(const void *function, *outExecutable = new ShaderExecutable9(function, length, pshader); } break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + default: + UNREACHABLE(); + return gl::InternalError(); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) { // Transform feedback is not supported in ES2 or D3D9 ASSERT(streamOutVaryings.empty()); - const char *profileType = NULL; + std::stringstream profileStream; + switch (type) { - case SHADER_VERTEX: - profileType = "vs"; - break; - case SHADER_PIXEL: - profileType = "ps"; - break; - default: - UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + case gl::SHADER_VERTEX: + profileStream << "vs"; + break; + case gl::SHADER_FRAGMENT: + profileStream << "ps"; + break; + default: + UNREACHABLE(); + return gl::InternalError(); } - unsigned int profileMajorVersion = (getMajorShaderModel() >= 3) ? 3 : 2; - unsigned int profileMinorVersion = 0; - std::string profile = FormatString("%s_%u_%u", profileType, profileMajorVersion, profileMinorVersion); + + profileStream << "_" << ((getMajorShaderModel() >= 3) ? 3 : 2); + profileStream << "_" + << "0"; + + std::string profile = profileStream.str(); UINT flags = ANGLE_COMPILE_OPTIMIZATION_LEVEL; @@ -2551,31 +2777,35 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, flags |= D3DCOMPILE_DEBUG; } - // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders when it would otherwise pass with alternative options. - // Try the default flags first and if compilation fails, try some alternatives. + // Sometimes D3DCompile will fail with the default compilation flags for complicated shaders + // when it would otherwise pass with alternative options. Try the default flags first and if + // compilation fails, try some alternatives. std::vector configs; - configs.push_back(CompileConfig(flags, "default" )); - configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control" )); + configs.push_back(CompileConfig(flags, "default")); + configs.push_back(CompileConfig(flags | D3DCOMPILE_AVOID_FLOW_CONTROL, "avoid flow control")); configs.push_back(CompileConfig(flags | D3DCOMPILE_PREFER_FLOW_CONTROL, "prefer flow control")); - ID3DBlob *binary = NULL; + ID3DBlob *binary = nullptr; std::string debugInfo; - gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, NULL, &binary, &debugInfo); + gl::Error error = mCompiler.compileToBinary(infoLog, shaderHLSL, profile, configs, nullptr, + &binary, &debugInfo); if (error.isError()) { return error; } - // It's possible that binary is NULL if the compiler failed in all configurations. Set the executable to NULL - // and return GL_NO_ERROR to signify that there was a link error but the internal state is still OK. + // It's possible that binary is NULL if the compiler failed in all configurations. Set the + // executable to NULL and return GL_NO_ERROR to signify that there was a link error but the + // internal state is still OK. if (!binary) { - *outExectuable = NULL; - return gl::Error(GL_NO_ERROR); + *outExectuable = nullptr; + return gl::NoError(); } - error = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type, - streamOutVaryings, separatedOutputBuffers, outExectuable); + error = loadExecutable(reinterpret_cast(binary->GetBufferPointer()), + binary->GetBufferSize(), type, streamOutVaryings, separatedOutputBuffers, + outExectuable); SafeRelease(binary); if (error.isError()) @@ -2588,7 +2818,12 @@ gl::Error Renderer9::compileToExecutable(gl::InfoLog &infoLog, (*outExectuable)->appendDebugInfo(debugInfo); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error Renderer9::ensureHLSLCompilerInitialized() +{ + return mCompiler.ensureInitialized(); } UniformStorageD3D *Renderer9::createUniformStorage(size_t storageSize) @@ -2603,7 +2838,7 @@ gl::Error Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *des D3DPOOL Renderer9::getTexturePool(DWORD usage) const { - if (mD3d9Ex != NULL) + if (mD3d9Ex != nullptr) { return D3DPOOL_DEFAULT; } @@ -2618,7 +2853,9 @@ D3DPOOL Renderer9::getTexturePool(DWORD usage) const return D3DPOOL_DEFAULT; } -gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) +gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, + IDirect3DSurface9 *source, + bool fromManaged) { ASSERT(source && dest); @@ -2630,28 +2867,34 @@ gl::Error Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurfac source->GetDesc(&desc); IDirect3DSurface9 *surf = 0; - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &surf, nullptr); if (SUCCEEDED(result)) { - Image9::copyLockableSurfaces(surf, source); - result = mDevice->UpdateSurface(surf, NULL, dest, NULL); + ANGLE_TRY(Image9::copyLockableSurfaces(surf, source)); + result = mDevice->UpdateSurface(surf, nullptr, dest, nullptr); SafeRelease(surf); } } else { endScene(); - result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); + result = mDevice->StretchRect(source, nullptr, dest, nullptr, D3DTEXF_NONE); } if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to blit internal texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to blit internal texture, " << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +RendererClass Renderer9::getRendererClass() const +{ + return RENDERER_D3D9; } ImageD3D *Renderer9::createImage() @@ -2659,18 +2902,34 @@ ImageD3D *Renderer9::createImage() return new Image9(this); } -gl::Error Renderer9::generateMipmap(ImageD3D *dest, ImageD3D *src) +gl::Error Renderer9::generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *src) { Image9 *src9 = GetAs(src); Image9 *dst9 = GetAs(dest); return Image9::generateMipmap(dst9, src9); } -gl::Error Renderer9::generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) +gl::Error Renderer9::generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) { UNREACHABLE(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); +} + +gl::Error Renderer9::copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) +{ + Image9 *dest9 = GetAs(dest); + Image9 *src9 = GetAs(source); + return Image9::CopyImage(context, dest9, src9, sourceRect, destOffset, unpackFlipY, + unpackPremultiplyAlpha, unpackUnmultiplyAlpha); } TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) @@ -2679,59 +2938,83 @@ TextureStorage *Renderer9::createTextureStorage2D(SwapChainD3D *swapChain) return new TextureStorage9_2D(this, swapChain9); } -TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage) +TextureStorage *Renderer9::createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) +{ + return new TextureStorage9_EGLImage(this, eglImage, GetAs(renderTargetD3D)); +} + +TextureStorage *Renderer9::createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) { - return new TextureStorage9_EGLImage(this, eglImage); + UNIMPLEMENTED(); + return nullptr; } -TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly) +TextureStorage *Renderer9::createTextureStorage2D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) { return new TextureStorage9_2D(this, internalformat, renderTarget, width, height, levels); } -TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) +TextureStorage *Renderer9::createTextureStorageCube(GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) { - return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels, hintLevelZeroOnly); + return new TextureStorage9_Cube(this, internalformat, renderTarget, size, levels, + hintLevelZeroOnly); } -TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) +TextureStorage *Renderer9::createTextureStorage3D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) { // 3D textures are not supported by the D3D9 backend. UNREACHABLE(); - return NULL; + return nullptr; } -TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels) +TextureStorage *Renderer9::createTextureStorage2DArray(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) { // 2D array textures are not supported by the D3D9 backend. UNREACHABLE(); - return NULL; + return nullptr; } -TextureImpl *Renderer9::createTexture(GLenum target) +TextureStorage *Renderer9::createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) { - switch(target) - { - case GL_TEXTURE_2D: return new TextureD3D_2D(this); - case GL_TEXTURE_CUBE_MAP: return new TextureD3D_Cube(this); - default: UNREACHABLE(); - } + // 2D multisampled textures are not supported by the D3D9 backend. + UNREACHABLE(); return NULL; } -RenderbufferImpl *Renderer9::createRenderbuffer() -{ - RenderbufferD3D *renderbuffer = new RenderbufferD3D(this); - return renderbuffer; -} - bool Renderer9::getLUID(LUID *adapterLuid) const { adapterLuid->HighPart = 0; - adapterLuid->LowPart = 0; + adapterLuid->LowPart = 0; if (mD3d9Ex) { @@ -2752,6 +3035,40 @@ GLenum Renderer9::getVertexComponentType(gl::VertexFormatType vertexFormatType) return d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType).componentType; } +gl::ErrorOrResult Renderer9::getVertexSpaceRequired(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const +{ + if (!attrib.enabled) + { + return 16u; + } + + gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT); + const d3d9::VertexFormat &d3d9VertexInfo = + d3d9::GetVertexFormatInfo(getCapsDeclTypes(), vertexFormatType); + + unsigned int elementCount = 0; + const unsigned int divisor = binding.getDivisor(); + if (instances == 0 || divisor == 0) + { + elementCount = static_cast(count); + } + else + { + // Round up to divisor, if possible + elementCount = UnsignedCeilDivide(static_cast(instances), divisor); + } + + if (d3d9VertexInfo.outputElementSize > std::numeric_limits::max() / elementCount) + { + return gl::OutOfMemory() << "New vertex buffer size would result in an overflow."; + } + + return static_cast(d3d9VertexInfo.outputElementSize) * elementCount; +} + void Renderer9::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions, @@ -2761,31 +3078,11 @@ void Renderer9::generateCaps(gl::Caps *outCaps, outExtensions, outLimitations); } -WorkaroundsD3D Renderer9::generateWorkarounds() const +angle::WorkaroundsD3D Renderer9::generateWorkarounds() const { return d3d9::GenerateWorkarounds(); } -void Renderer9::createAnnotator() -{ - mAnnotator = new DebugAnnotator9(); -} - -gl::Error Renderer9::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) -{ - // TODO(jmadill): faster way? - for (size_t samplerIndex = rangeStart; samplerIndex < rangeEnd; samplerIndex++) - { - gl::Error error = setTexture(samplerType, static_cast(samplerIndex), nullptr); - if (error.isError()) - { - return error; - } - } - - return gl::Error(GL_NO_ERROR); -} - egl::Error Renderer9::getEGLDevice(DeviceImpl **device) { if (mEGLDevice == nullptr) @@ -2803,14 +3100,211 @@ egl::Error Renderer9::getEGLDevice(DeviceImpl **device) } *device = static_cast(mEGLDevice); - return egl::Error(EGL_SUCCESS); + return egl::NoError(); } Renderer9::CurSamplerState::CurSamplerState() - : forceSet(true), - baseLevel(std::numeric_limits::max()), - samplerState() + : forceSet(true), baseLevel(std::numeric_limits::max()), samplerState() +{ +} + +gl::Error Renderer9::genericDrawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances) +{ + const auto &data = context->getContextState(); + gl::Program *program = context->getGLState().getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); + + programD3D->updateSamplerMapping(); + + if (!applyPrimitiveType(mode, count, usesPointSize)) + { + return gl::NoError(); + } + + ANGLE_TRY(updateState(context, mode)); + ANGLE_TRY(applyTextures(context)); + ANGLE_TRY(applyShaders(context, mode)); + + if (!skipDraw(data.getState(), mode)) + { + ANGLE_TRY(drawElementsImpl(context, mode, count, type, indices, instances)); + } + + return gl::NoError(); +} + +gl::Error Renderer9::genericDrawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances) +{ + gl::Program *program = context->getGLState().getProgram(); + ASSERT(program != nullptr); + ProgramD3D *programD3D = GetImplAs(program); + bool usesPointSize = programD3D->usesPointSize(); + + programD3D->updateSamplerMapping(); + + if (!applyPrimitiveType(mode, count, usesPointSize)) + { + return gl::NoError(); + } + + ANGLE_TRY(updateState(context, mode)); + ANGLE_TRY(applyVertexBuffer(context, mode, first, count, instances, nullptr)); + ANGLE_TRY(applyTextures(context)); + ANGLE_TRY(applyShaders(context, mode)); + + if (!skipDraw(context->getGLState(), mode)) + { + ANGLE_TRY(drawArraysImpl(context, mode, first, count, instances)); + } + + return gl::NoError(); +} + +FramebufferImpl *Renderer9::createDefaultFramebuffer(const gl::FramebufferState &state) { + return new Framebuffer9(state, this); } +gl::Version Renderer9::getMaxSupportedESVersion() const +{ + return gl::Version(2, 0); +} + +gl::Error Renderer9::clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) +{ + D3DCOLOR color = + D3DCOLOR_ARGB(gl::unorm<8>(clearColorValue.alpha), gl::unorm<8>(clearColorValue.red), + gl::unorm<8>(clearColorValue.green), gl::unorm<8>(clearColorValue.blue)); + float depth = clearDepthValue; + DWORD stencil = clearStencilValue & 0x000000FF; + + unsigned int renderTargetSerial = renderTarget->getSerial(); + RenderTarget9 *renderTarget9 = GetAs(renderTarget); + IDirect3DSurface9 *renderTargetSurface = renderTarget9->getSurface(); + ASSERT(renderTargetSurface); + + DWORD dxClearFlags = 0; + + const gl::InternalFormat &internalFormatInfo = + gl::GetSizedInternalFormatInfo(renderTarget->getInternalFormat()); + if (internalFormatInfo.depthBits > 0 || internalFormatInfo.stencilBits > 0) + { + dxClearFlags = D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL; + if (mAppliedDepthStencilSerial != renderTargetSerial) + { + mDevice->SetDepthStencilSurface(renderTargetSurface); + } + } + else + { + dxClearFlags = D3DCLEAR_TARGET; + if (mAppliedRenderTargetSerial != renderTargetSerial) + { + mDevice->SetRenderTarget(0, renderTargetSurface); + } + } + SafeRelease(renderTargetSurface); + + D3DVIEWPORT9 viewport; + viewport.X = 0; + viewport.Y = 0; + viewport.Width = renderTarget->getWidth(); + viewport.Height = renderTarget->getHeight(); + mDevice->SetViewport(&viewport); + + mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + + mDevice->Clear(0, nullptr, dxClearFlags, color, depth, stencil); + + markAllStateDirty(); + + return gl::NoError(); } + +bool Renderer9::canSelectViewInVertexShader() const +{ + return false; +} + +// For each Direct3D sampler of either the pixel or vertex stage, +// looks up the corresponding OpenGL texture image unit and texture type, +// and sets the texture and its addressing/filtering state (or NULL when inactive). +// Sampler mapping needs to be up-to-date on the program object before this is called. +gl::Error Renderer9::applyTextures(const gl::Context *context, gl::SamplerType shaderType) +{ + const auto &glState = context->getGLState(); + const auto &caps = context->getCaps(); + ProgramD3D *programD3D = GetImplAs(glState.getProgram()); + + ASSERT(!programD3D->isSamplerMappingDirty()); + + // TODO(jmadill): Use the Program's sampler bindings. + const auto &completeTextures = glState.getCompleteTextureCache(); + + unsigned int samplerRange = programD3D->getUsedSamplerRange(shaderType); + for (unsigned int samplerIndex = 0; samplerIndex < samplerRange; samplerIndex++) + { + GLint textureUnit = programD3D->getSamplerMapping(shaderType, samplerIndex, caps); + ASSERT(textureUnit != -1); + gl::Texture *texture = completeTextures[textureUnit]; + + // A nullptr texture indicates incomplete. + if (texture) + { + gl::Sampler *samplerObject = glState.getSampler(textureUnit); + + const gl::SamplerState &samplerState = + samplerObject ? samplerObject->getSamplerState() : texture->getSamplerState(); + + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, texture, samplerState)); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, texture)); + } + else + { + GLenum textureType = programD3D->getSamplerTextureType(shaderType, samplerIndex); + + // Texture is not sampler complete or it is in use by the framebuffer. Bind the + // incomplete texture. + gl::Texture *incompleteTexture = nullptr; + ANGLE_TRY(getIncompleteTexture(context, textureType, &incompleteTexture)); + ANGLE_TRY(setSamplerState(context, shaderType, samplerIndex, incompleteTexture, + incompleteTexture->getSamplerState())); + ANGLE_TRY(setTexture(context, shaderType, samplerIndex, incompleteTexture)); + } + } + + // Set all the remaining textures to NULL + size_t samplerCount = (shaderType == gl::SAMPLER_PIXEL) ? caps.maxTextureImageUnits + : caps.maxVertexTextureImageUnits; + + // TODO(jmadill): faster way? + for (size_t samplerIndex = samplerRange; samplerIndex < samplerCount; samplerIndex++) + { + ANGLE_TRY(setTexture(context, shaderType, static_cast(samplerIndex), nullptr)); + } + + return gl::NoError(); +} + +gl::Error Renderer9::applyTextures(const gl::Context *context) +{ + ANGLE_TRY(applyTextures(context, gl::SAMPLER_VERTEX)); + ANGLE_TRY(applyTextures(context, gl::SAMPLER_PIXEL)); + return gl::NoError(); +} + +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h index a0dfecb02e..9ddee45f0f 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/Renderer9.h @@ -12,12 +12,13 @@ #include "common/angleutils.h" #include "common/mathutil.h" #include "libANGLE/renderer/d3d/HLSLCompiler.h" -#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/RenderTargetD3D.h" +#include "libANGLE/renderer/d3d/RendererD3D.h" #include "libANGLE/renderer/d3d/d3d9/DebugAnnotator9.h" #include "libANGLE/renderer/d3d/d3d9/ShaderCache.h" -#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" #include "libANGLE/renderer/d3d/d3d9/StateManager9.h" +#include "libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h" +#include "libANGLE/renderer/driver_utils.h" namespace gl { @@ -32,6 +33,7 @@ class AttributeMap; namespace rx { class Blit9; +class Context9; class IndexDataManager; class ProgramD3D; class StreamingIndexBufferInterface; @@ -65,184 +67,270 @@ class Renderer9 : public RendererD3D { public: explicit Renderer9(egl::Display *display); - virtual ~Renderer9(); + ~Renderer9() override; egl::Error initialize() override; - virtual bool resetDevice(); + bool resetDevice() override; - egl::ConfigSet generateConfigs() const override; + egl::ConfigSet generateConfigs() override; void generateDisplayExtensions(egl::DisplayExtensions *outExtensions) const override; void startScene(); void endScene(); - gl::Error flush() override; - gl::Error finish() override; + gl::Error flush(); + gl::Error finish(); - SwapChainD3D *createSwapChain(NativeWindow nativeWindow, + bool isValidNativeWindow(EGLNativeWindowType window) const override; + NativeWindowD3D *createNativeWindow(EGLNativeWindowType window, + const egl::Config *config, + const egl::AttributeMap &attribs) const override; + + SwapChainD3D *createSwapChain(NativeWindowD3D *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, - EGLint orientation) override; - - CompilerImpl *createCompiler() override; + EGLint orientation, + EGLint samples) override; + egl::Error getD3DTextureInfo(const egl::Config *configuration, + IUnknown *d3dTexture, + EGLint *width, + EGLint *height, + GLenum *fboFormat) const override; + egl::Error validateShareHandle(const egl::Config *config, + HANDLE shareHandle, + const egl::AttributeMap &attribs) const override; + + ContextImpl *createContext(const gl::ContextState &state) override; gl::Error allocateEventQuery(IDirect3DQuery9 **outQuery); - void freeEventQuery(IDirect3DQuery9* query); + void freeEventQuery(IDirect3DQuery9 *query); // resource creation - gl::Error createVertexShader(const DWORD *function, size_t length, IDirect3DVertexShader9 **outShader); - gl::Error createPixelShader(const DWORD *function, size_t length, IDirect3DPixelShader9 **outShader); + gl::Error createVertexShader(const DWORD *function, + size_t length, + IDirect3DVertexShader9 **outShader); + gl::Error createPixelShader(const DWORD *function, + size_t length, + IDirect3DPixelShader9 **outShader); HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); - HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); - virtual gl::Error generateSwizzle(gl::Texture *texture); - virtual gl::Error setSamplerState(gl::SamplerType type, int index, gl::Texture *texture, const gl::SamplerState &sampler); - virtual gl::Error setTexture(gl::SamplerType type, int index, gl::Texture *texture); - - gl::Error setUniformBuffers(const gl::Data &data, - const std::vector &vertexUniformBuffers, - const std::vector &fragmentUniformBuffers) override; - - gl::Error updateState(const gl::Data &data, GLenum drawMode) override; + HRESULT createIndexBuffer(UINT Length, + DWORD Usage, + D3DFORMAT Format, + IDirect3DIndexBuffer9 **ppIndexBuffer); + gl::Error setSamplerState(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture, + const gl::SamplerState &sampler); + gl::Error setTexture(const gl::Context *context, + gl::SamplerType type, + int index, + gl::Texture *texture); + + gl::Error updateState(const gl::Context *context, GLenum drawMode); void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - void setViewport(const gl::Caps *caps, - const gl::Rectangle &viewport, + void setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, bool ignoreViewport); - gl::Error applyRenderTarget(const gl::Framebuffer *frameBuffer) override; - gl::Error applyRenderTarget(const gl::FramebufferAttachment *colorAttachment, + gl::Error applyRenderTarget(const gl::Context *context, const gl::Framebuffer *frameBuffer); + gl::Error applyRenderTarget(const gl::Context *context, + const gl::FramebufferAttachment *colorAttachment, const gl::FramebufferAttachment *depthStencilAttachment); - gl::Error applyUniforms(const ProgramD3D &programD3D, - GLenum drawMode, - const std::vector &uniformArray) override; - virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); - virtual gl::Error applyVertexBuffer(const gl::State &state, - GLenum mode, - GLint first, - GLsizei count, - GLsizei instances, - TranslatedIndexData *indexInfo); - gl::Error applyIndexBuffer(const gl::Data &data, - const GLvoid *indices, + gl::Error applyUniforms(ProgramD3D *programD3D); + bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount, bool usesPointSize); + gl::Error applyVertexBuffer(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances, + TranslatedIndexData *indexInfo); + gl::Error applyIndexBuffer(const gl::Context *context, + const void *indices, GLsizei count, GLenum mode, GLenum type, - TranslatedIndexData *indexInfo) override; + TranslatedIndexData *indexInfo); - void applyTransformFeedbackBuffers(const gl::State &state) override; - - gl::Error clear(const ClearParameters &clearParams, + gl::Error clear(const gl::Context *context, + const ClearParameters &clearParams, const gl::FramebufferAttachment *colorBuffer, const gl::FramebufferAttachment *depthStencilBuffer); - virtual void markAllStateDirty(); + void markAllStateDirty(); // lost device bool testDeviceLost() override; bool testDeviceResettable() override; VendorID getVendorId() const; - std::string getRendererDescription() const override; + std::string getRendererDescription() const; DeviceIdentifier getAdapterIdentifier() const override; IDirect3DDevice9 *getDevice() { return mDevice; } void *getD3DDevice() override; - virtual unsigned int getReservedVertexUniformVectors() const; - virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getReservedVertexUniformBuffers() const; - virtual unsigned int getReservedFragmentUniformBuffers() const; + unsigned int getReservedVertexUniformVectors() const; + unsigned int getReservedFragmentUniformVectors() const; bool getShareHandleSupport() const; - virtual int getMajorShaderModel() const; + int getMajorShaderModel() const override; int getMinorShaderModel() const override; std::string getShaderModelSuffix() const override; DWORD getCapsDeclTypes() const; // Pixel operations - virtual gl::Error copyImage2D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); - virtual gl::Error copyImageCube(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLenum target, GLint level); - virtual gl::Error copyImage3D(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); - virtual gl::Error copyImage2DArray(const gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - const gl::Offset &destOffset, TextureStorage *storage, GLint level); + gl::Error copyImage2D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + gl::Error copyImageCube(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum target, + GLint level) override; + gl::Error copyImage3D(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + gl::Error copyImage2DArray(const gl::Context *context, + const gl::Framebuffer *framebuffer, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLint level) override; + + gl::Error copyTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + const gl::Rectangle &sourceRect, + GLenum destFormat, + const gl::Offset &destOffset, + TextureStorage *storage, + GLenum destTarget, + GLint destLevel, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + gl::Error copyCompressedTexture(const gl::Context *context, + const gl::Texture *source, + GLint sourceLevel, + TextureStorage *storage, + GLint destLevel) override; // RenderTarget creation - virtual gl::Error createRenderTarget(int width, int height, GLenum format, GLsizei samples, RenderTargetD3D **outRT); + gl::Error createRenderTarget(int width, + int height, + GLenum format, + GLsizei samples, + RenderTargetD3D **outRT) override; gl::Error createRenderTargetCopy(RenderTargetD3D *source, RenderTargetD3D **outRT) override; - // Framebuffer creation - FramebufferImpl *createFramebuffer(const gl::Framebuffer::Data &data) override; - - // Shader creation - ShaderImpl *createShader(const gl::Shader::Data &data) override; - ProgramImpl *createProgram(const gl::Program::Data &data) override; - // Shader operations - gl::Error loadExecutable(const void *function, + gl::Error loadExecutable(const uint8_t *function, size_t length, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, ShaderExecutableD3D **outExecutable) override; gl::Error compileToExecutable(gl::InfoLog &infoLog, const std::string &shaderHLSL, - ShaderType type, + gl::ShaderType type, const std::vector &streamOutVaryings, bool separatedOutputBuffers, - const D3DCompilerWorkarounds &workarounds, + const angle::CompilerWorkaroundsD3D &workarounds, ShaderExecutableD3D **outExectuable) override; + gl::Error ensureHLSLCompilerInitialized() override; + UniformStorageD3D *createUniformStorage(size_t storageSize) override; // Image operations - virtual ImageD3D *createImage(); - gl::Error generateMipmap(ImageD3D *dest, ImageD3D *source) override; - gl::Error generateMipmapsUsingD3D(TextureStorage *storage, - const gl::TextureState &textureState) override; - virtual TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain); - TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage) override; - virtual TextureStorage *createTextureStorage2D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels, bool hintLevelZeroOnly); - virtual TextureStorage *createTextureStorageCube(GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); - virtual TextureStorage *createTextureStorage3D(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); - virtual TextureStorage *createTextureStorage2DArray(GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, GLsizei depth, int levels); - - // Texture creation - virtual TextureImpl *createTexture(GLenum target); - - // Renderbuffer creation - virtual RenderbufferImpl *createRenderbuffer(); + ImageD3D *createImage() override; + gl::Error generateMipmap(const gl::Context *context, ImageD3D *dest, ImageD3D *source) override; + gl::Error generateMipmapUsingD3D(const gl::Context *context, + TextureStorage *storage, + const gl::TextureState &textureState) override; + gl::Error copyImage(const gl::Context *context, + ImageD3D *dest, + ImageD3D *source, + const gl::Rectangle &sourceRect, + const gl::Offset &destOffset, + bool unpackFlipY, + bool unpackPremultiplyAlpha, + bool unpackUnmultiplyAlpha) override; + TextureStorage *createTextureStorage2D(SwapChainD3D *swapChain) override; + TextureStorage *createTextureStorageEGLImage(EGLImageD3D *eglImage, + RenderTargetD3D *renderTargetD3D) override; + TextureStorage *createTextureStorageExternal( + egl::Stream *stream, + const egl::Stream::GLTextureDescription &desc) override; + TextureStorage *createTextureStorage2D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + int levels, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorageCube(GLenum internalformat, + bool renderTarget, + int size, + int levels, + bool hintLevelZeroOnly) override; + TextureStorage *createTextureStorage3D(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) override; + TextureStorage *createTextureStorage2DArray(GLenum internalformat, + bool renderTarget, + GLsizei width, + GLsizei height, + GLsizei depth, + int levels) override; + + TextureStorage *createTextureStorage2DMultisample(GLenum internalformat, + GLsizei width, + GLsizei height, + int levels, + int samples, + bool fixedSampleLocations) override; // Buffer creation - virtual BufferImpl *createBuffer(); - virtual VertexBuffer *createVertexBuffer(); - virtual IndexBuffer *createIndexBuffer(); + VertexBuffer *createVertexBuffer() override; + IndexBuffer *createIndexBuffer() override; - // Vertex Array creation - VertexArrayImpl *createVertexArray(const gl::VertexArray::Data &data) override; - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type); - virtual FenceNVImpl *createFenceNV(); - virtual FenceSyncImpl *createFenceSync(); - - // Transform Feedback creation - virtual TransformFeedbackImpl* createTransformFeedback(); + // Stream Creation + StreamProducerImpl *createStreamProducerD3DTextureNV12( + egl::Stream::ConsumerType consumerType, + const egl::AttributeMap &attribs) override; // Buffer-to-texture and Texture-to-buffer copies - virtual bool supportsFastCopyBufferToTexture(GLenum internalFormat) const; - virtual gl::Error fastCopyBufferToTexture(const gl::PixelUnpackState &unpack, unsigned int offset, RenderTargetD3D *destRenderTarget, - GLenum destinationFormat, GLenum sourcePixelsType, const gl::Box &destArea); - - void syncState(const gl::State &state, const gl::State::DirtyBits &bitmask) override; + bool supportsFastCopyBufferToTexture(GLenum internalFormat) const override; + gl::Error fastCopyBufferToTexture(const gl::Context *context, + const gl::PixelUnpackState &unpack, + unsigned int offset, + RenderTargetD3D *destRenderTarget, + GLenum destinationFormat, + GLenum sourcePixelsType, + const gl::Box &destArea) override; // D3D9-renderer specific methods gl::Error boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); @@ -250,42 +338,82 @@ class Renderer9 : public RendererD3D D3DPOOL getTexturePool(DWORD usage) const; bool getLUID(LUID *adapterLuid) const override; - VertexConversionType getVertexConversionType(gl::VertexFormatType vertexFormatType) const override; + VertexConversionType getVertexConversionType( + gl::VertexFormatType vertexFormatType) const override; GLenum getVertexComponentType(gl::VertexFormatType vertexFormatType) const override; - gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. + gl::ErrorOrResult getVertexSpaceRequired(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, + GLsizei count, + GLsizei instances) const override; - RendererClass getRendererClass() const override { return RENDERER_D3D9; } + gl::Error copyToRenderTarget(IDirect3DSurface9 *dest, + IDirect3DSurface9 *source, + bool fromManaged); + + RendererClass getRendererClass() const override; D3DDEVTYPE getD3D9DeviceType() const { return mDeviceType; } egl::Error getEGLDevice(DeviceImpl **device) override; - protected: - void createAnnotator() override; - gl::Error clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) override; - gl::Error applyShadersImpl(const gl::Data &data, GLenum drawMode) override; + StateManager9 *getStateManager() { return &mStateManager; } + + gl::Error genericDrawArrays(const gl::Context *context, + GLenum mode, + GLint first, + GLsizei count, + GLsizei instances); + + gl::Error genericDrawElements(const gl::Context *context, + GLenum mode, + GLsizei count, + GLenum type, + const void *indices, + GLsizei instances); + + // Necessary hack for default framebuffers in D3D. + FramebufferImpl *createDefaultFramebuffer(const gl::FramebufferState &state) override; + + DebugAnnotator9 *getAnnotator() { return &mAnnotator; } + + gl::Version getMaxSupportedESVersion() const override; + + gl::Error clearRenderTarget(RenderTargetD3D *renderTarget, + const gl::ColorF &clearColorValue, + const float clearDepthValue, + const unsigned int clearStencilValue) override; + + bool canSelectViewInVertexShader() const override; private: - gl::Error drawArraysImpl(const gl::Data &data, + gl::Error drawArraysImpl(const gl::Context *context, GLenum mode, + GLint startVertex, GLsizei count, - GLsizei instances) override; - gl::Error drawElementsImpl(const gl::Data &data, - const TranslatedIndexData &indexInfo, + GLsizei instances); + gl::Error drawElementsImpl(const gl::Context *context, GLenum mode, GLsizei count, GLenum type, - const GLvoid *indices, - GLsizei instances) override; + const void *indices, + GLsizei instances); - void generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureCaps, + gl::Error applyShaders(const gl::Context *context, GLenum drawMode); + + gl::Error applyTextures(const gl::Context *context); + gl::Error applyTextures(const gl::Context *context, gl::SamplerType shaderType); + + void generateCaps(gl::Caps *outCaps, + gl::TextureCapsMap *outTextureCaps, gl::Extensions *outExtensions, gl::Limitations *outLimitations) const override; - WorkaroundsD3D generateWorkarounds() const override; + angle::WorkaroundsD3D generateWorkarounds() const override; - gl::Error setBlendDepthRasterStates(const gl::Data &glData, GLenum drawMode); + gl::Error setBlendDepthRasterStates(const gl::Context *context, GLenum drawMode); void release(); @@ -293,18 +421,30 @@ class Renderer9 : public RendererD3D void applyUniformniv(const D3DUniform *targetUniform, const GLint *v); void applyUniformnbv(const D3DUniform *targetUniform, const GLint *v); - gl::Error drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - gl::Error drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + gl::Error drawLineLoop(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer); + gl::Error drawIndexedPoints(const gl::Context *context, + GLsizei count, + GLenum type, + const void *indices, + int minIndex, + gl::Buffer *elementArrayBuffer); gl::Error getCountingIB(size_t count, StaticIndexBufferInterface **outIB); - gl::Error getNullColorbuffer(const gl::FramebufferAttachment *depthbuffer, const gl::FramebufferAttachment **outColorBuffer); + gl::Error getNullColorbuffer(const gl::Context *context, + const gl::FramebufferAttachment *depthbuffer, + const gl::FramebufferAttachment **outColorBuffer); D3DPOOL getBufferPool(DWORD usage) const; HMODULE mD3d9Module; - void initializeDevice(); + egl::Error initializeDevice(); D3DPRESENT_PARAMETERS getDefaultPresentParameters(); void releaseDeviceResources(); @@ -314,7 +454,7 @@ class Renderer9 : public RendererD3D UINT mAdapter; D3DDEVTYPE mDeviceType; - IDirect3D9 *mD3d9; // Always valid after successful initialization. + IDirect3D9 *mD3d9; // Always valid after successful initialization. IDirect3D9Ex *mD3d9Ex; // Might be null if D3D9Ex is not supported. IDirect3DDevice9 *mDevice; IDirect3DDevice9Ex *mDeviceEx; // Might be null if D3D9Ex is not supported. @@ -368,7 +508,7 @@ class Renderer9 : public RendererD3D unsigned int mAppliedProgramSerial; // A pool of event queries that are currently unused. - std::vector mEventQueryPool; + std::vector mEventQueryPool; VertexShaderCache mVertexShaderCache; PixelShaderCache mPixelShaderCache; @@ -379,7 +519,10 @@ class Renderer9 : public RendererD3D StreamingIndexBufferInterface *mLineLoopIB; StaticIndexBufferInterface *mCountingIB; - enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 }; + enum + { + NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 + }; struct NullColorbufferCacheEntry { UINT lruCount; @@ -390,7 +533,11 @@ class Renderer9 : public RendererD3D UINT mMaxNullColorbufferLRU; DeviceD3D *mEGLDevice; + std::vector mTranslatedAttribCache; + + DebugAnnotator9 mAnnotator; }; -} -#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ +} // namespace rx + +#endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h index cf831c62fa..399770dd8d 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderCache.h @@ -24,9 +24,7 @@ template class ShaderCache : angle::NonCopyable { public: - ShaderCache() : mDevice(NULL) - { - } + ShaderCache() : mDevice(nullptr) {} ~ShaderCache() { @@ -47,14 +45,14 @@ class ShaderCache : angle::NonCopyable { it->second->AddRef(); *outShaderObject = it->second; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } ShaderObject *shader; HRESULT result = createShader(function, &shader); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create shader, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create shader, " << gl::FmtHR(result); } // Random eviction policy. @@ -68,7 +66,7 @@ class ShaderCache : angle::NonCopyable mMap[key] = shader; *outShaderObject = shader; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void clear() diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp index 28a486056b..362c6c60a3 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.cpp @@ -18,14 +18,14 @@ ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirec : ShaderExecutableD3D(function, length) { mPixelExecutable = executable; - mVertexExecutable = NULL; + mVertexExecutable = nullptr; } ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable) : ShaderExecutableD3D(function, length) { mVertexExecutable = executable; - mPixelExecutable = NULL; + mPixelExecutable = nullptr; } ShaderExecutable9::~ShaderExecutable9() @@ -44,4 +44,4 @@ IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const return mPixelExecutable; } -} \ No newline at end of file +} diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h index 382a68c820..0b6b87947e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/ShaderExecutable9.h @@ -20,7 +20,7 @@ class ShaderExecutable9 : public ShaderExecutableD3D public: ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable); ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable); - virtual ~ShaderExecutable9(); + ~ShaderExecutable9() override; IDirect3DPixelShader9 *getPixelShader() const; IDirect3DVertexShader9 *getVertexShader() const; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp index c4c600aedb..a3bdc14efb 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.cpp @@ -7,7 +7,7 @@ // StateManager9.cpp: Defines a class for caching D3D9 state #include "libANGLE/renderer/d3d/d3d9/StateManager9.h" -#include "common/BitSetIterator.h" +#include "common/bitset_utils.h" #include "common/utilities.h" #include "libANGLE/formatutils.h" #include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" @@ -18,7 +18,8 @@ namespace rx { StateManager9::StateManager9(Renderer9 *renderer9) - : mCurBlendState(), + : mUsingZeroColorMaskWorkaround(false), + mCurBlendState(), mCurBlendColor(0, 0, 0, 0), mCurSampleMask(0), mCurRasterState(), @@ -67,6 +68,11 @@ StateManager9::~StateManager9() { } +void StateManager9::initialize() +{ + mUsingZeroColorMaskWorkaround = IsAMD(mRenderer9->getVendorId()); +} + void StateManager9::forceSetBlendState() { mDirtyBits |= mBlendStateDirtyBits; @@ -114,7 +120,7 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits return; } - for (auto dirtyBit : angle::IterateBitSet(dirtyBits)) + for (auto dirtyBit : dirtyBits) { switch (dirtyBit) { @@ -125,6 +131,12 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits // BlendColor and funcs and equations has to be set if blend is enabled mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + + // The color mask may have to be updated if the blend state changes + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } } break; case gl::State::DIRTY_BIT_BLEND_FUNCS: @@ -138,6 +150,12 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); // BlendColor depends on the values of blend funcs mDirtyBits.set(DIRTY_BIT_BLEND_COLOR); + + // The color mask may have to be updated if the blend funcs change + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } } break; } @@ -148,6 +166,12 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits blendState.blendEquationAlpha != mCurBlendState.blendEquationAlpha) { mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + + // The color mask may have to be updated if the blend funcs change + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + } } break; } @@ -167,6 +191,14 @@ void StateManager9::syncState(const gl::State &state, const gl::State::DirtyBits blendState.colorMaskAlpha != mCurBlendState.colorMaskAlpha) { mDirtyBits.set(DIRTY_BIT_COLOR_MASK); + + // The color mask can cause the blend state to get out of sync when using the + // zero color mask workaround + if (mUsingZeroColorMaskWorkaround) + { + mDirtyBits.set(DIRTY_BIT_BLEND_ENABLED); + mDirtyBits.set(DIRTY_BIT_BLEND_FUNCS_EQUATIONS); + } } break; } @@ -364,7 +396,7 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, mCurFrontFaceCCW = frontFaceCCW; } - for (auto dirtyBit : angle::IterateBitSet(mDirtyBits)) + for (auto dirtyBit : mDirtyBits) { switch (dirtyBit) { @@ -438,11 +470,10 @@ gl::Error StateManager9::setBlendDepthRasterStates(const gl::State &glState, setSampleMask(sampleMask); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -void StateManager9::setViewportState(const gl::Caps *caps, - const gl::Rectangle &viewport, +void StateManager9::setViewportState(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, @@ -698,6 +729,7 @@ void StateManager9::setStencilTestEnabled(bool stencilTestEnabled) if (stencilTestEnabled && mCurStencilSize > 0) { mRenderer9->getDevice()->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mRenderer9->getDevice()->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); } else { @@ -718,7 +750,7 @@ void StateManager9::setSampleAlphaToCoverage(bool enabled) { if (enabled) { - FIXME("Sample alpha to coverage is unimplemented."); + UNREACHABLE(); } } @@ -800,42 +832,52 @@ void StateManager9::setColorMask(const gl::Framebuffer *framebuffer, bool alpha) { // Set the color mask - bool zeroColorMaskAllowed = mRenderer9->getVendorId() != VENDOR_ID_AMD; - // Apparently some ATI cards have a bug where a draw with a zero color - // write mask can cause later draws to have incorrect results. Instead, - // set a nonzero color write mask but modify the blend state so that no - // drawing is done. - // http://code.google.com/p/angleproject/issues/detail?id=169 - const gl::FramebufferAttachment *attachment = framebuffer->getFirstColorbuffer(); - GLenum internalFormat = attachment ? attachment->getInternalFormat() : GL_NONE; - - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + const auto *attachment = framebuffer->getFirstColorbuffer(); + const auto &format = attachment ? attachment->getFormat() : gl::Format::Invalid(); DWORD colorMask = gl_d3d9::ConvertColorMask( - formatInfo.redBits > 0 && red, formatInfo.greenBits > 0 && green, - formatInfo.blueBits > 0 && blue, formatInfo.alphaBits > 0 && alpha); - - if (colorMask == 0 && !zeroColorMaskAllowed) + format.info->redBits > 0 && red, format.info->greenBits > 0 && green, + format.info->blueBits > 0 && blue, format.info->alphaBits > 0 && alpha); + + // Apparently some ATI cards have a bug where a draw with a zero color write mask can cause + // later draws to have incorrect results. Instead, set a nonzero color write mask but modify the + // blend state so that no drawing is done. + // http://anglebug.com/169 + if (colorMask == 0 && mUsingZeroColorMaskWorkaround) { IDirect3DDevice9 *device = mRenderer9->getDevice(); // Enable green channel, but set blending so nothing will be drawn. device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + + mCurBlendState.colorMaskRed = false; + mCurBlendState.colorMaskGreen = true; + mCurBlendState.colorMaskBlue = false; + mCurBlendState.colorMaskAlpha = false; + + mCurBlendState.blend = true; + mCurBlendState.sourceBlendRGB = GL_ZERO; + mCurBlendState.sourceBlendAlpha = GL_ZERO; + mCurBlendState.destBlendRGB = GL_ONE; + mCurBlendState.destBlendAlpha = GL_ONE; + mCurBlendState.blendEquationRGB = GL_FUNC_ADD; + mCurBlendState.blendEquationAlpha = GL_FUNC_ADD; } else { mRenderer9->getDevice()->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); - } - mCurBlendState.colorMaskRed = red; - mCurBlendState.colorMaskGreen = green; - mCurBlendState.colorMaskBlue = blue; - mCurBlendState.colorMaskAlpha = alpha; + mCurBlendState.colorMaskRed = red; + mCurBlendState.colorMaskGreen = green; + mCurBlendState.colorMaskBlue = blue; + mCurBlendState.colorMaskAlpha = alpha; + } } void StateManager9::setSampleMask(unsigned int sampleMask) @@ -848,7 +890,7 @@ void StateManager9::setSampleMask(unsigned int sampleMask) mCurSampleMask = sampleMask; } -void StateManager9::setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace) +void StateManager9::setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace) { if (cullFace) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h index d8c1eb9812..63ce17cb1e 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/StateManager9.h @@ -10,7 +10,7 @@ #define LIBANGLE_RENDERER_D3D9_STATEMANAGER9_H_ #include "libANGLE/angletypes.h" -#include "libANGLE/Data.h" +#include "libANGLE/ContextState.h" #include "libANGLE/State.h" #include "libANGLE/renderer/d3d/RendererD3D.h" @@ -39,12 +39,13 @@ class StateManager9 final : angle::NonCopyable StateManager9(Renderer9 *renderer9); ~StateManager9(); + void initialize(); + void syncState(const gl::State &state, const gl::State::DirtyBits &dirtyBits); gl::Error setBlendDepthRasterStates(const gl::State &glState, unsigned int sampleMask); void setScissorState(const gl::Rectangle &scissor, bool enabled); - void setViewportState(const gl::Caps *caps, - const gl::Rectangle &viewport, + void setViewportState(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, @@ -85,7 +86,7 @@ class StateManager9 final : angle::NonCopyable void setSampleMask(unsigned int sampleMask); // Current raster state functions - void setCullMode(bool cullFace, GLenum cullMode, GLenum frontFace); + void setCullMode(bool cullFace, gl::CullFaceMode cullMode, GLenum frontFace); void setDepthBias(bool polygonOffsetFill, GLfloat polygonOffsetFactor, GLfloat polygonOffsetUnits); @@ -154,7 +155,9 @@ class StateManager9 final : angle::NonCopyable DIRTY_BIT_MAX }; - typedef std::bitset DirtyBits; + using DirtyBits = angle::BitSet; + + bool mUsingZeroColorMaskWorkaround; // Currently applied blend state gl::BlendState mCurBlendState; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp index be6a9c424c..bc81aa18ec 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.cpp @@ -7,25 +7,29 @@ // SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain. #include "libANGLE/renderer/d3d/d3d9/SwapChain9.h" -#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" + +#include "libANGLE/features.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" +#include "libANGLE/renderer/d3d/d3d9/NativeWindow9.h" #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" -#include "libANGLE/features.h" +#include "libANGLE/renderer/d3d/d3d9/renderer9_utils.h" namespace rx { SwapChain9::SwapChain9(Renderer9 *renderer, - NativeWindow nativeWindow, + NativeWindow9 *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, EGLint orientation) - : SwapChainD3D(nativeWindow, shareHandle, backBufferFormat, depthBufferFormat), + : SwapChainD3D(shareHandle, d3dTexture, backBufferFormat, depthBufferFormat), mRenderer(renderer), mWidth(-1), mHeight(-1), mSwapInterval(-1), + mNativeWindow(nativeWindow), mSwapChain(nullptr), mBackBuffer(nullptr), mRenderTarget(nullptr), @@ -50,9 +54,9 @@ void SwapChain9::release() SafeRelease(mRenderTarget); SafeRelease(mOffscreenTexture); - if (mNativeWindow.getNativeWindow()) + if (mNativeWindow->getNativeWindow()) { - mShareHandle = NULL; + mShareHandle = nullptr; } } @@ -75,17 +79,20 @@ static DWORD convertInterval(EGLint interval) #endif } -EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight) +EGLint SwapChain9::resize(const gl::Context *context, int backbufferWidth, int backbufferHeight) { // D3D9 does not support resizing swap chains without recreating them - return reset(backbufferWidth, backbufferHeight, mSwapInterval); + return reset(context, backbufferWidth, backbufferHeight, mSwapInterval); } -EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) +EGLint SwapChain9::reset(const gl::Context *context, + int backbufferWidth, + int backbufferHeight, + EGLint swapInterval) { IDirect3DDevice9 *device = mRenderer->getDevice(); - if (device == NULL) + if (device == nullptr) { return EGL_BAD_ACCESS; } @@ -103,28 +110,37 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI SafeRelease(mOffscreenTexture); SafeRelease(mDepthStencil); - HANDLE *pShareHandle = NULL; - if (!mNativeWindow.getNativeWindow() && mRenderer->getShareHandleSupport()) + const d3d9::TextureFormat &backBufferd3dFormatInfo = + d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); + if (mD3DTexture != nullptr) { - pShareHandle = &mShareHandle; + result = mD3DTexture->QueryInterface(&mOffscreenTexture); + ASSERT(SUCCEEDED(result)); } - - const d3d9::TextureFormat &backBufferd3dFormatInfo = d3d9::GetTextureFormatInfo(mOffscreenRenderTargetFormat); - result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, - backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, &mOffscreenTexture, - pShareHandle); - if (FAILED(result)) + else { - ERR("Could not create offscreen texture: %08lX", result); - release(); - - if (d3d9::isDeviceLostError(result)) + HANDLE *pShareHandle = nullptr; + if (!mNativeWindow->getNativeWindow() && mRenderer->getShareHandleSupport()) { - return EGL_CONTEXT_LOST; + pShareHandle = &mShareHandle; } - else + + result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, + backBufferd3dFormatInfo.texFormat, D3DPOOL_DEFAULT, + &mOffscreenTexture, pShareHandle); + if (FAILED(result)) { - return EGL_BAD_ALLOC; + ERR() << "Could not create offscreen texture, " << gl::FmtHR(result); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } } } @@ -163,7 +179,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI // Don't create a swapchain for NULLREF devices D3DDEVTYPE deviceType = mRenderer->getD3D9DeviceType(); - EGLNativeWindowType window = mNativeWindow.getNativeWindow(); + EGLNativeWindowType window = mNativeWindow->getNativeWindow(); if (window && deviceType != D3DDEVTYPE_NULLREF) { D3DPRESENT_PARAMETERS presentParameters = {0}; @@ -189,7 +205,7 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI // // Some non-switchable AMD GPUs / drivers do not respect the source rectangle to Present. Therefore, when the vendor ID // is not Intel, the back buffer width must be exactly the same width as the window or horizontal scaling will occur. - if (mRenderer->getVendorId() == VENDOR_ID_INTEL) + if (IsIntel(mRenderer->getVendorId())) { presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64; } @@ -200,7 +216,8 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL || result == D3DERR_DEVICELOST); - ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); + ERR() << "Could not create additional swap chains or offscreen surfaces, " + << gl::FmtHR(result); release(); if (d3d9::isDeviceLostError(result)) @@ -215,20 +232,21 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); ASSERT(SUCCEEDED(result)); - InvalidateRect(window, NULL, FALSE); + InvalidateRect(window, nullptr, FALSE); } if (mDepthBufferFormat != GL_NONE) { - result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, - depthBufferd3dFormatInfo.renderFormat, - D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); + result = device->CreateDepthStencilSurface( + backbufferWidth, backbufferHeight, depthBufferd3dFormatInfo.renderFormat, + D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_INVALIDCALL); - ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + ERR() << "Could not create depthstencil surface for new swap chain, " + << gl::FmtHR(result); release(); if (d3d9::isDeviceLostError(result)) @@ -250,7 +268,11 @@ EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapI } // parameters should be validated/clamped by caller -EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +EGLint SwapChain9::swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) { if (!mSwapChain) { @@ -270,11 +292,11 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - device->SetPixelShader(NULL); - device->SetVertexShader(NULL); + device->SetPixelShader(nullptr); + device->SetVertexShader(nullptr); device->SetRenderTarget(0, mBackBuffer); - device->SetDepthStencilSurface(NULL); + device->SetDepthStencilSurface(nullptr); device->SetTexture(0, mOffscreenTexture); device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); @@ -313,7 +335,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); mRenderer->endScene(); - device->SetTexture(0, NULL); + device->SetTexture(0, nullptr); RECT rect = { @@ -321,7 +343,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) static_cast(x + width), static_cast(mHeight - y) }; - HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); + HRESULT result = mSwapChain->Present(&rect, &rect, nullptr, nullptr, 0); mRenderer->markAllStateDirty(); @@ -333,7 +355,7 @@ EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) // On Windows 8 systems, IDirect3DSwapChain9::Present sometimes returns 0x88760873 when the windows is // in the process of entering/exiting fullscreen. This code doesn't seem to have any documentation. The // device appears to be ok after emitting this error so simply return a failure to swap. - if (result == 0x88760873) + if (result == static_cast(0x88760873)) { return EGL_BAD_MATCH; } @@ -395,6 +417,12 @@ void *SwapChain9::getKeyedMutex() return nullptr; } +egl::Error SwapChain9::getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) +{ + UNREACHABLE(); + return egl::EglBadSurface(); +} + void SwapChain9::recreate() { if (!mSwapChain) @@ -403,7 +431,7 @@ void SwapChain9::recreate() } IDirect3DDevice9 *device = mRenderer->getDevice(); - if (device == NULL) + if (device == nullptr) { return; } @@ -412,7 +440,7 @@ void SwapChain9::recreate() HRESULT result = mSwapChain->GetPresentParameters(&presentParameters); ASSERT(SUCCEEDED(result)); - IDirect3DSwapChain9* newSwapChain = NULL; + IDirect3DSwapChain9 *newSwapChain = nullptr; result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain); if (FAILED(result)) { @@ -427,4 +455,13 @@ void SwapChain9::recreate() ASSERT(SUCCEEDED(result)); } +RenderTargetD3D *SwapChain9::getColorRenderTarget() +{ + return &mColorRenderTarget; +} + +RenderTargetD3D *SwapChain9::getDepthStencilRenderTarget() +{ + return &mDepthStencilRenderTarget; +} } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h index 55a700c2d6..5753637c47 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/SwapChain9.h @@ -15,26 +15,36 @@ namespace rx { +class NativeWindow9; class Renderer9; class SwapChain9 : public SwapChainD3D { public: SwapChain9(Renderer9 *renderer, - NativeWindow nativeWindow, + NativeWindow9 *nativeWindow, HANDLE shareHandle, + IUnknown *d3dTexture, GLenum backBufferFormat, GLenum depthBufferFormat, EGLint orientation); - virtual ~SwapChain9(); + ~SwapChain9() override; - EGLint resize(EGLint backbufferWidth, EGLint backbufferHeight); - virtual EGLint reset(EGLint backbufferWidth, EGLint backbufferHeight, EGLint swapInterval); - virtual EGLint swapRect(EGLint x, EGLint y, EGLint width, EGLint height); - virtual void recreate(); + EGLint resize(const gl::Context *context, EGLint backbufferWidth, EGLint backbufferHeight) + override; + EGLint reset(const gl::Context *context, + EGLint backbufferWidth, + EGLint backbufferHeight, + EGLint swapInterval) override; + EGLint swapRect(const gl::Context *context, + EGLint x, + EGLint y, + EGLint width, + EGLint height) override; + void recreate() override; - RenderTargetD3D *getColorRenderTarget() override { return &mColorRenderTarget; } - RenderTargetD3D *getDepthStencilRenderTarget() override { return &mDepthStencilRenderTarget; } + RenderTargetD3D *getColorRenderTarget() override; + RenderTargetD3D *getDepthStencilRenderTarget() override; virtual IDirect3DSurface9 *getRenderTarget(); virtual IDirect3DSurface9 *getDepthStencil(); @@ -45,6 +55,8 @@ class SwapChain9 : public SwapChainD3D void *getKeyedMutex() override; + egl::Error getSyncValues(EGLuint64KHR *ust, EGLuint64KHR *msc, EGLuint64KHR *sbc) override; + private: void release(); @@ -53,6 +65,8 @@ class SwapChain9 : public SwapChainD3D EGLint mHeight; EGLint mSwapInterval; + NativeWindow9 *mNativeWindow; + IDirect3DSwapChain9 *mSwapChain; IDirect3DSurface9 *mBackBuffer; IDirect3DSurface9 *mRenderTarget; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp index b28d5076b5..6404af6bba 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.cpp @@ -43,7 +43,7 @@ DWORD TextureStorage9::GetTextureUsage(GLenum internalformat, bool renderTarget) { DWORD d3dusage = 0; - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalformat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalformat); const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalformat); if (formatInfo.depthBits > 0 || formatInfo.stencilBits > 0) { @@ -93,11 +93,16 @@ int TextureStorage9::getLevelCount() const return static_cast(mMipLevels) - mTopLevel; } -gl::Error TextureStorage9::setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData) +gl::Error TextureStorage9::setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain) @@ -107,7 +112,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai mTexture = surfaceTexture; mMipLevels = surfaceTexture->GetLevelCount(); - mInternalFormat = swapchain->GetRenderTargetInternalFormat(); + mInternalFormat = swapchain->getRenderTargetInternalFormat(); D3DSURFACE_DESC surfaceDesc; surfaceTexture->GetLevelDesc(0, &surfaceDesc); @@ -121,7 +126,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchai TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { - mTexture = NULL; + mTexture = nullptr; mInternalFormat = internalformat; @@ -139,7 +144,7 @@ TextureStorage9_2D::TextureStorage9_2D(Renderer9 *renderer, GLenum internalforma TextureStorage9_2D::~TextureStorage9_2D() { SafeRelease(mTexture); - for (auto &renderTarget : mRenderTargets) + for (RenderTargetD3D *renderTarget : mRenderTargets) { SafeDelete(renderTarget); } @@ -147,16 +152,16 @@ TextureStorage9_2D::~TextureStorage9_2D() // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, +gl::Error TextureStorage9_2D::getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) { ASSERT(target == GL_TEXTURE_2D); - UNUSED_ASSERTION_VARIABLE(target); - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; @@ -169,33 +174,36 @@ gl::Error TextureStorage9_2D::getSurfaceLevel(GLenum target, ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get the surface from a texture, " + << gl::FmtHR(result); } // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level + mTopLevel != 0 && isManaged() && dirty) { - texture->AddDirtyRect(NULL); + texture->AddDirtyRect(nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage9_2D::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(index.mipIndex < getLevelCount()); if (!mRenderTargets[index.mipIndex] && isRenderTarget()) { - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; } - IDirect3DSurface9 *surface = NULL; - error = getSurfaceLevel(GL_TEXTURE_2D, index.mipIndex, false, &surface); + IDirect3DSurface9 *surface = nullptr; + error = getSurfaceLevel(context, GL_TEXTURE_2D, index.mipIndex, false, &surface); if (error.isError()) { return error; @@ -213,20 +221,22 @@ gl::Error TextureStorage9_2D::getRenderTarget(const gl::ImageIndex &index, Rende ASSERT(outRT); *outRT = mRenderTargets[index.mipIndex]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +gl::Error TextureStorage9_2D::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) { - IDirect3DSurface9 *upper = NULL; - gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper); + IDirect3DSurface9 *upper = nullptr; + gl::Error error = getSurfaceLevel(context, GL_TEXTURE_2D, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } - IDirect3DSurface9 *lower = NULL; - error = getSurfaceLevel(GL_TEXTURE_2D, destIndex.mipIndex, true, &lower); + IDirect3DSurface9 *lower = nullptr; + error = getSurfaceLevel(context, GL_TEXTURE_2D, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -242,32 +252,34 @@ gl::Error TextureStorage9_2D::generateMipmap(const gl::ImageIndex &sourceIndex, return error; } -gl::Error TextureStorage9_2D::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +gl::Error TextureStorage9_2D::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) { // if the width or height is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture(static_cast(mTextureWidth), + HRESULT result = device->CreateTexture(static_cast(mTextureWidth), static_cast(mTextureHeight), static_cast(mMipLevels), getUsage(), - mTextureFormat, getPool(), &mTexture, NULL); + mTextureFormat, getPool(), &mTexture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create 2D storage texture, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to create 2D storage texture, " << gl::FmtHR(result); } } *outTexture = mTexture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage9_2D::copyToStorage(const gl::Context *context, TextureStorage *destStorage) { ASSERT(destStorage); @@ -276,15 +288,15 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) int levels = getLevelCount(); for (int i = 0; i < levels; ++i) { - IDirect3DSurface9 *srcSurf = NULL; - gl::Error error = getSurfaceLevel(GL_TEXTURE_2D, i, false, &srcSurf); + IDirect3DSurface9 *srcSurf = nullptr; + gl::Error error = getSurfaceLevel(context, GL_TEXTURE_2D, i, false, &srcSurf); if (error.isError()) { return error; } - IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getSurfaceLevel(GL_TEXTURE_2D, i, true, &dstSurf); + IDirect3DSurface9 *dstSurf = nullptr; + error = dest9->getSurfaceLevel(context, GL_TEXTURE_2D, i, true, &dstSurf); if (error.isError()) { SafeRelease(srcSurf); @@ -302,17 +314,14 @@ gl::Error TextureStorage9_2D::copyToStorage(TextureStorage *destStorage) } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image) +TextureStorage9_EGLImage::TextureStorage9_EGLImage(Renderer9 *renderer, + EGLImageD3D *image, + RenderTarget9 *renderTarget9) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET), mImage(image) { - RenderTargetD3D *renderTargetD3D = nullptr; - mImage->getRenderTarget(&renderTargetD3D); - - RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); - mInternalFormat = renderTarget9->getInternalFormat(); mTextureFormat = renderTarget9->getD3DFormat(); mTextureWidth = renderTarget9->getWidth(); @@ -325,18 +334,17 @@ TextureStorage9_EGLImage::~TextureStorage9_EGLImage() { } -gl::Error TextureStorage9_EGLImage::getSurfaceLevel(GLenum target, +gl::Error TextureStorage9_EGLImage::getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool, IDirect3DSurface9 **outSurface) { ASSERT(target == GL_TEXTURE_2D); ASSERT(level == 0); - UNUSED_ASSERTION_VARIABLE(target); - UNUSED_ASSERTION_VARIABLE(level); RenderTargetD3D *renderTargetD3D = nullptr; - gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + gl::Error error = mImage->getRenderTarget(context, &renderTargetD3D); if (error.isError()) { return error; @@ -345,23 +353,24 @@ gl::Error TextureStorage9_EGLImage::getSurfaceLevel(GLenum target, RenderTarget9 *renderTarget9 = GetAs(renderTargetD3D); *outSurface = renderTarget9->getSurface(); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_EGLImage::getRenderTarget(const gl::ImageIndex &index, +gl::Error TextureStorage9_EGLImage::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, RenderTargetD3D **outRT) { ASSERT(!index.hasLayer()); ASSERT(index.mipIndex == 0); - UNUSED_ASSERTION_VARIABLE(index); - return mImage->getRenderTarget(outRT); + return mImage->getRenderTarget(context, outRT); } -gl::Error TextureStorage9_EGLImage::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +gl::Error TextureStorage9_EGLImage::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) { RenderTargetD3D *renderTargetD3D = nullptr; - gl::Error error = mImage->getRenderTarget(&renderTargetD3D); + gl::Error error = mImage->getRenderTarget(context, &renderTargetD3D); if (error.isError()) { return error; @@ -371,16 +380,19 @@ gl::Error TextureStorage9_EGLImage::getBaseTexture(IDirect3DBaseTexture9 **outTe *outTexture = renderTarget9->getTexture(); ASSERT(*outTexture != nullptr); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_EGLImage::generateMipmap(const gl::ImageIndex &, const gl::ImageIndex &) +gl::Error TextureStorage9_EGLImage::generateMipmap(const gl::Context *context, + const gl::ImageIndex &, + const gl::ImageIndex &) { UNREACHABLE(); - return gl::Error(GL_INVALID_OPERATION); + return gl::InternalError(); } -gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage9_EGLImage::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { ASSERT(destStorage); ASSERT(getLevelCount() == 1); @@ -388,7 +400,7 @@ gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) TextureStorage9 *dest9 = GetAs(destStorage); IDirect3DBaseTexture9 *destBaseTexture9 = nullptr; - gl::Error error = dest9->getBaseTexture(&destBaseTexture9); + gl::Error error = dest9->getBaseTexture(context, &destBaseTexture9); if (error.isError()) { return error; @@ -400,12 +412,12 @@ gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) HRESULT result = destTexture9->GetSurfaceLevel(destStorage->getTopLevel(), &destSurface); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, - "Failed to get the surface from a texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get the surface from a texture, " + << gl::FmtHR(result); } RenderTargetD3D *sourceRenderTarget = nullptr; - error = mImage->getRenderTarget(&sourceRenderTarget); + error = mImage->getRenderTarget(context, &sourceRenderTarget); if (error.isError()) { SafeRelease(destSurface); @@ -427,16 +439,16 @@ gl::Error TextureStorage9_EGLImage::copyToStorage(TextureStorage *destStorage) } SafeRelease(destSurface); - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } TextureStorage9_Cube::TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly) : TextureStorage9(renderer, GetTextureUsage(internalformat, renderTarget)) { - mTexture = NULL; - for (int i = 0; i < CUBE_FACE_COUNT; ++i) + mTexture = nullptr; + for (size_t i = 0; i < gl::CUBE_FACE_COUNT; ++i) { - mRenderTarget[i] = NULL; + mRenderTarget[i] = nullptr; } mInternalFormat = internalformat; @@ -455,7 +467,7 @@ TextureStorage9_Cube::~TextureStorage9_Cube() { SafeRelease(mTexture); - for (int i = 0; i < CUBE_FACE_COUNT; ++i) + for (size_t i = 0; i < gl::CUBE_FACE_COUNT; ++i) { SafeDelete(mRenderTarget[i]); } @@ -463,13 +475,14 @@ TextureStorage9_Cube::~TextureStorage9_Cube() // Increments refcount on surface. // caller must Release() the returned surface -gl::Error TextureStorage9_Cube::getSurfaceLevel(GLenum target, +gl::Error TextureStorage9_Cube::getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) { - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; @@ -483,35 +496,38 @@ gl::Error TextureStorage9_Cube::getSurfaceLevel(GLenum target, ASSERT(SUCCEEDED(result)); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to get the surface from a texture, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to get the surface from a texture, " + << gl::FmtHR(result); } // With managed textures the driver needs to be informed of updates to the lower mipmap levels if (level != 0 && isManaged() && dirty) { - texture->AddDirtyRect(face, NULL); + texture->AddDirtyRect(face, nullptr); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) +gl::Error TextureStorage9_Cube::getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) { ASSERT(outRT); ASSERT(index.mipIndex == 0); - ASSERT(index.layerIndex >= 0 && index.layerIndex < CUBE_FACE_COUNT); + ASSERT(index.layerIndex >= 0 && static_cast(index.layerIndex) < gl::CUBE_FACE_COUNT); - if (mRenderTarget[index.layerIndex] == NULL && isRenderTarget()) + if (mRenderTarget[index.layerIndex] == nullptr && isRenderTarget()) { - IDirect3DBaseTexture9 *baseTexture = NULL; - gl::Error error = getBaseTexture(&baseTexture); + IDirect3DBaseTexture9 *baseTexture = nullptr; + gl::Error error = getBaseTexture(context, &baseTexture); if (error.isError()) { return error; } - IDirect3DSurface9 *surface = NULL; - error = getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, + IDirect3DSurface9 *surface = nullptr; + error = getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + index.layerIndex, mTopLevel + index.mipIndex, false, &surface); if (error.isError()) { @@ -525,20 +541,23 @@ gl::Error TextureStorage9_Cube::getRenderTarget(const gl::ImageIndex &index, Ren } *outRT = mRenderTarget[index.layerIndex]; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) +gl::Error TextureStorage9_Cube::generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) { - IDirect3DSurface9 *upper = NULL; - gl::Error error = getSurfaceLevel(sourceIndex.type, sourceIndex.mipIndex, false, &upper); + IDirect3DSurface9 *upper = nullptr; + gl::Error error = + getSurfaceLevel(context, sourceIndex.type, sourceIndex.mipIndex, false, &upper); if (error.isError()) { return error; } - IDirect3DSurface9 *lower = NULL; - error = getSurfaceLevel(destIndex.type, destIndex.mipIndex, true, &lower); + IDirect3DSurface9 *lower = nullptr; + error = getSurfaceLevel(context, destIndex.type, destIndex.mipIndex, true, &lower); if (error.isError()) { SafeRelease(upper); @@ -554,52 +573,56 @@ gl::Error TextureStorage9_Cube::generateMipmap(const gl::ImageIndex &sourceIndex return error; } -gl::Error TextureStorage9_Cube::getBaseTexture(IDirect3DBaseTexture9 **outTexture) +gl::Error TextureStorage9_Cube::getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) { // if the size is not positive this should be treated as an incomplete texture // we handle that here by skipping the d3d texture creation - if (mTexture == NULL && mTextureWidth > 0 && mTextureHeight > 0) + if (mTexture == nullptr && mTextureWidth > 0 && mTextureHeight > 0) { ASSERT(mMipLevels > 0); ASSERT(mTextureWidth == mTextureHeight); IDirect3DDevice9 *device = mRenderer->getDevice(); - HRESULT result = device->CreateCubeTexture( + HRESULT result = device->CreateCubeTexture( static_cast(mTextureWidth), static_cast(mMipLevels), - getUsage(), mTextureFormat, getPool(), &mTexture, NULL); + getUsage(), mTextureFormat, getPool(), &mTexture, nullptr); if (FAILED(result)) { ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create cube storage texture, result: 0x%X.", result); + return gl::OutOfMemory() + << "Failed to create cube storage texture, " << gl::FmtHR(result); } } *outTexture = mTexture; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } -gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) +gl::Error TextureStorage9_Cube::copyToStorage(const gl::Context *context, + TextureStorage *destStorage) { ASSERT(destStorage); TextureStorage9_Cube *dest9 = GetAs(destStorage); int levels = getLevelCount(); - for (int f = 0; f < CUBE_FACE_COUNT; f++) + for (int f = 0; f < static_cast(gl::CUBE_FACE_COUNT); f++) { for (int i = 0; i < levels; i++) { - IDirect3DSurface9 *srcSurf = NULL; + IDirect3DSurface9 *srcSurf = nullptr; gl::Error error = - getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); + getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false, &srcSurf); if (error.isError()) { return error; } - IDirect3DSurface9 *dstSurf = NULL; - error = dest9->getSurfaceLevel(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, &dstSurf); + IDirect3DSurface9 *dstSurf = nullptr; + error = dest9->getSurfaceLevel(context, GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true, + &dstSurf); if (error.isError()) { SafeRelease(srcSurf); @@ -618,7 +641,7 @@ gl::Error TextureStorage9_Cube::copyToStorage(TextureStorage *destStorage) } } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h index 50e63a6f14..2f51901931 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/TextureStorage9.h @@ -25,28 +25,34 @@ class RenderTarget9; class TextureStorage9 : public TextureStorage { public: - virtual ~TextureStorage9(); + ~TextureStorage9() override; static DWORD GetTextureUsage(GLenum internalformat, bool renderTarget); D3DPOOL getPool() const; DWORD getUsage() const; - virtual gl::Error getSurfaceLevel(GLenum target, + virtual gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) = 0; - virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) = 0; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) = 0; + virtual gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) = 0; - virtual int getTopLevel() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; + int getTopLevel() const override; + bool isRenderTarget() const override; + bool isManaged() const override; bool supportsNativeMipmapFunction() const override; - virtual int getLevelCount() const; + int getLevelCount() const override; - virtual gl::Error setData(const gl::ImageIndex &index, ImageD3D *image, const gl::Box *destBox, GLenum type, - const gl::PixelUnpackState &unpack, const uint8_t *pixelData); + gl::Error setData(const gl::Context *context, + const gl::ImageIndex &index, + ImageD3D *image, + const gl::Box *destBox, + GLenum type, + const gl::PixelUnpackState &unpack, + const uint8_t *pixelData) override; protected: int mTopLevel; @@ -70,16 +76,22 @@ class TextureStorage9_2D : public TextureStorage9 public: TextureStorage9_2D(Renderer9 *renderer, SwapChain9 *swapchain); TextureStorage9_2D(Renderer9 *renderer, GLenum internalformat, bool renderTarget, GLsizei width, GLsizei height, int levels); - virtual ~TextureStorage9_2D(); + ~TextureStorage9_2D() override; - gl::Error getSurfaceLevel(GLenum target, + gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); - virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; private: IDirect3DTexture9 *mTexture; @@ -89,18 +101,23 @@ class TextureStorage9_2D : public TextureStorage9 class TextureStorage9_EGLImage final : public TextureStorage9 { public: - TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image); + TextureStorage9_EGLImage(Renderer9 *renderer, EGLImageD3D *image, RenderTarget9 *renderTarget9); ~TextureStorage9_EGLImage() override; - gl::Error getSurfaceLevel(GLenum target, + gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) override; - gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT) override; - gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture) override; - gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex) override; - gl::Error copyToStorage(TextureStorage *destStorage) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; private: EGLImageD3D *mImage; @@ -110,25 +127,28 @@ class TextureStorage9_Cube : public TextureStorage9 { public: TextureStorage9_Cube(Renderer9 *renderer, GLenum internalformat, bool renderTarget, int size, int levels, bool hintLevelZeroOnly); - virtual ~TextureStorage9_Cube(); + ~TextureStorage9_Cube() override; - gl::Error getSurfaceLevel(GLenum target, + gl::Error getSurfaceLevel(const gl::Context *context, + GLenum target, int level, bool dirty, IDirect3DSurface9 **outSurface) override; - virtual gl::Error getRenderTarget(const gl::ImageIndex &index, RenderTargetD3D **outRT); - virtual gl::Error getBaseTexture(IDirect3DBaseTexture9 **outTexture); - virtual gl::Error generateMipmap(const gl::ImageIndex &sourceIndex, const gl::ImageIndex &destIndex); - virtual gl::Error copyToStorage(TextureStorage *destStorage); + gl::Error getRenderTarget(const gl::Context *context, + const gl::ImageIndex &index, + RenderTargetD3D **outRT) override; + gl::Error getBaseTexture(const gl::Context *context, + IDirect3DBaseTexture9 **outTexture) override; + gl::Error generateMipmap(const gl::Context *context, + const gl::ImageIndex &sourceIndex, + const gl::ImageIndex &destIndex) override; + gl::Error copyToStorage(const gl::Context *context, TextureStorage *destStorage) override; private: - static const size_t CUBE_FACE_COUNT = 6; - IDirect3DCubeTexture9 *mTexture; - RenderTarget9 *mRenderTarget[CUBE_FACE_COUNT]; + RenderTarget9 *mRenderTarget[gl::CUBE_FACE_COUNT]; }; } #endif // LIBANGLE_RENDERER_D3D_D3D9_TEXTURESTORAGE9_H_ - diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h index 992201737f..0f4410b8de 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexArray9.h @@ -9,7 +9,9 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ #define LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ +#include "libANGLE/Context.h" #include "libANGLE/renderer/VertexArrayImpl.h" +#include "libANGLE/renderer/d3d/d3d9/Context9.h" #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" namespace rx @@ -19,14 +21,26 @@ class Renderer9; class VertexArray9 : public VertexArrayImpl { public: - VertexArray9(const gl::VertexArray::Data &data) - : VertexArrayImpl(data) - { - } + VertexArray9(const gl::VertexArrayState &data) : VertexArrayImpl(data) {} - virtual ~VertexArray9() { } + void syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits) override; + + ~VertexArray9() override {} + + Serial getCurrentStateSerial() const { return mCurrentStateSerial; } + + private: + Serial mCurrentStateSerial; }; +inline void VertexArray9::syncState(const gl::Context *context, + const gl::VertexArray::DirtyBits &dirtyBits) +{ + ASSERT(dirtyBits.any()); + Renderer9 *renderer = GetImplAs(context)->getRenderer(); + mCurrentStateSerial = renderer->generateSerial(); +} } #endif // LIBANGLE_RENDERER_D3D_D3D9_VERTEXARRAY9_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp index bfdf137126..c0b80a847c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.cpp @@ -19,7 +19,7 @@ namespace rx VertexBuffer9::VertexBuffer9(Renderer9 *renderer) : mRenderer(renderer) { - mVertexBuffer = NULL; + mVertexBuffer = nullptr; mBufferSize = 0; mDynamicUsage = false; } @@ -47,16 +47,18 @@ gl::Error VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to allocate internal vertex buffer of size, %lu.", size); + return gl::OutOfMemory() + << "Failed to allocate internal vertex buffer of size " << size; } } mBufferSize = size; mDynamicUsage = dynamicUsage; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, @@ -66,32 +68,33 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib { if (!mVertexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + return gl::OutOfMemory() << "Internal vertex buffer is not initialized."; } - int inputStride = static_cast(gl::ComputeVertexAttributeStride(attrib)); + int inputStride = static_cast(gl::ComputeVertexAttributeStride(attrib, binding)); int elementSize = static_cast(gl::ComputeVertexAttributeTypeSize(attrib)); DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - uint8_t *mapPtr = NULL; + uint8_t *mapPtr = nullptr; - unsigned int mapSize; - gl::Error error = spaceRequired(attrib, count, instances, &mapSize); - if (error.isError()) + auto errorOrMapSize = mRenderer->getVertexSpaceRequired(attrib, binding, count, instances); + if (errorOrMapSize.isError()) { - return error; + return errorOrMapSize.getError(); } + unsigned int mapSize = errorOrMapSize.getResult(); + HRESULT result = mVertexBuffer->Lock(offset, mapSize, reinterpret_cast(&mapPtr), lockFlags); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal vertex buffer, HRESULT: 0x%08x.", result); + return gl::OutOfMemory() << "Failed to lock internal vertex buffer, " << gl::FmtHR(result); } const uint8_t *input = sourceData; - if (instances == 0 || attrib.divisor == 0) + if (instances == 0 || binding.getDivisor() == 0) { input += inputStride * start; } @@ -112,13 +115,7 @@ gl::Error VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib mVertexBuffer->Unlock(); - return gl::Error(GL_NO_ERROR); -} - -gl::Error VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - return spaceRequired(attrib, count, instances, outSpaceRequired); + return gl::NoError(); } unsigned int VertexBuffer9::getBufferSize() const @@ -134,7 +131,7 @@ gl::Error VertexBuffer9::setBufferSize(unsigned int size) } else { - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -142,7 +139,7 @@ gl::Error VertexBuffer9::discard() { if (!mVertexBuffer) { - return gl::Error(GL_OUT_OF_MEMORY, "Internal vertex buffer is not initialized."); + return gl::OutOfMemory() << "Internal vertex buffer is not initialized."; } void *dummy; @@ -151,65 +148,22 @@ gl::Error VertexBuffer9::discard() result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to lock internal buffer for discarding, HRESULT: 0x%08x", result); + return gl::OutOfMemory() << "Failed to lock internal buffer for discarding, " + << gl::FmtHR(result); } result = mVertexBuffer->Unlock(); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to unlock internal buffer for discarding, HRESULT: 0x%08x", result); + return gl::OutOfMemory() << "Failed to unlock internal buffer for discarding, " + << gl::FmtHR(result); } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const { return mVertexBuffer; } - -gl::Error VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - gl::VertexFormatType vertexFormatType = gl::GetVertexFormatType(attrib, GL_FLOAT); - const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(mRenderer->getCapsDeclTypes(), vertexFormatType); - - if (attrib.enabled) - { - unsigned int elementCount = 0; - if (instances == 0 || attrib.divisor == 0) - { - elementCount = static_cast(count); - } - else - { - // Round up to divisor, if possible - elementCount = UnsignedCeilDivide(static_cast(instances), attrib.divisor); - } - - if (d3d9VertexInfo.outputElementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = - static_cast(d3d9VertexInfo.outputElementSize) * elementCount; - } - return gl::Error(GL_NO_ERROR); - } - else - { - return gl::Error(GL_OUT_OF_MEMORY, "New vertex buffer size would result in an overflow."); - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return gl::Error(GL_NO_ERROR); - } -} - -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h index 64271cbe2a..983616f4e4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexBuffer9.h @@ -19,11 +19,13 @@ class VertexBuffer9 : public VertexBuffer { public: explicit VertexBuffer9(Renderer9 *renderer); - virtual ~VertexBuffer9(); - virtual gl::Error initialize(unsigned int size, bool dynamicUsage); + gl::Error initialize(unsigned int size, bool dynamicUsage) override; + // Warning: you should ensure binding really matches attrib.bindingIndex before using this + // function. gl::Error storeVertexAttributes(const gl::VertexAttribute &attrib, + const gl::VertexBinding &binding, GLenum currentValueType, GLint start, GLsizei count, @@ -31,23 +33,19 @@ class VertexBuffer9 : public VertexBuffer unsigned int offset, const uint8_t *sourceData) override; - virtual gl::Error getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; - - virtual unsigned int getBufferSize() const; - virtual gl::Error setBufferSize(unsigned int size); - virtual gl::Error discard(); + unsigned int getBufferSize() const override; + gl::Error setBufferSize(unsigned int size) override; + gl::Error discard() override; IDirect3DVertexBuffer9 *getBuffer() const; private: + ~VertexBuffer9() override; Renderer9 *mRenderer; IDirect3DVertexBuffer9 *mVertexBuffer; unsigned int mBufferSize; bool mDynamicUsage; - - gl::Error spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) const; }; } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp index a23ab4a290..abadf5c0b5 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.cpp @@ -21,7 +21,7 @@ VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) { for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) { - mVertexDeclCache[i].vertexDeclaration = NULL; + mVertexDeclCache[i].vertexDeclaration = nullptr; mVertexDeclCache[i].lruCount = 0; } @@ -30,7 +30,7 @@ VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) mAppliedVBs[i].serial = 0; } - mLastSetVDecl = NULL; + mLastSetVDecl = nullptr; mInstancingEnabled = true; } @@ -42,11 +42,13 @@ VertexDeclarationCache::~VertexDeclarationCache() } } -gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, - const std::vector &attributes, - gl::Program *program, - GLsizei instances, - GLsizei *repeatDraw) +gl::Error VertexDeclarationCache::applyDeclaration( + IDirect3DDevice9 *device, + const std::vector &attributes, + gl::Program *program, + GLint start, + GLsizei instances, + GLsizei *repeatDraw) { ASSERT(gl::MAX_VERTEX_ATTRIBS >= attributes.size()); @@ -102,14 +104,14 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, D3DVERTEXELEMENT9 *element = &elements[0]; ProgramD3D *programD3D = GetImplAs(program); - const auto &semanticIndexes = programD3D->getSemanticIndexes(); + const auto &semanticIndexes = programD3D->getAttribLocationToD3DSemantics(); for (size_t i = 0; i < attributes.size(); i++) { if (attributes[i].active) { // Directly binding the storage buffer is not supported for d3d9 - ASSERT(attributes[i].storage == NULL); + ASSERT(attributes[i].storage == nullptr); int stream = static_cast(i); @@ -147,19 +149,24 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, } } - VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer); + VertexBuffer9 *vertexBuffer = GetAs(attributes[i].vertexBuffer.get()); + + unsigned int offset = 0; + ANGLE_TRY_RESULT(attributes[i].computeOffset(start), offset); if (mAppliedVBs[stream].serial != attributes[i].serial || mAppliedVBs[stream].stride != attributes[i].stride || - mAppliedVBs[stream].offset != attributes[i].offset) + mAppliedVBs[stream].offset != offset) { - device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride); + device->SetStreamSource(stream, vertexBuffer->getBuffer(), offset, + attributes[i].stride); mAppliedVBs[stream].serial = attributes[i].serial; mAppliedVBs[stream].stride = attributes[i].stride; - mAppliedVBs[stream].offset = attributes[i].offset; + mAppliedVBs[stream].offset = offset; } - gl::VertexFormatType vertexformatType = gl::GetVertexFormatType(*attributes[i].attribute, GL_FLOAT); + gl::VertexFormatType vertexformatType = + gl::GetVertexFormatType(*attributes[i].attribute, GL_FLOAT); const d3d9::VertexFormat &d3d9VertexInfo = d3d9::GetVertexFormatInfo(caps.DeclTypes, vertexformatType); element->Stream = static_cast(stream); @@ -200,7 +207,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, mLastSetVDecl = entry->vertexDeclaration; } - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } } @@ -214,7 +221,7 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, } } - if (lastCache->vertexDeclaration != NULL) + if (lastCache->vertexDeclaration != nullptr) { SafeRelease(lastCache->vertexDeclaration); // mLastSetVDecl is set to the replacement, so we don't have to worry @@ -225,14 +232,15 @@ gl::Error VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, HRESULT result = device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); if (FAILED(result)) { - return gl::Error(GL_OUT_OF_MEMORY, "Failed to create internal vertex declaration, result: 0x%X.", result); + return gl::OutOfMemory() << "Failed to create internal vertex declaration, " + << gl::FmtHR(result); } device->SetVertexDeclaration(lastCache->vertexDeclaration); mLastSetVDecl = lastCache->vertexDeclaration; lastCache->lruCount = ++mMaxLru; - return gl::Error(GL_NO_ERROR); + return gl::NoError(); } void VertexDeclarationCache::markStateDirty() @@ -242,7 +250,7 @@ void VertexDeclarationCache::markStateDirty() mAppliedVBs[i].serial = 0; } - mLastSetVDecl = NULL; + mLastSetVDecl = nullptr; mInstancingEnabled = true; // Forces it to be disabled when not used } diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h index bad4de4d6b..7bd7cabae4 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/VertexDeclarationCache.h @@ -30,6 +30,7 @@ class VertexDeclarationCache gl::Error applyDeclaration(IDirect3DDevice9 *device, const std::vector &attributes, gl::Program *program, + GLint start, GLsizei instances, GLsizei *repeatDraw); diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp index b672a60e3c..d10fa1ee87 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.cpp @@ -7,12 +7,16 @@ // formatutils9.cpp: Queries for GL image formats and their translations to D3D9 // formats. -#include "libANGLE/renderer/d3d/copyimage.h" #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" + +#include "image_util/copyimage.h" +#include "image_util/generatemip.h" +#include "image_util/loadimage.h" + #include "libANGLE/renderer/d3d/d3d9/Renderer9.h" #include "libANGLE/renderer/d3d/d3d9/vertexconversion.h" -#include "libANGLE/renderer/d3d/generatemip.h" -#include "libANGLE/renderer/d3d/loadimage.h" + +using namespace angle; namespace rx { @@ -20,35 +24,8 @@ namespace rx namespace d3d9 { -const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); -const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); - -struct D3D9FastCopyFormat -{ - GLenum destFormat; - GLenum destType; - ColorCopyFunction copyFunction; - - D3D9FastCopyFormat(GLenum destFormat, GLenum destType, ColorCopyFunction copyFunction) - : destFormat(destFormat), destType(destType), copyFunction(copyFunction) - { } - - bool operator<(const D3D9FastCopyFormat& other) const - { - return memcmp(this, &other, sizeof(D3D9FastCopyFormat)) < 0; - } -}; - -typedef std::multimap D3D9FastCopyMap; - -static D3D9FastCopyMap BuildFastCopyMap() -{ - D3D9FastCopyMap map; - - map.insert(std::make_pair(D3DFMT_A8R8G8B8, D3D9FastCopyFormat(GL_RGBA, GL_UNSIGNED_BYTE, CopyBGRA8ToRGBA8))); - - return map; -} +constexpr D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I', 'N', 'T', 'Z'))); +constexpr D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N', 'U', 'L', 'L'))); // A map to determine the pixel size and mip generation function of a given D3D format typedef std::map D3D9FormatInfoMap; @@ -64,109 +41,188 @@ D3DFormat::D3DFormat() luminanceBits(0), depthBits(0), stencilBits(0), - internalFormat(GL_NONE), - mipGenerationFunction(NULL), - colorReadFunction(NULL), - fastCopyFunctions() + formatID(angle::Format::ID::NONE) { } -ColorCopyFunction D3DFormat::getFastCopyFunction(GLenum format, GLenum type) const +D3DFormat::D3DFormat(GLuint bits, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint lumBits, + GLuint depthBits, + GLuint stencilBits, + Format::ID formatID) + : pixelBytes(bits / 8), + blockWidth(blockWidth), + blockHeight(blockHeight), + redBits(redBits), + greenBits(greenBits), + blueBits(blueBits), + alphaBits(alphaBits), + luminanceBits(lumBits), + depthBits(depthBits), + stencilBits(stencilBits), + formatID(formatID) { - FastCopyFunctionMap::const_iterator iter = fastCopyFunctions.find(std::make_pair(format, type)); - return (iter != fastCopyFunctions.end()) ? iter->second : NULL; } -static inline void InsertD3DFormatInfo(D3D9FormatInfoMap *map, D3DFORMAT format, GLuint bits, GLuint blockWidth, - GLuint blockHeight, GLuint redBits, GLuint greenBits, GLuint blueBits, - GLuint alphaBits, GLuint lumBits, GLuint depthBits, GLuint stencilBits, - GLenum internalFormat, MipGenerationFunction mipFunc, - ColorReadFunction colorReadFunc) +const D3DFormat &GetD3DFormatInfo(D3DFORMAT format) { - D3DFormat info; - info.pixelBytes = bits / 8; - info.blockWidth = blockWidth; - info.blockHeight = blockHeight; - info.redBits = redBits; - info.greenBits = greenBits; - info.blueBits = blueBits; - info.alphaBits = alphaBits; - info.luminanceBits = lumBits; - info.depthBits = depthBits; - info.stencilBits = stencilBits; - info.internalFormat = internalFormat; - info.mipGenerationFunction = mipFunc; - info.colorReadFunction = colorReadFunc; - - static const D3D9FastCopyMap fastCopyMap = BuildFastCopyMap(); - std::pair fastCopyIter = fastCopyMap.equal_range(format); - for (D3D9FastCopyMap::const_iterator i = fastCopyIter.first; i != fastCopyIter.second; i++) + if (format == D3DFMT_NULL) { - info.fastCopyFunctions.insert(std::make_pair(std::make_pair(i->second.destFormat, i->second.destType), i->second.copyFunction)); + static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE); + return info; } - map->insert(std::make_pair(format, info)); -} - -static D3D9FormatInfoMap BuildD3D9FormatInfoMap() -{ - D3D9FormatInfoMap map; - - // | D3DFORMAT | S |W |H | R | G | B | A | L | D | S | Internal format | Mip generation function | Color read function | - InsertD3DFormatInfo(&map, D3DFMT_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_UNKNOWN, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, GL_NONE, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_L8, 8, 1, 1, 0, 0, 0, 0, 8, 0, 0, GL_LUMINANCE8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A8, 8, 1, 1, 0, 0, 0, 8, 0, 0, 0, GL_ALPHA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A8L8, 16, 1, 1, 0, 0, 0, 8, 8, 0, 0, GL_LUMINANCE8_ALPHA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A4R4G4B4, 16, 1, 1, 4, 4, 4, 4, 0, 0, 0, GL_BGRA4_ANGLEX, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A1R5G5B5, 16, 1, 1, 5, 5, 5, 1, 0, 0, 0, GL_BGR5_A1_ANGLEX, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_R5G6B5, 16, 1, 1, 5, 6, 5, 0, 0, 0, 0, GL_RGB565, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_X8R8G8B8, 32, 1, 1, 8, 8, 8, 0, 0, 0, 0, GL_BGRA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A8R8G8B8, 32, 1, 1, 8, 8, 8, 8, 0, 0, 0, GL_BGRA8_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_R16F, 16, 1, 1, 16, 0, 0, 0, 0, 0, 0, GL_R16F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_G16R16F, 32, 1, 1, 16, 16, 0, 0, 0, 0, 0, GL_RG16F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A16B16G16R16F, 64, 1, 1, 16, 16, 16, 16, 0, 0, 0, GL_RGBA16F_EXT, GenerateMip, ReadColor); - InsertD3DFormatInfo(&map, D3DFMT_R32F, 32, 1, 1, 32, 0, 0, 0, 0, 0, 0, GL_R32F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_G32R32F, 64, 1, 1, 32, 32, 0, 0, 0, 0, 0, GL_RG32F_EXT, GenerateMip, ReadColor ); - InsertD3DFormatInfo(&map, D3DFMT_A32B32G32R32F, 128, 1, 1, 32, 32, 32, 32, 0, 0, 0, GL_RGBA32F_EXT, GenerateMip, ReadColor); - - InsertD3DFormatInfo(&map, D3DFMT_D16, 16, 1, 1, 0, 0, 0, 0, 0, 16, 0, GL_DEPTH_COMPONENT16, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D24S8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D24X8, 32, 1, 1, 0, 0, 0, 0, 0, 24, 0, GL_DEPTH_COMPONENT16, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_D32, 32, 1, 1, 0, 0, 0, 0, 0, 32, 0, GL_DEPTH_COMPONENT32_OES, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_INTZ, 32, 1, 1, 0, 0, 0, 0, 0, 24, 8, GL_DEPTH24_STENCIL8_OES, NULL, NULL ); - - InsertD3DFormatInfo(&map, D3DFMT_DXT1, 64, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT1_EXT, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_DXT3, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE, NULL, NULL ); - InsertD3DFormatInfo(&map, D3DFMT_DXT5, 128, 4, 4, 0, 0, 0, 0, 0, 0, 0, GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE, NULL, NULL ); - - return map; -} - -const D3DFormat &GetD3DFormatInfo(D3DFORMAT format) -{ - static const D3D9FormatInfoMap infoMap = BuildD3D9FormatInfoMap(); - D3D9FormatInfoMap::const_iterator iter = infoMap.find(format); - if (iter != infoMap.end()) + if (format == D3DFMT_INTZ) { - return iter->second; + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, Format::ID::D24_UNORM_S8_UINT); + return info; } - else + + switch (format) { - static const D3DFormat defaultInfo; - return defaultInfo; - } -} + case D3DFMT_UNKNOWN: + { + static const D3DFormat info(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Format::ID::NONE); + return info; + } + case D3DFMT_L8: + { + static const D3DFormat info(8, 1, 1, 0, 0, 0, 0, 8, 0, 0, Format::ID::L8_UNORM); + return info; + } + case D3DFMT_A8: + { + static const D3DFormat info(8, 1, 1, 0, 0, 0, 8, 0, 0, 0, Format::ID::A8_UNORM); + return info; + } + case D3DFMT_A8L8: + { + static const D3DFormat info(16, 1, 1, 0, 0, 0, 8, 8, 0, 0, Format::ID::L8A8_UNORM); + return info; + } + case D3DFMT_A4R4G4B4: + { + static const D3DFormat info(16, 1, 1, 4, 4, 4, 4, 0, 0, 0, Format::ID::B4G4R4A4_UNORM); + return info; + } + case D3DFMT_A1R5G5B5: + { + static const D3DFormat info(16, 1, 1, 5, 5, 5, 1, 0, 0, 0, Format::ID::B5G5R5A1_UNORM); + return info; + } + case D3DFMT_R5G6B5: + { + static const D3DFormat info(16, 1, 1, 5, 6, 5, 0, 0, 0, 0, Format::ID::R5G6B5_UNORM); + return info; + } + case D3DFMT_X8R8G8B8: + { + static const D3DFormat info(32, 1, 1, 8, 8, 8, 0, 0, 0, 0, Format::ID::B8G8R8X8_UNORM); + return info; + } + case D3DFMT_A8R8G8B8: + { + static const D3DFormat info(32, 1, 1, 8, 8, 8, 8, 0, 0, 0, Format::ID::B8G8R8A8_UNORM); + return info; + } + + case D3DFMT_R16F: + { + static const D3DFormat info(16, 1, 1, 16, 0, 0, 0, 0, 0, 0, Format::ID::R16_FLOAT); + return info; + } + case D3DFMT_G16R16F: + { + static const D3DFormat info(32, 1, 1, 16, 16, 0, 0, 0, 0, 0, Format::ID::R16G16_FLOAT); + return info; + } + case D3DFMT_A16B16G16R16F: + { + static const D3DFormat info(64, 1, 1, 16, 16, 16, 16, 0, 0, 0, + Format::ID::R16G16B16A16_FLOAT); + return info; + } + case D3DFMT_R32F: + { + static const D3DFormat info(32, 1, 1, 32, 0, 0, 0, 0, 0, 0, Format::ID::R32_FLOAT); + return info; + } + case D3DFMT_G32R32F: + { + static const D3DFormat info(64, 1, 1, 32, 32, 0, 0, 0, 0, 0, Format::ID::R32G32_FLOAT); + return info; + } + case D3DFMT_A32B32G32R32F: + { + static const D3DFormat info(128, 1, 1, 32, 32, 32, 32, 0, 0, 0, + Format::ID::R32G32B32A32_FLOAT); + return info; + } + + case D3DFMT_D16: + { + static const D3DFormat info(16, 1, 1, 0, 0, 0, 0, 0, 16, 0, Format::ID::D16_UNORM); + return info; + } + case D3DFMT_D24S8: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 8, + Format::ID::D24_UNORM_S8_UINT); + return info; + } + case D3DFMT_D24X8: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 24, 0, Format::ID::D16_UNORM); + return info; + } + case D3DFMT_D32: + { + static const D3DFormat info(32, 1, 1, 0, 0, 0, 0, 0, 32, 0, Format::ID::D32_UNORM); + return info; + } + + case D3DFMT_DXT1: + { + static const D3DFormat info(64, 4, 4, 0, 0, 0, 0, 0, 0, 0, + Format::ID::BC1_RGBA_UNORM_BLOCK); + return info; + } + case D3DFMT_DXT3: + { + static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0, + Format::ID::BC2_RGBA_UNORM_BLOCK); + return info; + } + case D3DFMT_DXT5: + { + static const D3DFormat info(128, 4, 4, 0, 0, 0, 0, 0, 0, 0, + Format::ID::BC3_RGBA_UNORM_BLOCK); + return info; + } + + default: + { + static const D3DFormat defaultInfo; + return defaultInfo; + } + } +} typedef std::pair InternalFormatInitialzerPair; typedef std::map InternalFormatInitialzerMap; static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() { + using namespace angle; // For image initialization functions + InternalFormatInitialzerMap map; map.insert(InternalFormatInitialzerPair(GL_RGB16F, Initialize4ComponentData)); @@ -175,28 +231,6 @@ static InternalFormatInitialzerMap BuildInternalFormatInitialzerMap() return map; } -// Each GL internal format corresponds to one D3D format and data loading function. -// Due to not all formats being available all the time, some of the function/format types are wrapped -// in templates that perform format support queries on a Renderer9 object which is supplied -// when requesting the function or format. - -typedef bool(*FallbackPredicateFunction)(); - -template -static void FallbackLoad(size_t width, size_t height, size_t depth, - const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, - uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) -{ - if (pred()) - { - prefered(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } - else - { - fallback(width, height, depth, input, inputRowPitch, inputDepthPitch, output, outputRowPitch, outputDepthPitch); - } -} - static void UnreachableLoad(size_t width, size_t height, size_t depth, const uint8_t *input, size_t inputRowPitch, size_t inputDepthPitch, uint8_t *output, size_t outputRowPitch, size_t outputDepthPitch) @@ -210,7 +244,7 @@ typedef std::map D3D9FormatMap; TextureFormat::TextureFormat() : texFormat(D3DFMT_UNKNOWN), renderFormat(D3DFMT_UNKNOWN), - dataInitializerFunction(NULL), + dataInitializerFunction(nullptr), loadFunction(UnreachableLoad) { } @@ -224,7 +258,8 @@ static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalForma static const InternalFormatInitialzerMap dataInitializationMap = BuildInternalFormatInitialzerMap(); InternalFormatInitialzerMap::const_iterator dataInitIter = dataInitializationMap.find(internalFormat); - info.dataInitializerFunction = (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : NULL; + info.dataInitializerFunction = + (dataInitIter != dataInitializationMap.end()) ? dataInitIter->second : nullptr; info.loadFunction = loadFunction; @@ -233,8 +268,11 @@ static inline void InsertD3D9FormatInfo(D3D9FormatMap *map, GLenum internalForma static D3D9FormatMap BuildD3D9FormatMap() { + using namespace angle; // For image loading functions + D3D9FormatMap map; + // clang-format off // | Internal format | Texture format | Render format | Load function | InsertD3D9FormatInfo(&map, GL_NONE, D3DFMT_NULL, D3DFMT_NULL, UnreachableLoad ); @@ -268,11 +306,11 @@ static D3D9FormatMap BuildD3D9FormatMap() InsertD3D9FormatInfo(&map, GL_LUMINANCE16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadL16FToRGBA16F ); InsertD3D9FormatInfo(&map, GL_LUMINANCE_ALPHA16F_EXT, D3DFMT_A16B16G16R16F, D3DFMT_UNKNOWN, LoadLA16FToRGBA16F ); - InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad); + InsertD3D9FormatInfo(&map, GL_ALPHA8_EXT, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadA8ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGB8_OES, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadRGB8ToBGRX8 ); InsertD3D9FormatInfo(&map, GL_RGB565, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR5G6B5ToBGRA8 ); - InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, FallbackLoad); + InsertD3D9FormatInfo(&map, GL_RGBA8_OES, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA8ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGBA4, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGBA4ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_RGB5_A1, D3DFMT_A8R8G8B8, D3DFMT_A8R8G8B8, LoadRGB5A1ToBGRA8 ); InsertD3D9FormatInfo(&map, GL_R8_EXT, D3DFMT_X8R8G8B8, D3DFMT_X8R8G8B8, LoadR8ToBGRX8 ); @@ -291,6 +329,7 @@ static D3D9FormatMap BuildD3D9FormatMap() // then changing the format and loading function appropriately. InsertD3D9FormatInfo(&map, GL_LUMINANCE8_EXT, D3DFMT_L8, D3DFMT_UNKNOWN, LoadToNative ); InsertD3D9FormatInfo(&map, GL_LUMINANCE8_ALPHA8_EXT, D3DFMT_A8L8, D3DFMT_UNKNOWN, LoadToNative ); + // clang-format on return map; } @@ -503,7 +542,7 @@ public: VertexFormat::VertexFormat() : conversionType(VERTEX_CONVERT_NONE), outputElementSize(0), - copyFunction(NULL), + copyFunction(nullptr), nativeFormat(D3DDECLTYPE_UNUSED), componentType(GL_NONE) { diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h index c55010760d..1bef320b53 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/formatutils9.h @@ -15,6 +15,8 @@ #include "common/platform.h" #include "libANGLE/angletypes.h" #include "libANGLE/formatutils.h" +#include "libANGLE/renderer/Format.h" +#include "libANGLE/renderer/renderer_utils.h" #include "libANGLE/renderer/d3d/formatutilsD3D.h" namespace rx @@ -25,11 +27,22 @@ class Renderer9; namespace d3d9 { -typedef std::map, ColorCopyFunction> FastCopyFunctionMap; - struct D3DFormat { D3DFormat(); + D3DFormat(GLuint pixelBytes, + GLuint blockWidth, + GLuint blockHeight, + GLuint redBits, + GLuint greenBits, + GLuint blueBits, + GLuint alphaBits, + GLuint luminanceBits, + GLuint depthBits, + GLuint stencilBits, + angle::Format::ID formatID); + + const angle::Format &info() const { return angle::Format::Get(formatID); } GLuint pixelBytes; GLuint blockWidth; @@ -44,14 +57,9 @@ struct D3DFormat GLuint depthBits; GLuint stencilBits; - GLenum internalFormat; - - MipGenerationFunction mipGenerationFunction; - ColorReadFunction colorReadFunction; - - FastCopyFunctionMap fastCopyFunctions; - ColorCopyFunction getFastCopyFunction(GLenum format, GLenum type) const; + angle::Format::ID formatID; }; + const D3DFormat &GetD3DFormatInfo(D3DFORMAT format); struct VertexFormat diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp index 8622dc4d13..fd451a6e51 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.cpp @@ -17,7 +17,9 @@ #include "libANGLE/renderer/d3d/d3d9/formatutils9.h" #include "libANGLE/renderer/d3d/d3d9/RenderTarget9.h" #include "libANGLE/renderer/d3d/FramebufferD3D.h" -#include "libANGLE/renderer/d3d/WorkaroundsD3D.h" +#include "libANGLE/renderer/driver_utils.h" +#include "platform/Platform.h" +#include "platform/WorkaroundsD3D.h" #include "third_party/systeminfo/SystemInfo.h" @@ -133,21 +135,22 @@ D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) return d3dWrap; } -D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace) +D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace) { D3DCULL cull = D3DCULL_CCW; switch (cullFace) { - case GL_FRONT: - cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); - break; - case GL_BACK: - cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); - break; - case GL_FRONT_AND_BACK: - cull = D3DCULL_NONE; // culling will be handled during draw - break; - default: UNREACHABLE(); + case gl::CullFaceMode::Front: + cull = (frontFace == GL_CCW ? D3DCULL_CW : D3DCULL_CCW); + break; + case gl::CullFaceMode::Back: + cull = (frontFace == GL_CCW ? D3DCULL_CCW : D3DCULL_CW); + break; + case gl::CullFaceMode::FrontAndBack: + cull = D3DCULL_NONE; // culling will be handled during draw + break; + default: + UNREACHABLE(); } return cull; @@ -264,6 +267,21 @@ void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DT } } +D3DQUERYTYPE ConvertQueryType(GLenum queryType) +{ + switch (queryType) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + return D3DQUERYTYPE_OCCLUSION; + case GL_COMMANDS_COMPLETED_CHROMIUM: + return D3DQUERYTYPE_EVENT; + default: + UNREACHABLE(); + return static_cast(0); + } +} + D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples) { return (samples > 1) ? static_cast(samples) : D3DMULTISAMPLE_NONE; @@ -291,8 +309,8 @@ GLsizei GetSamplesCount(D3DMULTISAMPLE_TYPE type) bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) { - GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).internalFormat; - GLenum convertedFormat = gl::GetInternalFormatInfo(internalFormat).format; + GLenum internalFormat = d3d9::GetD3DFormatInfo(d3dformat).info().glInternalFormat; + GLenum convertedFormat = gl::GetSizedInternalFormatInfo(internalFormat).format; return convertedFormat == format; } @@ -302,7 +320,7 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 gl::TextureCaps textureCaps; const d3d9::TextureFormat &d3dFormatInfo = d3d9::GetTextureFormatInfo(internalFormat); - const gl::InternalFormat &formatInfo = gl::GetInternalFormatInfo(internalFormat); + const gl::InternalFormat &formatInfo = gl::GetSizedInternalFormatInfo(internalFormat); if (d3dFormatInfo.texFormat != D3DFMT_UNKNOWN) { @@ -333,7 +351,8 @@ static gl::TextureCaps GenerateTextureFormatCaps(GLenum internalFormat, IDirect3 { D3DMULTISAMPLE_TYPE multisampleType = D3DMULTISAMPLE_TYPE(i); - HRESULT result = d3d9->CheckDeviceMultiSampleType(adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, NULL); + HRESULT result = d3d9->CheckDeviceMultiSampleType( + adapter, deviceType, d3dFormatInfo.renderFormat, TRUE, multisampleType, nullptr); if (SUCCEEDED(result)) { textureCaps.sampleCounts.insert(i); @@ -364,18 +383,17 @@ void GenerateCaps(IDirect3D9 *d3d9, d3d9->GetAdapterDisplayMode(adapter, ¤tDisplayMode); GLuint maxSamples = 0; - const gl::FormatSet &allFormats = gl::GetAllSizedInternalFormats(); - for (gl::FormatSet::const_iterator internalFormat = allFormats.begin(); internalFormat != allFormats.end(); ++internalFormat) + for (GLenum internalFormat : gl::GetAllSizedInternalFormats()) { - gl::TextureCaps textureCaps = GenerateTextureFormatCaps(*internalFormat, d3d9, deviceType, adapter, - currentDisplayMode.Format); - textureCapsMap->insert(*internalFormat, textureCaps); + gl::TextureCaps textureCaps = GenerateTextureFormatCaps(internalFormat, d3d9, deviceType, + adapter, currentDisplayMode.Format); + textureCapsMap->insert(internalFormat, textureCaps); maxSamples = std::max(maxSamples, textureCaps.getMaxSamples()); - if (gl::GetInternalFormatInfo(*internalFormat).compressed) + if (gl::GetSizedInternalFormatInfo(internalFormat).compressed) { - caps->compressedTextureFormats.push_back(*internalFormat); + caps->compressedTextureFormats.push_back(internalFormat); } } @@ -444,6 +462,8 @@ void GenerateCaps(IDirect3D9 *d3d9, // Vertex shader limits caps->maxVertexAttributes = 16; + // Vertex Attrib Binding not supported. + caps->maxVertexAttribBindings = caps->maxVertexAttributes; const size_t MAX_VERTEX_CONSTANT_VECTORS_D3D9 = 256; caps->maxVertexUniformVectors = @@ -525,12 +545,12 @@ void GenerateCaps(IDirect3D9 *d3d9, { // ATI cards on XP have problems with non-power-of-two textures. extensions->textureNPOT = !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && - !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && - !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && - !(!isWindowsVistaOrGreater() && adapterId.VendorId == VENDOR_ID_AMD); + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(deviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && + !(!isWindowsVistaOrGreater() && IsAMD(adapterId.VendorId)); // Disable depth texture support on AMD cards (See ANGLE issue 839) - if (adapterId.VendorId == VENDOR_ID_AMD) + if (IsAMD(adapterId.VendorId)) { extensions->depthTextures = false; } @@ -548,18 +568,21 @@ void GenerateCaps(IDirect3D9 *d3d9, extensions->maxTextureAnisotropy = static_cast(deviceCaps.MaxAnisotropy); // Check occlusion query support by trying to create one - IDirect3DQuery9 *occlusionQuery = NULL; + IDirect3DQuery9 *occlusionQuery = nullptr; extensions->occlusionQueryBoolean = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery; SafeRelease(occlusionQuery); // Check event query support by trying to create one - IDirect3DQuery9 *eventQuery = NULL; + IDirect3DQuery9 *eventQuery = nullptr; extensions->fence = SUCCEEDED(device->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery; SafeRelease(eventQuery); - extensions->timerQuery = false; // Unimplemented extensions->disjointTimerQuery = false; extensions->robustness = true; + // It seems that only DirectX 10 and higher enforce the well-defined behavior of always + // returning zero values when out-of-bounds reads. See + // https://www.khronos.org/registry/OpenGL/extensions/ARB/ARB_robustness.txt + extensions->robustBufferAccessBehavior = false; extensions->blendMinMax = true; extensions->framebufferBlit = true; extensions->framebufferMultisample = true; @@ -575,10 +598,11 @@ void GenerateCaps(IDirect3D9 *d3d9, extensions->colorBufferFloat = false; extensions->debugMarker = true; extensions->eglImage = true; + extensions->eglImageExternal = true; extensions->unpackSubimage = true; extensions->packSubimage = true; - extensions->vertexArrayObject = true; - extensions->noError = true; + extensions->syncQuery = extensions->fence; + extensions->copyTexture = true; // D3D9 has no concept of separate masks and refs for front and back faces in the depth stencil // state. @@ -625,15 +649,23 @@ void MakeValidSize(bool isImage, D3DFORMAT format, GLsizei *requestWidth, GLsize *levelOffset = upsampleCount; } -WorkaroundsD3D GenerateWorkarounds() +angle::WorkaroundsD3D GenerateWorkarounds() { - WorkaroundsD3D workarounds; + angle::WorkaroundsD3D workarounds; workarounds.mrtPerfWorkaround = true; workarounds.setDataFasterThanImageUpload = false; workarounds.useInstancedPointSpriteEmulation = false; + + // TODO(jmadill): Disable workaround when we have a fixed compiler DLL. + workarounds.expandIntegerPowExpressions = true; + + // Call platform hooks for testing overrides. + auto *platform = ANGLEPlatformCurrent(); + platform->overrideWorkaroundsD3D(platform, &workarounds); + return workarounds; } -} +} // namespace d3d9 -} +} // namespace rx diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h index aa494adb62..5b65b8910a 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/renderer9_utils.h @@ -10,9 +10,10 @@ #ifndef LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ #define LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ -#include "libANGLE/angletypes.h" +#include "common/Color.h" #include "libANGLE/Caps.h" #include "libANGLE/Error.h" +#include "platform/WorkaroundsD3D.h" namespace gl { @@ -22,7 +23,6 @@ class FramebufferAttachment; namespace rx { class RenderTarget9; -struct WorkaroundsD3D; namespace gl_d3d9 { @@ -33,12 +33,13 @@ D3DBLEND ConvertBlendFunc(GLenum blend); D3DBLENDOP ConvertBlendOp(GLenum blendOp); D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); -D3DCULL ConvertCullMode(GLenum cullFace, GLenum frontFace); +D3DCULL ConvertCullMode(gl::CullFaceMode cullFace, GLenum frontFace); D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace); DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha); D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy); void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float *d3dLodBias, float maxAnisotropy, size_t baseLevel); +D3DQUERYTYPE ConvertQueryType(GLenum queryType); D3DMULTISAMPLE_TYPE GetMultisampleType(GLuint samples); @@ -86,9 +87,9 @@ inline bool isDeviceLostError(HRESULT errorCode) } } -WorkaroundsD3D GenerateWorkarounds(); +angle::WorkaroundsD3D GenerateWorkarounds(); } -} +} // namespace d3d9 #endif // LIBANGLE_RENDERER_D3D_D3D9_RENDERER9UTILS_H_ diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps index dc357d0fa6..ecc593cc78 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.ps @@ -24,6 +24,23 @@ float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR return (tex2D(tex, texcoord.xy).xw * mult.xw + add.xw).xxxy; }; +float4 luminancepremultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 luma = tex2D(tex, texcoord.xy).xxxw; + luma.rgb *= luma.a; + return luma * mult + add; +}; + +float4 luminanceunmultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 luma = tex2D(tex, texcoord.xy).xxxw; + if (luma.a > 0.0f) + { + luma.rgb /= luma.a; + } + return luma * mult + add; +}; + // RGB/A Component Mask Pixel Shader // Performs a mad operation using the texture's RGBA data with mult.xyzw and add.xyzw. // Returns data in the form of rgba @@ -31,3 +48,20 @@ float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR { return tex2D(tex, texcoord.xy) * mult + add; }; + +float4 componentmaskpremultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 color = tex2D(tex, texcoord.xy); + color.rgb *= color.a; + return color * mult + add; +}; + +float4 componentmaskunmultps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 color = tex2D(tex, texcoord.xy); + if (color.a > 0.0f) + { + color.rgb /= color.a; + } + return color * mult + add; +}; diff --git a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs index 3a36980b93..c68395a69c 100644 --- a/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs +++ b/src/3rdparty/angle/src/libANGLE/renderer/d3d/d3d9/shaders/Blit.vs @@ -11,6 +11,7 @@ struct VS_OUTPUT }; uniform float4 halfPixelSize : c0; +uniform float4 texcoordOffset : c1; // Standard Vertex Shader // Input 0 is the homogenous position. @@ -22,22 +23,7 @@ VS_OUTPUT standardvs(in float4 position : POSITION) VS_OUTPUT Out; Out.position = position + halfPixelSize; - Out.texcoord = position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0); - - return Out; -}; - -// Flip Y Vertex Shader -// Input 0 is the homogenous position. -// Outputs the homogenous position as-is. -// Outputs a tex coord with (0,1) in the upper-left corner of the screen and (1,0) in the bottom right. -// C0.XY must be the half-pixel width and height. C0.ZW must be 0. -VS_OUTPUT flipyvs(in float4 position : POSITION) -{ - VS_OUTPUT Out; - - Out.position = position + halfPixelSize; - Out.texcoord = position * float4(0.5, 0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0); + Out.texcoord = ((position * float4(0.5, -0.5, 1.0, 1.0) + float4(0.5, 0.5, 0, 0)) * float4(texcoordOffset.zw, 1.0, 1.0)) + float4(texcoordOffset.xy, 0, 0); return Out; }; -- cgit v1.2.3