From a7d093e740b1e20874b5ebeb37b5c5d76ae19e42 Mon Sep 17 00:00:00 2001 From: Andrew Knight Date: Mon, 24 Feb 2014 11:18:33 +0200 Subject: Upgrade ANGLE to 1.3.5bb7ec572d0a This brings Qt's copy of ANGLE up to ANGLE master, which contains a number of bugfixes as well as restructuring for the upcoming ES 3.0 support. This version brings considerable stability improvements to the D3D11 renderer. The static translator project files have been merged to align with the ANGLE source tree. Two new patches have been applied to fix errors in upstream ANGLE: - 0011-ANGLE-Fix-compilation-error-on-MinGW-caused-by-trace.patch The event trace header in ANGLE's third_party directory has an unused template which causes a compilation error on MinGW. Disable this part of the code. - 0012-ANGLE-fix-semantic-index-lookup.patch The sorted semantic index table was returning a direct mapping to the new indices, instead of the old indices. This caused a mismatch in the GL type lookup for the translated attribute. All other patches have been rebased, removed if no longer needed, and renamed to clear up the application order: - 0001-Fix-compilation-for-MSVC-2008-and-std-tuple.patch No changes. - 0001-Fix-compilation-with-MinGW-mingw-tdm64-gcc-4.8.1.patch No changes. Renamed to 0002. - 0001-Fix-compilation-with-MinGW-gcc-64-bit.patch No changes. Renamed to 0003. - 0001-Make-it-possible-to-link-ANGLE-statically-for-single.patch Modified patch to adapt to new DLL loading structure. Renamed to 0004. - 0005-Fix-build-when-SSE2-is-not-available.patch No changes. - 0011-Fix-compilation-of-libGLESv2-with-older-MinGW-w64-he.patch No changes. Renamed to 0006. - 0006-Make-DX9-DX11-mutually-exclusive.patch Made the patch less invasive by allowing D3D9 code to run unless explicitly disabled (e.g. on WinRT, where it doesn't compile). This makes the patch smaller and allows Desktop Windows to compile both D3D9 and D3D11 codepaths. Renamed to 0007. - 0015-ANGLE-Dynamically-load-D3D-compiler-from-a-list-of-k.patch No changes. Renamed to 0008. - 0012-ANGLE-Support-WinRT.patch Made D3D11_level9 initialization only possible if D3D9 is disabled. This makes sure Desktop PCs use the old D3D9 codepath instead of the less-tested D3D11_level9 codepath. Renamed to 0009. - 0013-Enable-D3D11-for-feature-level-9-cards.patch Conveniently smaller patch due to buffer implementation improvements upstream. Renamed to 0010. - 0014-ANGLE-D3D11-Alwayls-execute-QueryInterface.patch This was a fix for patch 0009, so was integrated there. Removed. - 0016-ANGLE-D3D11-Fix-build-on-desktop-Windows.patch This was a fix for patch 0009, so it was integrated there. Removed. - 0001-ANGLE-Fix-compilation-with-MSVC2013.patch Fixed upstream. Removed. - 0007-ANGLE-Fix-typedefs-for-Win64.patch Fixed upstream. Removed. - 0004-Fix-black-screen-after-minimizing-OpenGL-window-with.patch The issue has been fixed in Qt itself. Removed. - 0008-DX11-Prevent-assert-when-view-is-minimized-or-.patch The cause of the problem was the same as patch 0004, but for the D3D11 codepath. Removed. Change-Id: Id69484ab3a3e013050741c462fb1b06dfb0fd112 Reviewed-by: Friedemann Kleint Reviewed-by: Kai Koehne Reviewed-by: Oliver Wolff --- src/3rdparty/angle/src/libGLESv2/Buffer.cpp | 8 +- src/3rdparty/angle/src/libGLESv2/Buffer.h | 4 +- src/3rdparty/angle/src/libGLESv2/Context.cpp | 30 +- src/3rdparty/angle/src/libGLESv2/Context.h | 9 +- src/3rdparty/angle/src/libGLESv2/Framebuffer.h | 2 +- src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp | 37 +- src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp | 15 + src/3rdparty/angle/src/libGLESv2/Renderbuffer.h | 5 + src/3rdparty/angle/src/libGLESv2/Shader.cpp | 2 + src/3rdparty/angle/src/libGLESv2/Shader.h | 3 +- src/3rdparty/angle/src/libGLESv2/Texture.cpp | 8 +- src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp | 10 +- src/3rdparty/angle/src/libGLESv2/libGLESv2.rc | 11 +- src/3rdparty/angle/src/libGLESv2/main.cpp | 112 +- src/3rdparty/angle/src/libGLESv2/main.h | 3 +- src/3rdparty/angle/src/libGLESv2/mathutil.h | 1 - src/3rdparty/angle/src/libGLESv2/precompiled.h | 57 +- src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp | 595 ---- src/3rdparty/angle/src/libGLESv2/renderer/Blit.h | 94 - .../angle/src/libGLESv2/renderer/BufferStorage.h | 2 +- .../src/libGLESv2/renderer/BufferStorage11.cpp | 361 -- .../angle/src/libGLESv2/renderer/BufferStorage11.h | 56 - .../src/libGLESv2/renderer/BufferStorage9.cpp | 78 - .../angle/src/libGLESv2/renderer/BufferStorage9.h | 42 - .../angle/src/libGLESv2/renderer/Fence11.cpp | 134 - .../angle/src/libGLESv2/renderer/Fence11.h | 39 - .../angle/src/libGLESv2/renderer/Fence9.cpp | 135 - src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h | 39 - .../angle/src/libGLESv2/renderer/Image11.cpp | 460 --- .../angle/src/libGLESv2/renderer/Image11.h | 76 - .../angle/src/libGLESv2/renderer/Image9.cpp | 736 ---- src/3rdparty/angle/src/libGLESv2/renderer/Image9.h | 79 - .../angle/src/libGLESv2/renderer/IndexBuffer11.cpp | 183 - .../angle/src/libGLESv2/renderer/IndexBuffer11.h | 53 - .../angle/src/libGLESv2/renderer/IndexBuffer9.cpp | 207 -- .../angle/src/libGLESv2/renderer/IndexBuffer9.h | 53 - .../src/libGLESv2/renderer/InputLayoutCache.cpp | 213 -- .../src/libGLESv2/renderer/InputLayoutCache.h | 95 - .../angle/src/libGLESv2/renderer/Query11.cpp | 122 - .../angle/src/libGLESv2/renderer/Query11.h | 40 - .../angle/src/libGLESv2/renderer/Query9.cpp | 125 - src/3rdparty/angle/src/libGLESv2/renderer/Query9.h | 40 - .../src/libGLESv2/renderer/RenderStateCache.cpp | 407 --- .../src/libGLESv2/renderer/RenderStateCache.h | 101 - .../src/libGLESv2/renderer/RenderTarget11.cpp | 355 -- .../angle/src/libGLESv2/renderer/RenderTarget11.h | 51 - .../angle/src/libGLESv2/renderer/RenderTarget9.cpp | 113 - .../angle/src/libGLESv2/renderer/RenderTarget9.h | 40 - .../angle/src/libGLESv2/renderer/Renderer.cpp | 83 +- .../angle/src/libGLESv2/renderer/Renderer.h | 34 +- .../angle/src/libGLESv2/renderer/Renderer11.cpp | 3672 -------------------- .../angle/src/libGLESv2/renderer/Renderer11.h | 360 -- .../angle/src/libGLESv2/renderer/Renderer9.cpp | 3260 ----------------- .../angle/src/libGLESv2/renderer/Renderer9.h | 350 -- .../src/libGLESv2/renderer/ShaderExecutable11.cpp | 109 - .../src/libGLESv2/renderer/ShaderExecutable11.h | 47 - .../src/libGLESv2/renderer/ShaderExecutable9.cpp | 60 - .../src/libGLESv2/renderer/ShaderExecutable9.h | 39 - .../angle/src/libGLESv2/renderer/SwapChain.h | 7 +- .../angle/src/libGLESv2/renderer/SwapChain11.cpp | 797 ----- .../angle/src/libGLESv2/renderer/SwapChain11.h | 78 - .../angle/src/libGLESv2/renderer/SwapChain9.cpp | 449 --- .../angle/src/libGLESv2/renderer/SwapChain9.h | 55 - .../src/libGLESv2/renderer/TextureStorage11.cpp | 667 ---- .../src/libGLESv2/renderer/TextureStorage11.h | 120 - .../src/libGLESv2/renderer/TextureStorage9.cpp | 328 -- .../angle/src/libGLESv2/renderer/TextureStorage9.h | 109 - .../src/libGLESv2/renderer/VertexBuffer11.cpp | 440 --- .../angle/src/libGLESv2/renderer/VertexBuffer11.h | 74 - .../angle/src/libGLESv2/renderer/VertexBuffer9.cpp | 530 --- .../angle/src/libGLESv2/renderer/VertexBuffer9.h | 91 - .../src/libGLESv2/renderer/VertexDataManager.cpp | 4 + .../libGLESv2/renderer/VertexDeclarationCache.cpp | 217 -- .../libGLESv2/renderer/VertexDeclarationCache.h | 58 - .../libGLESv2/renderer/d3d11/BufferStorage11.cpp | 366 ++ .../src/libGLESv2/renderer/d3d11/BufferStorage11.h | 92 + .../angle/src/libGLESv2/renderer/d3d11/Fence11.cpp | 134 + .../angle/src/libGLESv2/renderer/d3d11/Fence11.h | 39 + .../angle/src/libGLESv2/renderer/d3d11/Image11.cpp | 498 +++ .../angle/src/libGLESv2/renderer/d3d11/Image11.h | 76 + .../src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp | 183 + .../src/libGLESv2/renderer/d3d11/IndexBuffer11.h | 53 + .../libGLESv2/renderer/d3d11/InputLayoutCache.cpp | 213 ++ .../libGLESv2/renderer/d3d11/InputLayoutCache.h | 95 + .../angle/src/libGLESv2/renderer/d3d11/Query11.cpp | 122 + .../angle/src/libGLESv2/renderer/d3d11/Query11.h | 40 + .../libGLESv2/renderer/d3d11/RenderStateCache.cpp | 439 +++ .../libGLESv2/renderer/d3d11/RenderStateCache.h | 111 + .../libGLESv2/renderer/d3d11/RenderTarget11.cpp | 355 ++ .../src/libGLESv2/renderer/d3d11/RenderTarget11.h | 51 + .../src/libGLESv2/renderer/d3d11/Renderer11.cpp | 3670 +++++++++++++++++++ .../src/libGLESv2/renderer/d3d11/Renderer11.h | 358 ++ .../renderer/d3d11/ShaderExecutable11.cpp | 109 + .../libGLESv2/renderer/d3d11/ShaderExecutable11.h | 47 + .../src/libGLESv2/renderer/d3d11/SwapChain11.cpp | 700 ++++ .../src/libGLESv2/renderer/d3d11/SwapChain11.h | 78 + .../libGLESv2/renderer/d3d11/TextureStorage11.cpp | 667 ++++ .../libGLESv2/renderer/d3d11/TextureStorage11.h | 120 + .../libGLESv2/renderer/d3d11/VertexBuffer11.cpp | 440 +++ .../src/libGLESv2/renderer/d3d11/VertexBuffer11.h | 74 + .../libGLESv2/renderer/d3d11/renderer11_utils.cpp | 688 ++++ .../libGLESv2/renderer/d3d11/renderer11_utils.h | 95 + .../libGLESv2/renderer/d3d11/shaders/Clear11.hlsl | 42 + .../renderer/d3d11/shaders/Passthrough11.hlsl | 29 + .../angle/src/libGLESv2/renderer/d3d9/Blit.cpp | 595 ++++ .../angle/src/libGLESv2/renderer/d3d9/Blit.h | 94 + .../src/libGLESv2/renderer/d3d9/BufferStorage9.cpp | 78 + .../src/libGLESv2/renderer/d3d9/BufferStorage9.h | 42 + .../angle/src/libGLESv2/renderer/d3d9/Fence9.cpp | 135 + .../angle/src/libGLESv2/renderer/d3d9/Fence9.h | 39 + .../angle/src/libGLESv2/renderer/d3d9/Image9.cpp | 736 ++++ .../angle/src/libGLESv2/renderer/d3d9/Image9.h | 79 + .../src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp | 207 ++ .../src/libGLESv2/renderer/d3d9/IndexBuffer9.h | 53 + .../angle/src/libGLESv2/renderer/d3d9/Query9.cpp | 125 + .../angle/src/libGLESv2/renderer/d3d9/Query9.h | 40 + .../src/libGLESv2/renderer/d3d9/RenderTarget9.cpp | 113 + .../src/libGLESv2/renderer/d3d9/RenderTarget9.h | 40 + .../src/libGLESv2/renderer/d3d9/Renderer9.cpp | 3287 ++++++++++++++++++ .../angle/src/libGLESv2/renderer/d3d9/Renderer9.h | 356 ++ .../libGLESv2/renderer/d3d9/ShaderExecutable9.cpp | 60 + .../libGLESv2/renderer/d3d9/ShaderExecutable9.h | 39 + .../src/libGLESv2/renderer/d3d9/SwapChain9.cpp | 445 +++ .../angle/src/libGLESv2/renderer/d3d9/SwapChain9.h | 55 + .../libGLESv2/renderer/d3d9/TextureStorage9.cpp | 328 ++ .../src/libGLESv2/renderer/d3d9/TextureStorage9.h | 109 + .../src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp | 530 +++ .../src/libGLESv2/renderer/d3d9/VertexBuffer9.h | 91 + .../renderer/d3d9/VertexDeclarationCache.cpp | 217 ++ .../renderer/d3d9/VertexDeclarationCache.h | 58 + .../libGLESv2/renderer/d3d9/renderer9_utils.cpp | 500 +++ .../src/libGLESv2/renderer/d3d9/renderer9_utils.h | 74 + .../src/libGLESv2/renderer/d3d9/shaders/Blit.ps | 39 + .../src/libGLESv2/renderer/d3d9/shaders/Blit.vs | 43 + .../src/libGLESv2/renderer/d3d9/vertexconversion.h | 203 ++ .../src/libGLESv2/renderer/renderer11_utils.cpp | 688 ---- .../src/libGLESv2/renderer/renderer11_utils.h | 95 - .../src/libGLESv2/renderer/renderer9_utils.cpp | 500 --- .../angle/src/libGLESv2/renderer/renderer9_utils.h | 74 - .../angle/src/libGLESv2/renderer/shaders/Blit.ps | 39 - .../angle/src/libGLESv2/renderer/shaders/Blit.vs | 43 - .../src/libGLESv2/renderer/shaders/Clear11.hlsl | 42 - .../libGLESv2/renderer/shaders/Passthrough11.hlsl | 29 - .../src/libGLESv2/renderer/vertexconversion.h | 203 -- src/3rdparty/angle/src/libGLESv2/utilities.cpp | 63 +- 145 files changed, 19110 insertions(+), 18939 deletions(-) delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Blit.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Image11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Image9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Query11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Query9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.h create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.vs create mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/d3d9/vertexconversion.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl delete mode 100644 src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h (limited to 'src/3rdparty/angle/src/libGLESv2') diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp index 40baa95760..c007d5d9e9 100644 --- a/src/3rdparty/angle/src/libGLESv2/Buffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Buffer.cpp @@ -37,11 +37,11 @@ Buffer::~Buffer() delete mStaticIndexBuffer; } -void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target) +void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage) { mBufferStorage->clear(); mIndexRangeCache.clear(); - mBufferStorage->setData(data, size, 0, target); + mBufferStorage->setData(data, size, 0); mUsage = usage; @@ -54,9 +54,9 @@ void Buffer::bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum } } -void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target) +void Buffer::bufferSubData(const void *data, GLsizeiptr size, GLintptr offset) { - mBufferStorage->setData(data, size, offset, target); + mBufferStorage->setData(data, size, offset); mIndexRangeCache.invalidateRange(offset, size); if ((mStaticVertexBuffer && mStaticVertexBuffer->getBufferSize() != 0) || (mStaticIndexBuffer && mStaticIndexBuffer->getBufferSize() != 0)) diff --git a/src/3rdparty/angle/src/libGLESv2/Buffer.h b/src/3rdparty/angle/src/libGLESv2/Buffer.h index 9b86b9791f..4048f4b906 100644 --- a/src/3rdparty/angle/src/libGLESv2/Buffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Buffer.h @@ -33,8 +33,8 @@ class Buffer : public RefCountObject virtual ~Buffer(); - void bufferData(const void *data, GLsizeiptr size, GLenum usage, GLenum target); - void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset, GLenum target); + void bufferData(const void *data, GLsizeiptr size, GLenum usage); + void bufferSubData(const void *data, GLsizeiptr size, GLintptr offset); GLenum usage() const; diff --git a/src/3rdparty/angle/src/libGLESv2/Context.cpp b/src/3rdparty/angle/src/libGLESv2/Context.cpp index e829d508a6..e651785aed 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Context.cpp @@ -1779,7 +1779,7 @@ void Context::applyState(GLenum drawMode) { mask = 0xFFFFFFFF; } - mRenderer->setBlendState(mState.blend, mState.blendColor, mask); + mRenderer->setBlendState(framebufferObject, mState.blend, mState.blendColor, mask); mRenderer->setDepthStencilState(mState.depthStencil, mState.stencilRef, mState.stencilBackRef, mState.rasterizer.frontFace == GL_CCW); @@ -1813,6 +1813,8 @@ void Context::applyTextures(SamplerType type) { ProgramBinary *programBinary = getCurrentProgramBinary(); + FramebufferTextureSerialSet boundFramebufferTextures = getBoundFramebufferTextureSerials(); + // Range of Direct3D samplers of given sampler type int samplerCount = (type == SAMPLER_PIXEL) ? MAX_TEXTURE_IMAGE_UNITS : mRenderer->getMaxVertexTextureImageUnits(); int samplerRange = programBinary->getUsedSamplerRange(type); @@ -1826,7 +1828,8 @@ void Context::applyTextures(SamplerType type) TextureType textureType = programBinary->getSamplerTextureType(type, samplerIndex); Texture *texture = getSamplerTexture(textureUnit, textureType); - if (texture->isSamplerComplete()) + if (texture->isSamplerComplete() && + boundFramebufferTextures.find(texture->getTextureSerial()) == boundFramebufferTextures.end()) { SamplerState samplerState; texture->getSamplerState(&samplerState); @@ -2656,6 +2659,29 @@ const char *Context::getRendererString() const return mRendererString; } +Context::FramebufferTextureSerialSet Context::getBoundFramebufferTextureSerials() +{ + FramebufferTextureSerialSet set; + + Framebuffer *drawFramebuffer = getDrawFramebuffer(); + for (unsigned int i = 0; i < IMPLEMENTATION_MAX_DRAW_BUFFERS; i++) + { + Renderbuffer *renderBuffer = drawFramebuffer->getColorbuffer(i); + if (renderBuffer && renderBuffer->getTextureSerial() != 0) + { + set.insert(renderBuffer->getTextureSerial()); + } + } + + Renderbuffer *depthStencilBuffer = drawFramebuffer->getDepthOrStencilbuffer(); + if (depthStencilBuffer && depthStencilBuffer->getTextureSerial() != 0) + { + set.insert(depthStencilBuffer->getTextureSerial()); + } + + return set; +} + void Context::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask) diff --git a/src/3rdparty/angle/src/libGLESv2/Context.h b/src/3rdparty/angle/src/libGLESv2/Context.h index 9c222be24d..3dc95e3b95 100644 --- a/src/3rdparty/angle/src/libGLESv2/Context.h +++ b/src/3rdparty/angle/src/libGLESv2/Context.h @@ -18,6 +18,7 @@ #include #include +#include #ifdef _MSC_VER #include #else @@ -37,7 +38,6 @@ class Renderer; namespace egl { -class Display; class Surface; } @@ -73,7 +73,7 @@ enum QueryType class VertexAttribute { public: - VertexAttribute() : mType(GL_FLOAT), mSize(0), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0) + VertexAttribute() : mType(GL_FLOAT), mSize(4), mNormalized(false), mStride(0), mPointer(NULL), mArrayEnabled(false), mDivisor(0) { mCurrentValue[0] = 0.0f; mCurrentValue[1] = 0.0f; @@ -398,6 +398,8 @@ class Context GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask); + rx::Renderer *getRenderer() { return mRenderer; } + private: DISALLOW_COPY_AND_ASSIGN(Context); @@ -419,6 +421,9 @@ class Context void initExtensionString(); void initRendererString(); + typedef std::set FramebufferTextureSerialSet; + FramebufferTextureSerialSet getBoundFramebufferTextureSerials(); + rx::Renderer *const mRenderer; State mState; diff --git a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h index b54e008dd8..50bfd4fd0f 100644 --- a/src/3rdparty/angle/src/libGLESv2/Framebuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Framebuffer.h @@ -12,7 +12,7 @@ #include "common/angleutils.h" #include "common/RefCountObject.h" -#include "constants.h" +#include "Constants.h" namespace rx { diff --git a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp index bcd04b7157..a4d21192fa 100644 --- a/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp +++ b/src/3rdparty/angle/src/libGLESv2/ProgramBinary.cpp @@ -34,6 +34,11 @@ std::string str(int i) return buffer; } +static rx::D3DWorkaroundType DiscardWorkaround(bool usesDiscard) +{ + return (usesDiscard ? rx::ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER : rx::ANGLE_D3D_WORKAROUND_NONE); +} + UniformLocation::UniformLocation(const std::string &name, unsigned int element, unsigned int index) : name(name), element(element), index(index) { @@ -1622,9 +1627,19 @@ bool ProgramBinary::load(InfoLog &infoLog, const void *binary, GLsizei length) return false; } - int version = 0; - stream.read(&version); - if (version != VERSION_DWORD) + int majorVersion = 0; + int minorVersion = 0; + stream.read(&majorVersion); + stream.read(&minorVersion); + if (majorVersion != ANGLE_MAJOR_VERSION || minorVersion != ANGLE_MINOR_VERSION) + { + infoLog.append("Invalid program binary version."); + return false; + } + + unsigned char commitString[ANGLE_COMMIT_HASH_SIZE]; + stream.read(commitString, ANGLE_COMMIT_HASH_SIZE); + if (memcmp(commitString, ANGLE_COMMIT_HASH, sizeof(unsigned char) * ANGLE_COMMIT_HASH_SIZE) != 0) { infoLog.append("Invalid program binary version."); return false; @@ -1791,7 +1806,9 @@ bool ProgramBinary::save(void* binary, GLsizei bufSize, GLsizei *length) BinaryOutputStream stream; stream.write(GL_PROGRAM_BINARY_ANGLE); - stream.write(VERSION_DWORD); + stream.write(ANGLE_MAJOR_VERSION); + stream.write(ANGLE_MINOR_VERSION); + stream.write(ANGLE_COMMIT_HASH, ANGLE_COMMIT_HASH_SIZE); stream.write(ANGLE_COMPILE_OPTIMIZATION_LEVEL); for (unsigned int i = 0; i < MAX_VERTEX_ATTRIBS; ++i) @@ -1962,13 +1979,13 @@ bool ProgramBinary::link(InfoLog &infoLog, const AttributeBindings &attributeBin if (success) { - mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX); - mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL); + mVertexExecutable = mRenderer->compileToExecutable(infoLog, vertexHLSL.c_str(), rx::SHADER_VERTEX, DiscardWorkaround(vertexShader->mUsesDiscardRewriting)); + mPixelExecutable = mRenderer->compileToExecutable(infoLog, pixelHLSL.c_str(), rx::SHADER_PIXEL, DiscardWorkaround(fragmentShader->mUsesDiscardRewriting)); if (usesGeometryShader()) { std::string geometryHLSL = generateGeometryShaderHLSL(registers, packing, fragmentShader, vertexShader); - mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY); + mGeometryExecutable = mRenderer->compileToExecutable(infoLog, geometryHLSL.c_str(), rx::SHADER_GEOMETRY, rx::ANGLE_D3D_WORKAROUND_NONE); } if (!mVertexExecutable || !mPixelExecutable || (usesGeometryShader() && !mGeometryExecutable)) @@ -2587,7 +2604,9 @@ struct AttributeSorter bool operator()(int a, int b) { - return originalIndices[a] == -1 ? false : originalIndices[a] < originalIndices[b]; + if (originalIndices[a] == -1) return false; + if (originalIndices[b] == -1) return true; + return (originalIndices[a] < originalIndices[b]); } const int (&originalIndices)[MAX_VERTEX_ATTRIBS]; @@ -2615,7 +2634,7 @@ void ProgramBinary::sortAttributesByLayout(rx::TranslatedAttribute attributes[MA for (int i = 0; i < MAX_VERTEX_ATTRIBS; i++) { int oldIndex = mAttributesByLayout[i]; - sortedSemanticIndices[i] = mSemanticIndex[oldIndex]; + sortedSemanticIndices[i] = oldIndex; attributes[i] = oldTranslatedAttributes[oldIndex]; } } diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp index 127513741c..98d33ec6c3 100644 --- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.cpp @@ -129,6 +129,11 @@ unsigned int RenderbufferTexture2D::getSerial() const return mTexture2D->getRenderTargetSerial(mTarget); } +unsigned int RenderbufferTexture2D::getTextureSerial() const +{ + return mTexture2D->getTextureSerial(); +} + ///// RenderbufferTextureCubeMap Implementation //////// RenderbufferTextureCubeMap::RenderbufferTextureCubeMap(TextureCubeMap *texture, GLenum target) : mTarget(target) @@ -193,6 +198,11 @@ unsigned int RenderbufferTextureCubeMap::getSerial() const return mTextureCubeMap->getRenderTargetSerial(mTarget); } +unsigned int RenderbufferTextureCubeMap::getTextureSerial() const +{ + return mTextureCubeMap->getTextureSerial(); +} + ////// Renderbuffer Implementation ////// Renderbuffer::Renderbuffer(rx::Renderer *renderer, GLuint id, RenderbufferInterface *instance) : RefCountObject(id) @@ -292,6 +302,11 @@ unsigned int Renderbuffer::getSerial() const return mInstance->getSerial(); } +unsigned int Renderbuffer::getTextureSerial() const +{ + return mInstance->getTextureSerial(); +} + void Renderbuffer::setStorage(RenderbufferStorage *newStorage) { ASSERT(newStorage != NULL); diff --git a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h index eca2f3a780..d46fd44557 100644 --- a/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h +++ b/src/3rdparty/angle/src/libGLESv2/Renderbuffer.h @@ -60,6 +60,7 @@ class RenderbufferInterface GLuint getStencilSize() const; virtual unsigned int getSerial() const = 0; + virtual unsigned int getTextureSerial() const = 0; private: DISALLOW_COPY_AND_ASSIGN(RenderbufferInterface); @@ -85,6 +86,7 @@ class RenderbufferTexture2D : public RenderbufferInterface virtual GLsizei getSamples() const; virtual unsigned int getSerial() const; + virtual unsigned int getTextureSerial() const; private: DISALLOW_COPY_AND_ASSIGN(RenderbufferTexture2D); @@ -113,6 +115,7 @@ class RenderbufferTextureCubeMap : public RenderbufferInterface virtual GLsizei getSamples() const; virtual unsigned int getSerial() const; + virtual unsigned int getTextureSerial() const; private: DISALLOW_COPY_AND_ASSIGN(RenderbufferTextureCubeMap); @@ -141,6 +144,7 @@ class RenderbufferStorage : public RenderbufferInterface virtual GLsizei getSamples() const; virtual unsigned int getSerial() const; + virtual unsigned int getTextureSerial() const { return 0; } static unsigned int issueSerial(); static unsigned int issueCubeSerials(); @@ -193,6 +197,7 @@ class Renderbuffer : public RefCountObject GLsizei getSamples() const; unsigned int getSerial() const; + unsigned int getTextureSerial() const; void setStorage(RenderbufferStorage *newStorage); diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.cpp b/src/3rdparty/angle/src/libGLESv2/Shader.cpp index 7dfdd0ba3a..f6a2f03dfc 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Shader.cpp @@ -307,6 +307,7 @@ void Shader::parseVaryings() mUsesPointCoord = strstr(mHlsl, "GL_USES_POINT_COORD") != NULL; mUsesDepthRange = strstr(mHlsl, "GL_USES_DEPTH_RANGE") != NULL; mUsesFragDepth = strstr(mHlsl, "GL_USES_FRAG_DEPTH") != NULL; + mUsesDiscardRewriting = strstr(mHlsl, "ANGLE_USES_DISCARD_REWRITING") != NULL; } } @@ -340,6 +341,7 @@ void Shader::uncompile() mUsesPointCoord = false; mUsesDepthRange = false; mUsesFragDepth = false; + mUsesDiscardRewriting = false; mActiveUniforms.clear(); } diff --git a/src/3rdparty/angle/src/libGLESv2/Shader.h b/src/3rdparty/angle/src/libGLESv2/Shader.h index 2afe2976c3..2015addd11 100644 --- a/src/3rdparty/angle/src/libGLESv2/Shader.h +++ b/src/3rdparty/angle/src/libGLESv2/Shader.h @@ -18,7 +18,7 @@ #include #include -#include "compiler/Uniform.h" +#include "compiler/translator/Uniform.h" #include "common/angleutils.h" namespace rx @@ -107,6 +107,7 @@ class Shader bool mUsesPointCoord; bool mUsesDepthRange; bool mUsesFragDepth; + bool mUsesDiscardRewriting; static void *mFragmentCompiler; static void *mVertexCompiler; diff --git a/src/3rdparty/angle/src/libGLESv2/Texture.cpp b/src/3rdparty/angle/src/libGLESv2/Texture.cpp index 72c0a8ab79..3257d05dd4 100644 --- a/src/3rdparty/angle/src/libGLESv2/Texture.cpp +++ b/src/3rdparty/angle/src/libGLESv2/Texture.cpp @@ -14,8 +14,8 @@ #include "libGLESv2/main.h" #include "libGLESv2/mathutil.h" #include "libGLESv2/utilities.h" -#ifndef ANGLE_ENABLE_D3D11 -# include "libGLESv2/renderer/Blit.h" +#if defined(ANGLE_ENABLE_D3D9) +# include "libGLESv2/renderer/d3d9/Blit.h" #else # define D3DFMT_UNKNOWN DXGI_FORMAT_UNKNOWN #endif @@ -1362,10 +1362,10 @@ void TextureCubeMap::storage(GLsizei levels, GLenum internalformat, GLsizei size for (int level = 0; level < levels; level++) { + GLsizei mipSize = std::max(1, size >> level); for (int face = 0; face < 6; face++) { - mImageArray[face][level]->redefine(mRenderer, internalformat, size, size, true); - size = std::max(1, size >> 1); + mImageArray[face][level]->redefine(mRenderer, internalformat, mipSize, mipSize, true); } } diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp index 91719f8e6d..814dfbf965 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.cpp @@ -758,7 +758,7 @@ void __stdcall glBufferData(GLenum target, GLsizeiptr size, const GLvoid* data, return gl::error(GL_INVALID_OPERATION); } - buffer->bufferData(data, size, usage, target); + buffer->bufferData(data, size, usage); } } catch(std::bad_alloc&) @@ -812,7 +812,7 @@ void __stdcall glBufferSubData(GLenum target, GLintptr offset, GLsizeiptr size, return gl::error(GL_INVALID_VALUE); } - buffer->bufferSubData(data, size, offset, target); + buffer->bufferSubData(data, size, offset); } } catch(std::bad_alloc&) @@ -3844,9 +3844,9 @@ const GLubyte* __stdcall glGetString(GLenum name) case GL_RENDERER: return (GLubyte*)((context != NULL) ? context->getRendererString() : "ANGLE"); case GL_VERSION: - return (GLubyte*)"OpenGL ES 2.0 (ANGLE " VERSION_STRING ")"; + return (GLubyte*)"OpenGL ES 2.0 (ANGLE " ANGLE_VERSION_STRING ")"; case GL_SHADING_LANGUAGE_VERSION: - return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " VERSION_STRING ")"; + return (GLubyte*)"OpenGL ES GLSL ES 1.00 (ANGLE " ANGLE_VERSION_STRING ")"; case GL_EXTENSIONS: return (GLubyte*)((context != NULL) ? context->getExtensionString() : ""); default: @@ -4893,9 +4893,9 @@ void __stdcall glRenderbufferStorageMultisampleANGLE(GLenum target, GLsizei samp case GL_RGB565: case GL_RGB8_OES: case GL_RGBA8_OES: - case GL_BGRA8_EXT: case GL_STENCIL_INDEX8: case GL_DEPTH24_STENCIL8_OES: + case GL_BGRA8_EXT: context->setRenderbufferStorage(width, height, internalformat, samples); break; default: diff --git a/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc b/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc index 0ad21e440e..76cd05566e 100644 --- a/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc +++ b/src/3rdparty/angle/src/libGLESv2/libGLESv2.rc @@ -54,8 +54,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION - PRODUCTVERSION MAJOR_VERSION,MINOR_VERSION,BUILD_VERSION,BUILD_REVISION + FILEVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 + PRODUCTVERSION ANGLE_MAJOR_VERSION,ANGLE_MINOR_VERSION,0,0 FILEFLAGSMASK 0x17L #ifdef _DEBUG FILEFLAGS 0x1L @@ -71,13 +71,14 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "ANGLE libGLESv2 Dynamic Link Library" - VALUE "FileVersion", VERSION_STRING + VALUE "FileVersion", ANGLE_VERSION_STRING VALUE "InternalName", "libGLESv2" VALUE "LegalCopyright", "Copyright (C) 2011 Google Inc." VALUE "OriginalFilename", "libGLESv2.dll" - VALUE "PrivateBuild", VERSION_STRING + VALUE "PrivateBuild", ANGLE_VERSION_STRING VALUE "ProductName", "ANGLE libGLESv2 Dynamic Link Library" - VALUE "ProductVersion", VERSION_STRING + VALUE "ProductVersion", ANGLE_VERSION_STRING + VALUE "Comments", "Build Date: " ANGLE_COMMIT_DATE END END BLOCK "VarFileInfo" diff --git a/src/3rdparty/angle/src/libGLESv2/main.cpp b/src/3rdparty/angle/src/libGLESv2/main.cpp index defdf35f77..95f4b8de1c 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.cpp +++ b/src/3rdparty/angle/src/libGLESv2/main.cpp @@ -11,15 +11,60 @@ #include "libGLESv2/Context.h" -#ifndef QT_OPENGL_ES_2_ANGLE_STATIC - #if !defined(ANGLE_OS_WINRT) static DWORD currentTLS = TLS_OUT_OF_INDEXES; #else static __declspec(thread) void *currentTLS = 0; #endif -namespace gl { Current *getCurrent(); } +namespace gl +{ + +Current *AllocateCurrent() +{ +#if !defined(ANGLE_OS_WINRT) + Current *current = (Current*)LocalAlloc(LPTR, sizeof(Current)); +#else + currentTLS = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(Current)); + Current *current = (Current*)currentTLS; +#endif + + if (!current) + { + ERR("Could not allocate thread local storage."); + return NULL; + } + +#if !defined(ANGLE_OS_WINRT) + ASSERT(currentTLS != TLS_OUT_OF_INDEXES); + TlsSetValue(currentTLS, current); +#endif + + current->context = NULL; + current->display = NULL; + + return current; +} + +void DeallocateCurrent() +{ +#if !defined(ANGLE_OS_WINRT) + void *current = TlsGetValue(currentTLS); + + if (current) + { + LocalFree((HLOCAL)current); + } +#else + if (currentTLS) + { + HeapFree(GetProcessHeap(), 0, currentTLS); + currentTLS = 0; + } +#endif +} + +} extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { @@ -39,48 +84,19 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved // Fall throught to initialize index case DLL_THREAD_ATTACH: { - gl::Current *current = gl::getCurrent(); - - if (current) - { -#if !defined(ANGLE_OS_WINRT) - TlsSetValue(currentTLS, current); -#endif - current->context = NULL; - current->display = NULL; - } + gl::AllocateCurrent(); } break; case DLL_THREAD_DETACH: { - gl::Current *current = gl::getCurrent(); - - if (current) - { -#if !defined(ANGLE_OS_WINRT) - LocalFree((HLOCAL)current); -#else - HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current); - currentTLS = 0; -#endif - } + gl::DeallocateCurrent(); } break; case DLL_PROCESS_DETACH: { - gl::Current *current = gl::getCurrent(); - - if (current) - { + gl::DeallocateCurrent(); #if !defined(ANGLE_OS_WINRT) - LocalFree((HLOCAL)current); - } - TlsFree(currentTLS); -#else - HeapFree(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS, current); - currentTLS = 0; - } #endif } break; @@ -91,33 +107,31 @@ extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved return TRUE; } -#endif // !QT_OPENGL_ES_2_ANGLE_STATIC - namespace gl { -Current *getCurrent() + +Current *GetCurrentData() { #ifndef QT_OPENGL_ES_2_ANGLE_STATIC #if !defined(ANGLE_OS_WINRT) Current *current = (Current*)TlsGetValue(currentTLS); - if (!current) - current = (Current*)LocalAlloc(LPTR, sizeof(Current)); - return current; #else - if (!currentTLS) - currentTLS = HeapAlloc(GetProcessHeap(), HEAP_GENERATE_EXCEPTIONS|HEAP_ZERO_MEMORY, sizeof(Current)); - return (Current*)currentTLS; + Current *current = (Current*)currentTLS; #endif #else // No precautions for thread safety taken as ANGLE is used single-threaded in Qt. - static gl::Current curr = { 0, 0 }; - return &curr; + static Current s_current = { 0, 0 }; + Current *current = &s_current; #endif + + // ANGLE issue 488: when the dll is loaded after thread initialization, + // thread local storage (current) might not exist yet. + return (current ? current : AllocateCurrent()); } void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) { - Current *current = getCurrent(); + Current *current = GetCurrentData(); current->context = context; current->display = display; @@ -130,7 +144,7 @@ void makeCurrent(Context *context, egl::Display *display, egl::Surface *surface) Context *getContext() { - Current *current = getCurrent(); + Current *current = GetCurrentData(); return current->context; } @@ -156,7 +170,7 @@ Context *getNonLostContext() egl::Display *getDisplay() { - Current *current = getCurrent(); + Current *current = GetCurrentData(); return current->display; } diff --git a/src/3rdparty/angle/src/libGLESv2/main.h b/src/3rdparty/angle/src/libGLESv2/main.h index 196afaeab6..69465c9bbf 100644 --- a/src/3rdparty/angle/src/libGLESv2/main.h +++ b/src/3rdparty/angle/src/libGLESv2/main.h @@ -10,7 +10,6 @@ #define LIBGLESV2_MAIN_H_ #include "common/debug.h" -#include "common/system.h" namespace egl { @@ -58,7 +57,7 @@ gl::Context *glCreateContext(const gl::Context *shareContext, rx::Renderer *rend void glDestroyContext(gl::Context *context); void glMakeCurrent(gl::Context *context, egl::Display *display, egl::Surface *surface); gl::Context *glGetCurrentContext(); -rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId); +rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType displayId); void glDestroyRenderer(rx::Renderer *renderer); __eglMustCastToProperFunctionPointerType __stdcall glGetProcAddress(const char *procname); diff --git a/src/3rdparty/angle/src/libGLESv2/mathutil.h b/src/3rdparty/angle/src/libGLESv2/mathutil.h index 083548669a..6474b66745 100644 --- a/src/3rdparty/angle/src/libGLESv2/mathutil.h +++ b/src/3rdparty/angle/src/libGLESv2/mathutil.h @@ -11,7 +11,6 @@ #include -#include "common/system.h" #include "common/debug.h" namespace gl diff --git a/src/3rdparty/angle/src/libGLESv2/precompiled.h b/src/3rdparty/angle/src/libGLESv2/precompiled.h index 823d27bb60..2ff09f531e 100644 --- a/src/3rdparty/angle/src/libGLESv2/precompiled.h +++ b/src/3rdparty/angle/src/libGLESv2/precompiled.h @@ -33,26 +33,53 @@ #include #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY==WINAPI_FAMILY_APP || WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP) -#define ANGLE_OS_WINRT -#if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP -#define ANGLE_OS_WINPHONE +# define ANGLE_OS_WINRT +# if WINAPI_FAMILY==WINAPI_FAMILY_PHONE_APP +# define ANGLE_OS_WINPHONE +# endif #endif + +#if defined(ANGLE_ENABLE_D3D9) +# include +#endif +#if defined(ANGLE_ENABLE_D3D11) +# if !defined(ANGLE_OS_WINRT) +# include +# else +# include +# define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE) +# define GetVersion() WINVER +# define LoadLibrary(x) LoadPackagedLibrary(x, NULL) +# endif +# include +#endif +#if !defined(ANGLE_OS_WINPHONE) +# include #endif -#ifndef ANGLE_ENABLE_D3D11 -#include -#else -#if !defined(ANGLE_OS_WINRT) -#include -#else -#include -#define Sleep(x) WaitForSingleObjectEx(GetCurrentThread(), x, FALSE) -#define GetVersion() WINVER +#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0 +#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14) +#endif +#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1 +#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0 +#endif +#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2 +#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) +#endif +#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 +#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) +#endif +#ifndef D3DCOMPILE_DEBUG +#define D3DCOMPILE_DEBUG (1 << 0) +#endif +#ifndef D3DCOMPILE_SKIP_OPTIMIZATION +#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2) #endif -#include +#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL +#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9) #endif -#ifndef ANGLE_OS_WINPHONE -#include +#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL +#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10) #endif #ifdef _MSC_VER diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp deleted file mode 100644 index 2a3ce39c63..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Blit.cpp +++ /dev/null @@ -1,595 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2010 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. -// - -// Blit.cpp: Surface copy utility class. - -#include "libGLESv2/renderer/Blit.h" - -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/TextureStorage9.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/Renderbuffer.h" - -namespace -{ -#include "libGLESv2/renderer/shaders/compiled/standardvs.h" -#include "libGLESv2/renderer/shaders/compiled/flipyvs.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughps.h" -#include "libGLESv2/renderer/shaders/compiled/luminanceps.h" -#include "libGLESv2/renderer/shaders/compiled/componentmaskps.h" - -const BYTE* const g_shaderCode[] = -{ - g_vs20_standardvs, - g_vs20_flipyvs, - g_ps20_passthroughps, - g_ps20_luminanceps, - g_ps20_componentmaskps -}; - -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) -}; -} - -namespace rx -{ -Blit::Blit(rx::Renderer9 *renderer) - : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL) -{ - initGeometry(); - memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); -} - -Blit::~Blit() -{ - if (mSavedStateBlock) mSavedStateBlock->Release(); - if (mQuadVertexBuffer) mQuadVertexBuffer->Release(); - if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release(); - - for (int i = 0; i < SHADER_COUNT; i++) - { - if (mCompiledShaders[i]) - { - mCompiledShaders[i]->Release(); - } - } -} - -void Blit::initGeometry() -{ - static const float quad[] = - { - -1, -1, - -1, 1, - 1, -1, - 1, 1 - }; - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY); - } - - void *lockPtr = NULL; - result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); - - if (FAILED(result) || lockPtr == NULL) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY); - } - - memcpy(lockPtr, quad, sizeof(quad)); - mQuadVertexBuffer->Unlock(); - - static const D3DVERTEXELEMENT9 elements[] = - { - { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, - D3DDECL_END() - }; - - result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY); - } -} - -template -bool Blit::setShader(ShaderId source, const char *profile, - D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length), - HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - D3DShaderType *shader; - - if (mCompiledShaders[source] != NULL) - { - shader = static_cast(mCompiledShaders[source]); - } - else - { - const BYTE* shaderCode = g_shaderCode[source]; - size_t shaderSize = g_shaderSize[source]; - - shader = (mRenderer->*createShader)(reinterpret_cast(shaderCode), shaderSize); - if (!shader) - { - ERR("Failed to create shader for blit operation"); - return false; - } - - mCompiledShaders[source] = shader; - } - - HRESULT hr = (device->*setShader)(shader); - - if (FAILED(hr)) - { - ERR("Failed to set shader for blit operation"); - return false; - } - - return true; -} - -bool Blit::setVertexShader(ShaderId shader) -{ - return setShader(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader); -} - -bool Blit::setPixelShader(ShaderId shader) -{ - return setShader(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader); -} - -RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const -{ - D3DSURFACE_DESC desc; - surface->GetDesc(&desc); - - RECT rect; - rect.left = 0; - rect.top = 0; - rect.right = desc.Width; - rect.bottom = desc.Height; - - return rect; -} - -bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) -{ - IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source)); - if (!texture) - { - return false; - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - saveState(); - - device->SetTexture(0, texture); - device->SetRenderTarget(0, dest); - - setVertexShader(SHADER_VS_STANDARD); - setPixelShader(SHADER_PS_PASSTHROUGH); - - setCommonBlitState(); - device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); - device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); - - setViewport(getSurfaceRect(dest), 0, 0); - - render(); - - texture->Release(); - - restoreState(); - - return true; -} - -bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) -{ - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *source = NULL; - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); - - if (colorbuffer) - { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); - } - - if (renderTarget) - { - source = renderTarget->getSurface(); - } - - if (!source) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); - IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true); - bool result = false; - - if (destSurface) - { - result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); - destSurface->Release(); - } - - source->Release(); - return result; -} - -bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) -{ - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *source = NULL; - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); - - if (colorbuffer) - { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); - } - - if (renderTarget) - { - source = renderTarget->getSurface(); - } - - if (!source) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); - IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true); - bool result = false; - - if (destSurface) - { - result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); - destSurface->Release(); - } - - source->Release(); - return result; -} - -bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) -{ - if (!dest) - { - return false; - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - D3DSURFACE_DESC sourceDesc; - D3DSURFACE_DESC destDesc; - source->GetDesc(&sourceDesc); - dest->GetDesc(&destDesc); - - if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET && - d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect - { - RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)}; - HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY, false); - } - } - else - { - return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest); - } - return true; -} - -bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) -{ - IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); - if (!texture) - { - return false; - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - saveState(); - - device->SetTexture(0, texture); - device->SetRenderTarget(0, dest); - - setViewport(sourceRect, xoffset, yoffset); - - setCommonBlitState(); - if (setFormatConvertShaders(destFormat)) - { - render(); - } - - texture->Release(); - - restoreState(); - - return true; -} - -bool Blit::setFormatConvertShaders(GLenum destFormat) -{ - bool okay = setVertexShader(SHADER_VS_STANDARD); - - switch (destFormat) - { - default: UNREACHABLE(); - case GL_RGBA: - case GL_BGRA_EXT: - case GL_RGB: - case GL_ALPHA: - okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK); - break; - - case GL_LUMINANCE: - case GL_LUMINANCE_ALPHA: - okay = okay && setPixelShader(SHADER_PS_LUMINANCE); - break; - } - - if (!okay) - { - return false; - } - - enum { X = 0, Y = 1, Z = 2, W = 3 }; - - // The meaning of this constant depends on the shader that was selected. - // See the shader assembly code above for details. - float psConst0[4] = { 0, 0, 0, 0 }; - - switch (destFormat) - { - default: UNREACHABLE(); - case GL_RGBA: - case GL_BGRA_EXT: - psConst0[X] = 1; - psConst0[Z] = 1; - break; - - case GL_RGB: - psConst0[X] = 1; - psConst0[W] = 1; - break; - - case GL_ALPHA: - psConst0[Z] = 1; - break; - - case GL_LUMINANCE: - psConst0[Y] = 1; - break; - - case GL_LUMINANCE_ALPHA: - psConst0[X] = 1; - break; - } - - mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1); - - return true; -} - -IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) -{ - if (!surface) - { - return NULL; - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - D3DSURFACE_DESC sourceDesc; - surface->GetDesc(&sourceDesc); - - // 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); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); - } - - IDirect3DSurface9 *textureSurface; - result = texture->GetSurfaceLevel(0, &textureSurface); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - texture->Release(); - return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); - } - - mRenderer->endScene(); - result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); - - textureSurface->Release(); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - texture->Release(); - return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); - } - - return texture; -} - -void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - D3DVIEWPORT9 vp; - vp.X = xoffset; - vp.Y = yoffset; - vp.Width = sourceRect.right - sourceRect.left; - vp.Height = sourceRect.bottom - sourceRect.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); -} - -void Blit::setCommonBlitState() -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - device->SetDepthStencilSurface(NULL); - - device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); - device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); - device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); - - device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); - device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - - RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle - device->SetScissorRect(&scissorRect); - - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - device->SetStreamSourceFreq(i, 1); - } -} - -void Blit::render() -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float)); - hr = device->SetVertexDeclaration(mQuadVertexDeclaration); - - mRenderer->startScene(); - hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); -} - -void Blit::saveState() -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - HRESULT hr; - - device->GetDepthStencilSurface(&mSavedDepthStencil); - device->GetRenderTarget(0, &mSavedRenderTarget); - - if (mSavedStateBlock == NULL) - { - hr = device->BeginStateBlock(); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - - setCommonBlitState(); - - static const float dummyConst[4] = { 0, 0, 0, 0 }; - - device->SetVertexShader(NULL); - device->SetVertexShaderConstantF(0, dummyConst, 1); - device->SetPixelShader(NULL); - device->SetPixelShaderConstantF(0, dummyConst, 1); - - D3DVIEWPORT9 dummyVp; - dummyVp.X = 0; - dummyVp.Y = 0; - dummyVp.Width = 1; - dummyVp.Height = 1; - dummyVp.MinZ = 0; - dummyVp.MaxZ = 1; - - device->SetViewport(&dummyVp); - - device->SetTexture(0, NULL); - - device->SetStreamSource(0, mQuadVertexBuffer, 0, 0); - - device->SetVertexDeclaration(mQuadVertexDeclaration); - - hr = device->EndStateBlock(&mSavedStateBlock); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - } - - ASSERT(mSavedStateBlock != NULL); - - if (mSavedStateBlock != NULL) - { - hr = mSavedStateBlock->Capture(); - ASSERT(SUCCEEDED(hr)); - } -} - -void Blit::restoreState() -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - device->SetDepthStencilSurface(mSavedDepthStencil); - if (mSavedDepthStencil != NULL) - { - mSavedDepthStencil->Release(); - mSavedDepthStencil = NULL; - } - - device->SetRenderTarget(0, mSavedRenderTarget); - if (mSavedRenderTarget != NULL) - { - mSavedRenderTarget->Release(); - mSavedRenderTarget = NULL; - } - - ASSERT(mSavedStateBlock != NULL); - - if (mSavedStateBlock != NULL) - { - mSavedStateBlock->Apply(); - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Blit.h b/src/3rdparty/angle/src/libGLESv2/renderer/Blit.h deleted file mode 100644 index 3718028e66..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Blit.h +++ /dev/null @@ -1,94 +0,0 @@ -// -// Copyright (c) 2002-2010 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. -// - -// Blit.cpp: Surface copy utility class. - -#ifndef LIBGLESV2_BLIT_H_ -#define LIBGLESV2_BLIT_H_ - -#include "common/angleutils.h" - -namespace gl -{ -class Framebuffer; -} - -namespace rx -{ -class Renderer9; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; - -class Blit -{ - public: - explicit Blit(Renderer9 *renderer); - ~Blit(); - - // Copy from source surface to dest surface. - // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) - bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *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. - bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); - - // 2x2 box filter sample from source to dest. - // Requires that source is RGB(A) and dest has the same format as source. - bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); - - private: - rx::Renderer9 *mRenderer; - - IDirect3DVertexBuffer9 *mQuadVertexBuffer; - IDirect3DVertexDeclaration9 *mQuadVertexDeclaration; - - void initGeometry(); - - bool setFormatConvertShaders(GLenum destFormat); - - bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); - IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect); - void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset); - void setCommonBlitState(); - RECT getSurfaceRect(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_COMPONENTMASK, - SHADER_COUNT - }; - - // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown. - IUnknown *mCompiledShaders[SHADER_COUNT]; - - template - bool setShader(ShaderId source, const char *profile, - D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length), - HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)); - - bool setVertexShader(ShaderId shader); - bool setPixelShader(ShaderId shader); - void render(); - - void saveState(); - void restoreState(); - IDirect3DStateBlock9 *mSavedStateBlock; - IDirect3DSurface9 *mSavedRenderTarget; - IDirect3DSurface9 *mSavedDepthStencil; - - DISALLOW_COPY_AND_ASSIGN(Blit); -}; -} - -#endif // LIBGLESV2_BLIT_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h index 14a8c2765b..ace1a11bae 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage.h @@ -22,7 +22,7 @@ class BufferStorage // The data returned is only guaranteed valid until next non-const method. virtual void *getData() = 0; - virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target) = 0; + virtual void setData(const void* data, unsigned int size, unsigned int offset) = 0; virtual void clear() = 0; virtual unsigned int getSize() const = 0; virtual bool supportsDirectBinding() const = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp deleted file mode 100644 index 2f694db061..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.cpp +++ /dev/null @@ -1,361 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// BufferStorage11.cpp Defines the BufferStorage11 class. - -#include "libGLESv2/renderer/BufferStorage11.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/Renderer11.h" - -namespace rx -{ - -BufferStorage11::BufferStorage11(Renderer11 *renderer) -{ - mRenderer = renderer; - - mStagingBuffer = NULL; - mStagingBufferSize = 0; - - mBuffer = NULL; - mBufferSize = 0; - - mSize = 0; - - mResolvedData = NULL; - mResolvedDataSize = 0; - mResolvedDataValid = false; - - mReadUsageCount = 0; - mWriteUsageCount = 0; -} - -BufferStorage11::~BufferStorage11() -{ - if (mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - } - - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } - - if (mResolvedData) - { - free(mResolvedData); - mResolvedData = NULL; - } -} - -BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage) -{ - ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage)); - return static_cast(bufferStorage); -} - -void *BufferStorage11::getData() -{ - if (!mResolvedDataValid) - { - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - HRESULT result; - - if (!mStagingBuffer || mStagingBufferSize < mBufferSize) - { - if (mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - mStagingBufferSize = 0; - } - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = mSize; - bufferDesc.Usage = D3D11_USAGE_STAGING; - bufferDesc.BindFlags = 0; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); - } - - mStagingBufferSize = bufferDesc.ByteWidth; - } - - if (!mResolvedData || mResolvedDataSize < mBufferSize) - { - free(mResolvedData); - mResolvedData = malloc(mSize); - mResolvedDataSize = mSize; - } - - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = mSize; - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - context->CopySubresourceRegion(mStagingBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = context->Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); - } - - memcpy(mResolvedData, mappedResource.pData, mSize); - - context->Unmap(mStagingBuffer, 0); - - mResolvedDataValid = true; - } - - mReadUsageCount = 0; - - return mResolvedData; -} - -void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset, unsigned int target) -{ - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - HRESULT result; - - unsigned int requiredBufferSize = size + offset; - unsigned int requiredStagingSize = size; - bool directInitialization = offset == 0 && (!mBuffer || mBufferSize < size + offset); - - if (!directInitialization) - { - if (!mStagingBuffer || mStagingBufferSize < requiredStagingSize) - { - if (mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - mStagingBufferSize = 0; - } - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = size; - bufferDesc.Usage = D3D11_USAGE_STAGING; - bufferDesc.BindFlags = 0; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - if (data) - { - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = data; - initialData.SysMemPitch = size; - initialData.SysMemSlicePitch = 0; - - result = device->CreateBuffer(&bufferDesc, &initialData, &mStagingBuffer); - } - else - { - result = device->CreateBuffer(&bufferDesc, NULL, &mStagingBuffer); - } - - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - - mStagingBufferSize = size; - } - else if (data) - { - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - - memcpy(mappedResource.pData, data, size); - - context->Unmap(mStagingBuffer, 0); - } - } - - if (!mBuffer || mBufferSize < size + offset) - { - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = requiredBufferSize; - bufferDesc.Usage = D3D11_USAGE_DEFAULT; - if (mRenderer->getFeatureLevel() > D3D_FEATURE_LEVEL_9_3) - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER | D3D11_BIND_INDEX_BUFFER; - else - bufferDesc.BindFlags = target == GL_ARRAY_BUFFER ? D3D11_BIND_VERTEX_BUFFER : D3D11_BIND_INDEX_BUFFER; - bufferDesc.CPUAccessFlags = 0; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - if (directInitialization) - { - // Since the data will fill the entire buffer (being larger than the initial size and having - // no offset), the buffer can be initialized with the data so no staging buffer is required - - // No longer need the old buffer - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - mBufferSize = 0; - } - - if (data) - { - D3D11_SUBRESOURCE_DATA initialData; - initialData.pSysMem = data; - initialData.SysMemPitch = size; - initialData.SysMemSlicePitch = 0; - - result = device->CreateBuffer(&bufferDesc, &initialData, &mBuffer); - } - else - { - result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer); - } - - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - else if (mBuffer && offset > 0) - { - // If offset is greater than zero and the buffer is non-null, need to preserve the data from - // the old buffer up to offset - ID3D11Buffer *newBuffer = NULL; - - result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = std::min(offset, mBufferSize); - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - context->CopySubresourceRegion(newBuffer, 0, 0, 0, 0, mBuffer, 0, &srcBox); - - mBuffer->Release(); - mBuffer = newBuffer; - } - else - { - // Simple case, nothing needs to be copied from the old buffer to the new one, just create - // a new buffer - - // No longer need the old buffer - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - mBufferSize = 0; - } - - // Create a new buffer for data storage - result = device->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - updateSerial(); - mBufferSize = bufferDesc.ByteWidth; - } - - if (!directInitialization) - { - ASSERT(mStagingBuffer && mStagingBufferSize >= requiredStagingSize); - - // Data is already put into the staging buffer, copy it over to the data buffer - D3D11_BOX srcBox; - srcBox.left = 0; - srcBox.right = size; - srcBox.top = 0; - srcBox.bottom = 1; - srcBox.front = 0; - srcBox.back = 1; - - context->CopySubresourceRegion(mBuffer, 0, offset, 0, 0, mStagingBuffer, 0, &srcBox); - } - - mSize = std::max(mSize, offset + size); - - mWriteUsageCount = 0; - - mResolvedDataValid = false; -} - -void BufferStorage11::clear() -{ - mResolvedDataValid = false; - mSize = 0; -} - -unsigned int BufferStorage11::getSize() const -{ - return mSize; -} - -bool BufferStorage11::supportsDirectBinding() const -{ - return mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0; -} - -void BufferStorage11::markBufferUsage() -{ - mReadUsageCount++; - mWriteUsageCount++; - - static const unsigned int usageLimit = 5; - - if (mReadUsageCount > usageLimit && mResolvedData) - { - free(mResolvedData); - mResolvedData = NULL; - mResolvedDataSize = 0; - mResolvedDataValid = false; - } - - if (mReadUsageCount > usageLimit && mWriteUsageCount > usageLimit && mStagingBuffer) - { - mStagingBuffer->Release(); - mStagingBuffer = NULL; - mStagingBufferSize = 0; - } -} - -ID3D11Buffer *BufferStorage11::getBuffer() const -{ - return mBuffer; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h deleted file mode 100644 index c9489627c3..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage11.h +++ /dev/null @@ -1,56 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// BufferStorage11.h Defines the BufferStorage11 class. - -#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ -#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ - -#include "libGLESv2/renderer/BufferStorage.h" - -namespace rx -{ -class Renderer11; - -class BufferStorage11 : public BufferStorage -{ - public: - explicit BufferStorage11(Renderer11 *renderer); - virtual ~BufferStorage11(); - - static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage); - - virtual void *getData(); - virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target); - virtual void clear(); - virtual unsigned int getSize() const; - virtual bool supportsDirectBinding() const; - virtual void markBufferUsage(); - - ID3D11Buffer *getBuffer() const; - - private: - Renderer11 *mRenderer; - - ID3D11Buffer *mStagingBuffer; - unsigned int mStagingBufferSize; - - ID3D11Buffer *mBuffer; - unsigned int mBufferSize; - - unsigned int mSize; - - void *mResolvedData; - unsigned int mResolvedDataSize; - bool mResolvedDataValid; - - unsigned int mReadUsageCount; - unsigned int mWriteUsageCount; -}; - -} - -#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp deleted file mode 100644 index 57fd29bf80..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.cpp +++ /dev/null @@ -1,78 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// BufferStorage9.cpp Defines the BufferStorage9 class. - -#include "libGLESv2/renderer/BufferStorage9.h" -#include "common/debug.h" - -namespace rx -{ - -BufferStorage9::BufferStorage9() -{ - mMemory = NULL; - mAllocatedSize = 0; - mSize = 0; -} - -BufferStorage9::~BufferStorage9() -{ - delete[] mMemory; -} - -BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage) -{ - ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage)); - return static_cast(bufferStorage); -} - -void *BufferStorage9::getData() -{ - return mMemory; -} - -void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset, unsigned int) -{ - if (!mMemory || offset + size > mAllocatedSize) - { - unsigned int newAllocatedSize = offset + size; - void *newMemory = new char[newAllocatedSize]; - - if (offset > 0 && mMemory && mAllocatedSize > 0) - { - memcpy(newMemory, mMemory, std::min(offset, mAllocatedSize)); - } - - delete[] mMemory; - mMemory = newMemory; - mAllocatedSize = newAllocatedSize; - } - - mSize = std::max(mSize, offset + size); - if (data) - { - memcpy(reinterpret_cast(mMemory) + offset, data, size); - } -} - -void BufferStorage9::clear() -{ - mSize = 0; -} - -unsigned int BufferStorage9::getSize() const -{ - return mSize; -} - -bool BufferStorage9::supportsDirectBinding() const -{ - return false; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h deleted file mode 100644 index 82ae577e23..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/BufferStorage9.h +++ /dev/null @@ -1,42 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// BufferStorage9.h Defines the BufferStorage9 class. - -#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_ -#define LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_ - -#include "libGLESv2/renderer/BufferStorage.h" - -namespace rx -{ - -class BufferStorage9 : public BufferStorage -{ - public: - BufferStorage9(); - virtual ~BufferStorage9(); - - static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage); - - virtual void *getData(); - virtual void setData(const void* data, unsigned int size, unsigned int offset, unsigned int target = 0); - virtual void clear(); - virtual unsigned int getSize() const; - virtual bool supportsDirectBinding() const; - - private: - DISALLOW_COPY_AND_ASSIGN(BufferStorage9); - - void *mMemory; - unsigned int mAllocatedSize; - - unsigned int mSize; -}; - -} - -#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp deleted file mode 100644 index 9d11c9a0fc..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.cpp +++ /dev/null @@ -1,134 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. - -#include "libGLESv2/renderer/Fence11.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/Renderer11.h" - -namespace rx -{ - -Fence11::Fence11(rx::Renderer11 *renderer) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Fence11::~Fence11() -{ - if (mQuery) - { - mQuery->Release(); - mQuery = NULL; - } -} - -GLboolean Fence11::isFence() -{ - // GL_NV_fence spec: - // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. - return mQuery != NULL; -} - -void Fence11::setFence(GLenum condition) -{ - if (!mQuery) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_EVENT; - queryDesc.MiscFlags = 0; - - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - mRenderer->getDeviceContext()->End(mQuery); - - setCondition(condition); - setStatus(GL_FALSE); -} - -GLboolean Fence11::testFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION, GL_TRUE); - } - - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0); - - if (mRenderer->isDeviceLost()) - { - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - return getStatus(); -} - -void Fence11::finishFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - while (!testFence()) - { - Sleep(0); - } -} - -void Fence11::getFenceiv(GLenum pname, GLint *params) -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - switch (pname) - { - case GL_FENCE_STATUS_NV: - { - // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. - if (getStatus()) - { - params[0] = GL_TRUE; - return; - } - - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); - - if (mRenderer->isDeviceLost()) - { - params[0] = GL_TRUE; - return gl::error(GL_OUT_OF_MEMORY); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - params[0] = getStatus(); - - break; - } - case GL_FENCE_CONDITION_NV: - params[0] = getCondition(); - break; - default: - return gl::error(GL_INVALID_ENUM); - break; - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h deleted file mode 100644 index a5398bca14..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Fence11.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl. - -#ifndef LIBGLESV2_RENDERER_Fence11_H_ -#define LIBGLESV2_RENDERER_Fence11_H_ - -#include "libGLESv2/renderer/FenceImpl.h" - -namespace rx -{ -class Renderer11; - -class Fence11 : public FenceImpl -{ - public: - explicit Fence11(rx::Renderer11 *renderer); - virtual ~Fence11(); - - GLboolean isFence(); - void setFence(GLenum condition); - GLboolean testFence(); - void finishFence(); - void getFenceiv(GLenum pname, GLint *params); - - private: - DISALLOW_COPY_AND_ASSIGN(Fence11); - - rx::Renderer11 *mRenderer; - ID3D11Query *mQuery; -}; - -} - -#endif // LIBGLESV2_RENDERER_FENCE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp deleted file mode 100644 index 86064d7e52..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.cpp +++ /dev/null @@ -1,135 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Fence9.cpp: Defines the rx::Fence9 class. - -#include "libGLESv2/renderer/Fence9.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/Renderer9.h" - -namespace rx -{ - -Fence9::Fence9(rx::Renderer9 *renderer) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Fence9::~Fence9() -{ - if (mQuery) - { - mRenderer->freeEventQuery(mQuery); - mQuery = NULL; - } -} - -GLboolean Fence9::isFence() -{ - // GL_NV_fence spec: - // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. - return mQuery != NULL; -} - -void Fence9::setFence(GLenum condition) -{ - if (!mQuery) - { - mQuery = mRenderer->allocateEventQuery(); - if (!mQuery) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - HRESULT result = mQuery->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); - - setCondition(condition); - setStatus(GL_FALSE); -} - -GLboolean Fence9::testFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION, GL_TRUE); - } - - HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); - - if (d3d9::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - return getStatus(); -} - -void Fence9::finishFence() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - while (!testFence()) - { - Sleep(0); - } -} - -void Fence9::getFenceiv(GLenum pname, GLint *params) -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - switch (pname) - { - case GL_FENCE_STATUS_NV: - { - // GL_NV_fence spec: - // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV - // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. - if (getStatus()) - { - params[0] = GL_TRUE; - return; - } - - HRESULT result = mQuery->GetData(NULL, 0, 0); - - if (d3d9::isDeviceLostError(result)) - { - params[0] = GL_TRUE; - mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY); - } - - ASSERT(result == S_OK || result == S_FALSE); - setStatus(result == S_OK); - params[0] = getStatus(); - - break; - } - case GL_FENCE_CONDITION_NV: - params[0] = getCondition(); - break; - default: - return gl::error(GL_INVALID_ENUM); - break; - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h deleted file mode 100644 index 9f17641e51..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Fence9.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl. - -#ifndef LIBGLESV2_RENDERER_FENCE9_H_ -#define LIBGLESV2_RENDERER_FENCE9_H_ - -#include "libGLESv2/renderer/FenceImpl.h" - -namespace rx -{ -class Renderer9; - -class Fence9 : public FenceImpl -{ - public: - explicit Fence9(rx::Renderer9 *renderer); - virtual ~Fence9(); - - GLboolean isFence(); - void setFence(GLenum condition); - GLboolean testFence(); - void finishFence(); - void getFenceiv(GLenum pname, GLint *params); - - private: - DISALLOW_COPY_AND_ASSIGN(Fence9); - - rx::Renderer9 *mRenderer; - IDirect3DQuery9 *mQuery; -}; - -} - -#endif // LIBGLESV2_RENDERER_FENCE9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp deleted file mode 100644 index 81e9e9ecb2..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.cpp +++ /dev/null @@ -1,460 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// Image11.h: Implements the rx::Image11 class, which acts as the interface to -// the actual underlying resources of a Texture - -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/Image11.h" -#include "libGLESv2/renderer/TextureStorage11.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/Renderbuffer.h" - -#include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/renderer/generatemip.h" - -namespace rx -{ - -Image11::Image11() -{ - mStagingTexture = NULL; - mRenderer = NULL; - mDXGIFormat = DXGI_FORMAT_UNKNOWN; -} - -Image11::~Image11() -{ - if (mStagingTexture) - { - mStagingTexture->Release(); - } -} - -Image11 *Image11::makeImage11(Image *img) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img)); - return static_cast(img); -} - -void Image11::generateMipmap(Image11 *dest, Image11 *src) -{ - ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); - ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); - ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); - - D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped; - dest->map(D3D11_MAP_WRITE, &destMapped); - src->map(D3D11_MAP_READ, &srcMapped); - - const unsigned char *sourceData = reinterpret_cast(srcMapped.pData); - unsigned char *destData = reinterpret_cast(destMapped.pData); - - if (sourceData && destData) - { - switch (src->getDXGIFormat()) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_A8_UNORM: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R8_UNORM: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32G32B32_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R8G8_UNORM: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R16_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R16G16_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - case DXGI_FORMAT_R32G32_FLOAT: - GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); - break; - default: - UNREACHABLE(); - break; - } - - dest->unmap(); - src->unmap(); - } - - dest->markDirty(); -} - -bool Image11::isDirty() const -{ - return (mStagingTexture && mDirty); -} - -bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height); -} - -bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); - return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height); -} - -bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) -{ - if (mWidth != width || - mHeight != height || - mInternalFormat != internalformat || - forceRelease) - { - mRenderer = Renderer11::makeRenderer11(renderer); - - mWidth = width; - mHeight = height; - mInternalFormat = internalformat; - // compute the d3d format that will be used - mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel()); - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat); - - if (mStagingTexture) - { - mStagingTexture->Release(); - mStagingTexture = NULL; - } - - return true; - } - - return false; -} - -bool Image11::isRenderableFormat() const -{ - return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat); -} - -DXGI_FORMAT Image11::getDXGIFormat() const -{ - // this should only happen if the image hasn't been redefined first - // which would be a bug by the caller - ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN); - - return mDXGIFormat; -} - -// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input -// into the target pixel rectangle. -void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input) -{ - D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) - { - ERR("Could not map image for loading."); - return; - } - - GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); - size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8; - void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize)); - - switch (mInternalFormat) - { - case GL_ALPHA8_EXT: - if (mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) - loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - else - loadAlphaDataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE8_EXT: - loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); - break; - case GL_ALPHA32F_EXT: - loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE32F_EXT: - loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_ALPHA16F_EXT: - loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE16F_EXT: - loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE8_ALPHA8_EXT: - loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); - break; - case GL_LUMINANCE_ALPHA32F_EXT: - loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_LUMINANCE_ALPHA16F_EXT: - loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB8_OES: - loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB565: - loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA8_OES: - loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA4: - loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB5_A1: - loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_BGRA8_EXT: - loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB32F_EXT: - loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGB16F_EXT: - loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA32F_EXT: - loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - case GL_RGBA16F_EXT: - loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); - break; - default: UNREACHABLE(); - } - - unmap(); -} - -void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - const void *input) -{ - ASSERT(xoffset % 4 == 0); - ASSERT(yoffset % 4 == 0); - - D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - if (FAILED(result)) - { - ERR("Could not map image for loading."); - return; - } - - // Size computation assumes a 4x4 block compressed texture format - size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8; - void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize)); - - GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); - GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); - int rows = inputSize / inputPitch; - for (int i = 0; i < rows; ++i) - { - memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); - } - - unmap(); -} - -void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) -{ - gl::Renderbuffer *colorbuffer = source->getReadColorbuffer(); - - if (colorbuffer && colorbuffer->getActualFormat() == (GLuint)mActualFormat) - { - // No conversion needed-- use copyback fastpath - ID3D11Texture2D *colorBufferTexture = NULL; - unsigned int subresourceIndex = 0; - - if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) - { - D3D11_TEXTURE2D_DESC textureDesc; - colorBufferTexture->GetDesc(&textureDesc); - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - - ID3D11Texture2D* srcTex = NULL; - if (textureDesc.SampleDesc.Count > 1) - { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); - if (FAILED(result)) - { - ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); - return; - } - - deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); - subresourceIndex = 0; - } - else - { - srcTex = colorBufferTexture; - srcTex->AddRef(); - } - - D3D11_BOX srcBox; - srcBox.left = x; - srcBox.right = x + width; - srcBox.top = y; - srcBox.bottom = y + height; - srcBox.front = 0; - srcBox.back = 1; - - deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox); - - srcTex->Release(); - colorBufferTexture->Release(); - } - } - else - { - // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels - D3D11_MAPPED_SUBRESOURCE mappedImage; - HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); - - // determine the offset coordinate into the destination buffer - GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset; - void *dataOffset = static_cast(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset; - - mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat), - gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset); - - unmap(); - } -} - -ID3D11Texture2D *Image11::getStagingTexture() -{ - createStagingTexture(); - - return mStagingTexture; -} - -unsigned int Image11::getStagingSubresource() -{ - createStagingTexture(); - - return mStagingSubresource; -} - -void Image11::createStagingTexture() -{ - if (mStagingTexture) - { - return; - } - - ID3D11Texture2D *newTexture = NULL; - int lodOffset = 1; - const DXGI_FORMAT dxgiFormat = getDXGIFormat(); - ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures - - if (mWidth != 0 && mHeight != 0) - { - GLsizei width = mWidth; - GLsizei height = mHeight; - - // adjust size if needed for compressed textures - gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset); - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = lodOffset + 1; - desc.ArraySize = 1; - desc.Format = dxgiFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_STAGING; - desc.BindFlags = 0; - desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture); - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - mStagingTexture = newTexture; - mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); - mDirty = false; -} - -HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) -{ - createStagingTexture(); - - HRESULT result = E_FAIL; - - if (mStagingTexture) - { - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); - - // this can fail if the device is removed (from TDR) - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - } - else if (SUCCEEDED(result)) - { - mDirty = true; - } - } - - return result; -} - -void Image11::unmap() -{ - if (mStagingTexture) - { - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - deviceContext->Unmap(mStagingTexture, mStagingSubresource); - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h deleted file mode 100644 index 11a6492dc8..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image11.h +++ /dev/null @@ -1,76 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// Image11.h: Defines the rx::Image11 class, which acts as the interface to -// the actual underlying resources of a Texture - -#ifndef LIBGLESV2_RENDERER_IMAGE11_H_ -#define LIBGLESV2_RENDERER_IMAGE11_H_ - -#include "libGLESv2/renderer/Image.h" - -#include "common/debug.h" - -namespace gl -{ -class Framebuffer; -} - -namespace rx -{ -class Renderer; -class Renderer11; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; - -class Image11 : public Image -{ - public: - Image11(); - virtual ~Image11(); - - static Image11 *makeImage11(Image *img); - - static void generateMipmap(Image11 *dest, Image11 *src); - - virtual bool isDirty() const; - - virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - - virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease); - - virtual bool isRenderableFormat() const; - DXGI_FORMAT getDXGIFormat() const; - - virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - const void *input); - - virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - - protected: - HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); - void unmap(); - - private: - DISALLOW_COPY_AND_ASSIGN(Image11); - - ID3D11Texture2D *getStagingTexture(); - unsigned int getStagingSubresource(); - void createStagingTexture(); - - Renderer11 *mRenderer; - - DXGI_FORMAT mDXGIFormat; - ID3D11Texture2D *mStagingTexture; - unsigned int mStagingSubresource; -}; - -} - -#endif // LIBGLESV2_RENDERER_IMAGE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp deleted file mode 100644 index 53030b7f1e..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.cpp +++ /dev/null @@ -1,736 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2012 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. -// - -// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to -// the actual underlying surfaces of a Texture. - -#include "libGLESv2/renderer/Image9.h" - -#include "libGLESv2/main.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/TextureStorage9.h" - -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/generatemip.h" - -namespace rx -{ - -Image9::Image9() -{ - mSurface = NULL; - mRenderer = NULL; - - mD3DPool = D3DPOOL_SYSTEMMEM; - mD3DFormat = D3DFMT_UNKNOWN; -} - -Image9::~Image9() -{ - if (mSurface) - { - mSurface->Release(); - } -} - -void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface) -{ - D3DSURFACE_DESC destDesc; - HRESULT result = destSurface->GetDesc(&destDesc); - ASSERT(SUCCEEDED(result)); - - D3DSURFACE_DESC sourceDesc; - result = sourceSurface->GetDesc(&sourceDesc); - ASSERT(SUCCEEDED(result)); - - ASSERT(sourceDesc.Format == destDesc.Format); - ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); - ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); - - D3DLOCKED_RECT sourceLocked = {0}; - result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); - ASSERT(SUCCEEDED(result)); - - D3DLOCKED_RECT destLocked = {0}; - result = destSurface->LockRect(&destLocked, NULL, 0); - ASSERT(SUCCEEDED(result)); - - const unsigned char *sourceData = reinterpret_cast(sourceLocked.pBits); - unsigned char *destData = reinterpret_cast(destLocked.pBits); - - if (sourceData && destData) - { - switch (sourceDesc.Format) - { - case D3DFMT_L8: - GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A8L8: - GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A16B16G16R16F: - GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - case D3DFMT_A32B32G32R32F: - GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); - break; - default: - UNREACHABLE(); - break; - } - - destSurface->UnlockRect(); - sourceSurface->UnlockRect(); - } -} - -Image9 *Image9::makeImage9(Image *img) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img)); - return static_cast(img); -} - -void Image9::generateMipmap(Image9 *dest, Image9 *source) -{ - IDirect3DSurface9 *sourceSurface = source->getSurface(); - if (sourceSurface == NULL) - return gl::error(GL_OUT_OF_MEMORY); - - IDirect3DSurface9 *destSurface = dest->getSurface(); - generateMip(destSurface, sourceSurface); - - dest->markDirty(); -} - -void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) -{ - D3DLOCKED_RECT sourceLock = {0}; - D3DLOCKED_RECT destLock = {0}; - - source->LockRect(&sourceLock, NULL, 0); - dest->LockRect(&destLock, NULL, 0); - - if (sourceLock.pBits && destLock.pBits) - { - D3DSURFACE_DESC desc; - source->GetDesc(&desc); - - int rows = d3d9::IsCompressedFormat(desc.Format) ? desc.Height / 4 : desc.Height; - int bytes = d3d9::ComputeRowSize(desc.Format, desc.Width); - ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch); - - for(int i = 0; i < rows; i++) - { - memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); - } - - source->UnlockRect(); - dest->UnlockRect(); - } - else UNREACHABLE(); -} - -bool Image9::redefine(rx::Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) -{ - if (mWidth != width || - mHeight != height || - mInternalFormat != internalformat || - forceRelease) - { - mRenderer = Renderer9::makeRenderer9(renderer); - - mWidth = width; - mHeight = height; - mInternalFormat = internalformat; - // compute the d3d format that will be used - mD3DFormat = mRenderer->ConvertTextureInternalFormat(internalformat); - mActualFormat = d3d9_gl::GetEquivalentFormat(mD3DFormat); - - if (mSurface) - { - mSurface->Release(); - mSurface = NULL; - } - - return true; - } - - return false; -} - -void Image9::createSurface() -{ - if(mSurface) - { - return; - } - - IDirect3DTexture9 *newTexture = NULL; - IDirect3DSurface9 *newSurface = NULL; - const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; - const D3DFORMAT d3dFormat = getD3DFormat(); - ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures - - if (mWidth != 0 && mHeight != 0) - { - int levelToFetch = 0; - GLsizei requestWidth = mWidth; - GLsizei requestHeight = mHeight; - gl::MakeValidSize(true, gl::IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch); - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat, - poolToUse, &newTexture, NULL); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - ERR("Creating image surface failed."); - return gl::error(GL_OUT_OF_MEMORY); - } - - newTexture->GetSurfaceLevel(levelToFetch, &newSurface); - newTexture->Release(); - } - - mSurface = newSurface; - mDirty = false; - mD3DPool = poolToUse; -} - -HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect) -{ - createSurface(); - - HRESULT result = D3DERR_INVALIDCALL; - - if (mSurface) - { - result = mSurface->LockRect(lockedRect, rect, 0); - ASSERT(SUCCEEDED(result)); - - mDirty = true; - } - - return result; -} - -void Image9::unlock() -{ - if (mSurface) - { - HRESULT result = mSurface->UnlockRect(); - ASSERT(SUCCEEDED(result)); - } -} - -bool Image9::isRenderableFormat() const -{ - return TextureStorage9::IsTextureFormatRenderable(getD3DFormat()); -} - -D3DFORMAT Image9::getD3DFormat() const -{ - // this should only happen if the image hasn't been redefined first - // which would be a bug by the caller - ASSERT(mD3DFormat != D3DFMT_UNKNOWN); - - return mD3DFormat; -} - -IDirect3DSurface9 *Image9::getSurface() -{ - createSurface(); - - return mSurface; -} - -void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level) -{ - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); - setManagedSurface(storage9->getSurfaceLevel(level, false)); -} - -void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) -{ - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); - setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false)); -} - -void Image9::setManagedSurface(IDirect3DSurface9 *surface) -{ - D3DSURFACE_DESC desc; - surface->GetDesc(&desc); - ASSERT(desc.Pool == D3DPOOL_MANAGED); - - if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight) - { - if (mSurface) - { - copyLockableSurfaces(surface, mSurface); - mSurface->Release(); - } - - mSurface = surface; - mD3DPool = desc.Pool; - } -} - -bool Image9::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - ASSERT(getSurface() != NULL); - TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); - return updateSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); -} - -bool Image9::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - ASSERT(getSurface() != NULL); - TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); - return updateSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height); -} - -bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) -{ - if (!destSurface) - return false; - - IDirect3DSurface9 *sourceSurface = getSurface(); - - if (sourceSurface && sourceSurface != destSurface) - { - RECT rect; - rect.left = xoffset; - rect.top = yoffset; - rect.right = xoffset + width; - rect.bottom = yoffset + height; - - POINT point = {rect.left, rect.top}; - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - if (mD3DPool == D3DPOOL_MANAGED) - { - D3DSURFACE_DESC desc; - sourceSurface->GetDesc(&desc); - - IDirect3DSurface9 *surf = 0; - HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); - - if (SUCCEEDED(result)) - { - copyLockableSurfaces(surf, sourceSurface); - result = device->UpdateSurface(surf, &rect, destSurface, &point); - ASSERT(SUCCEEDED(result)); - surf->Release(); - } - } - else - { - // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools - HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); - ASSERT(SUCCEEDED(result)); - } - } - - destSurface->Release(); - return true; -} - -// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input -// into the target pixel rectangle. -void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input) -{ - RECT lockRect = - { - xoffset, yoffset, - xoffset + width, yoffset + height - }; - - D3DLOCKED_RECT locked; - HRESULT result = lock(&locked, &lockRect); - if (FAILED(result)) - { - return; - } - - - GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); - - switch (mInternalFormat) - { - case GL_ALPHA8_EXT: -#if defined(__SSE2__) - if (gl::supportsSSE2()) - { - loadAlphaDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - else -#endif - { - loadAlphaDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - break; - case GL_LUMINANCE8_EXT: - loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8); - break; - case GL_ALPHA32F_EXT: - loadAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE32F_EXT: - loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_ALPHA16F_EXT: - loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE16F_EXT: - loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE8_ALPHA8_EXT: - loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8); - break; - case GL_LUMINANCE_ALPHA32F_EXT: - loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_LUMINANCE_ALPHA16F_EXT: - loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB8_OES: - loadRGBUByteDataToBGRX(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB565: - loadRGB565DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGBA8_OES: -#if defined(__SSE2__) - if (gl::supportsSSE2()) - { - loadRGBAUByteDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - else -#endif - { - loadRGBAUByteDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - } - break; - case GL_RGBA4: - loadRGBA4444DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB5_A1: - loadRGBA5551DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_BGRA8_EXT: - loadBGRADataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D - case GL_RGB32F_EXT: - loadRGBFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGB16F_EXT: - loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGBA32F_EXT: - loadRGBAFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - case GL_RGBA16F_EXT: - loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); - break; - default: UNREACHABLE(); - } - - unlock(); -} - -void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - const void *input) -{ - ASSERT(xoffset % 4 == 0); - ASSERT(yoffset % 4 == 0); - - RECT lockRect = { - xoffset, yoffset, - xoffset + width, yoffset + height - }; - - D3DLOCKED_RECT locked; - HRESULT result = lock(&locked, &lockRect); - if (FAILED(result)) - { - return; - } - - GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); - GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); - int rows = inputSize / inputPitch; - for (int i = 0; i < rows; ++i) - { - memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); - } - - unlock(); -} - -// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures -void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) -{ - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *surface = NULL; - gl::Renderbuffer *colorbuffer = source->getColorbuffer(0); - - if (colorbuffer) - { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); - } - - if (renderTarget) - { - surface = renderTarget->getSurface(); - } - - if (!surface) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY); - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - IDirect3DSurface9 *renderTargetData = NULL; - D3DSURFACE_DESC description; - surface->GetDesc(&description); - - HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); - - if (FAILED(result)) - { - ERR("Could not create matching destination surface."); - surface->Release(); - return gl::error(GL_OUT_OF_MEMORY); - } - - result = device->GetRenderTargetData(surface, renderTargetData); - - if (FAILED(result)) - { - ERR("GetRenderTargetData unexpectedly failed."); - renderTargetData->Release(); - surface->Release(); - return gl::error(GL_OUT_OF_MEMORY); - } - - RECT sourceRect = {x, y, x + width, y + height}; - RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height}; - - D3DLOCKED_RECT sourceLock = {0}; - result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0); - - if (FAILED(result)) - { - ERR("Failed to lock the source surface (rectangle might be invalid)."); - renderTargetData->Release(); - surface->Release(); - return gl::error(GL_OUT_OF_MEMORY); - } - - D3DLOCKED_RECT destLock = {0}; - result = lock(&destLock, &destRect); - - if (FAILED(result)) - { - ERR("Failed to lock the destination surface (rectangle might be invalid)."); - renderTargetData->UnlockRect(); - renderTargetData->Release(); - surface->Release(); - return gl::error(GL_OUT_OF_MEMORY); - } - - if (destLock.pBits && sourceLock.pBits) - { - unsigned char *source = (unsigned char*)sourceLock.pBits; - unsigned char *dest = (unsigned char*)destLock.pBits; - - switch (description.Format) - { - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - switch(getD3DFormat()) - { - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - for(int y = 0; y < height; y++) - { - memcpy(dest, source, 4 * width); - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - dest[x] = source[x * 4 + 2]; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_A8L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - dest[x * 2 + 0] = source[x * 4 + 2]; - dest[x * 2 + 1] = source[x * 4 + 3]; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); - } - break; - case D3DFMT_R5G6B5: - switch(getD3DFormat()) - { - case D3DFMT_X8R8G8B8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned short rgb = ((unsigned short*)source)[x]; - unsigned char red = (rgb & 0xF800) >> 8; - unsigned char green = (rgb & 0x07E0) >> 3; - unsigned char blue = (rgb & 0x001F) << 3; - dest[x + 0] = blue | (blue >> 5); - dest[x + 1] = green | (green >> 6); - dest[x + 2] = red | (red >> 5); - dest[x + 3] = 0xFF; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned char red = source[x * 2 + 1] & 0xF8; - dest[x] = red | (red >> 5); - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); - } - break; - case D3DFMT_A1R5G5B5: - switch(getD3DFormat()) - { - case D3DFMT_X8R8G8B8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned short argb = ((unsigned short*)source)[x]; - unsigned char red = (argb & 0x7C00) >> 7; - unsigned char green = (argb & 0x03E0) >> 2; - unsigned char blue = (argb & 0x001F) << 3; - dest[x + 0] = blue | (blue >> 5); - dest[x + 1] = green | (green >> 5); - dest[x + 2] = red | (red >> 5); - dest[x + 3] = 0xFF; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_A8R8G8B8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned short argb = ((unsigned short*)source)[x]; - unsigned char red = (argb & 0x7C00) >> 7; - unsigned char green = (argb & 0x03E0) >> 2; - unsigned char blue = (argb & 0x001F) << 3; - unsigned char alpha = (signed short)argb >> 15; - dest[x + 0] = blue | (blue >> 5); - dest[x + 1] = green | (green >> 5); - dest[x + 2] = red | (red >> 5); - dest[x + 3] = alpha; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned char red = source[x * 2 + 1] & 0x7C; - dest[x] = (red << 1) | (red >> 4); - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - case D3DFMT_A8L8: - for(int y = 0; y < height; y++) - { - for(int x = 0; x < width; x++) - { - unsigned char red = source[x * 2 + 1] & 0x7C; - dest[x * 2 + 0] = (red << 1) | (red >> 4); - dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7; - } - - source += sourceLock.Pitch; - dest += destLock.Pitch; - } - break; - default: - UNREACHABLE(); - } - break; - default: - UNREACHABLE(); - } - } - - unlock(); - renderTargetData->UnlockRect(); - - renderTargetData->Release(); - surface->Release(); - - mDirty = true; -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Image9.h deleted file mode 100644 index 2fbbca3124..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Image9.h +++ /dev/null @@ -1,79 +0,0 @@ -// -// Copyright (c) 2002-2012 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. -// - -// Image9.h: Defines the rx::Image9 class, which acts as the interface to -// the actual underlying surfaces of a Texture. - -#ifndef LIBGLESV2_RENDERER_IMAGE9_H_ -#define LIBGLESV2_RENDERER_IMAGE9_H_ - -#include "libGLESv2/renderer/Image.h" -#include "common/debug.h" - -namespace gl -{ -class Framebuffer; -} - -namespace rx -{ -class Renderer; -class Renderer9; -class TextureStorageInterface2D; -class TextureStorageInterfaceCube; - -class Image9 : public Image -{ - public: - Image9(); - ~Image9(); - - static Image9 *makeImage9(Image *img); - - static void generateMipmap(Image9 *dest, Image9 *source); - static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); - static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); - - virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease); - - virtual bool isRenderableFormat() const; - D3DFORMAT getD3DFormat() const; - - virtual bool isDirty() const {return mSurface && mDirty;} - IDirect3DSurface9 *getSurface(); - - virtual void setManagedSurface(TextureStorageInterface2D *storage, int level); - virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level); - virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - - virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - GLint unpackAlignment, const void *input); - virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, - const void *input); - - virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); - - private: - DISALLOW_COPY_AND_ASSIGN(Image9); - - void createSurface(); - void setManagedSurface(IDirect3DSurface9 *surface); - bool updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - - HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); - void unlock(); - - Renderer9 *mRenderer; - - D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. - D3DFORMAT mD3DFormat; - - IDirect3DSurface9 *mSurface; -}; -} - -#endif // LIBGLESV2_RENDERER_IMAGE9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp deleted file mode 100644 index 36a62adc1c..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation. - -#include "libGLESv2/renderer/IndexBuffer11.h" -#include "libGLESv2/renderer/Renderer11.h" - -namespace rx -{ - -IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) -{ - mBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; -} - -IndexBuffer11::~IndexBuffer11() -{ - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } -} - -bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) -{ - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } - - updateSerial(); - - if (bufferSize > 0) - { - ID3D11Device* dxDevice = mRenderer->getDevice(); - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = bufferSize; - bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return false; - } - } - - mBufferSize = bufferSize; - mIndexType = indexType; - mDynamicUsage = dynamic; - - return true; -} - -IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer)); - return static_cast(indexBuffer); -} - -bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) -{ - if (mBuffer) - { - // Check for integer overflows and out-out-bounds map requests - if (offset + size < offset || offset + size > mBufferSize) - { - ERR("Index buffer map range is not inside the buffer."); - return false; - } - - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Index buffer map failed with error 0x%08x", result); - return false; - } - - *outMappedMemory = reinterpret_cast(mappedResource.pData) + offset; - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; - } -} - -bool IndexBuffer11::unmapBuffer() -{ - if (mBuffer) - { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - dxContext->Unmap(mBuffer, 0); - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; - } -} - -GLenum IndexBuffer11::getIndexType() const -{ - return mIndexType; -} - -unsigned int IndexBuffer11::getBufferSize() const -{ - return mBufferSize; -} - -bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) -{ - if (bufferSize > mBufferSize || indexType != mIndexType) - { - return initialize(bufferSize, indexType, mDynamicUsage); - } - else - { - return true; - } -} - -bool IndexBuffer11::discard() -{ - if (mBuffer) - { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Index buffer map failed with error 0x%08x", result); - return false; - } - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; - } -} - -DXGI_FORMAT IndexBuffer11::getIndexFormat() const -{ - switch (mIndexType) - { - case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT; - case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT; - case GL_UNSIGNED_INT: return mRenderer->get32BitIndexSupport() ? DXGI_FORMAT_R32_UINT : DXGI_FORMAT_R16_UINT; - default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; - } -} - -ID3D11Buffer *IndexBuffer11::getBuffer() const -{ - return mBuffer; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h deleted file mode 100644 index 39a61946ad..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer11.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation. - -#ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_ -#define LIBGLESV2_RENDERER_INDEXBUFFER11_H_ - -#include "libGLESv2/renderer/IndexBuffer.h" - -namespace rx -{ -class Renderer11; - -class IndexBuffer11 : public IndexBuffer -{ - public: - explicit IndexBuffer11(Renderer11 *const renderer); - virtual ~IndexBuffer11(); - - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); - - static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer); - - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual bool unmapBuffer(); - - virtual GLenum getIndexType() const; - virtual unsigned int getBufferSize() const; - virtual bool setSize(unsigned int bufferSize, GLenum indexType); - - virtual bool discard(); - - DXGI_FORMAT getIndexFormat() const; - ID3D11Buffer *getBuffer() const; - - private: - DISALLOW_COPY_AND_ASSIGN(IndexBuffer11); - - rx::Renderer11 *const mRenderer; - - ID3D11Buffer *mBuffer; - unsigned int mBufferSize; - GLenum mIndexType; - bool mDynamicUsage; -}; - -} - -#endif // LIBGLESV2_RENDERER_INDEXBUFFER11_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp deleted file mode 100644 index c6d83c5dca..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.cpp +++ /dev/null @@ -1,207 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2012 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. -// - -// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation. - -#include "libGLESv2/renderer/IndexBuffer9.h" -#include "libGLESv2/renderer/Renderer9.h" - -namespace rx -{ - -IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) -{ - mIndexBuffer = NULL; - mBufferSize = 0; - mIndexType = 0; - mDynamic = false; -} - -IndexBuffer9::~IndexBuffer9() -{ - if (mIndexBuffer) - { - mIndexBuffer->Release(); - mIndexBuffer = NULL; - } -} - -bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) -{ - if (mIndexBuffer) - { - mIndexBuffer->Release(); - mIndexBuffer = NULL; - } - - updateSerial(); - - if (bufferSize > 0) - { - D3DFORMAT format; - if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE) - { - format = D3DFMT_INDEX16; - } - else if (indexType == GL_UNSIGNED_INT) - { - if (mRenderer->get32BitIndexSupport()) - { - format = D3DFMT_INDEX32; - } - else - { - ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices."); - return false; - } - } - else - { - ERR("Invalid index type %u.", indexType); - return false; - } - - DWORD usageFlags = D3DUSAGE_WRITEONLY; - if (dynamic) - { - usageFlags |= D3DUSAGE_DYNAMIC; - } - - HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); - if (FAILED(result)) - { - ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result); - return false; - } - } - - mBufferSize = bufferSize; - mIndexType = indexType; - mDynamic = dynamic; - - return true; -} - -IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer)); - return static_cast(indexBuffer); -} - -bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) -{ - if (mIndexBuffer) - { - DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; - - void *mapPtr = NULL; - HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); - if (FAILED(result)) - { - ERR("Index buffer lock failed with error 0x%08x", result); - return false; - } - - *outMappedMemory = mapPtr; - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; - } -} - -bool IndexBuffer9::unmapBuffer() -{ - if (mIndexBuffer) - { - HRESULT result = mIndexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Index buffer unlock failed with error 0x%08x", result); - return false; - } - - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; - } -} - -GLenum IndexBuffer9::getIndexType() const -{ - return mIndexType; -} - -unsigned int IndexBuffer9::getBufferSize() const -{ - return mBufferSize; -} - -bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) -{ - if (bufferSize > mBufferSize || indexType != mIndexType) - { - return initialize(bufferSize, indexType, mDynamic); - } - else - { - return true; - } -} - -bool IndexBuffer9::discard() -{ - if (mIndexBuffer) - { - void *dummy; - HRESULT result; - - result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); - if (FAILED(result)) - { - ERR("Discard lock failed with error 0x%08x", result); - return false; - } - - result = mIndexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } - - return true; - } - else - { - ERR("Index buffer not initialized."); - return false; - } -} - -D3DFORMAT IndexBuffer9::getIndexFormat() const -{ - switch (mIndexType) - { - case GL_UNSIGNED_BYTE: return D3DFMT_INDEX16; - case GL_UNSIGNED_SHORT: return D3DFMT_INDEX16; - case GL_UNSIGNED_INT: return D3DFMT_INDEX32; - default: UNREACHABLE(); return D3DFMT_UNKNOWN; - } -} - -IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const -{ - return mIndexBuffer; -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h deleted file mode 100644 index 6801867532..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/IndexBuffer9.h +++ /dev/null @@ -1,53 +0,0 @@ -// -// Copyright (c) 2002-2012 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. -// - -// Indexffer9.h: Defines the D3D9 IndexBuffer implementation. - -#ifndef LIBGLESV2_RENDERER_INDEXBUFFER9_H_ -#define LIBGLESV2_RENDERER_INDEXBUFFER9_H_ - -#include "libGLESv2/renderer/IndexBuffer.h" - -namespace rx -{ -class Renderer9; - -class IndexBuffer9 : public IndexBuffer -{ - public: - explicit IndexBuffer9(Renderer9 *const renderer); - virtual ~IndexBuffer9(); - - virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); - - static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer); - - virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); - virtual bool unmapBuffer(); - - virtual GLenum getIndexType() const; - virtual unsigned int getBufferSize() const; - virtual bool setSize(unsigned int bufferSize, GLenum indexType); - - virtual bool discard(); - - D3DFORMAT getIndexFormat() const; - IDirect3DIndexBuffer9 *getBuffer() const; - - private: - DISALLOW_COPY_AND_ASSIGN(IndexBuffer9); - - rx::Renderer9 *const mRenderer; - - IDirect3DIndexBuffer9 *mIndexBuffer; - unsigned int mBufferSize; - GLenum mIndexType; - bool mDynamic; -}; - -} - -#endif // LIBGLESV2_RENDERER_INDEXBUFFER9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp deleted file mode 100644 index 1552f3a326..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.cpp +++ /dev/null @@ -1,213 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches -// D3D11 input layouts. - -#include "libGLESv2/renderer/InputLayoutCache.h" -#include "libGLESv2/renderer/VertexBuffer11.h" -#include "libGLESv2/renderer/BufferStorage11.h" -#include "libGLESv2/renderer/ShaderExecutable11.h" -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/Context.h" -#include "libGLESv2/renderer/VertexDataManager.h" - -#include "third_party/murmurhash/MurmurHash3.h" - -namespace rx -{ - -const unsigned int InputLayoutCache::kMaxInputLayouts = 1024; - -InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts) -{ - mCounter = 0; - mDevice = NULL; - mDeviceContext = NULL; - mCurrentIL = NULL; - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mCurrentBuffers[i] = -1; - mCurrentVertexStrides[i] = -1; - mCurrentVertexOffsets[i] = -1; - } -} - -InputLayoutCache::~InputLayoutCache() -{ - clear(); -} - -void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context) -{ - clear(); - mDevice = device; - mDeviceContext = context; -} - -void InputLayoutCache::clear() -{ - for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) - { - i->second.inputLayout->Release(); - } - mInputLayoutMap.clear(); - markDirty(); -} - -void InputLayoutCache::markDirty() -{ - mCurrentIL = NULL; - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mCurrentBuffers[i] = -1; - mCurrentVertexStrides[i] = -1; - mCurrentVertexOffsets[i] = -1; - } -} - -GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - gl::ProgramBinary *programBinary) -{ - int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]; - programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices); - - if (!mDevice || !mDeviceContext) - { - ERR("InputLayoutCache is not initialized."); - return GL_INVALID_OPERATION; - } - - InputLayoutKey ilKey = { 0 }; - - ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL }; - unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 }; - UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 }; - UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 }; - - static const char* semanticName = "TEXCOORD"; - - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - if (attributes[i].active) - { - VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer); - BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL; - - D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; - - // Record the type of the associated vertex shader vector in our key - // This will prevent mismatched vertex shaders from using the same input layout - GLint attributeSize; - programBinary->getActiveAttribute(ilKey.elementCount, 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL); - - ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; - ilKey.elements[ilKey.elementCount].desc.SemanticIndex = sortedSemanticIndices[i]; - ilKey.elements[ilKey.elementCount].desc.Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT; - ilKey.elements[ilKey.elementCount].desc.InputSlot = i; - ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; - ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; - ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor; - ilKey.elementCount++; - - vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer() : vertexBuffer->getBuffer(); - vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial(); - vertexStrides[i] = attributes[i].stride; - vertexOffsets[i] = attributes[i].offset; - } - } - - ID3D11InputLayout *inputLayout = NULL; - - InputLayoutMap::iterator i = mInputLayoutMap.find(ilKey); - if (i != mInputLayoutMap.end()) - { - inputLayout = i->second.inputLayout; - i->second.lastUsedTime = mCounter++; - } - else - { - ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); - - D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; - for (unsigned int j = 0; j < ilKey.elementCount; ++j) - { - descs[j] = ilKey.elements[j].desc; - } - - HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); - if (FAILED(result)) - { - ERR("Failed to crate input layout, result: 0x%08x", result); - return GL_INVALID_OPERATION; - } - - if (mInputLayoutMap.size() >= kMaxInputLayouts) - { - TRACE("Overflowed the limit of %u input layouts, removing the least recently used " - "to make room.", kMaxInputLayouts); - - InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin(); - for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) - { - if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime) - { - leastRecentlyUsed = i; - } - } - leastRecentlyUsed->second.inputLayout->Release(); - mInputLayoutMap.erase(leastRecentlyUsed); - } - - InputLayoutCounterPair inputCounterPair; - inputCounterPair.inputLayout = inputLayout; - inputCounterPair.lastUsedTime = mCounter++; - - mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair)); - } - - if (inputLayout != mCurrentIL) - { - mDeviceContext->IASetInputLayout(inputLayout); - mCurrentIL = inputLayout; - } - - for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] || - vertexOffsets[i] != mCurrentVertexOffsets[i]) - { - mDeviceContext->IASetVertexBuffers(i, 1, &vertexBuffers[i], &vertexStrides[i], &vertexOffsets[i]); - mCurrentBuffers[i] = vertexBufferSerials[i]; - mCurrentVertexStrides[i] = vertexStrides[i]; - mCurrentVertexOffsets[i] = vertexOffsets[i]; - } - } - - return GL_NO_ERROR; -} - -std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout) -{ - static const unsigned int seed = 0xDEADBEEF; - - std::size_t hash = 0; - MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash); - return hash; -} - -bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b) -{ - if (a.elementCount != b.elementCount) - { - return false; - } - - return std::equal(a.begin(), a.end(), b.begin()); -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h deleted file mode 100644 index bb1a8eebcf..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/InputLayoutCache.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches -// D3D11 input layouts. - -#ifndef LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ -#define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ - -#include "libGLESv2/Constants.h" -#include "common/angleutils.h" - -namespace gl -{ -class ProgramBinary; -} - -namespace rx -{ -struct TranslatedAttribute; - -class InputLayoutCache -{ - public: - InputLayoutCache(); - virtual ~InputLayoutCache(); - - void initialize(ID3D11Device *device, ID3D11DeviceContext *context); - void clear(); - void markDirty(); - - GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], - gl::ProgramBinary *programBinary); - - private: - DISALLOW_COPY_AND_ASSIGN(InputLayoutCache); - - struct InputLayoutElement - { - D3D11_INPUT_ELEMENT_DESC desc; - GLenum glslElementType; - }; - - struct InputLayoutKey - { - unsigned int elementCount; - InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS]; - - const char *begin() const - { - return reinterpret_cast(&elementCount); - } - - const char *end() const - { - return reinterpret_cast(&elements[elementCount]); - } - }; - - struct InputLayoutCounterPair - { - ID3D11InputLayout *inputLayout; - unsigned long long lastUsedTime; - }; - - ID3D11InputLayout *mCurrentIL; - unsigned int mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; - UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; - UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; - - static std::size_t hashInputLayout(const InputLayoutKey &inputLayout); - static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b); - - typedef std::size_t (*InputLayoutHashFunction)(const InputLayoutKey &); - typedef bool (*InputLayoutEqualityFunction)(const InputLayoutKey &, const InputLayoutKey &); - typedef std::unordered_map InputLayoutMap; - InputLayoutMap mInputLayoutMap; - - static const unsigned int kMaxInputLayouts; - - unsigned long long mCounter; - - ID3D11Device *mDevice; - ID3D11DeviceContext *mDeviceContext; -}; - -} - -#endif // LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp deleted file mode 100644 index 13210fc929..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Query11.cpp +++ /dev/null @@ -1,122 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl. - -#include "libGLESv2/renderer/Query11.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Query11::~Query11() -{ - if (mQuery) - { - mQuery->Release(); - mQuery = NULL; - } -} - -void Query11::begin() -{ - if (mQuery == NULL) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_OCCLUSION; - queryDesc.MiscFlags = 0; - - if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - mRenderer->getDeviceContext()->Begin(mQuery); -} - -void Query11::end() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - mRenderer->getDeviceContext()->End(mQuery); - - mStatus = GL_FALSE; - mResult = GL_FALSE; -} - -GLuint Query11::getResult() -{ - if (mQuery != NULL) - { - while (!testQuery()) - { - Sleep(0); - // explicitly check for device loss, some drivers seem to return S_FALSE - // if the device is lost - if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, 0); - } - } - } - - return mResult; -} - -GLboolean Query11::isResultAvailable() -{ - if (mQuery != NULL) - { - testQuery(); - } - - return mStatus; -} - -GLboolean Query11::testQuery() -{ - if (mQuery != NULL && mStatus != GL_TRUE) - { - UINT64 numPixels = 0; - HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, &numPixels, sizeof(UINT64), 0); - if (result == S_OK) - { - mStatus = GL_TRUE; - - switch (getType()) - { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; - break; - default: - UNREACHABLE(); - } - } - else if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - return mStatus; - } - - return GL_TRUE; // prevent blocking when query is null -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Query11.h deleted file mode 100644 index 0a03de77ca..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Query11.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl. - -#ifndef LIBGLESV2_RENDERER_QUERY11_H_ -#define LIBGLESV2_RENDERER_QUERY11_H_ - -#include "libGLESv2/renderer/QueryImpl.h" - -namespace rx -{ -class Renderer11; - -class Query11 : public QueryImpl -{ - public: - Query11(rx::Renderer11 *renderer, GLenum type); - virtual ~Query11(); - - void begin(); - void end(); - GLuint getResult(); - GLboolean isResultAvailable(); - - private: - DISALLOW_COPY_AND_ASSIGN(Query11); - - GLboolean testQuery(); - - rx::Renderer11 *mRenderer; - ID3D11Query *mQuery; -}; - -} - -#endif // LIBGLESV2_RENDERER_QUERY11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp deleted file mode 100644 index ef694267dd..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Query9.cpp +++ /dev/null @@ -1,125 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. - - -#include "libGLESv2/renderer/Query9.h" -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/Renderer9.h" - -namespace rx -{ - -Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type) -{ - mRenderer = renderer; - mQuery = NULL; -} - -Query9::~Query9() -{ - if (mQuery) - { - mQuery->Release(); - mQuery = NULL; - } -} - -void Query9::begin() -{ - if (mQuery == NULL) - { - if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) - { - return gl::error(GL_OUT_OF_MEMORY); - } - } - - HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); - ASSERT(SUCCEEDED(result)); -} - -void Query9::end() -{ - if (mQuery == NULL) - { - return gl::error(GL_INVALID_OPERATION); - } - - HRESULT result = mQuery->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); - - mStatus = GL_FALSE; - mResult = GL_FALSE; -} - -GLuint Query9::getResult() -{ - if (mQuery != NULL) - { - while (!testQuery()) - { - Sleep(0); - // explicitly check for device loss - // some drivers seem to return S_FALSE even if the device is lost - // instead of D3DERR_DEVICELOST like they should - if (mRenderer->testDeviceLost(true)) - { - return gl::error(GL_OUT_OF_MEMORY, 0); - } - } - } - - return mResult; -} - -GLboolean Query9::isResultAvailable() -{ - if (mQuery != NULL) - { - testQuery(); - } - - return mStatus; -} - -GLboolean Query9::testQuery() -{ - if (mQuery != NULL && mStatus != GL_TRUE) - { - DWORD numPixels = 0; - - HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); - if (hres == S_OK) - { - mStatus = GL_TRUE; - - switch (getType()) - { - case GL_ANY_SAMPLES_PASSED_EXT: - case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: - mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; - break; - default: - ASSERT(false); - } - } - else if (d3d9::isDeviceLostError(hres)) - { - mRenderer->notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); - } - - return mStatus; - } - - return GL_TRUE; // prevent blocking when query is null -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Query9.h deleted file mode 100644 index 47eef89336..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Query9.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2013 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. -// - -// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl. - -#ifndef LIBGLESV2_RENDERER_QUERY9_H_ -#define LIBGLESV2_RENDERER_QUERY9_H_ - -#include "libGLESv2/renderer/QueryImpl.h" - -namespace rx -{ -class Renderer9; - -class Query9 : public QueryImpl -{ - public: - Query9(rx::Renderer9 *renderer, GLenum type); - virtual ~Query9(); - - void begin(); - void end(); - GLuint getResult(); - GLboolean isResultAvailable(); - - private: - DISALLOW_COPY_AND_ASSIGN(Query9); - - GLboolean testQuery(); - - rx::Renderer9 *mRenderer; - IDirect3DQuery9 *mQuery; -}; - -} - -#endif // LIBGLESV2_RENDERER_QUERY9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp deleted file mode 100644 index fd388dfe08..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.cpp +++ /dev/null @@ -1,407 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render -// state objects. - -#include "libGLESv2/renderer/RenderStateCache.h" -#include "libGLESv2/renderer/renderer11_utils.h" - -#include "common/debug.h" -#include "third_party/murmurhash/MurmurHash3.h" - -namespace rx -{ - -// MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState, -// ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum -// number of unique states of each type an application can create is 4096 -const unsigned int RenderStateCache::kMaxBlendStates = 4096; -const unsigned int RenderStateCache::kMaxRasterizerStates = 4096; -const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096; -const unsigned int RenderStateCache::kMaxSamplerStates = 4096; - -RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0), - mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), - mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), - mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), - mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) -{ -} - -RenderStateCache::~RenderStateCache() -{ - clear(); -} - -void RenderStateCache::initialize(ID3D11Device *device) -{ - clear(); - mDevice = device; -} - -void RenderStateCache::clear() -{ - for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++) - { - i->second.first->Release(); - } - mBlendStateCache.clear(); - - for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++) - { - i->second.first->Release(); - } - mRasterizerStateCache.clear(); - - for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) - { - i->second.first->Release(); - } - mDepthStencilStateCache.clear(); - - for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++) - { - i->second.first->Release(); - } - mSamplerStateCache.clear(); -} - -std::size_t RenderStateCache::hashBlendState(const gl::BlendState &blendState) -{ - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&blendState, sizeof(gl::BlendState), seed, &hash); - return hash; -} - -bool RenderStateCache::compareBlendStates(const gl::BlendState &a, const gl::BlendState &b) -{ - return memcmp(&a, &b, sizeof(gl::BlendState)) == 0; -} - -ID3D11BlendState *RenderStateCache::getBlendState(const gl::BlendState &blendState) -{ - if (!mDevice) - { - ERR("RenderStateCache is not initialized."); - return NULL; - } - - BlendStateMap::iterator i = mBlendStateCache.find(blendState); - if (i != mBlendStateCache.end()) - { - BlendStateCounterPair &state = i->second; - state.second = mCounter++; - return state.first; - } - else - { - if (mBlendStateCache.size() >= kMaxBlendStates) - { - TRACE("Overflowed the limit of %u blend states, removing the least recently used " - "to make room.", kMaxBlendStates); - - BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin(); - for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - leastRecentlyUsed->second.first->Release(); - mBlendStateCache.erase(leastRecentlyUsed); - } - - // Create a new blend state and insert it into the cache - D3D11_BLEND_DESC blendDesc = { 0 }; - blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; - blendDesc.IndependentBlendEnable = FALSE; - - for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) - { - D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = blendDesc.RenderTarget[i]; - - rtBlend.BlendEnable = blendState.blend; - if (blendState.blend) - { - rtBlend.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false); - rtBlend.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false); - rtBlend.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB); - - rtBlend.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true); - rtBlend.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true); - rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); - } - - rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(blendState.colorMaskRed, - blendState.colorMaskGreen, - blendState.colorMaskBlue, - blendState.colorMaskAlpha); - } - - ID3D11BlendState *dx11BlendState = NULL; - HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState); - if (FAILED(result) || !dx11BlendState) - { - ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); - return NULL; - } - - mBlendStateCache.insert(std::make_pair(blendState, std::make_pair(dx11BlendState, mCounter++))); - - return dx11BlendState; - } -} - -std::size_t RenderStateCache::hashRasterizerState(const RasterizerStateKey &rasterState) -{ - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&rasterState, sizeof(RasterizerStateKey), seed, &hash); - return hash; -} - -bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b) -{ - return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; -} - -ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, - bool scissorEnabled, unsigned int depthSize) -{ - if (!mDevice) - { - ERR("RenderStateCache is not initialized."); - return NULL; - } - - RasterizerStateKey key; - key.rasterizerState = rasterState; - key.scissorEnabled = scissorEnabled; - key.depthSize = depthSize; - - RasterizerStateMap::iterator i = mRasterizerStateCache.find(key); - if (i != mRasterizerStateCache.end()) - { - RasterizerStateCounterPair &state = i->second; - state.second = mCounter++; - return state.first; - } - else - { - if (mRasterizerStateCache.size() >= kMaxRasterizerStates) - { - TRACE("Overflowed the limit of %u rasterizer states, removing the least recently used " - "to make room.", kMaxRasterizerStates); - - RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin(); - for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - leastRecentlyUsed->second.first->Release(); - mRasterizerStateCache.erase(leastRecentlyUsed); - } - - D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode); - - // Disable culling if drawing points - if (rasterState.pointDrawMode) - { - cullMode = D3D11_CULL_NONE; - } - - D3D11_RASTERIZER_DESC rasterDesc; - rasterDesc.FillMode = D3D11_FILL_SOLID; - rasterDesc.CullMode = cullMode; - rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE; - rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast(depthSize)); - rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though. - rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; - rasterDesc.DepthClipEnable = TRUE; - rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; - rasterDesc.MultisampleEnable = rasterState.multiSample; - rasterDesc.AntialiasedLineEnable = FALSE; - - ID3D11RasterizerState *dx11RasterizerState = NULL; - HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState); - if (FAILED(result) || !dx11RasterizerState) - { - ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); - return NULL; - } - - mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++))); - - return dx11RasterizerState; - } -} - -std::size_t RenderStateCache::hashDepthStencilState(const gl::DepthStencilState &dsState) -{ - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&dsState, sizeof(gl::DepthStencilState), seed, &hash); - return hash; -} - -bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b) -{ - return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0; -} - -ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState) -{ - if (!mDevice) - { - ERR("RenderStateCache is not initialized."); - return NULL; - } - - DepthStencilStateMap::iterator i = mDepthStencilStateCache.find(dsState); - if (i != mDepthStencilStateCache.end()) - { - DepthStencilStateCounterPair &state = i->second; - state.second = mCounter++; - return state.first; - } - else - { - if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates) - { - TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used " - "to make room.", kMaxDepthStencilStates); - - DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin(); - for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - leastRecentlyUsed->second.first->Release(); - mDepthStencilStateCache.erase(leastRecentlyUsed); - } - - D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 }; - dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE; - dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask); - dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc); - dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE; - dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask); - dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask); - dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail); - dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail); - dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass); - dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc); - dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail); - dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail); - dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass); - dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc); - - ID3D11DepthStencilState *dx11DepthStencilState = NULL; - HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); - if (FAILED(result) || !dx11DepthStencilState) - { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; - } - - mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++))); - - return dx11DepthStencilState; - } -} - -std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState) -{ - static const unsigned int seed = 0xABCDEF98; - - std::size_t hash = 0; - MurmurHash3_x86_32(&samplerState, sizeof(gl::SamplerState), seed, &hash); - return hash; -} - -bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b) -{ - return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0; -} - -ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState) -{ - if (!mDevice) - { - ERR("RenderStateCache is not initialized."); - return NULL; - } - - SamplerStateMap::iterator i = mSamplerStateCache.find(samplerState); - if (i != mSamplerStateCache.end()) - { - SamplerStateCounterPair &state = i->second; - state.second = mCounter++; - return state.first; - } - else - { - if (mSamplerStateCache.size() >= kMaxSamplerStates) - { - TRACE("Overflowed the limit of %u sampler states, removing the least recently used " - "to make room.", kMaxSamplerStates); - - SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin(); - for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++) - { - if (i->second.second < leastRecentlyUsed->second.second) - { - leastRecentlyUsed = i; - } - } - leastRecentlyUsed->second.first->Release(); - mSamplerStateCache.erase(leastRecentlyUsed); - } - - D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, samplerState.maxAnisotropy); - samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS); - samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT); - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.MipLODBias = static_cast(samplerState.lodOffset); - samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy; - samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; - samplerDesc.BorderColor[0] = 0.0f; - samplerDesc.BorderColor[1] = 0.0f; - samplerDesc.BorderColor[2] = 0.0f; - samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset); - samplerDesc.MaxLOD = mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 - ? gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset) : FLT_MAX; - - ID3D11SamplerState *dx11SamplerState = NULL; - HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState); - if (FAILED(result) || !dx11SamplerState) - { - ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); - return NULL; - } - - mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++))); - - return dx11SamplerState; - } -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h deleted file mode 100644 index f8b5111de4..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderStateCache.h +++ /dev/null @@ -1,101 +0,0 @@ -// -// Copyright (c) 2012-2013 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. -// - -// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render -// state objects. - -#ifndef LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ -#define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ - -#include "libGLESv2/angletypes.h" -#include "common/angleutils.h" - -namespace rx -{ - -class RenderStateCache -{ - public: - RenderStateCache(); - virtual ~RenderStateCache(); - - void initialize(ID3D11Device *device); - void clear(); - - // Increments refcount on the returned blend state, Release() must be called. - ID3D11BlendState *getBlendState(const gl::BlendState &blendState); - ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, - bool scissorEnabled, unsigned int depthSize); - ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState); - ID3D11SamplerState *getSamplerState(const gl::SamplerState &samplerState); - - private: - DISALLOW_COPY_AND_ASSIGN(RenderStateCache); - - unsigned long long mCounter; - - // Blend state cache - static std::size_t hashBlendState(const gl::BlendState &blendState); - static bool compareBlendStates(const gl::BlendState &a, const gl::BlendState &b); - static const unsigned int kMaxBlendStates; - - typedef std::size_t (*BlendStateHashFunction)(const gl::BlendState &); - typedef bool (*BlendStateEqualityFunction)(const gl::BlendState &, const gl::BlendState &); - typedef std::pair BlendStateCounterPair; - typedef std::unordered_map BlendStateMap; - BlendStateMap mBlendStateCache; - - // Rasterizer state cache - struct RasterizerStateKey - { - gl::RasterizerState rasterizerState; - bool scissorEnabled; - unsigned int depthSize; - }; - static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState); - static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b); - static const unsigned int kMaxRasterizerStates; - - typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &); - typedef bool (*RasterizerStateEqualityFunction)(const RasterizerStateKey &, const RasterizerStateKey &); - typedef std::pair RasterizerStateCounterPair; - typedef std::unordered_map RasterizerStateMap; - RasterizerStateMap mRasterizerStateCache; - - // Depth stencil state cache - static std::size_t hashDepthStencilState(const gl::DepthStencilState &dsState); - static bool compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b); - static const unsigned int kMaxDepthStencilStates; - - typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &); - typedef bool (*DepthStencilStateEqualityFunction)(const gl::DepthStencilState &, const gl::DepthStencilState &); - typedef std::pair DepthStencilStateCounterPair; - typedef std::unordered_map DepthStencilStateMap; - DepthStencilStateMap mDepthStencilStateCache; - - // Sample state cache - static std::size_t hashSamplerState(const gl::SamplerState &samplerState); - static bool compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b); - static const unsigned int kMaxSamplerStates; - - typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &); - typedef bool (*SamplerStateEqualityFunction)(const gl::SamplerState &, const gl::SamplerState &); - typedef std::pair SamplerStateCounterPair; - typedef std::unordered_map SamplerStateMap; - SamplerStateMap mSamplerStateCache; - - ID3D11Device *mDevice; -}; - -} - -#endif // LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp deleted file mode 100644 index 2667cc6fa7..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.cpp +++ /dev/null @@ -1,355 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers -// retained by Renderbuffers. - -#include "libGLESv2/renderer/RenderTarget11.h" -#include "libGLESv2/renderer/Renderer11.h" - -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view) -{ - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - view->GetDesc(&rtvDesc); - - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); - - unsigned int mipSlice = 0; - unsigned int arraySlice = 0; - unsigned int mipLevels = texDesc.MipLevels; - - switch (rtvDesc.ViewDimension) - { - case D3D11_RTV_DIMENSION_TEXTURE1D: - mipSlice = rtvDesc.Texture1D.MipSlice; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: - mipSlice = rtvDesc.Texture1DArray.MipSlice; - arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2D: - mipSlice = rtvDesc.Texture2D.MipSlice; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: - mipSlice = rtvDesc.Texture2DArray.MipSlice; - arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DMS: - mipSlice = 0; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: - mipSlice = 0; - arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_TEXTURE3D: - mipSlice = rtvDesc.Texture3D.MipSlice; - arraySlice = 0; - break; - - case D3D11_RTV_DIMENSION_UNKNOWN: - case D3D11_RTV_DIMENSION_BUFFER: - UNIMPLEMENTED(); - break; - - default: - UNREACHABLE(); - break; - } - - return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); -} - -static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view) -{ - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - view->GetDesc(&dsvDesc); - - D3D11_TEXTURE2D_DESC texDesc; - texture->GetDesc(&texDesc); - - unsigned int mipSlice = 0; - unsigned int arraySlice = 0; - unsigned int mipLevels = texDesc.MipLevels; - - switch (dsvDesc.ViewDimension) - { - case D3D11_DSV_DIMENSION_TEXTURE1D: - mipSlice = dsvDesc.Texture1D.MipSlice; - arraySlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: - mipSlice = dsvDesc.Texture1DArray.MipSlice; - arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2D: - mipSlice = dsvDesc.Texture2D.MipSlice; - arraySlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: - mipSlice = dsvDesc.Texture2DArray.MipSlice; - arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DMS: - mipSlice = 0; - arraySlice = 0; - break; - - case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: - mipSlice = 0; - arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; - break; - - case D3D11_RTV_DIMENSION_UNKNOWN: - UNIMPLEMENTED(); - break; - - default: - UNREACHABLE(); - break; - } - - return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); -} - -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) -{ - mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = tex; - mRenderTarget = rtv; - mDepthStencil = NULL; - mShaderResource = srv; - mSubresourceIndex = 0; - - if (mRenderTarget && mTexture) - { - D3D11_RENDER_TARGET_VIEW_DESC desc; - mRenderTarget->GetDesc(&desc); - - D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); - - mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); - mWidth = width; - mHeight = height; - mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; - - mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); - } -} - -RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) -{ - mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = tex; - mRenderTarget = NULL; - mDepthStencil = dsv; - mShaderResource = srv; - mSubresourceIndex = 0; - - if (mDepthStencil && mTexture) - { - D3D11_DEPTH_STENCIL_VIEW_DESC desc; - mDepthStencil->GetDesc(&desc); - - D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); - - mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); - mWidth = width; - mHeight = height; - mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; - - mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); - } -} - -RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth) -{ - mRenderer = Renderer11::makeRenderer11(renderer); - mTexture = NULL; - mRenderTarget = NULL; - mDepthStencil = NULL; - mShaderResource = NULL; - - DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format); - - int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); - if (supportedSamples < 0) - { - gl::error(GL_OUT_OF_MEMORY); - return; - } - - if (width > 0 && height > 0) - { - // Create texture resource - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; - desc.Height = height; - desc.MipLevels = 1; - desc.ArraySize = 1; - desc.Format = requestedFormat; - desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)); - - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - if (result == E_OUTOFMEMORY) - { - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - - if (depth) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = requestedFormat; - dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; - dsvDesc.Texture2D.MipSlice = 0; - dsvDesc.Flags = 0; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); - - if (result == E_OUTOFMEMORY) - { - mTexture->Release(); - mTexture = NULL; - gl::error(GL_OUT_OF_MEMORY); - } - ASSERT(SUCCEEDED(result)); - } - else - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = requestedFormat; - rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; - rtvDesc.Texture2D.MipSlice = 0; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); - - if (result == E_OUTOFMEMORY) - { - mTexture->Release(); - mTexture = NULL; - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = requestedFormat; - srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; - srvDesc.Texture2D.MostDetailedMip = 0; - srvDesc.Texture2D.MipLevels = 1; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); - - if (result == E_OUTOFMEMORY) - { - mTexture->Release(); - mTexture = NULL; - mRenderTarget->Release(); - mRenderTarget = NULL; - gl::error(GL_OUT_OF_MEMORY); - return; - } - ASSERT(SUCCEEDED(result)); - } - } - - mWidth = width; - mHeight = height; - mInternalFormat = format; - mSamples = supportedSamples; - mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat); - mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); -} - -RenderTarget11::~RenderTarget11() -{ - if (mTexture) - { - mTexture->Release(); - mTexture = NULL; - } - - if (mRenderTarget) - { - mRenderTarget->Release(); - mRenderTarget = NULL; - } - - if (mDepthStencil) - { - mDepthStencil->Release(); - mDepthStencil = NULL; - } - - if (mShaderResource) - { - mShaderResource->Release(); - mShaderResource = NULL; - } -} - -RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target)); - return static_cast(target); -} - -ID3D11Texture2D *RenderTarget11::getTexture() const -{ - return mTexture; -} - -ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const -{ - return mRenderTarget; -} - -ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const -{ - return mDepthStencil; -} - -ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const -{ - return mShaderResource; -} - -unsigned int RenderTarget11::getSubresourceIndex() const -{ - return mSubresourceIndex; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h deleted file mode 100644 index 97827f2639..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget11.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers -// retained by Renderbuffers. - -#ifndef LIBGLESV2_RENDERER_RENDERTARGET11_H_ -#define LIBGLESV2_RENDERER_RENDERTARGET11_H_ - -#include "libGLESv2/renderer/RenderTarget.h" - -namespace rx -{ -class Renderer; -class Renderer11; - -class RenderTarget11 : public RenderTarget -{ - public: - RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height); - RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height); - RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth); - virtual ~RenderTarget11(); - - static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget); - - ID3D11Texture2D *getTexture() const; - ID3D11RenderTargetView *getRenderTargetView() const; - ID3D11DepthStencilView *getDepthStencilView() const; - ID3D11ShaderResourceView *getShaderResourceView() const; - - unsigned int getSubresourceIndex() const; - - private: - DISALLOW_COPY_AND_ASSIGN(RenderTarget11); - - unsigned int mSubresourceIndex; - ID3D11Texture2D *mTexture; - ID3D11RenderTargetView *mRenderTarget; - ID3D11DepthStencilView *mDepthStencil; - ID3D11ShaderResourceView *mShaderResource; - - Renderer11 *mRenderer; -}; - -} - -#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp deleted file mode 100644 index a84c709059..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.cpp +++ /dev/null @@ -1,113 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9 -// pointers retained by renderbuffers. - -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/Renderer9.h" - -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) -{ - mRenderer = Renderer9::makeRenderer9(renderer); - mRenderTarget = surface; - - if (mRenderTarget) - { - D3DSURFACE_DESC description; - mRenderTarget->GetDesc(&description); - - mWidth = description.Width; - mHeight = description.Height; - - mInternalFormat = d3d9_gl::GetEquivalentFormat(description.Format); - mActualFormat = d3d9_gl::GetEquivalentFormat(description.Format); - mSamples = d3d9_gl::GetSamplesFromMultisampleType(description.MultiSampleType); - } -} - -RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples) -{ - mRenderer = Renderer9::makeRenderer9(renderer); - mRenderTarget = NULL; - - D3DFORMAT requestedFormat = gl_d3d9::ConvertRenderbufferFormat(format); - int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); - - if (supportedSamples == -1) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } - - HRESULT result = D3DERR_INVALIDCALL; - - if (width > 0 && height > 0) - { - if (requestedFormat == D3DFMT_D24S8) - { - result = mRenderer->getDevice()->CreateDepthStencilSurface(width, height, requestedFormat, - gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples), - 0, FALSE, &mRenderTarget, NULL); - } - else - { - result = mRenderer->getDevice()->CreateRenderTarget(width, height, requestedFormat, - gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples), - 0, FALSE, &mRenderTarget, NULL); - } - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) - { - gl::error(GL_OUT_OF_MEMORY); - - return; - } - - ASSERT(SUCCEEDED(result)); - } - - mWidth = width; - mHeight = height; - mInternalFormat = format; - mSamples = supportedSamples; - mActualFormat = d3d9_gl::GetEquivalentFormat(requestedFormat); -} - -RenderTarget9::~RenderTarget9() -{ - if (mRenderTarget) - { - mRenderTarget->Release(); - } -} - -RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target)); - return static_cast(target); -} - -IDirect3DSurface9 *RenderTarget9::getSurface() -{ - // Caller is responsible for releasing the returned surface reference. - if (mRenderTarget) - { - mRenderTarget->AddRef(); - } - - return mRenderTarget; -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h b/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h deleted file mode 100644 index faf8ad1c6d..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/RenderTarget9.h +++ /dev/null @@ -1,40 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers -// retained by Renderbuffers. - -#ifndef LIBGLESV2_RENDERER_RENDERTARGET9_H_ -#define LIBGLESV2_RENDERER_RENDERTARGET9_H_ - -#include "libGLESv2/renderer/RenderTarget.h" - -namespace rx -{ -class Renderer; -class Renderer9; - -class RenderTarget9 : public RenderTarget -{ - public: - RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface); - RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples); - virtual ~RenderTarget9(); - - static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget); - IDirect3DSurface9 *getSurface(); - - private: - DISALLOW_COPY_AND_ASSIGN(RenderTarget9); - - IDirect3DSurface9 *mRenderTarget; - - Renderer9 *mRenderer; -}; - -} - -#endif // LIBGLESV2_RENDERER_RENDERTARGET9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp index 39fd0f41f0..5278113811 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.cpp @@ -11,35 +11,26 @@ #include "libGLESv2/main.h" #include "libGLESv2/Program.h" #include "libGLESv2/renderer/Renderer.h" -#ifndef ANGLE_ENABLE_D3D11 -#include "libGLESv2/renderer/Renderer9.h" -#else -#include "libGLESv2/renderer/Renderer11.h" +#if defined(ANGLE_ENABLE_D3D9) +# include "libGLESv2/renderer/d3d9/Renderer9.h" +#endif +#if defined(ANGLE_ENABLE_D3D11) +# include "libGLESv2/renderer/d3d11/Renderer11.h" #endif #include "libGLESv2/utilities.h" #include "third_party/trace_event/trace_event.h" -#if !defined(ANGLE_ENABLE_D3D11) -// Enables use of the Direct3D 11 API for a default display, when available -#define ANGLE_ENABLE_D3D11 0 -#endif - #ifndef D3DERR_OUTOFVIDEOMEMORY #define D3DERR_OUTOFVIDEOMEMORY MAKE_HRESULT(1, 0x876, 380) #endif -#ifndef D3DCOMPILER_DLL -#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" // Lowest common denominator -#endif +#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE) -#ifndef QT_D3DCOMPILER_DLL -#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL -#endif +#ifndef D3DCOMPILER_DLL -#if defined(__MINGW32__) || defined(ANGLE_OS_WINPHONE) +// Add define + typedefs for older MinGW-w64 headers (pre 5783) -//Add define + typedefs for older MinGW-w64 headers (pre 5783) -//Also define these on Windows Phone, which doesn't have a shader compiler +#define D3DCOMPILER_DLL L"d3dcompiler_43.dll" HRESULT WINAPI D3DCompile(const void *data, SIZE_T data_size, const char *filename, const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, @@ -48,8 +39,14 @@ typedef HRESULT (WINAPI *pD3DCompile)(const void *data, SIZE_T data_size, const const D3D_SHADER_MACRO *defines, ID3DInclude *include, const char *entrypoint, const char *target, UINT sflags, UINT eflags, ID3DBlob **shader, ID3DBlob **error_messages); +#endif // D3DCOMPILER_DLL + #endif // __MINGW32__ || ANGLE_OS_WINPHONE +#ifndef QT_D3DCOMPILER_DLL +#define QT_D3DCOMPILER_DLL D3DCOMPILER_DLL +#endif + namespace rx { @@ -82,7 +79,8 @@ bool Renderer::initializeCompiler() break; } } -#else +#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES + // Load the compiler DLL specified by the environment, or default to QT_D3DCOMPILER_DLL #if !defined(ANGLE_OS_WINRT) const wchar_t *defaultCompiler = _wgetenv(L"QT_D3DCOMPILER_DLL"); @@ -109,15 +107,11 @@ bool Renderer::initializeCompiler() // Load the first available known compiler DLL for (int i = 0; compilerDlls[i]; ++i) { -#if !defined(ANGLE_OS_WINRT) + // Load the version of the D3DCompiler DLL associated with the Direct3D version ANGLE was built with. mD3dCompilerModule = LoadLibrary(compilerDlls[i]); -#else - mD3dCompilerModule = LoadPackagedLibrary(compilerDlls[i], NULL); -#endif if (mD3dCompilerModule) break; } -#endif // ANGLE_PRELOADED_D3DCOMPILER_MODULE_NAMES if (!mD3dCompilerModule) { @@ -230,18 +224,46 @@ ShaderBlob *Renderer::compileToBinary(gl::InfoLog &infoLog, const char *hlsl, co extern "C" { -rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayType displayId) +rx::Renderer *glCreateRenderer(egl::Display *display, EGLNativeDisplayType displayId) { rx::Renderer *renderer = NULL; EGLint status = EGL_BAD_ALLOC; -#if ANGLE_ENABLE_D3D11 - renderer = new rx::Renderer11(display, hDc); -#else - bool softwareDevice = (displayId == EGL_SOFTWARE_DISPLAY_ANGLE); - renderer = new rx::Renderer9(display, hDc, softwareDevice); +#if defined(ANGLE_OS_WINRT) + if (displayId == EGL_DEFAULT_DISPLAY) + displayId = EGL_D3D11_ONLY_DISPLAY_ANGLE; #endif +#if defined(ANGLE_ENABLE_D3D11) + if (displayId == EGL_DEFAULT_DISPLAY || + displayId == EGL_D3D11_ELSE_D3D9_DISPLAY_ANGLE || + displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) + { + renderer = new rx::Renderer11(display); + + if (renderer) + { + status = renderer->initialize(); + } + + if (status == EGL_SUCCESS) + { + return renderer; + } + else if (displayId == EGL_D3D11_ONLY_DISPLAY_ANGLE) + { + return NULL; + } + + // Failed to create a D3D11 renderer, try creating a D3D9 renderer + delete renderer; + } +#endif // ANGLE_ENABLE_D3D11 + +#if defined(ANGLE_ENABLE_D3D9) + bool softwareDevice = (displayId == EGL_SOFTWARE_DISPLAY_ANGLE); + renderer = new rx::Renderer9(display, displayId, softwareDevice); + if (renderer) { status = renderer->initialize(); @@ -251,6 +273,7 @@ rx::Renderer *glCreateRenderer(egl::Display *display, HDC hDc, EGLNativeDisplayT { return renderer; } +#endif // ANGLE_ENABLE_D3D9 return NULL; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h index ac67c27e71..79578b2458 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer.h @@ -14,30 +14,6 @@ #include "libGLESv2/Uniform.h" #include "libGLESv2/angletypes.h" -#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL0 -#define D3DCOMPILE_OPTIMIZATION_LEVEL0 (1 << 14) -#endif -#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL1 -#define D3DCOMPILE_OPTIMIZATION_LEVEL1 0 -#endif -#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL2 -#define D3DCOMPILE_OPTIMIZATION_LEVEL2 ((1 << 14) | (1 << 15)) -#endif -#ifndef D3DCOMPILE_OPTIMIZATION_LEVEL3 -#define D3DCOMPILE_OPTIMIZATION_LEVEL3 (1 << 15) -#endif -#ifndef D3DCOMPILE_DEBUG -#define D3DCOMPILE_DEBUG (1 << 0) -#endif -#ifndef D3DCOMPILE_SKIP_OPTIMIZATION -#define D3DCOMPILE_SKIP_OPTIMIZATION (1 << 2) -#endif -#ifndef D3DCOMPILE_AVOID_FLOW_CONTROL -#define D3DCOMPILE_AVOID_FLOW_CONTROL (1 << 9) -#endif -#ifndef D3DCOMPILE_PREFER_FLOW_CONTROL -#define D3DCOMPILE_PREFER_FLOW_CONTROL (1 << 10) -#endif #if !defined(ANGLE_COMPILE_OPTIMIZATION_LEVEL) #define ANGLE_COMPILE_OPTIMIZATION_LEVEL D3DCOMPILE_OPTIMIZATION_LEVEL3 #endif @@ -118,6 +94,12 @@ enum ShaderType SHADER_GEOMETRY }; +enum D3DWorkaroundType +{ + ANGLE_D3D_WORKAROUND_NONE, + ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER +}; + class Renderer { public: @@ -138,7 +120,7 @@ class Renderer virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture) = 0; virtual void setRasterizerState(const gl::RasterizerState &rasterState) = 0; - virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, + virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::Color &blendColor, unsigned int sampleMask) = 0; virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, int stencilBackRef, bool frontFaceCCW) = 0; @@ -232,7 +214,7 @@ class Renderer // Shader operations virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type) = 0; - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type) = 0; + virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) = 0; // Image operations virtual Image *createImage() = 0; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp deleted file mode 100644 index f83e9e91ce..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.cpp +++ /dev/null @@ -1,3672 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. - -#include "libGLESv2/main.h" -#include "libGLESv2/utilities.h" -#include "libGLESv2/Buffer.h" -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/RenderBuffer.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/RenderTarget11.h" -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/renderer/ShaderExecutable11.h" -#include "libGLESv2/renderer/SwapChain11.h" -#include "libGLESv2/renderer/Image11.h" -#include "libGLESv2/renderer/VertexBuffer11.h" -#include "libGLESv2/renderer/IndexBuffer11.h" -#include "libGLESv2/renderer/BufferStorage11.h" -#include "libGLESv2/renderer/VertexDataManager.h" -#include "libGLESv2/renderer/IndexDataManager.h" -#include "libGLESv2/renderer/TextureStorage11.h" -#include "libGLESv2/renderer/Query11.h" -#include "libGLESv2/renderer/Fence11.h" - -#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughrgb11ps.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughlum11ps.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughlumalpha11ps.h" - -#include "libGLESv2/renderer/shaders/compiled/clear11vs.h" -#include "libGLESv2/renderer/shaders/compiled/clearsingle11ps.h" -#include "libGLESv2/renderer/shaders/compiled/clearmultiple11ps.h" - -#include "libEGL/Display.h" - -#ifdef _DEBUG -// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples -// and conformance tests. to enable all warnings, remove this define. -#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1 -#endif - -namespace rx -{ -static const DXGI_FORMAT RenderTargetFormats[] = - { - DXGI_FORMAT_B8G8R8A8_UNORM, - DXGI_FORMAT_R8G8B8A8_UNORM - }; - -static const DXGI_FORMAT DepthStencilFormats[] = - { - DXGI_FORMAT_UNKNOWN, - DXGI_FORMAT_D24_UNORM_S8_UINT, - DXGI_FORMAT_D16_UNORM - }; - -enum -{ - MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 -}; - -Renderer11::Renderer11(egl::Display *display, HDC hDc) : Renderer(display), mDc(hDc) -{ - mVertexDataManager = NULL; - mIndexDataManager = NULL; - - mLineLoopIB = NULL; - mTriangleFanIB = NULL; - - mCopyResourcesInitialized = false; - mCopyVB = NULL; - mCopySampler = NULL; - mCopyIL = NULL; - mCopyVS = NULL; - mCopyRGBAPS = NULL; - mCopyRGBPS = NULL; - mCopyLumPS = NULL; - mCopyLumAlphaPS = NULL; - - mClearResourcesInitialized = false; - mClearVB = NULL; - mClearIL = NULL; - mClearVS = NULL; - mClearSinglePS = NULL; - mClearMultiplePS = NULL; - mClearScissorRS = NULL; - mClearNoScissorRS = NULL; - - mSyncQuery = NULL; - - mD3d11Module = NULL; - mDxgiModule = NULL; - - mDeviceLost = false; - - mMaxSupportedSamples = 0; - - mDevice = NULL; - mDeviceContext = NULL; - mDxgiAdapter = NULL; - mDxgiFactory = NULL; - - mDriverConstantBufferVS = NULL; - mDriverConstantBufferPS = NULL; - - mBGRATextureSupport = false; - - mIsGeometryShaderActive = false; -} - -Renderer11::~Renderer11() -{ - release(); -} - -Renderer11 *Renderer11::makeRenderer11(Renderer *renderer) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer)); - return static_cast(renderer); -} - -#ifndef __d3d11_1_h__ -#define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081) -#endif - -EGLint Renderer11::initialize() -{ - if (!initializeCompiler()) - { - return EGL_NOT_INITIALIZED; - } - -#if !defined(ANGLE_OS_WINRT) - mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); - mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); - - if (mD3d11Module == NULL || mDxgiModule == NULL) - { - ERR("Could not load D3D11 or DXGI library - aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - // create the D3D11 device - ASSERT(mDevice == NULL); - PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); - - if (D3D11CreateDevice == NULL) - { - ERR("Could not retrieve D3D11CreateDevice address - aborting!\n"); - return EGL_NOT_INITIALIZED; - } -#endif - - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, - }; - - HRESULT result = S_OK; - -#ifdef _DEBUG - result = D3D11CreateDevice(NULL, - D3D_DRIVER_TYPE_HARDWARE, - NULL, - D3D11_CREATE_DEVICE_DEBUG, - featureLevels, - ArraySize(featureLevels), - D3D11_SDK_VERSION, - &mDevice, - &mFeatureLevel, - &mDeviceContext); - - if (!mDevice || FAILED(result)) - { - ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); - } - - if (!mDevice || FAILED(result)) -#endif - { - result = D3D11CreateDevice(NULL, - D3D_DRIVER_TYPE_HARDWARE, - NULL, - 0, - featureLevels, - ArraySize(featureLevels), - D3D11_SDK_VERSION, - &mDevice, - &mFeatureLevel, - &mDeviceContext); - - if (!mDevice || FAILED(result)) - { - ERR("Could not create D3D11 device - aborting!\n"); - return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer - } - } - -#if !defined(ANGLE_OS_WINRT) - IDXGIDevice *dxgiDevice = NULL; -#else - IDXGIDevice1 *dxgiDevice = NULL; -#endif - result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); - - if (FAILED(result)) - { - ERR("Could not query DXGI device - aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter); - - if (FAILED(result)) - { - ERR("Could not retrieve DXGI adapter - aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - dxgiDevice->Release(); - - mDxgiAdapter->GetDesc(&mAdapterDescription); - memset(mDescription, 0, sizeof(mDescription)); - wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1); - - result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory); - - if (!mDxgiFactory || FAILED(result)) - { - ERR("Could not create DXGI factory - aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log -#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) - ID3D11InfoQueue *infoQueue; - result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); - - if (SUCCEEDED(result)) - { - D3D11_MESSAGE_ID hideMessages[] = - { - D3D11_MESSAGE_ID_DEVICE_OMSETRENDERTARGETS_HAZARD, - D3D11_MESSAGE_ID_DEVICE_PSSETSHADERRESOURCES_HAZARD, - D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET - }; - - D3D11_INFO_QUEUE_FILTER filter = {0}; - filter.DenyList.NumIDs = ArraySize(hideMessages); - filter.DenyList.pIDList = hideMessages; - - infoQueue->AddStorageFilterEntries(&filter); - - infoQueue->Release(); - } -#endif - - unsigned int maxSupportedSamples = 0; - unsigned int rtFormatCount = ArraySize(RenderTargetFormats); - unsigned int dsFormatCount = ArraySize(DepthStencilFormats); - for (unsigned int i = 0; i < rtFormatCount + dsFormatCount; ++i) - { - DXGI_FORMAT format = (i < rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount]; - if (format != DXGI_FORMAT_UNKNOWN) - { - UINT formatSupport; - result = mDevice->CheckFormatSupport(format, &formatSupport); - if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) - { - MultisampleSupportInfo supportInfo; - - for (unsigned int j = 1; j <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++) - { - result = mDevice->CheckMultisampleQualityLevels(format, j, &supportInfo.qualityLevels[j - 1]); - if (SUCCEEDED(result) && supportInfo.qualityLevels[j - 1] > 0) - { - maxSupportedSamples = std::max(j, maxSupportedSamples); - } - else - { - supportInfo.qualityLevels[j - 1] = 0; - } - } - - mMultisampleSupportMap.insert(std::make_pair(format, supportInfo)); - } - } - } - mMaxSupportedSamples = maxSupportedSamples; - - initializeDevice(); - - // BGRA texture support is optional in feature levels 10 and 10_1 - UINT formatSupport; - result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport); - if (FAILED(result)) - { - ERR("Error checking BGRA format support: 0x%08X", result); - } - else - { - const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET); - mBGRATextureSupport = (formatSupport & flags) == flags; - } - - // Check floating point texture support - static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE; - static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET; - static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; - - DXGI_FORMAT float16Formats[] = - { - DXGI_FORMAT_R16_FLOAT, - DXGI_FORMAT_R16G16_FLOAT, - DXGI_FORMAT_R16G16B16A16_FLOAT, - }; - - DXGI_FORMAT float32Formats[] = - { - DXGI_FORMAT_R32_FLOAT, - DXGI_FORMAT_R32G32_FLOAT, - DXGI_FORMAT_R32G32B32A32_FLOAT, - }; - - mFloat16TextureSupport = true; - mFloat16FilterSupport = true; - mFloat16RenderSupport = true; - for (unsigned int i = 0; i < ArraySize(float16Formats); i++) - { - if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport))) - { - mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags; - mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags; - mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags; - } - else - { - mFloat16TextureSupport = false; - mFloat16RenderSupport = false; - mFloat16FilterSupport = false; - } - } - - mFloat32TextureSupport = true; - mFloat32FilterSupport = true; - mFloat32RenderSupport = true; - for (unsigned int i = 0; i < ArraySize(float32Formats); i++) - { - if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport))) - { - mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags; - mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags; - mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags; - } - else - { - mFloat32TextureSupport = false; - mFloat32FilterSupport = false; - mFloat32RenderSupport = false; - } - } - - // Check compressed texture support - const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D; - - if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport))) - { - mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags; - } - else - { - mDXT1TextureSupport = false; - } - - if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport))) - { - mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags; - } - else - { - mDXT3TextureSupport = false; - } - - if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport))) - { - mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags; - } - else - { - mDXT5TextureSupport = false; - } - - // Check depth texture support - DXGI_FORMAT depthTextureFormats[] = - { - DXGI_FORMAT_D16_UNORM, - DXGI_FORMAT_D24_UNORM_S8_UINT, - }; - - static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL | - D3D11_FORMAT_SUPPORT_TEXTURE2D; - - mDepthTextureSupport = true; - for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++) - { - if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport))) - { - mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags); - } - else - { - mDepthTextureSupport = false; - } - } - - return EGL_SUCCESS; -} - -// 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 Renderer11::initializeDevice() -{ - mStateCache.initialize(mDevice); - mInputLayoutCache.initialize(mDevice, mDeviceContext); - - ASSERT(!mVertexDataManager && !mIndexDataManager); - mVertexDataManager = new VertexDataManager(this); - mIndexDataManager = new IndexDataManager(this); - - markAllStateDirty(); -} - -int Renderer11::generateConfigs(ConfigDesc **configDescList) -{ - unsigned int numRenderFormats = ArraySize(RenderTargetFormats); - unsigned int numDepthFormats = ArraySize(DepthStencilFormats); - (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; - int numConfigs = 0; - - for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) - { - for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) - { - DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; - - UINT formatSupport = 0; - HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport); - - if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) - { - DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; - - bool depthStencilFormatOK = true; - - if (depthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - UINT formatSupport = 0; - result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport); - depthStencilFormatOK = SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); - } - - if (depthStencilFormatOK) - { - ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat); - newConfig.multiSample = 0; // FIXME: enumerate multi-sampling - newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast - - (*configDescList)[numConfigs++] = newConfig; - } - } - } - } - - return numConfigs; -} - -void Renderer11::deleteConfigs(ConfigDesc *configDescList) -{ - delete [] (configDescList); -} - -void Renderer11::sync(bool block) -{ - if (block) - { - HRESULT result; - - if (!mSyncQuery) - { - D3D11_QUERY_DESC queryDesc; - queryDesc.Query = D3D11_QUERY_EVENT; - queryDesc.MiscFlags = 0; - - result = mDevice->CreateQuery(&queryDesc, &mSyncQuery); - ASSERT(SUCCEEDED(result)); - } - - mDeviceContext->End(mSyncQuery); - mDeviceContext->Flush(); - - do - { - result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); - - // Keep polling, but allow other threads to do something useful first - Sleep(0); - - if (testDeviceLost(true)) - { - return; - } - } - while (result == S_FALSE); - } - else - { - mDeviceContext->Flush(); - } -} - -SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) -{ - return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); -} - -void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) -{ - if (type == gl::SAMPLER_PIXEL) - { - if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) - { - ERR("Pixel shader sampler index %i is not valid.", index); - return; - } - - if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) - { - ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); - - if (!dxSamplerState) - { - ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" - "sampler state for pixel shaders at slot %i.", index); - } - - mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); - - mCurPixelSamplerStates[index] = samplerState; - } - - mForceSetPixelSamplerStates[index] = false; - } - else if (type == gl::SAMPLER_VERTEX) - { - if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) - { - ERR("Vertex shader sampler index %i is not valid.", index); - return; - } - - if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) - { - ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); - - if (!dxSamplerState) - { - ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" - "sampler state for vertex shaders at slot %i.", index); - } - - mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); - - mCurVertexSamplerStates[index] = samplerState; - } - - mForceSetVertexSamplerStates[index] = false; - } - else UNREACHABLE(); -} - -void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) -{ - ID3D11ShaderResourceView *textureSRV = NULL; - unsigned int serial = 0; - bool forceSetTexture = false; - - if (texture) - { - TextureStorageInterface *texStorage = texture->getNativeTexture(); - if (texStorage) - { - TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); - textureSRV = storage11->getSRV(); - } - - // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly - // missing the shader resource view - ASSERT(textureSRV != NULL); - - serial = texture->getTextureSerial(); - forceSetTexture = texture->hasDirtyImages(); - } - - if (type == gl::SAMPLER_PIXEL) - { - if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) - { - ERR("Pixel shader sampler index %i is not valid.", index); - return; - } - - if (forceSetTexture || mCurPixelTextureSerials[index] != serial) - { - mDeviceContext->PSSetShaderResources(index, 1, &textureSRV); - } - - mCurPixelTextureSerials[index] = serial; - } - else if (type == gl::SAMPLER_VERTEX) - { - if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) - { - ERR("Vertex shader sampler index %i is not valid.", index); - return; - } - - if (forceSetTexture || mCurVertexTextureSerials[index] != serial) - { - mDeviceContext->VSSetShaderResources(index, 1, &textureSRV); - } - - mCurVertexTextureSerials[index] = serial; - } - else UNREACHABLE(); -} - -void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) -{ - if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) - { - ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled, - mCurDepthSize); - if (!dxRasterState) - { - ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default" - "rasterizer state."); - } - - mDeviceContext->RSSetState(dxRasterState); - - mCurRasterState = rasterState; - } - - mForceSetRasterState = false; -} - -void Renderer11::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, - unsigned int sampleMask) -{ - if (mForceSetBlendState || - memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 || - memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 || - sampleMask != mCurSampleMask) - { - ID3D11BlendState *dxBlendState = mStateCache.getBlendState(blendState); - if (!dxBlendState) - { - ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " - "blend state."); - } - - float blendColors[4] = {0.0f}; - if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && - blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) - { - blendColors[0] = blendColor.red; - blendColors[1] = blendColor.green; - blendColors[2] = blendColor.blue; - blendColors[3] = blendColor.alpha; - } - else - { - blendColors[0] = blendColor.alpha; - blendColors[1] = blendColor.alpha; - blendColors[2] = blendColor.alpha; - blendColors[3] = blendColor.alpha; - } - - mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); - - mCurBlendState = blendState; - mCurBlendColor = blendColor; - mCurSampleMask = sampleMask; - } - - mForceSetBlendState = false; -} - -void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) -{ - if (mForceSetDepthStencilState || - memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 || - stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef) - { - if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask || - stencilRef != stencilBackRef || - depthStencilState.stencilMask != depthStencilState.stencilBackMask) - { - ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are " - "invalid under WebGL."); - return gl::error(GL_INVALID_OPERATION); - } - - ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState); - if (!dxDepthStencilState) - { - ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, " - "setting the default depth stencil state."); - } - - mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast(stencilRef)); - - mCurDepthStencilState = depthStencilState; - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; - } - - mForceSetDepthStencilState = false; -} - -void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) -{ - if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || - enabled != mScissorEnabled) - { - if (enabled) - { - D3D11_RECT rect; - rect.left = std::max(0, scissor.x); - rect.top = std::max(0, scissor.y); - rect.right = scissor.x + std::max(0, scissor.width); - rect.bottom = scissor.y + std::max(0, scissor.height); - - mDeviceContext->RSSetScissorRects(1, &rect); - } - - if (enabled != mScissorEnabled) - { - mForceSetRasterState = true; - } - - mCurScissor = scissor; - mScissorEnabled = enabled; - } - - mForceSetScissor = false; -} - -bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport) -{ - gl::Rectangle actualViewport = viewport; - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - if (ignoreViewport) - { - actualViewport.x = 0; - actualViewport.y = 0; - actualViewport.width = mRenderTargetDesc.width; - actualViewport.height = mRenderTargetDesc.height; - actualZNear = 0.0f; - actualZFar = 1.0f; - } - - // Get D3D viewport bounds, which depends on the feature level - const Range& viewportBounds = getViewportBounds(); - - // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds - D3D11_VIEWPORT dxViewport; - dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end); - dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end); - dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension()); - dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension()); - dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast(dxViewport.TopLeftX)); - dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast(dxViewport.TopLeftY)); - dxViewport.MinDepth = actualZNear; - dxViewport.MaxDepth = actualZFar; - - if (dxViewport.Width <= 0 || dxViewport.Height <= 0) - { - return false; // Nothing to render - } - - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar; - - if (viewportChanged) - { - mDeviceContext->RSSetViewports(1, &dxViewport); - - mCurViewport = actualViewport; - mCurNear = actualZNear; - mCurFar = actualZFar; - - mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f; - mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f; - mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); - mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); - - mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f; - mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - - mVertexConstants.depthRange[0] = actualZNear; - mVertexConstants.depthRange[1] = actualZFar; - mVertexConstants.depthRange[2] = actualZFar - actualZNear; - - mPixelConstants.depthRange[0] = actualZNear; - mPixelConstants.depthRange[1] = actualZFar; - mPixelConstants.depthRange[2] = actualZFar - actualZNear; - } - - mForceSetViewport = false; - return true; -} - -bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) -{ - D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; - - GLsizei minCount = 0; - - switch (mode) - { - case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; minCount = 1; break; - case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; minCount = 2; break; - case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; - case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; - case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; - case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break; - // emulate fans via rewriting index buffer - case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; - default: - return gl::error(GL_INVALID_ENUM, false); - } - - if (primitiveTopology != mCurrentPrimitiveTopology) - { - mDeviceContext->IASetPrimitiveTopology(primitiveTopology); - mCurrentPrimitiveTopology = primitiveTopology; - } - - return count >= minCount; -} - -bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) -{ - // Get the color render buffer and serial - // Also extract the render target dimensions and view - unsigned int renderTargetWidth = 0; - unsigned int renderTargetHeight = 0; - GLenum renderTargetFormat = 0; - unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0}; - ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; - bool missingColorRenderTarget = true; - - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) - { - const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment); - - if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE) - { - // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order) - ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment)); - - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(colorAttachment); - - if (!colorbuffer) - { - ERR("render target pointer unexpectedly null."); - return false; - } - - // check for zero-sized default framebuffer, which is a special case. - // in this case we do not wish to modify any state and just silently return false. - // this will not report any gl error but will cause the calling method to return. - if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0) - { - return false; - } - - renderTargetSerials[colorAttachment] = colorbuffer->getSerial(); - - // Extract the render target dimensions and view - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); - if (!renderTarget) - { - ERR("render target pointer unexpectedly null."); - return false; - } - - framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); - if (!framebufferRTVs[colorAttachment]) - { - ERR("render target view pointer unexpectedly null."); - return false; - } - - if (missingColorRenderTarget) - { - renderTargetWidth = colorbuffer->getWidth(); - renderTargetHeight = colorbuffer->getHeight(); - renderTargetFormat = colorbuffer->getActualFormat(); - missingColorRenderTarget = false; - } - } - } - - // Get the depth stencil render buffer and serials - gl::Renderbuffer *depthStencil = NULL; - unsigned int depthbufferSerial = 0; - unsigned int stencilbufferSerial = 0; - if (framebuffer->getDepthbufferType() != GL_NONE) - { - depthStencil = framebuffer->getDepthbuffer(); - if (!depthStencil) - { - ERR("Depth stencil pointer unexpectedly null."); - SafeRelease(framebufferRTVs); - return false; - } - - depthbufferSerial = depthStencil->getSerial(); - } - else if (framebuffer->getStencilbufferType() != GL_NONE) - { - depthStencil = framebuffer->getStencilbuffer(); - if (!depthStencil) - { - ERR("Depth stencil pointer unexpectedly null."); - SafeRelease(framebufferRTVs); - return false; - } - - stencilbufferSerial = depthStencil->getSerial(); - } - - // Extract the depth stencil sizes and view - unsigned int depthSize = 0; - unsigned int stencilSize = 0; - ID3D11DepthStencilView* framebufferDSV = NULL; - if (depthStencil) - { - RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil()); - if (!depthStencilRenderTarget) - { - ERR("render target pointer unexpectedly null."); - SafeRelease(framebufferRTVs); - return false; - } - - framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); - if (!framebufferDSV) - { - ERR("depth stencil view pointer unexpectedly null."); - SafeRelease(framebufferRTVs); - return false; - } - - // If there is no render buffer, the width, height and format values come from - // the depth stencil - if (missingColorRenderTarget) - { - renderTargetWidth = depthStencil->getWidth(); - renderTargetHeight = depthStencil->getHeight(); - renderTargetFormat = depthStencil->getActualFormat(); - } - - depthSize = depthStencil->getDepthSize(); - stencilSize = depthStencil->getStencilSize(); - } - - // Apply the render target and depth stencil - if (!mRenderTargetDescInitialized || !mDepthStencilInitialized || - memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 || - depthbufferSerial != mAppliedDepthbufferSerial || - stencilbufferSerial != mAppliedStencilbufferSerial) - { - mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV); - - mRenderTargetDesc.width = renderTargetWidth; - mRenderTargetDesc.height = renderTargetHeight; - mRenderTargetDesc.format = renderTargetFormat; - mForceSetViewport = true; - mForceSetScissor = true; - - if (!mDepthStencilInitialized || depthSize != mCurDepthSize) - { - mCurDepthSize = depthSize; - mForceSetRasterState = true; - } - - mCurStencilSize = stencilSize; - - for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) - { - mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex]; - } - mAppliedDepthbufferSerial = depthbufferSerial; - mAppliedStencilbufferSerial = stencilbufferSerial; - mRenderTargetDescInitialized = true; - mDepthStencilInitialized = true; - } - - return true; -} - -GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) -{ - TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances); - if (err != GL_NO_ERROR) - { - return err; - } - - return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); -} - -GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) -{ - GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); - - if (err == GL_NO_ERROR) - { - if (indexInfo->storage) - { - if (indexInfo->serial != mAppliedStorageIBSerial || indexInfo->startOffset != mAppliedIBOffset) - { - BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage); - IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); - - mDeviceContext->IASetIndexBuffer(storage->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset); - - mAppliedIBSerial = 0; - mAppliedStorageIBSerial = storage->getSerial(); - mAppliedIBOffset = indexInfo->startOffset; - } - } - else if (indexInfo->serial != mAppliedIBSerial || indexInfo->startOffset != mAppliedIBOffset) - { - IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); - - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset); - - mAppliedIBSerial = indexInfo->serial; - mAppliedStorageIBSerial = 0; - mAppliedIBOffset = indexInfo->startOffset; - } - } - - return err; -} - -void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances) -{ - if (mode == GL_LINE_LOOP) - { - drawLineLoop(count, GL_NONE, NULL, 0, NULL); - } - else if (mode == GL_TRIANGLE_FAN) - { - drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); - } - else if (instances > 0) - { - mDeviceContext->DrawInstanced(count, instances, 0, 0); - } - else - { - mDeviceContext->Draw(count, 0); - } -} - -void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) -{ - if (mode == GL_LINE_LOOP) - { - drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); - } - else if (mode == GL_TRIANGLE_FAN) - { - drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances); - } - else if (instances > 0) - { - mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast(indexInfo.minIndex), 0); - } - else - { - mDeviceContext->DrawIndexed(count, 0, -static_cast(indexInfo.minIndex)); - } -} - -template -static void drawLineLoopIndexed(T *data, GLenum type, const GLvoid *indices, GLsizei count) -{ - 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(); - } -} - -void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) -{ - // Get the raw indices for an indexed draw - if (type != GL_NONE && elementArrayBuffer) - { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferStorage *storage = indexBuffer->getStorage(); - intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; - } - - if (!mLineLoopIB) - { - mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) - { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - // Checked by Renderer11::applyPrimitiveType - ASSERT(count >= 0); - - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) - { - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); - } - - const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned int); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) - { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - void* mappedMemory = NULL; - unsigned int offset; - if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) - { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - if (get32BitIndexSupport()) - drawLineLoopIndexed(reinterpret_cast(mappedMemory), type, indices, count); - else - drawLineLoopIndexed(reinterpret_cast(mappedMemory), type, indices, count); - - unsigned int indexBufferOffset = offset; - - if (!mLineLoopIB->unmapBuffer()) - { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset) - { - IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); - - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); - mAppliedIBSerial = mLineLoopIB->getSerial(); - mAppliedStorageIBSerial = 0; - mAppliedIBOffset = indexBufferOffset; - } - - mDeviceContext->DrawIndexed(count + 1, 0, -minIndex); -} - -template -static void drawTriangleFanIndexed(T *data, GLenum type, const GLvoid *indices, unsigned int numTris) -{ - switch (type) - { - case GL_NONE: // Non-indexed draw - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = 0; - data[i*3 + 1] = i + 1; - data[i*3 + 2] = i + 2; - } - break; - case GL_UNSIGNED_BYTE: - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = static_cast(indices)[0]; - data[i*3 + 1] = static_cast(indices)[i + 1]; - data[i*3 + 2] = static_cast(indices)[i + 2]; - } - break; - case GL_UNSIGNED_SHORT: - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = static_cast(indices)[0]; - data[i*3 + 1] = static_cast(indices)[i + 1]; - data[i*3 + 2] = static_cast(indices)[i + 2]; - } - break; - case GL_UNSIGNED_INT: - for (unsigned int i = 0; i < numTris; i++) - { - data[i*3 + 0] = static_cast(indices)[0]; - data[i*3 + 1] = static_cast(indices)[i + 1]; - data[i*3 + 2] = static_cast(indices)[i + 2]; - } - break; - default: UNREACHABLE(); - } -} - -void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) -{ - // Get the raw indices for an indexed draw - if (type != GL_NONE && elementArrayBuffer) - { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferStorage *storage = indexBuffer->getStorage(); - intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; - } - - if (!mTriangleFanIB) - { - mTriangleFanIB = new StreamingIndexBufferInterface(this); - if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) - { - delete mTriangleFanIB; - mTriangleFanIB = NULL; - - ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - // Checked by Renderer11::applyPrimitiveType - ASSERT(count >= 3); - - const unsigned int numTris = count - 2; - - if (numTris > (std::numeric_limits::max() / (sizeof(unsigned int) * 3))) - { - ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); - } - - const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int); - if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) - { - ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); - } - - void* mappedMemory = NULL; - unsigned int offset; - if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) - { - ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); - } - - if (get32BitIndexSupport()) - drawTriangleFanIndexed(reinterpret_cast(mappedMemory), type, indices, numTris); - else - drawTriangleFanIndexed(reinterpret_cast(mappedMemory), type, indices, numTris); - - unsigned int indexBufferOffset = offset; - - if (!mTriangleFanIB->unmapBuffer()) - { - ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN."); - return gl::error(GL_OUT_OF_MEMORY); - } - - if (mAppliedIBSerial != mTriangleFanIB->getSerial() || mAppliedIBOffset != indexBufferOffset) - { - IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); - - mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); - mAppliedIBSerial = mTriangleFanIB->getSerial(); - mAppliedStorageIBSerial = 0; - mAppliedIBOffset = indexBufferOffset; - } - - if (instances > 0) - { - mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0); - } - else - { - mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex); - } -} - -void Renderer11::applyShaders(gl::ProgramBinary *programBinary) -{ - unsigned int programBinarySerial = programBinary->getSerial(); - const bool updateProgramState = (programBinarySerial != mAppliedProgramBinarySerial); - - if (updateProgramState) - { - ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); - ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); - - ID3D11VertexShader *vertexShader = NULL; - if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader(); - - ID3D11PixelShader *pixelShader = NULL; - if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader(); - - mDeviceContext->PSSetShader(pixelShader, NULL, 0); - mDeviceContext->VSSetShader(vertexShader, NULL, 0); - - programBinary->dirtyAllUniforms(); - - mAppliedProgramBinarySerial = programBinarySerial; - } - - // Only use the geometry shader currently for point sprite drawing - const bool usesGeometryShader = (programBinary->usesGeometryShader() && mCurRasterState.pointDrawMode); - - if (updateProgramState || usesGeometryShader != mIsGeometryShaderActive) - { - if (usesGeometryShader) - { - ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); - ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader(); - mDeviceContext->GSSetShader(geometryShader, NULL, 0); - } - else - { - mDeviceContext->GSSetShader(NULL, NULL, 0); - } - - mIsGeometryShaderActive = usesGeometryShader; - } -} - -void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) -{ - ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); - ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable()); - - unsigned int totalRegisterCountVS = 0; - unsigned int totalRegisterCountPS = 0; - - bool vertexUniformsDirty = false; - bool pixelUniformsDirty = false; - - for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) - { - const gl::Uniform *uniform = *uniform_iterator; - - if (uniform->vsRegisterIndex >= 0) - { - totalRegisterCountVS += uniform->registerCount; - vertexUniformsDirty = vertexUniformsDirty || uniform->dirty; - } - - if (uniform->psRegisterIndex >= 0) - { - totalRegisterCountPS += uniform->registerCount; - pixelUniformsDirty = pixelUniformsDirty || uniform->dirty; - } - } - - ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(mDevice, totalRegisterCountVS); - ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(mDevice, totalRegisterCountPS); - - float (*mapVS)[4] = NULL; - float (*mapPS)[4] = NULL; - - if (totalRegisterCountVS > 0 && vertexUniformsDirty) - { - D3D11_MAPPED_SUBRESOURCE map = {0}; - HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - ASSERT(SUCCEEDED(result)); - mapVS = (float(*)[4])map.pData; - } - - if (totalRegisterCountPS > 0 && pixelUniformsDirty) - { - D3D11_MAPPED_SUBRESOURCE map = {0}; - HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); - ASSERT(SUCCEEDED(result)); - mapPS = (float(*)[4])map.pData; - } - - for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) - { - gl::Uniform *uniform = *uniform_iterator; - - if (uniform->type != GL_SAMPLER_2D && uniform->type != GL_SAMPLER_CUBE) - { - if (uniform->vsRegisterIndex >= 0 && mapVS) - { - memcpy(mapVS + uniform->vsRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4])); - } - - if (uniform->psRegisterIndex >= 0 && mapPS) - { - memcpy(mapPS + uniform->psRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4])); - } - } - - uniform->dirty = false; - } - - if (mapVS) - { - mDeviceContext->Unmap(vertexConstantBuffer, 0); - } - - if (mapPS) - { - mDeviceContext->Unmap(pixelConstantBuffer, 0); - } - - if (mCurrentVertexConstantBuffer != vertexConstantBuffer) - { - mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); - mCurrentVertexConstantBuffer = vertexConstantBuffer; - } - - if (mCurrentPixelConstantBuffer != pixelConstantBuffer) - { - mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); - mCurrentPixelConstantBuffer = pixelConstantBuffer; - } - - // Driver uniforms - if (!mDriverConstantBufferVS) - { - D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants); - constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = 0; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS); - ASSERT(SUCCEEDED(result)); - - mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS); - } - - if (!mDriverConstantBufferPS) - { - D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants); - constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = 0; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS); - ASSERT(SUCCEEDED(result)); - - mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS); - } - - if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0) - { - mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0); - memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants)); - } - - if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0) - { - mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0); - memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants)); - } - - // needed for the point sprite geometry shader - if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) - { - mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); - mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; - } -} - -void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) -{ - bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha; - bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) && - !(clearParams.colorMaskRed && clearParams.colorMaskGreen && - clearParams.colorMaskBlue && alphaUnmasked); - - unsigned int stencilUnmasked = 0x0; - if (frameBuffer->hasStencil()) - { - unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat()); - stencilUnmasked = (0x1 << stencilSize) - 1; - } - bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) && - (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; - - bool needScissoredClear = mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 || - mCurScissor.x + mCurScissor.width < mRenderTargetDesc.width || - mCurScissor.y + mCurScissor.height < mRenderTargetDesc.height); - - if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear) - { - maskedClear(clearParams, frameBuffer->usingExtendedDrawBuffers()); - } - else - { - if (clearParams.mask & GL_COLOR_BUFFER_BIT) - { - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) - { - if (frameBuffer->isEnabledColorAttachment(colorAttachment)) - { - gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer(colorAttachment); - if (renderbufferObject) - { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget()); - if (!renderTarget) - { - ERR("render target pointer unexpectedly null."); - return; - } - - ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); - if (!framebufferRTV) - { - ERR("render target view pointer unexpectedly null."); - return; - } - - const float clearValues[4] = { clearParams.colorClearValue.red, - clearParams.colorClearValue.green, - clearParams.colorClearValue.blue, - clearParams.colorClearValue.alpha }; - mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues); - } - } - } - } - if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT) - { - gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer(); - if (renderbufferObject) - { - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getDepthStencil()); - if (!renderTarget) - { - ERR("render target pointer unexpectedly null."); - return; - } - - ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); - if (!framebufferDSV) - { - ERR("depth stencil view pointer unexpectedly null."); - return; - } - - UINT clearFlags = 0; - if (clearParams.mask & GL_DEPTH_BUFFER_BIT) - { - clearFlags |= D3D11_CLEAR_DEPTH; - } - if (clearParams.mask & GL_STENCIL_BUFFER_BIT) - { - clearFlags |= D3D11_CLEAR_STENCIL; - } - - float depthClear = gl::clamp01(clearParams.depthClearValue); - UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF; - - mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); - } - } - } -} - -void Renderer11::maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers) -{ - HRESULT result; - - if (!mClearResourcesInitialized) - { - ASSERT(!mClearVB && !mClearVS && !mClearSinglePS && !mClearMultiplePS && !mClearScissorRS && !mClearNoScissorRS); - - D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4; - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; - vbDesc.StructureByteStride = 0; - - result = mDevice->CreateBuffer(&vbDesc, NULL, &mClearVB); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearVB, "Renderer11 masked clear vertex buffer"); - - D3D11_INPUT_ELEMENT_DESC quadLayout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Clear, sizeof(g_VS_Clear), &mClearIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearIL, "Renderer11 masked clear input layout"); - - result = mDevice->CreateVertexShader(g_VS_Clear, sizeof(g_VS_Clear), NULL, &mClearVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearVS, "Renderer11 masked clear vertex shader"); - - result = mDevice->CreatePixelShader(g_PS_ClearSingle, sizeof(g_PS_ClearSingle), NULL, &mClearSinglePS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearSinglePS, "Renderer11 masked clear pixel shader (1 RT)"); - - result = mDevice->CreatePixelShader(g_PS_ClearMultiple, sizeof(g_PS_ClearMultiple), NULL, &mClearMultiplePS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearMultiplePS, "Renderer11 masked clear pixel shader (MRT)"); - - D3D11_RASTERIZER_DESC rsScissorDesc; - rsScissorDesc.FillMode = D3D11_FILL_SOLID; - rsScissorDesc.CullMode = D3D11_CULL_NONE; - rsScissorDesc.FrontCounterClockwise = FALSE; - rsScissorDesc.DepthBias = 0; - rsScissorDesc.DepthBiasClamp = 0.0f; - rsScissorDesc.SlopeScaledDepthBias = 0.0f; - rsScissorDesc.DepthClipEnable = FALSE; - rsScissorDesc.ScissorEnable = TRUE; - rsScissorDesc.MultisampleEnable = FALSE; - rsScissorDesc.AntialiasedLineEnable = FALSE; - - result = mDevice->CreateRasterizerState(&rsScissorDesc, &mClearScissorRS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearScissorRS, "Renderer11 masked clear scissor rasterizer state"); - - D3D11_RASTERIZER_DESC rsNoScissorDesc; - rsNoScissorDesc.FillMode = D3D11_FILL_SOLID; - rsNoScissorDesc.CullMode = D3D11_CULL_NONE; - rsNoScissorDesc.FrontCounterClockwise = FALSE; - rsNoScissorDesc.DepthBias = 0; - rsNoScissorDesc.DepthBiasClamp = 0.0f; - rsNoScissorDesc.SlopeScaledDepthBias = 0.0f; - rsNoScissorDesc.DepthClipEnable = FALSE; - rsNoScissorDesc.ScissorEnable = FALSE; - rsNoScissorDesc.MultisampleEnable = FALSE; - rsNoScissorDesc.AntialiasedLineEnable = FALSE; - - result = mDevice->CreateRasterizerState(&rsNoScissorDesc, &mClearNoScissorRS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mClearNoScissorRS, "Renderer11 masked clear no scissor rasterizer state"); - - mClearResourcesInitialized = true; - } - - // Prepare the depth stencil state to write depth values if the depth should be cleared - // and stencil values if the stencil should be cleared - gl::DepthStencilState glDSState; - glDSState.depthTest = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0; - glDSState.depthFunc = GL_ALWAYS; - glDSState.depthMask = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0; - glDSState.stencilTest = (clearParams.mask & GL_STENCIL_BUFFER_BIT) != 0; - glDSState.stencilFunc = GL_ALWAYS; - glDSState.stencilMask = 0; - glDSState.stencilFail = GL_REPLACE; - glDSState.stencilPassDepthFail = GL_REPLACE; - glDSState.stencilPassDepthPass = GL_REPLACE; - glDSState.stencilWritemask = clearParams.stencilWriteMask; - glDSState.stencilBackFunc = GL_ALWAYS; - glDSState.stencilBackMask = 0; - glDSState.stencilBackFail = GL_REPLACE; - glDSState.stencilBackPassDepthFail = GL_REPLACE; - glDSState.stencilBackPassDepthPass = GL_REPLACE; - glDSState.stencilBackWritemask = clearParams.stencilWriteMask; - - int stencilClear = clearParams.stencilClearValue & 0x000000FF; - - ID3D11DepthStencilState *dsState = mStateCache.getDepthStencilState(glDSState); - - // Prepare the blend state to use a write mask if the color buffer should be cleared - gl::BlendState glBlendState; - glBlendState.blend = false; - glBlendState.sourceBlendRGB = GL_ONE; - glBlendState.destBlendRGB = GL_ZERO; - glBlendState.sourceBlendAlpha = GL_ONE; - glBlendState.destBlendAlpha = GL_ZERO; - glBlendState.blendEquationRGB = GL_FUNC_ADD; - glBlendState.blendEquationAlpha = GL_FUNC_ADD; - glBlendState.colorMaskRed = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskRed : false; - glBlendState.colorMaskGreen = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskGreen : false; - glBlendState.colorMaskBlue = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskBlue : false; - glBlendState.colorMaskAlpha = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskAlpha : false; - glBlendState.sampleAlphaToCoverage = false; - glBlendState.dither = false; - - static const float blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - static const UINT sampleMask = 0xFFFFFFFF; - - ID3D11BlendState *blendState = mStateCache.getBlendState(glBlendState); - - // Set the vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = mDeviceContext->Map(mClearVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result); - return; - } - - d3d11::PositionDepthColorVertex *vertices = reinterpret_cast(mappedResource.pData); - - float depthClear = gl::clamp01(clearParams.depthClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[0], -1.0f, 1.0f, depthClear, clearParams.colorClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[1], -1.0f, -1.0f, depthClear, clearParams.colorClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[2], 1.0f, 1.0f, depthClear, clearParams.colorClearValue); - d3d11::SetPositionDepthColorVertex(&vertices[3], 1.0f, -1.0f, depthClear, clearParams.colorClearValue); - - mDeviceContext->Unmap(mClearVB, 0); - - // Apply state - mDeviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); - mDeviceContext->OMSetDepthStencilState(dsState, stencilClear); - mDeviceContext->RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS); - - // Apply shaders - ID3D11PixelShader *pixelShader = usingExtendedDrawBuffers ? mClearMultiplePS : mClearSinglePS; - - mDeviceContext->IASetInputLayout(mClearIL); - mDeviceContext->VSSetShader(mClearVS, NULL, 0); - mDeviceContext->PSSetShader(pixelShader, NULL, 0); - mDeviceContext->GSSetShader(NULL, NULL, 0); - - // Apply vertex buffer - static UINT stride = sizeof(d3d11::PositionDepthColorVertex); - static UINT startIdx = 0; - mDeviceContext->IASetVertexBuffers(0, 1, &mClearVB, &stride, &startIdx); - mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - - // Draw the clear quad - mDeviceContext->Draw(4, 0); - - // Clean up - markAllStateDirty(); -} - -void Renderer11::markAllStateDirty() -{ - for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) - { - mAppliedRenderTargetSerials[rtIndex] = 0; - } - mAppliedDepthbufferSerial = 0; - mAppliedStencilbufferSerial = 0; - mDepthStencilInitialized = false; - mRenderTargetDescInitialized = false; - - for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) - { - mForceSetVertexSamplerStates[i] = true; - mCurVertexTextureSerials[i] = 0; - } - for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) - { - mForceSetPixelSamplerStates[i] = true; - mCurPixelTextureSerials[i] = 0; - } - - mForceSetBlendState = true; - mForceSetRasterState = true; - mForceSetDepthStencilState = true; - mForceSetScissor = true; - mForceSetViewport = true; - - mAppliedIBSerial = 0; - mAppliedStorageIBSerial = 0; - mAppliedIBOffset = 0; - - mAppliedProgramBinarySerial = 0; - memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants)); - memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants)); - - mInputLayoutCache.markDirty(); - - mCurrentVertexConstantBuffer = NULL; - mCurrentPixelConstantBuffer = NULL; - mCurrentGeometryConstantBuffer = NULL; - - mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; -} - -void Renderer11::releaseDeviceResources() -{ - mStateCache.clear(); - mInputLayoutCache.clear(); - - delete mVertexDataManager; - mVertexDataManager = NULL; - - delete mIndexDataManager; - mIndexDataManager = NULL; - - delete mLineLoopIB; - mLineLoopIB = NULL; - - delete mTriangleFanIB; - mTriangleFanIB = NULL; - - SafeRelease(mCopyVB); - SafeRelease(mCopySampler); - SafeRelease(mCopyIL); - SafeRelease(mCopyIL); - SafeRelease(mCopyVS); - SafeRelease(mCopyRGBAPS); - SafeRelease(mCopyRGBPS); - SafeRelease(mCopyLumPS); - SafeRelease(mCopyLumAlphaPS); - - mCopyResourcesInitialized = false; - - SafeRelease(mClearVB); - SafeRelease(mClearIL); - SafeRelease(mClearVS); - SafeRelease(mClearSinglePS); - SafeRelease(mClearMultiplePS); - SafeRelease(mClearScissorRS); - SafeRelease(mClearNoScissorRS); - - mClearResourcesInitialized = false; - - SafeRelease(mDriverConstantBufferVS); - SafeRelease(mDriverConstantBufferPS); - SafeRelease(mSyncQuery); -} - -void Renderer11::notifyDeviceLost() -{ - mDeviceLost = true; - mDisplay->notifyDeviceLost(); -} - -bool Renderer11::isDeviceLost() -{ - return mDeviceLost; -} - -// set notify to true to broadcast a message to all contexts of the device loss -bool Renderer11::testDeviceLost(bool notify) -{ - bool isLost = false; - - // GetRemovedReason is used to test if the device is removed - HRESULT result = mDevice->GetDeviceRemovedReason(); - isLost = d3d11::isDeviceLostError(result); - - if (isLost) - { - // Log error if this is a new device lost event - if (mDeviceLost == false) - { - ERR("The D3D11 device was removed: 0x%08X", result); - } - - // 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; - if (notify) - { - notifyDeviceLost(); - } - } - - return isLost; -} - -bool Renderer11::testDeviceResettable() -{ - // determine if the device is resettable by creating a dummy device - PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); - - if (D3D11CreateDevice == NULL) - { - return false; - } - - D3D_FEATURE_LEVEL featureLevels[] = - { - D3D_FEATURE_LEVEL_11_1, - D3D_FEATURE_LEVEL_11_0, - D3D_FEATURE_LEVEL_10_1, - D3D_FEATURE_LEVEL_10_0, - D3D_FEATURE_LEVEL_9_3, - D3D_FEATURE_LEVEL_9_2, - D3D_FEATURE_LEVEL_9_1, - }; - - ID3D11Device* dummyDevice; - D3D_FEATURE_LEVEL dummyFeatureLevel; - ID3D11DeviceContext* dummyContext; - - HRESULT result = D3D11CreateDevice(NULL, - D3D_DRIVER_TYPE_HARDWARE, - NULL, - #if defined(_DEBUG) - D3D11_CREATE_DEVICE_DEBUG, - #else - 0, - #endif - featureLevels, - ArraySize(featureLevels), - D3D11_SDK_VERSION, - &dummyDevice, - &dummyFeatureLevel, - &dummyContext); - - if (!mDevice || FAILED(result)) - { - return false; - } - - dummyContext->Release(); - dummyDevice->Release(); - - return true; -} - -void Renderer11::release() -{ - releaseDeviceResources(); - - if (mDxgiFactory) - { - mDxgiFactory->Release(); - mDxgiFactory = NULL; - } - - if (mDxgiAdapter) - { - mDxgiAdapter->Release(); - mDxgiAdapter = NULL; - } - - if (mDeviceContext) - { - mDeviceContext->ClearState(); - mDeviceContext->Flush(); - mDeviceContext->Release(); - mDeviceContext = NULL; - } - - if (mDevice) - { - mDevice->Release(); - mDevice = NULL; - } - - if (mD3d11Module) - { - FreeLibrary(mD3d11Module); - mD3d11Module = NULL; - } - - if (mDxgiModule) - { - FreeLibrary(mDxgiModule); - mDxgiModule = NULL; - } -} - -bool Renderer11::resetDevice() -{ - // recreate everything - release(); - EGLint result = initialize(); - - if (result != EGL_SUCCESS) - { - ERR("Could not reinitialize D3D11 device: %08X", result); - return false; - } - - mDeviceLost = false; - - return true; -} - -DWORD Renderer11::getAdapterVendor() const -{ - return mAdapterDescription.VendorId; -} - -std::string Renderer11::getRendererDescription() const -{ - std::ostringstream rendererString; - - rendererString << mDescription; - rendererString << " Direct3D11"; - - rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel(); - rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel(); - - return rendererString.str(); -} - -GUID Renderer11::getAdapterIdentifier() const -{ - // Use the adapter LUID as our adapter ID - // This number is local to a machine is only guaranteed to be unique between restarts - META_ASSERT(sizeof(LUID) <= sizeof(GUID)); - GUID adapterId = {0}; - memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID)); - return adapterId; -} - -bool Renderer11::getBGRATextureSupport() const -{ - return mBGRATextureSupport; -} - -bool Renderer11::getDXT1TextureSupport() -{ - return mDXT1TextureSupport; -} - -bool Renderer11::getDXT3TextureSupport() -{ - return mDXT3TextureSupport; -} - -bool Renderer11::getDXT5TextureSupport() -{ - return mDXT5TextureSupport; -} - -bool Renderer11::getDepthTextureSupport() const -{ - return mDepthTextureSupport; -} - -bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable) -{ - *renderable = mFloat32RenderSupport; - *filtering = mFloat32FilterSupport; - return mFloat32TextureSupport; -} - -bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable) -{ - *renderable = mFloat16RenderSupport; - *filtering = mFloat16FilterSupport; - return mFloat16TextureSupport; -} - -bool Renderer11::getLuminanceTextureSupport() -{ - return false; -} - -bool Renderer11::getLuminanceAlphaTextureSupport() -{ - return false; -} - -bool Renderer11::getTextureFilterAnisotropySupport() const -{ - return true; -} - -float Renderer11::getTextureMaxAnisotropy() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - return D3D11_MAX_MAXANISOTROPY; - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_MAX_MAXANISOTROPY; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - return 16; - case D3D_FEATURE_LEVEL_9_1: - return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; - default: UNREACHABLE(); - return 0; - } -} - -bool Renderer11::getEventQuerySupport() -{ - return true; -} - -Range Renderer11::getViewportBounds() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX); - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX); - case D3D_FEATURE_LEVEL_9_3: - return Range(D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2); - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return Range(D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2); - default: UNREACHABLE(); - return Range(0, 0); - } -} - -unsigned int Renderer11::getMaxVertexTextureImageUnits() const -{ - META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 0; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxCombinedTextureImageUnits() const -{ - return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); -} - -unsigned int Renderer11::getReservedVertexUniformVectors() const -{ - return 0; // Driver uniforms are stored in a separate constant buffer -} - -unsigned int Renderer11::getReservedFragmentUniformVectors() const -{ - return 0; // Driver uniforms are stored in a separate constant buffer -} - -unsigned int Renderer11::getMaxVertexUniformVectors() const -{ - META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return MAX_VERTEX_UNIFORM_VECTORS_D3D11; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return MAX_VERTEX_UNIFORM_VECTORS_D3D9; - default: - UNIMPLEMENTED(); - return 0; - } -} - -unsigned int Renderer11::getMaxFragmentUniformVectors() const -{ - META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11; - case D3D_FEATURE_LEVEL_9_3: - return 221; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 29; - default: UNREACHABLE(); - return 0; - } -} - -unsigned int Renderer11::getMaxVaryingVectors() const -{ - META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - return D3D11_VS_OUTPUT_REGISTER_COUNT; - case D3D_FEATURE_LEVEL_10_1: - return D3D10_1_VS_OUTPUT_REGISTER_COUNT; - case D3D_FEATURE_LEVEL_10_0: - return D3D10_VS_OUTPUT_REGISTER_COUNT; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return 8; - default: UNREACHABLE(); - return 0; - } -} - -bool Renderer11::getNonPower2TextureSupport() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return true; - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return false; - default: UNREACHABLE(); - return false; - } -} - -bool Renderer11::getOcclusionQuerySupport() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - return true; - case D3D_FEATURE_LEVEL_9_1: - return false; - default: UNREACHABLE(); - return false; - } -} - -bool Renderer11::getInstancingSupport() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - case D3D_FEATURE_LEVEL_9_3: - return true; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return false; - default: UNREACHABLE(); - return false; - } -} - -bool Renderer11::getShareHandleSupport() const -{ - // We only currently support share handles with BGRA surfaces, because - // chrome needs BGRA. Once chrome fixes this, we should always support them. - // PIX doesn't seem to support using share handles, so disable them. - return getBGRATextureSupport() && !gl::perfActive(); -} - -bool Renderer11::getDerivativeInstructionSupport() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - case D3D_FEATURE_LEVEL_9_3: - return true; - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return false; - default: UNREACHABLE(); - return false; - } -} - -bool Renderer11::getPostSubBufferSupport() const -{ - // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2. - return false; -} - -int Renderer11::getMajorShaderModel() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5 - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4 - case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4 - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 4; // SM4 level 9, but treat as 4 - default: UNREACHABLE(); return 0; - } -} - -int Renderer11::getMinorShaderModel() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0 - case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1 - case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0 - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return 0; - default: UNREACHABLE(); return 0; - } -} - -float Renderer11::getMaxPointSize() const -{ - // choose a reasonable maximum. we enforce this in the shader. - // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size) - return 1024.0f; -} - -int Renderer11::getMaxViewportDimension() const -{ - // Maximum viewport size must be at least as large as the largest render buffer (or larger). - // In our case return the maximum texture size, which is the maximum render buffer size. - META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX); - META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX); - - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384 - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192 - case D3D_FEATURE_LEVEL_9_3: - return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096 - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048 - default: UNREACHABLE(); - return 0; - } -} - -int Renderer11::getMaxTextureWidth() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384 - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192 - case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096 - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048 - default: UNREACHABLE(); return 0; - } -} - -int Renderer11::getMaxTextureHeight() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384 - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192 - case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096 - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048 - default: UNREACHABLE(); return 0; - } -} - -bool Renderer11::get32BitIndexSupport() const -{ - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true - case D3D_FEATURE_LEVEL_9_3: - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: return false; - default: UNREACHABLE(); return false; - } -} - -int Renderer11::getMinSwapInterval() const -{ - return 0; -} - -int Renderer11::getMaxSwapInterval() const -{ - return 4; -} - -int Renderer11::getMaxSupportedSamples() const -{ - return mMaxSupportedSamples; -} - -int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const -{ - if (requested == 0) - { - return 0; - } - - MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); - if (iter != mMultisampleSupportMap.end()) - { - const MultisampleSupportInfo& info = iter->second; - for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) - { - if (info.qualityLevels[i] > 0) - { - return i + 1; - } - } - } - - return -1; -} - -unsigned int Renderer11::getMaxRenderTargets() const -{ - META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); - META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); - META_ASSERT(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); - META_ASSERT(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); - - switch (mFeatureLevel) - { - case D3D_FEATURE_LEVEL_11_1: - case D3D_FEATURE_LEVEL_11_0: - return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 - case D3D_FEATURE_LEVEL_10_1: - case D3D_FEATURE_LEVEL_10_0: - return D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 - case D3D_FEATURE_LEVEL_9_3: - return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; // 4 - case D3D_FEATURE_LEVEL_9_2: - case D3D_FEATURE_LEVEL_9_1: - return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; // 1 - default: - UNREACHABLE(); - return 1; - } -} - -bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) -{ - if (source && dest) - { - TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance()); - TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance()); - - mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture()); - return true; - } - - return false; -} - -bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) -{ - if (source && dest) - { - TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance()); - TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance()); - - mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture()); - return true; - } - - return false; -} - -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) -{ - gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); - if (!colorbuffer) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); - if (!sourceRenderTarget) - { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); - if (!storage11) - { - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level)); - if (!destRenderTarget) - { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - gl::Rectangle destRect; - destRect.x = xoffset; - destRect.y = yoffset; - destRect.width = sourceRect.width; - destRect.height = sourceRect.height; - - bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), - dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); - - return ret; -} - -bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) -{ - gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); - if (!colorbuffer) - { - ERR("Failed to retrieve the color buffer from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); - if (!sourceRenderTarget) - { - ERR("Failed to retrieve the render target from the frame buffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); - if (!source) - { - ERR("Failed to retrieve the render target view from the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); - if (!storage11) - { - ERR("Failed to retrieve the texture storage from the destination."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level)); - if (!destRenderTarget) - { - ERR("Failed to retrieve the render target from the destination storage."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); - if (!dest) - { - ERR("Failed to retrieve the render target view from the destination render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - gl::Rectangle destRect; - destRect.x = xoffset; - destRect.y = yoffset; - destRect.width = sourceRect.width; - destRect.height = sourceRect.height; - - bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), - dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); - - return ret; -} - -bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, - ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat) -{ - HRESULT result; - - if (!mCopyResourcesInitialized) - { - ASSERT(!mCopyVB && !mCopySampler && !mCopyIL && !mCopyVS && !mCopyRGBAPS && !mCopyRGBPS && !mCopyLumPS && !mCopyLumAlphaPS); - - D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; - vbDesc.StructureByteStride = 0; - - result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer"); - - D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; - samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.MipLODBias = 0.0f; - samplerDesc.MaxAnisotropy = 0; - samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; - samplerDesc.BorderColor[0] = 0.0f; - samplerDesc.BorderColor[1] = 0.0f; - samplerDesc.BorderColor[2] = 0.0f; - samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = 0.0f; - samplerDesc.MaxLOD = 0.0f; - - result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler"); - - D3D11_INPUT_ELEMENT_DESC quadLayout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mCopyIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyIL, "Renderer11 copy texture input layout"); - - result = mDevice->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mCopyVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyVS, "Renderer11 copy texture vertex shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mCopyRGBAPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyRGBAPS, "Renderer11 copy texture RGBA pixel shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &mCopyRGBPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyRGBPS, "Renderer11 copy texture RGB pixel shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &mCopyLumPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyLumPS, "Renderer11 copy texture luminance pixel shader"); - - result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &mCopyLumAlphaPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mCopyLumAlphaPS, "Renderer11 copy texture luminance alpha pixel shader"); - - mCopyResourcesInitialized = true; - } - - // Verify the source and destination area sizes - if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast(sourceWidth) || - sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast(sourceHeight) || - destArea.x < 0 || destArea.x + destArea.width > static_cast(destWidth) || - destArea.y < 0 || destArea.y + destArea.height > static_cast(destHeight)) - { - return gl::error(GL_INVALID_VALUE, false); - } - - // Set vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); - - // Create a quad in homogeneous coordinates - float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f; - float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f; - float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f; - float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f; - - float u1 = sourceArea.x / float(sourceWidth); - float v1 = sourceArea.y / float(sourceHeight); - float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth); - float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight); - - d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1); - - mDeviceContext->Unmap(mCopyVB, 0); - - static UINT stride = sizeof(d3d11::PositionTexCoordVertex); - static UINT startIdx = 0; - mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx); - - // Apply state - mDeviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); - mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); - mDeviceContext->RSSetState(NULL); - - // Apply shaders - mDeviceContext->IASetInputLayout(mCopyIL); - mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - mDeviceContext->VSSetShader(mCopyVS, NULL, 0); - - ID3D11PixelShader *ps = NULL; - switch(destFormat) - { - case GL_RGBA: ps = mCopyRGBAPS; break; - case GL_RGB: ps = mCopyRGBPS; break; - case GL_ALPHA: ps = mCopyRGBAPS; break; - case GL_BGRA_EXT: ps = mCopyRGBAPS; break; - case GL_LUMINANCE: ps = mCopyLumPS; break; - case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break; - default: UNREACHABLE(); ps = NULL; break; - } - - mDeviceContext->PSSetShader(ps, NULL, 0); - mDeviceContext->GSSetShader(NULL, NULL, 0); - - // Unset the currently bound shader resource to avoid conflicts - static ID3D11ShaderResourceView *const nullSRV = NULL; - mDeviceContext->PSSetShaderResources(0, 1, &nullSRV); - - // Apply render target - setOneTimeRenderTarget(dest); - - // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = destWidth; - viewport.Height = destHeight; - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - mDeviceContext->RSSetViewports(1, &viewport); - - // Apply textures - mDeviceContext->PSSetShaderResources(0, 1, &source); - mDeviceContext->PSSetSamplers(0, 1, &mCopySampler); - - // Draw the quad - mDeviceContext->Draw(4, 0); - - // Unbind textures and render targets and vertex buffer - mDeviceContext->PSSetShaderResources(0, 1, &nullSRV); - - unapplyRenderTargets(); - - UINT zero = 0; - ID3D11Buffer *const nullBuffer = NULL; - mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); - - markAllStateDirty(); - - return true; -} - -void Renderer11::unapplyRenderTargets() -{ - setOneTimeRenderTarget(NULL); -} - -void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView) -{ - ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; - - rtvArray[0] = renderTargetView; - - mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL); - - // Do not preserve the serial for this one-time-use render target - for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) - { - mAppliedRenderTargetSerials[rtIndex] = 0; - } -} - -RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) -{ - SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); - RenderTarget11 *renderTarget = NULL; - - if (depth) - { - // Note: depth stencil may be NULL for 0 sized surfaces - renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), - swapChain11->getDepthStencilTexture(), NULL, - swapChain11->getWidth(), swapChain11->getHeight()); - } - else - { - // Note: render target may be NULL for 0 sized surfaces - renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), - swapChain11->getOffscreenTexture(), - swapChain11->getRenderTargetShaderResource(), - swapChain11->getWidth(), swapChain11->getHeight()); - } - return renderTarget; -} - -RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) -{ - RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples, depth); - return renderTarget; -} - -ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type) -{ - ShaderExecutable11 *executable = NULL; - - switch (type) - { - case rx::SHADER_VERTEX: - { - ID3D11VertexShader *vshader = NULL; - HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader); - ASSERT(SUCCEEDED(result)); - - if (vshader) - { - executable = new ShaderExecutable11(function, length, vshader); - } - } - break; - case rx::SHADER_PIXEL: - { - ID3D11PixelShader *pshader = NULL; - HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader); - ASSERT(SUCCEEDED(result)); - - if (pshader) - { - executable = new ShaderExecutable11(function, length, pshader); - } - } - break; - case rx::SHADER_GEOMETRY: - { - ID3D11GeometryShader *gshader = NULL; - HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &gshader); - ASSERT(SUCCEEDED(result)); - - if (gshader) - { - executable = new ShaderExecutable11(function, length, gshader); - } - } - break; - default: - UNREACHABLE(); - break; - } - - return executable; -} - -ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type) -{ - std::string profile; - - switch (type) - { - case rx::SHADER_VERTEX: - profile = "vs_4_0"; - break; - case rx::SHADER_PIXEL: - profile = "ps_4_0"; - break; - case rx::SHADER_GEOMETRY: - profile = "gs_4_0"; - break; - default: - UNREACHABLE(); - return NULL; - } - - if (mFeatureLevel == D3D_FEATURE_LEVEL_9_3) - profile += "_level_9_3"; - else if (mFeatureLevel == D3D_FEATURE_LEVEL_9_2 || mFeatureLevel == D3D_FEATURE_LEVEL_9_1) - profile += "_level_9_1"; - - ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile.c_str(), D3DCOMPILE_OPTIMIZATION_LEVEL0, false); - if (!binary) - return NULL; - - ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type); - binary->Release(); - - return executable; -} - -VertexBuffer *Renderer11::createVertexBuffer() -{ - return new VertexBuffer11(this); -} - -IndexBuffer *Renderer11::createIndexBuffer() -{ - return new IndexBuffer11(this); -} - -BufferStorage *Renderer11::createBufferStorage() -{ - return new BufferStorage11(this); -} - -QueryImpl *Renderer11::createQuery(GLenum type) -{ - return new Query11(this, type); -} - -FenceImpl *Renderer11::createFence() -{ - return new Fence11(this); -} - -bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) -{ - ASSERT(colorbuffer != NULL); - - RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); - if (renderTarget) - { - *subresourceIndex = renderTarget->getSubresourceIndex(); - - ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView(); - if (colorBufferRTV) - { - ID3D11Resource *textureResource = NULL; - colorBufferRTV->GetResource(&textureResource); - - if (textureResource) - { - HRESULT result = textureResource->QueryInterface(IID_ID3D11Texture2D, (void**)resource); - textureResource->Release(); - - if (SUCCEEDED(result)) - { - return true; - } - else - { - ERR("Failed to extract the ID3D11Texture2D from the render target resource, " - "HRESULT: 0x%X.", result); - } - } - } - } - - return false; -} - -bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil) -{ - if (blitRenderTarget) - { - gl::Renderbuffer *readBuffer = readTarget->getReadColorbuffer(); - - if (!readBuffer) - { - ERR("Failed to retrieve the read buffer from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget *readRenderTarget = readBuffer->getRenderTarget(); - - for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) - { - if (drawTarget->isEnabledColorAttachment(colorAttachment)) - { - gl::Renderbuffer *drawBuffer = drawTarget->getColorbuffer(colorAttachment); - - if (!drawBuffer) - { - ERR("Failed to retrieve the draw buffer from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget(); - - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false)) - { - return false; - } - } - } - } - - if (blitDepthStencil) - { - gl::Renderbuffer *readBuffer = readTarget->getDepthOrStencilbuffer(); - gl::Renderbuffer *drawBuffer = drawTarget->getDepthOrStencilbuffer(); - - if (!readBuffer) - { - ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - if (!drawBuffer) - { - ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RenderTarget *readRenderTarget = readBuffer->getDepthStencil(); - RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil(); - - if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true)) - { - return false; - } - } - - return true; -} - -void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) -{ - ID3D11Texture2D *colorBufferTexture = NULL; - unsigned int subresourceIndex = 0; - - gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); - - if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) - { - gl::Rectangle area; - area.x = x; - area.y = y; - area.width = width; - area.height = height; - - readTextureData(colorBufferTexture, subresourceIndex, area, format, type, outputPitch, - packReverseRowOrder, packAlignment, pixels); - - colorBufferTexture->Release(); - colorBufferTexture = NULL; - } -} - -Image *Renderer11::createImage() -{ - return new Image11(); -} - -void Renderer11::generateMipmap(Image *dest, Image *src) -{ - Image11 *dest11 = Image11::makeImage11(dest); - Image11 *src11 = Image11::makeImage11(src); - Image11::generateMipmap(dest11, src11); -} - -TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) -{ - SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); - return new TextureStorage11_2D(this, swapChain11); -} - -TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) -{ - return new TextureStorage11_2D(this, levels, internalformat, usage, forceRenderable, width, height); -} - -TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) -{ - return new TextureStorage11_Cube(this, levels, internalformat, usage, forceRenderable, size); -} - -static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum destFormat, GLenum destType) -{ - if (sourceFormat == DXGI_FORMAT_A8_UNORM && - destFormat == GL_ALPHA && - destType == GL_UNSIGNED_BYTE) - { - return 1; - } - else if (sourceFormat == DXGI_FORMAT_R8G8B8A8_UNORM && - destFormat == GL_RGBA && - destType == GL_UNSIGNED_BYTE) - { - return 4; - } - else if (sourceFormat == DXGI_FORMAT_B8G8R8A8_UNORM && - destFormat == GL_BGRA_EXT && - destType == GL_UNSIGNED_BYTE) - { - return 4; - } - else if (sourceFormat == DXGI_FORMAT_R16G16B16A16_FLOAT && - destFormat == GL_RGBA && - destType == GL_HALF_FLOAT_OES) - { - return 8; - } - else if (sourceFormat == DXGI_FORMAT_R32G32B32_FLOAT && - destFormat == GL_RGB && - destType == GL_FLOAT) - { - return 12; - } - else if (sourceFormat == DXGI_FORMAT_R32G32B32A32_FLOAT && - destFormat == GL_RGBA && - destType == GL_FLOAT) - { - return 16; - } - else - { - return 0; - } -} - -static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, unsigned int x, - unsigned int y, int inputPitch, gl::Color *outColor) -{ - switch (format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - { - unsigned int rgba = *reinterpret_cast(data + 4 * x + y * inputPitch); - outColor->red = (rgba & 0x000000FF) * (1.0f / 0x000000FF); - outColor->green = (rgba & 0x0000FF00) * (1.0f / 0x0000FF00); - outColor->blue = (rgba & 0x00FF0000) * (1.0f / 0x00FF0000); - outColor->alpha = (rgba & 0xFF000000) * (1.0f / 0xFF000000); - } - break; - - case DXGI_FORMAT_A8_UNORM: - { - outColor->red = 0.0f; - outColor->green = 0.0f; - outColor->blue = 0.0f; - outColor->alpha = *(data + x + y * inputPitch) / 255.0f; - } - break; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - { - outColor->red = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 0); - outColor->green = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 1); - outColor->blue = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 2); - outColor->alpha = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 3); - } - break; - - case DXGI_FORMAT_R32G32B32_FLOAT: - { - outColor->red = *(reinterpret_cast(data + 12 * x + y * inputPitch) + 0); - outColor->green = *(reinterpret_cast(data + 12 * x + y * inputPitch) + 1); - outColor->blue = *(reinterpret_cast(data + 12 * x + y * inputPitch) + 2); - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - { - outColor->red = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 0)); - outColor->green = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 1)); - outColor->blue = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 2)); - outColor->alpha = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 3)); - } - break; - - case DXGI_FORMAT_B8G8R8A8_UNORM: - { - unsigned int bgra = *reinterpret_cast(data + 4 * x + y * inputPitch); - outColor->red = (bgra & 0x00FF0000) * (1.0f / 0x00FF0000); - outColor->blue = (bgra & 0x000000FF) * (1.0f / 0x000000FF); - outColor->green = (bgra & 0x0000FF00) * (1.0f / 0x0000FF00); - outColor->alpha = (bgra & 0xFF000000) * (1.0f / 0xFF000000); - } - break; - - case DXGI_FORMAT_R8_UNORM: - { - outColor->red = *(data + x + y * inputPitch) / 255.0f; - outColor->green = 0.0f; - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R8G8_UNORM: - { - unsigned short rg = *reinterpret_cast(data + 2 * x + y * inputPitch); - - outColor->red = (rg & 0xFF00) * (1.0f / 0xFF00); - outColor->green = (rg & 0x00FF) * (1.0f / 0x00FF); - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R16_FLOAT: - { - outColor->red = gl::float16ToFloat32(*reinterpret_cast(data + 2 * x + y * inputPitch)); - outColor->green = 0.0f; - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - case DXGI_FORMAT_R16G16_FLOAT: - { - outColor->red = gl::float16ToFloat32(*(reinterpret_cast(data + 4 * x + y * inputPitch) + 0)); - outColor->green = gl::float16ToFloat32(*(reinterpret_cast(data + 4 * x + y * inputPitch) + 1)); - outColor->blue = 0.0f; - outColor->alpha = 1.0f; - } - break; - - default: - ERR("ReadPixelColor not implemented for DXGI format %u.", format); - UNIMPLEMENTED(); - break; - } -} - -static inline void writePixelColor(const gl::Color &color, GLenum format, GLenum type, unsigned int x, - unsigned int y, int outputPitch, void *outData) -{ - unsigned char* byteData = reinterpret_cast(outData); - unsigned short* shortData = reinterpret_cast(outData); - - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - byteData[4 * x + y * outputPitch + 0] = static_cast(255 * color.red + 0.5f); - byteData[4 * x + y * outputPitch + 1] = static_cast(255 * color.green + 0.5f); - byteData[4 * x + y * outputPitch + 2] = static_cast(255 * color.blue + 0.5f); - byteData[4 * x + y * outputPitch + 3] = static_cast(255 * color.alpha + 0.5f); - break; - - default: - ERR("WritePixelColor not implemented for format GL_RGBA and type 0x%X.", type); - UNIMPLEMENTED(); - break; - } - break; - - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - byteData[4 * x + y * outputPitch + 0] = static_cast(255 * color.blue + 0.5f); - byteData[4 * x + y * outputPitch + 1] = static_cast(255 * color.green + 0.5f); - byteData[4 * x + y * outputPitch + 2] = static_cast(255 * color.red + 0.5f); - byteData[4 * x + y * outputPitch + 3] = static_cast(255 * color.alpha + 0.5f); - break; - - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - shortData[x + y * outputPitch / sizeof(unsigned short)] = - (static_cast(15 * color.alpha + 0.5f) << 12) | - (static_cast(15 * color.red + 0.5f) << 8) | - (static_cast(15 * color.green + 0.5f) << 4) | - (static_cast(15 * color.blue + 0.5f) << 0); - break; - - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - shortData[x + y * outputPitch / sizeof(unsigned short)] = - (static_cast( color.alpha + 0.5f) << 15) | - (static_cast(31 * color.red + 0.5f) << 10) | - (static_cast(31 * color.green + 0.5f) << 5) | - (static_cast(31 * color.blue + 0.5f) << 0); - break; - - default: - ERR("WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.", type); - UNIMPLEMENTED(); - break; - } - break; - - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_SHORT_5_6_5: - shortData[x + y * outputPitch / sizeof(unsigned short)] = - (static_cast(31 * color.blue + 0.5f) << 0) | - (static_cast(63 * color.green + 0.5f) << 5) | - (static_cast(31 * color.red + 0.5f) << 11); - break; - - case GL_UNSIGNED_BYTE: - byteData[3 * x + y * outputPitch + 0] = static_cast(255 * color.red + 0.5f); - byteData[3 * x + y * outputPitch + 1] = static_cast(255 * color.green + 0.5f); - byteData[3 * x + y * outputPitch + 2] = static_cast(255 * color.blue + 0.5f); - break; - - default: - ERR("WritePixelColor not implemented for format GL_RGB and type 0x%X.", type); - UNIMPLEMENTED(); - break; - } - break; - - default: - ERR("WritePixelColor not implemented for format 0x%X.", format); - UNIMPLEMENTED(); - break; - } -} - -void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, - GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, - GLint packAlignment, void *pixels) -{ - D3D11_TEXTURE2D_DESC textureDesc; - texture->GetDesc(&textureDesc); - - D3D11_TEXTURE2D_DESC stagingDesc; - stagingDesc.Width = area.width; - stagingDesc.Height = area.height; - stagingDesc.MipLevels = 1; - stagingDesc.ArraySize = 1; - stagingDesc.Format = textureDesc.Format; - stagingDesc.SampleDesc.Count = 1; - stagingDesc.SampleDesc.Quality = 0; - stagingDesc.Usage = D3D11_USAGE_STAGING; - stagingDesc.BindFlags = 0; - stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; - stagingDesc.MiscFlags = 0; - - ID3D11Texture2D* stagingTex = NULL; - HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex); - if (FAILED(result)) - { - ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result); - return; - } - - ID3D11Texture2D* srcTex = NULL; - if (textureDesc.SampleDesc.Count > 1) - { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = D3D11_USAGE_DEFAULT; - resolveDesc.BindFlags = 0; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex); - if (FAILED(result)) - { - ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result); - stagingTex->Release(); - return; - } - - mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format); - subResource = 0; - } - else - { - srcTex = texture; - srcTex->AddRef(); - } - - D3D11_BOX srcBox; - srcBox.left = area.x; - srcBox.right = area.x + area.width; - srcBox.top = area.y; - srcBox.bottom = area.y + area.height; - srcBox.front = 0; - srcBox.back = 1; - - mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox); - - srcTex->Release(); - srcTex = NULL; - - D3D11_MAPPED_SUBRESOURCE mapping; - mDeviceContext->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapping); - - unsigned char *source; - int inputPitch; - if (packReverseRowOrder) - { - source = static_cast(mapping.pData) + mapping.RowPitch * (area.height - 1); - inputPitch = -static_cast(mapping.RowPitch); - } - else - { - source = static_cast(mapping.pData); - inputPitch = static_cast(mapping.RowPitch); - } - - unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, format, type); - if (fastPixelSize != 0) - { - unsigned char *dest = static_cast(pixels); - for (int j = 0; j < area.height; j++) - { - memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize); - } - } - else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM && - format == GL_RGBA && - type == GL_UNSIGNED_BYTE) - { - // Fast path for swapping red with blue - unsigned char *dest = static_cast(pixels); - - for (int j = 0; j < area.height; j++) - { - for (int i = 0; i < area.width; i++) - { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); - *(unsigned int*)(dest + 4 * i + j * outputPitch) = - (argb & 0xFF00FF00) | // Keep alpha and green - (argb & 0x00FF0000) >> 16 | // Move red to blue - (argb & 0x000000FF) << 16; // Move blue to red - } - } - } - else - { - gl::Color pixelColor; - for (int j = 0; j < area.height; j++) - { - for (int i = 0; i < area.width; i++) - { - readPixelColor(source, textureDesc.Format, i, j, inputPitch, &pixelColor); - writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels); - } - } - } - - mDeviceContext->Unmap(stagingTex, 0); - - stagingTex->Release(); - stagingTex = NULL; -} - -bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, bool wholeBufferCopy) -{ - ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height); - - RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); - if (!drawRenderTarget) - { - ERR("Failed to retrieve the draw render target from the draw framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture(); - unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); - - RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); - if (!readRenderTarget) - { - ERR("Failed to retrieve the read render target from the read framebuffer."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - ID3D11Texture2D *readTexture = NULL; - unsigned int readSubresource = 0; - if (readRenderTarget->getSamples() > 0) - { - readTexture = resolveMultisampledTexture(readRenderTarget11->getTexture(), readRenderTarget11->getSubresourceIndex()); - readSubresource = 0; - } - else - { - readTexture = readRenderTarget11->getTexture(); - readTexture->AddRef(); - readSubresource = readRenderTarget11->getSubresourceIndex(); - } - - if (!readTexture) - { - ERR("Failed to retrieve the read render target view from the read render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - D3D11_BOX readBox; - readBox.left = readRect.x; - readBox.right = readRect.x + readRect.width; - readBox.top = readRect.y; - readBox.bottom = readRect.y + readRect.height; - readBox.front = 0; - readBox.back = 1; - - // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox - // We also require complete framebuffer copies for depth-stencil blit. - D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; - - mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0, - readTexture, readSubresource, pSrcBox); - - SafeRelease(readTexture); - - return true; -} - -ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) -{ - D3D11_TEXTURE2D_DESC textureDesc; - source->GetDesc(&textureDesc); - - if (textureDesc.SampleDesc.Count > 1) - { - D3D11_TEXTURE2D_DESC resolveDesc; - resolveDesc.Width = textureDesc.Width; - resolveDesc.Height = textureDesc.Height; - resolveDesc.MipLevels = 1; - resolveDesc.ArraySize = 1; - resolveDesc.Format = textureDesc.Format; - resolveDesc.SampleDesc.Count = 1; - resolveDesc.SampleDesc.Quality = 0; - resolveDesc.Usage = textureDesc.Usage; - resolveDesc.BindFlags = textureDesc.BindFlags; - resolveDesc.CPUAccessFlags = 0; - resolveDesc.MiscFlags = 0; - - ID3D11Texture2D *resolveTexture = NULL; - HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture); - if (FAILED(result)) - { - ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result); - return NULL; - } - - mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format); - return resolveTexture; - } - else - { - source->AddRef(); - return source; - } -} - -bool Renderer11::getLUID(LUID *adapterLuid) const -{ - adapterLuid->HighPart = 0; - adapterLuid->LowPart = 0; - - if (!mDxgiAdapter) - { - return false; - } - - DXGI_ADAPTER_DESC adapterDesc; - if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc))) - { - return false; - } - - *adapterLuid = adapterDesc.AdapterLuid; - return true; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h deleted file mode 100644 index 433945da7a..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer11.h +++ /dev/null @@ -1,360 +0,0 @@ -// -// Copyright (c) 2012-2013 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. -// - -// Renderer11.h: Defines a back-end specific class for the D3D11 renderer. - -#ifndef LIBGLESV2_RENDERER_RENDERER11_H_ -#define LIBGLESV2_RENDERER_RENDERER11_H_ - -#include "common/angleutils.h" -#include "libGLESv2/angletypes.h" -#include "libGLESv2/mathutil.h" - -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/RenderStateCache.h" -#include "libGLESv2/renderer/InputLayoutCache.h" -#include "libGLESv2/renderer/RenderTarget.h" - -namespace gl -{ -class Renderbuffer; -} - -namespace rx -{ - -class VertexDataManager; -class IndexDataManager; -class StreamingIndexBufferInterface; - -enum -{ - MAX_VERTEX_UNIFORM_VECTORS_D3D9 = 254, - MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024, - MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024 -}; - -class Renderer11 : public Renderer -{ - public: - Renderer11(egl::Display *display, HDC hDc); - virtual ~Renderer11(); - - static Renderer11 *makeRenderer11(Renderer *renderer); - - virtual EGLint initialize(); - virtual bool resetDevice(); - - virtual int generateConfigs(ConfigDesc **configDescList); - virtual void deleteConfigs(ConfigDesc *configDescList); - - virtual void sync(bool block); - - virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); - - virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); - virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); - - virtual void setRasterizerState(const gl::RasterizerState &rasterState); - virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, - unsigned int sampleMask); - virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); - - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport); - - virtual bool applyPrimitiveType(GLenum mode, GLsizei count); - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary); - virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances); - virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - - virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); - - virtual void markAllStateDirty(); - - // lost device - void notifyDeviceLost(); - virtual bool isDeviceLost(); - virtual bool testDeviceLost(bool notify); - virtual bool testDeviceResettable(); - - // Renderer capabilities - virtual DWORD getAdapterVendor() const; - virtual std::string getRendererDescription() const; - virtual GUID getAdapterIdentifier() const; - - virtual bool getBGRATextureSupport() const; - virtual bool getDXT1TextureSupport(); - virtual bool getDXT3TextureSupport(); - virtual bool getDXT5TextureSupport(); - virtual bool getEventQuerySupport(); - virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); - virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); - virtual bool getLuminanceTextureSupport(); - virtual bool getLuminanceAlphaTextureSupport(); - virtual unsigned int getMaxVertexTextureImageUnits() const; - virtual unsigned int getMaxCombinedTextureImageUnits() const; - virtual unsigned int getReservedVertexUniformVectors() const; - virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getMaxVertexUniformVectors() const; - virtual unsigned int getMaxFragmentUniformVectors() const; - virtual unsigned int getMaxVaryingVectors() const; - virtual bool getNonPower2TextureSupport() const; - virtual bool getDepthTextureSupport() const; - virtual bool getOcclusionQuerySupport() const; - virtual bool getInstancingSupport() const; - virtual bool getTextureFilterAnisotropySupport() const; - virtual float getTextureMaxAnisotropy() const; - virtual bool getShareHandleSupport() const; - virtual bool getDerivativeInstructionSupport() const; - virtual bool getPostSubBufferSupport() const; - - virtual int getMajorShaderModel() const; - virtual float getMaxPointSize() const; - virtual int getMaxViewportDimension() const; - virtual int getMaxTextureWidth() const; - virtual int getMaxTextureHeight() const; - virtual bool get32BitIndexSupport() const; - virtual int getMinSwapInterval() const; - virtual int getMaxSwapInterval() const; - - virtual GLsizei getMaxSupportedSamples() const; - int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const; - - virtual unsigned int getMaxRenderTargets() const; - - // Pixel operations - virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); - virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); - - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); - - bool copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, - ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat); - - virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil); - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); - - // RenderTarget creation - virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth); - - // Shader operations - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type); - - // Image operations - virtual Image *createImage(); - virtual void generateMipmap(Image *dest, Image *source); - virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); - virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); - - // Buffer creation - virtual VertexBuffer *createVertexBuffer(); - virtual IndexBuffer *createIndexBuffer(); - virtual BufferStorage *createBufferStorage(); - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type); - virtual FenceImpl *createFence(); - - // D3D11-renderer specific methods - ID3D11Device *getDevice() { return mDevice; } - ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; - IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; - D3D_FEATURE_LEVEL getFeatureLevel() const { return mFeatureLevel; } - - bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); - void unapplyRenderTargets(); - void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); - - virtual bool getLUID(LUID *adapterLuid) const; - - private: - DISALLOW_COPY_AND_ASSIGN(Renderer11); - - void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); - - void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, - GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, - GLint packAlignment, void *pixels); - - void maskedClear(const gl::ClearParameters &clearParams, bool usingExtendedDrawBuffers); - rx::Range getViewportBounds() const; - - bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, - RenderTarget *drawRenderTarget, bool wholeBufferCopy); - ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); - - HMODULE mD3d11Module; - HMODULE mDxgiModule; - HDC mDc; - - bool mDeviceLost; - - void initializeDevice(); - void releaseDeviceResources(); - int getMinorShaderModel() const; - void release(); - - RenderStateCache mStateCache; - - // Support flags - bool mFloat16TextureSupport; - bool mFloat16FilterSupport; - bool mFloat16RenderSupport; - - bool mFloat32TextureSupport; - bool mFloat32FilterSupport; - bool mFloat32RenderSupport; - - bool mDXT1TextureSupport; - bool mDXT3TextureSupport; - bool mDXT5TextureSupport; - - bool mDepthTextureSupport; - - // Multisample format support - struct MultisampleSupportInfo - { - unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT]; - }; - - typedef std::unordered_map MultisampleSupportMap; - MultisampleSupportMap mMultisampleSupportMap; - - unsigned int mMaxSupportedSamples; - - // current render target states - unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; - unsigned int mAppliedDepthbufferSerial; - unsigned int mAppliedStencilbufferSerial; - bool mDepthStencilInitialized; - bool mRenderTargetDescInitialized; - rx::RenderTarget::Desc mRenderTargetDesc; - unsigned int mCurDepthSize; - unsigned int mCurStencilSize; - - // Currently applied sampler states - bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - - bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - - // Currently applied textures - unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; - - // Currently applied blend state - bool mForceSetBlendState; - gl::BlendState mCurBlendState; - gl::Color mCurBlendColor; - unsigned int mCurSampleMask; - - // Currently applied rasterizer state - bool mForceSetRasterState; - gl::RasterizerState mCurRasterState; - - // Currently applied depth stencil state - bool mForceSetDepthStencilState; - gl::DepthStencilState mCurDepthStencilState; - int mCurStencilRef; - int mCurStencilBackRef; - - // Currently applied scissor rectangle - bool mForceSetScissor; - bool mScissorEnabled; - gl::Rectangle mCurScissor; - - // Currently applied viewport - bool mForceSetViewport; - gl::Rectangle mCurViewport; - float mCurNear; - float mCurFar; - - // Currently applied primitive topology - D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; - - unsigned int mAppliedIBSerial; - unsigned int mAppliedStorageIBSerial; - unsigned int mAppliedIBOffset; - - unsigned int mAppliedProgramBinarySerial; - bool mIsGeometryShaderActive; - - dx_VertexConstants mVertexConstants; - dx_VertexConstants mAppliedVertexConstants; - ID3D11Buffer *mDriverConstantBufferVS; - ID3D11Buffer *mCurrentVertexConstantBuffer; - - dx_PixelConstants mPixelConstants; - dx_PixelConstants mAppliedPixelConstants; - ID3D11Buffer *mDriverConstantBufferPS; - ID3D11Buffer *mCurrentPixelConstantBuffer; - - ID3D11Buffer *mCurrentGeometryConstantBuffer; - - // Vertex, index and input layouts - VertexDataManager *mVertexDataManager; - IndexDataManager *mIndexDataManager; - InputLayoutCache mInputLayoutCache; - - StreamingIndexBufferInterface *mLineLoopIB; - StreamingIndexBufferInterface *mTriangleFanIB; - - // Texture copy resources - bool mCopyResourcesInitialized; - ID3D11Buffer *mCopyVB; - ID3D11SamplerState *mCopySampler; - ID3D11InputLayout *mCopyIL; - ID3D11VertexShader *mCopyVS; - ID3D11PixelShader *mCopyRGBAPS; - ID3D11PixelShader *mCopyRGBPS; - ID3D11PixelShader *mCopyLumPS; - ID3D11PixelShader *mCopyLumAlphaPS; - - // Masked clear resources - bool mClearResourcesInitialized; - ID3D11Buffer *mClearVB; - ID3D11InputLayout *mClearIL; - ID3D11VertexShader *mClearVS; - ID3D11PixelShader *mClearSinglePS; - ID3D11PixelShader *mClearMultiplePS; - ID3D11RasterizerState *mClearScissorRS; - ID3D11RasterizerState *mClearNoScissorRS; - - // Sync query - ID3D11Query *mSyncQuery; - - ID3D11Device *mDevice; - D3D_FEATURE_LEVEL mFeatureLevel; - ID3D11DeviceContext *mDeviceContext; - IDXGIAdapter *mDxgiAdapter; - DXGI_ADAPTER_DESC mAdapterDescription; - char mDescription[128]; - IDXGIFactory *mDxgiFactory; - - // Cached device caps - bool mBGRATextureSupport; -}; - -} -#endif // LIBGLESV2_RENDERER_RENDERER11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp deleted file mode 100644 index d3f3814ae5..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.cpp +++ /dev/null @@ -1,3260 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer. - -#include "libGLESv2/main.h" -#include "libGLESv2/Buffer.h" -#include "libGLESv2/Texture.h" -#include "libGLESv2/Framebuffer.h" -#include "libGLESv2/Renderbuffer.h" -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/renderer/IndexDataManager.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/ShaderExecutable9.h" -#include "libGLESv2/renderer/SwapChain9.h" -#include "libGLESv2/renderer/TextureStorage9.h" -#include "libGLESv2/renderer/Image9.h" -#include "libGLESv2/renderer/Blit.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/VertexBuffer9.h" -#include "libGLESv2/renderer/IndexBuffer9.h" -#include "libGLESv2/renderer/BufferStorage9.h" -#include "libGLESv2/renderer/Query9.h" -#include "libGLESv2/renderer/Fence9.h" - -#include "libEGL/Display.h" - -#include "third_party/trace_event/trace_event.h" - -// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros -#define REF_RAST 0 - -// The "Debug This Pixel..." feature in PIX often fails when using the -// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 -// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file. -#if !defined(ANGLE_ENABLE_D3D9EX) -// Enables use of the IDirect3D9Ex interface, when available -#define ANGLE_ENABLE_D3D9EX 1 -#endif // !defined(ANGLE_ENABLE_D3D9EX) - -namespace rx -{ -static const D3DFORMAT RenderTargetFormats[] = - { - D3DFMT_A1R5G5B5, - // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value. - D3DFMT_A8R8G8B8, - D3DFMT_R5G6B5, - // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format - D3DFMT_X8R8G8B8 - }; - -static const D3DFORMAT DepthStencilFormats[] = - { - D3DFMT_UNKNOWN, - // D3DFMT_D16_LOCKABLE, - D3DFMT_D32, - // D3DFMT_D15S1, - D3DFMT_D24S8, - D3DFMT_D24X8, - // D3DFMT_D24X4S4, - D3DFMT_D16, - // D3DFMT_D32F_LOCKABLE, - // D3DFMT_D24FS8 - }; - -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_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 -}; - -Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Renderer(display), mDc(hDc), mSoftwareDevice(softwareDevice) -{ - mD3d9Module = NULL; - - mD3d9 = NULL; - mD3d9Ex = NULL; - mDevice = NULL; - mDeviceEx = NULL; - mDeviceWindow = NULL; - mBlit = NULL; - - mAdapter = D3DADAPTER_DEFAULT; - - #if REF_RAST == 1 || defined(FORCE_REF_RAST) - mDeviceType = D3DDEVTYPE_REF; - #else - mDeviceType = D3DDEVTYPE_HAL; - #endif - - mDeviceLost = false; - - mMaxSupportedSamples = 0; - - mMaskedClearSavedState = NULL; - - mVertexDataManager = NULL; - mIndexDataManager = NULL; - mLineLoopIB = NULL; - - 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; - } -} - -Renderer9::~Renderer9() -{ - releaseDeviceResources(); - - if (mDevice) - { - // If the device is lost, reset it first to prevent leaving the driver in an unstable state - if (testDeviceLost(false)) - { - resetDevice(); - } - - mDevice->Release(); - mDevice = NULL; - } - - if (mDeviceEx) - { - mDeviceEx->Release(); - mDeviceEx = NULL; - } - - if (mD3d9) - { - mD3d9->Release(); - mD3d9 = NULL; - } - - if (mDeviceWindow) - { - DestroyWindow(mDeviceWindow); - mDeviceWindow = NULL; - } - - if (mD3d9Ex) - { - mD3d9Ex->Release(); - mD3d9Ex = NULL; - } - - if (mD3d9Module) - { - mD3d9Module = NULL; - } - - while (!mMultiSampleSupport.empty()) - { - delete [] mMultiSampleSupport.begin()->second; - mMultiSampleSupport.erase(mMultiSampleSupport.begin()); - } -} - -Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer)); - return static_cast(renderer); -} - -EGLint Renderer9::initialize() -{ - if (!initializeCompiler()) - { - return EGL_NOT_INITIALIZED; - } - - if (mSoftwareDevice) - { - TRACE_EVENT0("gpu", "GetModuleHandle_swiftshader"); - mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); - } - else - { - TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); - mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); - } - - if (mD3d9Module == NULL) - { - ERR("No D3D9 module found - aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - 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_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) - { - TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); - ASSERT(mD3d9Ex); - mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); - ASSERT(mD3d9); - } - else - { - TRACE_EVENT0("gpu", "Direct3DCreate9"); - mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); - } - - if (!mD3d9) - { - ERR("Could not create D3D9 device - aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - if (mDc != NULL) - { - // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to - } - - HRESULT result; - - // Give up on getting device caps after about one second. - { - TRACE_EVENT0("gpu", "GetDeviceCaps"); - for (int i = 0; i < 10; ++i) - { - result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); - if (SUCCEEDED(result)) - { - break; - } - else if (result == D3DERR_NOTAVAILABLE) - { - 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 - { - ERR("failed to get device caps (0x%x)\n", result); - return EGL_NOT_INITIALIZED; - } - } - } - - if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) - { - ERR("Renderer does not support PS 2.0. aborting!\n"); - return EGL_NOT_INITIALIZED; - } - - // 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::convertToRenderTarget. - if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) - { - ERR("Renderer does not support stretctrect from textures!\n"); - return EGL_NOT_INITIALIZED; - } - - { - TRACE_EVENT0("gpu", "GetAdapterIdentifier"); - mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); - } - - // ATI cards on XP have problems with non-power-of-two textures. - mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && - !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && - !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && - !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD); - - // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec - mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2)); - - mMinSwapInterval = 4; - mMaxSwapInterval = 0; - - if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) - { - mMinSwapInterval = std::min(mMinSwapInterval, 0); - mMaxSwapInterval = std::max(mMaxSwapInterval, 0); - } - if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) - { - mMinSwapInterval = std::min(mMinSwapInterval, 1); - mMaxSwapInterval = std::max(mMaxSwapInterval, 1); - } - if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) - { - mMinSwapInterval = std::min(mMinSwapInterval, 2); - mMaxSwapInterval = std::max(mMaxSwapInterval, 2); - } - if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) - { - mMinSwapInterval = std::min(mMinSwapInterval, 3); - mMaxSwapInterval = std::max(mMaxSwapInterval, 3); - } - if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) - { - mMinSwapInterval = std::min(mMinSwapInterval, 4); - mMaxSwapInterval = std::max(mMaxSwapInterval, 4); - } - - int max = 0; - { - TRACE_EVENT0("gpu", "getMultiSampleSupport"); - for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i) - { - bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - getMultiSampleSupport(RenderTargetFormats[i], multisampleArray); - mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray; - - for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) - { - if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) - { - max = j; - } - } - } - } - - { - TRACE_EVENT0("gpu", "getMultiSampleSupport2"); - for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i) - { - if (DepthStencilFormats[i] == D3DFMT_UNKNOWN) - continue; - - bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; - getMultiSampleSupport(DepthStencilFormats[i], multisampleArray); - mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray; - - for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) - { - if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) - { - max = j; - } - } - } - } - - mMaxSupportedSamples = max; - - static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); - static const TCHAR className[] = TEXT("STATIC"); - - { - TRACE_EVENT0("gpu", "CreateWindowEx"); - mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); - } - - D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES; - - { - TRACE_EVENT0("gpu", "D3d9_CreateDevice"); - 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_BAD_ALLOC; - } - - if (FAILED(result)) - { - TRACE_EVENT0("gpu", "D3d9_CreateDevice2"); - 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_BAD_ALLOC; - } - } - - if (mD3d9Ex) - { - TRACE_EVENT0("gpu", "mDevice_QueryInterface"); - result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx); - ASSERT(SUCCEEDED(result)); - } - - { - TRACE_EVENT0("gpu", "ShaderCache initialize"); - mVertexShaderCache.initialize(mDevice); - mPixelShaderCache.initialize(mDevice); - } - - // Check occlusion query support - IDirect3DQuery9 *occlusionQuery = NULL; - { - TRACE_EVENT0("gpu", "device_CreateQuery"); - if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery) - { - occlusionQuery->Release(); - mOcclusionQuerySupport = true; - } - else - { - mOcclusionQuerySupport = false; - } - } - - // Check event query support - IDirect3DQuery9 *eventQuery = NULL; - { - TRACE_EVENT0("gpu", "device_CreateQuery2"); - if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery) - { - eventQuery->Release(); - mEventQuerySupport = true; - } - else - { - mEventQuerySupport = false; - } - } - - D3DDISPLAYMODE currentDisplayMode; - mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); - - // Check vertex texture support - // 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)); - - // Check depth texture support - // we use INTZ for depth textures in Direct3D9 - // we also want NULL texture support to ensure the we can make depth-only FBOs - // see http://aras-p.info/texts/D3D9GPUHacks.html - mDepthTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, - D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, - D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL)); - - // Check 32 bit floating point texture support - mFloat32FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, - D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, - D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); - - mFloat32RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, - D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, - D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); - - if (!mFloat32FilterSupport && !mFloat32RenderSupport) - { - mFloat32TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, - D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, - D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); - } - else - { - mFloat32TextureSupport = true; - } - - // Check 16 bit floating point texture support - mFloat16FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, - D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, - D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); - - mFloat16RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, - D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, - D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); - - if (!mFloat16FilterSupport && !mFloat16RenderSupport) - { - mFloat16TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, - D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && - SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, - D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); - } - else - { - mFloat16TextureSupport = true; - } - - // Check DXT texture support - mDXT1TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); - mDXT3TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3)); - mDXT5TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5)); - - // Check luminance[alpha] texture support - mLuminanceTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8)); - mLuminanceAlphaTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8)); - - initializeDevice(); - - return EGL_SUCCESS; -} - -// 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() -{ - // Permanent non-default states - mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); - mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE); - - if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) - { - mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize); - } - else - { - mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f - } - - markAllStateDirty(); - - mSceneStarted = false; - - ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager); - mBlit = new Blit(this); - mVertexDataManager = new rx::VertexDataManager(this); - mIndexDataManager = new rx::IndexDataManager(this); -} - -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. - presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; - 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; - - return presentParameters; -} - -int Renderer9::generateConfigs(ConfigDesc **configDescList) -{ - D3DDISPLAYMODE currentDisplayMode; - mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); - - unsigned int numRenderFormats = ArraySize(RenderTargetFormats); - unsigned int numDepthFormats = ArraySize(DepthStencilFormats); - (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; - int numConfigs = 0; - - for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) - { - D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; - - HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); - - if (SUCCEEDED(result)) - { - for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) - { - D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; - HRESULT result = D3D_OK; - - if(depthStencilFormat != D3DFMT_UNKNOWN) - { - result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); - } - - if (SUCCEEDED(result)) - { - if(depthStencilFormat != D3DFMT_UNKNOWN) - { - result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); - } - - if (SUCCEEDED(result)) - { - ConfigDesc newConfig; - newConfig.renderTargetFormat = d3d9_gl::ConvertBackBufferFormat(renderTargetFormat); - newConfig.depthStencilFormat = d3d9_gl::ConvertDepthStencilFormat(depthStencilFormat); - newConfig.multiSample = 0; // FIXME: enumerate multi-sampling - newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat); - - (*configDescList)[numConfigs++] = newConfig; - } - } - } - } - } - - return numConfigs; -} - -void Renderer9::deleteConfigs(ConfigDesc *configDescList) -{ - delete [] (configDescList); -} - -void Renderer9::startScene() -{ - if (!mSceneStarted) - { - long result = mDevice->BeginScene(); - if (SUCCEEDED(result)) { - // This is defensive checking against the device being - // lost at unexpected times. - mSceneStarted = true; - } - } -} - -void Renderer9::endScene() -{ - if (mSceneStarted) - { - // EndScene can fail if the device was lost, for example due - // to a TDR during a draw call. - mDevice->EndScene(); - mSceneStarted = false; - } -} - -void Renderer9::sync(bool block) -{ - HRESULT result; - - IDirect3DQuery9* query = allocateEventQuery(); - if (!query) - { - return; - } - - result = query->Issue(D3DISSUE_END); - ASSERT(SUCCEEDED(result)); - - do - { - result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); - - if(block && result == S_FALSE) - { - // Keep polling, but allow other threads to do something useful first - Sleep(0); - // explicitly check for device loss - // some drivers seem to return S_FALSE even if the device is lost - // instead of D3DERR_DEVICELOST like they should - if (testDeviceLost(false)) - { - result = D3DERR_DEVICELOST; - } - } - } - while(block && result == S_FALSE); - - freeEventQuery(query); - - if (d3d9::isDeviceLostError(result)) - { - notifyDeviceLost(); - } -} - -SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) -{ - return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat); -} - -IDirect3DQuery9* Renderer9::allocateEventQuery() -{ - IDirect3DQuery9 *query = NULL; - - if (mEventQueryPool.empty()) - { - HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); - ASSERT(SUCCEEDED(result)); - } - else - { - query = mEventQueryPool.back(); - mEventQueryPool.pop_back(); - } - - return query; -} - -void Renderer9::freeEventQuery(IDirect3DQuery9* query) -{ - if (mEventQueryPool.size() > 1000) - { - query->Release(); - } - else - { - mEventQueryPool.push_back(query); - } -} - -IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length) -{ - return mVertexShaderCache.create(function, length); -} - -IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length) -{ - return mPixelShaderCache.create(function, length); -} - -HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer) -{ - D3DPOOL Pool = getBufferPool(Usage); - return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL); -} - -VertexBuffer *Renderer9::createVertexBuffer() -{ - return new VertexBuffer9(this); -} - -HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer) -{ - D3DPOOL Pool = getBufferPool(Usage); - return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL); -} - -IndexBuffer *Renderer9::createIndexBuffer() -{ - return new IndexBuffer9(this); -} - -BufferStorage *Renderer9::createBufferStorage() -{ - return new BufferStorage9(); -} - -QueryImpl *Renderer9::createQuery(GLenum type) -{ - return new Query9(this, type); -} - -FenceImpl *Renderer9::createFence() -{ - return new Fence9(this); -} - -void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) -{ - bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; - gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; - - if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) - { - int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - 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_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); - D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; - gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset); - if (mSupportsTextureFilterAnisotropy) - { - mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); - } - } - - forceSetSamplers[index] = false; - appliedSamplers[index] = samplerState; -} - -void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) -{ - int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; - int d3dSampler = index + d3dSamplerOffset; - IDirect3DBaseTexture9 *d3dTexture = NULL; - unsigned int serial = 0; - bool forceSetTexture = false; - - unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; - - if (texture) - { - TextureStorageInterface *texStorage = texture->getNativeTexture(); - if (texStorage) - { - TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInstance()); - d3dTexture = storage9->getBaseTexture(); - } - // 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); - - serial = texture->getTextureSerial(); - forceSetTexture = texture->hasDirtyImages(); - } - - if (forceSetTexture || appliedSerials[index] != serial) - { - mDevice->SetTexture(d3dSampler, d3dTexture); - } - - appliedSerials[index] = serial; -} - -void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) -{ - bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; - - if (rasterStateChanged) - { - // Set the cull mode - if (rasterState.cullFace) - { - mDevice->SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace)); - } - else - { - mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - } - - if (rasterState.polygonOffsetFill) - { - if (mCurDepthSize > 0) - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&rasterState.polygonOffsetFactor); - - float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast(mCurDepthSize)); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); - } - } - else - { - mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); - mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); - } - - mCurRasterState = rasterState; - } - - mForceSetRasterState = false; -} - -void Renderer9::setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, unsigned int sampleMask) -{ - bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; - bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0; - bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask; - - if (blendStateChanged || blendColorChanged) - { - if (blendState.blend) - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && - blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor)); - } - else - { - mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha), - gl::unorm<8>(blendColor.alpha))); - } - - mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); - mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); - mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); - - if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || - blendState.destBlendRGB != blendState.destBlendAlpha || - blendState.blendEquationRGB != blendState.blendEquationAlpha) - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); - mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); - mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); - } - else - { - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); - } - } - else - { - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - } - - if (blendState.sampleAlphaToCoverage) - { - FIXME("Sample alpha to coverage is unimplemented."); - } - - // Set the color mask - bool zeroColorMaskAllowed = getAdapterVendor() != 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 - - DWORD colorMask = gl_d3d9::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, - blendState.colorMaskBlue, blendState.colorMaskAlpha); - if (colorMask == 0 && !zeroColorMaskAllowed) - { - // Enable green channel, but set blending so nothing will be drawn. - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); - - mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); - mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); - mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); - } - else - { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); - } - - mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE); - - mCurBlendState = blendState; - mCurBlendColor = blendColor; - } - - if (sampleMaskChanged) - { - // Set the multisample mask - mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); - mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast(sampleMask)); - - mCurSampleMask = sampleMask; - } - - mForceSetBlendState = false; -} - -void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW) -{ - bool depthStencilStateChanged = mForceSetDepthStencilState || - memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; - bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef || - stencilBackRef != mCurStencilBackRef; - bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW; - - if (depthStencilStateChanged) - { - if (depthStencilState.depthTest) - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); - mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc)); - } - else - { - mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - } - - mCurDepthStencilState = depthStencilState; - } - - if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged) - { - if (depthStencilState.stencilTest && mCurStencilSize > 0) - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); - - // FIXME: Unsupported by D3D9 - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; - const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; - if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask || - stencilRef != stencilBackRef || - depthStencilState.stencilMask != depthStencilState.stencilBackMask) - { - ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); - return gl::error(GL_INVALID_OPERATION); - } - - // get the maximum size of the stencil ref - unsigned int maxStencil = (1 << mCurStencilSize) - 1; - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilWritemask); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilFunc)); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilRef < (int)maxStencil) ? stencilRef : maxStencil); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilMask); - - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail)); - mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, - depthStencilState.stencilBackWritemask); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, - gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc)); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, - (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, - depthStencilState.stencilBackMask); - - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail)); - mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, - gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass)); - } - else - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE); - - mCurStencilRef = stencilRef; - mCurStencilBackRef = stencilBackRef; - mCurFrontFaceCCW = frontFaceCCW; - } - - mForceSetDepthStencilState = false; -} - -void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) -{ - bool scissorChanged = mForceSetScissor || - memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || - enabled != mScissorEnabled; - - if (scissorChanged) - { - if (enabled) - { - RECT rect; - rect.left = gl::clamp(scissor.x, 0, static_cast(mRenderTargetDesc.width)); - rect.top = gl::clamp(scissor.y, 0, static_cast(mRenderTargetDesc.height)); - rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast(mRenderTargetDesc.width)); - rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast(mRenderTargetDesc.height)); - mDevice->SetScissorRect(&rect); - } - - mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE); - - mScissorEnabled = enabled; - mCurScissor = scissor; - } - - mForceSetScissor = false; -} - -bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport) -{ - gl::Rectangle actualViewport = viewport; - float actualZNear = gl::clamp01(zNear); - float actualZFar = gl::clamp01(zFar); - if (ignoreViewport) - { - actualViewport.x = 0; - actualViewport.y = 0; - actualViewport.width = mRenderTargetDesc.width; - actualViewport.height = mRenderTargetDesc.height; - actualZNear = 0.0f; - actualZFar = 1.0f; - } - - D3DVIEWPORT9 dxViewport; - dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast(mRenderTargetDesc.width)); - dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast(mRenderTargetDesc.height)); - dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast(mRenderTargetDesc.width) - static_cast(dxViewport.X)); - dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast(mRenderTargetDesc.height) - static_cast(dxViewport.Y)); - dxViewport.MinZ = actualZNear; - dxViewport.MaxZ = actualZFar; - - if (dxViewport.Width <= 0 || dxViewport.Height <= 0) - { - return false; // Nothing to render - } - - float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); - - bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || - actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront; - if (viewportChanged) - { - mDevice->SetViewport(&dxViewport); - - mCurViewport = actualViewport; - mCurNear = actualZNear; - mCurFar = actualZFar; - mCurDepthFront = depthFront; - - dx_VertexConstants vc = {0}; - dx_PixelConstants pc = {0}; - - vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width; - vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height; - vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width; - vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height; - - pc.viewCoords[0] = actualViewport.width * 0.5f; - pc.viewCoords[1] = actualViewport.height * 0.5f; - pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); - pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); - - pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; - pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; - pc.depthFront[2] = depthFront; - - vc.depthRange[0] = actualZNear; - vc.depthRange[1] = actualZFar; - vc.depthRange[2] = actualZFar - actualZNear; - - pc.depthRange[0] = actualZNear; - pc.depthRange[1] = actualZFar; - pc.depthRange[2] = actualZFar - actualZNear; - - if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0) - { - mVertexConstants = vc; - mDxUniformsDirty = true; - } - - if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0) - { - mPixelConstants = pc; - mDxUniformsDirty = true; - } - } - - mForceSetViewport = false; - return true; -} - -bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) -{ - 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: - return gl::error(GL_INVALID_ENUM, false); - } - - return mPrimitiveCount > 0; -} - - -gl::Renderbuffer *Renderer9::getNullColorbuffer(gl::Renderbuffer *depthbuffer) -{ - if (!depthbuffer) - { - ERR("Unexpected null depthbuffer for depth-only FBO."); - return NULL; - } - - GLsizei width = depthbuffer->getWidth(); - GLsizei height = depthbuffer->getHeight(); - - // search cached nullcolorbuffers - for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) - { - if (mNullColorbufferCache[i].buffer != NULL && - mNullColorbufferCache[i].width == width && - mNullColorbufferCache[i].height == height) - { - mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; - return mNullColorbufferCache[i].buffer; - } - } - - gl::Renderbuffer *nullbuffer = new gl::Renderbuffer(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); - - // add nullbuffer to the cache - NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; - for (int i = 1; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) - { - if (mNullColorbufferCache[i].lruCount < oldest->lruCount) - { - oldest = &mNullColorbufferCache[i]; - } - } - - delete oldest->buffer; - oldest->buffer = nullbuffer; - oldest->lruCount = ++mMaxNullColorbufferLRU; - oldest->width = width; - oldest->height = height; - - return nullbuffer; -} - -bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) -{ - // 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. - gl::Renderbuffer *renderbufferObject = NULL; - if (framebuffer->getColorbufferType(0) != GL_NONE) - { - renderbufferObject = framebuffer->getColorbuffer(0); - } - else - { - renderbufferObject = getNullColorbuffer(framebuffer->getDepthbuffer()); - } - if (!renderbufferObject) - { - ERR("unable to locate renderbuffer for FBO."); - return false; - } - - bool renderTargetChanged = false; - unsigned int renderTargetSerial = renderbufferObject->getSerial(); - if (renderTargetSerial != mAppliedRenderTargetSerial) - { - // Apply the render target on the device - IDirect3DSurface9 *renderTargetSurface = NULL; - - RenderTarget *renderTarget = renderbufferObject->getRenderTarget(); - if (renderTarget) - { - renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface(); - } - - if (!renderTargetSurface) - { - ERR("render target pointer unexpectedly null."); - return false; // Context must be lost - } - - mDevice->SetRenderTarget(0, renderTargetSurface); - renderTargetSurface->Release(); - - mAppliedRenderTargetSerial = renderTargetSerial; - renderTargetChanged = true; - } - - gl::Renderbuffer *depthStencil = NULL; - unsigned int depthbufferSerial = 0; - unsigned int stencilbufferSerial = 0; - if (framebuffer->getDepthbufferType() != GL_NONE) - { - depthStencil = framebuffer->getDepthbuffer(); - if (!depthStencil) - { - ERR("Depth stencil pointer unexpectedly null."); - return false; - } - - depthbufferSerial = depthStencil->getSerial(); - } - else if (framebuffer->getStencilbufferType() != GL_NONE) - { - depthStencil = framebuffer->getStencilbuffer(); - if (!depthStencil) - { - ERR("Depth stencil pointer unexpectedly null."); - return false; - } - - stencilbufferSerial = depthStencil->getSerial(); - } - - if (depthbufferSerial != mAppliedDepthbufferSerial || - stencilbufferSerial != mAppliedStencilbufferSerial || - !mDepthStencilInitialized) - { - unsigned int depthSize = 0; - unsigned int stencilSize = 0; - - // Apply the depth stencil on the device - if (depthStencil) - { - IDirect3DSurface9 *depthStencilSurface = NULL; - RenderTarget *depthStencilRenderTarget = depthStencil->getDepthStencil(); - - if (depthStencilRenderTarget) - { - depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)->getSurface(); - } - - if (!depthStencilSurface) - { - ERR("depth stencil pointer unexpectedly null."); - return false; // Context must be lost - } - - mDevice->SetDepthStencilSurface(depthStencilSurface); - depthStencilSurface->Release(); - - depthSize = depthStencil->getDepthSize(); - stencilSize = depthStencil->getStencilSize(); - } - else - { - mDevice->SetDepthStencilSurface(NULL); - } - - if (!mDepthStencilInitialized || depthSize != mCurDepthSize) - { - mCurDepthSize = depthSize; - mForceSetRasterState = true; - } - - if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) - { - mCurStencilSize = stencilSize; - mForceSetDepthStencilState = true; - } - - mAppliedDepthbufferSerial = depthbufferSerial; - mAppliedStencilbufferSerial = stencilbufferSerial; - mDepthStencilInitialized = true; - } - - if (renderTargetChanged || !mRenderTargetDescInitialized) - { - mForceSetScissor = true; - mForceSetViewport = true; - - mRenderTargetDesc.width = renderbufferObject->getWidth(); - mRenderTargetDesc.height = renderbufferObject->getHeight(); - mRenderTargetDesc.format = renderbufferObject->getActualFormat(); - mRenderTargetDescInitialized = true; - } - - return true; -} - -GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) -{ - TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; - GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances); - if (err != GL_NO_ERROR) - { - return err; - } - - return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); -} - -// Applies the indices and element array bindings to the Direct3D 9 device -GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) -{ - GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); - - if (err == GL_NO_ERROR) - { - // Directly binding the storage buffer is not supported for d3d9 - ASSERT(indexInfo->storage == NULL); - - if (indexInfo->serial != mAppliedIBSerial) - { - IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); - - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = indexInfo->serial; - } - } - - return err; -} - -void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances) -{ - startScene(); - - if (mode == GL_LINE_LOOP) - { - drawLineLoop(count, GL_NONE, NULL, 0, NULL); - } - else if (instances > 0) - { - StaticIndexBufferInterface *countingIB = mIndexDataManager->getCountingIndices(count); - if (countingIB) - { - if (mAppliedIBSerial != countingIB->getSerial()) - { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); - - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = countingIB->getSerial(); - } - - for (int i = 0; i < mRepeatDraw; i++) - { - mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); - } - } - else - { - ERR("Could not create a counting index buffer for glDrawArraysInstanced."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - else // Regular case - { - mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); - } -} - -void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) -{ - startScene(); - - if (mode == GL_POINTS) - { - drawIndexedPoints(count, type, indices, elementArrayBuffer); - } - else if (mode == GL_LINE_LOOP) - { - drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); - } - else - { - for (int i = 0; i < mRepeatDraw; i++) - { - GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; - mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); - } - } -} - -void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) -{ - // Get the raw indices for an indexed draw - if (type != GL_NONE && elementArrayBuffer) - { - gl::Buffer *indexBuffer = elementArrayBuffer; - BufferStorage *storage = indexBuffer->getStorage(); - intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; - } - - unsigned int startIndex = 0; - - if (get32BitIndexSupport()) - { - if (!mLineLoopIB) - { - mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) - { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) - { - ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); - } - - // Checked by Renderer9::applyPrimitiveType - ASSERT(count >= 0); - - const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned int); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) - { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - void* mappedMemory = NULL; - unsigned int offset = 0; - if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) - { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - 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(); - } - - if (!mLineLoopIB->unmapBuffer()) - { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - else - { - if (!mLineLoopIB) - { - mLineLoopIB = new StreamingIndexBufferInterface(this); - if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT)) - { - delete mLineLoopIB; - mLineLoopIB = NULL; - - ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - // Checked by Renderer9::applyPrimitiveType - ASSERT(count >= 0); - - if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned short))) - { - ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); - return gl::error(GL_OUT_OF_MEMORY); - } - - const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned short); - if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)) - { - ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - void* mappedMemory = NULL; - unsigned int offset; - if (mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) - { - ERR("Could not map index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - - 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] = 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(); - } - - if (!mLineLoopIB->unmapBuffer()) - { - ERR("Could not unmap index buffer for GL_LINE_LOOP."); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - if (mAppliedIBSerial != mLineLoopIB->getSerial()) - { - IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB->getIndexBuffer()); - - mDevice->SetIndices(indexBuffer->getBuffer()); - mAppliedIBSerial = mLineLoopIB->getSerial(); - } - - mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); -} - -template -static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices) -{ - for (int i = 0; i < count; i++) - { - unsigned int indexValue = static_cast(static_cast(indices)[i]); - device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); - } -} - -void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, 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. - - if (elementArrayBuffer) - { - BufferStorage *storage = elementArrayBuffer->getStorage(); - intptr_t offset = reinterpret_cast(indices); - indices = static_cast(storage->getData()) + offset; - } - - switch (type) - { - case GL_UNSIGNED_BYTE: drawPoints(mDevice, count, indices); break; - case GL_UNSIGNED_SHORT: drawPoints(mDevice, count, indices); break; - case GL_UNSIGNED_INT: drawPoints(mDevice, count, indices); break; - default: UNREACHABLE(); - } -} - -void Renderer9::applyShaders(gl::ProgramBinary *programBinary) -{ - unsigned int programBinarySerial = programBinary->getSerial(); - if (programBinarySerial != mAppliedProgramBinarySerial) - { - ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); - ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); - - IDirect3DVertexShader9 *vertexShader = NULL; - if (vertexExe) vertexShader = ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader(); - - IDirect3DPixelShader9 *pixelShader = NULL; - if (pixelExe) pixelShader = ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader(); - - mDevice->SetPixelShader(pixelShader); - mDevice->SetVertexShader(vertexShader); - programBinary->dirtyAllUniforms(); - mDxUniformsDirty = true; - - mAppliedProgramBinarySerial = programBinarySerial; - } -} - -void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) -{ - for (std::vector::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub) - { - gl::Uniform *targetUniform = *ub; - - if (targetUniform->dirty) - { - GLfloat *f = (GLfloat*)targetUniform->data; - GLint *i = (GLint*)targetUniform->data; - - switch (targetUniform->type) - { - case GL_SAMPLER_2D: - case GL_SAMPLER_CUBE: - break; - case GL_BOOL: - case GL_BOOL_VEC2: - case GL_BOOL_VEC3: - case GL_BOOL_VEC4: - applyUniformnbv(targetUniform, i); - break; - case GL_FLOAT: - case GL_FLOAT_VEC2: - case GL_FLOAT_VEC3: - case GL_FLOAT_VEC4: - case GL_FLOAT_MAT2: - case GL_FLOAT_MAT3: - case GL_FLOAT_MAT4: - applyUniformnfv(targetUniform, f); - break; - case GL_INT: - case GL_INT_VEC2: - case GL_INT_VEC3: - case GL_INT_VEC4: - applyUniformniv(targetUniform, i); - break; - default: - UNREACHABLE(); - } - - targetUniform->dirty = false; - } - } - - // Driver uniforms - if (mDxUniformsDirty) - { - mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4])); - mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); - mDxUniformsDirty = false; - } -} - -void Renderer9::applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v) -{ - if (targetUniform->psRegisterIndex >= 0) - { - mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, targetUniform->registerCount); - } - - if (targetUniform->vsRegisterIndex >= 0) - { - mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, targetUniform->registerCount); - } -} - -void Renderer9::applyUniformniv(gl::Uniform *targetUniform, const GLint *v) -{ - ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); - GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; - - for (unsigned int i = 0; i < targetUniform->registerCount; i++) - { - vector[i][0] = (GLfloat)v[4 * i + 0]; - vector[i][1] = (GLfloat)v[4 * i + 1]; - vector[i][2] = (GLfloat)v[4 * i + 2]; - vector[i][3] = (GLfloat)v[4 * i + 3]; - } - - applyUniformnfv(targetUniform, (GLfloat*)vector); -} - -void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, const GLint *v) -{ - ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); - GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; - - for (unsigned int i = 0; i < targetUniform->registerCount; i++) - { - vector[i][0] = (v[4 * i + 0] == GL_FALSE) ? 0.0f : 1.0f; - vector[i][1] = (v[4 * i + 1] == GL_FALSE) ? 0.0f : 1.0f; - vector[i][2] = (v[4 * i + 2] == GL_FALSE) ? 0.0f : 1.0f; - vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f; - } - - applyUniformnfv(targetUniform, (GLfloat*)vector); -} - -void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) -{ - D3DCOLOR color = D3DCOLOR_ARGB(gl::unorm<8>(clearParams.colorClearValue.alpha), - gl::unorm<8>(clearParams.colorClearValue.red), - gl::unorm<8>(clearParams.colorClearValue.green), - gl::unorm<8>(clearParams.colorClearValue.blue)); - float depth = gl::clamp01(clearParams.depthClearValue); - int stencil = clearParams.stencilClearValue & 0x000000FF; - - unsigned int stencilUnmasked = 0x0; - if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil()) - { - unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat()); - stencilUnmasked = (0x1 << stencilSize) - 1; - } - - bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha; - - const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) && - (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; - const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) && - !(clearParams.colorMaskRed && clearParams.colorMaskGreen && - clearParams.colorMaskBlue && alphaUnmasked); - - if (needMaskedColorClear || needMaskedStencilClear) - { - // State which is altered in all paths from this point to the clear call is saved. - // 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) - { - hr = mDevice->BeginStateBlock(); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); - mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - mDevice->SetPixelShader(NULL); - mDevice->SetVertexShader(NULL); - mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); - mDevice->SetStreamSource(0, NULL, 0, 0); - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); - mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); - mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mDevice->SetStreamSourceFreq(i, 1); - } - - hr = mDevice->EndStateBlock(&mMaskedClearSavedState); - ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); - } - - ASSERT(mMaskedClearSavedState != NULL); - - if (mMaskedClearSavedState != NULL) - { - hr = mMaskedClearSavedState->Capture(); - ASSERT(SUCCEEDED(hr)); - } - - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); - mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); - mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); - mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - - if (clearParams.mask & GL_COLOR_BUFFER_BIT) - { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, - gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, - clearParams.colorMaskGreen, - clearParams.colorMaskBlue, - clearParams.colorMaskAlpha)); - } - else - { - mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); - } - - if (stencilUnmasked != 0x0 && (clearParams.mask & GL_STENCIL_BUFFER_BIT)) - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); - mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); - mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); - mDevice->SetRenderState(D3DRS_STENCILREF, stencil); - mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, clearParams.stencilWriteMask); - mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE); - mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE); - mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); - } - else - { - mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); - } - - mDevice->SetPixelShader(NULL); - mDevice->SetVertexShader(NULL); - mDevice->SetFVF(D3DFVF_XYZRHW); - mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); - mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); - mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); - mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); - mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); - mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); - - for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mDevice->SetStreamSourceFreq(i, 1); - } - - float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges - quad[0][0] = -0.5f; - quad[0][1] = mRenderTargetDesc.height - 0.5f; - quad[0][2] = 0.0f; - quad[0][3] = 1.0f; - - quad[1][0] = mRenderTargetDesc.width - 0.5f; - quad[1][1] = mRenderTargetDesc.height - 0.5f; - quad[1][2] = 0.0f; - quad[1][3] = 1.0f; - - quad[2][0] = -0.5f; - quad[2][1] = -0.5f; - quad[2][2] = 0.0f; - quad[2][3] = 1.0f; - - quad[3][0] = mRenderTargetDesc.width - 0.5f; - quad[3][1] = -0.5f; - quad[3][2] = 0.0f; - quad[3][3] = 1.0f; - - startScene(); - mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4])); - - if (clearParams.mask & GL_DEPTH_BUFFER_BIT) - { - mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); - mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); - mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil); - } - - if (mMaskedClearSavedState != NULL) - { - mMaskedClearSavedState->Apply(); - } - } - else if (clearParams.mask) - { - DWORD dxClearFlags = 0; - if (clearParams.mask & GL_COLOR_BUFFER_BIT) - { - dxClearFlags |= D3DCLEAR_TARGET; - } - if (clearParams.mask & GL_DEPTH_BUFFER_BIT) - { - dxClearFlags |= D3DCLEAR_ZBUFFER; - } - if (clearParams.mask & GL_STENCIL_BUFFER_BIT) - { - dxClearFlags |= D3DCLEAR_STENCIL; - } - - mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil); - } -} - -void Renderer9::markAllStateDirty() -{ - mAppliedRenderTargetSerial = 0; - mAppliedDepthbufferSerial = 0; - mAppliedStencilbufferSerial = 0; - mDepthStencilInitialized = false; - mRenderTargetDescInitialized = false; - - mForceSetDepthStencilState = true; - mForceSetRasterState = true; - mForceSetScissor = true; - mForceSetViewport = true; - mForceSetBlendState = true; - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) - { - mForceSetVertexSamplerStates[i] = true; - mCurVertexTextureSerials[i] = 0; - } - for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) - { - mForceSetPixelSamplerStates[i] = true; - mCurPixelTextureSerials[i] = 0; - } - - mAppliedIBSerial = 0; - mAppliedProgramBinarySerial = 0; - mDxUniformsDirty = true; - - mVertexDeclarationCache.markStateDirty(); -} - -void Renderer9::releaseDeviceResources() -{ - while (!mEventQueryPool.empty()) - { - mEventQueryPool.back()->Release(); - mEventQueryPool.pop_back(); - } - - if (mMaskedClearSavedState) - { - mMaskedClearSavedState->Release(); - mMaskedClearSavedState = NULL; - } - - mVertexShaderCache.clear(); - mPixelShaderCache.clear(); - - delete mBlit; - mBlit = NULL; - - delete mVertexDataManager; - mVertexDataManager = NULL; - - delete mIndexDataManager; - mIndexDataManager = NULL; - - delete mLineLoopIB; - mLineLoopIB = NULL; - - for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) - { - delete mNullColorbufferCache[i].buffer; - mNullColorbufferCache[i].buffer = NULL; - } - -} - - -void Renderer9::notifyDeviceLost() -{ - mDeviceLost = true; - mDisplay->notifyDeviceLost(); -} - -bool Renderer9::isDeviceLost() -{ - return mDeviceLost; -} - -// set notify to true to broadcast a message to all contexts of the device loss -bool Renderer9::testDeviceLost(bool notify) -{ - HRESULT status = S_OK; - - if (mDeviceEx) - { - status = mDeviceEx->CheckDeviceState(NULL); - } - else if (mDevice) - { - status = mDevice->TestCooperativeLevel(); - } - else - { - // No device yet, so no reset required - } - - bool isLost = FAILED(status) || d3d9::isDeviceLostError(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; - if (notify) - { - notifyDeviceLost(); - } - } - - return isLost; -} - -bool Renderer9::testDeviceResettable() -{ - HRESULT status = D3D_OK; - - if (mDeviceEx) - { - status = mDeviceEx->CheckDeviceState(NULL); - } - else if (mDevice) - { - status = mDevice->TestCooperativeLevel(); - } - - // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted - // DEVICEREMOVED indicates the device has been stopped and must be recreated - switch (status) - { - case D3DERR_DEVICENOTRESET: - case D3DERR_DEVICEHUNG: - return true; - case D3DERR_DEVICELOST: - return (mDeviceEx != NULL); - case D3DERR_DEVICEREMOVED: - UNIMPLEMENTED(); - return false; - default: - return false; - } -} - -bool Renderer9::resetDevice() -{ - releaseDeviceResources(); - - D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); - - HRESULT result = D3D_OK; - bool lost = testDeviceLost(false); - int attempts = 3; - - while (lost && attempts > 0) - { - if (mDeviceEx) - { - Sleep(500); // Give the graphics driver some CPU time - result = mDeviceEx->ResetEx(&presentParameters, NULL); - } - else - { - result = mDevice->TestCooperativeLevel(); - while (result == D3DERR_DEVICELOST) - { - Sleep(100); // Give the graphics driver some CPU time - result = mDevice->TestCooperativeLevel(); - } - - if (result == D3DERR_DEVICENOTRESET) - { - result = mDevice->Reset(&presentParameters); - } - } - - lost = testDeviceLost(false); - attempts --; - } - - if (FAILED(result)) - { - ERR("Reset/ResetEx failed multiple times: 0x%08X", result); - return false; - } - - // reset device defaults - initializeDevice(); - mDeviceLost = false; - - return true; -} - -DWORD Renderer9::getAdapterVendor() const -{ - return mAdapterIdentifier.VendorId; -} - -std::string Renderer9::getRendererDescription() const -{ - std::ostringstream rendererString; - - rendererString << mAdapterIdentifier.Description; - if (getShareHandleSupport()) - { - rendererString << " Direct3D9Ex"; - } - else - { - 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); - - return rendererString.str(); -} - -GUID Renderer9::getAdapterIdentifier() const -{ - return mAdapterIdentifier.DeviceIdentifier; -} - -void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) -{ - for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) - { - HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, - TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL); - - multiSampleArray[multiSampleIndex] = SUCCEEDED(result); - } -} - -bool Renderer9::getBGRATextureSupport() const -{ - // DirectX 9 always supports BGRA - return true; -} - -bool Renderer9::getDXT1TextureSupport() -{ - return mDXT1TextureSupport; -} - -bool Renderer9::getDXT3TextureSupport() -{ - return mDXT3TextureSupport; -} - -bool Renderer9::getDXT5TextureSupport() -{ - return mDXT5TextureSupport; -} - -bool Renderer9::getDepthTextureSupport() const -{ - return mDepthTextureSupport; -} - -bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable) -{ - *filtering = mFloat32FilterSupport; - *renderable = mFloat32RenderSupport; - return mFloat32TextureSupport; -} - -bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable) -{ - *filtering = mFloat16FilterSupport; - *renderable = mFloat16RenderSupport; - return mFloat16TextureSupport; -} - -bool Renderer9::getLuminanceTextureSupport() -{ - return mLuminanceTextureSupport; -} - -bool Renderer9::getLuminanceAlphaTextureSupport() -{ - return mLuminanceAlphaTextureSupport; -} - -bool Renderer9::getTextureFilterAnisotropySupport() const -{ - return mSupportsTextureFilterAnisotropy; -} - -float Renderer9::getTextureMaxAnisotropy() const -{ - if (mSupportsTextureFilterAnisotropy) - { - return static_cast(mDeviceCaps.MaxAnisotropy); - } - return 1.0f; -} - -bool Renderer9::getEventQuerySupport() -{ - return mEventQuerySupport; -} - -unsigned int Renderer9::getMaxVertexTextureImageUnits() const -{ - META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); - return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0; -} - -unsigned int Renderer9::getMaxCombinedTextureImageUnits() const -{ - return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); -} - -unsigned int Renderer9::getReservedVertexUniformVectors() const -{ - return 2; // dx_ViewAdjust and dx_DepthRange. -} - -unsigned int Renderer9::getReservedFragmentUniformVectors() const -{ - return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. -} - -unsigned int Renderer9::getMaxVertexUniformVectors() const -{ - return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors(); -} - -unsigned int Renderer9::getMaxFragmentUniformVectors() const -{ - const int maxPixelConstantVectors = (getMajorShaderModel() >= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2; - - return maxPixelConstantVectors - getReservedFragmentUniformVectors(); -} - -unsigned int Renderer9::getMaxVaryingVectors() const -{ - return (getMajorShaderModel() >= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2; -} - -bool Renderer9::getNonPower2TextureSupport() const -{ - return mSupportsNonPower2Textures; -} - -bool Renderer9::getOcclusionQuerySupport() const -{ - return mOcclusionQuerySupport; -} - -bool Renderer9::getInstancingSupport() const -{ - return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); -} - -bool Renderer9::getShareHandleSupport() const -{ - // PIX doesn't seem to support using share handles, so disable them. - return (mD3d9Ex != NULL) && !gl::perfActive(); -} - -bool Renderer9::getDerivativeInstructionSupport() const -{ - return (mDeviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; -} - -bool Renderer9::getPostSubBufferSupport() const -{ - return true; -} - -int Renderer9::getMajorShaderModel() const -{ - return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); -} - -float Renderer9::getMaxPointSize() const -{ - // Point size clamped at 1.0f for SM2 - return getMajorShaderModel() == 3 ? mDeviceCaps.MaxPointSize : 1.0f; -} - -int Renderer9::getMaxViewportDimension() const -{ - int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()), - (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE); - return maxTextureDimension; -} - -int Renderer9::getMaxTextureWidth() const -{ - return (int)mDeviceCaps.MaxTextureWidth; -} - -int Renderer9::getMaxTextureHeight() const -{ - return (int)mDeviceCaps.MaxTextureHeight; -} - -bool Renderer9::get32BitIndexSupport() const -{ - return mDeviceCaps.MaxVertexIndex >= (1 << 16); -} - -DWORD Renderer9::getCapsDeclTypes() const -{ - return mDeviceCaps.DeclTypes; -} - -int Renderer9::getMinSwapInterval() const -{ - return mMinSwapInterval; -} - -int Renderer9::getMaxSwapInterval() const -{ - return mMaxSwapInterval; -} - -int Renderer9::getMaxSupportedSamples() const -{ - return mMaxSupportedSamples; -} - -int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const -{ - if (requested == 0) - { - return requested; - } - - std::map::const_iterator itr = mMultiSampleSupport.find(format); - if (itr == mMultiSampleSupport.end()) - { - if (format == D3DFMT_UNKNOWN) - return 0; - return -1; - } - - for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i) - { - if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE) - { - return i; - } - } - - return -1; -} - -unsigned int Renderer9::getMaxRenderTargets() const -{ - // we do not support MRT in d3d9 - return 1; -} - -D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLint internalformat) -{ - switch (internalformat) - { - case GL_DEPTH_COMPONENT16: - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH24_STENCIL8_OES: - return D3DFMT_INTZ; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return D3DFMT_DXT1; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - return D3DFMT_DXT3; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - return D3DFMT_DXT5; - case GL_RGBA32F_EXT: - case GL_RGB32F_EXT: - case GL_ALPHA32F_EXT: - case GL_LUMINANCE32F_EXT: - case GL_LUMINANCE_ALPHA32F_EXT: - return D3DFMT_A32B32G32R32F; - case GL_RGBA16F_EXT: - case GL_RGB16F_EXT: - case GL_ALPHA16F_EXT: - case GL_LUMINANCE16F_EXT: - case GL_LUMINANCE_ALPHA16F_EXT: - return D3DFMT_A16B16G16R16F; - case GL_LUMINANCE8_EXT: - if (getLuminanceTextureSupport()) - { - return D3DFMT_L8; - } - break; - case GL_LUMINANCE8_ALPHA8_EXT: - if (getLuminanceAlphaTextureSupport()) - { - return D3DFMT_A8L8; - } - break; - case GL_RGB8_OES: - case GL_RGB565: - return D3DFMT_X8R8G8B8; - } - - return D3DFMT_A8R8G8B8; -} - -bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) -{ - bool result = false; - - if (source && dest) - { - TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance()); - TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance()); - - int levels = source9->levelCount(); - for (int i = 0; i < levels; ++i) - { - IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false); - IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false); - - result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - - if (srcSurf) srcSurf->Release(); - if (dstSurf) dstSurf->Release(); - - if (!result) - return false; - } - } - - return result; -} - -bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) -{ - bool result = false; - - if (source && dest) - { - TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance()); - TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance()); - int levels = source9->levelCount(); - for (int f = 0; f < 6; f++) - { - for (int i = 0; i < levels; i++) - { - IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false); - IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true); - - result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); - - if (srcSurf) srcSurf->Release(); - if (dstSurf) dstSurf->Release(); - - if (!result) - return false; - } - } - } - - return result; -} - -D3DPOOL Renderer9::getBufferPool(DWORD usage) const -{ - if (mD3d9Ex != NULL) - { - return D3DPOOL_DEFAULT; - } - else - { - if (!(usage & D3DUSAGE_DYNAMIC)) - { - return D3DPOOL_MANAGED; - } - } - - return D3DPOOL_DEFAULT; -} - -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) -{ - RECT rect; - rect.left = sourceRect.x; - rect.top = sourceRect.y; - rect.right = sourceRect.x + sourceRect.width; - rect.bottom = sourceRect.y + sourceRect.height; - - return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); -} - -bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) -{ - RECT rect; - rect.left = sourceRect.x; - rect.top = sourceRect.y; - rect.right = sourceRect.x + sourceRect.width; - rect.bottom = sourceRect.y + sourceRect.height; - - return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); -} - -bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil) -{ - endScene(); - - if (blitRenderTarget) - { - gl::Renderbuffer *readBuffer = readFramebuffer->getColorbuffer(0); - gl::Renderbuffer *drawBuffer = drawFramebuffer->getColorbuffer(0); - RenderTarget9 *readRenderTarget = NULL; - RenderTarget9 *drawRenderTarget = NULL; - IDirect3DSurface9* readSurface = NULL; - IDirect3DSurface9* drawSurface = NULL; - - if (readBuffer) - { - readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer->getRenderTarget()); - } - if (drawBuffer) - { - drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer->getRenderTarget()); - } - - if (readRenderTarget) - { - readSurface = readRenderTarget->getSurface(); - } - if (drawRenderTarget) - { - drawSurface = drawRenderTarget->getSurface(); - } - - if (!readSurface || !drawSurface) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - RECT srcRect; - srcRect.left = readRect.x; - srcRect.right = readRect.x + readRect.width; - srcRect.top = readRect.y; - srcRect.bottom = readRect.y + readRect.height; - - RECT dstRect; - dstRect.left = drawRect.x; - dstRect.right = drawRect.x + drawRect.width; - dstRect.top = drawRect.y; - dstRect.bottom = drawRect.y + drawRect.height; - - HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE); - - readSurface->Release(); - drawSurface->Release(); - - if (FAILED(result)) - { - ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); - return false; - } - } - - if (blitDepthStencil) - { - gl::Renderbuffer *readBuffer = readFramebuffer->getDepthOrStencilbuffer(); - gl::Renderbuffer *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); - RenderTarget9 *readDepthStencil = NULL; - RenderTarget9 *drawDepthStencil = NULL; - IDirect3DSurface9* readSurface = NULL; - IDirect3DSurface9* drawSurface = NULL; - - if (readBuffer) - { - readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer->getDepthStencil()); - } - if (drawBuffer) - { - drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer->getDepthStencil()); - } - - if (readDepthStencil) - { - readSurface = readDepthStencil->getSurface(); - } - if (drawDepthStencil) - { - drawSurface = drawDepthStencil->getSurface(); - } - - if (!readSurface || !drawSurface) - { - ERR("Failed to retrieve the render target."); - return gl::error(GL_OUT_OF_MEMORY, false); - } - - HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE); - - readSurface->Release(); - drawSurface->Release(); - - if (FAILED(result)) - { - ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); - return false; - } - } - - return true; -} - -void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) -{ - RenderTarget9 *renderTarget = NULL; - IDirect3DSurface9 *surface = NULL; - gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); - - if (colorbuffer) - { - renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); - } - - if (renderTarget) - { - surface = renderTarget->getSurface(); - } - - if (!surface) - { - // context must be lost - return; - } - - D3DSURFACE_DESC desc; - surface->GetDesc(&desc); - - if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) - { - UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target - surface->Release(); - return gl::error(GL_OUT_OF_MEMORY); - } - - HRESULT result; - IDirect3DSurface9 *systemSurface = NULL; - bool directToPixels = !packReverseRowOrder && packAlignment <= 4 && getShareHandleSupport() && - x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height && - desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; - if (directToPixels) - { - // Use the pixels ptr as a shared handle to write directly into client's memory - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, - D3DPOOL_SYSTEMMEM, &systemSurface, &pixels); - if (FAILED(result)) - { - // Try again without the shared handle - directToPixels = false; - } - } - - if (!directToPixels) - { - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, - D3DPOOL_SYSTEMMEM, &systemSurface, NULL); - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - surface->Release(); - return gl::error(GL_OUT_OF_MEMORY); - } - } - - result = mDevice->GetRenderTargetData(surface, systemSurface); - surface->Release(); - surface = NULL; - - if (FAILED(result)) - { - systemSurface->Release(); - - // It turns out that D3D will sometimes produce more error - // codes than those documented. - if (d3d9::isDeviceLostError(result)) - { - notifyDeviceLost(); - return gl::error(GL_OUT_OF_MEMORY); - } - else - { - UNREACHABLE(); - return; - } - - } - - if (directToPixels) - { - systemSurface->Release(); - return; - } - - RECT rect; - rect.left = gl::clamp(x, 0L, static_cast(desc.Width)); - rect.top = gl::clamp(y, 0L, static_cast(desc.Height)); - rect.right = gl::clamp(x + width, 0L, static_cast(desc.Width)); - rect.bottom = gl::clamp(y + height, 0L, static_cast(desc.Height)); - - D3DLOCKED_RECT lock; - result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); - - if (FAILED(result)) - { - UNREACHABLE(); - systemSurface->Release(); - - return; // No sensible error to generate - } - - unsigned char *dest = (unsigned char*)pixels; - unsigned short *dest16 = (unsigned short*)pixels; - - unsigned char *source; - int inputPitch; - if (packReverseRowOrder) - { - source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); - inputPitch = -lock.Pitch; - } - else - { - source = (unsigned char*)lock.pBits; - inputPitch = lock.Pitch; - } - - unsigned int fastPixelSize = 0; - - if (desc.Format == D3DFMT_A8R8G8B8 && - format == GL_BGRA_EXT && - type == GL_UNSIGNED_BYTE) - { - fastPixelSize = 4; - } - else if ((desc.Format == D3DFMT_A4R4G4B4 && - format == GL_BGRA_EXT && - type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) || - (desc.Format == D3DFMT_A1R5G5B5 && - format == GL_BGRA_EXT && - type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)) - { - fastPixelSize = 2; - } - else if (desc.Format == D3DFMT_A16B16G16R16F && - format == GL_RGBA && - type == GL_HALF_FLOAT_OES) - { - fastPixelSize = 8; - } - else if (desc.Format == D3DFMT_A32B32G32R32F && - format == GL_RGBA && - type == GL_FLOAT) - { - fastPixelSize = 16; - } - - for (int j = 0; j < rect.bottom - rect.top; j++) - { - if (fastPixelSize != 0) - { - // Fast path for formats which require no translation: - // D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE - // D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT - // D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT - // D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES - // D3DFMT_A32B32G32R32F to RGBA/FLOAT - // - // Note that buffers with no alpha go through the slow path below. - memcpy(dest + j * outputPitch, - source + j * inputPitch, - (rect.right - rect.left) * fastPixelSize); - continue; - } - else if (desc.Format == D3DFMT_A8R8G8B8 && - format == GL_RGBA && - type == GL_UNSIGNED_BYTE) - { - // Fast path for swapping red with blue - for (int i = 0; i < rect.right - rect.left; i++) - { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); - *(unsigned int*)(dest + 4 * i + j * outputPitch) = - (argb & 0xFF00FF00) | // Keep alpha and green - (argb & 0x00FF0000) >> 16 | // Move red to blue - (argb & 0x000000FF) << 16; // Move blue to red - } - continue; - } - - for (int i = 0; i < rect.right - rect.left; i++) - { - float r; - float g; - float b; - float a; - - switch (desc.Format) - { - case D3DFMT_R5G6B5: - { - unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); - - a = 1.0f; - b = (rgb & 0x001F) * (1.0f / 0x001F); - g = (rgb & 0x07E0) * (1.0f / 0x07E0); - r = (rgb & 0xF800) * (1.0f / 0xF800); - } - break; - case D3DFMT_A1R5G5B5: - { - unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); - - a = (argb & 0x8000) ? 1.0f : 0.0f; - b = (argb & 0x001F) * (1.0f / 0x001F); - g = (argb & 0x03E0) * (1.0f / 0x03E0); - r = (argb & 0x7C00) * (1.0f / 0x7C00); - } - break; - case D3DFMT_A8R8G8B8: - { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); - - a = (argb & 0xFF000000) * (1.0f / 0xFF000000); - b = (argb & 0x000000FF) * (1.0f / 0x000000FF); - g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); - r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); - } - break; - case D3DFMT_X8R8G8B8: - { - unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); - - a = 1.0f; - b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); - g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); - r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); - } - break; - case D3DFMT_A2R10G10B10: - { - unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); - - a = (argb & 0xC0000000) * (1.0f / 0xC0000000); - b = (argb & 0x000003FF) * (1.0f / 0x000003FF); - g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); - r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); - } - break; - case D3DFMT_A32B32G32R32F: - { - // float formats in D3D are stored rgba, rather than the other way round - r = *((float*)(source + 16 * i + j * inputPitch) + 0); - g = *((float*)(source + 16 * i + j * inputPitch) + 1); - b = *((float*)(source + 16 * i + j * inputPitch) + 2); - a = *((float*)(source + 16 * i + j * inputPitch) + 3); - } - break; - case D3DFMT_A16B16G16R16F: - { - // float formats in D3D are stored rgba, rather than the other way round - r = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0)); - g = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1)); - b = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2)); - a = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3)); - } - break; - default: - UNIMPLEMENTED(); // FIXME - UNREACHABLE(); - return; - } - - switch (format) - { - case GL_RGBA: - switch (type) - { - case GL_UNSIGNED_BYTE: - dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); - dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); - dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); - dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); - break; - default: UNREACHABLE(); - } - break; - case GL_BGRA_EXT: - switch (type) - { - case GL_UNSIGNED_BYTE: - dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); - dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); - dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); - dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); - break; - case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - dest16[i + j * outputPitch / sizeof(unsigned short)] = - ((unsigned short)(15 * a + 0.5f) << 12)| - ((unsigned short)(15 * r + 0.5f) << 8) | - ((unsigned short)(15 * g + 0.5f) << 4) | - ((unsigned short)(15 * b + 0.5f) << 0); - break; - case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: - // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section - // this type is packed as follows: - // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 - // -------------------------------------------------------------------------------- - // | 4th | 3rd | 2nd | 1st component | - // -------------------------------------------------------------------------------- - // in the case of BGRA_EXT, B is the first component, G the second, and so forth. - dest16[i + j * outputPitch / sizeof(unsigned short)] = - ((unsigned short)( a + 0.5f) << 15) | - ((unsigned short)(31 * r + 0.5f) << 10) | - ((unsigned short)(31 * g + 0.5f) << 5) | - ((unsigned short)(31 * b + 0.5f) << 0); - break; - default: UNREACHABLE(); - } - break; - case GL_RGB: - switch (type) - { - case GL_UNSIGNED_SHORT_5_6_5: - dest16[i + j * outputPitch / sizeof(unsigned short)] = - ((unsigned short)(31 * b + 0.5f) << 0) | - ((unsigned short)(63 * g + 0.5f) << 5) | - ((unsigned short)(31 * r + 0.5f) << 11); - break; - case GL_UNSIGNED_BYTE: - dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); - dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); - dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); - break; - default: UNREACHABLE(); - } - break; - default: UNREACHABLE(); - } - } - } - - systemSurface->UnlockRect(); - - systemSurface->Release(); -} - -RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) -{ - SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); - IDirect3DSurface9 *surface = NULL; - if (depth) - { - surface = swapChain9->getDepthStencil(); - } - else - { - surface = swapChain9->getRenderTarget(); - } - - RenderTarget9 *renderTarget = new RenderTarget9(this, surface); - - return renderTarget; -} - -RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) -{ - RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples); - return renderTarget; -} - -ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type) -{ - ShaderExecutable9 *executable = NULL; - - switch (type) - { - case rx::SHADER_VERTEX: - { - IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length); - if (vshader) - { - executable = new ShaderExecutable9(function, length, vshader); - } - } - break; - case rx::SHADER_PIXEL: - { - IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length); - if (pshader) - { - executable = new ShaderExecutable9(function, length, pshader); - } - } - break; - default: - UNREACHABLE(); - break; - } - - return executable; -} - -ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type) -{ - const char *profile = NULL; - - switch (type) - { - case rx::SHADER_VERTEX: - profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0"; - break; - case rx::SHADER_PIXEL: - profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0"; - break; - default: - UNREACHABLE(); - return NULL; - } - - ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, ANGLE_COMPILE_OPTIMIZATION_LEVEL, true); - if (!binary) - return NULL; - - ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type); - binary->Release(); - - return executable; -} - -bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) -{ - return mBlit->boxFilter(source, dest); -} - -D3DPOOL Renderer9::getTexturePool(DWORD usage) const -{ - if (mD3d9Ex != NULL) - { - return D3DPOOL_DEFAULT; - } - else - { - if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET))) - { - return D3DPOOL_MANAGED; - } - } - - return D3DPOOL_DEFAULT; -} - -bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) -{ - if (source && dest) - { - HRESULT result = D3DERR_OUTOFVIDEOMEMORY; - - if (fromManaged) - { - D3DSURFACE_DESC desc; - source->GetDesc(&desc); - - IDirect3DSurface9 *surf = 0; - result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); - - if (SUCCEEDED(result)) - { - Image9::copyLockableSurfaces(surf, source); - result = mDevice->UpdateSurface(surf, NULL, dest, NULL); - surf->Release(); - } - } - else - { - endScene(); - result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); - } - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - return false; - } - } - - return true; -} - -Image *Renderer9::createImage() -{ - return new Image9(); -} - -void Renderer9::generateMipmap(Image *dest, Image *src) -{ - Image9 *src9 = Image9::makeImage9(src); - Image9 *dst9 = Image9::makeImage9(dest); - Image9::generateMipmap(dst9, src9); -} - -TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain) -{ - SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); - return new TextureStorage9_2D(this, swapChain9); -} - -TextureStorage *Renderer9::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) -{ - return new TextureStorage9_2D(this, levels, internalformat, usage, forceRenderable, width, height); -} - -TextureStorage *Renderer9::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) -{ - return new TextureStorage9_Cube(this, levels, internalformat, usage, forceRenderable, size); -} - -bool Renderer9::getLUID(LUID *adapterLuid) const -{ - adapterLuid->HighPart = 0; - adapterLuid->LowPart = 0; - - if (mD3d9Ex) - { - mD3d9Ex->GetAdapterLUID(mAdapter, adapterLuid); - return true; - } - - return false; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h deleted file mode 100644 index f8932c4fd4..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/Renderer9.h +++ /dev/null @@ -1,350 +0,0 @@ -// -// Copyright (c) 2012-2013 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. -// - -// Renderer9.h: Defines a back-end specific class for the D3D9 renderer. - -#ifndef LIBGLESV2_RENDERER_RENDERER9_H_ -#define LIBGLESV2_RENDERER_RENDERER9_H_ - -#include "common/angleutils.h" -#include "libGLESv2/mathutil.h" -#include "libGLESv2/renderer/ShaderCache.h" -#include "libGLESv2/renderer/VertexDeclarationCache.h" -#include "libGLESv2/renderer/Renderer.h" -#include "libGLESv2/renderer/RenderTarget.h" - -namespace gl -{ -class Renderbuffer; -} - -namespace rx -{ -class VertexDataManager; -class IndexDataManager; -class StreamingIndexBufferInterface; -struct TranslatedAttribute; - -class Renderer9 : public Renderer -{ - public: - Renderer9(egl::Display *display, HDC hDc, bool softwareDevice); - virtual ~Renderer9(); - - static Renderer9 *makeRenderer9(Renderer *renderer); - - virtual EGLint initialize(); - virtual bool resetDevice(); - - virtual int generateConfigs(ConfigDesc **configDescList); - virtual void deleteConfigs(ConfigDesc *configDescList); - - void startScene(); - void endScene(); - - virtual void sync(bool block); - - virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); - - IDirect3DQuery9* allocateEventQuery(); - void freeEventQuery(IDirect3DQuery9* query); - - // resource creation - IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length); - IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length); - HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); - HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); -#if 0 - void *createTexture2D(); - void *createTextureCube(); - void *createQuery(); - void *createIndexBuffer(); - void *createVertexbuffer(); - - // state setup - void applyShaders(); - void applyConstants(); -#endif - virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); - virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); - - virtual void setRasterizerState(const gl::RasterizerState &rasterState); - virtual void setBlendState(const gl::BlendState &blendState, const gl::Color &blendColor, - unsigned int sampleMask); - virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, - int stencilBackRef, bool frontFaceCCW); - - virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); - virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, - bool ignoreViewport); - - virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); - virtual void applyShaders(gl::ProgramBinary *programBinary); - virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray); - virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); - virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances); - virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); - - virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); - virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); - - virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); - - virtual void markAllStateDirty(); - - // lost device - void notifyDeviceLost(); - virtual bool isDeviceLost(); - virtual bool testDeviceLost(bool notify); - virtual bool testDeviceResettable(); - - // Renderer capabilities - IDirect3DDevice9 *getDevice() { return mDevice; } - virtual DWORD getAdapterVendor() const; - virtual std::string getRendererDescription() const; - virtual GUID getAdapterIdentifier() const; - - virtual bool getBGRATextureSupport() const; - virtual bool getDXT1TextureSupport(); - virtual bool getDXT3TextureSupport(); - virtual bool getDXT5TextureSupport(); - virtual bool getEventQuerySupport(); - virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); - virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); - virtual bool getLuminanceTextureSupport(); - virtual bool getLuminanceAlphaTextureSupport(); - virtual unsigned int getMaxVertexTextureImageUnits() const; - virtual unsigned int getMaxCombinedTextureImageUnits() const; - virtual unsigned int getReservedVertexUniformVectors() const; - virtual unsigned int getReservedFragmentUniformVectors() const; - virtual unsigned int getMaxVertexUniformVectors() const; - virtual unsigned int getMaxFragmentUniformVectors() const; - virtual unsigned int getMaxVaryingVectors() const; - virtual bool getNonPower2TextureSupport() const; - virtual bool getDepthTextureSupport() const; - virtual bool getOcclusionQuerySupport() const; - virtual bool getInstancingSupport() const; - virtual bool getTextureFilterAnisotropySupport() const; - virtual float getTextureMaxAnisotropy() const; - virtual bool getShareHandleSupport() const; - virtual bool getDerivativeInstructionSupport() const; - virtual bool getPostSubBufferSupport() const; - - virtual int getMajorShaderModel() const; - virtual float getMaxPointSize() const; - virtual int getMaxViewportDimension() const; - virtual int getMaxTextureWidth() const; - virtual int getMaxTextureHeight() const; - virtual bool get32BitIndexSupport() const; - DWORD getCapsDeclTypes() const; - virtual int getMinSwapInterval() const; - virtual int getMaxSwapInterval() const; - - virtual GLsizei getMaxSupportedSamples() const; - int getNearestSupportedSamples(D3DFORMAT format, int requested) const; - - virtual unsigned int getMaxRenderTargets() const; - - D3DFORMAT ConvertTextureInternalFormat(GLint internalformat); - - // Pixel operations - virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); - virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); - - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); - virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, - GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); - - virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, - bool blitRenderTarget, bool blitDepthStencil); - virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, - GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); - - // RenderTarget creation - virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); - virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth); - - // Shader operations - virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type); - virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type); - - // Image operations - virtual Image *createImage(); - virtual void generateMipmap(Image *dest, Image *source); - virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); - virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); - - // Buffer creation - virtual VertexBuffer *createVertexBuffer(); - virtual IndexBuffer *createIndexBuffer(); - virtual BufferStorage *createBufferStorage(); - - // Query and Fence creation - virtual QueryImpl *createQuery(GLenum type); - virtual FenceImpl *createFence(); - - // D3D9-renderer specific methods - bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); - - D3DPOOL getTexturePool(DWORD usage) const; - - virtual bool getLUID(LUID *adapterLuid) const; - - private: - DISALLOW_COPY_AND_ASSIGN(Renderer9); - - void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v); - void applyUniformniv(gl::Uniform *targetUniform, const GLint *v); - void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v); - - void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); - void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer); - - void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); - bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); - gl::Renderbuffer *getNullColorbuffer(gl::Renderbuffer *depthbuffer); - - D3DPOOL getBufferPool(DWORD usage) const; - - HMODULE mD3d9Module; - HDC mDc; - - void initializeDevice(); - D3DPRESENT_PARAMETERS getDefaultPresentParameters(); - void releaseDeviceResources(); - - UINT mAdapter; - D3DDEVTYPE mDeviceType; - bool mSoftwareDevice; // FIXME: Deprecate - 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. - - Blit *mBlit; - - HWND mDeviceWindow; - - bool mDeviceLost; - D3DCAPS9 mDeviceCaps; - D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; - - D3DPRIMITIVETYPE mPrimitiveType; - int mPrimitiveCount; - GLsizei mRepeatDraw; - - bool mSceneStarted; - bool mSupportsNonPower2Textures; - bool mSupportsTextureFilterAnisotropy; - int mMinSwapInterval; - int mMaxSwapInterval; - - bool mOcclusionQuerySupport; - bool mEventQuerySupport; - bool mVertexTextureSupport; - - bool mDepthTextureSupport; - - bool mFloat32TextureSupport; - bool mFloat32FilterSupport; - bool mFloat32RenderSupport; - - bool mFloat16TextureSupport; - bool mFloat16FilterSupport; - bool mFloat16RenderSupport; - - bool mDXT1TextureSupport; - bool mDXT3TextureSupport; - bool mDXT5TextureSupport; - - bool mLuminanceTextureSupport; - bool mLuminanceAlphaTextureSupport; - - std::map mMultiSampleSupport; - GLsizei mMaxSupportedSamples; - - // current render target states - unsigned int mAppliedRenderTargetSerial; - unsigned int mAppliedDepthbufferSerial; - unsigned int mAppliedStencilbufferSerial; - bool mDepthStencilInitialized; - bool mRenderTargetDescInitialized; - rx::RenderTarget::Desc mRenderTargetDesc; - unsigned int mCurStencilSize; - unsigned int mCurDepthSize; - - IDirect3DStateBlock9 *mMaskedClearSavedState; - - // previously set render states - bool mForceSetDepthStencilState; - gl::DepthStencilState mCurDepthStencilState; - int mCurStencilRef; - int mCurStencilBackRef; - bool mCurFrontFaceCCW; - - bool mForceSetRasterState; - gl::RasterizerState mCurRasterState; - - bool mForceSetScissor; - gl::Rectangle mCurScissor; - bool mScissorEnabled; - - bool mForceSetViewport; - gl::Rectangle mCurViewport; - float mCurNear; - float mCurFar; - float mCurDepthFront; - - bool mForceSetBlendState; - gl::BlendState mCurBlendState; - gl::Color mCurBlendColor; - GLuint mCurSampleMask; - - // Currently applied sampler states - bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - - bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; - - // Currently applied textures - unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; - unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; - - unsigned int mAppliedIBSerial; - unsigned int mAppliedProgramBinarySerial; - - rx::dx_VertexConstants mVertexConstants; - rx::dx_PixelConstants mPixelConstants; - bool mDxUniformsDirty; - - // A pool of event queries that are currently unused. - std::vector mEventQueryPool; - VertexShaderCache mVertexShaderCache; - PixelShaderCache mPixelShaderCache; - - VertexDataManager *mVertexDataManager; - VertexDeclarationCache mVertexDeclarationCache; - - IndexDataManager *mIndexDataManager; - StreamingIndexBufferInterface *mLineLoopIB; - - enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 }; - struct NullColorbufferCacheEntry - { - UINT lruCount; - int width; - int height; - gl::Renderbuffer *buffer; - } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES]; - UINT mMaxNullColorbufferLRU; - -}; - -} -#endif // LIBGLESV2_RENDERER_RENDERER9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp deleted file mode 100644 index e1eb560334..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.cpp +++ /dev/null @@ -1,109 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader -// executable implementation details. - -#include "libGLESv2/renderer/ShaderExecutable11.h" - -#include "common/debug.h" - -namespace rx -{ - -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable) - : ShaderExecutable(function, length) -{ - mPixelExecutable = executable; - mVertexExecutable = NULL; - mGeometryExecutable = NULL; - - mConstantBuffer = NULL; -} - -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable) - : ShaderExecutable(function, length) -{ - mVertexExecutable = executable; - mPixelExecutable = NULL; - mGeometryExecutable = NULL; - - mConstantBuffer = NULL; -} - -ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable) - : ShaderExecutable(function, length) -{ - mGeometryExecutable = executable; - mVertexExecutable = NULL; - mPixelExecutable = NULL; - - mConstantBuffer = NULL; -} - -ShaderExecutable11::~ShaderExecutable11() -{ - if (mVertexExecutable) - { - mVertexExecutable->Release(); - } - if (mPixelExecutable) - { - mPixelExecutable->Release(); - } - if (mGeometryExecutable) - { - mGeometryExecutable->Release(); - } - - if (mConstantBuffer) - { - mConstantBuffer->Release(); - } -} - -ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable) -{ - ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable11*, executable)); - return static_cast(executable); -} - -ID3D11VertexShader *ShaderExecutable11::getVertexShader() const -{ - return mVertexExecutable; -} - -ID3D11PixelShader *ShaderExecutable11::getPixelShader() const -{ - return mPixelExecutable; -} - -ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const -{ - return mGeometryExecutable; -} - -ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount) -{ - if (!mConstantBuffer && registerCount > 0) - { - D3D11_BUFFER_DESC constantBufferDescription = {0}; - constantBufferDescription.ByteWidth = registerCount * sizeof(float[4]); - constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC; - constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; - constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - constantBufferDescription.MiscFlags = 0; - constantBufferDescription.StructureByteStride = 0; - - HRESULT result = device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer); - ASSERT(SUCCEEDED(result)); - } - - return mConstantBuffer; -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h deleted file mode 100644 index c6ec1cf7d2..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable11.h +++ /dev/null @@ -1,47 +0,0 @@ -// -// Copyright (c) 2012-2013 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. -// - -// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader -// executable implementation details. - -#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_ -#define LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_ - -#include "libGLESv2/renderer/ShaderExecutable.h" - -namespace rx -{ - -class ShaderExecutable11 : public ShaderExecutable -{ - public: - ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable); - ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable); - ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable); - - virtual ~ShaderExecutable11(); - - static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutable *executable); - - ID3D11PixelShader *getPixelShader() const; - ID3D11VertexShader *getVertexShader() const; - ID3D11GeometryShader *getGeometryShader() const; - - ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount); - - private: - DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11); - - ID3D11PixelShader *mPixelExecutable; - ID3D11VertexShader *mVertexExecutable; - ID3D11GeometryShader *mGeometryExecutable; - - ID3D11Buffer *mConstantBuffer; -}; - -} - -#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp deleted file mode 100644 index 98868a3fbf..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.cpp +++ /dev/null @@ -1,60 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader -// executable implementation details. - -#include "libGLESv2/renderer/ShaderExecutable9.h" - -#include "common/debug.h" - -namespace rx -{ - -ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable) - : ShaderExecutable(function, length) -{ - mPixelExecutable = executable; - mVertexExecutable = NULL; -} - -ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable) - : ShaderExecutable(function, length) -{ - mVertexExecutable = executable; - mPixelExecutable = NULL; -} - -ShaderExecutable9::~ShaderExecutable9() -{ - if (mVertexExecutable) - { - mVertexExecutable->Release(); - } - if (mPixelExecutable) - { - mPixelExecutable->Release(); - } -} - -ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutable *executable) -{ - ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable9*, executable)); - return static_cast(executable); -} - -IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const -{ - return mVertexExecutable; -} - -IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const -{ - return mPixelExecutable; -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h b/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h deleted file mode 100644 index fa1e6c2844..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/ShaderExecutable9.h +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2012-2013 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. -// - -// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader -// executable implementation details. - -#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ -#define LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ - -#include "libGLESv2/renderer/ShaderExecutable.h" - -namespace rx -{ - -class ShaderExecutable9 : public ShaderExecutable -{ - public: - ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable); - ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable); - virtual ~ShaderExecutable9(); - - static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutable *executable); - - IDirect3DPixelShader9 *getPixelShader() const; - IDirect3DVertexShader9 *getVertexShader() const; - - private: - DISALLOW_COPY_AND_ASSIGN(ShaderExecutable9); - - IDirect3DPixelShader9 *mPixelExecutable; - IDirect3DVertexShader9 *mVertexExecutable; -}; - -} - -#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h index a6870ebedc..8231fbcb25 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h +++ b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain.h @@ -1,3 +1,4 @@ +#include "../precompiled.h" // // Copyright (c) 2012 The ANGLE Project Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be @@ -12,6 +13,10 @@ #include "common/angleutils.h" +#if !defined(ANGLE_FORCE_VSYNC_OFF) +#define ANGLE_FORCE_VSYNC_OFF 0 +#endif + namespace rx { @@ -33,7 +38,7 @@ class SwapChain virtual HANDLE getShareHandle() {return mShareHandle;}; protected: - const EGLNativeWindowType mWindow; // Window that the surface is created for. + const EGLNativeWindowType mWindow; // Window that the surface is created for. const GLenum mBackBufferFormat; const GLenum mDepthBufferFormat; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp deleted file mode 100644 index 2fe15ff5b8..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.cpp +++ /dev/null @@ -1,797 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. - -#include "libGLESv2/renderer/SwapChain11.h" - -#include "libGLESv2/renderer/renderer11_utils.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/shaders/compiled/passthrough11vs.h" -#include "libGLESv2/renderer/shaders/compiled/passthroughrgba11ps.h" - -namespace rx -{ - -SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) -{ - mSwapChain = NULL; - mBackBufferTexture = NULL; - mBackBufferRTView = NULL; - mOffscreenTexture = NULL; - mOffscreenRTView = NULL; - mOffscreenSRView = NULL; - mDepthStencilTexture = NULL; - mDepthStencilDSView = NULL; - mQuadVB = NULL; - mPassThroughSampler = NULL; - mPassThroughIL = NULL; - mPassThroughVS = NULL; - mPassThroughPS = NULL; - mWidth = -1; - mHeight = -1; - mSwapInterval = 0; - mAppCreatedShareHandle = mShareHandle != NULL; - mPassThroughResourcesInit = false; -} - -SwapChain11::~SwapChain11() -{ - release(); -} - -void SwapChain11::release() -{ - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBufferTexture) - { - mBackBufferTexture->Release(); - mBackBufferTexture = NULL; - } - - if (mBackBufferRTView) - { - mBackBufferRTView->Release(); - mBackBufferRTView = NULL; - } - - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mOffscreenRTView) - { - mOffscreenRTView->Release(); - mOffscreenRTView = NULL; - } - - if (mOffscreenSRView) - { - mOffscreenSRView->Release(); - mOffscreenSRView = NULL; - } - - if (mDepthStencilTexture) - { - mDepthStencilTexture->Release(); - mDepthStencilTexture = NULL; - } - - if (mDepthStencilDSView) - { - mDepthStencilDSView->Release(); - mDepthStencilDSView = NULL; - } - - if (mQuadVB) - { - mQuadVB->Release(); - mQuadVB = NULL; - } - - if (mPassThroughSampler) - { - mPassThroughSampler->Release(); - mPassThroughSampler = NULL; - } - - if (mPassThroughIL) - { - mPassThroughIL->Release(); - mPassThroughIL = NULL; - } - - if (mPassThroughVS) - { - mPassThroughVS->Release(); - mPassThroughVS = NULL; - } - - if (mPassThroughPS) - { - mPassThroughPS->Release(); - mPassThroughPS = NULL; - } - - if (!mAppCreatedShareHandle) - { - mShareHandle = NULL; - } -} - -void SwapChain11::releaseOffscreenTexture() -{ - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mOffscreenRTView) - { - mOffscreenRTView->Release(); - mOffscreenRTView = NULL; - } - - if (mOffscreenSRView) - { - mOffscreenSRView->Release(); - mOffscreenSRView = NULL; - } - - if (mDepthStencilTexture) - { - mDepthStencilTexture->Release(); - mDepthStencilTexture = NULL; - } - - if (mDepthStencilDSView) - { - mDepthStencilDSView->Release(); - mDepthStencilDSView = NULL; - } -} - -EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight) -{ - ID3D11Device *device = mRenderer->getDevice(); - - ASSERT(device != NULL); - - // D3D11 does not allow zero size textures - ASSERT(backbufferWidth >= 1); - ASSERT(backbufferHeight >= 1); - - // Preserve the render target content - ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; - if (previousOffscreenTexture) - { - previousOffscreenTexture->AddRef(); - } - const int previousWidth = mWidth; - const int previousHeight = mHeight; - - releaseOffscreenTexture(); - - // If the app passed in a share handle, open the resource - // See EGL_ANGLE_d3d_share_handle_client_buffer - if (mAppCreatedShareHandle) - { - ID3D11Resource *tempResource11; - HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11); - - if (FAILED(result)) - { - ERR("Failed to open the swap chain pbuffer share handle: %08lX", result); - release(); - return EGL_BAD_PARAMETER; - } - - result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture); - tempResource11->Release(); - - if (FAILED(result)) - { - ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result); - release(); - return EGL_BAD_PARAMETER; - } - - // Validate offscreen texture parameters - D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; - mOffscreenTexture->GetDesc(&offscreenTextureDesc); - - if (offscreenTextureDesc.Width != (UINT)backbufferWidth - || offscreenTextureDesc.Height != (UINT)backbufferHeight - || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat) - || offscreenTextureDesc.MipLevels != 1 - || offscreenTextureDesc.ArraySize != 1) - { - ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); - release(); - return EGL_BAD_PARAMETER; - } - } - else - { - const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport(); - - D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; - offscreenTextureDesc.Width = backbufferWidth; - offscreenTextureDesc.Height = backbufferHeight; - offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); - offscreenTextureDesc.MipLevels = 1; - offscreenTextureDesc.ArraySize = 1; - offscreenTextureDesc.SampleDesc.Count = 1; - offscreenTextureDesc.SampleDesc.Quality = 0; - offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; - offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; - offscreenTextureDesc.CPUAccessFlags = 0; - offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0; - - HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); - - if (FAILED(result)) - { - ERR("Could not create offscreen texture: %08lX", result); - release(); - - if (d3d11::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - - d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture"); - - // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client - if (useSharedResource) - { - IDXGIResource *offscreenTextureResource = NULL; - result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource); - - // Fall back to no share handle on failure - if (FAILED(result)) - { - ERR("Could not query offscreen texture resource: %08lX", result); - } - else - { - result = offscreenTextureResource->GetSharedHandle(&mShareHandle); - offscreenTextureResource->Release(); - - if (FAILED(result)) - { - mShareHandle = NULL; - ERR("Could not get offscreen texture shared handle: %08lX", result); - } - } - } - } - - HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView); - - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target"); - - result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource"); - - if (mDepthBufferFormat != GL_NONE) - { - D3D11_TEXTURE2D_DESC depthStencilDesc = {0}; - depthStencilDesc.Width = backbufferWidth; - depthStencilDesc.Height = backbufferHeight; - depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat); - depthStencilDesc.MipLevels = 1; - depthStencilDesc.ArraySize = 1; - depthStencilDesc.SampleDesc.Count = 1; - depthStencilDesc.SampleDesc.Quality = 0; - depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; - depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; - depthStencilDesc.CPUAccessFlags = 0; - depthStencilDesc.MiscFlags = 0; - - result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture); - if (FAILED(result)) - { - ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); - release(); - - if (d3d11::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture"); - - result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view"); - } - - mWidth = backbufferWidth; - mHeight = backbufferHeight; - - if (previousOffscreenTexture != NULL) - { - D3D11_BOX sourceBox = {0}; - sourceBox.left = 0; - sourceBox.right = std::min(previousWidth, mWidth); - sourceBox.top = std::max(previousHeight - mHeight, 0); - sourceBox.bottom = previousHeight; - sourceBox.front = 0; - sourceBox.back = 1; - - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - const int yoffset = std::max(mHeight - previousHeight, 0); - deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox); - - previousOffscreenTexture->Release(); - - if (mSwapChain) - { - swapRect(0, 0, mWidth, mHeight); - } - } - - return EGL_SUCCESS; -} - -EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) -{ - ID3D11Device *device = mRenderer->getDevice(); - - if (device == NULL) - { - return EGL_BAD_ACCESS; - } - - if (!mSwapChain) - reset(backbufferWidth, backbufferHeight, mSwapInterval); - - // Can only call resize if we have already created our swap buffer and resources - ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); - - if (mBackBufferTexture) - { - mBackBufferTexture->Release(); - mBackBufferTexture = NULL; - } - - if (mBackBufferRTView) - { - mBackBufferRTView->Release(); - mBackBufferRTView = NULL; - } - - // Resize swap chain - DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); - HRESULT result = mSwapChain->ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0); - - if (FAILED(result)) - { - ERR("Error resizing swap chain buffers: 0x%08X", result); - release(); - - if (d3d11::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - - result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); - } - - result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); - ASSERT(SUCCEEDED(result)); - if (SUCCEEDED(result)) - { - d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); - } - - return resetOffscreenTexture(backbufferWidth, backbufferHeight); -} - -EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) -{ - ID3D11Device *device = mRenderer->getDevice(); - - if (device == NULL) - { - return EGL_BAD_ACCESS; - } - - // Release specific resources to free up memory for the new render target, while the - // old render target still exists for the purpose of preserving its contents. - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBufferTexture) - { - mBackBufferTexture->Release(); - mBackBufferTexture = NULL; - } - - if (mBackBufferRTView) - { - mBackBufferRTView->Release(); - mBackBufferRTView = NULL; - } - - mSwapInterval = static_cast(swapInterval); - if (mSwapInterval > 4) - { - // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range - return EGL_BAD_PARAMETER; - } - - // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains - if (backbufferWidth < 1 || backbufferHeight < 1) - { - releaseOffscreenTexture(); - return EGL_SUCCESS; - } - - if (mWindow) - { -#if !defined(ANGLE_OS_WINRT) - // We cannot create a swap chain for an HWND that is owned by a different process - DWORD currentProcessId = GetCurrentProcessId(); - DWORD wndProcessId; - GetWindowThreadProcessId(mWindow, &wndProcessId); - - if (currentProcessId != wndProcessId) - { - ERR("Could not create swap chain, window owned by different process"); - release(); - return EGL_BAD_NATIVE_WINDOW; - } - - IDXGIFactory *factory = mRenderer->getDxgiFactory(); - - DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; - swapChainDesc.BufferCount = 2; - swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); - swapChainDesc.BufferDesc.Width = backbufferWidth; - swapChainDesc.BufferDesc.Height = backbufferHeight; - swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; - swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; - swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; - swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; - swapChainDesc.Windowed = TRUE; - swapChainDesc.OutputWindow = mWindow; -#else - IDXGIFactory2 *factory; - HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory)); - ASSERT(SUCCEEDED(result)); - - DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; - swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); - swapChainDesc.Width = backbufferWidth; - swapChainDesc.Height = backbufferHeight; - swapChainDesc.Stereo = FALSE; -#if !defined(ANGLE_OS_WINPHONE) - swapChainDesc.BufferCount = 2; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; -#else - swapChainDesc.BufferCount = 1; - swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; -#endif -#endif - - swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; - swapChainDesc.Flags = 0; - swapChainDesc.SampleDesc.Count = 1; - swapChainDesc.SampleDesc.Quality = 0; - -#if !defined(ANGLE_OS_WINRT) - HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); -#else - IDXGISwapChain1 *swapChain; - result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain); - mSwapChain = swapChain; -#endif - - if (FAILED(result)) - { - ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); - release(); - - if (d3d11::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - - result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); - - result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); - } - - // If we are resizing the swap chain, we don't wish to recreate all the static resources - if (!mPassThroughResourcesInit) - { - mPassThroughResourcesInit = true; - initPassThroughResources(); - } - - return resetOffscreenTexture(backbufferWidth, backbufferHeight); -} - -void SwapChain11::initPassThroughResources() -{ - ID3D11Device *device = mRenderer->getDevice(); - - ASSERT(device != NULL); - - // Make sure our resources are all not allocated, when we create - ASSERT(mQuadVB == NULL && mPassThroughSampler == NULL); - ASSERT(mPassThroughIL == NULL && mPassThroughVS == NULL && mPassThroughPS == NULL); - - D3D11_BUFFER_DESC vbDesc; - vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; - vbDesc.Usage = D3D11_USAGE_DYNAMIC; - vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - vbDesc.MiscFlags = 0; - vbDesc.StructureByteStride = 0; - - HRESULT result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer"); - - D3D11_SAMPLER_DESC samplerDesc; - samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; - samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; - samplerDesc.MipLODBias = 0.0f; - samplerDesc.MaxAnisotropy = 0; - samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; - samplerDesc.BorderColor[0] = 0.0f; - samplerDesc.BorderColor[1] = 0.0f; - samplerDesc.BorderColor[2] = 0.0f; - samplerDesc.BorderColor[3] = 0.0f; - samplerDesc.MinLOD = 0; - samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; - - result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler"); - - D3D11_INPUT_ELEMENT_DESC quadLayout[] = - { - { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, - }; - - result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout"); - - result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader"); - - result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS); - ASSERT(SUCCEEDED(result)); - d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader"); -} - -// parameters should be validated/clamped by caller -EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) -{ - if (!mSwapChain) - { - return EGL_SUCCESS; - } - - ID3D11Device *device = mRenderer->getDevice(); - ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); - - // Set vertices - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - return EGL_BAD_ACCESS; - } - - d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); - - // Create a quad in homogeneous coordinates - float x1 = (x / float(mWidth)) * 2.0f - 1.0f; - float y1 = (y / float(mHeight)) * 2.0f - 1.0f; - float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; - float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; - - float u1 = x / float(mWidth); - float v1 = y / float(mHeight); - float u2 = (x + width) / float(mWidth); - float v2 = (y + height) / float(mHeight); - - d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1); - d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); - d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); - d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); - - deviceContext->Unmap(mQuadVB, 0); - - static UINT stride = sizeof(d3d11::PositionTexCoordVertex); - static UINT startIdx = 0; - deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx); - - // Apply state - deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); - - static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; - deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF); - - deviceContext->RSSetState(NULL); - - // Apply shaders - deviceContext->IASetInputLayout(mPassThroughIL); - deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); - deviceContext->VSSetShader(mPassThroughVS, NULL, 0); - deviceContext->PSSetShader(mPassThroughPS, NULL, 0); - deviceContext->GSSetShader(NULL, NULL, 0); - - // Apply render targets - mRenderer->setOneTimeRenderTarget(mBackBufferRTView); - - // Set the viewport - D3D11_VIEWPORT viewport; - viewport.TopLeftX = 0; - viewport.TopLeftY = 0; - viewport.Width = mWidth; - viewport.Height = mHeight; - viewport.MinDepth = 0.0f; - viewport.MaxDepth = 1.0f; - deviceContext->RSSetViewports(1, &viewport); - - // Apply textures - deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView); - deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); - - // Draw - deviceContext->Draw(4, 0); - result = mSwapChain->Present(mSwapInterval, 0); - - if (result == DXGI_ERROR_DEVICE_REMOVED) - { - HRESULT removedReason = device->GetDeviceRemovedReason(); - ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason); - return EGL_CONTEXT_LOST; - } - else if (result == DXGI_ERROR_DEVICE_RESET) - { - ERR("Present failed: the D3D11 device was reset from a bad command."); - return EGL_CONTEXT_LOST; - } - else if (FAILED(result)) - { - ERR("Present failed with error code 0x%08X", result); - } - - // Unbind - static ID3D11ShaderResourceView *const nullSRV = NULL; - deviceContext->PSSetShaderResources(0, 1, &nullSRV); - - mRenderer->unapplyRenderTargets(); - mRenderer->markAllStateDirty(); - - return EGL_SUCCESS; -} - -// Increments refcount on texture. -// caller must Release() the returned texture -ID3D11Texture2D *SwapChain11::getOffscreenTexture() -{ - if (mOffscreenTexture) - { - mOffscreenTexture->AddRef(); - } - - return mOffscreenTexture; -} - -// Increments refcount on view. -// caller must Release() the returned view -ID3D11RenderTargetView *SwapChain11::getRenderTarget() -{ - if (mOffscreenRTView) - { - mOffscreenRTView->AddRef(); - } - - return mOffscreenRTView; -} - -// Increments refcount on view. -// caller must Release() the returned view -ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource() -{ - if (mOffscreenSRView) - { - mOffscreenSRView->AddRef(); - } - - return mOffscreenSRView; -} - -// Increments refcount on view. -// caller must Release() the returned view -ID3D11DepthStencilView *SwapChain11::getDepthStencil() -{ - if (mDepthStencilDSView) - { - mDepthStencilDSView->AddRef(); - } - - return mDepthStencilDSView; -} - -ID3D11Texture2D *SwapChain11::getDepthStencilTexture() -{ - if (mDepthStencilTexture) - { - mDepthStencilTexture->AddRef(); - } - - return mDepthStencilTexture; -} - -SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain)); - return static_cast(swapChain); -} - -void SwapChain11::recreate() -{ - // possibly should use this method instead of reset -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h deleted file mode 100644 index 2a030c839d..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain11.h +++ /dev/null @@ -1,78 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain. - -#ifndef LIBGLESV2_RENDERER_SWAPCHAIN11_H_ -#define LIBGLESV2_RENDERER_SWAPCHAIN11_H_ - -#include "common/angleutils.h" -#include "libGLESv2/renderer/SwapChain.h" - -namespace rx -{ -class Renderer11; - -class SwapChain11 : public SwapChain -{ - public: - SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat); - virtual ~SwapChain11(); - - 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(); - - virtual ID3D11Texture2D *getOffscreenTexture(); - virtual ID3D11RenderTargetView *getRenderTarget(); - virtual ID3D11ShaderResourceView *getRenderTargetShaderResource(); - - virtual ID3D11Texture2D *getDepthStencilTexture(); - virtual ID3D11DepthStencilView *getDepthStencil(); - - EGLint getWidth() const { return mWidth; } - EGLint getHeight() const { return mHeight; } - - static SwapChain11 *makeSwapChain11(SwapChain *swapChain); - - private: - DISALLOW_COPY_AND_ASSIGN(SwapChain11); - - void release(); - void initPassThroughResources(); - void releaseOffscreenTexture(); - EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight); - - Renderer11 *mRenderer; - EGLint mHeight; - EGLint mWidth; - bool mAppCreatedShareHandle; - unsigned int mSwapInterval; - bool mPassThroughResourcesInit; - - IDXGISwapChain *mSwapChain; - - ID3D11Texture2D *mBackBufferTexture; - ID3D11RenderTargetView *mBackBufferRTView; - - ID3D11Texture2D *mOffscreenTexture; - ID3D11RenderTargetView *mOffscreenRTView; - ID3D11ShaderResourceView *mOffscreenSRView; - - ID3D11Texture2D *mDepthStencilTexture; - ID3D11DepthStencilView *mDepthStencilDSView; - - ID3D11Buffer *mQuadVB; - ID3D11SamplerState *mPassThroughSampler; - ID3D11InputLayout *mPassThroughIL; - ID3D11VertexShader *mPassThroughVS; - ID3D11PixelShader *mPassThroughPS; -}; - -} -#endif // LIBGLESV2_RENDERER_SWAPCHAIN11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp deleted file mode 100644 index f57a874688..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.cpp +++ /dev/null @@ -1,449 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012-2013 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. -// - -// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain. - -#include "libGLESv2/renderer/SwapChain9.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/renderer/Renderer9.h" - -namespace rx -{ - -SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat) - : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) -{ - mSwapChain = NULL; - mBackBuffer = NULL; - mDepthStencil = NULL; - mRenderTarget = NULL; - mOffscreenTexture = NULL; - mWidth = -1; - mHeight = -1; - mSwapInterval = -1; -} - -SwapChain9::~SwapChain9() -{ - release(); -} - -void SwapChain9::release() -{ - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBuffer) - { - mBackBuffer->Release(); - mBackBuffer = NULL; - } - - if (mDepthStencil) - { - mDepthStencil->Release(); - mDepthStencil = NULL; - } - - if (mRenderTarget) - { - mRenderTarget->Release(); - mRenderTarget = NULL; - } - - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mWindow) - mShareHandle = NULL; -} - -static DWORD convertInterval(EGLint interval) -{ - switch(interval) - { - case 0: return D3DPRESENT_INTERVAL_IMMEDIATE; - case 1: return D3DPRESENT_INTERVAL_ONE; - case 2: return D3DPRESENT_INTERVAL_TWO; - case 3: return D3DPRESENT_INTERVAL_THREE; - case 4: return D3DPRESENT_INTERVAL_FOUR; - default: UNREACHABLE(); - } - - return D3DPRESENT_INTERVAL_DEFAULT; -} - -EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight) -{ - // D3D9 does not support resizing swap chains without recreating them - return reset(backbufferWidth, backbufferHeight, mSwapInterval); -} - -EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) -{ - IDirect3DDevice9 *device = mRenderer->getDevice(); - - if (device == NULL) - { - return EGL_BAD_ACCESS; - } - - // Evict all non-render target textures to system memory and release all resources - // before reallocating them to free up as much video memory as possible. - device->EvictManagedResources(); - - HRESULT result; - - // Release specific resources to free up memory for the new render target, while the - // old render target still exists for the purpose of preserving its contents. - if (mSwapChain) - { - mSwapChain->Release(); - mSwapChain = NULL; - } - - if (mBackBuffer) - { - mBackBuffer->Release(); - mBackBuffer = NULL; - } - - if (mOffscreenTexture) - { - mOffscreenTexture->Release(); - mOffscreenTexture = NULL; - } - - if (mDepthStencil) - { - mDepthStencil->Release(); - mDepthStencil = NULL; - } - - HANDLE *pShareHandle = NULL; - if (!mWindow && mRenderer->getShareHandleSupport()) - { - pShareHandle = &mShareHandle; - } - - // CreateTexture will fail on zero dimensions, so just release old target - if (!backbufferWidth || !backbufferHeight) - { - if (mRenderTarget) - { - mRenderTarget->Release(); - mRenderTarget = NULL; - } - - mWidth = backbufferWidth; - mHeight = backbufferHeight; - - return EGL_SUCCESS; - } - - result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, - gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT, - &mOffscreenTexture, pShareHandle); - if (FAILED(result)) - { - ERR("Could not create offscreen texture: %08lX", result); - release(); - - if (d3d9::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - - IDirect3DSurface9 *oldRenderTarget = mRenderTarget; - - result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); - ASSERT(SUCCEEDED(result)); - - if (oldRenderTarget) - { - RECT rect = - { - 0, 0, - mWidth, mHeight - }; - - if (rect.right > static_cast(backbufferWidth)) - { - rect.right = backbufferWidth; - } - - if (rect.bottom > static_cast(backbufferHeight)) - { - rect.bottom = backbufferHeight; - } - - mRenderer->endScene(); - - result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); - ASSERT(SUCCEEDED(result)); - - oldRenderTarget->Release(); - } - - if (mWindow) - { - D3DPRESENT_PARAMETERS presentParameters = {0}; - presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat); - presentParameters.BackBufferCount = 1; - presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat); - presentParameters.EnableAutoDepthStencil = FALSE; - presentParameters.Flags = 0; - presentParameters.hDeviceWindow = mWindow; - presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented - presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented - presentParameters.PresentationInterval = convertInterval(swapInterval); - presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; - presentParameters.Windowed = TRUE; - presentParameters.BackBufferWidth = backbufferWidth; - presentParameters.BackBufferHeight = backbufferHeight; - - // http://crbug.com/140239 - // http://crbug.com/143434 - // - // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width - // when using the integrated Intel. This rounds the width up rather than down. - // - // 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->getAdapterVendor() == VENDOR_ID_INTEL) - { - presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64; - } - - result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); - - if (FAILED(result)) - { - 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); - release(); - - if (d3d9::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - - result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); - ASSERT(SUCCEEDED(result)); - InvalidateRect(mWindow, NULL, FALSE); - } - - if (mDepthBufferFormat != GL_NONE) - { - result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, - gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat), - D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); - - 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); - release(); - - if (d3d9::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - else - { - return EGL_BAD_ALLOC; - } - } - } - - mWidth = backbufferWidth; - mHeight = backbufferHeight; - mSwapInterval = swapInterval; - - return EGL_SUCCESS; -} - -// parameters should be validated/clamped by caller -EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) -{ - if (!mSwapChain) - { - return EGL_SUCCESS; - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - - // Disable all pipeline operations - device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); - device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); - device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); - device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); - device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); - device->SetRenderState(D3DRS_STENCILENABLE, FALSE); - device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); - 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->SetRenderTarget(0, mBackBuffer); - device->SetDepthStencilSurface(NULL); - - device->SetTexture(0, mOffscreenTexture); - device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); - device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); - device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); - device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); - device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); - - D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; - device->SetViewport(&viewport); - - float x1 = x - 0.5f; - float y1 = (mHeight - y - height) - 0.5f; - float x2 = (x + width) - 0.5f; - float y2 = (mHeight - y) - 0.5f; - - float u1 = x / float(mWidth); - float v1 = y / float(mHeight); - float u2 = (x + width) / float(mWidth); - float v2 = (y + height) / float(mHeight); - - float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2}, - {x2, y1, 0.0f, 1.0f, u2, v2}, - {x2, y2, 0.0f, 1.0f, u2, v1}, - {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v - - mRenderer->startScene(); - device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); - mRenderer->endScene(); - - device->SetTexture(0, NULL); - - RECT rect = - { - x, mHeight - y - height, - x + width, mHeight - y - }; - - HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); - - mRenderer->markAllStateDirty(); - - if (d3d9::isDeviceLostError(result)) - { - return EGL_CONTEXT_LOST; - } - - if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) - { - return EGL_BAD_ALLOC; - } - - ASSERT(SUCCEEDED(result)); - - return EGL_SUCCESS; -} - -// Increments refcount on surface. -// caller must Release() the returned surface -IDirect3DSurface9 *SwapChain9::getRenderTarget() -{ - if (mRenderTarget) - { - mRenderTarget->AddRef(); - } - - return mRenderTarget; -} - -// Increments refcount on surface. -// caller must Release() the returned surface -IDirect3DSurface9 *SwapChain9::getDepthStencil() -{ - if (mDepthStencil) - { - mDepthStencil->AddRef(); - } - - return mDepthStencil; -} - -// Increments refcount on texture. -// caller must Release() the returned texture -IDirect3DTexture9 *SwapChain9::getOffscreenTexture() -{ - if (mOffscreenTexture) - { - mOffscreenTexture->AddRef(); - } - - return mOffscreenTexture; -} - -SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain) -{ - ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain)); - return static_cast(swapChain); -} - -void SwapChain9::recreate() -{ - if (!mSwapChain) - { - return; - } - - IDirect3DDevice9 *device = mRenderer->getDevice(); - if (device == NULL) - { - return; - } - - D3DPRESENT_PARAMETERS presentParameters; - HRESULT result = mSwapChain->GetPresentParameters(&presentParameters); - ASSERT(SUCCEEDED(result)); - - IDirect3DSwapChain9* newSwapChain = NULL; - result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain); - if (FAILED(result)) - { - return; - } - - mSwapChain->Release(); - mSwapChain = newSwapChain; - - mBackBuffer->Release(); - result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); - ASSERT(SUCCEEDED(result)); -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h deleted file mode 100644 index 16a62bd86f..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/SwapChain9.h +++ /dev/null @@ -1,55 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain. - -#ifndef LIBGLESV2_RENDERER_SWAPCHAIN9_H_ -#define LIBGLESV2_RENDERER_SWAPCHAIN9_H_ - -#include "common/angleutils.h" -#include "libGLESv2/renderer/SwapChain.h" - -namespace rx -{ -class Renderer9; - -class SwapChain9 : public SwapChain -{ - public: - SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, - GLenum backBufferFormat, GLenum depthBufferFormat); - virtual ~SwapChain9(); - - 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(); - - virtual IDirect3DSurface9 *getRenderTarget(); - virtual IDirect3DSurface9 *getDepthStencil(); - virtual IDirect3DTexture9 *getOffscreenTexture(); - - static SwapChain9 *makeSwapChain9(SwapChain *swapChain); - - private: - DISALLOW_COPY_AND_ASSIGN(SwapChain9); - - void release(); - - Renderer9 *mRenderer; - EGLint mHeight; - EGLint mWidth; - EGLint mSwapInterval; - - IDirect3DSwapChain9 *mSwapChain; - IDirect3DSurface9 *mBackBuffer; - IDirect3DSurface9 *mRenderTarget; - IDirect3DSurface9 *mDepthStencil; - IDirect3DTexture9* mOffscreenTexture; -}; - -} -#endif // LIBGLESV2_RENDERER_SWAPCHAIN9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp deleted file mode 100644 index 32a407a988..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.cpp +++ /dev/null @@ -1,667 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived -// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. - -#include "libGLESv2/renderer/TextureStorage11.h" - -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/renderer/RenderTarget11.h" -#include "libGLESv2/renderer/SwapChain11.h" -#include "libGLESv2/renderer/renderer11_utils.h" - -#include "libGLESv2/utilities.h" -#include "libGLESv2/main.h" - -namespace rx -{ - -TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags) - : mBindFlags(bindFlags), - mLodOffset(0), - mMipLevels(0), - mTexture(NULL), - mTextureFormat(DXGI_FORMAT_UNKNOWN), - mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), - mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), - mDepthStencilFormat(DXGI_FORMAT_UNKNOWN), - mSRV(NULL), - mTextureWidth(0), - mTextureHeight(0) -{ - mRenderer = Renderer11::makeRenderer11(renderer); -} - -TextureStorage11::~TextureStorage11() -{ -} - -TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage)); - return static_cast(storage); -} - -DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable) -{ - UINT bindFlags = D3D11_BIND_SHADER_RESOURCE; - - if (d3d11::IsDepthStencilFormat(format)) - { - bindFlags |= D3D11_BIND_DEPTH_STENCIL; - } - else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) - { - bindFlags |= D3D11_BIND_RENDER_TARGET; - } - return bindFlags; -} - -bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format) -{ - switch(format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_R8_UNORM: - case DXGI_FORMAT_R8G8_UNORM: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16G16_FLOAT: - return true; - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_R32G32B32_FLOAT: // not renderable on all devices - return false; - default: - UNREACHABLE(); - return false; - } -} - -UINT TextureStorage11::getBindFlags() const -{ - return mBindFlags; -} - -ID3D11Texture2D *TextureStorage11::getBaseTexture() const -{ - return mTexture; -} - -int TextureStorage11::getLodOffset() const -{ - return mLodOffset; -} - -bool TextureStorage11::isRenderTarget() const -{ - return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0; -} - -bool TextureStorage11::isManaged() const -{ - return false; -} - -int TextureStorage11::levelCount() -{ - int levels = 0; - if (getBaseTexture()) - { - levels = mMipLevels - getLodOffset(); - } - return levels; -} - -UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex) -{ - UINT index = 0; - if (getBaseTexture()) - { - index = D3D11CalcSubresource(level, faceIndex, mMipLevels); - } - return index; -} - -bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, unsigned int sourceSubresource, - int level, int face, GLint xoffset, GLint yoffset, - GLsizei width, GLsizei height) -{ - if (srcTexture) - { - // Round up the width and height to the nearest multiple of dimension alignment - unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(mTextureFormat); - width = width + dimensionAlignment - 1 - (width - 1) % dimensionAlignment; - height = height + dimensionAlignment - 1 - (height - 1) % dimensionAlignment; - - D3D11_BOX srcBox; - srcBox.left = xoffset; - srcBox.top = yoffset; - srcBox.right = xoffset + width; - srcBox.bottom = yoffset + height; - srcBox.front = 0; - srcBox.back = 1; - - ID3D11DeviceContext *context = mRenderer->getDeviceContext(); - - ASSERT(getBaseTexture()); - context->CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level + mLodOffset, face), - xoffset, yoffset, 0, srcTexture, sourceSubresource, &srcBox); - return true; - } - - return false; -} - -void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) -{ - if (source && dest) - { - ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView(); - ID3D11RenderTargetView *destRTV = dest->getRenderTargetView(); - - if (sourceSRV && destRTV) - { - gl::Rectangle sourceArea; - sourceArea.x = 0; - sourceArea.y = 0; - sourceArea.width = source->getWidth(); - sourceArea.height = source->getHeight(); - - gl::Rectangle destArea; - destArea.x = 0; - destArea.y = 0; - destArea.width = dest->getWidth(); - destArea.height = dest->getHeight(); - - mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(), - destRTV, destArea, dest->getWidth(), dest->getHeight(), - GL_RGBA); - } - } -} - -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) - : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) -{ - mTexture = swapchain->getOffscreenTexture(); - mSRV = swapchain->getRenderTargetShaderResource(); - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mRenderTarget[i] = NULL; - } - - D3D11_TEXTURE2D_DESC texDesc; - mTexture->GetDesc(&texDesc); - mMipLevels = texDesc.MipLevels; - mTextureFormat = texDesc.Format; - mTextureWidth = texDesc.Width; - mTextureHeight = texDesc.Height; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - mSRV->GetDesc(&srvDesc); - mShaderResourceFormat = srvDesc.Format; - - ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget(); - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - offscreenRTV->GetDesc(&rtvDesc); - mRenderTargetFormat = rtvDesc.Format; - offscreenRTV->Release(); - - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; -} - -TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) - : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable)) -{ - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - mRenderTarget[i] = NULL; - } - - DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()); - if (d3d11::IsDepthStencilFormat(convertedFormat)) - { - mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat); - mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat); - mDepthStencilFormat = convertedFormat; - mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; - } - else - { - mTextureFormat = convertedFormat; - mShaderResourceFormat = convertedFormat; - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; - mRenderTargetFormat = convertedFormat; - } - - // 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 (width > 0 && height > 0) - { - // adjust size if needed for compressed textures - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = width; // Compressed texture size constraints? - desc.Height = height; - desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0; - desc.ArraySize = 1; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = 0; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - // this can happen from windows TDR - if (d3d11::isDeviceLostError(result)) - { - mRenderer->notifyDeviceLost(); - gl::error(GL_OUT_OF_MEMORY); - } - else if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - } - } -} - -TextureStorage11_2D::~TextureStorage11_2D() -{ - if (mTexture) - { - mTexture->Release(); - mTexture = NULL; - } - - if (mSRV) - { - mSRV->Release(); - mSRV = NULL; - } - - for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) - { - delete mRenderTarget[i]; - mRenderTarget[i] = NULL; - } -} - -TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage)); - return static_cast(storage); -} - -RenderTarget *TextureStorage11_2D::getRenderTarget(int level) -{ - if (level >= 0 && level < static_cast(mMipLevels)) - { - if (!mRenderTarget[level]) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MostDetailedMip = level; - srvDesc.Texture2D.MipLevels = 1; - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; - rtvDesc.Texture2D.MipSlice = level; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mDepthStencilFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; - dsvDesc.Texture2D.MipSlice = level; - dsvDesc.Flags = 0; - - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else - { - UNREACHABLE(); - } - } - - return mRenderTarget[level]; - } - else - { - return NULL; - } -} - -ID3D11ShaderResourceView *TextureStorage11_2D::getSRV() -{ - if (!mSRV) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; - srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels); - srvDesc.Texture2D.MostDetailedMip = 0; - - HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - } - - return mSRV; -} - -void TextureStorage11_2D::generateMipmap(int level) -{ - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); - - generateMipmapLayer(source, dest); -} - -TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) - : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable)) -{ - for (unsigned int i = 0; i < 6; i++) - { - for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++) - { - mRenderTarget[i][j] = NULL; - } - } - - DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()); - if (d3d11::IsDepthStencilFormat(convertedFormat)) - { - mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat); - mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat); - mDepthStencilFormat = convertedFormat; - mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; - } - else - { - mTextureFormat = convertedFormat; - mShaderResourceFormat = convertedFormat; - mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; - mRenderTargetFormat = convertedFormat; - } - - // 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 (size > 0) - { - // adjust size if needed for compressed textures - int height = size; - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset); - - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_TEXTURE2D_DESC desc; - desc.Width = size; - desc.Height = size; - desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0; - desc.ArraySize = 6; - desc.Format = mTextureFormat; - desc.SampleDesc.Count = 1; - desc.SampleDesc.Quality = 0; - desc.Usage = D3D11_USAGE_DEFAULT; - desc.BindFlags = getBindFlags(); - desc.CPUAccessFlags = 0; - desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; - - HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); - - if (FAILED(result)) - { - ASSERT(result == E_OUTOFMEMORY); - ERR("Creating image failed."); - gl::error(GL_OUT_OF_MEMORY); - } - else - { - mTexture->GetDesc(&desc); - mMipLevels = desc.MipLevels; - mTextureWidth = desc.Width; - mTextureHeight = desc.Height; - } - } -} - -TextureStorage11_Cube::~TextureStorage11_Cube() -{ - if (mTexture) - { - mTexture->Release(); - mTexture = NULL; - } - - if (mSRV) - { - mSRV->Release(); - mSRV = NULL; - } - - for (unsigned int i = 0; i < 6; i++) - { - for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++) - { - delete mRenderTarget[i][j]; - mRenderTarget[i][j] = NULL; - } - } -} - -TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage)); - return static_cast(storage); -} - -RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level) -{ - unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget); - if (level >= 0 && level < static_cast(mMipLevels)) - { - if (!mRenderTarget[faceIdx][level]) - { - ID3D11Device *device = mRenderer->getDevice(); - HRESULT result; - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srvDesc.Texture2DArray.MostDetailedMip = level; - srvDesc.Texture2DArray.MipLevels = 1; - srvDesc.Texture2DArray.FirstArraySlice = faceIdx; - srvDesc.Texture2DArray.ArraySize = 1; - - ID3D11ShaderResourceView *srv; - result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; - rtvDesc.Format = mRenderTargetFormat; - rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; - rtvDesc.Texture2DArray.MipSlice = level; - rtvDesc.Texture2DArray.FirstArraySlice = faceIdx; - rtvDesc.Texture2DArray.ArraySize = 1; - - ID3D11RenderTargetView *rtv; - result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) - { - D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; - dsvDesc.Format = mRenderTargetFormat; - dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; - dsvDesc.Texture2DArray.MipSlice = level; - dsvDesc.Texture2DArray.FirstArraySlice = faceIdx; - dsvDesc.Texture2DArray.ArraySize = 1; - - ID3D11DepthStencilView *dsv; - result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); - - if (result == E_OUTOFMEMORY) - { - srv->Release(); - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - - // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 - // also needs to keep a reference to the texture. - mTexture->AddRef(); - - mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, - std::max(mTextureWidth >> level, 1U), - std::max(mTextureHeight >> level, 1U)); - } - else - { - UNREACHABLE(); - } - } - - return mRenderTarget[faceIdx][level]; - } - else - { - return NULL; - } -} - -ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV() -{ - if (!mSRV) - { - ID3D11Device *device = mRenderer->getDevice(); - - D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; - srvDesc.Format = mShaderResourceFormat; - srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; - srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels); - srvDesc.TextureCube.MostDetailedMip = 0; - - HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV); - - if (result == E_OUTOFMEMORY) - { - return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); - } - ASSERT(SUCCEEDED(result)); - } - - return mSRV; -} - -void TextureStorage11_Cube::generateMipmap(int face, int level) -{ - RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1)); - RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level)); - - generateMipmapLayer(source, dest); -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h deleted file mode 100644 index 3c5ded05b8..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage11.h +++ /dev/null @@ -1,120 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived -// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. - -#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ -#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ - -#include "libGLESv2/Texture.h" -#include "libGLESv2/renderer/TextureStorage.h" - -namespace rx -{ -class RenderTarget; -class RenderTarget11; -class Renderer; -class Renderer11; -class SwapChain11; - -class TextureStorage11 : public TextureStorage -{ - public: - TextureStorage11(Renderer *renderer, UINT bindFlags); - virtual ~TextureStorage11(); - - static TextureStorage11 *makeTextureStorage11(TextureStorage *storage); - - static DWORD GetTextureBindFlags(DXGI_FORMAT d3dfmt, GLenum glusage, bool forceRenderable); - static bool IsTextureFormatRenderable(DXGI_FORMAT format); - - UINT getBindFlags() const; - - virtual ID3D11Texture2D *getBaseTexture() const; - virtual ID3D11ShaderResourceView *getSRV() = 0; - virtual RenderTarget *getRenderTarget() { return getRenderTarget(0); } - virtual RenderTarget *getRenderTarget(int level) { return NULL; } - virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return getRenderTarget(faceTarget, 0); } - virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level) { return NULL; } - - virtual void generateMipmap(int level) {}; - virtual void generateMipmap(int face, int level) {}; - - virtual int getLodOffset() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; - virtual int levelCount(); - UINT getSubresourceIndex(int level, int faceTarget); - - bool updateSubresourceLevel(ID3D11Texture2D *texture, unsigned int sourceSubresource, int level, - int faceTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); - - protected: - void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); - - Renderer11 *mRenderer; - int mLodOffset; - unsigned int mMipLevels; - - ID3D11Texture2D *mTexture; - DXGI_FORMAT mTextureFormat; - DXGI_FORMAT mShaderResourceFormat; - DXGI_FORMAT mRenderTargetFormat; - DXGI_FORMAT mDepthStencilFormat; - unsigned int mTextureWidth; - unsigned int mTextureHeight; - - ID3D11ShaderResourceView *mSRV; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11); - - const UINT mBindFlags; -}; - -class TextureStorage11_2D : public TextureStorage11 -{ - public: - TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain); - TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual ~TextureStorage11_2D(); - - static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); - - virtual ID3D11ShaderResourceView *getSRV(); - virtual RenderTarget *getRenderTarget(int level); - - virtual void generateMipmap(int level); - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); - - RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; -}; - -class TextureStorage11_Cube : public TextureStorage11 -{ - public: - TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); - virtual ~TextureStorage11_Cube(); - - static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); - - virtual ID3D11ShaderResourceView *getSRV(); - virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level); - - virtual void generateMipmap(int face, int level); - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); - - RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; -}; - -} - -#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp deleted file mode 100644 index 8aa74a7cba..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.cpp +++ /dev/null @@ -1,328 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived -// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the -// D3D9 texture. - -#include "libGLESv2/main.h" -#include "libGLESv2/renderer/Renderer9.h" -#include "libGLESv2/renderer/TextureStorage9.h" -#include "libGLESv2/renderer/SwapChain9.h" -#include "libGLESv2/renderer/RenderTarget9.h" -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/Texture.h" - -namespace rx -{ -TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage) - : mLodOffset(0), - mRenderer(Renderer9::makeRenderer9(renderer)), - mD3DUsage(usage), - mD3DPool(mRenderer->getTexturePool(usage)) -{ -} - -TextureStorage9::~TextureStorage9() -{ -} - -TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9*, storage)); - return static_cast(storage); -} - -DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable) -{ - DWORD d3dusage = 0; - - if (d3dfmt == D3DFMT_INTZ) - { - d3dusage |= D3DUSAGE_DEPTHSTENCIL; - } - else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) - { - d3dusage |= D3DUSAGE_RENDERTARGET; - } - return d3dusage; -} - -bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - { - return true; - } - switch(format) - { - case D3DFMT_L8: - case D3DFMT_A8L8: - case D3DFMT_DXT1: - case D3DFMT_DXT3: - case D3DFMT_DXT5: - return false; - case D3DFMT_A8R8G8B8: - case D3DFMT_X8R8G8B8: - case D3DFMT_A16B16G16R16F: - case D3DFMT_A32B32G32R32F: - return true; - default: - UNREACHABLE(); - } - - return false; -} - -bool TextureStorage9::isRenderTarget() const -{ - return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0; -} - -bool TextureStorage9::isManaged() const -{ - return (mD3DPool == D3DPOOL_MANAGED); -} - -D3DPOOL TextureStorage9::getPool() const -{ - return mD3DPool; -} - -DWORD TextureStorage9::getUsage() const -{ - return mD3DUsage; -} - -int TextureStorage9::getLodOffset() const -{ - return mLodOffset; -} - -int TextureStorage9::levelCount() -{ - return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0; -} - -TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET) -{ - IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture(); - mTexture = surfaceTexture; - mRenderTarget = NULL; - - initializeRenderTarget(); -} - -TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) - : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) -{ - mTexture = NULL; - mRenderTarget = NULL; - // 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 (width > 0 && height > 0) - { - IDirect3DDevice9 *device = mRenderer->getDevice(); - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); - HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(), - mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - gl::error(GL_OUT_OF_MEMORY); - } - } - - initializeRenderTarget(); -} - -TextureStorage9_2D::~TextureStorage9_2D() -{ - if (mTexture) - { - mTexture->Release(); - } - - delete mRenderTarget; -} - -TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_2D*, storage)); - return static_cast(storage); -} - -// Increments refcount on surface. -// caller must Release() the returned surface -IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) -{ - IDirect3DSurface9 *surface = NULL; - - if (mTexture) - { - HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface); - ASSERT(SUCCEEDED(result)); - - // With managed textures the driver needs to be informed of updates to the lower mipmap levels - if (level + mLodOffset != 0 && isManaged() && dirty) - { - mTexture->AddDirtyRect(NULL); - } - } - - return surface; -} - -RenderTarget *TextureStorage9_2D::getRenderTarget() -{ - return mRenderTarget; -} - -void TextureStorage9_2D::generateMipmap(int level) -{ - IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); - IDirect3DSurface9 *lower = getSurfaceLevel(level, true); - - if (upper != NULL && lower != NULL) - { - mRenderer->boxFilter(upper, lower); - } - - if (upper != NULL) upper->Release(); - if (lower != NULL) lower->Release(); -} - -IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const -{ - return mTexture; -} - -void TextureStorage9_2D::initializeRenderTarget() -{ - ASSERT(mRenderTarget == NULL); - - if (mTexture != NULL && isRenderTarget()) - { - IDirect3DSurface9 *surface = getSurfaceLevel(0, false); - - mRenderTarget = new RenderTarget9(mRenderer, surface); - } -} - -TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) - : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) -{ - mTexture = NULL; - for (int i = 0; i < 6; ++i) - { - mRenderTarget[i] = NULL; - } - - // 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 (size > 0) - { - IDirect3DDevice9 *device = mRenderer->getDevice(); - int height = size; - gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset); - HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(), - mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); - - if (FAILED(result)) - { - ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); - gl::error(GL_OUT_OF_MEMORY); - } - } - - initializeRenderTarget(); -} - -TextureStorage9_Cube::~TextureStorage9_Cube() -{ - if (mTexture) - { - mTexture->Release(); - } - - for (int i = 0; i < 6; ++i) - { - delete mRenderTarget[i]; - } -} - -TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStorage *storage) -{ - ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_Cube*, storage)); - return static_cast(storage); -} - -// Increments refcount on surface. -// caller must Release() the returned surface -IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty) -{ - IDirect3DSurface9 *surface = NULL; - - if (mTexture) - { - D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); - HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface); - ASSERT(SUCCEEDED(result)); - - // With managed textures the driver needs to be informed of updates to the lower mipmap levels - if (level != 0 && isManaged() && dirty) - { - mTexture->AddDirtyRect(face, NULL); - } - } - - return surface; -} - -RenderTarget *TextureStorage9_Cube::getRenderTarget(GLenum faceTarget) -{ - return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)]; -} - -void TextureStorage9_Cube::generateMipmap(int face, int level) -{ - IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false); - IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true); - - if (upper != NULL && lower != NULL) - { - mRenderer->boxFilter(upper, lower); - } - - if (upper != NULL) upper->Release(); - if (lower != NULL) lower->Release(); -} - -IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const -{ - return mTexture; -} - -void TextureStorage9_Cube::initializeRenderTarget() -{ - if (mTexture != NULL && isRenderTarget()) - { - IDirect3DSurface9 *surface = NULL; - - for (int i = 0; i < 6; ++i) - { - ASSERT(mRenderTarget[i] == NULL); - - surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false); - - mRenderTarget[i] = new RenderTarget9(mRenderer, surface); - } - } -} - -} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h deleted file mode 100644 index 86f551a131..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/TextureStorage9.h +++ /dev/null @@ -1,109 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived -// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the -// D3D9 texture. - -#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_ -#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_ - -#include "libGLESv2/renderer/TextureStorage.h" -#include "common/debug.h" - -namespace rx -{ -class Renderer9; -class SwapChain9; -class RenderTarget; -class RenderTarget9; -class Blit; - -class TextureStorage9 : public TextureStorage -{ - public: - TextureStorage9(Renderer *renderer, DWORD usage); - virtual ~TextureStorage9(); - - static TextureStorage9 *makeTextureStorage9(TextureStorage *storage); - - static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable); - static bool IsTextureFormatRenderable(D3DFORMAT format); - - D3DPOOL getPool() const; - DWORD getUsage() const; - - virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; - virtual RenderTarget *getRenderTarget() { return NULL; } - virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return NULL; } - virtual void generateMipmap(int level) {}; - virtual void generateMipmap(int face, int level) {}; - - virtual int getLodOffset() const; - virtual bool isRenderTarget() const; - virtual bool isManaged() const; - virtual int levelCount(); - - protected: - int mLodOffset; - Renderer9 *mRenderer; - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage9); - - const DWORD mD3DUsage; - const D3DPOOL mD3DPool; -}; - -class TextureStorage9_2D : public TextureStorage9 -{ - public: - TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain); - TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); - virtual ~TextureStorage9_2D(); - - static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); - - IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); - virtual RenderTarget *getRenderTarget(); - virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int level); - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D); - - void initializeRenderTarget(); - - IDirect3DTexture9 *mTexture; - RenderTarget9 *mRenderTarget; -}; - -class TextureStorage9_Cube : public TextureStorage9 -{ - public: - TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); - virtual ~TextureStorage9_Cube(); - - static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); - - IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); - virtual RenderTarget *getRenderTarget(GLenum faceTarget); - virtual IDirect3DBaseTexture9 *getBaseTexture() const; - virtual void generateMipmap(int face, int level); - - private: - DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube); - - void initializeRenderTarget(); - - IDirect3DCubeTexture9 *mTexture; - RenderTarget9 *mRenderTarget[6]; -}; - -} - -#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_ - diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp deleted file mode 100644 index 521da80c3d..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.cpp +++ /dev/null @@ -1,440 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2013 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. -// - -// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. - -#include "libGLESv2/renderer/VertexBuffer11.h" -#include "libGLESv2/renderer/BufferStorage.h" - -#include "libGLESv2/Buffer.h" -#include "libGLESv2/renderer/Renderer11.h" -#include "libGLESv2/Context.h" - -namespace rx -{ - -VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) -{ - mBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; -} - -VertexBuffer11::~VertexBuffer11() -{ - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } -} - -bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) -{ - if (mBuffer) - { - mBuffer->Release(); - mBuffer = NULL; - } - - updateSerial(); - - if (size > 0) - { - ID3D11Device* dxDevice = mRenderer->getDevice(); - - D3D11_BUFFER_DESC bufferDesc; - bufferDesc.ByteWidth = size; - bufferDesc.Usage = D3D11_USAGE_DYNAMIC; - bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; - bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; - bufferDesc.MiscFlags = 0; - bufferDesc.StructureByteStride = 0; - - HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); - if (FAILED(result)) - { - return false; - } - } - - mBufferSize = size; - mDynamicUsage = dynamicUsage; - return true; -} - -VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); - return static_cast(vetexBuffer); -} - -bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, - GLsizei instances, unsigned int offset) -{ - if (mBuffer) - { - gl::Buffer *buffer = attrib.mBoundBuffer.get(); - - int inputStride = attrib.stride(); - const VertexConverter &converter = getVertexConversion(attrib); - - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } - - char* output = reinterpret_cast(mappedResource.pData) + offset; - - const char *input = NULL; - if (buffer) - { - BufferStorage *storage = buffer->getStorage(); - input = static_cast(storage->getData()) + static_cast(attrib.mOffset); - } - else - { - input = static_cast(attrib.mPointer); - } - - if (instances == 0 || attrib.mDivisor == 0) - { - input += inputStride * start; - } - - converter.conversionFunc(input, inputStride, count, output); - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned int offset) -{ - if (mBuffer) - { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } - - char* bufferData = static_cast(mappedResource.pData); - memcpy(bufferData + offset, data, size); - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, - GLsizei instances, unsigned int *outSpaceRequired) const -{ - unsigned int elementSize = getVertexConversion(attrib).outputElementSize; - - unsigned int elementCount = 0; - if (instances == 0 || attrib.mDivisor == 0) - { - elementCount = count; - } - else - { - if (static_cast(instances) < std::numeric_limits::max() - (attrib.mDivisor - 1)) - { - // Round up - elementCount = (static_cast(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; - } - else - { - elementCount = instances / attrib.mDivisor; - } - } - - if (elementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * elementCount; - } - return true; - } - else - { - return false; - } -} - -bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const -{ - return !getVertexConversion(attrib).identity; -} - -unsigned int VertexBuffer11::getBufferSize() const -{ - return mBufferSize; -} - -bool VertexBuffer11::setBufferSize(unsigned int size) -{ - if (size > mBufferSize) - { - return initialize(size, mDynamicUsage); - } - else - { - return true; - } -} - -bool VertexBuffer11::discard() -{ - if (mBuffer) - { - ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); - - D3D11_MAPPED_SUBRESOURCE mappedResource; - HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); - if (FAILED(result)) - { - ERR("Vertex buffer map failed with error 0x%08x", result); - return false; - } - - dxContext->Unmap(mBuffer, 0); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const -{ - return getVertexConversion(attrib).outputElementSize; -} - -DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const -{ - return getVertexConversion(attrib).dxgiFormat; -} - -ID3D11Buffer *VertexBuffer11::getBuffer() const -{ - return mBuffer; -} - -template -static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output) -{ - unsigned int attribSize = sizeof(T) * componentCount; - - if (attribSize == stride && !widen) - { - memcpy(output, input, count * attribSize); - } - else - { - unsigned int outputStride = widen ? 4 : componentCount; - T defaultVal = normalized ? std::numeric_limits::max() : T(1); - - for (unsigned int i = 0; i < count; i++) - { - const T *offsetInput = reinterpret_cast(reinterpret_cast(input) + i * stride); - T *offsetOutput = reinterpret_cast(output) + i * outputStride; - - for (unsigned int j = 0; j < componentCount; j++) - { - offsetOutput[j] = offsetInput[j]; - } - - if (widen) - { - offsetOutput[3] = defaultVal; - } - } - } -} - -template -static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output) -{ - static const float divisor = 1.0f / (1 << 16); - - for (unsigned int i = 0; i < count; i++) - { - const GLfixed* offsetInput = reinterpret_cast(reinterpret_cast(input) + stride * i); - float* offsetOutput = reinterpret_cast(output) + i * componentCount; - - for (unsigned int j = 0; j < componentCount; j++) - { - offsetOutput[j] = static_cast(offsetInput[j]) * divisor; - } - } -} - -template -static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output) -{ - typedef std::numeric_limits NL; - - for (unsigned int i = 0; i < count; i++) - { - const T *offsetInput = reinterpret_cast(reinterpret_cast(input) + stride * i); - float *offsetOutput = reinterpret_cast(output) + i * componentCount; - - for (unsigned int j = 0; j < componentCount; j++) - { - if (normalized) - { - if (NL::is_signed) - { - const float divisor = 1.0f / (2 * static_cast(NL::max()) + 1); - offsetOutput[j] = (2 * static_cast(offsetInput[j]) + 1) * divisor; - } - else - { - offsetOutput[j] = static_cast(offsetInput[j]) / NL::max(); - } - } - else - { - offsetOutput[j] = static_cast(offsetInput[j]); - } - } - } -} - -const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = -{ - { // GL_BYTE - { // unnormalized - { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData, true, DXGI_FORMAT_R8_SNORM, 1 }, - { ©VertexData, true, DXGI_FORMAT_R8G8_SNORM, 2 }, - { ©VertexData, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, - { ©VertexData, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, - }, - }, - { // GL_UNSIGNED_BYTE - { // unnormalized - { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData, true, DXGI_FORMAT_R8_UNORM, 1 }, - { ©VertexData, true, DXGI_FORMAT_R8G8_UNORM, 2 }, - { ©VertexData, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, - { ©VertexData, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, - }, - }, - { // GL_SHORT - { // unnormalized - { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData, true, DXGI_FORMAT_R16_SNORM, 2 }, - { ©VertexData, true, DXGI_FORMAT_R16G16_SNORM, 4 }, - { ©VertexData, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, - { ©VertexData, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, - }, - }, - { // GL_UNSIGNED_SHORT - { // unnormalized - { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData, true, DXGI_FORMAT_R16_UNORM, 2 }, - { ©VertexData, true, DXGI_FORMAT_R16G16_UNORM, 4 }, - { ©VertexData, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, - { ©VertexData, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, - }, - }, - { // GL_FIXED - { // unnormalized - { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - }, - { // GL_FLOAT - { // unnormalized - { ©VertexData, true, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©VertexData, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©VertexData, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©VertexData, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - { // normalized - { ©VertexData, true, DXGI_FORMAT_R32_FLOAT, 4 }, - { ©VertexData, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, - { ©VertexData, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, - { ©VertexData, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, - }, - }, -}; - -const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute) -{ - unsigned int typeIndex = 0; - switch (attribute.mType) - { - case GL_BYTE: typeIndex = 0; break; - case GL_UNSIGNED_BYTE: typeIndex = 1; break; - case GL_SHORT: typeIndex = 2; break; - case GL_UNSIGNED_SHORT: typeIndex = 3; break; - case GL_FIXED: typeIndex = 4; break; - case GL_FLOAT: typeIndex = 5; break; - default: UNREACHABLE(); break; - } - - return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1]; -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h deleted file mode 100644 index eceb426e82..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer11.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation. - -#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ -#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ - -#include "libGLESv2/renderer/VertexBuffer.h" - -namespace rx -{ -class Renderer11; - -class VertexBuffer11 : public VertexBuffer -{ - public: - explicit VertexBuffer11(rx::Renderer11 *const renderer); - virtual ~VertexBuffer11(); - - virtual bool initialize(unsigned int size, bool dynamicUsage); - - static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer); - - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int offset); - virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); - - virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const; - - virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; - - virtual unsigned int getBufferSize() const; - virtual bool setBufferSize(unsigned int size); - virtual bool discard(); - - unsigned int getVertexSize(const gl::VertexAttribute &attrib) const; - DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &attrib) const; - - ID3D11Buffer *getBuffer() const; - - private: - DISALLOW_COPY_AND_ASSIGN(VertexBuffer11); - - rx::Renderer11 *const mRenderer; - - ID3D11Buffer *mBuffer; - unsigned int mBufferSize; - bool mDynamicUsage; - - typedef void (*VertexConversionFunction)(const void *, unsigned int, unsigned int, void *); - struct VertexConverter - { - VertexConversionFunction conversionFunc; - bool identity; - DXGI_FORMAT dxgiFormat; - unsigned int outputElementSize; - }; - - enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; - - // This table is used to generate mAttributeTypes. - static const VertexConverter mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1] - - static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute); -}; - -} - -#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp deleted file mode 100644 index b017b3af33..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.cpp +++ /dev/null @@ -1,530 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2012 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. -// - -// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. - -#include "libGLESv2/renderer/VertexBuffer9.h" -#include "libGLESv2/renderer/vertexconversion.h" -#include "libGLESv2/renderer/BufferStorage.h" -#include "libGLESv2/Context.h" -#include "libGLESv2/renderer/Renderer9.h" - -#include "libGLESv2/Buffer.h" - -namespace rx -{ - -bool VertexBuffer9::mTranslationsInitialized = false; -VertexBuffer9::FormatConverter VertexBuffer9::mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - -VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) -{ - mVertexBuffer = NULL; - mBufferSize = 0; - mDynamicUsage = false; - - if (!mTranslationsInitialized) - { - initializeTranslations(renderer->getCapsDeclTypes()); - mTranslationsInitialized = true; - } -} - -VertexBuffer9::~VertexBuffer9() -{ - if (mVertexBuffer) - { - mVertexBuffer->Release(); - mVertexBuffer = NULL; - } -} - -bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) -{ - if (mVertexBuffer) - { - mVertexBuffer->Release(); - mVertexBuffer = NULL; - } - - updateSerial(); - - if (size > 0) - { - DWORD flags = D3DUSAGE_WRITEONLY; - if (dynamicUsage) - { - flags |= D3DUSAGE_DYNAMIC; - } - - HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer); - - if (FAILED(result)) - { - ERR("Out of memory allocating a vertex buffer of size %lu.", size); - return false; - } - } - - mBufferSize = size; - mDynamicUsage = dynamicUsage; - return true; -} - -VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) -{ - ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer)); - return static_cast(vertexBuffer); -} - -bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, - GLsizei instances, unsigned int offset) -{ - if (mVertexBuffer) - { - gl::Buffer *buffer = attrib.mBoundBuffer.get(); - - int inputStride = attrib.stride(); - int elementSize = attrib.typeSize(); - const FormatConverter &converter = formatConverter(attrib); - - DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - - void *mapPtr = NULL; - - unsigned int mapSize; - if (!spaceRequired(attrib, count, instances, &mapSize)) - { - return false; - } - - HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); - - if (FAILED(result)) - { - ERR("Lock failed with error 0x%08x", result); - return false; - } - - const char *input = NULL; - if (buffer) - { - BufferStorage *storage = buffer->getStorage(); - input = static_cast(storage->getData()) + static_cast(attrib.mOffset); - } - else - { - input = static_cast(attrib.mPointer); - } - - if (instances == 0 || attrib.mDivisor == 0) - { - input += inputStride * start; - } - - if (converter.identity && inputStride == elementSize) - { - memcpy(mapPtr, input, count * inputStride); - } - else - { - converter.convertArray(input, inputStride, count, mapPtr); - } - - mVertexBuffer->Unlock(); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned int offset) -{ - if (mVertexBuffer) - { - DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; - - void *mapPtr = NULL; - HRESULT result = mVertexBuffer->Lock(offset, size, &mapPtr, lockFlags); - - if (FAILED(result)) - { - ERR("Lock failed with error 0x%08x", result); - return false; - } - - memcpy(mapPtr, data, size); - - mVertexBuffer->Unlock(); - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, - unsigned int *outSpaceRequired) const -{ - return spaceRequired(attrib, count, instances, outSpaceRequired); -} - -bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const -{ - return formatConverter(attrib).identity; -} - -unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const -{ - unsigned int spaceRequired; - return getSpaceRequired(attrib, 1, 0, &spaceRequired) ? spaceRequired : 0; -} - -D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const -{ - return formatConverter(attrib).d3dDeclType; -} - -unsigned int VertexBuffer9::getBufferSize() const -{ - return mBufferSize; -} - -bool VertexBuffer9::setBufferSize(unsigned int size) -{ - if (size > mBufferSize) - { - return initialize(size, mDynamicUsage); - } - else - { - return true; - } -} - -bool VertexBuffer9::discard() -{ - if (mVertexBuffer) - { - void *dummy; - HRESULT result; - - result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); - if (FAILED(result)) - { - ERR("Discard lock failed with error 0x%08x", result); - return false; - } - - result = mVertexBuffer->Unlock(); - if (FAILED(result)) - { - ERR("Discard unlock failed with error 0x%08x", result); - return false; - } - - return true; - } - else - { - ERR("Vertex buffer not initialized."); - return false; - } -} - -IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const -{ - return mVertexBuffer; -} - -// Mapping from OpenGL-ES vertex attrib type to D3D decl type: -// -// BYTE SHORT (Cast) -// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) -// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) -// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) -// SHORT SHORT (Identity) -// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) -// UNSIGNED_SHORT FLOAT (Cast) -// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) -// FIXED (not in WebGL) FLOAT (FixedToFloat) -// FLOAT FLOAT (Identity) - -// GLToCType maps from GL type (as GLenum) to the C typedef. -template struct GLToCType { }; - -template <> struct GLToCType { typedef GLbyte type; }; -template <> struct GLToCType { typedef GLubyte type; }; -template <> struct GLToCType { typedef GLshort type; }; -template <> struct GLToCType { typedef GLushort type; }; -template <> struct GLToCType { typedef GLuint type; }; -template <> struct GLToCType { typedef GLfloat type; }; - -// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) -enum D3DVertexType -{ - D3DVT_FLOAT, - D3DVT_SHORT, - D3DVT_SHORT_NORM, - D3DVT_UBYTE, - D3DVT_UBYTE_NORM, - D3DVT_USHORT_NORM -}; - -// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. -template struct D3DToCType { }; - -template <> struct D3DToCType { typedef float type; }; -template <> struct D3DToCType { typedef short type; }; -template <> struct D3DToCType { typedef short type; }; -template <> struct D3DToCType { typedef unsigned char type; }; -template <> struct D3DToCType { typedef unsigned char type; }; -template <> struct D3DToCType { typedef unsigned short type; }; - -// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size. -template struct WidenRule { }; - -template struct WidenRule : NoWiden { }; -template struct WidenRule : WidenToEven { }; -template struct WidenRule : WidenToEven { }; -template struct WidenRule : WidenToFour { }; -template struct WidenRule : WidenToFour { }; -template struct WidenRule : WidenToEven { }; - -// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination. -template struct VertexTypeFlags { }; - -template -struct VertexTypeFlagsHelper -{ - enum { capflag = _capflag }; - enum { declflag = _declflag }; -}; - -template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; -template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; - - -// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums). -template struct VertexTypeMapping { }; - -template -struct VertexTypeMappingBase -{ - enum { preferred = Preferred }; - enum { fallback = Fallback }; -}; - -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Normalize -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity, Cast -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity, Normalize -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast, Normalize -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast -template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast, Normalize -template struct VertexTypeMapping : VertexTypeMappingBase { }; // FixedToFloat -template struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity - - -// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat). -// The conversion rules themselves are defined in vertexconversion.h. - -// Almost all cases are covered by Cast (including those that are actually Identity since Cast knows it's an identity mapping). -template -struct ConversionRule : Cast::type, typename D3DToCType::type> { }; - -// All conversions from normalized types to float use the Normalize operator. -template struct ConversionRule : Normalize::type> { }; - -// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules. -template <> struct ConversionRule : FixedToFloat { }; -template <> struct ConversionRule : FixedToFloat { }; - -// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1) -// whether it is normalized or not. -template struct DefaultVertexValuesStage2 { }; - -template struct DefaultVertexValuesStage2 : NormalizedDefaultValues { }; -template struct DefaultVertexValuesStage2 : SimpleDefaultValues { }; - -// Work out the default value rule for a D3D type (expressed as the C type) and -template struct DefaultVertexValues : DefaultVertexValuesStage2 { }; -template struct DefaultVertexValues : SimpleDefaultValues { }; - -// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion. -// The fallback conversion produces an output that all D3D9 devices must support. -template struct UsePreferred { enum { type = T::preferred }; }; -template struct UseFallback { enum { type = T::fallback }; }; - -// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion, -// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag -// and the D3DDECLTYPE member needed for the vertex declaration in declflag. -template class PreferenceRule> -struct Converter - : VertexDataConverter::type, - WidenRule >::type, size>, - ConversionRule >::type>, - DefaultVertexValues >::type>::type, normalized > > -{ -private: - enum { d3dtype = PreferenceRule< VertexTypeMapping >::type }; - enum { d3dsize = WidenRule::finalWidth }; - -public: - enum { capflag = VertexTypeFlags::capflag }; - enum { declflag = VertexTypeFlags::declflag }; -}; - -// Initialize a TranslationInfo -#define TRANSLATION(type, norm, size, preferred) \ - { \ - Converter::identity, \ - Converter::finalSize, \ - Converter::convertArray, \ - static_cast(Converter::declflag) \ - } - -#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ - { \ - Converter::capflag, \ - TRANSLATION(type, norm, size, UsePreferred), \ - TRANSLATION(type, norm, size, UseFallback) \ - } - -#define TRANSLATIONS_FOR_TYPE(type) \ - { \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \ - } - -#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ - { \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ - { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ - } - -const VertexBuffer9::TranslationDescription VertexBuffer9::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] -{ - TRANSLATIONS_FOR_TYPE(GL_BYTE), - TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), - TRANSLATIONS_FOR_TYPE(GL_SHORT), - TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), - TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), - TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) -}; - -void VertexBuffer9::initializeTranslations(DWORD declTypes) -{ - for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) - { - for (unsigned int j = 0; j < 2; j++) - { - for (unsigned int k = 0; k < 4; k++) - { - if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) - { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; - } - else - { - mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; - } - } - } - } -} - -unsigned int VertexBuffer9::typeIndex(GLenum type) -{ - switch (type) - { - case GL_BYTE: return 0; - case GL_UNSIGNED_BYTE: return 1; - case GL_SHORT: return 2; - case GL_UNSIGNED_SHORT: return 3; - case GL_FIXED: return 4; - case GL_FLOAT: return 5; - - default: UNREACHABLE(); return 5; - } -} - -const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute) -{ - return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1]; -} - -bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired) -{ - unsigned int elementSize = formatConverter(attrib).outputElementSize; - - if (attrib.mArrayEnabled) - { - unsigned int elementCount = 0; - if (instances == 0 || attrib.mDivisor == 0) - { - elementCount = count; - } - else - { - if (static_cast(instances) < std::numeric_limits::max() - (attrib.mDivisor - 1)) - { - // Round up - elementCount = (static_cast(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; - } - else - { - elementCount = static_cast(instances) / attrib.mDivisor; - } - } - - if (elementSize <= std::numeric_limits::max() / elementCount) - { - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * elementCount; - } - return true; - } - else - { - return false; - } - } - else - { - const unsigned int elementSize = 4; - if (outSpaceRequired) - { - *outSpaceRequired = elementSize * 4; - } - return true; - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h deleted file mode 100644 index 2f88117bda..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexBuffer9.h +++ /dev/null @@ -1,91 +0,0 @@ -// -// Copyright (c) 2002-2012 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. -// - -// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation. - -#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ -#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ - -#include "libGLESv2/renderer/VertexBuffer.h" - -namespace rx -{ -class Renderer9; - -class VertexBuffer9 : public VertexBuffer -{ - public: - explicit VertexBuffer9(rx::Renderer9 *const renderer); - virtual ~VertexBuffer9(); - - virtual bool initialize(unsigned int size, bool dynamicUsage); - - static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer); - - virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, - unsigned int offset); - virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); - - virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; - - virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; - - unsigned int getVertexSize(const gl::VertexAttribute &attrib) const; - D3DDECLTYPE getDeclType(const gl::VertexAttribute &attrib) const; - - virtual unsigned int getBufferSize() const; - virtual bool setBufferSize(unsigned int size); - virtual bool discard(); - - IDirect3DVertexBuffer9 *getBuffer() const; - - private: - DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); - - rx::Renderer9 *const mRenderer; - - IDirect3DVertexBuffer9 *mVertexBuffer; - unsigned int mBufferSize; - bool mDynamicUsage; - - // Attribute format conversion - enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; - - struct FormatConverter - { - bool identity; - std::size_t outputElementSize; - void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); - D3DDECLTYPE d3dDeclType; - }; - - static bool mTranslationsInitialized; - static void initializeTranslations(DWORD declTypes); - - // [GL types as enumerated by typeIndex()][normalized][size - 1] - static FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - - struct TranslationDescription - { - DWORD capsFlag; - FormatConverter preferredConversion; - FormatConverter fallbackConversion; - }; - - // This table is used to generate mFormatConverters. - // [GL types as enumerated by typeIndex()][normalized][size - 1] - static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; - - static unsigned int typeIndex(GLenum type); - static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); - - static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, - unsigned int *outSpaceRequired); -}; - -} - -#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp index 7ff5171fca..8034aed8c9 100644 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp +++ b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDataManager.cpp @@ -266,6 +266,10 @@ GLenum VertexDataManager::prepareVertexData(const gl::VertexAttribute attribs[], return GL_OUT_OF_MEMORY; } + mCurrentValue[i][0] = attribs[i].mCurrentValue[0]; + mCurrentValue[i][1] = attribs[i].mCurrentValue[1]; + mCurrentValue[i][2] = attribs[i].mCurrentValue[2]; + mCurrentValue[i][3] = attribs[i].mCurrentValue[3]; mCurrentValueOffsets[i] = streamOffset; } diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp deleted file mode 100644 index 9b83a6476e..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.cpp +++ /dev/null @@ -1,217 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. - -#include "libGLESv2/ProgramBinary.h" -#include "libGLESv2/Context.h" -#include "libGLESv2/renderer/VertexBuffer9.h" -#include "libGLESv2/renderer/VertexDeclarationCache.h" - -namespace rx -{ - -VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) -{ - for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) - { - mVertexDeclCache[i].vertexDeclaration = NULL; - mVertexDeclCache[i].lruCount = 0; - } - - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mAppliedVBs[i].serial = 0; - } - - mLastSetVDecl = NULL; - mInstancingEnabled = true; -} - -VertexDeclarationCache::~VertexDeclarationCache() -{ - for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) - { - if (mVertexDeclCache[i].vertexDeclaration) - { - mVertexDeclCache[i].vertexDeclaration->Release(); - } - } -} - -GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) -{ - *repeatDraw = 1; - - int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; - int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; - - if (instances > 0) - { - // Find an indexed attribute to be mapped to D3D stream 0 - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - if (attributes[i].active) - { - if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0) - { - indexedAttribute = i; - } - else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0) - { - instancedAttribute = i; - } - if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS) - break; // Found both an indexed and instanced attribute - } - } - - if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS) - { - return GL_INVALID_OPERATION; - } - } - - D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; - D3DVERTEXELEMENT9 *element = &elements[0]; - - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - if (attributes[i].active) - { - // Directly binding the storage buffer is not supported for d3d9 - ASSERT(attributes[i].storage == NULL); - - int stream = i; - - if (instances > 0) - { - // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced. - if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS) - { - *repeatDraw = instances; - } - else - { - if (i == indexedAttribute) - { - stream = 0; - } - else if (i == 0) - { - stream = indexedAttribute; - } - - UINT frequency = 1; - - if (attributes[i].divisor == 0) - { - frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances; - } - else - { - frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor; - } - - device->SetStreamSourceFreq(stream, frequency); - mInstancingEnabled = true; - } - } - - VertexBuffer9 *vertexBuffer = VertexBuffer9::makeVertexBuffer9(attributes[i].vertexBuffer); - - if (mAppliedVBs[stream].serial != attributes[i].serial || - mAppliedVBs[stream].stride != attributes[i].stride || - mAppliedVBs[stream].offset != attributes[i].offset) - { - device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride); - mAppliedVBs[stream].serial = attributes[i].serial; - mAppliedVBs[stream].stride = attributes[i].stride; - mAppliedVBs[stream].offset = attributes[i].offset; - } - - element->Stream = stream; - element->Offset = 0; - element->Type = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDeclType(*attributes[i].attribute) : D3DDECLTYPE_FLOAT4; - element->Method = D3DDECLMETHOD_DEFAULT; - element->Usage = D3DDECLUSAGE_TEXCOORD; - element->UsageIndex = programBinary->getSemanticIndex(i); - element++; - } - } - - if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS) - { - if (mInstancingEnabled) - { - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - device->SetStreamSourceFreq(i, 1); - } - - mInstancingEnabled = false; - } - } - - static const D3DVERTEXELEMENT9 end = D3DDECL_END(); - *(element++) = end; - - for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) - { - VertexDeclCacheEntry *entry = &mVertexDeclCache[i]; - if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration) - { - entry->lruCount = ++mMaxLru; - if(entry->vertexDeclaration != mLastSetVDecl) - { - device->SetVertexDeclaration(entry->vertexDeclaration); - mLastSetVDecl = entry->vertexDeclaration; - } - - return GL_NO_ERROR; - } - } - - VertexDeclCacheEntry *lastCache = mVertexDeclCache; - - for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) - { - if (mVertexDeclCache[i].lruCount < lastCache->lruCount) - { - lastCache = &mVertexDeclCache[i]; - } - } - - if (lastCache->vertexDeclaration != NULL) - { - lastCache->vertexDeclaration->Release(); - lastCache->vertexDeclaration = NULL; - // mLastSetVDecl is set to the replacement, so we don't have to worry - // about it. - } - - memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); - device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); - device->SetVertexDeclaration(lastCache->vertexDeclaration); - mLastSetVDecl = lastCache->vertexDeclaration; - lastCache->lruCount = ++mMaxLru; - - return GL_NO_ERROR; -} - -void VertexDeclarationCache::markStateDirty() -{ - for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) - { - mAppliedVBs[i].serial = 0; - } - - mLastSetVDecl = NULL; - mInstancingEnabled = true; // Forces it to be disabled when not used -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h deleted file mode 100644 index 3fc024a9ba..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/VertexDeclarationCache.h +++ /dev/null @@ -1,58 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations. - -#ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ -#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ - -#include "libGLESv2/renderer/VertexDataManager.h" - -namespace gl -{ -class VertexDataManager; -} - -namespace rx -{ - -class VertexDeclarationCache -{ - public: - VertexDeclarationCache(); - ~VertexDeclarationCache(); - - GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw); - - void markStateDirty(); - - private: - UINT mMaxLru; - - enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 }; - - struct VBData - { - unsigned int serial; - unsigned int stride; - unsigned int offset; - }; - - VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS]; - IDirect3DVertexDeclaration9 *mLastSetVDecl; - bool mInstancingEnabled; - - struct VertexDeclCacheEntry - { - D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1]; - UINT lruCount; - IDirect3DVertexDeclaration9 *vertexDeclaration; - } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES]; -}; - -} - -#endif // LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp new file mode 100644 index 0000000000..31d5b8b886 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.cpp @@ -0,0 +1,366 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// BufferStorage11.cpp Defines the BufferStorage11 class. + +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" + +namespace rx +{ + +BufferStorage11::BufferStorage11(Renderer11 *renderer) +{ + mRenderer = renderer; + + mStagingBuffer = NULL; + mStagingBufferSize = 0; + + mSize = 0; + + mResolvedData = NULL; + mResolvedDataSize = 0; + mResolvedDataValid = false; + + mReadUsageCount = 0; + mWriteUsageCount = 0; +} + +BufferStorage11::~BufferStorage11() +{ + SafeRelease(mStagingBuffer); + + if (mResolvedData) + { + free(mResolvedData); + mResolvedData = NULL; + } + + for (auto it = mDirectBuffers.begin(); it != mDirectBuffers.end(); it++) + { + SafeDelete(it->second); + } +} + +BufferStorage11 *BufferStorage11::makeBufferStorage11(BufferStorage *bufferStorage) +{ + ASSERT(HAS_DYNAMIC_TYPE(BufferStorage11*, bufferStorage)); + return static_cast(bufferStorage); +} + +void *BufferStorage11::getData() +{ + ASSERT(mStagingBuffer); + + if (!mResolvedDataValid) + { + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + HRESULT result; + + if (!mResolvedData || mResolvedDataSize < mStagingBufferSize) + { + free(mResolvedData); + mResolvedData = malloc(mSize); + mResolvedDataSize = mSize; + } + + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = context->Map(mStagingBuffer, 0, D3D11_MAP_READ, 0, &mappedResource); + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY, (void*)NULL); + } + + memcpy(mResolvedData, mappedResource.pData, mSize); + + context->Unmap(mStagingBuffer, 0); + + mResolvedDataValid = true; + } + + mReadUsageCount = 0; + + return mResolvedData; +} + +void BufferStorage11::setData(const void* data, unsigned int size, unsigned int offset) +{ + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + HRESULT result; + + const unsigned int requiredStagingBufferSize = size + offset; + const bool createStagingBuffer = !mStagingBuffer || mStagingBufferSize < requiredStagingBufferSize; + + if (createStagingBuffer) + { + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = requiredStagingBufferSize; + bufferDesc.Usage = D3D11_USAGE_STAGING; + bufferDesc.BindFlags = 0; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + HRESULT result; + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + ID3D11Buffer *newStagingBuffer; + + if (data && offset == 0) + { + D3D11_SUBRESOURCE_DATA initialData; + initialData.pSysMem = data; + initialData.SysMemPitch = requiredStagingBufferSize; + initialData.SysMemSlicePitch = 0; + + result = device->CreateBuffer(&bufferDesc, &initialData, &newStagingBuffer); + } + else + { + result = device->CreateBuffer(&bufferDesc, NULL, &newStagingBuffer); + } + + if (FAILED(result)) + { + mStagingBufferSize = 0; + return gl::error(GL_OUT_OF_MEMORY); + } + + mStagingBufferSize = requiredStagingBufferSize; + + if (mStagingBuffer && offset > 0) + { + // If offset is greater than zero and the buffer is non-null, need to preserve the data from + // the old buffer up to offset + D3D11_BOX srcBox; + srcBox.left = 0; + srcBox.right = std::min(offset, requiredStagingBufferSize); + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + context->CopySubresourceRegion(newStagingBuffer, 0, 0, 0, 0, mStagingBuffer, 0, &srcBox); + } + + SafeRelease(mStagingBuffer); + mStagingBuffer = newStagingBuffer; + } + + if (data && (offset != 0 || !createStagingBuffer)) + { + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = context->Map(mStagingBuffer, 0, D3D11_MAP_WRITE, 0, &mappedResource); + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY); + } + + unsigned char *offsetBufferPointer = reinterpret_cast(mappedResource.pData) + offset; + memcpy(offsetBufferPointer, data, size); + + context->Unmap(mStagingBuffer, 0); + } + + for (auto it = mDirectBuffers.begin(); it != mDirectBuffers.end(); it++) + { + it->second->markDirty(); + } + + mSize = std::max(mSize, requiredStagingBufferSize); + mWriteUsageCount = 0; + + mResolvedDataValid = false; +} + +void BufferStorage11::copyData(BufferStorage* sourceStorage, unsigned int size, + unsigned int sourceOffset, unsigned int destOffset) +{ + BufferStorage11* source = makeBufferStorage11(sourceStorage); + if (source) + { + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + D3D11_BOX srcBox; + srcBox.left = sourceOffset; + srcBox.right = sourceOffset + size; + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + ASSERT(mStagingBuffer && source->mStagingBuffer); + context->CopySubresourceRegion(mStagingBuffer, 0, destOffset, 0, 0, source->mStagingBuffer, 0, &srcBox); + } +} + +void BufferStorage11::clear() +{ + mResolvedDataValid = false; + mSize = 0; +} + +unsigned int BufferStorage11::getSize() const +{ + return mSize; +} + +bool BufferStorage11::supportsDirectBinding() const +{ + return true; +} + +void BufferStorage11::markBufferUsage() +{ + mReadUsageCount++; + mWriteUsageCount++; + + const unsigned int usageLimit = 5; + + if (mReadUsageCount > usageLimit && mResolvedData) + { + free(mResolvedData); + mResolvedData = NULL; + mResolvedDataSize = 0; + mResolvedDataValid = false; + } +} + +ID3D11Buffer *BufferStorage11::getBuffer(BufferUsage usage) +{ + markBufferUsage(); + + DirectBufferStorage11 *directBuffer = NULL; + + auto directBufferIt = mDirectBuffers.find(usage); + if (directBufferIt != mDirectBuffers.end()) + { + directBuffer = directBufferIt->second; + } + + if (directBuffer) + { + if (directBuffer->isDirty()) + { + // if updateFromStagingBuffer returns true, the D3D buffer has been recreated + // and we should update our serial + if (directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0)) + { + updateSerial(); + } + } + } + else + { + // buffer is not allocated, create it + directBuffer = new DirectBufferStorage11(mRenderer, usage); + directBuffer->updateFromStagingBuffer(mStagingBuffer, mSize, 0); + + mDirectBuffers.insert(std::make_pair(usage, directBuffer)); + updateSerial(); + } + + return directBuffer->getD3DBuffer(); +} + +DirectBufferStorage11::DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage) + : mRenderer(renderer), + mUsage(usage), + mDirectBuffer(NULL), + mBufferSize(0), + mDirty(false) +{ +} + +DirectBufferStorage11::~DirectBufferStorage11() +{ + SafeRelease(mDirectBuffer); +} + +BufferUsage DirectBufferStorage11::getUsage() const +{ + return mUsage; +} + +// Returns true if it recreates the direct buffer +bool DirectBufferStorage11::updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset) +{ + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + // unused for now + ASSERT(offset == 0); + + unsigned int requiredBufferSize = size + offset; + bool createBuffer = !mDirectBuffer || mBufferSize < requiredBufferSize; + + // (Re)initialize D3D buffer if needed + if (createBuffer) + { + D3D11_BUFFER_DESC bufferDesc; + fillBufferDesc(&bufferDesc, mRenderer, mUsage, requiredBufferSize); + + ID3D11Buffer *newBuffer; + HRESULT result = device->CreateBuffer(&bufferDesc, NULL, &newBuffer); + + if (FAILED(result)) + { + return gl::error(GL_OUT_OF_MEMORY, false); + } + + // No longer need the old buffer + SafeRelease(mDirectBuffer); + mDirectBuffer = newBuffer; + + mBufferSize = bufferDesc.ByteWidth; + } + + // Copy data via staging buffer + D3D11_BOX srcBox; + srcBox.left = 0; + srcBox.right = size; + srcBox.top = 0; + srcBox.bottom = 1; + srcBox.front = 0; + srcBox.back = 1; + + context->CopySubresourceRegion(mDirectBuffer, 0, offset, 0, 0, stagingBuffer, 0, &srcBox); + + mDirty = false; + + return createBuffer; +} + +void DirectBufferStorage11::fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize) +{ + bufferDesc->ByteWidth = bufferSize; + bufferDesc->MiscFlags = 0; + bufferDesc->StructureByteStride = 0; + + switch (usage) + { + case BUFFER_USAGE_VERTEX: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc->CPUAccessFlags = 0; + break; + + case BUFFER_USAGE_INDEX: + bufferDesc->Usage = D3D11_USAGE_DEFAULT; + bufferDesc->BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc->CPUAccessFlags = 0; + break; + + default: + UNREACHABLE(); + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h new file mode 100644 index 0000000000..a6afafe1b4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/BufferStorage11.h @@ -0,0 +1,92 @@ +// +// Copyright (c) 2013 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. +// + +// BufferStorage11.h Defines the BufferStorage11 class. + +#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ +#define LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ + +#include "libGLESv2/renderer/BufferStorage.h" + +namespace rx +{ +class Renderer; +class Renderer11; +class DirectBufferStorage11; + +enum BufferUsage +{ + BUFFER_USAGE_VERTEX, + BUFFER_USAGE_INDEX, +}; + +class BufferStorage11 : public BufferStorage +{ + public: + explicit BufferStorage11(Renderer11 *renderer); + virtual ~BufferStorage11(); + + static BufferStorage11 *makeBufferStorage11(BufferStorage *bufferStorage); + + virtual void *getData(); + virtual void setData(const void* data, unsigned int size, unsigned int offset); + virtual void copyData(BufferStorage* sourceStorage, unsigned int size, + unsigned int sourceOffset, unsigned int destOffset); + virtual void clear(); + virtual unsigned int getSize() const; + virtual bool supportsDirectBinding() const; + + ID3D11Buffer *getBuffer(BufferUsage usage); + + private: + Renderer11 *mRenderer; + + ID3D11Buffer *mStagingBuffer; + unsigned int mStagingBufferSize; + + std::map mDirectBuffers; + + unsigned int mSize; + + void *mResolvedData; + unsigned int mResolvedDataSize; + bool mResolvedDataValid; + + unsigned int mReadUsageCount; + unsigned int mWriteUsageCount; + + void markBufferUsage(); +}; + +// Each instance of BufferStorageD3DBuffer11 is specialized for a class of D3D binding points +// - vertex buffers +// - index buffers +class DirectBufferStorage11 +{ + public: + DirectBufferStorage11(Renderer11 *renderer, BufferUsage usage); + ~DirectBufferStorage11(); + + BufferUsage getUsage() const; + bool updateFromStagingBuffer(ID3D11Buffer *stagingBuffer, size_t size, size_t offset); + + ID3D11Buffer *getD3DBuffer() { return mDirectBuffer; } + bool isDirty() const { return mDirty; } + void markDirty() { mDirty = true; } + + private: + Renderer11 *mRenderer; + const BufferUsage mUsage; + ID3D11Buffer *mDirectBuffer; + size_t mBufferSize; + bool mDirty; + + static void fillBufferDesc(D3D11_BUFFER_DESC* bufferDesc, Renderer *renderer, BufferUsage usage, unsigned int bufferSize); +}; + +} + +#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp new file mode 100644 index 0000000000..2a7d4d43ef --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.cpp @@ -0,0 +1,134 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Fence11.cpp: Defines the rx::Fence11 class which implements rx::FenceImpl. + +#include "libGLESv2/renderer/d3d11/Fence11.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" + +namespace rx +{ + +Fence11::Fence11(rx::Renderer11 *renderer) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Fence11::~Fence11() +{ + if (mQuery) + { + mQuery->Release(); + mQuery = NULL; + } +} + +GLboolean Fence11::isFence() +{ + // GL_NV_fence spec: + // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. + return mQuery != NULL; +} + +void Fence11::setFence(GLenum condition) +{ + if (!mQuery) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.MiscFlags = 0; + + if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + mRenderer->getDeviceContext()->End(mQuery); + + setCondition(condition); + setStatus(GL_FALSE); +} + +GLboolean Fence11::testFence() +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION, GL_TRUE); + } + + HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, 0); + + if (mRenderer->isDeviceLost()) + { + return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + } + + ASSERT(result == S_OK || result == S_FALSE); + setStatus(result == S_OK); + return getStatus(); +} + +void Fence11::finishFence() +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + while (!testFence()) + { + Sleep(0); + } +} + +void Fence11::getFenceiv(GLenum pname, GLint *params) +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (pname) + { + case GL_FENCE_STATUS_NV: + { + // GL_NV_fence spec: + // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV + // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + if (getStatus()) + { + params[0] = GL_TRUE; + return; + } + + HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); + + if (mRenderer->isDeviceLost()) + { + params[0] = GL_TRUE; + return gl::error(GL_OUT_OF_MEMORY); + } + + ASSERT(result == S_OK || result == S_FALSE); + setStatus(result == S_OK); + params[0] = getStatus(); + + break; + } + case GL_FENCE_CONDITION_NV: + params[0] = getCondition(); + break; + default: + return gl::error(GL_INVALID_ENUM); + break; + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.h new file mode 100644 index 0000000000..a5398bca14 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Fence11.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2013 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. +// + +// Fence11.h: Defines the rx::Fence11 class which implements rx::FenceImpl. + +#ifndef LIBGLESV2_RENDERER_Fence11_H_ +#define LIBGLESV2_RENDERER_Fence11_H_ + +#include "libGLESv2/renderer/FenceImpl.h" + +namespace rx +{ +class Renderer11; + +class Fence11 : public FenceImpl +{ + public: + explicit Fence11(rx::Renderer11 *renderer); + virtual ~Fence11(); + + GLboolean isFence(); + void setFence(GLenum condition); + GLboolean testFence(); + void finishFence(); + void getFenceiv(GLenum pname, GLint *params); + + private: + DISALLOW_COPY_AND_ASSIGN(Fence11); + + rx::Renderer11 *mRenderer; + ID3D11Query *mQuery; +}; + +} + +#endif // LIBGLESV2_RENDERER_FENCE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.cpp new file mode 100644 index 0000000000..5d039a35e8 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.cpp @@ -0,0 +1,498 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// Image11.h: Implements the rx::Image11 class, which acts as the interface to +// the actual underlying resources of a Texture + +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" + +#include "libGLESv2/main.h" +#include "libGLESv2/utilities.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/generatemip.h" + +namespace rx +{ + +Image11::Image11() +{ + mStagingTexture = NULL; + mRenderer = NULL; + mDXGIFormat = DXGI_FORMAT_UNKNOWN; +} + +Image11::~Image11() +{ + if (mStagingTexture) + { + mStagingTexture->Release(); + } +} + +Image11 *Image11::makeImage11(Image *img) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::Image11*, img)); + return static_cast(img); +} + +void Image11::generateMipmap(Image11 *dest, Image11 *src) +{ + ASSERT(src->getDXGIFormat() == dest->getDXGIFormat()); + ASSERT(src->getWidth() == 1 || src->getWidth() / 2 == dest->getWidth()); + ASSERT(src->getHeight() == 1 || src->getHeight() / 2 == dest->getHeight()); + + D3D11_MAPPED_SUBRESOURCE destMapped, srcMapped; + dest->map(D3D11_MAP_WRITE, &destMapped); + src->map(D3D11_MAP_READ, &srcMapped); + + const unsigned char *sourceData = reinterpret_cast(srcMapped.pData); + unsigned char *destData = reinterpret_cast(destMapped.pData); + + if (sourceData && destData) + { + switch (src->getDXGIFormat()) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_A8_UNORM: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R8_UNORM: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R32G32B32_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R8G8_UNORM: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R16_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R16G16_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R32_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + case DXGI_FORMAT_R32G32_FLOAT: + GenerateMip(src->getWidth(), src->getHeight(), sourceData, srcMapped.RowPitch, destData, destMapped.RowPitch); + break; + default: + UNREACHABLE(); + break; + } + + dest->unmap(); + src->unmap(); + } + + dest->markDirty(); +} + +static bool FormatRequiresInitialization(DXGI_FORMAT dxgiFormat, GLenum internalFormat) +{ + return (dxgiFormat == DXGI_FORMAT_R8G8B8A8_UNORM && gl::GetAlphaSize(internalFormat) == 0) || + (dxgiFormat == DXGI_FORMAT_R32G32B32A32_FLOAT && gl::GetAlphaSize(internalFormat) == 0); +} + +bool Image11::isDirty() const +{ + return ((mStagingTexture || FormatRequiresInitialization(mDXGIFormat, mInternalFormat)) && mDirty); +} + +bool Image11::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); + return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, 0, xoffset, yoffset, width, height); +} + +bool Image11::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); + return storage11->updateSubresourceLevel(getStagingTexture(), getStagingSubresource(), level, face, xoffset, yoffset, width, height); +} + +bool Image11::redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) +{ + if (mWidth != width || + mHeight != height || + mInternalFormat != internalformat || + forceRelease) + { + mRenderer = Renderer11::makeRenderer11(renderer); + + mWidth = width; + mHeight = height; + mInternalFormat = internalformat; + // compute the d3d format that will be used + mDXGIFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel()); + mActualFormat = d3d11_gl::ConvertTextureInternalFormat(mDXGIFormat); + + if (mStagingTexture) + { + mStagingTexture->Release(); + mStagingTexture = NULL; + } + + return true; + } + + return false; +} + +bool Image11::isRenderableFormat() const +{ + return TextureStorage11::IsTextureFormatRenderable(mDXGIFormat); +} + +DXGI_FORMAT Image11::getDXGIFormat() const +{ + // this should only happen if the image hasn't been redefined first + // which would be a bug by the caller + ASSERT(mDXGIFormat != DXGI_FORMAT_UNKNOWN); + + return mDXGIFormat; +} + +// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input +// into the target pixel rectangle. +void Image11::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLint unpackAlignment, const void *input) +{ + D3D11_MAPPED_SUBRESOURCE mappedImage; + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + if (FAILED(result)) + { + ERR("Could not map image for loading."); + return; + } + + GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); + size_t pixelSize = d3d11::ComputePixelSizeBits(mDXGIFormat) / 8; + void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + (yoffset * mappedImage.RowPitch + xoffset * pixelSize)); + + switch (mInternalFormat) + { + case GL_ALPHA8_EXT: + if (mRenderer->getFeatureLevel() >= D3D_FEATURE_LEVEL_10_0) + loadAlphaDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + else + loadAlphaDataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_LUMINANCE8_EXT: + loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); + break; + case GL_ALPHA32F_EXT: + loadAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_LUMINANCE32F_EXT: + loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_ALPHA16F_EXT: + loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_LUMINANCE16F_EXT: + loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_LUMINANCE8_ALPHA8_EXT: + loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData, false); + break; + case GL_LUMINANCE_ALPHA32F_EXT: + loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_LUMINANCE_ALPHA16F_EXT: + loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGB8_OES: + loadRGBUByteDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGB565: + loadRGB565DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGBA8_OES: + loadRGBAUByteDataToNative(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGBA4: + loadRGBA4444DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGB5_A1: + loadRGBA5551DataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_BGRA8_EXT: + loadBGRADataToBGRA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGB32F_EXT: + loadRGBFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGB16F_EXT: + loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGBA32F_EXT: + loadRGBAFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + case GL_RGBA16F_EXT: + loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, mappedImage.RowPitch, offsetMappedData); + break; + default: UNREACHABLE(); + } + + unmap(); +} + +void Image11::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + const void *input) +{ + ASSERT(xoffset % 4 == 0); + ASSERT(yoffset % 4 == 0); + + D3D11_MAPPED_SUBRESOURCE mappedImage; + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + if (FAILED(result)) + { + ERR("Could not map image for loading."); + return; + } + + // Size computation assumes a 4x4 block compressed texture format + size_t blockSize = d3d11::ComputeBlockSizeBits(mDXGIFormat) / 8; + void* offsetMappedData = (void*)((BYTE *)mappedImage.pData + ((yoffset / 4) * mappedImage.RowPitch + (xoffset / 4) * blockSize)); + + GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); + GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); + int rows = inputSize / inputPitch; + for (int i = 0; i < rows; ++i) + { + memcpy((void*)((BYTE*)offsetMappedData + i * mappedImage.RowPitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); + } + + unmap(); +} + +void Image11::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +{ + gl::Renderbuffer *colorbuffer = source->getReadColorbuffer(); + + if (colorbuffer && colorbuffer->getActualFormat() == (GLuint)mActualFormat) + { + // No conversion needed-- use copyback fastpath + ID3D11Texture2D *colorBufferTexture = NULL; + unsigned int subresourceIndex = 0; + + if (mRenderer->getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + { + D3D11_TEXTURE2D_DESC textureDesc; + colorBufferTexture->GetDesc(&textureDesc); + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + ID3D11Texture2D* srcTex = NULL; + if (textureDesc.SampleDesc.Count > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = textureDesc.Width; + resolveDesc.Height = textureDesc.Height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureDesc.Format; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&resolveDesc, NULL, &srcTex); + if (FAILED(result)) + { + ERR("Failed to create resolve texture for Image11::copy, HRESULT: 0x%X.", result); + return; + } + + deviceContext->ResolveSubresource(srcTex, 0, colorBufferTexture, subresourceIndex, textureDesc.Format); + subresourceIndex = 0; + } + else + { + srcTex = colorBufferTexture; + srcTex->AddRef(); + } + + D3D11_BOX srcBox; + srcBox.left = x; + srcBox.right = x + width; + srcBox.top = y; + srcBox.bottom = y + height; + srcBox.front = 0; + srcBox.back = 1; + + deviceContext->CopySubresourceRegion(mStagingTexture, 0, xoffset, yoffset, 0, srcTex, subresourceIndex, &srcBox); + + srcTex->Release(); + colorBufferTexture->Release(); + } + } + else + { + // This format requires conversion, so we must copy the texture to staging and manually convert via readPixels + D3D11_MAPPED_SUBRESOURCE mappedImage; + HRESULT result = map(D3D11_MAP_WRITE, &mappedImage); + + // determine the offset coordinate into the destination buffer + GLsizei rowOffset = gl::ComputePixelSize(mActualFormat) * xoffset; + void *dataOffset = static_cast(mappedImage.pData) + mappedImage.RowPitch * yoffset + rowOffset; + + mRenderer->readPixels(source, x, y, width, height, gl::ExtractFormat(mInternalFormat), + gl::ExtractType(mInternalFormat), mappedImage.RowPitch, false, 4, dataOffset); + + unmap(); + } +} + +ID3D11Texture2D *Image11::getStagingTexture() +{ + createStagingTexture(); + + return mStagingTexture; +} + +unsigned int Image11::getStagingSubresource() +{ + createStagingTexture(); + + return mStagingSubresource; +} + +template +static void setDefaultData(ID3D11DeviceContext *deviceContext, ID3D11Texture2D *texture, UINT subresource, + GLsizei width, GLsizei height, const T (&defaultData)[N]) +{ + D3D11_MAPPED_SUBRESOURCE map; + deviceContext->Map(texture, subresource, D3D11_MAP_WRITE, 0, &map); + + unsigned char* ptr = reinterpret_cast(map.pData); + size_t pixelSize = sizeof(T) * N; + + for (GLsizei y = 0; y < height; y++) + { + for (GLsizei x = 0; x < width; x++) + { + memcpy(ptr + (y * map.RowPitch) + (x * pixelSize), defaultData, pixelSize); + } + } + + deviceContext->Unmap(texture, subresource); +} + +void Image11::createStagingTexture() +{ + if (mStagingTexture) + { + return; + } + + ID3D11Texture2D *newTexture = NULL; + int lodOffset = 1; + const DXGI_FORMAT dxgiFormat = getDXGIFormat(); + ASSERT(!d3d11::IsDepthStencilFormat(dxgiFormat)); // We should never get here for depth textures + + if (mWidth != 0 && mHeight != 0) + { + GLsizei width = mWidth; + GLsizei height = mHeight; + + // adjust size if needed for compressed textures + gl::MakeValidSize(false, d3d11::IsCompressed(dxgiFormat), &width, &height, &lodOffset); + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = lodOffset + 1; + desc.ArraySize = 1; + desc.Format = dxgiFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ | D3D11_CPU_ACCESS_WRITE; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &newTexture); + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + mStagingTexture = newTexture; + mStagingSubresource = D3D11CalcSubresource(lodOffset, 0, lodOffset + 1); + mDirty = false; + + if (mDXGIFormat == DXGI_FORMAT_R8G8B8A8_UNORM && gl::GetAlphaSize(mInternalFormat) == 0) + { + unsigned char defaultPixel[4] = { 0, 0, 0, 255 }; + setDefaultData(mRenderer->getDeviceContext(), mStagingTexture, mStagingSubresource, mWidth, mHeight, defaultPixel); + } + else if (mDXGIFormat == DXGI_FORMAT_R32G32B32A32_FLOAT && gl::GetAlphaSize(mInternalFormat) == 0) + { + float defaultPixel[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + setDefaultData(mRenderer->getDeviceContext(), mStagingTexture, mStagingSubresource, mWidth, mHeight, defaultPixel); + } +} + +HRESULT Image11::map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map) +{ + createStagingTexture(); + + HRESULT result = E_FAIL; + + if (mStagingTexture) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + result = deviceContext->Map(mStagingTexture, mStagingSubresource, mapType, 0, map); + + // this can fail if the device is removed (from TDR) + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + } + else if (SUCCEEDED(result)) + { + mDirty = true; + } + } + + return result; +} + +void Image11::unmap() +{ + if (mStagingTexture) + { + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + deviceContext->Unmap(mStagingTexture, mStagingSubresource); + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.h new file mode 100644 index 0000000000..11a6492dc8 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Image11.h @@ -0,0 +1,76 @@ +// +// Copyright (c) 2012 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. +// + +// Image11.h: Defines the rx::Image11 class, which acts as the interface to +// the actual underlying resources of a Texture + +#ifndef LIBGLESV2_RENDERER_IMAGE11_H_ +#define LIBGLESV2_RENDERER_IMAGE11_H_ + +#include "libGLESv2/renderer/Image.h" + +#include "common/debug.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ +class Renderer; +class Renderer11; +class TextureStorageInterface2D; +class TextureStorageInterfaceCube; + +class Image11 : public Image +{ + public: + Image11(); + virtual ~Image11(); + + static Image11 *makeImage11(Image *img); + + static void generateMipmap(Image11 *dest, Image11 *src); + + virtual bool isDirty() const; + + virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + + virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease); + + virtual bool isRenderableFormat() const; + DXGI_FORMAT getDXGIFormat() const; + + virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLint unpackAlignment, const void *input); + virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + const void *input); + + virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + + protected: + HRESULT map(D3D11_MAP mapType, D3D11_MAPPED_SUBRESOURCE *map); + void unmap(); + + private: + DISALLOW_COPY_AND_ASSIGN(Image11); + + ID3D11Texture2D *getStagingTexture(); + unsigned int getStagingSubresource(); + void createStagingTexture(); + + Renderer11 *mRenderer; + + DXGI_FORMAT mDXGIFormat; + ID3D11Texture2D *mStagingTexture; + unsigned int mStagingSubresource; +}; + +} + +#endif // LIBGLESV2_RENDERER_IMAGE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp new file mode 100644 index 0000000000..44f9976d43 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.cpp @@ -0,0 +1,183 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// IndexBuffer11.cpp: Defines the D3D11 IndexBuffer implementation. + +#include "libGLESv2/renderer/d3d11/IndexBuffer11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" + +namespace rx +{ + +IndexBuffer11::IndexBuffer11(Renderer11 *const renderer) : mRenderer(renderer) +{ + mBuffer = NULL; + mBufferSize = 0; + mDynamicUsage = false; +} + +IndexBuffer11::~IndexBuffer11() +{ + if (mBuffer) + { + mBuffer->Release(); + mBuffer = NULL; + } +} + +bool IndexBuffer11::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) +{ + if (mBuffer) + { + mBuffer->Release(); + mBuffer = NULL; + } + + updateSerial(); + + if (bufferSize > 0) + { + ID3D11Device* dxDevice = mRenderer->getDevice(); + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = bufferSize; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_INDEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); + if (FAILED(result)) + { + return false; + } + } + + mBufferSize = bufferSize; + mIndexType = indexType; + mDynamicUsage = dynamic; + + return true; +} + +IndexBuffer11 *IndexBuffer11::makeIndexBuffer11(IndexBuffer *indexBuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer11*, indexBuffer)); + return static_cast(indexBuffer); +} + +bool IndexBuffer11::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) +{ + if (mBuffer) + { + // Check for integer overflows and out-out-bounds map requests + if (offset + size < offset || offset + size > mBufferSize) + { + ERR("Index buffer map range is not inside the buffer."); + return false; + } + + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Index buffer map failed with error 0x%08x", result); + return false; + } + + *outMappedMemory = reinterpret_cast(mappedResource.pData) + offset; + return true; + } + else + { + ERR("Index buffer not initialized."); + return false; + } +} + +bool IndexBuffer11::unmapBuffer() +{ + if (mBuffer) + { + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + dxContext->Unmap(mBuffer, 0); + return true; + } + else + { + ERR("Index buffer not initialized."); + return false; + } +} + +GLenum IndexBuffer11::getIndexType() const +{ + return mIndexType; +} + +unsigned int IndexBuffer11::getBufferSize() const +{ + return mBufferSize; +} + +bool IndexBuffer11::setSize(unsigned int bufferSize, GLenum indexType) +{ + if (bufferSize > mBufferSize || indexType != mIndexType) + { + return initialize(bufferSize, indexType, mDynamicUsage); + } + else + { + return true; + } +} + +bool IndexBuffer11::discard() +{ + if (mBuffer) + { + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Index buffer map failed with error 0x%08x", result); + return false; + } + + dxContext->Unmap(mBuffer, 0); + + return true; + } + else + { + ERR("Index buffer not initialized."); + return false; + } +} + +DXGI_FORMAT IndexBuffer11::getIndexFormat() const +{ + switch (mIndexType) + { + case GL_UNSIGNED_BYTE: return DXGI_FORMAT_R16_UINT; + case GL_UNSIGNED_SHORT: return DXGI_FORMAT_R16_UINT; + case GL_UNSIGNED_INT: return DXGI_FORMAT_R32_UINT; + default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; + } +} + +ID3D11Buffer *IndexBuffer11::getBuffer() const +{ + return mBuffer; +} + +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.h new file mode 100644 index 0000000000..39a61946ad --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/IndexBuffer11.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2012 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. +// + +// IndexBuffer11.h: Defines the D3D11 IndexBuffer implementation. + +#ifndef LIBGLESV2_RENDERER_INDEXBUFFER11_H_ +#define LIBGLESV2_RENDERER_INDEXBUFFER11_H_ + +#include "libGLESv2/renderer/IndexBuffer.h" + +namespace rx +{ +class Renderer11; + +class IndexBuffer11 : public IndexBuffer +{ + public: + explicit IndexBuffer11(Renderer11 *const renderer); + virtual ~IndexBuffer11(); + + virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + + static IndexBuffer11 *makeIndexBuffer11(IndexBuffer *indexBuffer); + + virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); + virtual bool unmapBuffer(); + + virtual GLenum getIndexType() const; + virtual unsigned int getBufferSize() const; + virtual bool setSize(unsigned int bufferSize, GLenum indexType); + + virtual bool discard(); + + DXGI_FORMAT getIndexFormat() const; + ID3D11Buffer *getBuffer() const; + + private: + DISALLOW_COPY_AND_ASSIGN(IndexBuffer11); + + rx::Renderer11 *const mRenderer; + + ID3D11Buffer *mBuffer; + unsigned int mBufferSize; + GLenum mIndexType; + bool mDynamicUsage; +}; + +} + +#endif // LIBGLESV2_RENDERER_INDEXBUFFER11_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp new file mode 100644 index 0000000000..4940b8c638 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.cpp @@ -0,0 +1,213 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// InputLayoutCache.cpp: Defines InputLayoutCache, a class that builds and caches +// D3D11 input layouts. + +#include "libGLESv2/renderer/d3d11/InputLayoutCache.h" +#include "libGLESv2/renderer/d3d11/VertexBuffer11.h" +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" +#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/renderer/VertexDataManager.h" + +#include "third_party/murmurhash/MurmurHash3.h" + +namespace rx +{ + +const unsigned int InputLayoutCache::kMaxInputLayouts = 1024; + +InputLayoutCache::InputLayoutCache() : mInputLayoutMap(kMaxInputLayouts, hashInputLayout, compareInputLayouts) +{ + mCounter = 0; + mDevice = NULL; + mDeviceContext = NULL; + mCurrentIL = NULL; + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mCurrentBuffers[i] = -1; + mCurrentVertexStrides[i] = -1; + mCurrentVertexOffsets[i] = -1; + } +} + +InputLayoutCache::~InputLayoutCache() +{ + clear(); +} + +void InputLayoutCache::initialize(ID3D11Device *device, ID3D11DeviceContext *context) +{ + clear(); + mDevice = device; + mDeviceContext = context; +} + +void InputLayoutCache::clear() +{ + for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) + { + i->second.inputLayout->Release(); + } + mInputLayoutMap.clear(); + markDirty(); +} + +void InputLayoutCache::markDirty() +{ + mCurrentIL = NULL; + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mCurrentBuffers[i] = -1; + mCurrentVertexStrides[i] = -1; + mCurrentVertexOffsets[i] = -1; + } +} + +GLenum InputLayoutCache::applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], + gl::ProgramBinary *programBinary) +{ + int sortedSemanticIndices[gl::MAX_VERTEX_ATTRIBS]; + programBinary->sortAttributesByLayout(attributes, sortedSemanticIndices); + + if (!mDevice || !mDeviceContext) + { + ERR("InputLayoutCache is not initialized."); + return GL_INVALID_OPERATION; + } + + InputLayoutKey ilKey = { 0 }; + + ID3D11Buffer *vertexBuffers[gl::MAX_VERTEX_ATTRIBS] = { NULL }; + unsigned int vertexBufferSerials[gl::MAX_VERTEX_ATTRIBS] = { 0 }; + UINT vertexStrides[gl::MAX_VERTEX_ATTRIBS] = { 0 }; + UINT vertexOffsets[gl::MAX_VERTEX_ATTRIBS] = { 0 }; + + static const char* semanticName = "TEXCOORD"; + + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + if (attributes[i].active) + { + VertexBuffer11 *vertexBuffer = VertexBuffer11::makeVertexBuffer11(attributes[i].vertexBuffer); + BufferStorage11 *bufferStorage = attributes[i].storage ? BufferStorage11::makeBufferStorage11(attributes[i].storage) : NULL; + + D3D11_INPUT_CLASSIFICATION inputClass = attributes[i].divisor > 0 ? D3D11_INPUT_PER_INSTANCE_DATA : D3D11_INPUT_PER_VERTEX_DATA; + + // Record the type of the associated vertex shader vector in our key + // This will prevent mismatched vertex shaders from using the same input layout + GLint attributeSize; + programBinary->getActiveAttribute(sortedSemanticIndices[i], 0, NULL, &attributeSize, &ilKey.elements[ilKey.elementCount].glslElementType, NULL); + + ilKey.elements[ilKey.elementCount].desc.SemanticName = semanticName; + ilKey.elements[ilKey.elementCount].desc.SemanticIndex = i; + ilKey.elements[ilKey.elementCount].desc.Format = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDXGIFormat(*attributes[i].attribute) : DXGI_FORMAT_R32G32B32A32_FLOAT; + ilKey.elements[ilKey.elementCount].desc.InputSlot = i; + ilKey.elements[ilKey.elementCount].desc.AlignedByteOffset = 0; + ilKey.elements[ilKey.elementCount].desc.InputSlotClass = inputClass; + ilKey.elements[ilKey.elementCount].desc.InstanceDataStepRate = attributes[i].divisor; + ilKey.elementCount++; + + vertexBuffers[i] = bufferStorage ? bufferStorage->getBuffer(BUFFER_USAGE_VERTEX) : vertexBuffer->getBuffer(); + vertexBufferSerials[i] = bufferStorage ? bufferStorage->getSerial() : vertexBuffer->getSerial(); + vertexStrides[i] = attributes[i].stride; + vertexOffsets[i] = attributes[i].offset; + } + } + + ID3D11InputLayout *inputLayout = NULL; + + InputLayoutMap::iterator i = mInputLayoutMap.find(ilKey); + if (i != mInputLayoutMap.end()) + { + inputLayout = i->second.inputLayout; + i->second.lastUsedTime = mCounter++; + } + else + { + ShaderExecutable11 *shader = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); + + D3D11_INPUT_ELEMENT_DESC descs[gl::MAX_VERTEX_ATTRIBS]; + for (unsigned int j = 0; j < ilKey.elementCount; ++j) + { + descs[j] = ilKey.elements[j].desc; + } + + HRESULT result = mDevice->CreateInputLayout(descs, ilKey.elementCount, shader->getFunction(), shader->getLength(), &inputLayout); + if (FAILED(result)) + { + ERR("Failed to crate input layout, result: 0x%08x", result); + return GL_INVALID_OPERATION; + } + + if (mInputLayoutMap.size() >= kMaxInputLayouts) + { + TRACE("Overflowed the limit of %u input layouts, removing the least recently used " + "to make room.", kMaxInputLayouts); + + InputLayoutMap::iterator leastRecentlyUsed = mInputLayoutMap.begin(); + for (InputLayoutMap::iterator i = mInputLayoutMap.begin(); i != mInputLayoutMap.end(); i++) + { + if (i->second.lastUsedTime < leastRecentlyUsed->second.lastUsedTime) + { + leastRecentlyUsed = i; + } + } + leastRecentlyUsed->second.inputLayout->Release(); + mInputLayoutMap.erase(leastRecentlyUsed); + } + + InputLayoutCounterPair inputCounterPair; + inputCounterPair.inputLayout = inputLayout; + inputCounterPair.lastUsedTime = mCounter++; + + mInputLayoutMap.insert(std::make_pair(ilKey, inputCounterPair)); + } + + if (inputLayout != mCurrentIL) + { + mDeviceContext->IASetInputLayout(inputLayout); + mCurrentIL = inputLayout; + } + + for (unsigned int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + if (vertexBufferSerials[i] != mCurrentBuffers[i] || vertexStrides[i] != mCurrentVertexStrides[i] || + vertexOffsets[i] != mCurrentVertexOffsets[i]) + { + mDeviceContext->IASetVertexBuffers(i, 1, &vertexBuffers[i], &vertexStrides[i], &vertexOffsets[i]); + mCurrentBuffers[i] = vertexBufferSerials[i]; + mCurrentVertexStrides[i] = vertexStrides[i]; + mCurrentVertexOffsets[i] = vertexOffsets[i]; + } + } + + return GL_NO_ERROR; +} + +std::size_t InputLayoutCache::hashInputLayout(const InputLayoutKey &inputLayout) +{ + static const unsigned int seed = 0xDEADBEEF; + + std::size_t hash = 0; + MurmurHash3_x86_32(inputLayout.begin(), inputLayout.end() - inputLayout.begin(), seed, &hash); + return hash; +} + +bool InputLayoutCache::compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b) +{ + if (a.elementCount != b.elementCount) + { + return false; + } + + return std::equal(a.begin(), a.end(), b.begin()); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.h new file mode 100644 index 0000000000..bb1a8eebcf --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/InputLayoutCache.h @@ -0,0 +1,95 @@ +// +// Copyright (c) 2012 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. +// + +// InputLayoutCache.h: Defines InputLayoutCache, a class that builds and caches +// D3D11 input layouts. + +#ifndef LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ +#define LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ + +#include "libGLESv2/Constants.h" +#include "common/angleutils.h" + +namespace gl +{ +class ProgramBinary; +} + +namespace rx +{ +struct TranslatedAttribute; + +class InputLayoutCache +{ + public: + InputLayoutCache(); + virtual ~InputLayoutCache(); + + void initialize(ID3D11Device *device, ID3D11DeviceContext *context); + void clear(); + void markDirty(); + + GLenum applyVertexBuffers(TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS], + gl::ProgramBinary *programBinary); + + private: + DISALLOW_COPY_AND_ASSIGN(InputLayoutCache); + + struct InputLayoutElement + { + D3D11_INPUT_ELEMENT_DESC desc; + GLenum glslElementType; + }; + + struct InputLayoutKey + { + unsigned int elementCount; + InputLayoutElement elements[gl::MAX_VERTEX_ATTRIBS]; + + const char *begin() const + { + return reinterpret_cast(&elementCount); + } + + const char *end() const + { + return reinterpret_cast(&elements[elementCount]); + } + }; + + struct InputLayoutCounterPair + { + ID3D11InputLayout *inputLayout; + unsigned long long lastUsedTime; + }; + + ID3D11InputLayout *mCurrentIL; + unsigned int mCurrentBuffers[gl::MAX_VERTEX_ATTRIBS]; + UINT mCurrentVertexStrides[gl::MAX_VERTEX_ATTRIBS]; + UINT mCurrentVertexOffsets[gl::MAX_VERTEX_ATTRIBS]; + + static std::size_t hashInputLayout(const InputLayoutKey &inputLayout); + static bool compareInputLayouts(const InputLayoutKey &a, const InputLayoutKey &b); + + typedef std::size_t (*InputLayoutHashFunction)(const InputLayoutKey &); + typedef bool (*InputLayoutEqualityFunction)(const InputLayoutKey &, const InputLayoutKey &); + typedef std::unordered_map InputLayoutMap; + InputLayoutMap mInputLayoutMap; + + static const unsigned int kMaxInputLayouts; + + unsigned long long mCounter; + + ID3D11Device *mDevice; + ID3D11DeviceContext *mDeviceContext; +}; + +} + +#endif // LIBGLESV2_RENDERER_INPUTLAYOUTCACHE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.cpp new file mode 100644 index 0000000000..24c0330a1e --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.cpp @@ -0,0 +1,122 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Query11.cpp: Defines the rx::Query11 class which implements rx::QueryImpl. + +#include "libGLESv2/renderer/d3d11/Query11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +Query11::Query11(rx::Renderer11 *renderer, GLenum type) : QueryImpl(type) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Query11::~Query11() +{ + if (mQuery) + { + mQuery->Release(); + mQuery = NULL; + } +} + +void Query11::begin() +{ + if (mQuery == NULL) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_OCCLUSION; + queryDesc.MiscFlags = 0; + + if (FAILED(mRenderer->getDevice()->CreateQuery(&queryDesc, &mQuery))) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + mRenderer->getDeviceContext()->Begin(mQuery); +} + +void Query11::end() +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + mRenderer->getDeviceContext()->End(mQuery); + + mStatus = GL_FALSE; + mResult = GL_FALSE; +} + +GLuint Query11::getResult() +{ + if (mQuery != NULL) + { + while (!testQuery()) + { + Sleep(0); + // explicitly check for device loss, some drivers seem to return S_FALSE + // if the device is lost + if (mRenderer->testDeviceLost(true)) + { + return gl::error(GL_OUT_OF_MEMORY, 0); + } + } + } + + return mResult; +} + +GLboolean Query11::isResultAvailable() +{ + if (mQuery != NULL) + { + testQuery(); + } + + return mStatus; +} + +GLboolean Query11::testQuery() +{ + if (mQuery != NULL && mStatus != GL_TRUE) + { + UINT64 numPixels = 0; + HRESULT result = mRenderer->getDeviceContext()->GetData(mQuery, &numPixels, sizeof(UINT64), 0); + if (result == S_OK) + { + mStatus = GL_TRUE; + + switch (getType()) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + break; + default: + UNREACHABLE(); + } + } + else if (mRenderer->testDeviceLost(true)) + { + return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + } + + return mStatus; + } + + return GL_TRUE; // prevent blocking when query is null +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.h new file mode 100644 index 0000000000..0a03de77ca --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Query11.h @@ -0,0 +1,40 @@ +// +// Copyright (c) 2013 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. +// + +// Query11.h: Defines the rx::Query11 class which implements rx::QueryImpl. + +#ifndef LIBGLESV2_RENDERER_QUERY11_H_ +#define LIBGLESV2_RENDERER_QUERY11_H_ + +#include "libGLESv2/renderer/QueryImpl.h" + +namespace rx +{ +class Renderer11; + +class Query11 : public QueryImpl +{ + public: + Query11(rx::Renderer11 *renderer, GLenum type); + virtual ~Query11(); + + void begin(); + void end(); + GLuint getResult(); + GLboolean isResultAvailable(); + + private: + DISALLOW_COPY_AND_ASSIGN(Query11); + + GLboolean testQuery(); + + rx::Renderer11 *mRenderer; + ID3D11Query *mQuery; +}; + +} + +#endif // LIBGLESV2_RENDERER_QUERY11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp new file mode 100644 index 0000000000..a1c324cd80 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.cpp @@ -0,0 +1,439 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// RenderStateCache.cpp: Defines rx::RenderStateCache, a cache of Direct3D render +// state objects. + +#include "libGLESv2/renderer/d3d11/RenderStateCache.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" + +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/utilities.h" +#include "common/debug.h" +#include "third_party/murmurhash/MurmurHash3.h" + +namespace rx +{ + +// MSDN's documentation of ID3D11Device::CreateBlendState, ID3D11Device::CreateRasterizerState, +// ID3D11Device::CreateDepthStencilState and ID3D11Device::CreateSamplerState claims the maximum +// number of unique states of each type an application can create is 4096 +const unsigned int RenderStateCache::kMaxBlendStates = 4096; +const unsigned int RenderStateCache::kMaxRasterizerStates = 4096; +const unsigned int RenderStateCache::kMaxDepthStencilStates = 4096; +const unsigned int RenderStateCache::kMaxSamplerStates = 4096; + +RenderStateCache::RenderStateCache() : mDevice(NULL), mCounter(0), + mBlendStateCache(kMaxBlendStates, hashBlendState, compareBlendStates), + mRasterizerStateCache(kMaxRasterizerStates, hashRasterizerState, compareRasterizerStates), + mDepthStencilStateCache(kMaxDepthStencilStates, hashDepthStencilState, compareDepthStencilStates), + mSamplerStateCache(kMaxSamplerStates, hashSamplerState, compareSamplerStates) +{ +} + +RenderStateCache::~RenderStateCache() +{ + clear(); +} + +void RenderStateCache::initialize(ID3D11Device *device) +{ + clear(); + mDevice = device; +} + +void RenderStateCache::clear() +{ + for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++) + { + i->second.first->Release(); + } + mBlendStateCache.clear(); + + for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++) + { + i->second.first->Release(); + } + mRasterizerStateCache.clear(); + + for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) + { + i->second.first->Release(); + } + mDepthStencilStateCache.clear(); + + for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++) + { + i->second.first->Release(); + } + mSamplerStateCache.clear(); +} + +std::size_t RenderStateCache::hashBlendState(const BlendStateKey &blendState) +{ + static const unsigned int seed = 0xABCDEF98; + + std::size_t hash = 0; + MurmurHash3_x86_32(&blendState, sizeof(BlendStateKey), seed, &hash); + return hash; +} + +bool RenderStateCache::compareBlendStates(const BlendStateKey &a, const BlendStateKey &b) +{ + return memcmp(&a, &b, sizeof(gl::BlendState)) == 0; +} + +ID3D11BlendState *RenderStateCache::getBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState) +{ + if (!mDevice) + { + ERR("RenderStateCache is not initialized."); + return NULL; + } + + bool mrt = false; + + BlendStateKey key = { 0 }; + key.blendState = blendState; + for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + gl::Renderbuffer *renderBuffer = framebuffer->getColorbuffer(i); + if (renderBuffer) + { + if (i > 0) + { + mrt = true; + } + + GLenum internalFormat = renderBuffer->getInternalFormat(); + key.rtChannels[i][0] = gl::GetRedSize(internalFormat) > 0; + key.rtChannels[i][1] = gl::GetGreenSize(internalFormat) > 0; + key.rtChannels[i][2] = gl::GetBlueSize(internalFormat) > 0;; + key.rtChannels[i][3] = gl::GetAlphaSize(internalFormat) > 0; + } + else + { + key.rtChannels[i][0] = false; + key.rtChannels[i][1] = false; + key.rtChannels[i][2] = false; + key.rtChannels[i][3] = false; + } + } + + BlendStateMap::iterator i = mBlendStateCache.find(key); + if (i != mBlendStateCache.end()) + { + BlendStateCounterPair &state = i->second; + state.second = mCounter++; + return state.first; + } + else + { + if (mBlendStateCache.size() >= kMaxBlendStates) + { + TRACE("Overflowed the limit of %u blend states, removing the least recently used " + "to make room.", kMaxBlendStates); + + BlendStateMap::iterator leastRecentlyUsed = mBlendStateCache.begin(); + for (BlendStateMap::iterator i = mBlendStateCache.begin(); i != mBlendStateCache.end(); i++) + { + if (i->second.second < leastRecentlyUsed->second.second) + { + leastRecentlyUsed = i; + } + } + leastRecentlyUsed->second.first->Release(); + mBlendStateCache.erase(leastRecentlyUsed); + } + + // Create a new blend state and insert it into the cache + D3D11_BLEND_DESC blendDesc = { 0 }; + blendDesc.AlphaToCoverageEnable = blendState.sampleAlphaToCoverage; + blendDesc.IndependentBlendEnable = mrt ? TRUE : FALSE; + + for (unsigned int i = 0; i < D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; i++) + { + D3D11_RENDER_TARGET_BLEND_DESC &rtBlend = blendDesc.RenderTarget[i]; + + rtBlend.BlendEnable = blendState.blend; + if (blendState.blend) + { + rtBlend.SrcBlend = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendRGB, false); + rtBlend.DestBlend = gl_d3d11::ConvertBlendFunc(blendState.destBlendRGB, false); + rtBlend.BlendOp = gl_d3d11::ConvertBlendOp(blendState.blendEquationRGB); + + rtBlend.SrcBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.sourceBlendAlpha, true); + rtBlend.DestBlendAlpha = gl_d3d11::ConvertBlendFunc(blendState.destBlendAlpha, true); + rtBlend.BlendOpAlpha = gl_d3d11::ConvertBlendOp(blendState.blendEquationAlpha); + } + + rtBlend.RenderTargetWriteMask = gl_d3d11::ConvertColorMask(key.rtChannels[i][0] && blendState.colorMaskRed, + key.rtChannels[i][1] && blendState.colorMaskGreen, + key.rtChannels[i][2] && blendState.colorMaskBlue, + key.rtChannels[i][3] && blendState.colorMaskAlpha); + } + + ID3D11BlendState *dx11BlendState = NULL; + HRESULT result = mDevice->CreateBlendState(&blendDesc, &dx11BlendState); + if (FAILED(result) || !dx11BlendState) + { + ERR("Unable to create a ID3D11BlendState, HRESULT: 0x%X.", result); + return NULL; + } + + mBlendStateCache.insert(std::make_pair(key, std::make_pair(dx11BlendState, mCounter++))); + + return dx11BlendState; + } +} + +std::size_t RenderStateCache::hashRasterizerState(const RasterizerStateKey &rasterState) +{ + static const unsigned int seed = 0xABCDEF98; + + std::size_t hash = 0; + MurmurHash3_x86_32(&rasterState, sizeof(RasterizerStateKey), seed, &hash); + return hash; +} + +bool RenderStateCache::compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b) +{ + return memcmp(&a, &b, sizeof(RasterizerStateKey)) == 0; +} + +ID3D11RasterizerState *RenderStateCache::getRasterizerState(const gl::RasterizerState &rasterState, + bool scissorEnabled, unsigned int depthSize) +{ + if (!mDevice) + { + ERR("RenderStateCache is not initialized."); + return NULL; + } + + RasterizerStateKey key; + key.rasterizerState = rasterState; + key.scissorEnabled = scissorEnabled; + key.depthSize = depthSize; + + RasterizerStateMap::iterator i = mRasterizerStateCache.find(key); + if (i != mRasterizerStateCache.end()) + { + RasterizerStateCounterPair &state = i->second; + state.second = mCounter++; + return state.first; + } + else + { + if (mRasterizerStateCache.size() >= kMaxRasterizerStates) + { + TRACE("Overflowed the limit of %u rasterizer states, removing the least recently used " + "to make room.", kMaxRasterizerStates); + + RasterizerStateMap::iterator leastRecentlyUsed = mRasterizerStateCache.begin(); + for (RasterizerStateMap::iterator i = mRasterizerStateCache.begin(); i != mRasterizerStateCache.end(); i++) + { + if (i->second.second < leastRecentlyUsed->second.second) + { + leastRecentlyUsed = i; + } + } + leastRecentlyUsed->second.first->Release(); + mRasterizerStateCache.erase(leastRecentlyUsed); + } + + D3D11_CULL_MODE cullMode = gl_d3d11::ConvertCullMode(rasterState.cullFace, rasterState.cullMode); + + // Disable culling if drawing points + if (rasterState.pointDrawMode) + { + cullMode = D3D11_CULL_NONE; + } + + D3D11_RASTERIZER_DESC rasterDesc; + rasterDesc.FillMode = D3D11_FILL_SOLID; + rasterDesc.CullMode = cullMode; + rasterDesc.FrontCounterClockwise = (rasterState.frontFace == GL_CCW) ? FALSE: TRUE; + rasterDesc.DepthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast(depthSize)); + rasterDesc.DepthBiasClamp = 0.0f; // MSDN documentation of DepthBiasClamp implies a value of zero will preform no clamping, must be tested though. + rasterDesc.SlopeScaledDepthBias = rasterState.polygonOffsetFactor; + rasterDesc.DepthClipEnable = TRUE; + rasterDesc.ScissorEnable = scissorEnabled ? TRUE : FALSE; + rasterDesc.MultisampleEnable = rasterState.multiSample; + rasterDesc.AntialiasedLineEnable = FALSE; + + ID3D11RasterizerState *dx11RasterizerState = NULL; + HRESULT result = mDevice->CreateRasterizerState(&rasterDesc, &dx11RasterizerState); + if (FAILED(result) || !dx11RasterizerState) + { + ERR("Unable to create a ID3D11RasterizerState, HRESULT: 0x%X.", result); + return NULL; + } + + mRasterizerStateCache.insert(std::make_pair(key, std::make_pair(dx11RasterizerState, mCounter++))); + + return dx11RasterizerState; + } +} + +std::size_t RenderStateCache::hashDepthStencilState(const gl::DepthStencilState &dsState) +{ + static const unsigned int seed = 0xABCDEF98; + + std::size_t hash = 0; + MurmurHash3_x86_32(&dsState, sizeof(gl::DepthStencilState), seed, &hash); + return hash; +} + +bool RenderStateCache::compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b) +{ + return memcmp(&a, &b, sizeof(gl::DepthStencilState)) == 0; +} + +ID3D11DepthStencilState *RenderStateCache::getDepthStencilState(const gl::DepthStencilState &dsState) +{ + if (!mDevice) + { + ERR("RenderStateCache is not initialized."); + return NULL; + } + + DepthStencilStateMap::iterator i = mDepthStencilStateCache.find(dsState); + if (i != mDepthStencilStateCache.end()) + { + DepthStencilStateCounterPair &state = i->second; + state.second = mCounter++; + return state.first; + } + else + { + if (mDepthStencilStateCache.size() >= kMaxDepthStencilStates) + { + TRACE("Overflowed the limit of %u depth stencil states, removing the least recently used " + "to make room.", kMaxDepthStencilStates); + + DepthStencilStateMap::iterator leastRecentlyUsed = mDepthStencilStateCache.begin(); + for (DepthStencilStateMap::iterator i = mDepthStencilStateCache.begin(); i != mDepthStencilStateCache.end(); i++) + { + if (i->second.second < leastRecentlyUsed->second.second) + { + leastRecentlyUsed = i; + } + } + leastRecentlyUsed->second.first->Release(); + mDepthStencilStateCache.erase(leastRecentlyUsed); + } + + D3D11_DEPTH_STENCIL_DESC dsDesc = { 0 }; + dsDesc.DepthEnable = dsState.depthTest ? TRUE : FALSE; + dsDesc.DepthWriteMask = gl_d3d11::ConvertDepthMask(dsState.depthMask); + dsDesc.DepthFunc = gl_d3d11::ConvertComparison(dsState.depthFunc); + dsDesc.StencilEnable = dsState.stencilTest ? TRUE : FALSE; + dsDesc.StencilReadMask = gl_d3d11::ConvertStencilMask(dsState.stencilMask); + dsDesc.StencilWriteMask = gl_d3d11::ConvertStencilMask(dsState.stencilWritemask); + dsDesc.FrontFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilFail); + dsDesc.FrontFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthFail); + dsDesc.FrontFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilPassDepthPass); + dsDesc.FrontFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilFunc); + dsDesc.BackFace.StencilFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackFail); + dsDesc.BackFace.StencilDepthFailOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthFail); + dsDesc.BackFace.StencilPassOp = gl_d3d11::ConvertStencilOp(dsState.stencilBackPassDepthPass); + dsDesc.BackFace.StencilFunc = gl_d3d11::ConvertComparison(dsState.stencilBackFunc); + + ID3D11DepthStencilState *dx11DepthStencilState = NULL; + HRESULT result = mDevice->CreateDepthStencilState(&dsDesc, &dx11DepthStencilState); + if (FAILED(result) || !dx11DepthStencilState) + { + ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); + return NULL; + } + + mDepthStencilStateCache.insert(std::make_pair(dsState, std::make_pair(dx11DepthStencilState, mCounter++))); + + return dx11DepthStencilState; + } +} + +std::size_t RenderStateCache::hashSamplerState(const gl::SamplerState &samplerState) +{ + static const unsigned int seed = 0xABCDEF98; + + std::size_t hash = 0; + MurmurHash3_x86_32(&samplerState, sizeof(gl::SamplerState), seed, &hash); + return hash; +} + +bool RenderStateCache::compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b) +{ + return memcmp(&a, &b, sizeof(gl::SamplerState)) == 0; +} + +ID3D11SamplerState *RenderStateCache::getSamplerState(const gl::SamplerState &samplerState) +{ + if (!mDevice) + { + ERR("RenderStateCache is not initialized."); + return NULL; + } + + SamplerStateMap::iterator i = mSamplerStateCache.find(samplerState); + if (i != mSamplerStateCache.end()) + { + SamplerStateCounterPair &state = i->second; + state.second = mCounter++; + return state.first; + } + else + { + if (mSamplerStateCache.size() >= kMaxSamplerStates) + { + TRACE("Overflowed the limit of %u sampler states, removing the least recently used " + "to make room.", kMaxSamplerStates); + + SamplerStateMap::iterator leastRecentlyUsed = mSamplerStateCache.begin(); + for (SamplerStateMap::iterator i = mSamplerStateCache.begin(); i != mSamplerStateCache.end(); i++) + { + if (i->second.second < leastRecentlyUsed->second.second) + { + leastRecentlyUsed = i; + } + } + leastRecentlyUsed->second.first->Release(); + mSamplerStateCache.erase(leastRecentlyUsed); + } + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = gl_d3d11::ConvertFilter(samplerState.minFilter, samplerState.magFilter, samplerState.maxAnisotropy); + samplerDesc.AddressU = gl_d3d11::ConvertTextureWrap(samplerState.wrapS); + samplerDesc.AddressV = gl_d3d11::ConvertTextureWrap(samplerState.wrapT); + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.MipLODBias = static_cast(samplerState.lodOffset); + samplerDesc.MaxAnisotropy = samplerState.maxAnisotropy; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + samplerDesc.BorderColor[0] = 0.0f; + samplerDesc.BorderColor[1] = 0.0f; + samplerDesc.BorderColor[2] = 0.0f; + samplerDesc.BorderColor[3] = 0.0f; + samplerDesc.MinLOD = gl_d3d11::ConvertMinLOD(samplerState.minFilter, samplerState.lodOffset); + samplerDesc.MaxLOD = mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 + ? gl_d3d11::ConvertMaxLOD(samplerState.minFilter, samplerState.lodOffset) : FLT_MAX; + + ID3D11SamplerState *dx11SamplerState = NULL; + HRESULT result = mDevice->CreateSamplerState(&samplerDesc, &dx11SamplerState); + if (FAILED(result) || !dx11SamplerState) + { + ERR("Unable to create a ID3D11DepthStencilState, HRESULT: 0x%X.", result); + return NULL; + } + + mSamplerStateCache.insert(std::make_pair(samplerState, std::make_pair(dx11SamplerState, mCounter++))); + + return dx11SamplerState; + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.h new file mode 100644 index 0000000000..b4b871a4bd --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderStateCache.h @@ -0,0 +1,111 @@ +// +// Copyright (c) 2012-2013 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. +// + +// RenderStateCache.h: Defines rx::RenderStateCache, a cache of Direct3D render +// state objects. + +#ifndef LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ +#define LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ + +#include "libGLESv2/angletypes.h" +#include "common/angleutils.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ + +class RenderStateCache +{ + public: + RenderStateCache(); + virtual ~RenderStateCache(); + + void initialize(ID3D11Device *device); + void clear(); + + // Increments refcount on the returned blend state, Release() must be called. + ID3D11BlendState *getBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState); + ID3D11RasterizerState *getRasterizerState(const gl::RasterizerState &rasterState, + bool scissorEnabled, unsigned int depthSize); + ID3D11DepthStencilState *getDepthStencilState(const gl::DepthStencilState &dsState); + ID3D11SamplerState *getSamplerState(const gl::SamplerState &samplerState); + + private: + DISALLOW_COPY_AND_ASSIGN(RenderStateCache); + + unsigned long long mCounter; + + // Blend state cache + struct BlendStateKey + { + gl::BlendState blendState; + bool rtChannels[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT][4]; + }; + static std::size_t hashBlendState(const BlendStateKey &blendState); + static bool compareBlendStates(const BlendStateKey &a, const BlendStateKey &b); + static const unsigned int kMaxBlendStates; + + typedef std::size_t (*BlendStateHashFunction)(const BlendStateKey &); + typedef bool (*BlendStateEqualityFunction)(const BlendStateKey &, const BlendStateKey &); + typedef std::pair BlendStateCounterPair; + typedef std::unordered_map BlendStateMap; + BlendStateMap mBlendStateCache; + + // Rasterizer state cache + struct RasterizerStateKey + { + gl::RasterizerState rasterizerState; + bool scissorEnabled; + unsigned int depthSize; + }; + static std::size_t hashRasterizerState(const RasterizerStateKey &rasterState); + static bool compareRasterizerStates(const RasterizerStateKey &a, const RasterizerStateKey &b); + static const unsigned int kMaxRasterizerStates; + + typedef std::size_t (*RasterizerStateHashFunction)(const RasterizerStateKey &); + typedef bool (*RasterizerStateEqualityFunction)(const RasterizerStateKey &, const RasterizerStateKey &); + typedef std::pair RasterizerStateCounterPair; + typedef std::unordered_map RasterizerStateMap; + RasterizerStateMap mRasterizerStateCache; + + // Depth stencil state cache + static std::size_t hashDepthStencilState(const gl::DepthStencilState &dsState); + static bool compareDepthStencilStates(const gl::DepthStencilState &a, const gl::DepthStencilState &b); + static const unsigned int kMaxDepthStencilStates; + + typedef std::size_t (*DepthStencilStateHashFunction)(const gl::DepthStencilState &); + typedef bool (*DepthStencilStateEqualityFunction)(const gl::DepthStencilState &, const gl::DepthStencilState &); + typedef std::pair DepthStencilStateCounterPair; + typedef std::unordered_map DepthStencilStateMap; + DepthStencilStateMap mDepthStencilStateCache; + + // Sample state cache + static std::size_t hashSamplerState(const gl::SamplerState &samplerState); + static bool compareSamplerStates(const gl::SamplerState &a, const gl::SamplerState &b); + static const unsigned int kMaxSamplerStates; + + typedef std::size_t (*SamplerStateHashFunction)(const gl::SamplerState &); + typedef bool (*SamplerStateEqualityFunction)(const gl::SamplerState &, const gl::SamplerState &); + typedef std::pair SamplerStateCounterPair; + typedef std::unordered_map SamplerStateMap; + SamplerStateMap mSamplerStateCache; + + ID3D11Device *mDevice; +}; + +} + +#endif // LIBGLESV2_RENDERER_RENDERSTATECACHE_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp new file mode 100644 index 0000000000..3707097aa4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.cpp @@ -0,0 +1,355 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// RenderTarget11.cpp: Implements a DX11-specific wrapper for ID3D11View pointers +// retained by Renderbuffers. + +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" + +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +static unsigned int getRTVSubresourceIndex(ID3D11Texture2D *texture, ID3D11RenderTargetView *view) +{ + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + view->GetDesc(&rtvDesc); + + D3D11_TEXTURE2D_DESC texDesc; + texture->GetDesc(&texDesc); + + unsigned int mipSlice = 0; + unsigned int arraySlice = 0; + unsigned int mipLevels = texDesc.MipLevels; + + switch (rtvDesc.ViewDimension) + { + case D3D11_RTV_DIMENSION_TEXTURE1D: + mipSlice = rtvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE1DARRAY: + mipSlice = rtvDesc.Texture1DArray.MipSlice; + arraySlice = rtvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2D: + mipSlice = rtvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DARRAY: + mipSlice = rtvDesc.Texture2DArray.MipSlice; + arraySlice = rtvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = rtvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_TEXTURE3D: + mipSlice = rtvDesc.Texture3D.MipSlice; + arraySlice = 0; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + case D3D11_RTV_DIMENSION_BUFFER: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); +} + +static unsigned int getDSVSubresourceIndex(ID3D11Texture2D *texture, ID3D11DepthStencilView *view) +{ + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + view->GetDesc(&dsvDesc); + + D3D11_TEXTURE2D_DESC texDesc; + texture->GetDesc(&texDesc); + + unsigned int mipSlice = 0; + unsigned int arraySlice = 0; + unsigned int mipLevels = texDesc.MipLevels; + + switch (dsvDesc.ViewDimension) + { + case D3D11_DSV_DIMENSION_TEXTURE1D: + mipSlice = dsvDesc.Texture1D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE1DARRAY: + mipSlice = dsvDesc.Texture1DArray.MipSlice; + arraySlice = dsvDesc.Texture1DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2D: + mipSlice = dsvDesc.Texture2D.MipSlice; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DARRAY: + mipSlice = dsvDesc.Texture2DArray.MipSlice; + arraySlice = dsvDesc.Texture2DArray.FirstArraySlice; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMS: + mipSlice = 0; + arraySlice = 0; + break; + + case D3D11_DSV_DIMENSION_TEXTURE2DMSARRAY: + mipSlice = 0; + arraySlice = dsvDesc.Texture2DMSArray.FirstArraySlice; + break; + + case D3D11_RTV_DIMENSION_UNKNOWN: + UNIMPLEMENTED(); + break; + + default: + UNREACHABLE(); + break; + } + + return D3D11CalcSubresource(mipSlice, arraySlice, mipLevels); +} + +RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) +{ + mRenderer = Renderer11::makeRenderer11(renderer); + mTexture = tex; + mRenderTarget = rtv; + mDepthStencil = NULL; + mShaderResource = srv; + mSubresourceIndex = 0; + + if (mRenderTarget && mTexture) + { + D3D11_RENDER_TARGET_VIEW_DESC desc; + mRenderTarget->GetDesc(&desc); + + D3D11_TEXTURE2D_DESC texDesc; + mTexture->GetDesc(&texDesc); + + mSubresourceIndex = getRTVSubresourceIndex(mTexture, mRenderTarget); + mWidth = width; + mHeight = height; + mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; + + mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); + mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); + } +} + +RenderTarget11::RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height) +{ + mRenderer = Renderer11::makeRenderer11(renderer); + mTexture = tex; + mRenderTarget = NULL; + mDepthStencil = dsv; + mShaderResource = srv; + mSubresourceIndex = 0; + + if (mDepthStencil && mTexture) + { + D3D11_DEPTH_STENCIL_VIEW_DESC desc; + mDepthStencil->GetDesc(&desc); + + D3D11_TEXTURE2D_DESC texDesc; + mTexture->GetDesc(&texDesc); + + mSubresourceIndex = getDSVSubresourceIndex(mTexture, mDepthStencil); + mWidth = width; + mHeight = height; + mSamples = (texDesc.SampleDesc.Count > 1) ? texDesc.SampleDesc.Count : 0; + + mInternalFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); + mActualFormat = d3d11_gl::ConvertTextureInternalFormat(desc.Format); + } +} + +RenderTarget11::RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth) +{ + mRenderer = Renderer11::makeRenderer11(renderer); + mTexture = NULL; + mRenderTarget = NULL; + mDepthStencil = NULL; + mShaderResource = NULL; + + DXGI_FORMAT requestedFormat = gl_d3d11::ConvertRenderbufferFormat(format); + + int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); + if (supportedSamples < 0) + { + gl::error(GL_OUT_OF_MEMORY); + return; + } + + if (width > 0 && height > 0) + { + // Create texture resource + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; + desc.Height = height; + desc.MipLevels = 1; + desc.ArraySize = 1; + desc.Format = requestedFormat; + desc.SampleDesc.Count = (supportedSamples == 0) ? 1 : supportedSamples; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + desc.BindFlags = (depth ? D3D11_BIND_DEPTH_STENCIL : (D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE)); + + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + if (result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + return; + } + ASSERT(SUCCEEDED(result)); + + if (depth) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = requestedFormat; + dsvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_DSV_DIMENSION_TEXTURE2D : D3D11_DSV_DIMENSION_TEXTURE2DMS; + dsvDesc.Texture2D.MipSlice = 0; + dsvDesc.Flags = 0; + result = device->CreateDepthStencilView(mTexture, &dsvDesc, &mDepthStencil); + + if (result == E_OUTOFMEMORY) + { + mTexture->Release(); + mTexture = NULL; + gl::error(GL_OUT_OF_MEMORY); + } + ASSERT(SUCCEEDED(result)); + } + else + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = requestedFormat; + rtvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_RTV_DIMENSION_TEXTURE2D : D3D11_RTV_DIMENSION_TEXTURE2DMS; + rtvDesc.Texture2D.MipSlice = 0; + result = device->CreateRenderTargetView(mTexture, &rtvDesc, &mRenderTarget); + + if (result == E_OUTOFMEMORY) + { + mTexture->Release(); + mTexture = NULL; + gl::error(GL_OUT_OF_MEMORY); + return; + } + ASSERT(SUCCEEDED(result)); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = requestedFormat; + srvDesc.ViewDimension = (supportedSamples == 0) ? D3D11_SRV_DIMENSION_TEXTURE2D : D3D11_SRV_DIMENSION_TEXTURE2DMS; + srvDesc.Texture2D.MostDetailedMip = 0; + srvDesc.Texture2D.MipLevels = 1; + result = device->CreateShaderResourceView(mTexture, &srvDesc, &mShaderResource); + + if (result == E_OUTOFMEMORY) + { + mTexture->Release(); + mTexture = NULL; + mRenderTarget->Release(); + mRenderTarget = NULL; + gl::error(GL_OUT_OF_MEMORY); + return; + } + ASSERT(SUCCEEDED(result)); + } + } + + mWidth = width; + mHeight = height; + mInternalFormat = format; + mSamples = supportedSamples; + mActualFormat = d3d11_gl::ConvertTextureInternalFormat(requestedFormat); + mSubresourceIndex = D3D11CalcSubresource(0, 0, 1); +} + +RenderTarget11::~RenderTarget11() +{ + if (mTexture) + { + mTexture->Release(); + mTexture = NULL; + } + + if (mRenderTarget) + { + mRenderTarget->Release(); + mRenderTarget = NULL; + } + + if (mDepthStencil) + { + mDepthStencil->Release(); + mDepthStencil = NULL; + } + + if (mShaderResource) + { + mShaderResource->Release(); + mShaderResource = NULL; + } +} + +RenderTarget11 *RenderTarget11::makeRenderTarget11(RenderTarget *target) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget11*, target)); + return static_cast(target); +} + +ID3D11Texture2D *RenderTarget11::getTexture() const +{ + return mTexture; +} + +ID3D11RenderTargetView *RenderTarget11::getRenderTargetView() const +{ + return mRenderTarget; +} + +ID3D11DepthStencilView *RenderTarget11::getDepthStencilView() const +{ + return mDepthStencil; +} + +ID3D11ShaderResourceView *RenderTarget11::getShaderResourceView() const +{ + return mShaderResource; +} + +unsigned int RenderTarget11::getSubresourceIndex() const +{ + return mSubresourceIndex; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.h new file mode 100644 index 0000000000..97827f2639 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/RenderTarget11.h @@ -0,0 +1,51 @@ +// +// Copyright (c) 2012 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. +// + +// RenderTarget11.h: Defines a DX11-specific wrapper for ID3D11View pointers +// retained by Renderbuffers. + +#ifndef LIBGLESV2_RENDERER_RENDERTARGET11_H_ +#define LIBGLESV2_RENDERER_RENDERTARGET11_H_ + +#include "libGLESv2/renderer/RenderTarget.h" + +namespace rx +{ +class Renderer; +class Renderer11; + +class RenderTarget11 : public RenderTarget +{ + public: + RenderTarget11(Renderer *renderer, ID3D11RenderTargetView *rtv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height); + RenderTarget11(Renderer *renderer, ID3D11DepthStencilView *dsv, ID3D11Texture2D *tex, ID3D11ShaderResourceView *srv, GLsizei width, GLsizei height); + RenderTarget11(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples, bool depth); + virtual ~RenderTarget11(); + + static RenderTarget11 *makeRenderTarget11(RenderTarget *renderTarget); + + ID3D11Texture2D *getTexture() const; + ID3D11RenderTargetView *getRenderTargetView() const; + ID3D11DepthStencilView *getDepthStencilView() const; + ID3D11ShaderResourceView *getShaderResourceView() const; + + unsigned int getSubresourceIndex() const; + + private: + DISALLOW_COPY_AND_ASSIGN(RenderTarget11); + + unsigned int mSubresourceIndex; + ID3D11Texture2D *mTexture; + ID3D11RenderTargetView *mRenderTarget; + ID3D11DepthStencilView *mDepthStencil; + ID3D11ShaderResourceView *mShaderResource; + + Renderer11 *mRenderer; +}; + +} + +#endif LIBGLESV2_RENDERER_RENDERTARGET11_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp new file mode 100644 index 0000000000..31d976dec4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.cpp @@ -0,0 +1,3670 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// Renderer11.cpp: Implements a back-end specific class for the D3D11 renderer. + +#include "libGLESv2/main.h" +#include "libGLESv2/utilities.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h" +#include "libGLESv2/renderer/d3d11/SwapChain11.h" +#include "libGLESv2/renderer/d3d11/Image11.h" +#include "libGLESv2/renderer/d3d11/VertexBuffer11.h" +#include "libGLESv2/renderer/d3d11/IndexBuffer11.h" +#include "libGLESv2/renderer/d3d11/BufferStorage11.h" +#include "libGLESv2/renderer/VertexDataManager.h" +#include "libGLESv2/renderer/IndexDataManager.h" +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" +#include "libGLESv2/renderer/d3d11/Query11.h" +#include "libGLESv2/renderer/d3d11/Fence11.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgb11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlum11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughlumalpha11ps.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/clear11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearsingle11ps.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/clearmultiple11ps.h" + +#include "libEGL/Display.h" + +#ifdef _DEBUG +// this flag enables suppressing some spurious warnings that pop up in certain WebGL samples +// and conformance tests. to enable all warnings, remove this define. +#define ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS 1 +#endif + +namespace rx +{ +static const DXGI_FORMAT RenderTargetFormats[] = + { + DXGI_FORMAT_B8G8R8A8_UNORM, + DXGI_FORMAT_R8G8B8A8_UNORM + }; + +static const DXGI_FORMAT DepthStencilFormats[] = + { + DXGI_FORMAT_UNKNOWN, + DXGI_FORMAT_D24_UNORM_S8_UINT, + DXGI_FORMAT_D16_UNORM + }; + +enum +{ + MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 = 16 +}; + +Renderer11::Renderer11(egl::Display *display) : Renderer(display) +{ + mVertexDataManager = NULL; + mIndexDataManager = NULL; + + mLineLoopIB = NULL; + mTriangleFanIB = NULL; + + mCopyResourcesInitialized = false; + mCopyVB = NULL; + mCopySampler = NULL; + mCopyIL = NULL; + mCopyVS = NULL; + mCopyRGBAPS = NULL; + mCopyRGBPS = NULL; + mCopyLumPS = NULL; + mCopyLumAlphaPS = NULL; + + mClearResourcesInitialized = false; + mClearVB = NULL; + mClearIL = NULL; + mClearVS = NULL; + mClearSinglePS = NULL; + mClearMultiplePS = NULL; + mClearScissorRS = NULL; + mClearNoScissorRS = NULL; + + mSyncQuery = NULL; + + mD3d11Module = NULL; + mDxgiModule = NULL; + + mDeviceLost = false; + + mMaxSupportedSamples = 0; + + mDevice = NULL; + mDeviceContext = NULL; + mDxgiAdapter = NULL; + mDxgiFactory = NULL; + + mDriverConstantBufferVS = NULL; + mDriverConstantBufferPS = NULL; + + mBGRATextureSupport = false; + + mIsGeometryShaderActive = false; +} + +Renderer11::~Renderer11() +{ + release(); +} + +Renderer11 *Renderer11::makeRenderer11(Renderer *renderer) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer11*, renderer)); + return static_cast(renderer); +} + +#ifndef __d3d11_1_h__ +#define D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET ((D3D11_MESSAGE_ID)3146081) +#endif + +EGLint Renderer11::initialize() +{ + if (!initializeCompiler()) + { + return EGL_NOT_INITIALIZED; + } + +#if !defined(ANGLE_OS_WINRT) + mDxgiModule = LoadLibrary(TEXT("dxgi.dll")); + mD3d11Module = LoadLibrary(TEXT("d3d11.dll")); + + if (mD3d11Module == NULL || mDxgiModule == NULL) + { + ERR("Could not load D3D11 or DXGI library - aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + + // create the D3D11 device + ASSERT(mDevice == NULL); + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); + + if (D3D11CreateDevice == NULL) + { + ERR("Could not retrieve D3D11CreateDevice address - aborting!\n"); + return EGL_NOT_INITIALIZED; + } +#endif + + D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, +#if !defined(ANGLE_ENABLE_D3D9) + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, +#endif + }; + + HRESULT result = S_OK; + +#ifdef _DEBUG + result = D3D11CreateDevice(NULL, + D3D_DRIVER_TYPE_HARDWARE, + NULL, + D3D11_CREATE_DEVICE_DEBUG, + featureLevels, + ArraySize(featureLevels), + D3D11_SDK_VERSION, + &mDevice, + &mFeatureLevel, + &mDeviceContext); + + if (!mDevice || FAILED(result)) + { + ERR("Failed creating Debug D3D11 device - falling back to release runtime.\n"); + } + + if (!mDevice || FAILED(result)) +#endif + { + result = D3D11CreateDevice(NULL, + D3D_DRIVER_TYPE_HARDWARE, + NULL, + 0, + featureLevels, + ArraySize(featureLevels), + D3D11_SDK_VERSION, + &mDevice, + &mFeatureLevel, + &mDeviceContext); + + if (!mDevice || FAILED(result)) + { + ERR("Could not create D3D11 device - aborting!\n"); + return EGL_NOT_INITIALIZED; // Cleanup done by destructor through glDestroyRenderer + } + } + +#if !defined(ANGLE_OS_WINRT) + IDXGIDevice *dxgiDevice = NULL; +#else + IDXGIDevice1 *dxgiDevice = NULL; +#endif + result = mDevice->QueryInterface(IID_PPV_ARGS(&dxgiDevice)); + + if (FAILED(result)) + { + ERR("Could not query DXGI device - aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + result = dxgiDevice->GetParent(__uuidof(IDXGIAdapter), (void**)&mDxgiAdapter); + + if (FAILED(result)) + { + ERR("Could not retrieve DXGI adapter - aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + dxgiDevice->Release(); + + mDxgiAdapter->GetDesc(&mAdapterDescription); + memset(mDescription, 0, sizeof(mDescription)); + wcstombs(mDescription, mAdapterDescription.Description, sizeof(mDescription) - 1); + + result = mDxgiAdapter->GetParent(__uuidof(IDXGIFactory), (void**)&mDxgiFactory); + + if (!mDxgiFactory || FAILED(result)) + { + ERR("Could not create DXGI factory - aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + // Disable some spurious D3D11 debug warnings to prevent them from flooding the output log +#if defined(ANGLE_SUPPRESS_D3D11_HAZARD_WARNINGS) && defined(_DEBUG) + ID3D11InfoQueue *infoQueue; + result = mDevice->QueryInterface(__uuidof(ID3D11InfoQueue), (void **)&infoQueue); + + if (SUCCEEDED(result)) + { + D3D11_MESSAGE_ID hideMessages[] = + { + D3D11_MESSAGE_ID_DEVICE_DRAW_RENDERTARGETVIEW_NOT_SET + }; + + D3D11_INFO_QUEUE_FILTER filter = {0}; + filter.DenyList.NumIDs = ArraySize(hideMessages); + filter.DenyList.pIDList = hideMessages; + + infoQueue->AddStorageFilterEntries(&filter); + + infoQueue->Release(); + } +#endif + + unsigned int maxSupportedSamples = 0; + unsigned int rtFormatCount = ArraySize(RenderTargetFormats); + unsigned int dsFormatCount = ArraySize(DepthStencilFormats); + for (unsigned int i = 0; i < rtFormatCount + dsFormatCount; ++i) + { + DXGI_FORMAT format = (i < rtFormatCount) ? RenderTargetFormats[i] : DepthStencilFormats[i - rtFormatCount]; + if (format != DXGI_FORMAT_UNKNOWN) + { + UINT formatSupport; + result = mDevice->CheckFormatSupport(format, &formatSupport); + if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_MULTISAMPLE_RENDERTARGET)) + { + MultisampleSupportInfo supportInfo; + + for (unsigned int j = 1; j <= D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; j++) + { + result = mDevice->CheckMultisampleQualityLevels(format, j, &supportInfo.qualityLevels[j - 1]); + if (SUCCEEDED(result) && supportInfo.qualityLevels[j - 1] > 0) + { + maxSupportedSamples = std::max(j, maxSupportedSamples); + } + else + { + supportInfo.qualityLevels[j - 1] = 0; + } + } + + mMultisampleSupportMap.insert(std::make_pair(format, supportInfo)); + } + } + } + mMaxSupportedSamples = maxSupportedSamples; + + initializeDevice(); + + // BGRA texture support is optional in feature levels 10 and 10_1 + UINT formatSupport; + result = mDevice->CheckFormatSupport(DXGI_FORMAT_B8G8R8A8_UNORM, &formatSupport); + if (FAILED(result)) + { + ERR("Error checking BGRA format support: 0x%08X", result); + } + else + { + const int flags = (D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_RENDER_TARGET); + mBGRATextureSupport = (formatSupport & flags) == flags; + } + + // Check floating point texture support + static const unsigned int requiredTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D | D3D11_FORMAT_SUPPORT_TEXTURECUBE; + static const unsigned int requiredRenderableFlags = D3D11_FORMAT_SUPPORT_RENDER_TARGET; + static const unsigned int requiredFilterFlags = D3D11_FORMAT_SUPPORT_SHADER_SAMPLE; + + DXGI_FORMAT float16Formats[] = + { + DXGI_FORMAT_R16_FLOAT, + DXGI_FORMAT_R16G16_FLOAT, + DXGI_FORMAT_R16G16B16A16_FLOAT, + }; + + DXGI_FORMAT float32Formats[] = + { + DXGI_FORMAT_R32_FLOAT, + DXGI_FORMAT_R32G32_FLOAT, + DXGI_FORMAT_R32G32B32A32_FLOAT, + }; + + mFloat16TextureSupport = true; + mFloat16FilterSupport = true; + mFloat16RenderSupport = true; + for (unsigned int i = 0; i < ArraySize(float16Formats); i++) + { + if (SUCCEEDED(mDevice->CheckFormatSupport(float16Formats[i], &formatSupport))) + { + mFloat16TextureSupport = mFloat16TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags; + mFloat16FilterSupport = mFloat16FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags; + mFloat16RenderSupport = mFloat16RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags; + } + else + { + mFloat16TextureSupport = false; + mFloat16RenderSupport = false; + mFloat16FilterSupport = false; + } + } + + mFloat32TextureSupport = true; + mFloat32FilterSupport = true; + mFloat32RenderSupport = true; + for (unsigned int i = 0; i < ArraySize(float32Formats); i++) + { + if (SUCCEEDED(mDevice->CheckFormatSupport(float32Formats[i], &formatSupport))) + { + mFloat32TextureSupport = mFloat32TextureSupport && (formatSupport & requiredTextureFlags) == requiredTextureFlags; + mFloat32FilterSupport = mFloat32FilterSupport && (formatSupport & requiredFilterFlags) == requiredFilterFlags; + mFloat32RenderSupport = mFloat32RenderSupport && (formatSupport & requiredRenderableFlags) == requiredRenderableFlags; + } + else + { + mFloat32TextureSupport = false; + mFloat32FilterSupport = false; + mFloat32RenderSupport = false; + } + } + + // Check compressed texture support + const unsigned int requiredCompressedTextureFlags = D3D11_FORMAT_SUPPORT_TEXTURE2D; + + if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC1_UNORM, &formatSupport))) + { + mDXT1TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags; + } + else + { + mDXT1TextureSupport = false; + } + + if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC3_UNORM, &formatSupport))) + { + mDXT3TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags; + } + else + { + mDXT3TextureSupport = false; + } + + if (SUCCEEDED(mDevice->CheckFormatSupport(DXGI_FORMAT_BC5_UNORM, &formatSupport))) + { + mDXT5TextureSupport = (formatSupport & requiredCompressedTextureFlags) == requiredCompressedTextureFlags; + } + else + { + mDXT5TextureSupport = false; + } + + // Check depth texture support + DXGI_FORMAT depthTextureFormats[] = + { + DXGI_FORMAT_D16_UNORM, + DXGI_FORMAT_D24_UNORM_S8_UINT, + }; + + static const unsigned int requiredDepthTextureFlags = D3D11_FORMAT_SUPPORT_DEPTH_STENCIL | + D3D11_FORMAT_SUPPORT_TEXTURE2D; + + mDepthTextureSupport = true; + for (unsigned int i = 0; i < ArraySize(depthTextureFormats); i++) + { + if (SUCCEEDED(mDevice->CheckFormatSupport(depthTextureFormats[i], &formatSupport))) + { + mDepthTextureSupport = mDepthTextureSupport && ((formatSupport & requiredDepthTextureFlags) == requiredDepthTextureFlags); + } + else + { + mDepthTextureSupport = false; + } + } + + return EGL_SUCCESS; +} + +// 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 Renderer11::initializeDevice() +{ + mStateCache.initialize(mDevice); + mInputLayoutCache.initialize(mDevice, mDeviceContext); + + ASSERT(!mVertexDataManager && !mIndexDataManager); + mVertexDataManager = new VertexDataManager(this); + mIndexDataManager = new IndexDataManager(this); + + markAllStateDirty(); +} + +int Renderer11::generateConfigs(ConfigDesc **configDescList) +{ + unsigned int numRenderFormats = ArraySize(RenderTargetFormats); + unsigned int numDepthFormats = ArraySize(DepthStencilFormats); + (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; + int numConfigs = 0; + + for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) + { + for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) + { + DXGI_FORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; + + UINT formatSupport = 0; + HRESULT result = mDevice->CheckFormatSupport(renderTargetFormat, &formatSupport); + + if (SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_RENDER_TARGET)) + { + DXGI_FORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; + + bool depthStencilFormatOK = true; + + if (depthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + UINT formatSupport = 0; + result = mDevice->CheckFormatSupport(depthStencilFormat, &formatSupport); + depthStencilFormatOK = SUCCEEDED(result) && (formatSupport & D3D11_FORMAT_SUPPORT_DEPTH_STENCIL); + } + + if (depthStencilFormatOK) + { + ConfigDesc newConfig; + newConfig.renderTargetFormat = d3d11_gl::ConvertBackBufferFormat(renderTargetFormat); + newConfig.depthStencilFormat = d3d11_gl::ConvertDepthStencilFormat(depthStencilFormat); + newConfig.multiSample = 0; // FIXME: enumerate multi-sampling + newConfig.fastConfig = true; // Assume all DX11 format conversions to be fast + + (*configDescList)[numConfigs++] = newConfig; + } + } + } + } + + return numConfigs; +} + +void Renderer11::deleteConfigs(ConfigDesc *configDescList) +{ + delete [] (configDescList); +} + +void Renderer11::sync(bool block) +{ + if (block) + { + HRESULT result; + + if (!mSyncQuery) + { + D3D11_QUERY_DESC queryDesc; + queryDesc.Query = D3D11_QUERY_EVENT; + queryDesc.MiscFlags = 0; + + result = mDevice->CreateQuery(&queryDesc, &mSyncQuery); + ASSERT(SUCCEEDED(result)); + } + + mDeviceContext->End(mSyncQuery); + mDeviceContext->Flush(); + + do + { + result = mDeviceContext->GetData(mSyncQuery, NULL, 0, D3D11_ASYNC_GETDATA_DONOTFLUSH); + + // Keep polling, but allow other threads to do something useful first + Sleep(0); + + if (testDeviceLost(true)) + { + return; + } + } + while (result == S_FALSE); + } + else + { + mDeviceContext->Flush(); + } +} + +SwapChain *Renderer11::createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +{ + return new rx::SwapChain11(this, window, shareHandle, backBufferFormat, depthBufferFormat); +} + +void Renderer11::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +{ + if (type == gl::SAMPLER_PIXEL) + { + if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) + { + ERR("Pixel shader sampler index %i is not valid.", index); + return; + } + + if (mForceSetPixelSamplerStates[index] || memcmp(&samplerState, &mCurPixelSamplerStates[index], sizeof(gl::SamplerState)) != 0) + { + ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); + + if (!dxSamplerState) + { + ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" + "sampler state for pixel shaders at slot %i.", index); + } + + mDeviceContext->PSSetSamplers(index, 1, &dxSamplerState); + + mCurPixelSamplerStates[index] = samplerState; + } + + mForceSetPixelSamplerStates[index] = false; + } + else if (type == gl::SAMPLER_VERTEX) + { + if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) + { + ERR("Vertex shader sampler index %i is not valid.", index); + return; + } + + if (mForceSetVertexSamplerStates[index] || memcmp(&samplerState, &mCurVertexSamplerStates[index], sizeof(gl::SamplerState)) != 0) + { + ID3D11SamplerState *dxSamplerState = mStateCache.getSamplerState(samplerState); + + if (!dxSamplerState) + { + ERR("NULL sampler state returned by RenderStateCache::getSamplerState, setting the default" + "sampler state for vertex shaders at slot %i.", index); + } + + mDeviceContext->VSSetSamplers(index, 1, &dxSamplerState); + + mCurVertexSamplerStates[index] = samplerState; + } + + mForceSetVertexSamplerStates[index] = false; + } + else UNREACHABLE(); +} + +void Renderer11::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +{ + ID3D11ShaderResourceView *textureSRV = NULL; + unsigned int serial = 0; + bool forceSetTexture = false; + + if (texture) + { + TextureStorageInterface *texStorage = texture->getNativeTexture(); + if (texStorage) + { + TextureStorage11 *storage11 = TextureStorage11::makeTextureStorage11(texStorage->getStorageInstance()); + textureSRV = storage11->getSRV(); + } + + // If we get NULL back from getSRV here, something went wrong in the texture class and we're unexpectedly + // missing the shader resource view + ASSERT(textureSRV != NULL); + + serial = texture->getTextureSerial(); + forceSetTexture = texture->hasDirtyImages(); + } + + if (type == gl::SAMPLER_PIXEL) + { + if (index < 0 || index >= gl::MAX_TEXTURE_IMAGE_UNITS) + { + ERR("Pixel shader sampler index %i is not valid.", index); + return; + } + + if (forceSetTexture || mCurPixelTextureSerials[index] != serial) + { + mDeviceContext->PSSetShaderResources(index, 1, &textureSRV); + } + + mCurPixelTextureSerials[index] = serial; + } + else if (type == gl::SAMPLER_VERTEX) + { + if (index < 0 || index >= (int)getMaxVertexTextureImageUnits()) + { + ERR("Vertex shader sampler index %i is not valid.", index); + return; + } + + if (forceSetTexture || mCurVertexTextureSerials[index] != serial) + { + mDeviceContext->VSSetShaderResources(index, 1, &textureSRV); + } + + mCurVertexTextureSerials[index] = serial; + } + else UNREACHABLE(); +} + +void Renderer11::setRasterizerState(const gl::RasterizerState &rasterState) +{ + if (mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0) + { + ID3D11RasterizerState *dxRasterState = mStateCache.getRasterizerState(rasterState, mScissorEnabled, + mCurDepthSize); + if (!dxRasterState) + { + ERR("NULL rasterizer state returned by RenderStateCache::getRasterizerState, setting the default" + "rasterizer state."); + } + + mDeviceContext->RSSetState(dxRasterState); + + mCurRasterState = rasterState; + } + + mForceSetRasterState = false; +} + +void Renderer11::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::Color &blendColor, + unsigned int sampleMask) +{ + if (mForceSetBlendState || + memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0 || + memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0 || + sampleMask != mCurSampleMask) + { + ID3D11BlendState *dxBlendState = mStateCache.getBlendState(framebuffer, blendState); + if (!dxBlendState) + { + ERR("NULL blend state returned by RenderStateCache::getBlendState, setting the default " + "blend state."); + } + + float blendColors[4] = {0.0f}; + if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) + { + blendColors[0] = blendColor.red; + blendColors[1] = blendColor.green; + blendColors[2] = blendColor.blue; + blendColors[3] = blendColor.alpha; + } + else + { + blendColors[0] = blendColor.alpha; + blendColors[1] = blendColor.alpha; + blendColors[2] = blendColor.alpha; + blendColors[3] = blendColor.alpha; + } + + mDeviceContext->OMSetBlendState(dxBlendState, blendColors, sampleMask); + + mCurBlendState = blendState; + mCurBlendColor = blendColor; + mCurSampleMask = sampleMask; + } + + mForceSetBlendState = false; +} + +void Renderer11::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) +{ + if (mForceSetDepthStencilState || + memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0 || + stencilRef != mCurStencilRef || stencilBackRef != mCurStencilBackRef) + { + if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask || + stencilRef != stencilBackRef || + depthStencilState.stencilMask != depthStencilState.stencilBackMask) + { + ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are " + "invalid under WebGL."); + return gl::error(GL_INVALID_OPERATION); + } + + ID3D11DepthStencilState *dxDepthStencilState = mStateCache.getDepthStencilState(depthStencilState); + if (!dxDepthStencilState) + { + ERR("NULL depth stencil state returned by RenderStateCache::getDepthStencilState, " + "setting the default depth stencil state."); + } + + mDeviceContext->OMSetDepthStencilState(dxDepthStencilState, static_cast(stencilRef)); + + mCurDepthStencilState = depthStencilState; + mCurStencilRef = stencilRef; + mCurStencilBackRef = stencilBackRef; + } + + mForceSetDepthStencilState = false; +} + +void Renderer11::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) +{ + if (mForceSetScissor || memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || + enabled != mScissorEnabled) + { + if (enabled) + { + D3D11_RECT rect; + rect.left = std::max(0, scissor.x); + rect.top = std::max(0, scissor.y); + rect.right = scissor.x + std::max(0, scissor.width); + rect.bottom = scissor.y + std::max(0, scissor.height); + + mDeviceContext->RSSetScissorRects(1, &rect); + } + + if (enabled != mScissorEnabled) + { + mForceSetRasterState = true; + } + + mCurScissor = scissor; + mScissorEnabled = enabled; + } + + mForceSetScissor = false; +} + +bool Renderer11::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + bool ignoreViewport) +{ + gl::Rectangle actualViewport = viewport; + float actualZNear = gl::clamp01(zNear); + float actualZFar = gl::clamp01(zFar); + if (ignoreViewport) + { + actualViewport.x = 0; + actualViewport.y = 0; + actualViewport.width = mRenderTargetDesc.width; + actualViewport.height = mRenderTargetDesc.height; + actualZNear = 0.0f; + actualZFar = 1.0f; + } + + // Get D3D viewport bounds, which depends on the feature level + const Range& viewportBounds = getViewportBounds(); + + // Clamp width and height first to the gl maximum, then clamp further if we extend past the D3D maximum bounds + D3D11_VIEWPORT dxViewport; + dxViewport.TopLeftX = gl::clamp(actualViewport.x, viewportBounds.start, viewportBounds.end); + dxViewport.TopLeftY = gl::clamp(actualViewport.y, viewportBounds.start, viewportBounds.end); + dxViewport.Width = gl::clamp(actualViewport.width, 0, getMaxViewportDimension()); + dxViewport.Height = gl::clamp(actualViewport.height, 0, getMaxViewportDimension()); + dxViewport.Width = std::min((int)dxViewport.Width, viewportBounds.end - static_cast(dxViewport.TopLeftX)); + dxViewport.Height = std::min((int)dxViewport.Height, viewportBounds.end - static_cast(dxViewport.TopLeftY)); + dxViewport.MinDepth = actualZNear; + dxViewport.MaxDepth = actualZFar; + + if (dxViewport.Width <= 0 || dxViewport.Height <= 0) + { + return false; // Nothing to render + } + + bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || + actualZNear != mCurNear || actualZFar != mCurFar; + + if (viewportChanged) + { + mDeviceContext->RSSetViewports(1, &dxViewport); + + mCurViewport = actualViewport; + mCurNear = actualZNear; + mCurFar = actualZFar; + + mPixelConstants.viewCoords[0] = actualViewport.width * 0.5f; + mPixelConstants.viewCoords[1] = actualViewport.height * 0.5f; + mPixelConstants.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); + mPixelConstants.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); + + mPixelConstants.depthFront[0] = (actualZFar - actualZNear) * 0.5f; + mPixelConstants.depthFront[1] = (actualZNear + actualZFar) * 0.5f; + + mVertexConstants.depthRange[0] = actualZNear; + mVertexConstants.depthRange[1] = actualZFar; + mVertexConstants.depthRange[2] = actualZFar - actualZNear; + + mPixelConstants.depthRange[0] = actualZNear; + mPixelConstants.depthRange[1] = actualZFar; + mPixelConstants.depthRange[2] = actualZFar - actualZNear; + } + + mForceSetViewport = false; + return true; +} + +bool Renderer11::applyPrimitiveType(GLenum mode, GLsizei count) +{ + D3D11_PRIMITIVE_TOPOLOGY primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; + + GLsizei minCount = 0; + + switch (mode) + { + case GL_POINTS: primitiveTopology = D3D11_PRIMITIVE_TOPOLOGY_POINTLIST; minCount = 1; break; + case GL_LINES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINELIST; minCount = 2; break; + case GL_LINE_LOOP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; + case GL_LINE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_LINESTRIP; minCount = 2; break; + case GL_TRIANGLES: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; + case GL_TRIANGLE_STRIP: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP; minCount = 3; break; + // emulate fans via rewriting index buffer + case GL_TRIANGLE_FAN: primitiveTopology = D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST; minCount = 3; break; + default: + return gl::error(GL_INVALID_ENUM, false); + } + + if (primitiveTopology != mCurrentPrimitiveTopology) + { + mDeviceContext->IASetPrimitiveTopology(primitiveTopology); + mCurrentPrimitiveTopology = primitiveTopology; + } + + return count >= minCount; +} + +bool Renderer11::applyRenderTarget(gl::Framebuffer *framebuffer) +{ + // Get the color render buffer and serial + // Also extract the render target dimensions and view + unsigned int renderTargetWidth = 0; + unsigned int renderTargetHeight = 0; + GLenum renderTargetFormat = 0; + unsigned int renderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {0}; + ID3D11RenderTargetView* framebufferRTVs[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; + bool missingColorRenderTarget = true; + + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + const GLenum drawBufferState = framebuffer->getDrawBufferState(colorAttachment); + + if (framebuffer->getColorbufferType(colorAttachment) != GL_NONE && drawBufferState != GL_NONE) + { + // the draw buffer must be either "none", "back" for the default buffer or the same index as this color (in order) + ASSERT(drawBufferState == GL_BACK || drawBufferState == (GL_COLOR_ATTACHMENT0_EXT + colorAttachment)); + + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(colorAttachment); + + if (!colorbuffer) + { + ERR("render target pointer unexpectedly null."); + return false; + } + + // check for zero-sized default framebuffer, which is a special case. + // in this case we do not wish to modify any state and just silently return false. + // this will not report any gl error but will cause the calling method to return. + if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0) + { + return false; + } + + renderTargetSerials[colorAttachment] = colorbuffer->getSerial(); + + // Extract the render target dimensions and view + RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + if (!renderTarget) + { + ERR("render target pointer unexpectedly null."); + return false; + } + + framebufferRTVs[colorAttachment] = renderTarget->getRenderTargetView(); + if (!framebufferRTVs[colorAttachment]) + { + ERR("render target view pointer unexpectedly null."); + return false; + } + + if (missingColorRenderTarget) + { + renderTargetWidth = colorbuffer->getWidth(); + renderTargetHeight = colorbuffer->getHeight(); + renderTargetFormat = colorbuffer->getActualFormat(); + missingColorRenderTarget = false; + } + +#ifdef _DEBUG + // Workaround for Debug SETSHADERRESOURCES_HAZARD D3D11 warnings + for (unsigned int vertexSerialIndex = 0; vertexSerialIndex < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; vertexSerialIndex++) + { + if (colorbuffer->getTextureSerial() != 0 && mCurVertexTextureSerials[vertexSerialIndex] == colorbuffer->getTextureSerial()) + { + setTexture(gl::SAMPLER_VERTEX, vertexSerialIndex, NULL); + } + } + + for (unsigned int pixelSerialIndex = 0; pixelSerialIndex < gl::MAX_TEXTURE_IMAGE_UNITS; pixelSerialIndex++) + { + if (colorbuffer->getTextureSerial() != 0 && mCurPixelTextureSerials[pixelSerialIndex] == colorbuffer->getTextureSerial()) + { + setTexture(gl::SAMPLER_PIXEL, pixelSerialIndex, NULL); + } + } +#endif + } + } + + // Get the depth stencil render buffer and serials + gl::Renderbuffer *depthStencil = NULL; + unsigned int depthbufferSerial = 0; + unsigned int stencilbufferSerial = 0; + if (framebuffer->getDepthbufferType() != GL_NONE) + { + depthStencil = framebuffer->getDepthbuffer(); + if (!depthStencil) + { + ERR("Depth stencil pointer unexpectedly null."); + SafeRelease(framebufferRTVs); + return false; + } + + depthbufferSerial = depthStencil->getSerial(); + } + else if (framebuffer->getStencilbufferType() != GL_NONE) + { + depthStencil = framebuffer->getStencilbuffer(); + if (!depthStencil) + { + ERR("Depth stencil pointer unexpectedly null."); + SafeRelease(framebufferRTVs); + return false; + } + + stencilbufferSerial = depthStencil->getSerial(); + } + + // Extract the depth stencil sizes and view + unsigned int depthSize = 0; + unsigned int stencilSize = 0; + ID3D11DepthStencilView* framebufferDSV = NULL; + if (depthStencil) + { + RenderTarget11 *depthStencilRenderTarget = RenderTarget11::makeRenderTarget11(depthStencil->getDepthStencil()); + if (!depthStencilRenderTarget) + { + ERR("render target pointer unexpectedly null."); + SafeRelease(framebufferRTVs); + return false; + } + + framebufferDSV = depthStencilRenderTarget->getDepthStencilView(); + if (!framebufferDSV) + { + ERR("depth stencil view pointer unexpectedly null."); + SafeRelease(framebufferRTVs); + return false; + } + + // If there is no render buffer, the width, height and format values come from + // the depth stencil + if (missingColorRenderTarget) + { + renderTargetWidth = depthStencil->getWidth(); + renderTargetHeight = depthStencil->getHeight(); + renderTargetFormat = depthStencil->getActualFormat(); + } + + depthSize = depthStencil->getDepthSize(); + stencilSize = depthStencil->getStencilSize(); + } + + // Apply the render target and depth stencil + if (!mRenderTargetDescInitialized || !mDepthStencilInitialized || + memcmp(renderTargetSerials, mAppliedRenderTargetSerials, sizeof(renderTargetSerials)) != 0 || + depthbufferSerial != mAppliedDepthbufferSerial || + stencilbufferSerial != mAppliedStencilbufferSerial) + { + mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), framebufferRTVs, framebufferDSV); + + mRenderTargetDesc.width = renderTargetWidth; + mRenderTargetDesc.height = renderTargetHeight; + mRenderTargetDesc.format = renderTargetFormat; + mForceSetViewport = true; + mForceSetScissor = true; + + if (!mDepthStencilInitialized || depthSize != mCurDepthSize) + { + mCurDepthSize = depthSize; + mForceSetRasterState = true; + } + + mCurStencilSize = stencilSize; + + for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) + { + mAppliedRenderTargetSerials[rtIndex] = renderTargetSerials[rtIndex]; + } + mAppliedDepthbufferSerial = depthbufferSerial; + mAppliedStencilbufferSerial = stencilbufferSerial; + mRenderTargetDescInitialized = true; + mDepthStencilInitialized = true; + } + + return true; +} + +GLenum Renderer11::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) +{ + TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; + GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances); + if (err != GL_NO_ERROR) + { + return err; + } + + return mInputLayoutCache.applyVertexBuffers(attributes, programBinary); +} + +GLenum Renderer11::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +{ + GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + + if (err == GL_NO_ERROR) + { + if (indexInfo->storage) + { + if (indexInfo->serial != mAppliedStorageIBSerial || indexInfo->startOffset != mAppliedIBOffset) + { + BufferStorage11 *storage = BufferStorage11::makeBufferStorage11(indexInfo->storage); + IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + + mDeviceContext->IASetIndexBuffer(storage->getBuffer(BUFFER_USAGE_INDEX), indexBuffer->getIndexFormat(), indexInfo->startOffset); + + mAppliedIBSerial = 0; + mAppliedStorageIBSerial = storage->getSerial(); + mAppliedIBOffset = indexInfo->startOffset; + } + } + else if (indexInfo->serial != mAppliedIBSerial || indexInfo->startOffset != mAppliedIBOffset) + { + IndexBuffer11* indexBuffer = IndexBuffer11::makeIndexBuffer11(indexInfo->indexBuffer); + + mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexInfo->startOffset); + + mAppliedIBSerial = indexInfo->serial; + mAppliedStorageIBSerial = 0; + mAppliedIBOffset = indexInfo->startOffset; + } + } + + return err; +} + +void Renderer11::drawArrays(GLenum mode, GLsizei count, GLsizei instances) +{ + if (mode == GL_LINE_LOOP) + { + drawLineLoop(count, GL_NONE, NULL, 0, NULL); + } + else if (mode == GL_TRIANGLE_FAN) + { + drawTriangleFan(count, GL_NONE, NULL, 0, NULL, instances); + } + else if (instances > 0) + { + mDeviceContext->DrawInstanced(count, instances, 0, 0); + } + else + { + mDeviceContext->Draw(count, 0); + } +} + +void Renderer11::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances) +{ + if (mode == GL_LINE_LOOP) + { + drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + } + else if (mode == GL_TRIANGLE_FAN) + { + drawTriangleFan(count, type, indices, indexInfo.minIndex, elementArrayBuffer, instances); + } + else if (instances > 0) + { + mDeviceContext->DrawIndexedInstanced(count, instances, 0, -static_cast(indexInfo.minIndex), 0); + } + else + { + mDeviceContext->DrawIndexed(count, 0, -static_cast(indexInfo.minIndex)); + } +} + +void Renderer11::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +{ + // Get the raw indices for an indexed draw + if (type != GL_NONE && elementArrayBuffer) + { + gl::Buffer *indexBuffer = elementArrayBuffer; + BufferStorage *storage = indexBuffer->getStorage(); + intptr_t offset = reinterpret_cast(indices); + indices = static_cast(storage->getData()) + offset; + } + + if (!mLineLoopIB) + { + mLineLoopIB = new StreamingIndexBufferInterface(this); + if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) + { + delete mLineLoopIB; + mLineLoopIB = NULL; + + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + // Checked by Renderer11::applyPrimitiveType + ASSERT(count >= 0); + + if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) + { + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned int); + if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) + { + ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + void* mappedMemory = NULL; + unsigned int offset; + if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + { + ERR("Could not map index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + unsigned int *data = reinterpret_cast(mappedMemory); + unsigned int indexBufferOffset = offset; + + 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(); + } + + if (!mLineLoopIB->unmapBuffer()) + { + ERR("Could not unmap index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + if (mAppliedIBSerial != mLineLoopIB->getSerial() || mAppliedIBOffset != indexBufferOffset) + { + IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mLineLoopIB->getIndexBuffer()); + + mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); + mAppliedIBSerial = mLineLoopIB->getSerial(); + mAppliedStorageIBSerial = 0; + mAppliedIBOffset = indexBufferOffset; + } + + mDeviceContext->DrawIndexed(count + 1, 0, -minIndex); +} + +void Renderer11::drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances) +{ + // Get the raw indices for an indexed draw + if (type != GL_NONE && elementArrayBuffer) + { + gl::Buffer *indexBuffer = elementArrayBuffer; + BufferStorage *storage = indexBuffer->getStorage(); + intptr_t offset = reinterpret_cast(indices); + indices = static_cast(storage->getData()) + offset; + } + + if (!mTriangleFanIB) + { + mTriangleFanIB = new StreamingIndexBufferInterface(this); + if (!mTriangleFanIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) + { + delete mTriangleFanIB; + mTriangleFanIB = NULL; + + ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + // Checked by Renderer11::applyPrimitiveType + ASSERT(count >= 3); + + const unsigned int numTris = count - 2; + + if (numTris > (std::numeric_limits::max() / (sizeof(unsigned int) * 3))) + { + ERR("Could not create a scratch index buffer for GL_TRIANGLE_FAN, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (numTris * 3) * sizeof(unsigned int); + if (!mTriangleFanIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) + { + ERR("Could not reserve enough space in scratch index buffer for GL_TRIANGLE_FAN."); + return gl::error(GL_OUT_OF_MEMORY); + } + + void* mappedMemory = NULL; + unsigned int offset; + if (!mTriangleFanIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + { + ERR("Could not map scratch index buffer for GL_TRIANGLE_FAN."); + return gl::error(GL_OUT_OF_MEMORY); + } + + unsigned int *data = reinterpret_cast(mappedMemory); + unsigned int indexBufferOffset = offset; + + switch (type) + { + case GL_NONE: // Non-indexed draw + for (unsigned int i = 0; i < numTris; i++) + { + data[i*3 + 0] = 0; + data[i*3 + 1] = i + 1; + data[i*3 + 2] = i + 2; + } + break; + case GL_UNSIGNED_BYTE: + for (unsigned int i = 0; i < numTris; i++) + { + data[i*3 + 0] = static_cast(indices)[0]; + data[i*3 + 1] = static_cast(indices)[i + 1]; + data[i*3 + 2] = static_cast(indices)[i + 2]; + } + break; + case GL_UNSIGNED_SHORT: + for (unsigned int i = 0; i < numTris; i++) + { + data[i*3 + 0] = static_cast(indices)[0]; + data[i*3 + 1] = static_cast(indices)[i + 1]; + data[i*3 + 2] = static_cast(indices)[i + 2]; + } + break; + case GL_UNSIGNED_INT: + for (unsigned int i = 0; i < numTris; i++) + { + data[i*3 + 0] = static_cast(indices)[0]; + data[i*3 + 1] = static_cast(indices)[i + 1]; + data[i*3 + 2] = static_cast(indices)[i + 2]; + } + break; + default: UNREACHABLE(); + } + + if (!mTriangleFanIB->unmapBuffer()) + { + ERR("Could not unmap scratch index buffer for GL_TRIANGLE_FAN."); + return gl::error(GL_OUT_OF_MEMORY); + } + + if (mAppliedIBSerial != mTriangleFanIB->getSerial() || mAppliedIBOffset != indexBufferOffset) + { + IndexBuffer11 *indexBuffer = IndexBuffer11::makeIndexBuffer11(mTriangleFanIB->getIndexBuffer()); + + mDeviceContext->IASetIndexBuffer(indexBuffer->getBuffer(), indexBuffer->getIndexFormat(), indexBufferOffset); + mAppliedIBSerial = mTriangleFanIB->getSerial(); + mAppliedStorageIBSerial = 0; + mAppliedIBOffset = indexBufferOffset; + } + + if (instances > 0) + { + mDeviceContext->DrawIndexedInstanced(numTris * 3, instances, 0, -minIndex, 0); + } + else + { + mDeviceContext->DrawIndexed(numTris * 3, 0, -minIndex); + } +} + +void Renderer11::applyShaders(gl::ProgramBinary *programBinary) +{ + unsigned int programBinarySerial = programBinary->getSerial(); + const bool updateProgramState = (programBinarySerial != mAppliedProgramBinarySerial); + + if (updateProgramState) + { + ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); + ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); + + ID3D11VertexShader *vertexShader = NULL; + if (vertexExe) vertexShader = ShaderExecutable11::makeShaderExecutable11(vertexExe)->getVertexShader(); + + ID3D11PixelShader *pixelShader = NULL; + if (pixelExe) pixelShader = ShaderExecutable11::makeShaderExecutable11(pixelExe)->getPixelShader(); + + mDeviceContext->PSSetShader(pixelShader, NULL, 0); + mDeviceContext->VSSetShader(vertexShader, NULL, 0); + + programBinary->dirtyAllUniforms(); + + mAppliedProgramBinarySerial = programBinarySerial; + } + + // Only use the geometry shader currently for point sprite drawing + const bool usesGeometryShader = (programBinary->usesGeometryShader() && mCurRasterState.pointDrawMode); + + if (updateProgramState || usesGeometryShader != mIsGeometryShaderActive) + { + if (usesGeometryShader) + { + ShaderExecutable *geometryExe = programBinary->getGeometryExecutable(); + ID3D11GeometryShader *geometryShader = ShaderExecutable11::makeShaderExecutable11(geometryExe)->getGeometryShader(); + mDeviceContext->GSSetShader(geometryShader, NULL, 0); + } + else + { + mDeviceContext->GSSetShader(NULL, NULL, 0); + } + + mIsGeometryShaderActive = usesGeometryShader; + } +} + +void Renderer11::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) +{ + ShaderExecutable11 *vertexExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getVertexExecutable()); + ShaderExecutable11 *pixelExecutable = ShaderExecutable11::makeShaderExecutable11(programBinary->getPixelExecutable()); + + unsigned int totalRegisterCountVS = 0; + unsigned int totalRegisterCountPS = 0; + + bool vertexUniformsDirty = false; + bool pixelUniformsDirty = false; + + for (gl::UniformArray::const_iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) + { + const gl::Uniform *uniform = *uniform_iterator; + + if (uniform->vsRegisterIndex >= 0) + { + totalRegisterCountVS += uniform->registerCount; + vertexUniformsDirty = vertexUniformsDirty || uniform->dirty; + } + + if (uniform->psRegisterIndex >= 0) + { + totalRegisterCountPS += uniform->registerCount; + pixelUniformsDirty = pixelUniformsDirty || uniform->dirty; + } + } + + ID3D11Buffer *vertexConstantBuffer = vertexExecutable->getConstantBuffer(mDevice, totalRegisterCountVS); + ID3D11Buffer *pixelConstantBuffer = pixelExecutable->getConstantBuffer(mDevice, totalRegisterCountPS); + + float (*mapVS)[4] = NULL; + float (*mapPS)[4] = NULL; + + if (totalRegisterCountVS > 0 && vertexUniformsDirty) + { + D3D11_MAPPED_SUBRESOURCE map = {0}; + HRESULT result = mDeviceContext->Map(vertexConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + ASSERT(SUCCEEDED(result)); + mapVS = (float(*)[4])map.pData; + } + + if (totalRegisterCountPS > 0 && pixelUniformsDirty) + { + D3D11_MAPPED_SUBRESOURCE map = {0}; + HRESULT result = mDeviceContext->Map(pixelConstantBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &map); + ASSERT(SUCCEEDED(result)); + mapPS = (float(*)[4])map.pData; + } + + for (gl::UniformArray::iterator uniform_iterator = uniformArray->begin(); uniform_iterator != uniformArray->end(); uniform_iterator++) + { + gl::Uniform *uniform = *uniform_iterator; + + if (uniform->type != GL_SAMPLER_2D && uniform->type != GL_SAMPLER_CUBE) + { + if (uniform->vsRegisterIndex >= 0 && mapVS) + { + memcpy(mapVS + uniform->vsRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4])); + } + + if (uniform->psRegisterIndex >= 0 && mapPS) + { + memcpy(mapPS + uniform->psRegisterIndex, uniform->data, uniform->registerCount * sizeof(float[4])); + } + } + + uniform->dirty = false; + } + + if (mapVS) + { + mDeviceContext->Unmap(vertexConstantBuffer, 0); + } + + if (mapPS) + { + mDeviceContext->Unmap(pixelConstantBuffer, 0); + } + + if (mCurrentVertexConstantBuffer != vertexConstantBuffer) + { + mDeviceContext->VSSetConstantBuffers(0, 1, &vertexConstantBuffer); + mCurrentVertexConstantBuffer = vertexConstantBuffer; + } + + if (mCurrentPixelConstantBuffer != pixelConstantBuffer) + { + mDeviceContext->PSSetConstantBuffers(0, 1, &pixelConstantBuffer); + mCurrentPixelConstantBuffer = pixelConstantBuffer; + } + + // Driver uniforms + if (!mDriverConstantBufferVS) + { + D3D11_BUFFER_DESC constantBufferDescription = {0}; + constantBufferDescription.ByteWidth = sizeof(dx_VertexConstants); + constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; + constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDescription.CPUAccessFlags = 0; + constantBufferDescription.MiscFlags = 0; + constantBufferDescription.StructureByteStride = 0; + + HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferVS); + ASSERT(SUCCEEDED(result)); + + mDeviceContext->VSSetConstantBuffers(1, 1, &mDriverConstantBufferVS); + } + + if (!mDriverConstantBufferPS) + { + D3D11_BUFFER_DESC constantBufferDescription = {0}; + constantBufferDescription.ByteWidth = sizeof(dx_PixelConstants); + constantBufferDescription.Usage = D3D11_USAGE_DEFAULT; + constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDescription.CPUAccessFlags = 0; + constantBufferDescription.MiscFlags = 0; + constantBufferDescription.StructureByteStride = 0; + + HRESULT result = mDevice->CreateBuffer(&constantBufferDescription, NULL, &mDriverConstantBufferPS); + ASSERT(SUCCEEDED(result)); + + mDeviceContext->PSSetConstantBuffers(1, 1, &mDriverConstantBufferPS); + } + + if (memcmp(&mVertexConstants, &mAppliedVertexConstants, sizeof(dx_VertexConstants)) != 0) + { + mDeviceContext->UpdateSubresource(mDriverConstantBufferVS, 0, NULL, &mVertexConstants, 16, 0); + memcpy(&mAppliedVertexConstants, &mVertexConstants, sizeof(dx_VertexConstants)); + } + + if (memcmp(&mPixelConstants, &mAppliedPixelConstants, sizeof(dx_PixelConstants)) != 0) + { + mDeviceContext->UpdateSubresource(mDriverConstantBufferPS, 0, NULL, &mPixelConstants, 16, 0); + memcpy(&mAppliedPixelConstants, &mPixelConstants, sizeof(dx_PixelConstants)); + } + + // needed for the point sprite geometry shader + if (mFeatureLevel >= D3D_FEATURE_LEVEL_10_0 && mCurrentGeometryConstantBuffer != mDriverConstantBufferPS) + { + mDeviceContext->GSSetConstantBuffers(0, 1, &mDriverConstantBufferPS); + mCurrentGeometryConstantBuffer = mDriverConstantBufferPS; + } +} + +void Renderer11::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +{ + gl::Renderbuffer *firstRenderbuffer = frameBuffer->getFirstColorbuffer(); + GLenum internalFormat = firstRenderbuffer ? firstRenderbuffer->getInternalFormat() : GL_NONE; + + bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) && + ((!clearParams.colorMaskRed && gl::GetRedSize(internalFormat) > 0) || + (!clearParams.colorMaskGreen && gl::GetGreenSize(internalFormat) > 0) || + (!clearParams.colorMaskBlue && gl::GetBlueSize(internalFormat) > 0) || + (!clearParams.colorMaskAlpha && gl::GetAlphaSize(internalFormat) > 0)); + + unsigned int stencilUnmasked = 0x0; + if (frameBuffer->hasStencil()) + { + unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat()); + stencilUnmasked = (0x1 << stencilSize) - 1; + } + bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + + bool needScissoredClear = mScissorEnabled && (mCurScissor.x > 0 || mCurScissor.y > 0 || + mCurScissor.x + mCurScissor.width < mRenderTargetDesc.width || + mCurScissor.y + mCurScissor.height < mRenderTargetDesc.height); + + if (needMaskedColorClear || needMaskedStencilClear || needScissoredClear) + { + maskedClear(clearParams, frameBuffer); + } + else + { + if (clearParams.mask & GL_COLOR_BUFFER_BIT) + { + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + if (frameBuffer->isEnabledColorAttachment(colorAttachment)) + { + gl::Renderbuffer *renderbufferObject = frameBuffer->getColorbuffer(colorAttachment); + if (renderbufferObject) + { + RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getRenderTarget()); + if (!renderTarget) + { + ERR("render target pointer unexpectedly null."); + return; + } + + ID3D11RenderTargetView *framebufferRTV = renderTarget->getRenderTargetView(); + if (!framebufferRTV) + { + ERR("render target view pointer unexpectedly null."); + return; + } + + GLenum format = renderbufferObject->getInternalFormat(); + + const float clearValues[4] = { (gl::GetRedSize(format) > 0) ? clearParams.colorClearValue.red : 0.0f, + (gl::GetGreenSize(format) > 0) ? clearParams.colorClearValue.green : 0.0f, + (gl::GetBlueSize(format) > 0) ? clearParams.colorClearValue.blue : 0.0f, + (gl::GetAlphaSize(format) > 0) ? clearParams.colorClearValue.alpha : 1.0f }; + mDeviceContext->ClearRenderTargetView(framebufferRTV, clearValues); + } + } + } + } + if (clearParams.mask & GL_DEPTH_BUFFER_BIT || clearParams.mask & GL_STENCIL_BUFFER_BIT) + { + gl::Renderbuffer *renderbufferObject = frameBuffer->getDepthOrStencilbuffer(); + if (renderbufferObject) + { + RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(renderbufferObject->getDepthStencil()); + if (!renderTarget) + { + ERR("render target pointer unexpectedly null."); + return; + } + + ID3D11DepthStencilView *framebufferDSV = renderTarget->getDepthStencilView(); + if (!framebufferDSV) + { + ERR("depth stencil view pointer unexpectedly null."); + return; + } + + UINT clearFlags = 0; + if (clearParams.mask & GL_DEPTH_BUFFER_BIT) + { + clearFlags |= D3D11_CLEAR_DEPTH; + } + if (clearParams.mask & GL_STENCIL_BUFFER_BIT) + { + clearFlags |= D3D11_CLEAR_STENCIL; + } + + float depthClear = gl::clamp01(clearParams.depthClearValue); + UINT8 stencilClear = clearParams.stencilClearValue & 0x000000FF; + + mDeviceContext->ClearDepthStencilView(framebufferDSV, clearFlags, depthClear, stencilClear); + } + } + } +} + +void Renderer11::maskedClear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +{ + HRESULT result; + + if (!mClearResourcesInitialized) + { + ASSERT(!mClearVB && !mClearVS && !mClearSinglePS && !mClearMultiplePS && !mClearScissorRS && !mClearNoScissorRS); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = sizeof(d3d11::PositionDepthColorVertex) * 4; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + result = mDevice->CreateBuffer(&vbDesc, NULL, &mClearVB); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearVB, "Renderer11 masked clear vertex buffer"); + + D3D11_INPUT_ELEMENT_DESC quadLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32B32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "COLOR", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 12, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Clear, sizeof(g_VS_Clear), &mClearIL); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearIL, "Renderer11 masked clear input layout"); + + result = mDevice->CreateVertexShader(g_VS_Clear, sizeof(g_VS_Clear), NULL, &mClearVS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearVS, "Renderer11 masked clear vertex shader"); + + result = mDevice->CreatePixelShader(g_PS_ClearSingle, sizeof(g_PS_ClearSingle), NULL, &mClearSinglePS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearSinglePS, "Renderer11 masked clear pixel shader (1 RT)"); + + result = mDevice->CreatePixelShader(g_PS_ClearMultiple, sizeof(g_PS_ClearMultiple), NULL, &mClearMultiplePS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearMultiplePS, "Renderer11 masked clear pixel shader (MRT)"); + + D3D11_RASTERIZER_DESC rsScissorDesc; + rsScissorDesc.FillMode = D3D11_FILL_SOLID; + rsScissorDesc.CullMode = D3D11_CULL_NONE; + rsScissorDesc.FrontCounterClockwise = FALSE; + rsScissorDesc.DepthBias = 0; + rsScissorDesc.DepthBiasClamp = 0.0f; + rsScissorDesc.SlopeScaledDepthBias = 0.0f; + rsScissorDesc.DepthClipEnable = FALSE; + rsScissorDesc.ScissorEnable = TRUE; + rsScissorDesc.MultisampleEnable = FALSE; + rsScissorDesc.AntialiasedLineEnable = FALSE; + + result = mDevice->CreateRasterizerState(&rsScissorDesc, &mClearScissorRS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearScissorRS, "Renderer11 masked clear scissor rasterizer state"); + + D3D11_RASTERIZER_DESC rsNoScissorDesc; + rsNoScissorDesc.FillMode = D3D11_FILL_SOLID; + rsNoScissorDesc.CullMode = D3D11_CULL_NONE; + rsNoScissorDesc.FrontCounterClockwise = FALSE; + rsNoScissorDesc.DepthBias = 0; + rsNoScissorDesc.DepthBiasClamp = 0.0f; + rsNoScissorDesc.SlopeScaledDepthBias = 0.0f; + rsNoScissorDesc.DepthClipEnable = FALSE; + rsNoScissorDesc.ScissorEnable = FALSE; + rsNoScissorDesc.MultisampleEnable = FALSE; + rsNoScissorDesc.AntialiasedLineEnable = FALSE; + + result = mDevice->CreateRasterizerState(&rsNoScissorDesc, &mClearNoScissorRS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mClearNoScissorRS, "Renderer11 masked clear no scissor rasterizer state"); + + mClearResourcesInitialized = true; + } + + // Prepare the depth stencil state to write depth values if the depth should be cleared + // and stencil values if the stencil should be cleared + gl::DepthStencilState glDSState; + glDSState.depthTest = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0; + glDSState.depthFunc = GL_ALWAYS; + glDSState.depthMask = (clearParams.mask & GL_DEPTH_BUFFER_BIT) != 0; + glDSState.stencilTest = (clearParams.mask & GL_STENCIL_BUFFER_BIT) != 0; + glDSState.stencilFunc = GL_ALWAYS; + glDSState.stencilMask = 0; + glDSState.stencilFail = GL_REPLACE; + glDSState.stencilPassDepthFail = GL_REPLACE; + glDSState.stencilPassDepthPass = GL_REPLACE; + glDSState.stencilWritemask = clearParams.stencilWriteMask; + glDSState.stencilBackFunc = GL_ALWAYS; + glDSState.stencilBackMask = 0; + glDSState.stencilBackFail = GL_REPLACE; + glDSState.stencilBackPassDepthFail = GL_REPLACE; + glDSState.stencilBackPassDepthPass = GL_REPLACE; + glDSState.stencilBackWritemask = clearParams.stencilWriteMask; + + int stencilClear = clearParams.stencilClearValue & 0x000000FF; + + ID3D11DepthStencilState *dsState = mStateCache.getDepthStencilState(glDSState); + + // Prepare the blend state to use a write mask if the color buffer should be cleared + gl::BlendState glBlendState; + glBlendState.blend = false; + glBlendState.sourceBlendRGB = GL_ONE; + glBlendState.destBlendRGB = GL_ZERO; + glBlendState.sourceBlendAlpha = GL_ONE; + glBlendState.destBlendAlpha = GL_ZERO; + glBlendState.blendEquationRGB = GL_FUNC_ADD; + glBlendState.blendEquationAlpha = GL_FUNC_ADD; + glBlendState.colorMaskRed = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskRed : false; + glBlendState.colorMaskGreen = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskGreen : false; + glBlendState.colorMaskBlue = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskBlue : false; + glBlendState.colorMaskAlpha = (clearParams.mask & GL_COLOR_BUFFER_BIT) ? clearParams.colorMaskAlpha : false; + glBlendState.sampleAlphaToCoverage = false; + glBlendState.dither = false; + + static const float blendFactors[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + static const UINT sampleMask = 0xFFFFFFFF; + + ID3D11BlendState *blendState = mStateCache.getBlendState(frameBuffer, glBlendState); + + // Set the vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = mDeviceContext->Map(mClearVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map masked clear vertex buffer, HRESULT: 0x%X.", result); + return; + } + + d3d11::PositionDepthColorVertex *vertices = reinterpret_cast(mappedResource.pData); + + float depthClear = gl::clamp01(clearParams.depthClearValue); + d3d11::SetPositionDepthColorVertex(&vertices[0], -1.0f, 1.0f, depthClear, clearParams.colorClearValue); + d3d11::SetPositionDepthColorVertex(&vertices[1], -1.0f, -1.0f, depthClear, clearParams.colorClearValue); + d3d11::SetPositionDepthColorVertex(&vertices[2], 1.0f, 1.0f, depthClear, clearParams.colorClearValue); + d3d11::SetPositionDepthColorVertex(&vertices[3], 1.0f, -1.0f, depthClear, clearParams.colorClearValue); + + mDeviceContext->Unmap(mClearVB, 0); + + // Apply state + mDeviceContext->OMSetBlendState(blendState, blendFactors, sampleMask); + mDeviceContext->OMSetDepthStencilState(dsState, stencilClear); + mDeviceContext->RSSetState(mScissorEnabled ? mClearScissorRS : mClearNoScissorRS); + + // Apply shaders + ID3D11PixelShader *pixelShader = frameBuffer->usingExtendedDrawBuffers() ? mClearMultiplePS : mClearSinglePS; + + mDeviceContext->IASetInputLayout(mClearIL); + mDeviceContext->VSSetShader(mClearVS, NULL, 0); + mDeviceContext->PSSetShader(pixelShader, NULL, 0); + mDeviceContext->GSSetShader(NULL, NULL, 0); + + // Apply vertex buffer + static UINT stride = sizeof(d3d11::PositionDepthColorVertex); + static UINT startIdx = 0; + mDeviceContext->IASetVertexBuffers(0, 1, &mClearVB, &stride, &startIdx); + mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + + // Draw the clear quad + mDeviceContext->Draw(4, 0); + + // Clean up + markAllStateDirty(); +} + +void Renderer11::markAllStateDirty() +{ + for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) + { + mAppliedRenderTargetSerials[rtIndex] = 0; + } + mAppliedDepthbufferSerial = 0; + mAppliedStencilbufferSerial = 0; + mDepthStencilInitialized = false; + mRenderTargetDescInitialized = false; + + for (int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) + { + mForceSetVertexSamplerStates[i] = true; + mCurVertexTextureSerials[i] = 0; + } + for (int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) + { + mForceSetPixelSamplerStates[i] = true; + mCurPixelTextureSerials[i] = 0; + } + + mForceSetBlendState = true; + mForceSetRasterState = true; + mForceSetDepthStencilState = true; + mForceSetScissor = true; + mForceSetViewport = true; + + mAppliedIBSerial = 0; + mAppliedStorageIBSerial = 0; + mAppliedIBOffset = 0; + + mAppliedProgramBinarySerial = 0; + memset(&mAppliedVertexConstants, 0, sizeof(dx_VertexConstants)); + memset(&mAppliedPixelConstants, 0, sizeof(dx_PixelConstants)); + + mInputLayoutCache.markDirty(); + + mCurrentVertexConstantBuffer = NULL; + mCurrentPixelConstantBuffer = NULL; + mCurrentGeometryConstantBuffer = NULL; + + mCurrentPrimitiveTopology = D3D_PRIMITIVE_TOPOLOGY_UNDEFINED; +} + +void Renderer11::releaseDeviceResources() +{ + mStateCache.clear(); + mInputLayoutCache.clear(); + + delete mVertexDataManager; + mVertexDataManager = NULL; + + delete mIndexDataManager; + mIndexDataManager = NULL; + + delete mLineLoopIB; + mLineLoopIB = NULL; + + delete mTriangleFanIB; + mTriangleFanIB = NULL; + + SafeRelease(mCopyVB); + SafeRelease(mCopySampler); + SafeRelease(mCopyIL); + SafeRelease(mCopyIL); + SafeRelease(mCopyVS); + SafeRelease(mCopyRGBAPS); + SafeRelease(mCopyRGBPS); + SafeRelease(mCopyLumPS); + SafeRelease(mCopyLumAlphaPS); + + mCopyResourcesInitialized = false; + + SafeRelease(mClearVB); + SafeRelease(mClearIL); + SafeRelease(mClearVS); + SafeRelease(mClearSinglePS); + SafeRelease(mClearMultiplePS); + SafeRelease(mClearScissorRS); + SafeRelease(mClearNoScissorRS); + + mClearResourcesInitialized = false; + + SafeRelease(mDriverConstantBufferVS); + SafeRelease(mDriverConstantBufferPS); + SafeRelease(mSyncQuery); +} + +void Renderer11::notifyDeviceLost() +{ + mDeviceLost = true; + mDisplay->notifyDeviceLost(); +} + +bool Renderer11::isDeviceLost() +{ + return mDeviceLost; +} + +// set notify to true to broadcast a message to all contexts of the device loss +bool Renderer11::testDeviceLost(bool notify) +{ + bool isLost = false; + + // GetRemovedReason is used to test if the device is removed + HRESULT result = mDevice->GetDeviceRemovedReason(); + isLost = d3d11::isDeviceLostError(result); + + if (isLost) + { + // Log error if this is a new device lost event + if (mDeviceLost == false) + { + ERR("The D3D11 device was removed: 0x%08X", result); + } + + // 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; + if (notify) + { + notifyDeviceLost(); + } + } + + return isLost; +} + +bool Renderer11::testDeviceResettable() +{ + // determine if the device is resettable by creating a dummy device + PFN_D3D11_CREATE_DEVICE D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(mD3d11Module, "D3D11CreateDevice"); + + if (D3D11CreateDevice == NULL) + { + return false; + } + + D3D_FEATURE_LEVEL featureLevels[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, +#if !defined(ANGLE_ENABLE_D3D9) + D3D_FEATURE_LEVEL_9_3, + D3D_FEATURE_LEVEL_9_2, + D3D_FEATURE_LEVEL_9_1, +#endif + }; + + ID3D11Device* dummyDevice; + D3D_FEATURE_LEVEL dummyFeatureLevel; + ID3D11DeviceContext* dummyContext; + + HRESULT result = D3D11CreateDevice(NULL, + D3D_DRIVER_TYPE_HARDWARE, + NULL, + #if defined(_DEBUG) + D3D11_CREATE_DEVICE_DEBUG, + #else + 0, + #endif + featureLevels, + ArraySize(featureLevels), + D3D11_SDK_VERSION, + &dummyDevice, + &dummyFeatureLevel, + &dummyContext); + + if (!mDevice || FAILED(result)) + { + return false; + } + + dummyContext->Release(); + dummyDevice->Release(); + + return true; +} + +void Renderer11::release() +{ + releaseDeviceResources(); + + if (mDxgiFactory) + { + mDxgiFactory->Release(); + mDxgiFactory = NULL; + } + + if (mDxgiAdapter) + { + mDxgiAdapter->Release(); + mDxgiAdapter = NULL; + } + + if (mDeviceContext) + { + mDeviceContext->ClearState(); + mDeviceContext->Flush(); + mDeviceContext->Release(); + mDeviceContext = NULL; + } + + if (mDevice) + { + mDevice->Release(); + mDevice = NULL; + } + + if (mD3d11Module) + { + FreeLibrary(mD3d11Module); + mD3d11Module = NULL; + } + + if (mDxgiModule) + { + FreeLibrary(mDxgiModule); + mDxgiModule = NULL; + } +} + +bool Renderer11::resetDevice() +{ + // recreate everything + release(); + EGLint result = initialize(); + + if (result != EGL_SUCCESS) + { + ERR("Could not reinitialize D3D11 device: %08X", result); + return false; + } + + mDeviceLost = false; + + return true; +} + +DWORD Renderer11::getAdapterVendor() const +{ + return mAdapterDescription.VendorId; +} + +std::string Renderer11::getRendererDescription() const +{ + std::ostringstream rendererString; + + rendererString << mDescription; + rendererString << " Direct3D11"; + + rendererString << " vs_" << getMajorShaderModel() << "_" << getMinorShaderModel(); + rendererString << " ps_" << getMajorShaderModel() << "_" << getMinorShaderModel(); + + return rendererString.str(); +} + +GUID Renderer11::getAdapterIdentifier() const +{ + // Use the adapter LUID as our adapter ID + // This number is local to a machine is only guaranteed to be unique between restarts + META_ASSERT(sizeof(LUID) <= sizeof(GUID)); + GUID adapterId = {0}; + memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID)); + return adapterId; +} + +bool Renderer11::getBGRATextureSupport() const +{ + return mBGRATextureSupport; +} + +bool Renderer11::getDXT1TextureSupport() +{ + return mDXT1TextureSupport; +} + +bool Renderer11::getDXT3TextureSupport() +{ + return mDXT3TextureSupport; +} + +bool Renderer11::getDXT5TextureSupport() +{ + return mDXT5TextureSupport; +} + +bool Renderer11::getDepthTextureSupport() const +{ + return mDepthTextureSupport; +} + +bool Renderer11::getFloat32TextureSupport(bool *filtering, bool *renderable) +{ + *renderable = mFloat32RenderSupport; + *filtering = mFloat32FilterSupport; + return mFloat32TextureSupport; +} + +bool Renderer11::getFloat16TextureSupport(bool *filtering, bool *renderable) +{ + *renderable = mFloat16RenderSupport; + *filtering = mFloat16FilterSupport; + return mFloat16TextureSupport; +} + +bool Renderer11::getLuminanceTextureSupport() +{ + return false; +} + +bool Renderer11::getLuminanceAlphaTextureSupport() +{ + return false; +} + +bool Renderer11::getTextureFilterAnisotropySupport() const +{ + return true; +} + +float Renderer11::getTextureMaxAnisotropy() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_MAX_MAXANISOTROPY; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_MAX_MAXANISOTROPY; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return 16; + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_DEFAULT_MAX_ANISOTROPY; + default: UNREACHABLE(); + return 0; + } +} + +bool Renderer11::getEventQuerySupport() +{ + return true; +} + +Range Renderer11::getViewportBounds() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return Range(D3D11_VIEWPORT_BOUNDS_MIN, D3D11_VIEWPORT_BOUNDS_MAX); + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return Range(D3D10_VIEWPORT_BOUNDS_MIN, D3D10_VIEWPORT_BOUNDS_MAX); + case D3D_FEATURE_LEVEL_9_3: + return Range(D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2); + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return Range(D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * -2, D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2); + default: UNREACHABLE(); + return Range(0, 0); + } +} + +unsigned int Renderer11::getMaxVertexTextureImageUnits() const +{ + META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM4 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return MAX_TEXTURE_IMAGE_UNITS_VTF_SM4; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 0; + default: UNREACHABLE(); + return 0; + } +} + +unsigned int Renderer11::getMaxCombinedTextureImageUnits() const +{ + return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); +} + +unsigned int Renderer11::getReservedVertexUniformVectors() const +{ + return 0; // Driver uniforms are stored in a separate constant buffer +} + +unsigned int Renderer11::getReservedFragmentUniformVectors() const +{ + return 0; // Driver uniforms are stored in a separate constant buffer +} + +unsigned int Renderer11::getMaxVertexUniformVectors() const +{ + META_ASSERT(MAX_VERTEX_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); + ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_9_1); + return MAX_VERTEX_UNIFORM_VECTORS_D3D11; +} + +unsigned int Renderer11::getMaxFragmentUniformVectors() const +{ + META_ASSERT(MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 <= D3D10_REQ_CONSTANT_BUFFER_ELEMENT_COUNT); + ASSERT(mFeatureLevel >= D3D_FEATURE_LEVEL_9_1); + return MAX_FRAGMENT_UNIFORM_VECTORS_D3D11; +} + +unsigned int Renderer11::getMaxVaryingVectors() const +{ + META_ASSERT(gl::IMPLEMENTATION_MAX_VARYING_VECTORS == D3D11_VS_OUTPUT_REGISTER_COUNT); + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_VS_OUTPUT_REGISTER_COUNT; + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_VS_OUTPUT_REGISTER_COUNT; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return 8; + default: UNREACHABLE(); + return 0; + } +} + +bool Renderer11::getNonPower2TextureSupport() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + default: UNREACHABLE(); + return false; + } +} + +bool Renderer11::getOcclusionQuerySupport() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + return true; + case D3D_FEATURE_LEVEL_9_1: + return false; + default: UNREACHABLE(); + return false; + } +} + +bool Renderer11::getInstancingSupport() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: + return true; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + default: UNREACHABLE(); + return false; + } +} + +bool Renderer11::getShareHandleSupport() const +{ + // We only currently support share handles with BGRA surfaces, because + // chrome needs BGRA. Once chrome fixes this, we should always support them. + // PIX doesn't seem to support using share handles, so disable them. + return getBGRATextureSupport() && !gl::perfActive(); +} + +bool Renderer11::getDerivativeInstructionSupport() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return true; + case D3D_FEATURE_LEVEL_9_3: + return true; + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return false; + default: UNREACHABLE(); + return false; + } +} + +bool Renderer11::getPostSubBufferSupport() const +{ + // D3D11 does not support present with dirty rectangles until D3D11.1 and DXGI 1.2. + return false; +} + +int Renderer11::getMajorShaderModel() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MAJOR_VERSION; // 5 + case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MAJOR_VERSION; // 4 + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MAJOR_VERSION; // 4 (level 9) + default: UNREACHABLE(); return 0; + } +} + +int Renderer11::getMinorShaderModel() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: return D3D11_SHADER_MINOR_VERSION; // 0 + case D3D_FEATURE_LEVEL_10_1: return D3D10_1_SHADER_MINOR_VERSION; // 1 + case D3D_FEATURE_LEVEL_10_0: return D3D10_SHADER_MINOR_VERSION; // 0 + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return D3D10_SHADER_MINOR_VERSION; // 0 (level 9) + default: UNREACHABLE(); return 0; + } +} + +float Renderer11::getMaxPointSize() const +{ + // choose a reasonable maximum. we enforce this in the shader. + // (nb: on a Radeon 2600xt, DX9 reports a 256 max point size) + return 1024.0f; +} + +int Renderer11::getMaxViewportDimension() const +{ + // Maximum viewport size must be at least as large as the largest render buffer (or larger). + // In our case return the maximum texture size, which is the maximum render buffer size. + META_ASSERT(D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D11_VIEWPORT_BOUNDS_MAX); + META_ASSERT(D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION * 2 - 1 <= D3D10_VIEWPORT_BOUNDS_MAX); + + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384 + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192 + case D3D_FEATURE_LEVEL_9_3: + return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096 + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: + return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048 + default: UNREACHABLE(); + return 0; + } +} + +int Renderer11::getMaxTextureWidth() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384 + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192 + case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096 + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048 + default: UNREACHABLE(); return 0; + } +} + +int Renderer11::getMaxTextureHeight() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: return D3D11_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 16384 + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 8192 + case D3D_FEATURE_LEVEL_9_3: return D3D_FL9_3_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 4096 + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return D3D_FL9_1_REQ_TEXTURE2D_U_OR_V_DIMENSION; // 2048 + default: UNREACHABLE(); return 0; + } +} + +bool Renderer11::get32BitIndexSupport() const +{ + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: return D3D10_REQ_DRAWINDEXED_INDEX_COUNT_2_TO_EXP >= 32; // true + case D3D_FEATURE_LEVEL_9_3: + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: return false; + default: UNREACHABLE(); return false; + } +} + +int Renderer11::getMinSwapInterval() const +{ + return 0; +} + +int Renderer11::getMaxSwapInterval() const +{ + return 4; +} + +int Renderer11::getMaxSupportedSamples() const +{ + return mMaxSupportedSamples; +} + +int Renderer11::getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const +{ + if (requested == 0) + { + return 0; + } + + MultisampleSupportMap::const_iterator iter = mMultisampleSupportMap.find(format); + if (iter != mMultisampleSupportMap.end()) + { + const MultisampleSupportInfo& info = iter->second; + for (unsigned int i = requested - 1; i < D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT; i++) + { + if (info.qualityLevels[i] > 0) + { + return i + 1; + } + } + } + + return -1; +} + +unsigned int Renderer11::getMaxRenderTargets() const +{ + META_ASSERT(D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); + META_ASSERT(D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); + META_ASSERT(D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); + META_ASSERT(D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT <= gl::IMPLEMENTATION_MAX_DRAW_BUFFERS); + + switch (mFeatureLevel) + { + case D3D_FEATURE_LEVEL_11_0: + return D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT; // 8 + case D3D_FEATURE_LEVEL_10_1: + case D3D_FEATURE_LEVEL_10_0: + case D3D_FEATURE_LEVEL_9_3: // return D3D_FL9_3_SIMULTANEOUS_RENDER_TARGET_COUNT; // 4 + case D3D_FEATURE_LEVEL_9_2: + case D3D_FEATURE_LEVEL_9_1: // return D3D_FL9_1_SIMULTANEOUS_RENDER_TARGET_COUNT; // 1 + // Feature level 10.0 and 10.1 cards perform very poorly when the pixel shader + // outputs to multiple RTs that are not bound. + // TODO: Remove pixel shader outputs for render targets that are not bound. + return 1; + default: + UNREACHABLE(); + return 1; + } +} + +bool Renderer11::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) +{ + if (source && dest) + { + TextureStorage11_2D *source11 = TextureStorage11_2D::makeTextureStorage11_2D(source->getStorageInstance()); + TextureStorage11_2D *dest11 = TextureStorage11_2D::makeTextureStorage11_2D(dest->getStorageInstance()); + + mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture()); + return true; + } + + return false; +} + +bool Renderer11::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) +{ + if (source && dest) + { + TextureStorage11_Cube *source11 = TextureStorage11_Cube::makeTextureStorage11_Cube(source->getStorageInstance()); + TextureStorage11_Cube *dest11 = TextureStorage11_Cube::makeTextureStorage11_Cube(dest->getStorageInstance()); + + mDeviceContext->CopyResource(dest11->getBaseTexture(), source11->getBaseTexture()); + return true; + } + + return false; +} + +bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +{ + gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); + if (!colorbuffer) + { + ERR("Failed to retrieve the color buffer from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + if (!sourceRenderTarget) + { + ERR("Failed to retrieve the render target from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + if (!source) + { + ERR("Failed to retrieve the render target view from the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + TextureStorage11_2D *storage11 = TextureStorage11_2D::makeTextureStorage11_2D(storage->getStorageInstance()); + if (!storage11) + { + ERR("Failed to retrieve the texture storage from the destination."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(level)); + if (!destRenderTarget) + { + ERR("Failed to retrieve the render target from the destination storage."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); + if (!dest) + { + ERR("Failed to retrieve the render target view from the destination render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + gl::Rectangle destRect; + destRect.x = xoffset; + destRect.y = yoffset; + destRect.width = sourceRect.width; + destRect.height = sourceRect.height; + + bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), + dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); + + return ret; +} + +bool Renderer11::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +{ + gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); + if (!colorbuffer) + { + ERR("Failed to retrieve the color buffer from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget11 *sourceRenderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + if (!sourceRenderTarget) + { + ERR("Failed to retrieve the render target from the frame buffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11ShaderResourceView *source = sourceRenderTarget->getShaderResourceView(); + if (!source) + { + ERR("Failed to retrieve the render target view from the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + TextureStorage11_Cube *storage11 = TextureStorage11_Cube::makeTextureStorage11_Cube(storage->getStorageInstance()); + if (!storage11) + { + ERR("Failed to retrieve the texture storage from the destination."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget11 *destRenderTarget = RenderTarget11::makeRenderTarget11(storage11->getRenderTarget(target, level)); + if (!destRenderTarget) + { + ERR("Failed to retrieve the render target from the destination storage."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11RenderTargetView *dest = destRenderTarget->getRenderTargetView(); + if (!dest) + { + ERR("Failed to retrieve the render target view from the destination render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + gl::Rectangle destRect; + destRect.x = xoffset; + destRect.y = yoffset; + destRect.width = sourceRect.width; + destRect.height = sourceRect.height; + + bool ret = copyTexture(source, sourceRect, sourceRenderTarget->getWidth(), sourceRenderTarget->getHeight(), + dest, destRect, destRenderTarget->getWidth(), destRenderTarget->getHeight(), destFormat); + + return ret; +} + +bool Renderer11::copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, + ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat) +{ + HRESULT result; + + if (!mCopyResourcesInitialized) + { + ASSERT(!mCopyVB && !mCopySampler && !mCopyIL && !mCopyVS && !mCopyRGBAPS && !mCopyRGBPS && !mCopyLumPS && !mCopyLumAlphaPS); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + result = mDevice->CreateBuffer(&vbDesc, NULL, &mCopyVB); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyVB, "Renderer11 copy texture vertex buffer"); + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_LINEAR; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 0; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + samplerDesc.BorderColor[0] = 0.0f; + samplerDesc.BorderColor[1] = 0.0f; + samplerDesc.BorderColor[2] = 0.0f; + samplerDesc.BorderColor[3] = 0.0f; + samplerDesc.MinLOD = 0.0f; + samplerDesc.MaxLOD = mDevice->GetFeatureLevel() >= D3D_FEATURE_LEVEL_10_0 ? 0.0f : FLT_MAX; + + result = mDevice->CreateSamplerState(&samplerDesc, &mCopySampler); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopySampler, "Renderer11 copy sampler"); + + D3D11_INPUT_ELEMENT_DESC quadLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + result = mDevice->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mCopyIL); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyIL, "Renderer11 copy texture input layout"); + + result = mDevice->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mCopyVS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyVS, "Renderer11 copy texture vertex shader"); + + result = mDevice->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mCopyRGBAPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyRGBAPS, "Renderer11 copy texture RGBA pixel shader"); + + result = mDevice->CreatePixelShader(g_PS_PassthroughRGB, sizeof(g_PS_PassthroughRGB), NULL, &mCopyRGBPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyRGBPS, "Renderer11 copy texture RGB pixel shader"); + + result = mDevice->CreatePixelShader(g_PS_PassthroughLum, sizeof(g_PS_PassthroughLum), NULL, &mCopyLumPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyLumPS, "Renderer11 copy texture luminance pixel shader"); + + result = mDevice->CreatePixelShader(g_PS_PassthroughLumAlpha, sizeof(g_PS_PassthroughLumAlpha), NULL, &mCopyLumAlphaPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mCopyLumAlphaPS, "Renderer11 copy texture luminance alpha pixel shader"); + + mCopyResourcesInitialized = true; + } + + // Verify the source and destination area sizes + if (sourceArea.x < 0 || sourceArea.x + sourceArea.width > static_cast(sourceWidth) || + sourceArea.y < 0 || sourceArea.y + sourceArea.height > static_cast(sourceHeight) || + destArea.x < 0 || destArea.x + destArea.width > static_cast(destWidth) || + destArea.y < 0 || destArea.y + destArea.height > static_cast(destHeight)) + { + return gl::error(GL_INVALID_VALUE, false); + } + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + result = mDeviceContext->Map(mCopyVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Failed to map vertex buffer for texture copy, HRESULT: 0x%X.", result); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); + + // Create a quad in homogeneous coordinates + float x1 = (destArea.x / float(destWidth)) * 2.0f - 1.0f; + float y1 = ((destHeight - destArea.y - destArea.height) / float(destHeight)) * 2.0f - 1.0f; + float x2 = ((destArea.x + destArea.width) / float(destWidth)) * 2.0f - 1.0f; + float y2 = ((destHeight - destArea.y) / float(destHeight)) * 2.0f - 1.0f; + + float u1 = sourceArea.x / float(sourceWidth); + float v1 = sourceArea.y / float(sourceHeight); + float u2 = (sourceArea.x + sourceArea.width) / float(sourceWidth); + float v2 = (sourceArea.y + sourceArea.height) / float(sourceHeight); + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v2); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v1); + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v2); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v1); + + mDeviceContext->Unmap(mCopyVB, 0); + + static UINT stride = sizeof(d3d11::PositionTexCoordVertex); + static UINT startIdx = 0; + mDeviceContext->IASetVertexBuffers(0, 1, &mCopyVB, &stride, &startIdx); + + // Apply state + mDeviceContext->OMSetBlendState(NULL, NULL, 0xFFFFFFF); + mDeviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); + mDeviceContext->RSSetState(NULL); + + // Apply shaders + mDeviceContext->IASetInputLayout(mCopyIL); + mDeviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + mDeviceContext->VSSetShader(mCopyVS, NULL, 0); + + ID3D11PixelShader *ps = NULL; + switch(destFormat) + { + case GL_RGBA: ps = mCopyRGBAPS; break; + case GL_RGB: ps = mCopyRGBPS; break; + case GL_ALPHA: ps = mCopyRGBAPS; break; + case GL_BGRA_EXT: ps = mCopyRGBAPS; break; + case GL_LUMINANCE: ps = mCopyLumPS; break; + case GL_LUMINANCE_ALPHA: ps = mCopyLumAlphaPS; break; + default: UNREACHABLE(); ps = NULL; break; + } + + mDeviceContext->PSSetShader(ps, NULL, 0); + mDeviceContext->GSSetShader(NULL, NULL, 0); + + // Unset the currently bound shader resource to avoid conflicts + static ID3D11ShaderResourceView *const nullSRV = NULL; + mDeviceContext->PSSetShaderResources(0, 1, &nullSRV); + + // Apply render target + setOneTimeRenderTarget(dest); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = destWidth; + viewport.Height = destHeight; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + mDeviceContext->RSSetViewports(1, &viewport); + + // Apply textures + mDeviceContext->PSSetShaderResources(0, 1, &source); + mDeviceContext->PSSetSamplers(0, 1, &mCopySampler); + + // Draw the quad + mDeviceContext->Draw(4, 0); + + // Unbind textures and render targets and vertex buffer + mDeviceContext->PSSetShaderResources(0, 1, &nullSRV); + + unapplyRenderTargets(); + + UINT zero = 0; + ID3D11Buffer *const nullBuffer = NULL; + mDeviceContext->IASetVertexBuffers(0, 1, &nullBuffer, &zero, &zero); + + markAllStateDirty(); + + return true; +} + +void Renderer11::unapplyRenderTargets() +{ + setOneTimeRenderTarget(NULL); +} + +void Renderer11::setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView) +{ + ID3D11RenderTargetView *rtvArray[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS] = {NULL}; + + rtvArray[0] = renderTargetView; + + mDeviceContext->OMSetRenderTargets(getMaxRenderTargets(), rtvArray, NULL); + + // Do not preserve the serial for this one-time-use render target + for (unsigned int rtIndex = 0; rtIndex < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; rtIndex++) + { + mAppliedRenderTargetSerials[rtIndex] = 0; + } +} + +RenderTarget *Renderer11::createRenderTarget(SwapChain *swapChain, bool depth) +{ + SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); + RenderTarget11 *renderTarget = NULL; + + if (depth) + { + // Note: depth stencil may be NULL for 0 sized surfaces + renderTarget = new RenderTarget11(this, swapChain11->getDepthStencil(), + swapChain11->getDepthStencilTexture(), NULL, + swapChain11->getWidth(), swapChain11->getHeight()); + } + else + { + // Note: render target may be NULL for 0 sized surfaces + renderTarget = new RenderTarget11(this, swapChain11->getRenderTarget(), + swapChain11->getOffscreenTexture(), + swapChain11->getRenderTargetShaderResource(), + swapChain11->getWidth(), swapChain11->getHeight()); + } + return renderTarget; +} + +RenderTarget *Renderer11::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) +{ + RenderTarget11 *renderTarget = new RenderTarget11(this, width, height, format, samples, depth); + return renderTarget; +} + +ShaderExecutable *Renderer11::loadExecutable(const void *function, size_t length, rx::ShaderType type) +{ + ShaderExecutable11 *executable = NULL; + + switch (type) + { + case rx::SHADER_VERTEX: + { + ID3D11VertexShader *vshader = NULL; + HRESULT result = mDevice->CreateVertexShader(function, length, NULL, &vshader); + ASSERT(SUCCEEDED(result)); + + if (vshader) + { + executable = new ShaderExecutable11(function, length, vshader); + } + } + break; + case rx::SHADER_PIXEL: + { + ID3D11PixelShader *pshader = NULL; + HRESULT result = mDevice->CreatePixelShader(function, length, NULL, &pshader); + ASSERT(SUCCEEDED(result)); + + if (pshader) + { + executable = new ShaderExecutable11(function, length, pshader); + } + } + break; + case rx::SHADER_GEOMETRY: + { + ID3D11GeometryShader *gshader = NULL; + HRESULT result = mDevice->CreateGeometryShader(function, length, NULL, &gshader); + ASSERT(SUCCEEDED(result)); + + if (gshader) + { + executable = new ShaderExecutable11(function, length, gshader); + } + } + break; + default: + UNREACHABLE(); + break; + } + + return executable; +} + +ShaderExecutable *Renderer11::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) +{ + std::string profile; + + switch (type) + { + case rx::SHADER_VERTEX: + profile = "vs_4_0"; + break; + case rx::SHADER_PIXEL: + profile = "ps_4_0"; + break; + case rx::SHADER_GEOMETRY: + profile = "gs_4_0"; + break; + default: + UNREACHABLE(); + return NULL; + } + + if (mFeatureLevel == D3D_FEATURE_LEVEL_9_3) + profile += "_level_9_3"; + else if (mFeatureLevel == D3D_FEATURE_LEVEL_9_2 || mFeatureLevel == D3D_FEATURE_LEVEL_9_1) + profile += "_level_9_1"; + + ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile.c_str(), D3DCOMPILE_OPTIMIZATION_LEVEL0, false); + if (!binary) + return NULL; + + ShaderExecutable *executable = loadExecutable((DWORD *)binary->GetBufferPointer(), binary->GetBufferSize(), type); + binary->Release(); + + return executable; +} + +VertexBuffer *Renderer11::createVertexBuffer() +{ + return new VertexBuffer11(this); +} + +IndexBuffer *Renderer11::createIndexBuffer() +{ + return new IndexBuffer11(this); +} + +BufferStorage *Renderer11::createBufferStorage() +{ + return new BufferStorage11(this); +} + +QueryImpl *Renderer11::createQuery(GLenum type) +{ + return new Query11(this, type); +} + +FenceImpl *Renderer11::createFence() +{ + return new Fence11(this); +} + +bool Renderer11::getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource) +{ + ASSERT(colorbuffer != NULL); + + RenderTarget11 *renderTarget = RenderTarget11::makeRenderTarget11(colorbuffer->getRenderTarget()); + if (renderTarget) + { + *subresourceIndex = renderTarget->getSubresourceIndex(); + + ID3D11RenderTargetView *colorBufferRTV = renderTarget->getRenderTargetView(); + if (colorBufferRTV) + { + ID3D11Resource *textureResource = NULL; + colorBufferRTV->GetResource(&textureResource); + + if (textureResource) + { + HRESULT result = textureResource->QueryInterface(IID_ID3D11Texture2D, (void**)resource); + textureResource->Release(); + + if (SUCCEEDED(result)) + { + return true; + } + else + { + ERR("Failed to extract the ID3D11Texture2D from the render target resource, " + "HRESULT: 0x%X.", result); + } + } + } + } + + return false; +} + +bool Renderer11::blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + bool blitRenderTarget, bool blitDepthStencil) +{ + if (blitRenderTarget) + { + gl::Renderbuffer *readBuffer = readTarget->getReadColorbuffer(); + + if (!readBuffer) + { + ERR("Failed to retrieve the read buffer from the read framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget *readRenderTarget = readBuffer->getRenderTarget(); + + for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++) + { + if (drawTarget->isEnabledColorAttachment(colorAttachment)) + { + gl::Renderbuffer *drawBuffer = drawTarget->getColorbuffer(colorAttachment); + + if (!drawBuffer) + { + ERR("Failed to retrieve the draw buffer from the draw framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget *drawRenderTarget = drawBuffer->getRenderTarget(); + + if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, false)) + { + return false; + } + } + } + } + + if (blitDepthStencil) + { + gl::Renderbuffer *readBuffer = readTarget->getDepthOrStencilbuffer(); + gl::Renderbuffer *drawBuffer = drawTarget->getDepthOrStencilbuffer(); + + if (!readBuffer) + { + ERR("Failed to retrieve the read depth-stencil buffer from the read framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + if (!drawBuffer) + { + ERR("Failed to retrieve the draw depth-stencil buffer from the draw framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RenderTarget *readRenderTarget = readBuffer->getDepthStencil(); + RenderTarget *drawRenderTarget = drawBuffer->getDepthStencil(); + + if (!blitRenderbufferRect(readRect, drawRect, readRenderTarget, drawRenderTarget, true)) + { + return false; + } + } + + return true; +} + +void Renderer11::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) +{ + ID3D11Texture2D *colorBufferTexture = NULL; + unsigned int subresourceIndex = 0; + + gl::Renderbuffer *colorbuffer = framebuffer->getReadColorbuffer(); + + if (colorbuffer && getRenderTargetResource(colorbuffer, &subresourceIndex, &colorBufferTexture)) + { + gl::Rectangle area; + area.x = x; + area.y = y; + area.width = width; + area.height = height; + + readTextureData(colorBufferTexture, subresourceIndex, area, colorbuffer->getActualFormat(), format, type, outputPitch, + packReverseRowOrder, packAlignment, pixels); + + colorBufferTexture->Release(); + colorBufferTexture = NULL; + } +} + +Image *Renderer11::createImage() +{ + return new Image11(); +} + +void Renderer11::generateMipmap(Image *dest, Image *src) +{ + Image11 *dest11 = Image11::makeImage11(dest); + Image11 *src11 = Image11::makeImage11(src); + Image11::generateMipmap(dest11, src11); +} + +TextureStorage *Renderer11::createTextureStorage2D(SwapChain *swapChain) +{ + SwapChain11 *swapChain11 = SwapChain11::makeSwapChain11(swapChain); + return new TextureStorage11_2D(this, swapChain11); +} + +TextureStorage *Renderer11::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) +{ + return new TextureStorage11_2D(this, levels, internalformat, usage, forceRenderable, width, height); +} + +TextureStorage *Renderer11::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) +{ + return new TextureStorage11_Cube(this, levels, internalformat, usage, forceRenderable, size); +} + +static inline unsigned int getFastPixelCopySize(DXGI_FORMAT sourceFormat, GLenum sourceGLFormat, GLenum destFormat, GLenum destType) +{ + if (sourceFormat == DXGI_FORMAT_A8_UNORM && + destFormat == GL_ALPHA && + destType == GL_UNSIGNED_BYTE) + { + return 1; + } + else if (sourceFormat == DXGI_FORMAT_R8G8B8A8_UNORM && + sourceGLFormat == GL_RGBA8_OES && + destFormat == GL_RGBA && + destType == GL_UNSIGNED_BYTE) + { + return 4; + } + else if (sourceFormat == DXGI_FORMAT_B8G8R8A8_UNORM && + destFormat == GL_BGRA_EXT && + destType == GL_UNSIGNED_BYTE) + { + return 4; + } + else if (sourceFormat == DXGI_FORMAT_R16G16B16A16_FLOAT && + sourceGLFormat == GL_RGBA16F_EXT && + destFormat == GL_RGBA && + destType == GL_HALF_FLOAT_OES) + { + return 8; + } + else if (sourceFormat == DXGI_FORMAT_R32G32B32_FLOAT && + destFormat == GL_RGB && + destType == GL_FLOAT) + { + return 12; + } + else if (sourceFormat == DXGI_FORMAT_R32G32B32A32_FLOAT && + sourceGLFormat == GL_RGBA32F_EXT && + destFormat == GL_RGBA && + destType == GL_FLOAT) + { + return 16; + } + else + { + return 0; + } +} + +static inline void readPixelColor(const unsigned char *data, DXGI_FORMAT format, GLenum glFormat, unsigned int x, + unsigned int y, int inputPitch, gl::Color *outColor) +{ + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + { + unsigned int rgba = *reinterpret_cast(data + 4 * x + y * inputPitch); + outColor->red = (rgba & 0x000000FF) * (1.0f / 0x000000FF); + outColor->green = (rgba & 0x0000FF00) * (1.0f / 0x0000FF00); + outColor->blue = (rgba & 0x00FF0000) * (1.0f / 0x00FF0000); + + if (gl::GetAlphaSize(glFormat) > 0) + { + outColor->alpha = (rgba & 0xFF000000) * (1.0f / 0xFF000000); + } + else + { + outColor->alpha = 1.0f; + } + } + break; + + case DXGI_FORMAT_A8_UNORM: + { + outColor->red = 0.0f; + outColor->green = 0.0f; + outColor->blue = 0.0f; + outColor->alpha = *(data + x + y * inputPitch) / 255.0f; + } + break; + + case DXGI_FORMAT_R32G32B32A32_FLOAT: + { + outColor->red = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 0); + outColor->green = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 1); + outColor->blue = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 2); + + if (gl::GetAlphaSize(glFormat) > 0) + { + outColor->alpha = *(reinterpret_cast(data + 16 * x + y * inputPitch) + 3); + } + else + { + outColor->alpha = 1.0f; + } + } + break; + + case DXGI_FORMAT_R32G32B32_FLOAT: + { + outColor->red = *(reinterpret_cast(data + 12 * x + y * inputPitch) + 0); + outColor->green = *(reinterpret_cast(data + 12 * x + y * inputPitch) + 1); + outColor->blue = *(reinterpret_cast(data + 12 * x + y * inputPitch) + 2); + outColor->alpha = 1.0f; + } + break; + + case DXGI_FORMAT_R16G16B16A16_FLOAT: + { + outColor->red = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 0)); + outColor->green = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 1)); + outColor->blue = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 2)); + + if (gl::GetAlphaSize(glFormat) > 0) + { + outColor->alpha = gl::float16ToFloat32(*(reinterpret_cast(data + 8 * x + y * inputPitch) + 3)); + } + else + { + outColor->alpha = 1.0f; + } + } + break; + + case DXGI_FORMAT_B8G8R8A8_UNORM: + { + unsigned int bgra = *reinterpret_cast(data + 4 * x + y * inputPitch); + outColor->red = (bgra & 0x00FF0000) * (1.0f / 0x00FF0000); + outColor->blue = (bgra & 0x000000FF) * (1.0f / 0x000000FF); + outColor->green = (bgra & 0x0000FF00) * (1.0f / 0x0000FF00); + outColor->alpha = (bgra & 0xFF000000) * (1.0f / 0xFF000000); + } + break; + + case DXGI_FORMAT_R8_UNORM: + { + outColor->red = *(data + x + y * inputPitch) / 255.0f; + outColor->green = 0.0f; + outColor->blue = 0.0f; + outColor->alpha = 1.0f; + } + break; + + case DXGI_FORMAT_R8G8_UNORM: + { + unsigned short rg = *reinterpret_cast(data + 2 * x + y * inputPitch); + + outColor->red = (rg & 0xFF00) * (1.0f / 0xFF00); + outColor->green = (rg & 0x00FF) * (1.0f / 0x00FF); + outColor->blue = 0.0f; + outColor->alpha = 1.0f; + } + break; + + case DXGI_FORMAT_R16_FLOAT: + { + outColor->red = gl::float16ToFloat32(*reinterpret_cast(data + 2 * x + y * inputPitch)); + outColor->green = 0.0f; + outColor->blue = 0.0f; + outColor->alpha = 1.0f; + } + break; + + case DXGI_FORMAT_R16G16_FLOAT: + { + outColor->red = gl::float16ToFloat32(*(reinterpret_cast(data + 4 * x + y * inputPitch) + 0)); + outColor->green = gl::float16ToFloat32(*(reinterpret_cast(data + 4 * x + y * inputPitch) + 1)); + outColor->blue = 0.0f; + outColor->alpha = 1.0f; + } + break; + + default: + ERR("ReadPixelColor not implemented for DXGI format %u.", format); + UNIMPLEMENTED(); + break; + } +} + +static inline void writePixelColor(const gl::Color &color, GLenum format, GLenum type, unsigned int x, + unsigned int y, int outputPitch, void *outData) +{ + unsigned char* byteData = reinterpret_cast(outData); + unsigned short* shortData = reinterpret_cast(outData); + + switch (format) + { + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + byteData[4 * x + y * outputPitch + 0] = static_cast(255 * color.red + 0.5f); + byteData[4 * x + y * outputPitch + 1] = static_cast(255 * color.green + 0.5f); + byteData[4 * x + y * outputPitch + 2] = static_cast(255 * color.blue + 0.5f); + byteData[4 * x + y * outputPitch + 3] = static_cast(255 * color.alpha + 0.5f); + break; + + default: + ERR("WritePixelColor not implemented for format GL_RGBA and type 0x%X.", type); + UNIMPLEMENTED(); + break; + } + break; + + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + byteData[4 * x + y * outputPitch + 0] = static_cast(255 * color.blue + 0.5f); + byteData[4 * x + y * outputPitch + 1] = static_cast(255 * color.green + 0.5f); + byteData[4 * x + y * outputPitch + 2] = static_cast(255 * color.red + 0.5f); + byteData[4 * x + y * outputPitch + 3] = static_cast(255 * color.alpha + 0.5f); + break; + + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section + // this type is packed as follows: + // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // -------------------------------------------------------------------------------- + // | 4th | 3rd | 2nd | 1st component | + // -------------------------------------------------------------------------------- + // in the case of BGRA_EXT, B is the first component, G the second, and so forth. + shortData[x + y * outputPitch / sizeof(unsigned short)] = + (static_cast(15 * color.alpha + 0.5f) << 12) | + (static_cast(15 * color.red + 0.5f) << 8) | + (static_cast(15 * color.green + 0.5f) << 4) | + (static_cast(15 * color.blue + 0.5f) << 0); + break; + + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section + // this type is packed as follows: + // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // -------------------------------------------------------------------------------- + // | 4th | 3rd | 2nd | 1st component | + // -------------------------------------------------------------------------------- + // in the case of BGRA_EXT, B is the first component, G the second, and so forth. + shortData[x + y * outputPitch / sizeof(unsigned short)] = + (static_cast( color.alpha + 0.5f) << 15) | + (static_cast(31 * color.red + 0.5f) << 10) | + (static_cast(31 * color.green + 0.5f) << 5) | + (static_cast(31 * color.blue + 0.5f) << 0); + break; + + default: + ERR("WritePixelColor not implemented for format GL_BGRA_EXT and type 0x%X.", type); + UNIMPLEMENTED(); + break; + } + break; + + case GL_RGB: + switch (type) + { + case GL_UNSIGNED_SHORT_5_6_5: + shortData[x + y * outputPitch / sizeof(unsigned short)] = + (static_cast(31 * color.blue + 0.5f) << 0) | + (static_cast(63 * color.green + 0.5f) << 5) | + (static_cast(31 * color.red + 0.5f) << 11); + break; + + case GL_UNSIGNED_BYTE: + byteData[3 * x + y * outputPitch + 0] = static_cast(255 * color.red + 0.5f); + byteData[3 * x + y * outputPitch + 1] = static_cast(255 * color.green + 0.5f); + byteData[3 * x + y * outputPitch + 2] = static_cast(255 * color.blue + 0.5f); + break; + + default: + ERR("WritePixelColor not implemented for format GL_RGB and type 0x%X.", type); + UNIMPLEMENTED(); + break; + } + break; + + default: + ERR("WritePixelColor not implemented for format 0x%X.", format); + UNIMPLEMENTED(); + break; + } +} + +void Renderer11::readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, + GLenum sourceFormat, GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, + GLint packAlignment, void *pixels) +{ + D3D11_TEXTURE2D_DESC textureDesc; + texture->GetDesc(&textureDesc); + + D3D11_TEXTURE2D_DESC stagingDesc; + stagingDesc.Width = area.width; + stagingDesc.Height = area.height; + stagingDesc.MipLevels = 1; + stagingDesc.ArraySize = 1; + stagingDesc.Format = textureDesc.Format; + stagingDesc.SampleDesc.Count = 1; + stagingDesc.SampleDesc.Quality = 0; + stagingDesc.Usage = D3D11_USAGE_STAGING; + stagingDesc.BindFlags = 0; + stagingDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + stagingDesc.MiscFlags = 0; + + ID3D11Texture2D* stagingTex = NULL; + HRESULT result = mDevice->CreateTexture2D(&stagingDesc, NULL, &stagingTex); + if (FAILED(result)) + { + ERR("Failed to create staging texture for readPixels, HRESULT: 0x%X.", result); + return; + } + + ID3D11Texture2D* srcTex = NULL; + if (textureDesc.SampleDesc.Count > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = textureDesc.Width; + resolveDesc.Height = textureDesc.Height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureDesc.Format; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = D3D11_USAGE_DEFAULT; + resolveDesc.BindFlags = 0; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + result = mDevice->CreateTexture2D(&resolveDesc, NULL, &srcTex); + if (FAILED(result)) + { + ERR("Failed to create resolve texture for readPixels, HRESULT: 0x%X.", result); + stagingTex->Release(); + return; + } + + mDeviceContext->ResolveSubresource(srcTex, 0, texture, subResource, textureDesc.Format); + subResource = 0; + } + else + { + srcTex = texture; + srcTex->AddRef(); + } + + D3D11_BOX srcBox; + srcBox.left = area.x; + srcBox.right = area.x + area.width; + srcBox.top = area.y; + srcBox.bottom = area.y + area.height; + srcBox.front = 0; + srcBox.back = 1; + + mDeviceContext->CopySubresourceRegion(stagingTex, 0, 0, 0, 0, srcTex, subResource, &srcBox); + + srcTex->Release(); + srcTex = NULL; + + D3D11_MAPPED_SUBRESOURCE mapping; + mDeviceContext->Map(stagingTex, 0, D3D11_MAP_READ, 0, &mapping); + + unsigned char *source; + int inputPitch; + if (packReverseRowOrder) + { + source = static_cast(mapping.pData) + mapping.RowPitch * (area.height - 1); + inputPitch = -static_cast(mapping.RowPitch); + } + else + { + source = static_cast(mapping.pData); + inputPitch = static_cast(mapping.RowPitch); + } + + unsigned int fastPixelSize = getFastPixelCopySize(textureDesc.Format, sourceFormat, format, type); + if (fastPixelSize != 0) + { + unsigned char *dest = static_cast(pixels); + for (int j = 0; j < area.height; j++) + { + memcpy(dest + j * outputPitch, source + j * inputPitch, area.width * fastPixelSize); + } + } + else if (textureDesc.Format == DXGI_FORMAT_B8G8R8A8_UNORM && + format == GL_RGBA && + type == GL_UNSIGNED_BYTE) + { + // Fast path for swapping red with blue + unsigned char *dest = static_cast(pixels); + + for (int j = 0; j < area.height; j++) + { + for (int i = 0; i < area.width; i++) + { + unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); + *(unsigned int*)(dest + 4 * i + j * outputPitch) = + (argb & 0xFF00FF00) | // Keep alpha and green + (argb & 0x00FF0000) >> 16 | // Move red to blue + (argb & 0x000000FF) << 16; // Move blue to red + } + } + } + else + { + gl::Color pixelColor; + for (int j = 0; j < area.height; j++) + { + for (int i = 0; i < area.width; i++) + { + readPixelColor(source, textureDesc.Format, sourceFormat, i, j, inputPitch, &pixelColor); + writePixelColor(pixelColor, format, type, i, j, outputPitch, pixels); + } + } + } + + mDeviceContext->Unmap(stagingTex, 0); + + stagingTex->Release(); + stagingTex = NULL; +} + +bool Renderer11::blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, bool wholeBufferCopy) +{ + ASSERT(readRect.width == drawRect.width && readRect.height == drawRect.height); + + RenderTarget11 *drawRenderTarget11 = RenderTarget11::makeRenderTarget11(drawRenderTarget); + if (!drawRenderTarget) + { + ERR("Failed to retrieve the draw render target from the draw framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11Texture2D *drawTexture = drawRenderTarget11->getTexture(); + unsigned int drawSubresource = drawRenderTarget11->getSubresourceIndex(); + + RenderTarget11 *readRenderTarget11 = RenderTarget11::makeRenderTarget11(readRenderTarget); + if (!readRenderTarget) + { + ERR("Failed to retrieve the read render target from the read framebuffer."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + ID3D11Texture2D *readTexture = NULL; + unsigned int readSubresource = 0; + if (readRenderTarget->getSamples() > 0) + { + readTexture = resolveMultisampledTexture(readRenderTarget11->getTexture(), readRenderTarget11->getSubresourceIndex()); + readSubresource = 0; + } + else + { + readTexture = readRenderTarget11->getTexture(); + readTexture->AddRef(); + readSubresource = readRenderTarget11->getSubresourceIndex(); + } + + if (!readTexture) + { + ERR("Failed to retrieve the read render target view from the read render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + D3D11_BOX readBox; + readBox.left = readRect.x; + readBox.right = readRect.x + readRect.width; + readBox.top = readRect.y; + readBox.bottom = readRect.y + readRect.height; + readBox.front = 0; + readBox.back = 1; + + // D3D11 needs depth-stencil CopySubresourceRegions to have a NULL pSrcBox + // We also require complete framebuffer copies for depth-stencil blit. + D3D11_BOX *pSrcBox = wholeBufferCopy ? NULL : &readBox; + + mDeviceContext->CopySubresourceRegion(drawTexture, drawSubresource, drawRect.x, drawRect.y, 0, + readTexture, readSubresource, pSrcBox); + + SafeRelease(readTexture); + + return true; +} + +ID3D11Texture2D *Renderer11::resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource) +{ + D3D11_TEXTURE2D_DESC textureDesc; + source->GetDesc(&textureDesc); + + if (textureDesc.SampleDesc.Count > 1) + { + D3D11_TEXTURE2D_DESC resolveDesc; + resolveDesc.Width = textureDesc.Width; + resolveDesc.Height = textureDesc.Height; + resolveDesc.MipLevels = 1; + resolveDesc.ArraySize = 1; + resolveDesc.Format = textureDesc.Format; + resolveDesc.SampleDesc.Count = 1; + resolveDesc.SampleDesc.Quality = 0; + resolveDesc.Usage = textureDesc.Usage; + resolveDesc.BindFlags = textureDesc.BindFlags; + resolveDesc.CPUAccessFlags = 0; + resolveDesc.MiscFlags = 0; + + ID3D11Texture2D *resolveTexture = NULL; + HRESULT result = mDevice->CreateTexture2D(&resolveDesc, NULL, &resolveTexture); + if (FAILED(result)) + { + ERR("Failed to create a multisample resolve texture, HRESULT: 0x%X.", result); + return NULL; + } + + mDeviceContext->ResolveSubresource(resolveTexture, 0, source, subresource, textureDesc.Format); + return resolveTexture; + } + else + { + source->AddRef(); + return source; + } +} + +bool Renderer11::getLUID(LUID *adapterLuid) const +{ + adapterLuid->HighPart = 0; + adapterLuid->LowPart = 0; + + if (!mDxgiAdapter) + { + return false; + } + + DXGI_ADAPTER_DESC adapterDesc; + if (FAILED(mDxgiAdapter->GetDesc(&adapterDesc))) + { + return false; + } + + *adapterLuid = adapterDesc.AdapterLuid; + return true; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h new file mode 100644 index 0000000000..a8a722c56c --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/Renderer11.h @@ -0,0 +1,358 @@ +// +// Copyright (c) 2012-2013 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. +// + +// Renderer11.h: Defines a back-end specific class for the D3D11 renderer. + +#ifndef LIBGLESV2_RENDERER_RENDERER11_H_ +#define LIBGLESV2_RENDERER_RENDERER11_H_ + +#include "common/angleutils.h" +#include "libGLESv2/angletypes.h" +#include "libGLESv2/mathutil.h" + +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/d3d11/RenderStateCache.h" +#include "libGLESv2/renderer/d3d11/InputLayoutCache.h" +#include "libGLESv2/renderer/RenderTarget.h" + +namespace gl +{ +class Renderbuffer; +} + +namespace rx +{ + +class VertexDataManager; +class IndexDataManager; +class StreamingIndexBufferInterface; + +enum +{ + MAX_VERTEX_UNIFORM_VECTORS_D3D11 = 1024, + MAX_FRAGMENT_UNIFORM_VECTORS_D3D11 = 1024 +}; + +class Renderer11 : public Renderer +{ + public: + Renderer11(egl::Display *display); + virtual ~Renderer11(); + + static Renderer11 *makeRenderer11(Renderer *renderer); + + virtual EGLint initialize(); + virtual bool resetDevice(); + + virtual int generateConfigs(ConfigDesc **configDescList); + virtual void deleteConfigs(ConfigDesc *configDescList); + + virtual void sync(bool block); + + virtual SwapChain *createSwapChain(EGLNativeWindowType window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + + virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); + + virtual void setRasterizerState(const gl::RasterizerState &rasterState); + virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::Color &blendColor, + unsigned int sampleMask); + virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW); + + virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); + virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + bool ignoreViewport); + + virtual bool applyPrimitiveType(GLenum mode, GLsizei count); + virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); + virtual void applyShaders(gl::ProgramBinary *programBinary); + virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray); + virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances); + virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + + virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); + virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + + virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + + virtual void markAllStateDirty(); + + // lost device + void notifyDeviceLost(); + virtual bool isDeviceLost(); + virtual bool testDeviceLost(bool notify); + virtual bool testDeviceResettable(); + + // Renderer capabilities + virtual DWORD getAdapterVendor() const; + virtual std::string getRendererDescription() const; + virtual GUID getAdapterIdentifier() const; + + virtual bool getBGRATextureSupport() const; + virtual bool getDXT1TextureSupport(); + virtual bool getDXT3TextureSupport(); + virtual bool getDXT5TextureSupport(); + virtual bool getEventQuerySupport(); + virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); + virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); + virtual bool getLuminanceTextureSupport(); + virtual bool getLuminanceAlphaTextureSupport(); + virtual unsigned int getMaxVertexTextureImageUnits() const; + virtual unsigned int getMaxCombinedTextureImageUnits() const; + virtual unsigned int getReservedVertexUniformVectors() const; + virtual unsigned int getReservedFragmentUniformVectors() const; + virtual unsigned int getMaxVertexUniformVectors() const; + virtual unsigned int getMaxFragmentUniformVectors() const; + virtual unsigned int getMaxVaryingVectors() const; + virtual bool getNonPower2TextureSupport() const; + virtual bool getDepthTextureSupport() const; + virtual bool getOcclusionQuerySupport() const; + virtual bool getInstancingSupport() const; + virtual bool getTextureFilterAnisotropySupport() const; + virtual float getTextureMaxAnisotropy() const; + virtual bool getShareHandleSupport() const; + virtual bool getDerivativeInstructionSupport() const; + virtual bool getPostSubBufferSupport() const; + + virtual int getMajorShaderModel() const; + virtual float getMaxPointSize() const; + virtual int getMaxViewportDimension() const; + virtual int getMaxTextureWidth() const; + virtual int getMaxTextureHeight() const; + virtual bool get32BitIndexSupport() const; + virtual int getMinSwapInterval() const; + virtual int getMaxSwapInterval() const; + + virtual GLsizei getMaxSupportedSamples() const; + int getNearestSupportedSamples(DXGI_FORMAT format, unsigned int requested) const; + + virtual unsigned int getMaxRenderTargets() const; + + // Pixel operations + virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); + virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); + + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); + + bool copyTexture(ID3D11ShaderResourceView *source, const gl::Rectangle &sourceArea, unsigned int sourceWidth, unsigned int sourceHeight, + ID3D11RenderTargetView *dest, const gl::Rectangle &destArea, unsigned int destWidth, unsigned int destHeight, GLenum destFormat); + + virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + bool blitRenderTarget, bool blitDepthStencil); + virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); + + // RenderTarget creation + virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); + virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth); + + // Shader operations + virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type); + virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround); + + // Image operations + virtual Image *createImage(); + virtual void generateMipmap(Image *dest, Image *source); + virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); + virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); + virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + + // Buffer creation + virtual VertexBuffer *createVertexBuffer(); + virtual IndexBuffer *createIndexBuffer(); + virtual BufferStorage *createBufferStorage(); + + // Query and Fence creation + virtual QueryImpl *createQuery(GLenum type); + virtual FenceImpl *createFence(); + + // D3D11-renderer specific methods + ID3D11Device *getDevice() { return mDevice; } + ID3D11DeviceContext *getDeviceContext() { return mDeviceContext; }; + IDXGIFactory *getDxgiFactory() { return mDxgiFactory; }; + D3D_FEATURE_LEVEL getFeatureLevel() { return mFeatureLevel; } + + bool getRenderTargetResource(gl::Renderbuffer *colorbuffer, unsigned int *subresourceIndex, ID3D11Texture2D **resource); + void unapplyRenderTargets(); + void setOneTimeRenderTarget(ID3D11RenderTargetView *renderTargetView); + + virtual bool getLUID(LUID *adapterLuid) const; + + private: + DISALLOW_COPY_AND_ASSIGN(Renderer11); + + void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + void drawTriangleFan(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer, int instances); + + void readTextureData(ID3D11Texture2D *texture, unsigned int subResource, const gl::Rectangle &area, + GLenum sourceFormat, GLenum format, GLenum type, GLsizei outputPitch, bool packReverseRowOrder, + GLint packAlignment, void *pixels); + + void maskedClear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + rx::Range getViewportBounds() const; + + bool blitRenderbufferRect(const gl::Rectangle &readRect, const gl::Rectangle &drawRect, RenderTarget *readRenderTarget, + RenderTarget *drawRenderTarget, bool wholeBufferCopy); + ID3D11Texture2D *resolveMultisampledTexture(ID3D11Texture2D *source, unsigned int subresource); + + HMODULE mD3d11Module; + HMODULE mDxgiModule; + + bool mDeviceLost; + + void initializeDevice(); + void releaseDeviceResources(); + int getMinorShaderModel() const; + void release(); + + RenderStateCache mStateCache; + + // Support flags + bool mFloat16TextureSupport; + bool mFloat16FilterSupport; + bool mFloat16RenderSupport; + + bool mFloat32TextureSupport; + bool mFloat32FilterSupport; + bool mFloat32RenderSupport; + + bool mDXT1TextureSupport; + bool mDXT3TextureSupport; + bool mDXT5TextureSupport; + + bool mDepthTextureSupport; + + // Multisample format support + struct MultisampleSupportInfo + { + unsigned int qualityLevels[D3D11_MAX_MULTISAMPLE_SAMPLE_COUNT]; + }; + + typedef std::unordered_map > MultisampleSupportMap; + MultisampleSupportMap mMultisampleSupportMap; + + unsigned int mMaxSupportedSamples; + + // current render target states + unsigned int mAppliedRenderTargetSerials[gl::IMPLEMENTATION_MAX_DRAW_BUFFERS]; + unsigned int mAppliedDepthbufferSerial; + unsigned int mAppliedStencilbufferSerial; + bool mDepthStencilInitialized; + bool mRenderTargetDescInitialized; + rx::RenderTarget::Desc mRenderTargetDesc; + unsigned int mCurDepthSize; + unsigned int mCurStencilSize; + + // Currently applied sampler states + bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + + bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + + // Currently applied textures + unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; + + // Currently applied blend state + bool mForceSetBlendState; + gl::BlendState mCurBlendState; + gl::Color mCurBlendColor; + unsigned int mCurSampleMask; + + // Currently applied rasterizer state + bool mForceSetRasterState; + gl::RasterizerState mCurRasterState; + + // Currently applied depth stencil state + bool mForceSetDepthStencilState; + gl::DepthStencilState mCurDepthStencilState; + int mCurStencilRef; + int mCurStencilBackRef; + + // Currently applied scissor rectangle + bool mForceSetScissor; + bool mScissorEnabled; + gl::Rectangle mCurScissor; + + // Currently applied viewport + bool mForceSetViewport; + gl::Rectangle mCurViewport; + float mCurNear; + float mCurFar; + + // Currently applied primitive topology + D3D11_PRIMITIVE_TOPOLOGY mCurrentPrimitiveTopology; + + unsigned int mAppliedIBSerial; + unsigned int mAppliedStorageIBSerial; + unsigned int mAppliedIBOffset; + + unsigned int mAppliedProgramBinarySerial; + bool mIsGeometryShaderActive; + + dx_VertexConstants mVertexConstants; + dx_VertexConstants mAppliedVertexConstants; + ID3D11Buffer *mDriverConstantBufferVS; + ID3D11Buffer *mCurrentVertexConstantBuffer; + + dx_PixelConstants mPixelConstants; + dx_PixelConstants mAppliedPixelConstants; + ID3D11Buffer *mDriverConstantBufferPS; + ID3D11Buffer *mCurrentPixelConstantBuffer; + + ID3D11Buffer *mCurrentGeometryConstantBuffer; + + // Vertex, index and input layouts + VertexDataManager *mVertexDataManager; + IndexDataManager *mIndexDataManager; + InputLayoutCache mInputLayoutCache; + + StreamingIndexBufferInterface *mLineLoopIB; + StreamingIndexBufferInterface *mTriangleFanIB; + + // Texture copy resources + bool mCopyResourcesInitialized; + ID3D11Buffer *mCopyVB; + ID3D11SamplerState *mCopySampler; + ID3D11InputLayout *mCopyIL; + ID3D11VertexShader *mCopyVS; + ID3D11PixelShader *mCopyRGBAPS; + ID3D11PixelShader *mCopyRGBPS; + ID3D11PixelShader *mCopyLumPS; + ID3D11PixelShader *mCopyLumAlphaPS; + + // Masked clear resources + bool mClearResourcesInitialized; + ID3D11Buffer *mClearVB; + ID3D11InputLayout *mClearIL; + ID3D11VertexShader *mClearVS; + ID3D11PixelShader *mClearSinglePS; + ID3D11PixelShader *mClearMultiplePS; + ID3D11RasterizerState *mClearScissorRS; + ID3D11RasterizerState *mClearNoScissorRS; + + // Sync query + ID3D11Query *mSyncQuery; + + ID3D11Device *mDevice; + D3D_FEATURE_LEVEL mFeatureLevel; + ID3D11DeviceContext *mDeviceContext; + IDXGIAdapter *mDxgiAdapter; + DXGI_ADAPTER_DESC mAdapterDescription; + char mDescription[128]; + IDXGIFactory *mDxgiFactory; + + // Cached device caps + bool mBGRATextureSupport; +}; + +} +#endif // LIBGLESV2_RENDERER_RENDERER11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp new file mode 100644 index 0000000000..2e455e3af5 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.cpp @@ -0,0 +1,109 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// ShaderExecutable11.cpp: Implements a D3D11-specific class to contain shader +// executable implementation details. + +#include "libGLESv2/renderer/d3d11/ShaderExecutable11.h" + +#include "common/debug.h" + +namespace rx +{ + +ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable) + : ShaderExecutable(function, length) +{ + mPixelExecutable = executable; + mVertexExecutable = NULL; + mGeometryExecutable = NULL; + + mConstantBuffer = NULL; +} + +ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable) + : ShaderExecutable(function, length) +{ + mVertexExecutable = executable; + mPixelExecutable = NULL; + mGeometryExecutable = NULL; + + mConstantBuffer = NULL; +} + +ShaderExecutable11::ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable) + : ShaderExecutable(function, length) +{ + mGeometryExecutable = executable; + mVertexExecutable = NULL; + mPixelExecutable = NULL; + + mConstantBuffer = NULL; +} + +ShaderExecutable11::~ShaderExecutable11() +{ + if (mVertexExecutable) + { + mVertexExecutable->Release(); + } + if (mPixelExecutable) + { + mPixelExecutable->Release(); + } + if (mGeometryExecutable) + { + mGeometryExecutable->Release(); + } + + if (mConstantBuffer) + { + mConstantBuffer->Release(); + } +} + +ShaderExecutable11 *ShaderExecutable11::makeShaderExecutable11(ShaderExecutable *executable) +{ + ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable11*, executable)); + return static_cast(executable); +} + +ID3D11VertexShader *ShaderExecutable11::getVertexShader() const +{ + return mVertexExecutable; +} + +ID3D11PixelShader *ShaderExecutable11::getPixelShader() const +{ + return mPixelExecutable; +} + +ID3D11GeometryShader *ShaderExecutable11::getGeometryShader() const +{ + return mGeometryExecutable; +} + +ID3D11Buffer *ShaderExecutable11::getConstantBuffer(ID3D11Device *device, unsigned int registerCount) +{ + if (!mConstantBuffer && registerCount > 0) + { + D3D11_BUFFER_DESC constantBufferDescription = {0}; + constantBufferDescription.ByteWidth = registerCount * sizeof(float[4]); + constantBufferDescription.Usage = D3D11_USAGE_DYNAMIC; + constantBufferDescription.BindFlags = D3D11_BIND_CONSTANT_BUFFER; + constantBufferDescription.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + constantBufferDescription.MiscFlags = 0; + constantBufferDescription.StructureByteStride = 0; + + HRESULT result = device->CreateBuffer(&constantBufferDescription, NULL, &mConstantBuffer); + ASSERT(SUCCEEDED(result)); + } + + return mConstantBuffer; +} + +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h new file mode 100644 index 0000000000..c6ec1cf7d2 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/ShaderExecutable11.h @@ -0,0 +1,47 @@ +// +// Copyright (c) 2012-2013 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. +// + +// ShaderExecutable11.h: Defines a D3D11-specific class to contain shader +// executable implementation details. + +#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_ +#define LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_ + +#include "libGLESv2/renderer/ShaderExecutable.h" + +namespace rx +{ + +class ShaderExecutable11 : public ShaderExecutable +{ + public: + ShaderExecutable11(const void *function, size_t length, ID3D11PixelShader *executable); + ShaderExecutable11(const void *function, size_t length, ID3D11VertexShader *executable); + ShaderExecutable11(const void *function, size_t length, ID3D11GeometryShader *executable); + + virtual ~ShaderExecutable11(); + + static ShaderExecutable11 *makeShaderExecutable11(ShaderExecutable *executable); + + ID3D11PixelShader *getPixelShader() const; + ID3D11VertexShader *getVertexShader() const; + ID3D11GeometryShader *getGeometryShader() const; + + ID3D11Buffer *getConstantBuffer(ID3D11Device *device, unsigned int registerCount); + + private: + DISALLOW_COPY_AND_ASSIGN(ShaderExecutable11); + + ID3D11PixelShader *mPixelExecutable; + ID3D11VertexShader *mVertexExecutable; + ID3D11GeometryShader *mGeometryExecutable; + + ID3D11Buffer *mConstantBuffer; +}; + +} + +#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.cpp new file mode 100644 index 0000000000..bd97d5cff5 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.cpp @@ -0,0 +1,700 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// SwapChain11.cpp: Implements a back-end specific class for the D3D11 swap chain. + +#include "libGLESv2/renderer/d3d11/SwapChain11.h" + +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" + +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthrough11vs.h" +#include "libGLESv2/renderer/d3d11/shaders/compiled/passthroughrgba11ps.h" + +namespace rx +{ + +SwapChain11::SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, + GLenum backBufferFormat, GLenum depthBufferFormat) + : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) +{ + mSwapChain = NULL; + mBackBufferTexture = NULL; + mBackBufferRTView = NULL; + mOffscreenTexture = NULL; + mOffscreenRTView = NULL; + mOffscreenSRView = NULL; + mDepthStencilTexture = NULL; + mDepthStencilDSView = NULL; + mQuadVB = NULL; + mPassThroughSampler = NULL; + mPassThroughIL = NULL; + mPassThroughVS = NULL; + mPassThroughPS = NULL; + mWidth = -1; + mHeight = -1; + mSwapInterval = 0; + mAppCreatedShareHandle = mShareHandle != NULL; + mPassThroughResourcesInit = false; +} + +SwapChain11::~SwapChain11() +{ + release(); +} + +void SwapChain11::release() +{ + SafeRelease(mSwapChain); + SafeRelease(mBackBufferTexture); + SafeRelease(mBackBufferRTView); + SafeRelease(mOffscreenTexture); + SafeRelease(mOffscreenRTView); + SafeRelease(mOffscreenSRView); + SafeRelease(mDepthStencilTexture); + SafeRelease(mDepthStencilDSView); + SafeRelease(mQuadVB); + SafeRelease(mPassThroughSampler); + SafeRelease(mPassThroughIL); + SafeRelease(mPassThroughVS); + SafeRelease(mPassThroughPS); + + if (!mAppCreatedShareHandle) + { + mShareHandle = NULL; + } +} + +void SwapChain11::releaseOffscreenTexture() +{ + SafeRelease(mOffscreenTexture); + SafeRelease(mOffscreenRTView); + SafeRelease(mOffscreenSRView); + SafeRelease(mDepthStencilTexture); + SafeRelease(mDepthStencilDSView); +} + +EGLint SwapChain11::resetOffscreenTexture(int backbufferWidth, int backbufferHeight) +{ + ID3D11Device *device = mRenderer->getDevice(); + + ASSERT(device != NULL); + + // D3D11 does not allow zero size textures + ASSERT(backbufferWidth >= 1); + ASSERT(backbufferHeight >= 1); + + // Preserve the render target content + ID3D11Texture2D *previousOffscreenTexture = mOffscreenTexture; + if (previousOffscreenTexture) + { + previousOffscreenTexture->AddRef(); + } + const int previousWidth = mWidth; + const int previousHeight = mHeight; + + releaseOffscreenTexture(); + + // If the app passed in a share handle, open the resource + // See EGL_ANGLE_d3d_share_handle_client_buffer + if (mAppCreatedShareHandle) + { + ID3D11Resource *tempResource11; + HRESULT result = device->OpenSharedResource(mShareHandle, __uuidof(ID3D11Resource), (void**)&tempResource11); + + if (FAILED(result)) + { + ERR("Failed to open the swap chain pbuffer share handle: %08lX", result); + release(); + return EGL_BAD_PARAMETER; + } + + result = tempResource11->QueryInterface(__uuidof(ID3D11Texture2D), (void**)&mOffscreenTexture); + tempResource11->Release(); + + if (FAILED(result)) + { + ERR("Failed to query texture2d interface in pbuffer share handle: %08lX", result); + release(); + return EGL_BAD_PARAMETER; + } + + // Validate offscreen texture parameters + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; + mOffscreenTexture->GetDesc(&offscreenTextureDesc); + + if (offscreenTextureDesc.Width != (UINT)backbufferWidth + || offscreenTextureDesc.Height != (UINT)backbufferHeight + || offscreenTextureDesc.Format != gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat) + || offscreenTextureDesc.MipLevels != 1 + || offscreenTextureDesc.ArraySize != 1) + { + ERR("Invalid texture parameters in the shared offscreen texture pbuffer"); + release(); + return EGL_BAD_PARAMETER; + } + } + else + { + const bool useSharedResource = !mWindow && mRenderer->getShareHandleSupport(); + + D3D11_TEXTURE2D_DESC offscreenTextureDesc = {0}; + offscreenTextureDesc.Width = backbufferWidth; + offscreenTextureDesc.Height = backbufferHeight; + offscreenTextureDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); + offscreenTextureDesc.MipLevels = 1; + offscreenTextureDesc.ArraySize = 1; + offscreenTextureDesc.SampleDesc.Count = 1; + offscreenTextureDesc.SampleDesc.Quality = 0; + offscreenTextureDesc.Usage = D3D11_USAGE_DEFAULT; + offscreenTextureDesc.BindFlags = D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE; + offscreenTextureDesc.CPUAccessFlags = 0; + offscreenTextureDesc.MiscFlags = useSharedResource ? D3D11_RESOURCE_MISC_SHARED : 0; + + HRESULT result = device->CreateTexture2D(&offscreenTextureDesc, NULL, &mOffscreenTexture); + + if (FAILED(result)) + { + ERR("Could not create offscreen texture: %08lX", result); + release(); + + if (d3d11::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + d3d11::SetDebugName(mOffscreenTexture, "Offscreen texture"); + + // EGL_ANGLE_surface_d3d_texture_2d_share_handle requires that we store a share handle for the client + if (useSharedResource) + { + IDXGIResource *offscreenTextureResource = NULL; + result = mOffscreenTexture->QueryInterface(__uuidof(IDXGIResource), (void**)&offscreenTextureResource); + + // Fall back to no share handle on failure + if (FAILED(result)) + { + ERR("Could not query offscreen texture resource: %08lX", result); + } + else + { + result = offscreenTextureResource->GetSharedHandle(&mShareHandle); + offscreenTextureResource->Release(); + + if (FAILED(result)) + { + mShareHandle = NULL; + ERR("Could not get offscreen texture shared handle: %08lX", result); + } + } + } + } + + HRESULT result = device->CreateRenderTargetView(mOffscreenTexture, NULL, &mOffscreenRTView); + + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mOffscreenRTView, "Offscreen render target"); + + result = device->CreateShaderResourceView(mOffscreenTexture, NULL, &mOffscreenSRView); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mOffscreenSRView, "Offscreen shader resource"); + + if (mDepthBufferFormat != GL_NONE) + { + D3D11_TEXTURE2D_DESC depthStencilDesc = {0}; + depthStencilDesc.Width = backbufferWidth; + depthStencilDesc.Height = backbufferHeight; + depthStencilDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mDepthBufferFormat); + depthStencilDesc.MipLevels = 1; + depthStencilDesc.ArraySize = 1; + depthStencilDesc.SampleDesc.Count = 1; + depthStencilDesc.SampleDesc.Quality = 0; + depthStencilDesc.Usage = D3D11_USAGE_DEFAULT; + depthStencilDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL; + depthStencilDesc.CPUAccessFlags = 0; + depthStencilDesc.MiscFlags = 0; + + result = device->CreateTexture2D(&depthStencilDesc, NULL, &mDepthStencilTexture); + if (FAILED(result)) + { + ERR("Could not create depthstencil surface for new swap chain: 0x%08X", result); + release(); + + if (d3d11::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + d3d11::SetDebugName(mDepthStencilTexture, "Depth stencil texture"); + + result = device->CreateDepthStencilView(mDepthStencilTexture, NULL, &mDepthStencilDSView); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mDepthStencilDSView, "Depth stencil view"); + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + + if (previousOffscreenTexture != NULL) + { + D3D11_BOX sourceBox = {0}; + sourceBox.left = 0; + sourceBox.right = std::min(previousWidth, mWidth); + sourceBox.top = std::max(previousHeight - mHeight, 0); + sourceBox.bottom = previousHeight; + sourceBox.front = 0; + sourceBox.back = 1; + + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + const int yoffset = std::max(mHeight - previousHeight, 0); + deviceContext->CopySubresourceRegion(mOffscreenTexture, 0, 0, yoffset, 0, previousOffscreenTexture, 0, &sourceBox); + + previousOffscreenTexture->Release(); + + if (mSwapChain) + { + swapRect(0, 0, mWidth, mHeight); + } + } + + return EGL_SUCCESS; +} + +EGLint SwapChain11::resize(EGLint backbufferWidth, EGLint backbufferHeight) +{ + ID3D11Device *device = mRenderer->getDevice(); + + if (device == NULL) + { + return EGL_BAD_ACCESS; + } + + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains + if (backbufferWidth < 1 || backbufferHeight < 1) + { + return EGL_SUCCESS; + } + + // Can only call resize if we have already created our swap buffer and resources + ASSERT(mSwapChain && mBackBufferTexture && mBackBufferRTView); + + SafeRelease(mBackBufferTexture); + SafeRelease(mBackBufferRTView); + + // Resize swap chain + DXGI_FORMAT backbufferDXGIFormat = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); + HRESULT result = mSwapChain->ResizeBuffers(2, backbufferWidth, backbufferHeight, backbufferDXGIFormat, 0); + + if (FAILED(result)) + { + ERR("Error resizing swap chain buffers: 0x%08X", result); + release(); + + if (d3d11::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); + ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { + d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); + } + + result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); + ASSERT(SUCCEEDED(result)); + if (SUCCEEDED(result)) + { + d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); + } + + return resetOffscreenTexture(backbufferWidth, backbufferHeight); +} + +EGLint SwapChain11::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) +{ + ID3D11Device *device = mRenderer->getDevice(); + + if (device == NULL) + { + return EGL_BAD_ACCESS; + } + + // Release specific resources to free up memory for the new render target, while the + // old render target still exists for the purpose of preserving its contents. + SafeRelease(mSwapChain); + SafeRelease(mBackBufferTexture); + SafeRelease(mBackBufferRTView); + + mSwapInterval = static_cast(swapInterval); + if (mSwapInterval > 4) + { + // IDXGISwapChain::Present documentation states that valid sync intervals are in the [0,4] range + return EGL_BAD_PARAMETER; + } + + // EGL allows creating a surface with 0x0 dimension, however, DXGI does not like 0x0 swapchains + if (backbufferWidth < 1 || backbufferHeight < 1) + { + releaseOffscreenTexture(); + return EGL_SUCCESS; + } + + if (mWindow) + { +#if !defined(ANGLE_OS_WINRT) + IDXGIFactory *factory = mRenderer->getDxgiFactory(); + + DXGI_SWAP_CHAIN_DESC swapChainDesc = {0}; + swapChainDesc.BufferDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); + swapChainDesc.BufferDesc.Width = backbufferWidth; + swapChainDesc.BufferDesc.Height = backbufferHeight; + swapChainDesc.BufferCount = 2; + swapChainDesc.BufferDesc.Scaling = DXGI_MODE_SCALING_UNSPECIFIED; + swapChainDesc.BufferDesc.ScanlineOrdering = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED; + swapChainDesc.BufferDesc.RefreshRate.Numerator = 0; + swapChainDesc.BufferDesc.RefreshRate.Denominator = 1; + swapChainDesc.Windowed = TRUE; + swapChainDesc.OutputWindow = mWindow; +#else + IDXGIFactory2 *factory; + HRESULT result = mRenderer->getDxgiFactory()->QueryInterface(IID_PPV_ARGS(&factory)); + ASSERT(SUCCEEDED(result)); + + DXGI_SWAP_CHAIN_DESC1 swapChainDesc = {0}; + swapChainDesc.Format = gl_d3d11::ConvertRenderbufferFormat(mBackBufferFormat); + swapChainDesc.Width = backbufferWidth; + swapChainDesc.Height = backbufferHeight; + swapChainDesc.Stereo = FALSE; +#if !defined(ANGLE_OS_WINPHONE) + swapChainDesc.BufferCount = 2; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_FLIP_SEQUENTIAL; +#else + swapChainDesc.BufferCount = 1; + swapChainDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD; +#endif +#endif + swapChainDesc.BufferUsage = DXGI_USAGE_RENDER_TARGET_OUTPUT; + swapChainDesc.Flags = 0; + swapChainDesc.SampleDesc.Count = 1; + swapChainDesc.SampleDesc.Quality = 0; + +#if !defined(ANGLE_OS_WINRT) + HRESULT result = factory->CreateSwapChain(device, &swapChainDesc, &mSwapChain); +#else + IDXGISwapChain1 *swapChain; + result = factory->CreateSwapChainForCoreWindow(device, mWindow, &swapChainDesc, NULL, &swapChain); + mSwapChain = swapChain; +#endif + + if (FAILED(result)) + { + ERR("Could not create additional swap chains or offscreen surfaces: %08lX", result); + release(); + + if (d3d11::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } +#if !defined(ANGLE_OS_WINRT) + else + { + // We cannot create a swap chain for an HWND that is owned by a different process on some versions of + // windows + DWORD currentProcessId = GetCurrentProcessId(); + DWORD wndProcessId; + GetWindowThreadProcessId(mWindow, &wndProcessId); + + if (currentProcessId != wndProcessId) + { + ERR("Could not create swap chain, window owned by different process"); + return EGL_BAD_NATIVE_WINDOW; + } + else + { + return EGL_BAD_ALLOC; + } + } +#else + return EGL_BAD_ALLOC; +#endif + } + + result = mSwapChain->GetBuffer(0, __uuidof(ID3D11Texture2D), (LPVOID*)&mBackBufferTexture); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mBackBufferTexture, "Back buffer texture"); + + result = device->CreateRenderTargetView(mBackBufferTexture, NULL, &mBackBufferRTView); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mBackBufferRTView, "Back buffer render target"); + } + + // If we are resizing the swap chain, we don't wish to recreate all the static resources + if (!mPassThroughResourcesInit) + { + mPassThroughResourcesInit = true; + initPassThroughResources(); + } + + return resetOffscreenTexture(backbufferWidth, backbufferHeight); +} + +void SwapChain11::initPassThroughResources() +{ + ID3D11Device *device = mRenderer->getDevice(); + + ASSERT(device != NULL); + + // Make sure our resources are all not allocated, when we create + ASSERT(mQuadVB == NULL && mPassThroughSampler == NULL); + ASSERT(mPassThroughIL == NULL && mPassThroughVS == NULL && mPassThroughPS == NULL); + + D3D11_BUFFER_DESC vbDesc; + vbDesc.ByteWidth = sizeof(d3d11::PositionTexCoordVertex) * 4; + vbDesc.Usage = D3D11_USAGE_DYNAMIC; + vbDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + vbDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + vbDesc.MiscFlags = 0; + vbDesc.StructureByteStride = 0; + + HRESULT result = device->CreateBuffer(&vbDesc, NULL, &mQuadVB); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mQuadVB, "Swap chain quad vertex buffer"); + + D3D11_SAMPLER_DESC samplerDesc; + samplerDesc.Filter = D3D11_FILTER_MIN_MAG_MIP_POINT; + samplerDesc.AddressU = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressV = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.AddressW = D3D11_TEXTURE_ADDRESS_CLAMP; + samplerDesc.MipLODBias = 0.0f; + samplerDesc.MaxAnisotropy = 0; + samplerDesc.ComparisonFunc = D3D11_COMPARISON_NEVER; + samplerDesc.BorderColor[0] = 0.0f; + samplerDesc.BorderColor[1] = 0.0f; + samplerDesc.BorderColor[2] = 0.0f; + samplerDesc.BorderColor[3] = 0.0f; + samplerDesc.MinLOD = 0; + samplerDesc.MaxLOD = D3D11_FLOAT32_MAX; + + result = device->CreateSamplerState(&samplerDesc, &mPassThroughSampler); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mPassThroughSampler, "Swap chain pass through sampler"); + + D3D11_INPUT_ELEMENT_DESC quadLayout[] = + { + { "POSITION", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 0, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + { "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 8, D3D11_INPUT_PER_VERTEX_DATA, 0 }, + }; + + result = device->CreateInputLayout(quadLayout, 2, g_VS_Passthrough, sizeof(g_VS_Passthrough), &mPassThroughIL); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mPassThroughIL, "Swap chain pass through layout"); + + result = device->CreateVertexShader(g_VS_Passthrough, sizeof(g_VS_Passthrough), NULL, &mPassThroughVS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mPassThroughVS, "Swap chain pass through vertex shader"); + + result = device->CreatePixelShader(g_PS_PassthroughRGBA, sizeof(g_PS_PassthroughRGBA), NULL, &mPassThroughPS); + ASSERT(SUCCEEDED(result)); + d3d11::SetDebugName(mPassThroughPS, "Swap chain pass through pixel shader"); +} + +// parameters should be validated/clamped by caller +EGLint SwapChain11::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (!mSwapChain) + { + return EGL_SUCCESS; + } + + ID3D11Device *device = mRenderer->getDevice(); + ID3D11DeviceContext *deviceContext = mRenderer->getDeviceContext(); + + // Set vertices + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = deviceContext->Map(mQuadVB, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + return EGL_BAD_ACCESS; + } + + d3d11::PositionTexCoordVertex *vertices = static_cast(mappedResource.pData); + + // Create a quad in homogeneous coordinates + float x1 = (x / float(mWidth)) * 2.0f - 1.0f; + float y1 = (y / float(mHeight)) * 2.0f - 1.0f; + float x2 = ((x + width) / float(mWidth)) * 2.0f - 1.0f; + float y2 = ((y + height) / float(mHeight)) * 2.0f - 1.0f; + + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); + float v2 = (y + height) / float(mHeight); + + d3d11::SetPositionTexCoordVertex(&vertices[0], x1, y1, u1, v1); + d3d11::SetPositionTexCoordVertex(&vertices[1], x1, y2, u1, v2); + d3d11::SetPositionTexCoordVertex(&vertices[2], x2, y1, u2, v1); + d3d11::SetPositionTexCoordVertex(&vertices[3], x2, y2, u2, v2); + + deviceContext->Unmap(mQuadVB, 0); + + static UINT stride = sizeof(d3d11::PositionTexCoordVertex); + static UINT startIdx = 0; + deviceContext->IASetVertexBuffers(0, 1, &mQuadVB, &stride, &startIdx); + + // Apply state + deviceContext->OMSetDepthStencilState(NULL, 0xFFFFFFFF); + + static const float blendFactor[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + deviceContext->OMSetBlendState(NULL, blendFactor, 0xFFFFFFF); + + deviceContext->RSSetState(NULL); + + // Apply shaders + deviceContext->IASetInputLayout(mPassThroughIL); + deviceContext->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); + deviceContext->VSSetShader(mPassThroughVS, NULL, 0); + deviceContext->PSSetShader(mPassThroughPS, NULL, 0); + deviceContext->GSSetShader(NULL, NULL, 0); + + // Apply render targets + mRenderer->setOneTimeRenderTarget(mBackBufferRTView); + + // Set the viewport + D3D11_VIEWPORT viewport; + viewport.TopLeftX = 0; + viewport.TopLeftY = 0; + viewport.Width = mWidth; + viewport.Height = mHeight; + viewport.MinDepth = 0.0f; + viewport.MaxDepth = 1.0f; + deviceContext->RSSetViewports(1, &viewport); + + // Apply textures + deviceContext->PSSetShaderResources(0, 1, &mOffscreenSRView); + deviceContext->PSSetSamplers(0, 1, &mPassThroughSampler); + + // Draw + deviceContext->Draw(4, 0); + +#if ANGLE_FORCE_VSYNC_OFF + result = mSwapChain->Present(0, 0); +#else + result = mSwapChain->Present(mSwapInterval, 0); +#endif + + if (result == DXGI_ERROR_DEVICE_REMOVED) + { + HRESULT removedReason = device->GetDeviceRemovedReason(); + ERR("Present failed: the D3D11 device was removed: 0x%08X", removedReason); + return EGL_CONTEXT_LOST; + } + else if (result == DXGI_ERROR_DEVICE_RESET) + { + ERR("Present failed: the D3D11 device was reset from a bad command."); + return EGL_CONTEXT_LOST; + } + else if (FAILED(result)) + { + ERR("Present failed with error code 0x%08X", result); + } + + // Unbind + static ID3D11ShaderResourceView *const nullSRV = NULL; + deviceContext->PSSetShaderResources(0, 1, &nullSRV); + + mRenderer->unapplyRenderTargets(); + mRenderer->markAllStateDirty(); + + return EGL_SUCCESS; +} + +// Increments refcount on texture. +// caller must Release() the returned texture +ID3D11Texture2D *SwapChain11::getOffscreenTexture() +{ + if (mOffscreenTexture) + { + mOffscreenTexture->AddRef(); + } + + return mOffscreenTexture; +} + +// Increments refcount on view. +// caller must Release() the returned view +ID3D11RenderTargetView *SwapChain11::getRenderTarget() +{ + if (mOffscreenRTView) + { + mOffscreenRTView->AddRef(); + } + + return mOffscreenRTView; +} + +// Increments refcount on view. +// caller must Release() the returned view +ID3D11ShaderResourceView *SwapChain11::getRenderTargetShaderResource() +{ + if (mOffscreenSRView) + { + mOffscreenSRView->AddRef(); + } + + return mOffscreenSRView; +} + +// Increments refcount on view. +// caller must Release() the returned view +ID3D11DepthStencilView *SwapChain11::getDepthStencil() +{ + if (mDepthStencilDSView) + { + mDepthStencilDSView->AddRef(); + } + + return mDepthStencilDSView; +} + +ID3D11Texture2D *SwapChain11::getDepthStencilTexture() +{ + if (mDepthStencilTexture) + { + mDepthStencilTexture->AddRef(); + } + + return mDepthStencilTexture; +} + +SwapChain11 *SwapChain11::makeSwapChain11(SwapChain *swapChain) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain11*, swapChain)); + return static_cast(swapChain); +} + +void SwapChain11::recreate() +{ + // possibly should use this method instead of reset +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.h new file mode 100644 index 0000000000..2a030c839d --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/SwapChain11.h @@ -0,0 +1,78 @@ +// +// Copyright (c) 2012 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. +// + +// SwapChain11.h: Defines a back-end specific class for the D3D11 swap chain. + +#ifndef LIBGLESV2_RENDERER_SWAPCHAIN11_H_ +#define LIBGLESV2_RENDERER_SWAPCHAIN11_H_ + +#include "common/angleutils.h" +#include "libGLESv2/renderer/SwapChain.h" + +namespace rx +{ +class Renderer11; + +class SwapChain11 : public SwapChain +{ + public: + SwapChain11(Renderer11 *renderer, EGLNativeWindowType window, HANDLE shareHandle, + GLenum backBufferFormat, GLenum depthBufferFormat); + virtual ~SwapChain11(); + + 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(); + + virtual ID3D11Texture2D *getOffscreenTexture(); + virtual ID3D11RenderTargetView *getRenderTarget(); + virtual ID3D11ShaderResourceView *getRenderTargetShaderResource(); + + virtual ID3D11Texture2D *getDepthStencilTexture(); + virtual ID3D11DepthStencilView *getDepthStencil(); + + EGLint getWidth() const { return mWidth; } + EGLint getHeight() const { return mHeight; } + + static SwapChain11 *makeSwapChain11(SwapChain *swapChain); + + private: + DISALLOW_COPY_AND_ASSIGN(SwapChain11); + + void release(); + void initPassThroughResources(); + void releaseOffscreenTexture(); + EGLint resetOffscreenTexture(int backbufferWidth, int backbufferHeight); + + Renderer11 *mRenderer; + EGLint mHeight; + EGLint mWidth; + bool mAppCreatedShareHandle; + unsigned int mSwapInterval; + bool mPassThroughResourcesInit; + + IDXGISwapChain *mSwapChain; + + ID3D11Texture2D *mBackBufferTexture; + ID3D11RenderTargetView *mBackBufferRTView; + + ID3D11Texture2D *mOffscreenTexture; + ID3D11RenderTargetView *mOffscreenRTView; + ID3D11ShaderResourceView *mOffscreenSRView; + + ID3D11Texture2D *mDepthStencilTexture; + ID3D11DepthStencilView *mDepthStencilDSView; + + ID3D11Buffer *mQuadVB; + ID3D11SamplerState *mPassThroughSampler; + ID3D11InputLayout *mPassThroughIL; + ID3D11VertexShader *mPassThroughVS; + ID3D11PixelShader *mPassThroughPS; +}; + +} +#endif // LIBGLESV2_RENDERER_SWAPCHAIN11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp new file mode 100644 index 0000000000..fdfbe526ec --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.cpp @@ -0,0 +1,667 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// TextureStorage11.cpp: Implements the abstract rx::TextureStorage11 class and its concrete derived +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. + +#include "libGLESv2/renderer/d3d11/TextureStorage11.h" + +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/renderer/d3d11/RenderTarget11.h" +#include "libGLESv2/renderer/d3d11/SwapChain11.h" +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" + +#include "libGLESv2/utilities.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +TextureStorage11::TextureStorage11(Renderer *renderer, UINT bindFlags) + : mBindFlags(bindFlags), + mLodOffset(0), + mMipLevels(0), + mTexture(NULL), + mTextureFormat(DXGI_FORMAT_UNKNOWN), + mShaderResourceFormat(DXGI_FORMAT_UNKNOWN), + mRenderTargetFormat(DXGI_FORMAT_UNKNOWN), + mDepthStencilFormat(DXGI_FORMAT_UNKNOWN), + mSRV(NULL), + mTextureWidth(0), + mTextureHeight(0) +{ + mRenderer = Renderer11::makeRenderer11(renderer); +} + +TextureStorage11::~TextureStorage11() +{ +} + +TextureStorage11 *TextureStorage11::makeTextureStorage11(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11*, storage)); + return static_cast(storage); +} + +DWORD TextureStorage11::GetTextureBindFlags(DXGI_FORMAT format, GLenum glusage, bool forceRenderable) +{ + UINT bindFlags = D3D11_BIND_SHADER_RESOURCE; + + if (d3d11::IsDepthStencilFormat(format)) + { + bindFlags |= D3D11_BIND_DEPTH_STENCIL; + } + else if(forceRenderable || (TextureStorage11::IsTextureFormatRenderable(format) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) + { + bindFlags |= D3D11_BIND_RENDER_TARGET; + } + return bindFlags; +} + +bool TextureStorage11::IsTextureFormatRenderable(DXGI_FORMAT format) +{ + switch(format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_A8_UNORM: + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_R8_UNORM: + case DXGI_FORMAT_R8G8_UNORM: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_R16G16_FLOAT: + return true; + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_R32G32B32_FLOAT: // not renderable on all devices + return false; + default: + UNREACHABLE(); + return false; + } +} + +UINT TextureStorage11::getBindFlags() const +{ + return mBindFlags; +} + +ID3D11Texture2D *TextureStorage11::getBaseTexture() const +{ + return mTexture; +} + +int TextureStorage11::getLodOffset() const +{ + return mLodOffset; +} + +bool TextureStorage11::isRenderTarget() const +{ + return (mBindFlags & (D3D11_BIND_RENDER_TARGET | D3D11_BIND_DEPTH_STENCIL)) != 0; +} + +bool TextureStorage11::isManaged() const +{ + return false; +} + +int TextureStorage11::levelCount() +{ + int levels = 0; + if (getBaseTexture()) + { + levels = mMipLevels - getLodOffset(); + } + return levels; +} + +UINT TextureStorage11::getSubresourceIndex(int level, int faceIndex) +{ + UINT index = 0; + if (getBaseTexture()) + { + index = D3D11CalcSubresource(level, faceIndex, mMipLevels); + } + return index; +} + +bool TextureStorage11::updateSubresourceLevel(ID3D11Texture2D *srcTexture, unsigned int sourceSubresource, + int level, int face, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height) +{ + if (srcTexture) + { + // Round up the width and height to the nearest multiple of dimension alignment + unsigned int dimensionAlignment = d3d11::GetTextureFormatDimensionAlignment(mTextureFormat); + width = width + dimensionAlignment - 1 - (width - 1) % dimensionAlignment; + height = height + dimensionAlignment - 1 - (height - 1) % dimensionAlignment; + + D3D11_BOX srcBox; + srcBox.left = xoffset; + srcBox.top = yoffset; + srcBox.right = xoffset + width; + srcBox.bottom = yoffset + height; + srcBox.front = 0; + srcBox.back = 1; + + ID3D11DeviceContext *context = mRenderer->getDeviceContext(); + + ASSERT(getBaseTexture()); + context->CopySubresourceRegion(getBaseTexture(), getSubresourceIndex(level + mLodOffset, face), + xoffset, yoffset, 0, srcTexture, sourceSubresource, &srcBox); + return true; + } + + return false; +} + +void TextureStorage11::generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest) +{ + if (source && dest) + { + ID3D11ShaderResourceView *sourceSRV = source->getShaderResourceView(); + ID3D11RenderTargetView *destRTV = dest->getRenderTargetView(); + + if (sourceSRV && destRTV) + { + gl::Rectangle sourceArea; + sourceArea.x = 0; + sourceArea.y = 0; + sourceArea.width = source->getWidth(); + sourceArea.height = source->getHeight(); + + gl::Rectangle destArea; + destArea.x = 0; + destArea.y = 0; + destArea.width = dest->getWidth(); + destArea.height = dest->getHeight(); + + mRenderer->copyTexture(sourceSRV, sourceArea, source->getWidth(), source->getHeight(), + destRTV, destArea, dest->getWidth(), dest->getHeight(), + GL_RGBA); + } + } +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain) + : TextureStorage11(renderer, D3D11_BIND_RENDER_TARGET | D3D11_BIND_SHADER_RESOURCE) +{ + mTexture = swapchain->getOffscreenTexture(); + mSRV = swapchain->getRenderTargetShaderResource(); + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mRenderTarget[i] = NULL; + } + + D3D11_TEXTURE2D_DESC texDesc; + mTexture->GetDesc(&texDesc); + mMipLevels = texDesc.MipLevels; + mTextureFormat = texDesc.Format; + mTextureWidth = texDesc.Width; + mTextureHeight = texDesc.Height; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + mSRV->GetDesc(&srvDesc); + mShaderResourceFormat = srvDesc.Format; + + ID3D11RenderTargetView* offscreenRTV = swapchain->getRenderTarget(); + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + offscreenRTV->GetDesc(&rtvDesc); + mRenderTargetFormat = rtvDesc.Format; + offscreenRTV->Release(); + + mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; +} + +TextureStorage11_2D::TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) + : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable)) +{ + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + mRenderTarget[i] = NULL; + } + + DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel()); + if (d3d11::IsDepthStencilFormat(convertedFormat)) + { + mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat); + mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat); + mDepthStencilFormat = convertedFormat; + mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; + } + else + { + mTextureFormat = convertedFormat; + mShaderResourceFormat = convertedFormat; + mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; + mRenderTargetFormat = convertedFormat; + } + + // 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 (width > 0 && height > 0) + { + // adjust size if needed for compressed textures + gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = width; // Compressed texture size constraints? + desc.Height = height; + desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0; + desc.ArraySize = 1; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = 0; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + // this can happen from windows TDR + if (d3d11::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + gl::error(GL_OUT_OF_MEMORY); + } + else if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + gl::error(GL_OUT_OF_MEMORY); + } + else + { + mTexture->GetDesc(&desc); + mMipLevels = desc.MipLevels; + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + } + } +} + +TextureStorage11_2D::~TextureStorage11_2D() +{ + if (mTexture) + { + mTexture->Release(); + mTexture = NULL; + } + + if (mSRV) + { + mSRV->Release(); + mSRV = NULL; + } + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; i++) + { + delete mRenderTarget[i]; + mRenderTarget[i] = NULL; + } +} + +TextureStorage11_2D *TextureStorage11_2D::makeTextureStorage11_2D(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_2D*, storage)); + return static_cast(storage); +} + +RenderTarget *TextureStorage11_2D::getRenderTarget(int level) +{ + if (level >= 0 && level < static_cast(mMipLevels)) + { + if (!mRenderTarget[level]) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MostDetailedMip = level; + srvDesc.Texture2D.MipLevels = level ? 1 : -1; + + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D; + rtvDesc.Texture2D.MipSlice = level; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + srv->Release(); + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + + // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 + // also needs to keep a reference to the texture. + mTexture->AddRef(); + + mRenderTarget[level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, + std::max(mTextureWidth >> level, 1U), + std::max(mTextureHeight >> level, 1U)); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mDepthStencilFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D; + dsvDesc.Texture2D.MipSlice = level; + dsvDesc.Flags = 0; + + ID3D11DepthStencilView *dsv; + result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + + if (result == E_OUTOFMEMORY) + { + srv->Release(); + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + + // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 + // also needs to keep a reference to the texture. + mTexture->AddRef(); + + mRenderTarget[level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, + std::max(mTextureWidth >> level, 1U), + std::max(mTextureHeight >> level, 1U)); + } + else + { + UNREACHABLE(); + } + } + + return mRenderTarget[level]; + } + else + { + return NULL; + } +} + +ID3D11ShaderResourceView *TextureStorage11_2D::getSRV() +{ + if (!mSRV) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D; + srvDesc.Texture2D.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels); + srvDesc.Texture2D.MostDetailedMip = 0; + + HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSRV; +} + +void TextureStorage11_2D::generateMipmap(int level) +{ + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(level - 1)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(level)); + + generateMipmapLayer(source, dest); +} + +TextureStorage11_Cube::TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) + : TextureStorage11(renderer, GetTextureBindFlags(gl_d3d11::ConvertTextureFormat(internalformat, Renderer11::makeRenderer11(renderer)->getFeatureLevel()), usage, forceRenderable)) +{ + for (unsigned int i = 0; i < 6; i++) + { + for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++) + { + mRenderTarget[i][j] = NULL; + } + } + + DXGI_FORMAT convertedFormat = gl_d3d11::ConvertTextureFormat(internalformat, mRenderer->getFeatureLevel()); + if (d3d11::IsDepthStencilFormat(convertedFormat)) + { + mTextureFormat = d3d11::GetDepthTextureFormat(convertedFormat); + mShaderResourceFormat = d3d11::GetDepthShaderResourceFormat(convertedFormat); + mDepthStencilFormat = convertedFormat; + mRenderTargetFormat = DXGI_FORMAT_UNKNOWN; + } + else + { + mTextureFormat = convertedFormat; + mShaderResourceFormat = convertedFormat; + mDepthStencilFormat = DXGI_FORMAT_UNKNOWN; + mRenderTargetFormat = convertedFormat; + } + + // 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 (size > 0) + { + // adjust size if needed for compressed textures + int height = size; + gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset); + + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_TEXTURE2D_DESC desc; + desc.Width = size; + desc.Height = size; + desc.MipLevels = (levels > 0) ? levels + mLodOffset : 0; + desc.ArraySize = 6; + desc.Format = mTextureFormat; + desc.SampleDesc.Count = 1; + desc.SampleDesc.Quality = 0; + desc.Usage = D3D11_USAGE_DEFAULT; + desc.BindFlags = getBindFlags(); + desc.CPUAccessFlags = 0; + desc.MiscFlags = D3D11_RESOURCE_MISC_TEXTURECUBE; + + HRESULT result = device->CreateTexture2D(&desc, NULL, &mTexture); + + if (FAILED(result)) + { + ASSERT(result == E_OUTOFMEMORY); + ERR("Creating image failed."); + gl::error(GL_OUT_OF_MEMORY); + } + else + { + mTexture->GetDesc(&desc); + mMipLevels = desc.MipLevels; + mTextureWidth = desc.Width; + mTextureHeight = desc.Height; + } + } +} + +TextureStorage11_Cube::~TextureStorage11_Cube() +{ + if (mTexture) + { + mTexture->Release(); + mTexture = NULL; + } + + if (mSRV) + { + mSRV->Release(); + mSRV = NULL; + } + + for (unsigned int i = 0; i < 6; i++) + { + for (unsigned int j = 0; j < gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS; j++) + { + delete mRenderTarget[i][j]; + mRenderTarget[i][j] = NULL; + } + } +} + +TextureStorage11_Cube *TextureStorage11_Cube::makeTextureStorage11_Cube(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage11_Cube*, storage)); + return static_cast(storage); +} + +RenderTarget *TextureStorage11_Cube::getRenderTarget(GLenum faceTarget, int level) +{ + unsigned int faceIdx = gl::TextureCubeMap::faceIndex(faceTarget); + if (level >= 0 && level < static_cast(mMipLevels)) + { + if (!mRenderTarget[faceIdx][level]) + { + ID3D11Device *device = mRenderer->getDevice(); + HRESULT result; + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY; // Will be used with Texture2D sampler, not TextureCube + srvDesc.Texture2DArray.MostDetailedMip = level; + srvDesc.Texture2DArray.MipLevels = 1; + srvDesc.Texture2DArray.FirstArraySlice = faceIdx; + srvDesc.Texture2DArray.ArraySize = 1; + + ID3D11ShaderResourceView *srv; + result = device->CreateShaderResourceView(mTexture, &srvDesc, &srv); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + + if (mRenderTargetFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_RENDER_TARGET_VIEW_DESC rtvDesc; + rtvDesc.Format = mRenderTargetFormat; + rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2DARRAY; + rtvDesc.Texture2DArray.MipSlice = level; + rtvDesc.Texture2DArray.FirstArraySlice = faceIdx; + rtvDesc.Texture2DArray.ArraySize = 1; + + ID3D11RenderTargetView *rtv; + result = device->CreateRenderTargetView(mTexture, &rtvDesc, &rtv); + + if (result == E_OUTOFMEMORY) + { + srv->Release(); + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + + // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 + // also needs to keep a reference to the texture. + mTexture->AddRef(); + + mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, rtv, mTexture, srv, + std::max(mTextureWidth >> level, 1U), + std::max(mTextureHeight >> level, 1U)); + } + else if (mDepthStencilFormat != DXGI_FORMAT_UNKNOWN) + { + D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc; + dsvDesc.Format = mRenderTargetFormat; + dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2DARRAY; + dsvDesc.Texture2DArray.MipSlice = level; + dsvDesc.Texture2DArray.FirstArraySlice = faceIdx; + dsvDesc.Texture2DArray.ArraySize = 1; + + ID3D11DepthStencilView *dsv; + result = device->CreateDepthStencilView(mTexture, &dsvDesc, &dsv); + + if (result == E_OUTOFMEMORY) + { + srv->Release(); + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + + // RenderTarget11 expects to be the owner of the resources it is given but TextureStorage11 + // also needs to keep a reference to the texture. + mTexture->AddRef(); + + mRenderTarget[faceIdx][level] = new RenderTarget11(mRenderer, dsv, mTexture, srv, + std::max(mTextureWidth >> level, 1U), + std::max(mTextureHeight >> level, 1U)); + } + else + { + UNREACHABLE(); + } + } + + return mRenderTarget[faceIdx][level]; + } + else + { + return NULL; + } +} + +ID3D11ShaderResourceView *TextureStorage11_Cube::getSRV() +{ + if (!mSRV) + { + ID3D11Device *device = mRenderer->getDevice(); + + D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc; + srvDesc.Format = mShaderResourceFormat; + srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE; + srvDesc.TextureCube.MipLevels = (mMipLevels == 0 ? -1 : mMipLevels); + srvDesc.TextureCube.MostDetailedMip = 0; + + HRESULT result = device->CreateShaderResourceView(mTexture, &srvDesc, &mSRV); + + if (result == E_OUTOFMEMORY) + { + return gl::error(GL_OUT_OF_MEMORY, static_cast(NULL)); + } + ASSERT(SUCCEEDED(result)); + } + + return mSRV; +} + +void TextureStorage11_Cube::generateMipmap(int face, int level) +{ + RenderTarget11 *source = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1)); + RenderTarget11 *dest = RenderTarget11::makeRenderTarget11(getRenderTarget(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level)); + + generateMipmapLayer(source, dest); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h new file mode 100644 index 0000000000..3c5ded05b8 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/TextureStorage11.h @@ -0,0 +1,120 @@ +// +// Copyright (c) 2012 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. +// + +// TextureStorage11.h: Defines the abstract rx::TextureStorage11 class and its concrete derived +// classes TextureStorage11_2D and TextureStorage11_Cube, which act as the interface to the D3D11 texture. + +#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ +#define LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ + +#include "libGLESv2/Texture.h" +#include "libGLESv2/renderer/TextureStorage.h" + +namespace rx +{ +class RenderTarget; +class RenderTarget11; +class Renderer; +class Renderer11; +class SwapChain11; + +class TextureStorage11 : public TextureStorage +{ + public: + TextureStorage11(Renderer *renderer, UINT bindFlags); + virtual ~TextureStorage11(); + + static TextureStorage11 *makeTextureStorage11(TextureStorage *storage); + + static DWORD GetTextureBindFlags(DXGI_FORMAT d3dfmt, GLenum glusage, bool forceRenderable); + static bool IsTextureFormatRenderable(DXGI_FORMAT format); + + UINT getBindFlags() const; + + virtual ID3D11Texture2D *getBaseTexture() const; + virtual ID3D11ShaderResourceView *getSRV() = 0; + virtual RenderTarget *getRenderTarget() { return getRenderTarget(0); } + virtual RenderTarget *getRenderTarget(int level) { return NULL; } + virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return getRenderTarget(faceTarget, 0); } + virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level) { return NULL; } + + virtual void generateMipmap(int level) {}; + virtual void generateMipmap(int face, int level) {}; + + virtual int getLodOffset() const; + virtual bool isRenderTarget() const; + virtual bool isManaged() const; + virtual int levelCount(); + UINT getSubresourceIndex(int level, int faceTarget); + + bool updateSubresourceLevel(ID3D11Texture2D *texture, unsigned int sourceSubresource, int level, + int faceTarget, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + + protected: + void generateMipmapLayer(RenderTarget11 *source, RenderTarget11 *dest); + + Renderer11 *mRenderer; + int mLodOffset; + unsigned int mMipLevels; + + ID3D11Texture2D *mTexture; + DXGI_FORMAT mTextureFormat; + DXGI_FORMAT mShaderResourceFormat; + DXGI_FORMAT mRenderTargetFormat; + DXGI_FORMAT mDepthStencilFormat; + unsigned int mTextureWidth; + unsigned int mTextureHeight; + + ID3D11ShaderResourceView *mSRV; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11); + + const UINT mBindFlags; +}; + +class TextureStorage11_2D : public TextureStorage11 +{ + public: + TextureStorage11_2D(Renderer *renderer, SwapChain11 *swapchain); + TextureStorage11_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); + virtual ~TextureStorage11_2D(); + + static TextureStorage11_2D *makeTextureStorage11_2D(TextureStorage *storage); + + virtual ID3D11ShaderResourceView *getSRV(); + virtual RenderTarget *getRenderTarget(int level); + + virtual void generateMipmap(int level); + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11_2D); + + RenderTarget11 *mRenderTarget[gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +class TextureStorage11_Cube : public TextureStorage11 +{ + public: + TextureStorage11_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + virtual ~TextureStorage11_Cube(); + + static TextureStorage11_Cube *makeTextureStorage11_Cube(TextureStorage *storage); + + virtual ID3D11ShaderResourceView *getSRV(); + virtual RenderTarget *getRenderTarget(GLenum faceTarget, int level); + + virtual void generateMipmap(int face, int level); + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage11_Cube); + + RenderTarget11 *mRenderTarget[6][gl::IMPLEMENTATION_MAX_TEXTURE_LEVELS]; +}; + +} + +#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp new file mode 100644 index 0000000000..6f9b4181f1 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.cpp @@ -0,0 +1,440 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// VertexBuffer11.cpp: Defines the D3D11 VertexBuffer implementation. + +#include "libGLESv2/renderer/d3d11/VertexBuffer11.h" +#include "libGLESv2/renderer/BufferStorage.h" + +#include "libGLESv2/Buffer.h" +#include "libGLESv2/renderer/d3d11/Renderer11.h" +#include "libGLESv2/Context.h" + +namespace rx +{ + +VertexBuffer11::VertexBuffer11(rx::Renderer11 *const renderer) : mRenderer(renderer) +{ + mBuffer = NULL; + mBufferSize = 0; + mDynamicUsage = false; +} + +VertexBuffer11::~VertexBuffer11() +{ + if (mBuffer) + { + mBuffer->Release(); + mBuffer = NULL; + } +} + +bool VertexBuffer11::initialize(unsigned int size, bool dynamicUsage) +{ + if (mBuffer) + { + mBuffer->Release(); + mBuffer = NULL; + } + + updateSerial(); + + if (size > 0) + { + ID3D11Device* dxDevice = mRenderer->getDevice(); + + D3D11_BUFFER_DESC bufferDesc; + bufferDesc.ByteWidth = size; + bufferDesc.Usage = D3D11_USAGE_DYNAMIC; + bufferDesc.BindFlags = D3D11_BIND_VERTEX_BUFFER; + bufferDesc.CPUAccessFlags = D3D11_CPU_ACCESS_WRITE; + bufferDesc.MiscFlags = 0; + bufferDesc.StructureByteStride = 0; + + HRESULT result = dxDevice->CreateBuffer(&bufferDesc, NULL, &mBuffer); + if (FAILED(result)) + { + return false; + } + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + return true; +} + +VertexBuffer11 *VertexBuffer11::makeVertexBuffer11(VertexBuffer *vetexBuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer11*, vetexBuffer)); + return static_cast(vetexBuffer); +} + +bool VertexBuffer11::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, + GLsizei instances, unsigned int offset) +{ + if (mBuffer) + { + gl::Buffer *buffer = attrib.mBoundBuffer.get(); + + int inputStride = attrib.stride(); + const VertexConverter &converter = getVertexConversion(attrib); + + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Vertex buffer map failed with error 0x%08x", result); + return false; + } + + char* output = reinterpret_cast(mappedResource.pData) + offset; + + const char *input = NULL; + if (buffer) + { + BufferStorage *storage = buffer->getStorage(); + input = static_cast(storage->getData()) + static_cast(attrib.mOffset); + } + else + { + input = static_cast(attrib.mPointer); + } + + if (instances == 0 || attrib.mDivisor == 0) + { + input += inputStride * start; + } + + converter.conversionFunc(input, inputStride, count, output); + + dxContext->Unmap(mBuffer, 0); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +bool VertexBuffer11::storeRawData(const void* data, unsigned int size, unsigned int offset) +{ + if (mBuffer) + { + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_NO_OVERWRITE, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Vertex buffer map failed with error 0x%08x", result); + return false; + } + + char* bufferData = static_cast(mappedResource.pData); + memcpy(bufferData + offset, data, size); + + dxContext->Unmap(mBuffer, 0); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +bool VertexBuffer11::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, + GLsizei instances, unsigned int *outSpaceRequired) const +{ + unsigned int elementSize = getVertexConversion(attrib).outputElementSize; + + unsigned int elementCount = 0; + if (instances == 0 || attrib.mDivisor == 0) + { + elementCount = count; + } + else + { + if (static_cast(instances) < std::numeric_limits::max() - (attrib.mDivisor - 1)) + { + // Round up + elementCount = (static_cast(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; + } + else + { + elementCount = instances / attrib.mDivisor; + } + } + + if (elementSize <= std::numeric_limits::max() / elementCount) + { + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * elementCount; + } + return true; + } + else + { + return false; + } +} + +bool VertexBuffer11::requiresConversion(const gl::VertexAttribute &attrib) const +{ + return !getVertexConversion(attrib).identity; +} + +unsigned int VertexBuffer11::getBufferSize() const +{ + return mBufferSize; +} + +bool VertexBuffer11::setBufferSize(unsigned int size) +{ + if (size > mBufferSize) + { + return initialize(size, mDynamicUsage); + } + else + { + return true; + } +} + +bool VertexBuffer11::discard() +{ + if (mBuffer) + { + ID3D11DeviceContext *dxContext = mRenderer->getDeviceContext(); + + D3D11_MAPPED_SUBRESOURCE mappedResource; + HRESULT result = dxContext->Map(mBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &mappedResource); + if (FAILED(result)) + { + ERR("Vertex buffer map failed with error 0x%08x", result); + return false; + } + + dxContext->Unmap(mBuffer, 0); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +unsigned int VertexBuffer11::getVertexSize(const gl::VertexAttribute &attrib) const +{ + return getVertexConversion(attrib).outputElementSize; +} + +DXGI_FORMAT VertexBuffer11::getDXGIFormat(const gl::VertexAttribute &attrib) const +{ + return getVertexConversion(attrib).dxgiFormat; +} + +ID3D11Buffer *VertexBuffer11::getBuffer() const +{ + return mBuffer; +} + +template +static void copyVertexData(const void *input, unsigned int stride, unsigned int count, void *output) +{ + unsigned int attribSize = sizeof(T) * componentCount; + + if (attribSize == stride && !widen) + { + memcpy(output, input, count * attribSize); + } + else + { + unsigned int outputStride = widen ? 4 : componentCount; + T defaultVal = normalized ? std::numeric_limits::max() : T(1); + + for (unsigned int i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(reinterpret_cast(input) + i * stride); + T *offsetOutput = reinterpret_cast(output) + i * outputStride; + + for (unsigned int j = 0; j < componentCount; j++) + { + offsetOutput[j] = offsetInput[j]; + } + + if (widen) + { + offsetOutput[3] = defaultVal; + } + } + } +} + +template +static void copyFixedVertexData(const void* input, unsigned int stride, unsigned int count, void* output) +{ + static const float divisor = 1.0f / (1 << 16); + + for (unsigned int i = 0; i < count; i++) + { + const GLfixed* offsetInput = reinterpret_cast(reinterpret_cast(input) + stride * i); + float* offsetOutput = reinterpret_cast(output) + i * componentCount; + + for (unsigned int j = 0; j < componentCount; j++) + { + offsetOutput[j] = static_cast(offsetInput[j]) * divisor; + } + } +} + +template +static void copyToFloatVertexData(const void* input, unsigned int stride, unsigned int count, void* output) +{ + typedef std::numeric_limits NL; + + for (unsigned int i = 0; i < count; i++) + { + const T *offsetInput = reinterpret_cast(reinterpret_cast(input) + stride * i); + float *offsetOutput = reinterpret_cast(output) + i * componentCount; + + for (unsigned int j = 0; j < componentCount; j++) + { + if (normalized) + { + if (NL::is_signed) + { + const float divisor = 1.0f / (2 * static_cast(NL::max()) + 1); + offsetOutput[j] = (2 * static_cast(offsetInput[j]) + 1) * divisor; + } + else + { + offsetOutput[j] = static_cast(offsetInput[j]) / NL::max(); + } + } + else + { + offsetOutput[j] = static_cast(offsetInput[j]); + } + } + } +} + +const VertexBuffer11::VertexConverter VertexBuffer11::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = +{ + { // GL_BYTE + { // unnormalized + { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + { // normalized + { ©VertexData, true, DXGI_FORMAT_R8_SNORM, 1 }, + { ©VertexData, true, DXGI_FORMAT_R8G8_SNORM, 2 }, + { ©VertexData, false, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, + { ©VertexData, true, DXGI_FORMAT_R8G8B8A8_SNORM, 4 }, + }, + }, + { // GL_UNSIGNED_BYTE + { // unnormalized + { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + { // normalized + { ©VertexData, true, DXGI_FORMAT_R8_UNORM, 1 }, + { ©VertexData, true, DXGI_FORMAT_R8G8_UNORM, 2 }, + { ©VertexData, false, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, + { ©VertexData, true, DXGI_FORMAT_R8G8B8A8_UNORM, 4 }, + }, + }, + { // GL_SHORT + { // unnormalized + { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + { // normalized + { ©VertexData, true, DXGI_FORMAT_R16_SNORM, 2 }, + { ©VertexData, true, DXGI_FORMAT_R16G16_SNORM, 4 }, + { ©VertexData, false, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, + { ©VertexData, true, DXGI_FORMAT_R16G16B16A16_SNORM, 8 }, + }, + }, + { // GL_UNSIGNED_SHORT + { // unnormalized + { ©ToFloatVertexData, false, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©ToFloatVertexData, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + { // normalized + { ©VertexData, true, DXGI_FORMAT_R16_UNORM, 2 }, + { ©VertexData, true, DXGI_FORMAT_R16G16_UNORM, 4 }, + { ©VertexData, false, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, + { ©VertexData, true, DXGI_FORMAT_R16G16B16A16_UNORM, 8 }, + }, + }, + { // GL_FIXED + { // unnormalized + { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + { // normalized + { ©FixedVertexData<1>, false, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©FixedVertexData<2>, false, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©FixedVertexData<3>, false, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©FixedVertexData<4>, false, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + }, + { // GL_FLOAT + { // unnormalized + { ©VertexData, true, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©VertexData, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©VertexData, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©VertexData, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + { // normalized + { ©VertexData, true, DXGI_FORMAT_R32_FLOAT, 4 }, + { ©VertexData, true, DXGI_FORMAT_R32G32_FLOAT, 8 }, + { ©VertexData, true, DXGI_FORMAT_R32G32B32_FLOAT, 12 }, + { ©VertexData, true, DXGI_FORMAT_R32G32B32A32_FLOAT, 16 }, + }, + }, +}; + +const VertexBuffer11::VertexConverter &VertexBuffer11::getVertexConversion(const gl::VertexAttribute &attribute) +{ + unsigned int typeIndex = 0; + switch (attribute.mType) + { + case GL_BYTE: typeIndex = 0; break; + case GL_UNSIGNED_BYTE: typeIndex = 1; break; + case GL_SHORT: typeIndex = 2; break; + case GL_UNSIGNED_SHORT: typeIndex = 3; break; + case GL_FIXED: typeIndex = 4; break; + case GL_FLOAT: typeIndex = 5; break; + default: UNREACHABLE(); break; + } + + return mPossibleTranslations[typeIndex][attribute.mNormalized ? 1 : 0][attribute.mSize - 1]; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.h new file mode 100644 index 0000000000..eceb426e82 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/VertexBuffer11.h @@ -0,0 +1,74 @@ +// +// Copyright (c) 2012 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. +// + +// VertexBuffer11.h: Defines the D3D11 VertexBuffer implementation. + +#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ +#define LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ + +#include "libGLESv2/renderer/VertexBuffer.h" + +namespace rx +{ +class Renderer11; + +class VertexBuffer11 : public VertexBuffer +{ + public: + explicit VertexBuffer11(rx::Renderer11 *const renderer); + virtual ~VertexBuffer11(); + + virtual bool initialize(unsigned int size, bool dynamicUsage); + + static VertexBuffer11 *makeVertexBuffer11(VertexBuffer *vetexBuffer); + + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, + unsigned int offset); + virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); + + virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const; + + virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; + + virtual unsigned int getBufferSize() const; + virtual bool setBufferSize(unsigned int size); + virtual bool discard(); + + unsigned int getVertexSize(const gl::VertexAttribute &attrib) const; + DXGI_FORMAT getDXGIFormat(const gl::VertexAttribute &attrib) const; + + ID3D11Buffer *getBuffer() const; + + private: + DISALLOW_COPY_AND_ASSIGN(VertexBuffer11); + + rx::Renderer11 *const mRenderer; + + ID3D11Buffer *mBuffer; + unsigned int mBufferSize; + bool mDynamicUsage; + + typedef void (*VertexConversionFunction)(const void *, unsigned int, unsigned int, void *); + struct VertexConverter + { + VertexConversionFunction conversionFunc; + bool identity; + DXGI_FORMAT dxgiFormat; + unsigned int outputElementSize; + }; + + enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; + + // This table is used to generate mAttributeTypes. + static const VertexConverter mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; // [GL types as enumerated by typeIndex()][normalized][size - 1] + + static const VertexConverter &getVertexConversion(const gl::VertexAttribute &attribute); +}; + +} + +#endif // LIBGLESV2_RENDERER_VERTEXBUFFER11_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp new file mode 100644 index 0000000000..34b8259a80 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.cpp @@ -0,0 +1,688 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// renderer11_utils.cpp: Conversion functions and other utility routines +// specific to the D3D11 renderer. + +#include "libGLESv2/renderer/d3d11/renderer11_utils.h" + +#include "common/debug.h" + +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) +{ + D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; + + switch (glBlend) + { + case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break; + case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break; + case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break; + case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break; + case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break; + case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break; + case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break; + case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break; + case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break; + case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; + case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; + case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; + case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; + case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break; + default: UNREACHABLE(); + } + + return d3dBlend; +} + +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) +{ + D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; + + switch (glBlendOp) + { + case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break; + case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break; + case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break; + default: UNREACHABLE(); + } + + return d3dBlendOp; +} + +UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + UINT8 mask = 0; + if (red) + { + mask |= D3D11_COLOR_WRITE_ENABLE_RED; + } + if (green) + { + mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; + } + if (blue) + { + mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; + } + if (alpha) + { + mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; + } + return mask; +} + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode) +{ + D3D11_CULL_MODE cull = D3D11_CULL_NONE; + + if (cullEnabled) + { + switch (cullMode) + { + case GL_FRONT: cull = D3D11_CULL_FRONT; break; + case GL_BACK: cull = D3D11_CULL_BACK; break; + case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break; + default: UNREACHABLE(); + } + } + else + { + cull = D3D11_CULL_NONE; + } + + return cull; +} + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) +{ + D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; + switch (comparison) + { + case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break; + case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break; + case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break; + case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break; + case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break; + case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break; + case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break; + case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break; + default: UNREACHABLE(); + } + + return d3dComp; +} + +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) +{ + return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; +} + +UINT8 ConvertStencilMask(GLuint stencilmask) +{ + return static_cast(stencilmask); +} + +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) +{ + D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break; + case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break; + case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break; + case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break; + case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break; + case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break; + case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break; + case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break; + default: UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy) +{ + if (maxAnisotropy > 1.0f) + { + return D3D11_ENCODE_ANISOTROPIC_FILTER(false); + } + else + { + D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; + D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; + switch (minFilter) + { + case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; + case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break; + case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break; + default: UNREACHABLE(); + } + + D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; + switch (magFilter) + { + case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break; + case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break; + default: UNREACHABLE(); + } + + return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, false); + } +} + +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) +{ + switch (wrap) + { + case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP; + case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP; + case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR; + default: UNREACHABLE(); + } + + return D3D11_TEXTURE_ADDRESS_WRAP; +} + +FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset) +{ + return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast(lodOffset) : -FLT_MAX; +} + +FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset) +{ + return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast(lodOffset) : FLT_MAX; +} + +} + +namespace d3d11_gl +{ + +GLenum ConvertBackBufferFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES; + case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT; + default: + UNREACHABLE(); + } + + return GL_RGBA8_OES; +} + +GLenum ConvertDepthStencilFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_UNKNOWN: return GL_NONE; + case DXGI_FORMAT_D16_UNORM: return GL_DEPTH_COMPONENT16; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES; + default: + UNREACHABLE(); + } + + return GL_DEPTH24_STENCIL8_OES; +} + +GLenum ConvertRenderbufferFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_B8G8R8A8_UNORM: + return GL_BGRA8_EXT; + case DXGI_FORMAT_R8G8B8A8_UNORM: + return GL_RGBA8_OES; + case DXGI_FORMAT_D16_UNORM: + return GL_DEPTH_COMPONENT16; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + return GL_DEPTH24_STENCIL8_OES; + default: + UNREACHABLE(); + } + + return GL_RGBA8_OES; +} + +GLenum ConvertTextureInternalFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R8G8B8A8_UNORM: + return GL_RGBA8_OES; + case DXGI_FORMAT_A8_UNORM: + return GL_ALPHA8_EXT; + case DXGI_FORMAT_BC1_UNORM: + return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case DXGI_FORMAT_BC2_UNORM: + return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + case DXGI_FORMAT_BC3_UNORM: + return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; + case DXGI_FORMAT_R32G32B32A32_FLOAT: + return GL_RGBA32F_EXT; + case DXGI_FORMAT_R32G32B32_FLOAT: + return GL_RGB32F_EXT; + case DXGI_FORMAT_R16G16B16A16_FLOAT: + return GL_RGBA16F_EXT; + case DXGI_FORMAT_B8G8R8A8_UNORM: + return GL_BGRA8_EXT; + case DXGI_FORMAT_R8_UNORM: + return GL_R8_EXT; + case DXGI_FORMAT_R8G8_UNORM: + return GL_RG8_EXT; + case DXGI_FORMAT_R16_FLOAT: + return GL_R16F_EXT; + case DXGI_FORMAT_R16G16_FLOAT: + return GL_RG16F_EXT; + case DXGI_FORMAT_D16_UNORM: + return GL_DEPTH_COMPONENT16; + case DXGI_FORMAT_D24_UNORM_S8_UINT: + return GL_DEPTH24_STENCIL8_OES; + case DXGI_FORMAT_UNKNOWN: + return GL_NONE; + default: + UNREACHABLE(); + } + + return GL_RGBA8_OES; +} + +} + +namespace gl_d3d11 +{ + +DXGI_FORMAT ConvertRenderbufferFormat(GLenum format) +{ + switch (format) + { + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8_OES: + case GL_RGB565: + case GL_RGB8_OES: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case GL_BGRA8_EXT: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case GL_DEPTH_COMPONENT16: + return DXGI_FORMAT_D16_UNORM; + case GL_STENCIL_INDEX8: + case GL_DEPTH24_STENCIL8_OES: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + default: + UNREACHABLE(); + } + + return DXGI_FORMAT_R8G8B8A8_UNORM; +} + +DXGI_FORMAT ConvertTextureFormat(GLenum internalformat, D3D_FEATURE_LEVEL featureLevel) +{ + switch (internalformat) + { + case GL_RGB565: + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGB8_OES: + case GL_RGBA8_OES: + case GL_LUMINANCE8_EXT: + case GL_LUMINANCE8_ALPHA8_EXT: + return DXGI_FORMAT_R8G8B8A8_UNORM; + case GL_ALPHA8_EXT: + return featureLevel >= D3D_FEATURE_LEVEL_10_0 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return DXGI_FORMAT_BC1_UNORM; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return DXGI_FORMAT_BC2_UNORM; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return DXGI_FORMAT_BC3_UNORM; + case GL_RGBA32F_EXT: + case GL_ALPHA32F_EXT: + case GL_LUMINANCE_ALPHA32F_EXT: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case GL_RGB32F_EXT: + case GL_LUMINANCE32F_EXT: + return DXGI_FORMAT_R32G32B32A32_FLOAT; + case GL_RGBA16F_EXT: + case GL_ALPHA16F_EXT: + case GL_LUMINANCE_ALPHA16F_EXT: + case GL_RGB16F_EXT: + case GL_LUMINANCE16F_EXT: + return DXGI_FORMAT_R16G16B16A16_FLOAT; + case GL_BGRA8_EXT: + return DXGI_FORMAT_B8G8R8A8_UNORM; + case GL_R8_EXT: + return DXGI_FORMAT_R8_UNORM; + case GL_RG8_EXT: + return DXGI_FORMAT_R8G8_UNORM; + case GL_R16F_EXT: + return DXGI_FORMAT_R16_FLOAT; + case GL_RG16F_EXT: + return DXGI_FORMAT_R16G16_FLOAT; + case GL_DEPTH_COMPONENT16: + return DXGI_FORMAT_D16_UNORM; + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH24_STENCIL8_OES: + return DXGI_FORMAT_D24_UNORM_S8_UINT; + case GL_NONE: + return DXGI_FORMAT_UNKNOWN; + default: + UNREACHABLE(); + } + + return DXGI_FORMAT_R8G8B8A8_UNORM; +} + +} + +namespace d3d11 +{ + +void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) +{ + vertex->x = x; + vertex->y = y; + vertex->u = u; + vertex->v = v; +} + +void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, + const gl::Color &color) +{ + vertex->x = x; + vertex->y = y; + vertex->z = z; + vertex->r = color.red; + vertex->g = color.green; + vertex->b = color.blue; + vertex->a = color.alpha; +} + +size_t ComputePixelSizeBits(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_R1_UNORM: + return 1; + + case DXGI_FORMAT_A8_UNORM: + case DXGI_FORMAT_R8_SINT: + case DXGI_FORMAT_R8_SNORM: + case DXGI_FORMAT_R8_TYPELESS: + case DXGI_FORMAT_R8_UINT: + case DXGI_FORMAT_R8_UNORM: + return 8; + + case DXGI_FORMAT_B5G5R5A1_UNORM: + case DXGI_FORMAT_B5G6R5_UNORM: + case DXGI_FORMAT_D16_UNORM: + case DXGI_FORMAT_R16_FLOAT: + case DXGI_FORMAT_R16_SINT: + case DXGI_FORMAT_R16_SNORM: + case DXGI_FORMAT_R16_TYPELESS: + case DXGI_FORMAT_R16_UINT: + case DXGI_FORMAT_R16_UNORM: + case DXGI_FORMAT_R8G8_SINT: + case DXGI_FORMAT_R8G8_SNORM: + case DXGI_FORMAT_R8G8_TYPELESS: + case DXGI_FORMAT_R8G8_UINT: + case DXGI_FORMAT_R8G8_UNORM: + return 16; + + case DXGI_FORMAT_B8G8R8X8_TYPELESS: + case DXGI_FORMAT_B8G8R8X8_UNORM: + case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_G8R8_G8B8_UNORM: + case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: + case DXGI_FORMAT_R10G10B10A2_TYPELESS: + case DXGI_FORMAT_R10G10B10A2_UINT: + case DXGI_FORMAT_R10G10B10A2_UNORM: + case DXGI_FORMAT_R11G11B10_FLOAT: + case DXGI_FORMAT_R16G16_FLOAT: + case DXGI_FORMAT_R16G16_SINT: + case DXGI_FORMAT_R16G16_SNORM: + case DXGI_FORMAT_R16G16_TYPELESS: + case DXGI_FORMAT_R16G16_UINT: + case DXGI_FORMAT_R16G16_UNORM: + case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: + case DXGI_FORMAT_R24G8_TYPELESS: + case DXGI_FORMAT_R32_FLOAT: + case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: + case DXGI_FORMAT_R32_SINT: + case DXGI_FORMAT_R32_TYPELESS: + case DXGI_FORMAT_R32_UINT: + case DXGI_FORMAT_R8G8_B8G8_UNORM: + case DXGI_FORMAT_R8G8B8A8_SINT: + case DXGI_FORMAT_R8G8B8A8_SNORM: + case DXGI_FORMAT_R8G8B8A8_TYPELESS: + case DXGI_FORMAT_R8G8B8A8_UINT: + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + case DXGI_FORMAT_B8G8R8A8_TYPELESS: + case DXGI_FORMAT_B8G8R8A8_UNORM: + case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: + case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: + case DXGI_FORMAT_X24_TYPELESS_G8_UINT: + case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: + return 32; + + case DXGI_FORMAT_R16G16B16A16_FLOAT: + case DXGI_FORMAT_R16G16B16A16_SINT: + case DXGI_FORMAT_R16G16B16A16_SNORM: + case DXGI_FORMAT_R16G16B16A16_TYPELESS: + case DXGI_FORMAT_R16G16B16A16_UINT: + case DXGI_FORMAT_R16G16B16A16_UNORM: + case DXGI_FORMAT_R32G32_FLOAT: + case DXGI_FORMAT_R32G32_SINT: + case DXGI_FORMAT_R32G32_TYPELESS: + case DXGI_FORMAT_R32G32_UINT: + case DXGI_FORMAT_R32G8X24_TYPELESS: + return 64; + + case DXGI_FORMAT_R32G32B32_FLOAT: + case DXGI_FORMAT_R32G32B32_SINT: + case DXGI_FORMAT_R32G32B32_TYPELESS: + case DXGI_FORMAT_R32G32B32_UINT: + return 96; + + case DXGI_FORMAT_R32G32B32A32_FLOAT: + case DXGI_FORMAT_R32G32B32A32_SINT: + case DXGI_FORMAT_R32G32B32A32_TYPELESS: + case DXGI_FORMAT_R32G32B32A32_UINT: + return 128; + + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + return 4; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 8; + + default: + return 0; + } +} + +size_t ComputeBlockSizeBits(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return ComputePixelSizeBits(format) * 16; + default: + UNREACHABLE(); + return 0; + } +} + +bool IsCompressed(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return true; + case DXGI_FORMAT_UNKNOWN: + UNREACHABLE(); + return false; + default: + return false; + } +} + +unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + case DXGI_FORMAT_BC1_UNORM_SRGB: + case DXGI_FORMAT_BC4_SNORM: + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + case DXGI_FORMAT_BC2_UNORM_SRGB: + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + case DXGI_FORMAT_BC3_UNORM_SRGB: + case DXGI_FORMAT_BC5_SNORM: + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + case DXGI_FORMAT_BC6H_SF16: + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + case DXGI_FORMAT_BC7_UNORM_SRGB: + return 4; + case DXGI_FORMAT_UNKNOWN: + UNREACHABLE(); + return 1; + default: + return 1; + } +} + +bool IsDepthStencilFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: + case DXGI_FORMAT_D32_FLOAT: + case DXGI_FORMAT_D24_UNORM_S8_UINT: + case DXGI_FORMAT_D16_UNORM: + return true; + default: + return false; + } +} + +DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS; + case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24G8_TYPELESS; + case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS; + default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; + } +} + +DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format) +{ + switch (format) + { + case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; + case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_UINT; + case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; + case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_UNORM; + default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; + } +} + +HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) +{ +#if defined(_DEBUG) + return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); +#else + return S_OK; +#endif +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h new file mode 100644 index 0000000000..70ad4fea2b --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/renderer11_utils.h @@ -0,0 +1,95 @@ +// +// Copyright (c) 2012 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. +// + +// renderer11_utils.h: Conversion functions and other utility routines +// specific to the D3D11 renderer. + +#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H +#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H + +#include "libGLESv2/angletypes.h" + +namespace gl_d3d11 +{ + +D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha); +D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp); +UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha); + +D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode); + +D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison); +D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled); +UINT8 ConvertStencilMask(GLuint stencilmask); +D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp); + +D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy); +D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); +FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset); +FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset); + +DXGI_FORMAT ConvertRenderbufferFormat(GLenum format); +DXGI_FORMAT ConvertTextureFormat(GLenum format, D3D_FEATURE_LEVEL featureLevel); +} + +namespace d3d11_gl +{ + +GLenum ConvertBackBufferFormat(DXGI_FORMAT format); +GLenum ConvertDepthStencilFormat(DXGI_FORMAT format); +GLenum ConvertRenderbufferFormat(DXGI_FORMAT format); +GLenum ConvertTextureInternalFormat(DXGI_FORMAT format); + +} + +namespace d3d11 +{ + +struct PositionTexCoordVertex +{ + float x, y; + float u, v; +}; +void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v); + +struct PositionDepthColorVertex +{ + float x, y, z; + float r, g, b, a; +}; +void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, + const gl::Color &color); + +size_t ComputePixelSizeBits(DXGI_FORMAT format); +size_t ComputeBlockSizeBits(DXGI_FORMAT format); + +bool IsCompressed(DXGI_FORMAT format); +unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format); + +bool IsDepthStencilFormat(DXGI_FORMAT format); +DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format); +DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format); + +HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); + +inline bool isDeviceLostError(HRESULT errorCode) +{ + switch (errorCode) + { + case DXGI_ERROR_DEVICE_HUNG: + case DXGI_ERROR_DEVICE_REMOVED: + case DXGI_ERROR_DEVICE_RESET: + case DXGI_ERROR_DRIVER_INTERNAL_ERROR: + case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: + return true; + default: + return false; + } +} + +} + +#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl new file mode 100644 index 0000000000..cb132dc99c --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Clear11.hlsl @@ -0,0 +1,42 @@ +void VS_Clear( in float3 inPosition : POSITION, in float4 inColor : COLOR, + out float4 outPosition : SV_POSITION, out float4 outColor : COLOR) +{ + outPosition = float4(inPosition, 1.0f); + outColor = inColor; +} + +// Assume we are in SM4+, which has 8 color outputs +struct PS_OutputMultiple +{ + float4 color0 : SV_TARGET0; + float4 color1 : SV_TARGET1; + float4 color2 : SV_TARGET2; + float4 color3 : SV_TARGET3; +#ifdef SM4 + float4 color4 : SV_TARGET4; + float4 color5 : SV_TARGET5; + float4 color6 : SV_TARGET6; + float4 color7 : SV_TARGET7; +#endif +}; + +PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) +{ + PS_OutputMultiple outColor; + outColor.color0 = inColor; + outColor.color1 = inColor; + outColor.color2 = inColor; + outColor.color3 = inColor; +#ifdef SM4 + outColor.color4 = inColor; + outColor.color5 = inColor; + outColor.color6 = inColor; + outColor.color7 = inColor; +#endif + return outColor; +} + +float4 PS_ClearSingle(in float4 inPosition : SV_Position, in float4 inColor : COLOR) : SV_Target0 +{ + return inColor; +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl new file mode 100644 index 0000000000..43b7801efc --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d11/shaders/Passthrough11.hlsl @@ -0,0 +1,29 @@ +Texture2D Texture : register(t0); +SamplerState Sampler : register(s0); + +void VS_Passthrough( in float2 inPosition : POSITION, in float2 inTexCoord : TEXCOORD0, + out float4 outPosition : SV_POSITION, out float2 outTexCoord : TEXCOORD0) +{ + outPosition = float4(inPosition, 0.0f, 1.0f); + outTexCoord = inTexCoord; +} + +float4 PS_PassthroughRGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return Texture.Sample(Sampler, inTexCoord).rgba; +} + +float4 PS_PassthroughRGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(Texture.Sample(Sampler, inTexCoord).rgb, 1.0f); +} + +float4 PS_PassthroughLum(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return float4(Texture.Sample(Sampler, inTexCoord).rrr, 1.0f); +} + +float4 PS_PassthroughLumAlpha(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 +{ + return Texture.Sample(Sampler, inTexCoord).rrra; +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.cpp new file mode 100644 index 0000000000..d73df6418d --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.cpp @@ -0,0 +1,595 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2010 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. +// + +// Blit.cpp: Surface copy utility class. + +#include "libGLESv2/renderer/d3d9/Blit.h" + +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" + +namespace +{ +#include "libGLESv2/renderer/d3d9/shaders/compiled/standardvs.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/flipyvs.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/passthroughps.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/luminanceps.h" +#include "libGLESv2/renderer/d3d9/shaders/compiled/componentmaskps.h" + +const BYTE* const g_shaderCode[] = +{ + g_vs20_standardvs, + g_vs20_flipyvs, + g_ps20_passthroughps, + g_ps20_luminanceps, + g_ps20_componentmaskps +}; + +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) +}; +} + +namespace rx +{ +Blit::Blit(rx::Renderer9 *renderer) + : mRenderer(renderer), mQuadVertexBuffer(NULL), mQuadVertexDeclaration(NULL), mSavedStateBlock(NULL), mSavedRenderTarget(NULL), mSavedDepthStencil(NULL) +{ + initGeometry(); + memset(mCompiledShaders, 0, sizeof(mCompiledShaders)); +} + +Blit::~Blit() +{ + if (mSavedStateBlock) mSavedStateBlock->Release(); + if (mQuadVertexBuffer) mQuadVertexBuffer->Release(); + if (mQuadVertexDeclaration) mQuadVertexDeclaration->Release(); + + for (int i = 0; i < SHADER_COUNT; i++) + { + if (mCompiledShaders[i]) + { + mCompiledShaders[i]->Release(); + } + } +} + +void Blit::initGeometry() +{ + static const float quad[] = + { + -1, -1, + -1, 1, + 1, -1, + 1, 1 + }; + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT result = device->CreateVertexBuffer(sizeof(quad), D3DUSAGE_WRITEONLY, 0, D3DPOOL_DEFAULT, &mQuadVertexBuffer, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::error(GL_OUT_OF_MEMORY); + } + + void *lockPtr = NULL; + result = mQuadVertexBuffer->Lock(0, 0, &lockPtr, 0); + + if (FAILED(result) || lockPtr == NULL) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::error(GL_OUT_OF_MEMORY); + } + + memcpy(lockPtr, quad, sizeof(quad)); + mQuadVertexBuffer->Unlock(); + + static const D3DVERTEXELEMENT9 elements[] = + { + { 0, 0, D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0 }, + D3DDECL_END() + }; + + result = device->CreateVertexDeclaration(elements, &mQuadVertexDeclaration); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::error(GL_OUT_OF_MEMORY); + } +} + +template +bool Blit::setShader(ShaderId source, const char *profile, + D3DShaderType *(rx::Renderer9::*createShader)(const DWORD *, size_t length), + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)) +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DShaderType *shader; + + if (mCompiledShaders[source] != NULL) + { + shader = static_cast(mCompiledShaders[source]); + } + else + { + const BYTE* shaderCode = g_shaderCode[source]; + size_t shaderSize = g_shaderSize[source]; + + shader = (mRenderer->*createShader)(reinterpret_cast(shaderCode), shaderSize); + if (!shader) + { + ERR("Failed to create shader for blit operation"); + return false; + } + + mCompiledShaders[source] = shader; + } + + HRESULT hr = (device->*setShader)(shader); + + if (FAILED(hr)) + { + ERR("Failed to set shader for blit operation"); + return false; + } + + return true; +} + +bool Blit::setVertexShader(ShaderId shader) +{ + return setShader(shader, "vs_2_0", &rx::Renderer9::createVertexShader, &IDirect3DDevice9::SetVertexShader); +} + +bool Blit::setPixelShader(ShaderId shader) +{ + return setShader(shader, "ps_2_0", &rx::Renderer9::createPixelShader, &IDirect3DDevice9::SetPixelShader); +} + +RECT Blit::getSurfaceRect(IDirect3DSurface9 *surface) const +{ + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + + RECT rect; + rect.left = 0; + rect.top = 0; + rect.right = desc.Width; + rect.bottom = desc.Height; + + return rect; +} + +bool Blit::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) +{ + IDirect3DTexture9 *texture = copySurfaceToTexture(source, getSurfaceRect(source)); + if (!texture) + { + return false; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + saveState(); + + device->SetTexture(0, texture); + device->SetRenderTarget(0, dest); + + setVertexShader(SHADER_VS_STANDARD); + setPixelShader(SHADER_PS_PASSTHROUGH); + + setCommonBlitState(); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_LINEAR); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_LINEAR); + + setViewport(getSurfaceRect(dest), 0, 0); + + render(); + + texture->Release(); + + restoreState(); + + return true; +} + +bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +{ + RenderTarget9 *renderTarget = NULL; + IDirect3DSurface9 *source = NULL; + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + + if (colorbuffer) + { + renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + } + + if (renderTarget) + { + source = renderTarget->getSurface(); + } + + if (!source) + { + ERR("Failed to retrieve the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + IDirect3DSurface9 *destSurface = storage9->getSurfaceLevel(level, true); + bool result = false; + + if (destSurface) + { + result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); + destSurface->Release(); + } + + source->Release(); + return result; +} + +bool Blit::copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +{ + RenderTarget9 *renderTarget = NULL; + IDirect3DSurface9 *source = NULL; + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + + if (colorbuffer) + { + renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + } + + if (renderTarget) + { + source = renderTarget->getSurface(); + } + + if (!source) + { + ERR("Failed to retrieve the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + IDirect3DSurface9 *destSurface = storage9->getCubeMapSurface(target, level, true); + bool result = false; + + if (destSurface) + { + result = copy(source, sourceRect, destFormat, xoffset, yoffset, destSurface); + destSurface->Release(); + } + + source->Release(); + return result; +} + +bool Blit::copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +{ + if (!dest) + { + return false; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DSURFACE_DESC sourceDesc; + D3DSURFACE_DESC destDesc; + source->GetDesc(&sourceDesc); + dest->GetDesc(&destDesc); + + if (sourceDesc.Format == destDesc.Format && destDesc.Usage & D3DUSAGE_RENDERTARGET && + d3d9_gl::IsFormatChannelEquivalent(destDesc.Format, destFormat)) // Can use StretchRect + { + RECT destRect = {xoffset, yoffset, xoffset + (sourceRect.right - sourceRect.left), yoffset + (sourceRect.bottom - sourceRect.top)}; + HRESULT result = device->StretchRect(source, &sourceRect, dest, &destRect, D3DTEXF_POINT); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::error(GL_OUT_OF_MEMORY, false); + } + } + else + { + return formatConvert(source, sourceRect, destFormat, xoffset, yoffset, dest); + } + return true; +} + +bool Blit::formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest) +{ + IDirect3DTexture9 *texture = copySurfaceToTexture(source, sourceRect); + if (!texture) + { + return false; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + saveState(); + + device->SetTexture(0, texture); + device->SetRenderTarget(0, dest); + + setViewport(sourceRect, xoffset, yoffset); + + setCommonBlitState(); + if (setFormatConvertShaders(destFormat)) + { + render(); + } + + texture->Release(); + + restoreState(); + + return true; +} + +bool Blit::setFormatConvertShaders(GLenum destFormat) +{ + bool okay = setVertexShader(SHADER_VS_STANDARD); + + switch (destFormat) + { + default: UNREACHABLE(); + case GL_RGBA: + case GL_BGRA_EXT: + case GL_RGB: + case GL_ALPHA: + okay = okay && setPixelShader(SHADER_PS_COMPONENTMASK); + break; + + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + okay = okay && setPixelShader(SHADER_PS_LUMINANCE); + break; + } + + if (!okay) + { + return false; + } + + enum { X = 0, Y = 1, Z = 2, W = 3 }; + + // The meaning of this constant depends on the shader that was selected. + // See the shader assembly code above for details. + float psConst0[4] = { 0, 0, 0, 0 }; + + switch (destFormat) + { + default: UNREACHABLE(); + case GL_RGBA: + case GL_BGRA_EXT: + psConst0[X] = 1; + psConst0[Z] = 1; + break; + + case GL_RGB: + psConst0[X] = 1; + psConst0[W] = 1; + break; + + case GL_ALPHA: + psConst0[Z] = 1; + break; + + case GL_LUMINANCE: + psConst0[Y] = 1; + break; + + case GL_LUMINANCE_ALPHA: + psConst0[X] = 1; + break; + } + + mRenderer->getDevice()->SetPixelShaderConstantF(0, psConst0, 1); + + return true; +} + +IDirect3DTexture9 *Blit::copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect) +{ + if (!surface) + { + return NULL; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DSURFACE_DESC sourceDesc; + surface->GetDesc(&sourceDesc); + + // 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); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); + } + + IDirect3DSurface9 *textureSurface; + result = texture->GetSurfaceLevel(0, &textureSurface); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + texture->Release(); + return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); + } + + mRenderer->endScene(); + result = device->StretchRect(surface, &sourceRect, textureSurface, NULL, D3DTEXF_NONE); + + textureSurface->Release(); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + texture->Release(); + return gl::error(GL_OUT_OF_MEMORY, (IDirect3DTexture9*)NULL); + } + + return texture; +} + +void Blit::setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset) +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + D3DVIEWPORT9 vp; + vp.X = xoffset; + vp.Y = yoffset; + vp.Width = sourceRect.right - sourceRect.left; + vp.Height = sourceRect.bottom - sourceRect.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); +} + +void Blit::setCommonBlitState() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + device->SetDepthStencilSurface(NULL); + + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + device->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_ALPHA | D3DCOLORWRITEENABLE_BLUE | D3DCOLORWRITEENABLE_GREEN | D3DCOLORWRITEENABLE_RED); + device->SetRenderState(D3DRS_SRGBWRITEENABLE, FALSE); + device->SetRenderState(D3DRS_SCISSORTESTENABLE, FALSE); + + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, FALSE); + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + + RECT scissorRect = {0}; // Scissoring is disabled for flipping, but we need this to capture and restore the old rectangle + device->SetScissorRect(&scissorRect); + + for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + device->SetStreamSourceFreq(i, 1); + } +} + +void Blit::render() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT hr = device->SetStreamSource(0, mQuadVertexBuffer, 0, 2 * sizeof(float)); + hr = device->SetVertexDeclaration(mQuadVertexDeclaration); + + mRenderer->startScene(); + hr = device->DrawPrimitive(D3DPT_TRIANGLESTRIP, 0, 2); +} + +void Blit::saveState() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT hr; + + device->GetDepthStencilSurface(&mSavedDepthStencil); + device->GetRenderTarget(0, &mSavedRenderTarget); + + if (mSavedStateBlock == NULL) + { + hr = device->BeginStateBlock(); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + + setCommonBlitState(); + + static const float dummyConst[4] = { 0, 0, 0, 0 }; + + device->SetVertexShader(NULL); + device->SetVertexShaderConstantF(0, dummyConst, 1); + device->SetPixelShader(NULL); + device->SetPixelShaderConstantF(0, dummyConst, 1); + + D3DVIEWPORT9 dummyVp; + dummyVp.X = 0; + dummyVp.Y = 0; + dummyVp.Width = 1; + dummyVp.Height = 1; + dummyVp.MinZ = 0; + dummyVp.MaxZ = 1; + + device->SetViewport(&dummyVp); + + device->SetTexture(0, NULL); + + device->SetStreamSource(0, mQuadVertexBuffer, 0, 0); + + device->SetVertexDeclaration(mQuadVertexDeclaration); + + hr = device->EndStateBlock(&mSavedStateBlock); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + } + + ASSERT(mSavedStateBlock != NULL); + + if (mSavedStateBlock != NULL) + { + hr = mSavedStateBlock->Capture(); + ASSERT(SUCCEEDED(hr)); + } +} + +void Blit::restoreState() +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + device->SetDepthStencilSurface(mSavedDepthStencil); + if (mSavedDepthStencil != NULL) + { + mSavedDepthStencil->Release(); + mSavedDepthStencil = NULL; + } + + device->SetRenderTarget(0, mSavedRenderTarget); + if (mSavedRenderTarget != NULL) + { + mSavedRenderTarget->Release(); + mSavedRenderTarget = NULL; + } + + ASSERT(mSavedStateBlock != NULL); + + if (mSavedStateBlock != NULL) + { + mSavedStateBlock->Apply(); + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.h new file mode 100644 index 0000000000..3718028e66 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Blit.h @@ -0,0 +1,94 @@ +// +// Copyright (c) 2002-2010 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. +// + +// Blit.cpp: Surface copy utility class. + +#ifndef LIBGLESV2_BLIT_H_ +#define LIBGLESV2_BLIT_H_ + +#include "common/angleutils.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ +class Renderer9; +class TextureStorageInterface2D; +class TextureStorageInterfaceCube; + +class Blit +{ + public: + explicit Blit(Renderer9 *renderer); + ~Blit(); + + // Copy from source surface to dest surface. + // sourceRect, xoffset, yoffset are in D3D coordinates (0,0 in upper-left) + bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); + bool copy(gl::Framebuffer *framebuffer, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *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. + bool formatConvert(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); + + // 2x2 box filter sample from source to dest. + // Requires that source is RGB(A) and dest has the same format as source. + bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); + + private: + rx::Renderer9 *mRenderer; + + IDirect3DVertexBuffer9 *mQuadVertexBuffer; + IDirect3DVertexDeclaration9 *mQuadVertexDeclaration; + + void initGeometry(); + + bool setFormatConvertShaders(GLenum destFormat); + + bool copy(IDirect3DSurface9 *source, const RECT &sourceRect, GLenum destFormat, GLint xoffset, GLint yoffset, IDirect3DSurface9 *dest); + IDirect3DTexture9 *copySurfaceToTexture(IDirect3DSurface9 *surface, const RECT &sourceRect); + void setViewport(const RECT &sourceRect, GLint xoffset, GLint yoffset); + void setCommonBlitState(); + RECT getSurfaceRect(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_COMPONENTMASK, + SHADER_COUNT + }; + + // This actually contains IDirect3DVertexShader9 or IDirect3DPixelShader9 casted to IUnknown. + IUnknown *mCompiledShaders[SHADER_COUNT]; + + template + bool setShader(ShaderId source, const char *profile, + D3DShaderType *(Renderer9::*createShader)(const DWORD *, size_t length), + HRESULT (WINAPI IDirect3DDevice9::*setShader)(D3DShaderType*)); + + bool setVertexShader(ShaderId shader); + bool setPixelShader(ShaderId shader); + void render(); + + void saveState(); + void restoreState(); + IDirect3DStateBlock9 *mSavedStateBlock; + IDirect3DSurface9 *mSavedRenderTarget; + IDirect3DSurface9 *mSavedDepthStencil; + + DISALLOW_COPY_AND_ASSIGN(Blit); +}; +} + +#endif // LIBGLESV2_BLIT_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp new file mode 100644 index 0000000000..9fdc1246f1 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.cpp @@ -0,0 +1,78 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// BufferStorage9.cpp Defines the BufferStorage9 class. + +#include "libGLESv2/renderer/d3d9/BufferStorage9.h" +#include "common/debug.h" + +namespace rx +{ + +BufferStorage9::BufferStorage9() +{ + mMemory = NULL; + mAllocatedSize = 0; + mSize = 0; +} + +BufferStorage9::~BufferStorage9() +{ + delete[] mMemory; +} + +BufferStorage9 *BufferStorage9::makeBufferStorage9(BufferStorage *bufferStorage) +{ + ASSERT(HAS_DYNAMIC_TYPE(BufferStorage9*, bufferStorage)); + return static_cast(bufferStorage); +} + +void *BufferStorage9::getData() +{ + return mMemory; +} + +void BufferStorage9::setData(const void* data, unsigned int size, unsigned int offset) +{ + if (!mMemory || offset + size > mAllocatedSize) + { + unsigned int newAllocatedSize = offset + size; + void *newMemory = new char[newAllocatedSize]; + + if (offset > 0 && mMemory && mAllocatedSize > 0) + { + memcpy(newMemory, mMemory, std::min(offset, mAllocatedSize)); + } + + delete[] mMemory; + mMemory = newMemory; + mAllocatedSize = newAllocatedSize; + } + + mSize = std::max(mSize, offset + size); + if (data) + { + memcpy(reinterpret_cast(mMemory) + offset, data, size); + } +} + +void BufferStorage9::clear() +{ + mSize = 0; +} + +unsigned int BufferStorage9::getSize() const +{ + return mSize; +} + +bool BufferStorage9::supportsDirectBinding() const +{ + return false; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.h new file mode 100644 index 0000000000..3e803969bc --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/BufferStorage9.h @@ -0,0 +1,42 @@ +// +// Copyright (c) 2013 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. +// + +// BufferStorage9.h Defines the BufferStorage9 class. + +#ifndef LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_ +#define LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_ + +#include "libGLESv2/renderer/BufferStorage.h" + +namespace rx +{ + +class BufferStorage9 : public BufferStorage +{ + public: + BufferStorage9(); + virtual ~BufferStorage9(); + + static BufferStorage9 *makeBufferStorage9(BufferStorage *bufferStorage); + + virtual void *getData(); + virtual void setData(const void* data, unsigned int size, unsigned int offset); + virtual void clear(); + virtual unsigned int getSize() const; + virtual bool supportsDirectBinding() const; + + private: + DISALLOW_COPY_AND_ASSIGN(BufferStorage9); + + void *mMemory; + unsigned int mAllocatedSize; + + unsigned int mSize; +}; + +} + +#endif // LIBGLESV2_RENDERER_BUFFERSTORAGE9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp new file mode 100644 index 0000000000..639c37b4e4 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.cpp @@ -0,0 +1,135 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Fence9.cpp: Defines the rx::Fence9 class. + +#include "libGLESv2/renderer/d3d9/Fence9.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +namespace rx +{ + +Fence9::Fence9(rx::Renderer9 *renderer) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Fence9::~Fence9() +{ + if (mQuery) + { + mRenderer->freeEventQuery(mQuery); + mQuery = NULL; + } +} + +GLboolean Fence9::isFence() +{ + // GL_NV_fence spec: + // A name returned by GenFencesNV, but not yet set via SetFenceNV, is not the name of an existing fence. + return mQuery != NULL; +} + +void Fence9::setFence(GLenum condition) +{ + if (!mQuery) + { + mQuery = mRenderer->allocateEventQuery(); + if (!mQuery) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + HRESULT result = mQuery->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + + setCondition(condition); + setStatus(GL_FALSE); +} + +GLboolean Fence9::testFence() +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION, GL_TRUE); + } + + HRESULT result = mQuery->GetData(NULL, 0, D3DGETDATA_FLUSH); + + if (d3d9::isDeviceLostError(result)) + { + mRenderer->notifyDeviceLost(); + return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + } + + ASSERT(result == S_OK || result == S_FALSE); + setStatus(result == S_OK); + return getStatus(); +} + +void Fence9::finishFence() +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + while (!testFence()) + { + Sleep(0); + } +} + +void Fence9::getFenceiv(GLenum pname, GLint *params) +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + switch (pname) + { + case GL_FENCE_STATUS_NV: + { + // GL_NV_fence spec: + // Once the status of a fence has been finished (via FinishFenceNV) or tested and the returned status is TRUE (via either TestFenceNV + // or GetFenceivNV querying the FENCE_STATUS_NV), the status remains TRUE until the next SetFenceNV of the fence. + if (getStatus()) + { + params[0] = GL_TRUE; + return; + } + + HRESULT result = mQuery->GetData(NULL, 0, 0); + + if (d3d9::isDeviceLostError(result)) + { + params[0] = GL_TRUE; + mRenderer->notifyDeviceLost(); + return gl::error(GL_OUT_OF_MEMORY); + } + + ASSERT(result == S_OK || result == S_FALSE); + setStatus(result == S_OK); + params[0] = getStatus(); + + break; + } + case GL_FENCE_CONDITION_NV: + params[0] = getCondition(); + break; + default: + return gl::error(GL_INVALID_ENUM); + break; + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.h new file mode 100644 index 0000000000..9f17641e51 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Fence9.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2013 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. +// + +// Fence9.h: Defines the rx::Fence9 class which implements rx::FenceImpl. + +#ifndef LIBGLESV2_RENDERER_FENCE9_H_ +#define LIBGLESV2_RENDERER_FENCE9_H_ + +#include "libGLESv2/renderer/FenceImpl.h" + +namespace rx +{ +class Renderer9; + +class Fence9 : public FenceImpl +{ + public: + explicit Fence9(rx::Renderer9 *renderer); + virtual ~Fence9(); + + GLboolean isFence(); + void setFence(GLenum condition); + GLboolean testFence(); + void finishFence(); + void getFenceiv(GLenum pname, GLint *params); + + private: + DISALLOW_COPY_AND_ASSIGN(Fence9); + + rx::Renderer9 *mRenderer; + IDirect3DQuery9 *mQuery; +}; + +} + +#endif // LIBGLESV2_RENDERER_FENCE9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.cpp new file mode 100644 index 0000000000..cd12d8cc9e --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.cpp @@ -0,0 +1,736 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2012 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. +// + +// Image9.cpp: Implements the rx::Image9 class, which acts as the interface to +// the actual underlying surfaces of a Texture. + +#include "libGLESv2/renderer/d3d9/Image9.h" + +#include "libGLESv2/main.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" + +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/generatemip.h" + +namespace rx +{ + +Image9::Image9() +{ + mSurface = NULL; + mRenderer = NULL; + + mD3DPool = D3DPOOL_SYSTEMMEM; + mD3DFormat = D3DFMT_UNKNOWN; +} + +Image9::~Image9() +{ + if (mSurface) + { + mSurface->Release(); + } +} + +void Image9::generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface) +{ + D3DSURFACE_DESC destDesc; + HRESULT result = destSurface->GetDesc(&destDesc); + ASSERT(SUCCEEDED(result)); + + D3DSURFACE_DESC sourceDesc; + result = sourceSurface->GetDesc(&sourceDesc); + ASSERT(SUCCEEDED(result)); + + ASSERT(sourceDesc.Format == destDesc.Format); + ASSERT(sourceDesc.Width == 1 || sourceDesc.Width / 2 == destDesc.Width); + ASSERT(sourceDesc.Height == 1 || sourceDesc.Height / 2 == destDesc.Height); + + D3DLOCKED_RECT sourceLocked = {0}; + result = sourceSurface->LockRect(&sourceLocked, NULL, D3DLOCK_READONLY); + ASSERT(SUCCEEDED(result)); + + D3DLOCKED_RECT destLocked = {0}; + result = destSurface->LockRect(&destLocked, NULL, 0); + ASSERT(SUCCEEDED(result)); + + const unsigned char *sourceData = reinterpret_cast(sourceLocked.pBits); + unsigned char *destData = reinterpret_cast(destLocked.pBits); + + if (sourceData && destData) + { + switch (sourceDesc.Format) + { + case D3DFMT_L8: + GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); + break; + case D3DFMT_A8L8: + GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); + break; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); + break; + case D3DFMT_A16B16G16R16F: + GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); + break; + case D3DFMT_A32B32G32R32F: + GenerateMip(sourceDesc.Width, sourceDesc.Height, sourceData, sourceLocked.Pitch, destData, destLocked.Pitch); + break; + default: + UNREACHABLE(); + break; + } + + destSurface->UnlockRect(); + sourceSurface->UnlockRect(); + } +} + +Image9 *Image9::makeImage9(Image *img) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::Image9*, img)); + return static_cast(img); +} + +void Image9::generateMipmap(Image9 *dest, Image9 *source) +{ + IDirect3DSurface9 *sourceSurface = source->getSurface(); + if (sourceSurface == NULL) + return gl::error(GL_OUT_OF_MEMORY); + + IDirect3DSurface9 *destSurface = dest->getSurface(); + generateMip(destSurface, sourceSurface); + + dest->markDirty(); +} + +void Image9::copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source) +{ + D3DLOCKED_RECT sourceLock = {0}; + D3DLOCKED_RECT destLock = {0}; + + source->LockRect(&sourceLock, NULL, 0); + dest->LockRect(&destLock, NULL, 0); + + if (sourceLock.pBits && destLock.pBits) + { + D3DSURFACE_DESC desc; + source->GetDesc(&desc); + + int rows = d3d9::IsCompressedFormat(desc.Format) ? desc.Height / 4 : desc.Height; + int bytes = d3d9::ComputeRowSize(desc.Format, desc.Width); + ASSERT(bytes <= sourceLock.Pitch && bytes <= destLock.Pitch); + + for(int i = 0; i < rows; i++) + { + memcpy((char*)destLock.pBits + destLock.Pitch * i, (char*)sourceLock.pBits + sourceLock.Pitch * i, bytes); + } + + source->UnlockRect(); + dest->UnlockRect(); + } + else UNREACHABLE(); +} + +bool Image9::redefine(rx::Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease) +{ + if (mWidth != width || + mHeight != height || + mInternalFormat != internalformat || + forceRelease) + { + mRenderer = Renderer9::makeRenderer9(renderer); + + mWidth = width; + mHeight = height; + mInternalFormat = internalformat; + // compute the d3d format that will be used + mD3DFormat = mRenderer->ConvertTextureInternalFormat(internalformat); + mActualFormat = d3d9_gl::GetEquivalentFormat(mD3DFormat); + + if (mSurface) + { + mSurface->Release(); + mSurface = NULL; + } + + return true; + } + + return false; +} + +void Image9::createSurface() +{ + if(mSurface) + { + return; + } + + IDirect3DTexture9 *newTexture = NULL; + IDirect3DSurface9 *newSurface = NULL; + const D3DPOOL poolToUse = D3DPOOL_SYSTEMMEM; + const D3DFORMAT d3dFormat = getD3DFormat(); + ASSERT(d3dFormat != D3DFMT_INTZ); // We should never get here for depth textures + + if (mWidth != 0 && mHeight != 0) + { + int levelToFetch = 0; + GLsizei requestWidth = mWidth; + GLsizei requestHeight = mHeight; + gl::MakeValidSize(true, gl::IsCompressed(mInternalFormat), &requestWidth, &requestHeight, &levelToFetch); + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + HRESULT result = device->CreateTexture(requestWidth, requestHeight, levelToFetch + 1, 0, d3dFormat, + poolToUse, &newTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + ERR("Creating image surface failed."); + return gl::error(GL_OUT_OF_MEMORY); + } + + newTexture->GetSurfaceLevel(levelToFetch, &newSurface); + newTexture->Release(); + } + + mSurface = newSurface; + mDirty = false; + mD3DPool = poolToUse; +} + +HRESULT Image9::lock(D3DLOCKED_RECT *lockedRect, const RECT *rect) +{ + createSurface(); + + HRESULT result = D3DERR_INVALIDCALL; + + if (mSurface) + { + result = mSurface->LockRect(lockedRect, rect, 0); + ASSERT(SUCCEEDED(result)); + + mDirty = true; + } + + return result; +} + +void Image9::unlock() +{ + if (mSurface) + { + HRESULT result = mSurface->UnlockRect(); + ASSERT(SUCCEEDED(result)); + } +} + +bool Image9::isRenderableFormat() const +{ + return TextureStorage9::IsTextureFormatRenderable(getD3DFormat()); +} + +D3DFORMAT Image9::getD3DFormat() const +{ + // this should only happen if the image hasn't been redefined first + // which would be a bug by the caller + ASSERT(mD3DFormat != D3DFMT_UNKNOWN); + + return mD3DFormat; +} + +IDirect3DSurface9 *Image9::getSurface() +{ + createSurface(); + + return mSurface; +} + +void Image9::setManagedSurface(TextureStorageInterface2D *storage, int level) +{ + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + setManagedSurface(storage9->getSurfaceLevel(level, false)); +} + +void Image9::setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level) +{ + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + setManagedSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, false)); +} + +void Image9::setManagedSurface(IDirect3DSurface9 *surface) +{ + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + ASSERT(desc.Pool == D3DPOOL_MANAGED); + + if ((GLsizei)desc.Width == mWidth && (GLsizei)desc.Height == mHeight) + { + if (mSurface) + { + copyLockableSurfaces(surface, mSurface); + mSurface->Release(); + } + + mSurface = surface; + mD3DPool = desc.Pool; + } +} + +bool Image9::updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + ASSERT(getSurface() != NULL); + TextureStorage9_2D *storage9 = TextureStorage9_2D::makeTextureStorage9_2D(storage->getStorageInstance()); + return updateSurface(storage9->getSurfaceLevel(level, true), xoffset, yoffset, width, height); +} + +bool Image9::updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + ASSERT(getSurface() != NULL); + TextureStorage9_Cube *storage9 = TextureStorage9_Cube::makeTextureStorage9_Cube(storage->getStorageInstance()); + return updateSurface(storage9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true), xoffset, yoffset, width, height); +} + +bool Image9::updateSurface(IDirect3DSurface9 *destSurface, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height) +{ + if (!destSurface) + return false; + + IDirect3DSurface9 *sourceSurface = getSurface(); + + if (sourceSurface && sourceSurface != destSurface) + { + RECT rect; + rect.left = xoffset; + rect.top = yoffset; + rect.right = xoffset + width; + rect.bottom = yoffset + height; + + POINT point = {rect.left, rect.top}; + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + if (mD3DPool == D3DPOOL_MANAGED) + { + D3DSURFACE_DESC desc; + sourceSurface->GetDesc(&desc); + + IDirect3DSurface9 *surf = 0; + HRESULT result = device->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + + if (SUCCEEDED(result)) + { + copyLockableSurfaces(surf, sourceSurface); + result = device->UpdateSurface(surf, &rect, destSurface, &point); + ASSERT(SUCCEEDED(result)); + surf->Release(); + } + } + else + { + // UpdateSurface: source must be SYSTEMMEM, dest must be DEFAULT pools + HRESULT result = device->UpdateSurface(sourceSurface, &rect, destSurface, &point); + ASSERT(SUCCEEDED(result)); + } + } + + destSurface->Release(); + return true; +} + +// Store the pixel rectangle designated by xoffset,yoffset,width,height with pixels stored as format/type at input +// into the target pixel rectangle. +void Image9::loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLint unpackAlignment, const void *input) +{ + RECT lockRect = + { + xoffset, yoffset, + xoffset + width, yoffset + height + }; + + D3DLOCKED_RECT locked; + HRESULT result = lock(&locked, &lockRect); + if (FAILED(result)) + { + return; + } + + + GLsizei inputPitch = gl::ComputePitch(width, mInternalFormat, unpackAlignment); + + switch (mInternalFormat) + { + case GL_ALPHA8_EXT: +#if defined(__SSE2__) + if (gl::supportsSSE2()) + { + loadAlphaDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); + } + else +#endif + { + loadAlphaDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + } + break; + case GL_LUMINANCE8_EXT: + loadLuminanceDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_L8); + break; + case GL_ALPHA32F_EXT: + loadAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_LUMINANCE32F_EXT: + loadLuminanceFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_ALPHA16F_EXT: + loadAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_LUMINANCE16F_EXT: + loadLuminanceHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_LUMINANCE8_ALPHA8_EXT: + loadLuminanceAlphaDataToNativeOrBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits, getD3DFormat() == D3DFMT_A8L8); + break; + case GL_LUMINANCE_ALPHA32F_EXT: + loadLuminanceAlphaFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_LUMINANCE_ALPHA16F_EXT: + loadLuminanceAlphaHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGB8_OES: + loadRGBUByteDataToBGRX(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGB565: + loadRGB565DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGBA8_OES: +#if defined(__SSE2__) + if (gl::supportsSSE2()) + { + loadRGBAUByteDataToBGRASSE2(width, height, inputPitch, input, locked.Pitch, locked.pBits); + } + else +#endif + { + loadRGBAUByteDataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + } + break; + case GL_RGBA4: + loadRGBA4444DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGB5_A1: + loadRGBA5551DataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_BGRA8_EXT: + loadBGRADataToBGRA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + // float textures are converted to RGBA, not BGRA, as they're stored that way in D3D + case GL_RGB32F_EXT: + loadRGBFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGB16F_EXT: + loadRGBHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGBA32F_EXT: + loadRGBAFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + case GL_RGBA16F_EXT: + loadRGBAHalfFloatDataToRGBA(width, height, inputPitch, input, locked.Pitch, locked.pBits); + break; + default: UNREACHABLE(); + } + + unlock(); +} + +void Image9::loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + const void *input) +{ + ASSERT(xoffset % 4 == 0); + ASSERT(yoffset % 4 == 0); + + RECT lockRect = { + xoffset, yoffset, + xoffset + width, yoffset + height + }; + + D3DLOCKED_RECT locked; + HRESULT result = lock(&locked, &lockRect); + if (FAILED(result)) + { + return; + } + + GLsizei inputSize = gl::ComputeCompressedSize(width, height, mInternalFormat); + GLsizei inputPitch = gl::ComputeCompressedPitch(width, mInternalFormat); + int rows = inputSize / inputPitch; + for (int i = 0; i < rows; ++i) + { + memcpy((void*)((BYTE*)locked.pBits + i * locked.Pitch), (void*)((BYTE*)input + i * inputPitch), inputPitch); + } + + unlock(); +} + +// This implements glCopyTex[Sub]Image2D for non-renderable internal texture formats and incomplete textures +void Image9::copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source) +{ + RenderTarget9 *renderTarget = NULL; + IDirect3DSurface9 *surface = NULL; + gl::Renderbuffer *colorbuffer = source->getColorbuffer(0); + + if (colorbuffer) + { + renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + } + + if (renderTarget) + { + surface = renderTarget->getSurface(); + } + + if (!surface) + { + ERR("Failed to retrieve the render target."); + return gl::error(GL_OUT_OF_MEMORY); + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + IDirect3DSurface9 *renderTargetData = NULL; + D3DSURFACE_DESC description; + surface->GetDesc(&description); + + HRESULT result = device->CreateOffscreenPlainSurface(description.Width, description.Height, description.Format, D3DPOOL_SYSTEMMEM, &renderTargetData, NULL); + + if (FAILED(result)) + { + ERR("Could not create matching destination surface."); + surface->Release(); + return gl::error(GL_OUT_OF_MEMORY); + } + + result = device->GetRenderTargetData(surface, renderTargetData); + + if (FAILED(result)) + { + ERR("GetRenderTargetData unexpectedly failed."); + renderTargetData->Release(); + surface->Release(); + return gl::error(GL_OUT_OF_MEMORY); + } + + RECT sourceRect = {x, y, x + width, y + height}; + RECT destRect = {xoffset, yoffset, xoffset + width, yoffset + height}; + + D3DLOCKED_RECT sourceLock = {0}; + result = renderTargetData->LockRect(&sourceLock, &sourceRect, 0); + + if (FAILED(result)) + { + ERR("Failed to lock the source surface (rectangle might be invalid)."); + renderTargetData->Release(); + surface->Release(); + return gl::error(GL_OUT_OF_MEMORY); + } + + D3DLOCKED_RECT destLock = {0}; + result = lock(&destLock, &destRect); + + if (FAILED(result)) + { + ERR("Failed to lock the destination surface (rectangle might be invalid)."); + renderTargetData->UnlockRect(); + renderTargetData->Release(); + surface->Release(); + return gl::error(GL_OUT_OF_MEMORY); + } + + if (destLock.pBits && sourceLock.pBits) + { + unsigned char *source = (unsigned char*)sourceLock.pBits; + unsigned char *dest = (unsigned char*)destLock.pBits; + + switch (description.Format) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + switch(getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + for(int y = 0; y < height; y++) + { + memcpy(dest, source, 4 * width); + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + case D3DFMT_L8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + dest[x] = source[x * 4 + 2]; + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + dest[x * 2 + 0] = source[x * 4 + 2]; + dest[x * 2 + 1] = source[x * 4 + 3]; + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_R5G6B5: + switch(getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + unsigned short rgb = ((unsigned short*)source)[x]; + unsigned char red = (rgb & 0xF800) >> 8; + unsigned char green = (rgb & 0x07E0) >> 3; + unsigned char blue = (rgb & 0x001F) << 3; + dest[x + 0] = blue | (blue >> 5); + dest[x + 1] = green | (green >> 6); + dest[x + 2] = red | (red >> 5); + dest[x + 3] = 0xFF; + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + case D3DFMT_L8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + unsigned char red = source[x * 2 + 1] & 0xF8; + dest[x] = red | (red >> 5); + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + case D3DFMT_A1R5G5B5: + switch(getD3DFormat()) + { + case D3DFMT_X8R8G8B8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + unsigned short argb = ((unsigned short*)source)[x]; + unsigned char red = (argb & 0x7C00) >> 7; + unsigned char green = (argb & 0x03E0) >> 2; + unsigned char blue = (argb & 0x001F) << 3; + dest[x + 0] = blue | (blue >> 5); + dest[x + 1] = green | (green >> 5); + dest[x + 2] = red | (red >> 5); + dest[x + 3] = 0xFF; + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + case D3DFMT_A8R8G8B8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + unsigned short argb = ((unsigned short*)source)[x]; + unsigned char red = (argb & 0x7C00) >> 7; + unsigned char green = (argb & 0x03E0) >> 2; + unsigned char blue = (argb & 0x001F) << 3; + unsigned char alpha = (signed short)argb >> 15; + dest[x + 0] = blue | (blue >> 5); + dest[x + 1] = green | (green >> 5); + dest[x + 2] = red | (red >> 5); + dest[x + 3] = alpha; + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + case D3DFMT_L8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + unsigned char red = source[x * 2 + 1] & 0x7C; + dest[x] = (red << 1) | (red >> 4); + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + case D3DFMT_A8L8: + for(int y = 0; y < height; y++) + { + for(int x = 0; x < width; x++) + { + unsigned char red = source[x * 2 + 1] & 0x7C; + dest[x * 2 + 0] = (red << 1) | (red >> 4); + dest[x * 2 + 1] = (signed char)source[x * 2 + 1] >> 7; + } + + source += sourceLock.Pitch; + dest += destLock.Pitch; + } + break; + default: + UNREACHABLE(); + } + break; + default: + UNREACHABLE(); + } + } + + unlock(); + renderTargetData->UnlockRect(); + + renderTargetData->Release(); + surface->Release(); + + mDirty = true; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.h new file mode 100644 index 0000000000..2fbbca3124 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Image9.h @@ -0,0 +1,79 @@ +// +// Copyright (c) 2002-2012 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. +// + +// Image9.h: Defines the rx::Image9 class, which acts as the interface to +// the actual underlying surfaces of a Texture. + +#ifndef LIBGLESV2_RENDERER_IMAGE9_H_ +#define LIBGLESV2_RENDERER_IMAGE9_H_ + +#include "libGLESv2/renderer/Image.h" +#include "common/debug.h" + +namespace gl +{ +class Framebuffer; +} + +namespace rx +{ +class Renderer; +class Renderer9; +class TextureStorageInterface2D; +class TextureStorageInterfaceCube; + +class Image9 : public Image +{ + public: + Image9(); + ~Image9(); + + static Image9 *makeImage9(Image *img); + + static void generateMipmap(Image9 *dest, Image9 *source); + static void generateMip(IDirect3DSurface9 *destSurface, IDirect3DSurface9 *sourceSurface); + static void copyLockableSurfaces(IDirect3DSurface9 *dest, IDirect3DSurface9 *source); + + virtual bool redefine(Renderer *renderer, GLint internalformat, GLsizei width, GLsizei height, bool forceRelease); + + virtual bool isRenderableFormat() const; + D3DFORMAT getD3DFormat() const; + + virtual bool isDirty() const {return mSurface && mDirty;} + IDirect3DSurface9 *getSurface(); + + virtual void setManagedSurface(TextureStorageInterface2D *storage, int level); + virtual void setManagedSurface(TextureStorageInterfaceCube *storage, int face, int level); + virtual bool updateSurface(TextureStorageInterface2D *storage, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + virtual bool updateSurface(TextureStorageInterfaceCube *storage, int face, int level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + + virtual void loadData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + GLint unpackAlignment, const void *input); + virtual void loadCompressedData(GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, + const void *input); + + virtual void copy(GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height, gl::Framebuffer *source); + + private: + DISALLOW_COPY_AND_ASSIGN(Image9); + + void createSurface(); + void setManagedSurface(IDirect3DSurface9 *surface); + bool updateSurface(IDirect3DSurface9 *dest, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height); + + HRESULT lock(D3DLOCKED_RECT *lockedRect, const RECT *rect); + void unlock(); + + Renderer9 *mRenderer; + + D3DPOOL mD3DPool; // can only be D3DPOOL_SYSTEMMEM or D3DPOOL_MANAGED since it needs to be lockable. + D3DFORMAT mD3DFormat; + + IDirect3DSurface9 *mSurface; +}; +} + +#endif // LIBGLESV2_RENDERER_IMAGE9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp new file mode 100644 index 0000000000..7cb5d13a18 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.cpp @@ -0,0 +1,207 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2012 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. +// + +// Indexffer9.cpp: Defines the D3D9 IndexBuffer implementation. + +#include "libGLESv2/renderer/d3d9/IndexBuffer9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +namespace rx +{ + +IndexBuffer9::IndexBuffer9(Renderer9 *const renderer) : mRenderer(renderer) +{ + mIndexBuffer = NULL; + mBufferSize = 0; + mIndexType = 0; + mDynamic = false; +} + +IndexBuffer9::~IndexBuffer9() +{ + if (mIndexBuffer) + { + mIndexBuffer->Release(); + mIndexBuffer = NULL; + } +} + +bool IndexBuffer9::initialize(unsigned int bufferSize, GLenum indexType, bool dynamic) +{ + if (mIndexBuffer) + { + mIndexBuffer->Release(); + mIndexBuffer = NULL; + } + + updateSerial(); + + if (bufferSize > 0) + { + D3DFORMAT format; + if (indexType == GL_UNSIGNED_SHORT || indexType == GL_UNSIGNED_BYTE) + { + format = D3DFMT_INDEX16; + } + else if (indexType == GL_UNSIGNED_INT) + { + if (mRenderer->get32BitIndexSupport()) + { + format = D3DFMT_INDEX32; + } + else + { + ERR("Attempted to create a 32-bit index buffer but renderer does not support 32-bit indices."); + return false; + } + } + else + { + ERR("Invalid index type %u.", indexType); + return false; + } + + DWORD usageFlags = D3DUSAGE_WRITEONLY; + if (dynamic) + { + usageFlags |= D3DUSAGE_DYNAMIC; + } + + HRESULT result = mRenderer->createIndexBuffer(bufferSize, usageFlags, format, &mIndexBuffer); + if (FAILED(result)) + { + ERR("Failed to create an index buffer of size %u, result: 0x%08x.", mBufferSize, result); + return false; + } + } + + mBufferSize = bufferSize; + mIndexType = indexType; + mDynamic = dynamic; + + return true; +} + +IndexBuffer9 *IndexBuffer9::makeIndexBuffer9(IndexBuffer *indexBuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(IndexBuffer9*, indexBuffer)); + return static_cast(indexBuffer); +} + +bool IndexBuffer9::mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory) +{ + if (mIndexBuffer) + { + DWORD lockFlags = mDynamic ? D3DLOCK_NOOVERWRITE : 0; + + void *mapPtr = NULL; + HRESULT result = mIndexBuffer->Lock(offset, size, &mapPtr, lockFlags); + if (FAILED(result)) + { + ERR("Index buffer lock failed with error 0x%08x", result); + return false; + } + + *outMappedMemory = mapPtr; + return true; + } + else + { + ERR("Index buffer not initialized."); + return false; + } +} + +bool IndexBuffer9::unmapBuffer() +{ + if (mIndexBuffer) + { + HRESULT result = mIndexBuffer->Unlock(); + if (FAILED(result)) + { + ERR("Index buffer unlock failed with error 0x%08x", result); + return false; + } + + return true; + } + else + { + ERR("Index buffer not initialized."); + return false; + } +} + +GLenum IndexBuffer9::getIndexType() const +{ + return mIndexType; +} + +unsigned int IndexBuffer9::getBufferSize() const +{ + return mBufferSize; +} + +bool IndexBuffer9::setSize(unsigned int bufferSize, GLenum indexType) +{ + if (bufferSize > mBufferSize || indexType != mIndexType) + { + return initialize(bufferSize, indexType, mDynamic); + } + else + { + return true; + } +} + +bool IndexBuffer9::discard() +{ + if (mIndexBuffer) + { + void *dummy; + HRESULT result; + + result = mIndexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + ERR("Discard lock failed with error 0x%08x", result); + return false; + } + + result = mIndexBuffer->Unlock(); + if (FAILED(result)) + { + ERR("Discard unlock failed with error 0x%08x", result); + return false; + } + + return true; + } + else + { + ERR("Index buffer not initialized."); + return false; + } +} + +D3DFORMAT IndexBuffer9::getIndexFormat() const +{ + switch (mIndexType) + { + case GL_UNSIGNED_BYTE: return D3DFMT_INDEX16; + case GL_UNSIGNED_SHORT: return D3DFMT_INDEX16; + case GL_UNSIGNED_INT: return D3DFMT_INDEX32; + default: UNREACHABLE(); return D3DFMT_UNKNOWN; + } +} + +IDirect3DIndexBuffer9 * IndexBuffer9::getBuffer() const +{ + return mIndexBuffer; +} + +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.h new file mode 100644 index 0000000000..6801867532 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/IndexBuffer9.h @@ -0,0 +1,53 @@ +// +// Copyright (c) 2002-2012 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. +// + +// Indexffer9.h: Defines the D3D9 IndexBuffer implementation. + +#ifndef LIBGLESV2_RENDERER_INDEXBUFFER9_H_ +#define LIBGLESV2_RENDERER_INDEXBUFFER9_H_ + +#include "libGLESv2/renderer/IndexBuffer.h" + +namespace rx +{ +class Renderer9; + +class IndexBuffer9 : public IndexBuffer +{ + public: + explicit IndexBuffer9(Renderer9 *const renderer); + virtual ~IndexBuffer9(); + + virtual bool initialize(unsigned int bufferSize, GLenum indexType, bool dynamic); + + static IndexBuffer9 *makeIndexBuffer9(IndexBuffer *indexBuffer); + + virtual bool mapBuffer(unsigned int offset, unsigned int size, void** outMappedMemory); + virtual bool unmapBuffer(); + + virtual GLenum getIndexType() const; + virtual unsigned int getBufferSize() const; + virtual bool setSize(unsigned int bufferSize, GLenum indexType); + + virtual bool discard(); + + D3DFORMAT getIndexFormat() const; + IDirect3DIndexBuffer9 *getBuffer() const; + + private: + DISALLOW_COPY_AND_ASSIGN(IndexBuffer9); + + rx::Renderer9 *const mRenderer; + + IDirect3DIndexBuffer9 *mIndexBuffer; + unsigned int mBufferSize; + GLenum mIndexType; + bool mDynamic; +}; + +} + +#endif // LIBGLESV2_RENDERER_INDEXBUFFER9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.cpp new file mode 100644 index 0000000000..72781cbc39 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.cpp @@ -0,0 +1,125 @@ +#include "precompiled.h" +// +// Copyright (c) 2013 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. +// + +// Query9.cpp: Defines the rx::Query9 class which implements rx::QueryImpl. + + +#include "libGLESv2/renderer/d3d9/Query9.h" +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +namespace rx +{ + +Query9::Query9(rx::Renderer9 *renderer, GLenum type) : QueryImpl(type) +{ + mRenderer = renderer; + mQuery = NULL; +} + +Query9::~Query9() +{ + if (mQuery) + { + mQuery->Release(); + mQuery = NULL; + } +} + +void Query9::begin() +{ + if (mQuery == NULL) + { + if (FAILED(mRenderer->getDevice()->CreateQuery(D3DQUERYTYPE_OCCLUSION, &mQuery))) + { + return gl::error(GL_OUT_OF_MEMORY); + } + } + + HRESULT result = mQuery->Issue(D3DISSUE_BEGIN); + ASSERT(SUCCEEDED(result)); +} + +void Query9::end() +{ + if (mQuery == NULL) + { + return gl::error(GL_INVALID_OPERATION); + } + + HRESULT result = mQuery->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + + mStatus = GL_FALSE; + mResult = GL_FALSE; +} + +GLuint Query9::getResult() +{ + if (mQuery != NULL) + { + while (!testQuery()) + { + Sleep(0); + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (mRenderer->testDeviceLost(true)) + { + return gl::error(GL_OUT_OF_MEMORY, 0); + } + } + } + + return mResult; +} + +GLboolean Query9::isResultAvailable() +{ + if (mQuery != NULL) + { + testQuery(); + } + + return mStatus; +} + +GLboolean Query9::testQuery() +{ + if (mQuery != NULL && mStatus != GL_TRUE) + { + DWORD numPixels = 0; + + HRESULT hres = mQuery->GetData(&numPixels, sizeof(DWORD), D3DGETDATA_FLUSH); + if (hres == S_OK) + { + mStatus = GL_TRUE; + + switch (getType()) + { + case GL_ANY_SAMPLES_PASSED_EXT: + case GL_ANY_SAMPLES_PASSED_CONSERVATIVE_EXT: + mResult = (numPixels > 0) ? GL_TRUE : GL_FALSE; + break; + default: + ASSERT(false); + } + } + else if (d3d9::isDeviceLostError(hres)) + { + mRenderer->notifyDeviceLost(); + return gl::error(GL_OUT_OF_MEMORY, GL_TRUE); + } + + return mStatus; + } + + return GL_TRUE; // prevent blocking when query is null +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.h new file mode 100644 index 0000000000..47eef89336 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Query9.h @@ -0,0 +1,40 @@ +// +// Copyright (c) 2013 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. +// + +// Query9.h: Defines the rx::Query9 class which implements rx::QueryImpl. + +#ifndef LIBGLESV2_RENDERER_QUERY9_H_ +#define LIBGLESV2_RENDERER_QUERY9_H_ + +#include "libGLESv2/renderer/QueryImpl.h" + +namespace rx +{ +class Renderer9; + +class Query9 : public QueryImpl +{ + public: + Query9(rx::Renderer9 *renderer, GLenum type); + virtual ~Query9(); + + void begin(); + void end(); + GLuint getResult(); + GLboolean isResultAvailable(); + + private: + DISALLOW_COPY_AND_ASSIGN(Query9); + + GLboolean testQuery(); + + rx::Renderer9 *mRenderer; + IDirect3DQuery9 *mQuery; +}; + +} + +#endif // LIBGLESV2_RENDERER_QUERY9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp new file mode 100644 index 0000000000..090431db99 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.cpp @@ -0,0 +1,113 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// RenderTarget9.cpp: Implements a D3D9-specific wrapper for IDirect3DSurface9 +// pointers retained by renderbuffers. + +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/main.h" + +namespace rx +{ + +RenderTarget9::RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface) +{ + mRenderer = Renderer9::makeRenderer9(renderer); + mRenderTarget = surface; + + if (mRenderTarget) + { + D3DSURFACE_DESC description; + mRenderTarget->GetDesc(&description); + + mWidth = description.Width; + mHeight = description.Height; + + mInternalFormat = d3d9_gl::GetEquivalentFormat(description.Format); + mActualFormat = d3d9_gl::GetEquivalentFormat(description.Format); + mSamples = d3d9_gl::GetSamplesFromMultisampleType(description.MultiSampleType); + } +} + +RenderTarget9::RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples) +{ + mRenderer = Renderer9::makeRenderer9(renderer); + mRenderTarget = NULL; + + D3DFORMAT requestedFormat = gl_d3d9::ConvertRenderbufferFormat(format); + int supportedSamples = mRenderer->getNearestSupportedSamples(requestedFormat, samples); + + if (supportedSamples == -1) + { + gl::error(GL_OUT_OF_MEMORY); + + return; + } + + HRESULT result = D3DERR_INVALIDCALL; + + if (width > 0 && height > 0) + { + if (requestedFormat == D3DFMT_D24S8) + { + result = mRenderer->getDevice()->CreateDepthStencilSurface(width, height, requestedFormat, + gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples), + 0, FALSE, &mRenderTarget, NULL); + } + else + { + result = mRenderer->getDevice()->CreateRenderTarget(width, height, requestedFormat, + gl_d3d9::GetMultisampleTypeFromSamples(supportedSamples), + 0, FALSE, &mRenderTarget, NULL); + } + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY) + { + gl::error(GL_OUT_OF_MEMORY); + + return; + } + + ASSERT(SUCCEEDED(result)); + } + + mWidth = width; + mHeight = height; + mInternalFormat = format; + mSamples = supportedSamples; + mActualFormat = d3d9_gl::GetEquivalentFormat(requestedFormat); +} + +RenderTarget9::~RenderTarget9() +{ + if (mRenderTarget) + { + mRenderTarget->Release(); + } +} + +RenderTarget9 *RenderTarget9::makeRenderTarget9(RenderTarget *target) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::RenderTarget9*, target)); + return static_cast(target); +} + +IDirect3DSurface9 *RenderTarget9::getSurface() +{ + // Caller is responsible for releasing the returned surface reference. + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + return mRenderTarget; +} + +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.h new file mode 100644 index 0000000000..faf8ad1c6d --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/RenderTarget9.h @@ -0,0 +1,40 @@ +// +// Copyright (c) 2012 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. +// + +// RenderTarget9.h: Defines a D3D9-specific wrapper for IDirect3DSurface9 pointers +// retained by Renderbuffers. + +#ifndef LIBGLESV2_RENDERER_RENDERTARGET9_H_ +#define LIBGLESV2_RENDERER_RENDERTARGET9_H_ + +#include "libGLESv2/renderer/RenderTarget.h" + +namespace rx +{ +class Renderer; +class Renderer9; + +class RenderTarget9 : public RenderTarget +{ + public: + RenderTarget9(Renderer *renderer, IDirect3DSurface9 *surface); + RenderTarget9(Renderer *renderer, GLsizei width, GLsizei height, GLenum format, GLsizei samples); + virtual ~RenderTarget9(); + + static RenderTarget9 *makeRenderTarget9(RenderTarget *renderTarget); + IDirect3DSurface9 *getSurface(); + + private: + DISALLOW_COPY_AND_ASSIGN(RenderTarget9); + + IDirect3DSurface9 *mRenderTarget; + + Renderer9 *mRenderer; +}; + +} + +#endif // LIBGLESV2_RENDERER_RENDERTARGET9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.cpp new file mode 100644 index 0000000000..97a10d64bf --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.cpp @@ -0,0 +1,3287 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// Renderer9.cpp: Implements a back-end specific class for the D3D9 renderer. + +#include "libGLESv2/main.h" +#include "libGLESv2/Buffer.h" +#include "libGLESv2/Texture.h" +#include "libGLESv2/Framebuffer.h" +#include "libGLESv2/Renderbuffer.h" +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/renderer/IndexDataManager.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/ShaderExecutable9.h" +#include "libGLESv2/renderer/d3d9/SwapChain9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/Image9.h" +#include "libGLESv2/renderer/d3d9/Blit.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d9/IndexBuffer9.h" +#include "libGLESv2/renderer/d3d9/BufferStorage9.h" +#include "libGLESv2/renderer/d3d9/Query9.h" +#include "libGLESv2/renderer/d3d9/Fence9.h" + +#include "libEGL/Display.h" + +#include "third_party/trace_event/trace_event.h" + +// Can also be enabled by defining FORCE_REF_RAST in the project's predefined macros +#define REF_RAST 0 + +// The "Debug This Pixel..." feature in PIX often fails when using the +// D3D9Ex interfaces. In order to get debug pixel to work on a Vista/Win 7 +// machine, define "ANGLE_ENABLE_D3D9EX=0" in your project file. +#if !defined(ANGLE_ENABLE_D3D9EX) +// Enables use of the IDirect3D9Ex interface, when available +#define ANGLE_ENABLE_D3D9EX 1 +#endif // !defined(ANGLE_ENABLE_D3D9EX) + +namespace rx +{ +static const D3DFORMAT RenderTargetFormats[] = + { + D3DFMT_A1R5G5B5, + // D3DFMT_A2R10G10B10, // The color_ramp conformance test uses ReadPixels with UNSIGNED_BYTE causing it to think that rendering skipped a colour value. + D3DFMT_A8R8G8B8, + D3DFMT_R5G6B5, + // D3DFMT_X1R5G5B5, // Has no compatible OpenGL ES renderbuffer format + D3DFMT_X8R8G8B8 + }; + +static const D3DFORMAT DepthStencilFormats[] = + { + D3DFMT_UNKNOWN, + // D3DFMT_D16_LOCKABLE, + D3DFMT_D32, + // D3DFMT_D15S1, + D3DFMT_D24S8, + D3DFMT_D24X8, + // D3DFMT_D24X4S4, + D3DFMT_D16, + // D3DFMT_D32F_LOCKABLE, + // D3DFMT_D24FS8 + }; + +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_TEXTURE_IMAGE_UNITS_VTF_SM3 = 4 +}; + +Renderer9::Renderer9(egl::Display *display, HDC hDc, bool softwareDevice) : Renderer(display), mDc(hDc), mSoftwareDevice(softwareDevice) +{ + mD3d9Module = NULL; + + mD3d9 = NULL; + mD3d9Ex = NULL; + mDevice = NULL; + mDeviceEx = NULL; + mDeviceWindow = NULL; + mBlit = NULL; + + mAdapter = D3DADAPTER_DEFAULT; + + #if REF_RAST == 1 || defined(FORCE_REF_RAST) + mDeviceType = D3DDEVTYPE_REF; + #else + mDeviceType = D3DDEVTYPE_HAL; + #endif + + mDeviceLost = false; + + mMaxSupportedSamples = 0; + + mMaskedClearSavedState = NULL; + + mVertexDataManager = NULL; + mIndexDataManager = NULL; + mLineLoopIB = NULL; + + 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; + } +} + +Renderer9::~Renderer9() +{ + if (mDevice) + { + // If the device is lost, reset it first to prevent leaving the driver in an unstable state + if (testDeviceLost(false)) + { + resetDevice(); + } + } + + deinitialize(); +} + +void Renderer9::deinitialize() +{ + releaseDeviceResources(); + + SafeRelease(mDevice); + SafeRelease(mDeviceEx); + SafeRelease(mD3d9); + SafeRelease(mD3d9Ex); + + if (mDeviceWindow) + { + DestroyWindow(mDeviceWindow); + mDeviceWindow = NULL; + } + + if (mD3d9Module) + { + mD3d9Module = NULL; + } + + while (!mMultiSampleSupport.empty()) + { + delete [] mMultiSampleSupport.begin()->second; + mMultiSampleSupport.erase(mMultiSampleSupport.begin()); + } +} + +Renderer9 *Renderer9::makeRenderer9(Renderer *renderer) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::Renderer9*, renderer)); + return static_cast(renderer); +} + +EGLint Renderer9::initialize() +{ + if (!initializeCompiler()) + { + return EGL_NOT_INITIALIZED; + } + + if (mSoftwareDevice) + { + TRACE_EVENT0("gpu", "GetModuleHandle_swiftshader"); + mD3d9Module = GetModuleHandle(TEXT("swiftshader_d3d9.dll")); + } + else + { + TRACE_EVENT0("gpu", "GetModuleHandle_d3d9"); + mD3d9Module = GetModuleHandle(TEXT("d3d9.dll")); + } + + if (mD3d9Module == NULL) + { + ERR("No D3D9 module found - aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + 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_ENABLE_D3D9EX && Direct3DCreate9ExPtr && SUCCEEDED(Direct3DCreate9ExPtr(D3D_SDK_VERSION, &mD3d9Ex))) + { + TRACE_EVENT0("gpu", "D3d9Ex_QueryInterface"); + ASSERT(mD3d9Ex); + mD3d9Ex->QueryInterface(IID_IDirect3D9, reinterpret_cast(&mD3d9)); + ASSERT(mD3d9); + } + else + { + TRACE_EVENT0("gpu", "Direct3DCreate9"); + mD3d9 = Direct3DCreate9(D3D_SDK_VERSION); + } + + if (!mD3d9) + { + ERR("Could not create D3D9 device - aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + if (mDc != NULL) + { + // UNIMPLEMENTED(); // FIXME: Determine which adapter index the device context corresponds to + } + + HRESULT result; + + // Give up on getting device caps after about one second. + { + TRACE_EVENT0("gpu", "GetDeviceCaps"); + for (int i = 0; i < 10; ++i) + { + result = mD3d9->GetDeviceCaps(mAdapter, mDeviceType, &mDeviceCaps); + if (SUCCEEDED(result)) + { + break; + } + else if (result == D3DERR_NOTAVAILABLE) + { + 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 + { + ERR("failed to get device caps (0x%x)\n", result); + return EGL_NOT_INITIALIZED; + } + } + } + + if (mDeviceCaps.PixelShaderVersion < D3DPS_VERSION(2, 0)) + { + ERR("Renderer does not support PS 2.0. aborting!\n"); + return EGL_NOT_INITIALIZED; + } + + // 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::convertToRenderTarget. + if ((mDeviceCaps.DevCaps2 & D3DDEVCAPS2_CAN_STRETCHRECT_FROM_TEXTURES) == 0) + { + ERR("Renderer does not support stretctrect from textures!\n"); + return EGL_NOT_INITIALIZED; + } + + { + TRACE_EVENT0("gpu", "GetAdapterIdentifier"); + mD3d9->GetAdapterIdentifier(mAdapter, 0, &mAdapterIdentifier); + } + + // ATI cards on XP have problems with non-power-of-two textures. + mSupportsNonPower2Textures = !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_POW2) && + !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_CUBEMAP_POW2) && + !(mDeviceCaps.TextureCaps & D3DPTEXTURECAPS_NONPOW2CONDITIONAL) && + !(getComparableOSVersion() < versionWindowsVista && mAdapterIdentifier.VendorId == VENDOR_ID_AMD); + + // Must support a minimum of 2:1 anisotropy for max anisotropy to be considered supported, per the spec + mSupportsTextureFilterAnisotropy = ((mDeviceCaps.RasterCaps & D3DPRASTERCAPS_ANISOTROPY) && (mDeviceCaps.MaxAnisotropy >= 2)); + + mMinSwapInterval = 4; + mMaxSwapInterval = 0; + + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_IMMEDIATE) + { + mMinSwapInterval = std::min(mMinSwapInterval, 0); + mMaxSwapInterval = std::max(mMaxSwapInterval, 0); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_ONE) + { + mMinSwapInterval = std::min(mMinSwapInterval, 1); + mMaxSwapInterval = std::max(mMaxSwapInterval, 1); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_TWO) + { + mMinSwapInterval = std::min(mMinSwapInterval, 2); + mMaxSwapInterval = std::max(mMaxSwapInterval, 2); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_THREE) + { + mMinSwapInterval = std::min(mMinSwapInterval, 3); + mMaxSwapInterval = std::max(mMaxSwapInterval, 3); + } + if (mDeviceCaps.PresentationIntervals & D3DPRESENT_INTERVAL_FOUR) + { + mMinSwapInterval = std::min(mMinSwapInterval, 4); + mMaxSwapInterval = std::max(mMaxSwapInterval, 4); + } + + int max = 0; + { + TRACE_EVENT0("gpu", "getMultiSampleSupport"); + for (unsigned int i = 0; i < ArraySize(RenderTargetFormats); ++i) + { + bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; + getMultiSampleSupport(RenderTargetFormats[i], multisampleArray); + mMultiSampleSupport[RenderTargetFormats[i]] = multisampleArray; + + for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) + { + if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) + { + max = j; + } + } + } + } + + { + TRACE_EVENT0("gpu", "getMultiSampleSupport2"); + for (unsigned int i = 0; i < ArraySize(DepthStencilFormats); ++i) + { + if (DepthStencilFormats[i] == D3DFMT_UNKNOWN) + continue; + + bool *multisampleArray = new bool[D3DMULTISAMPLE_16_SAMPLES + 1]; + getMultiSampleSupport(DepthStencilFormats[i], multisampleArray); + mMultiSampleSupport[DepthStencilFormats[i]] = multisampleArray; + + for (int j = D3DMULTISAMPLE_16_SAMPLES; j >= 0; --j) + { + if (multisampleArray[j] && j != D3DMULTISAMPLE_NONMASKABLE && j > max) + { + max = j; + } + } + } + } + + mMaxSupportedSamples = max; + + static const TCHAR windowName[] = TEXT("AngleHiddenWindow"); + static const TCHAR className[] = TEXT("STATIC"); + + { + TRACE_EVENT0("gpu", "CreateWindowEx"); + mDeviceWindow = CreateWindowEx(WS_EX_NOACTIVATE, className, windowName, WS_DISABLED | WS_POPUP, 0, 0, 1, 1, HWND_MESSAGE, NULL, GetModuleHandle(NULL), NULL); + } + + D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); + DWORD behaviorFlags = D3DCREATE_FPU_PRESERVE | D3DCREATE_NOWINDOWCHANGES; + + { + TRACE_EVENT0("gpu", "D3d9_CreateDevice"); + 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_BAD_ALLOC; + } + + if (FAILED(result)) + { + TRACE_EVENT0("gpu", "D3d9_CreateDevice2"); + 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_BAD_ALLOC; + } + } + + if (mD3d9Ex) + { + TRACE_EVENT0("gpu", "mDevice_QueryInterface"); + result = mDevice->QueryInterface(IID_IDirect3DDevice9Ex, (void**) &mDeviceEx); + ASSERT(SUCCEEDED(result)); + } + + { + TRACE_EVENT0("gpu", "ShaderCache initialize"); + mVertexShaderCache.initialize(mDevice); + mPixelShaderCache.initialize(mDevice); + } + + // Check occlusion query support + IDirect3DQuery9 *occlusionQuery = NULL; + { + TRACE_EVENT0("gpu", "device_CreateQuery"); + if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_OCCLUSION, &occlusionQuery)) && occlusionQuery) + { + occlusionQuery->Release(); + mOcclusionQuerySupport = true; + } + else + { + mOcclusionQuerySupport = false; + } + } + + // Check event query support + IDirect3DQuery9 *eventQuery = NULL; + { + TRACE_EVENT0("gpu", "device_CreateQuery2"); + if (SUCCEEDED(mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &eventQuery)) && eventQuery) + { + eventQuery->Release(); + mEventQuerySupport = true; + } + else + { + mEventQuerySupport = false; + } + } + + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + // Check vertex texture support + // 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)); + + // Check depth texture support + // we use INTZ for depth textures in Direct3D9 + // we also want NULL texture support to ensure the we can make depth-only FBOs + // see http://aras-p.info/texts/D3D9GPUHacks.html + mDepthTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_TEXTURE, D3DFMT_INTZ)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, + D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, D3DFMT_NULL)); + + // Check 32 bit floating point texture support + mFloat32FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, + D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, + D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); + + mFloat32RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); + + if (!mFloat32FilterSupport && !mFloat32RenderSupport) + { + mFloat32TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, + D3DRTYPE_TEXTURE, D3DFMT_A32B32G32R32F)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, + D3DRTYPE_CUBETEXTURE, D3DFMT_A32B32G32R32F)); + } + else + { + mFloat32TextureSupport = true; + } + + // Check 16 bit floating point texture support + mFloat16FilterSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, + D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_QUERY_FILTER, + D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); + + mFloat16RenderSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, + D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); + + if (!mFloat16FilterSupport && !mFloat16RenderSupport) + { + mFloat16TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, + D3DRTYPE_TEXTURE, D3DFMT_A16B16G16R16F)) && + SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, + D3DRTYPE_CUBETEXTURE, D3DFMT_A16B16G16R16F)); + } + else + { + mFloat16TextureSupport = true; + } + + // Check DXT texture support + mDXT1TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT1)); + mDXT3TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT3)); + mDXT5TextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_DXT5)); + + // Check luminance[alpha] texture support + mLuminanceTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_L8)); + mLuminanceAlphaTextureSupport = SUCCEEDED(mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, 0, D3DRTYPE_TEXTURE, D3DFMT_A8L8)); + + initializeDevice(); + + return EGL_SUCCESS; +} + +// 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() +{ + // Permanent non-default states + mDevice->SetRenderState(D3DRS_POINTSPRITEENABLE, TRUE); + mDevice->SetRenderState(D3DRS_LASTPIXEL, FALSE); + + if (mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0)) + { + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, (DWORD&)mDeviceCaps.MaxPointSize); + } + else + { + mDevice->SetRenderState(D3DRS_POINTSIZE_MAX, 0x3F800000); // 1.0f + } + + markAllStateDirty(); + + mSceneStarted = false; + + ASSERT(!mBlit && !mVertexDataManager && !mIndexDataManager); + mBlit = new Blit(this); + mVertexDataManager = new rx::VertexDataManager(this); + mIndexDataManager = new rx::IndexDataManager(this); +} + +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. + presentParameters.AutoDepthStencilFormat = D3DFMT_UNKNOWN; + 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; + + return presentParameters; +} + +int Renderer9::generateConfigs(ConfigDesc **configDescList) +{ + D3DDISPLAYMODE currentDisplayMode; + mD3d9->GetAdapterDisplayMode(mAdapter, ¤tDisplayMode); + + unsigned int numRenderFormats = ArraySize(RenderTargetFormats); + unsigned int numDepthFormats = ArraySize(DepthStencilFormats); + (*configDescList) = new ConfigDesc[numRenderFormats * numDepthFormats]; + int numConfigs = 0; + + for (unsigned int formatIndex = 0; formatIndex < numRenderFormats; formatIndex++) + { + D3DFORMAT renderTargetFormat = RenderTargetFormats[formatIndex]; + + HRESULT result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_RENDERTARGET, D3DRTYPE_SURFACE, renderTargetFormat); + + if (SUCCEEDED(result)) + { + for (unsigned int depthStencilIndex = 0; depthStencilIndex < numDepthFormats; depthStencilIndex++) + { + D3DFORMAT depthStencilFormat = DepthStencilFormats[depthStencilIndex]; + HRESULT result = D3D_OK; + + if(depthStencilFormat != D3DFMT_UNKNOWN) + { + result = mD3d9->CheckDeviceFormat(mAdapter, mDeviceType, currentDisplayMode.Format, D3DUSAGE_DEPTHSTENCIL, D3DRTYPE_SURFACE, depthStencilFormat); + } + + if (SUCCEEDED(result)) + { + if(depthStencilFormat != D3DFMT_UNKNOWN) + { + result = mD3d9->CheckDepthStencilMatch(mAdapter, mDeviceType, currentDisplayMode.Format, renderTargetFormat, depthStencilFormat); + } + + if (SUCCEEDED(result)) + { + ConfigDesc newConfig; + newConfig.renderTargetFormat = d3d9_gl::ConvertBackBufferFormat(renderTargetFormat); + newConfig.depthStencilFormat = d3d9_gl::ConvertDepthStencilFormat(depthStencilFormat); + newConfig.multiSample = 0; // FIXME: enumerate multi-sampling + newConfig.fastConfig = (currentDisplayMode.Format == renderTargetFormat); + + (*configDescList)[numConfigs++] = newConfig; + } + } + } + } + } + + return numConfigs; +} + +void Renderer9::deleteConfigs(ConfigDesc *configDescList) +{ + delete [] (configDescList); +} + +void Renderer9::startScene() +{ + if (!mSceneStarted) + { + long result = mDevice->BeginScene(); + if (SUCCEEDED(result)) { + // This is defensive checking against the device being + // lost at unexpected times. + mSceneStarted = true; + } + } +} + +void Renderer9::endScene() +{ + if (mSceneStarted) + { + // EndScene can fail if the device was lost, for example due + // to a TDR during a draw call. + mDevice->EndScene(); + mSceneStarted = false; + } +} + +void Renderer9::sync(bool block) +{ + HRESULT result; + + IDirect3DQuery9* query = allocateEventQuery(); + if (!query) + { + return; + } + + result = query->Issue(D3DISSUE_END); + ASSERT(SUCCEEDED(result)); + + do + { + result = query->GetData(NULL, 0, D3DGETDATA_FLUSH); + + if(block && result == S_FALSE) + { + // Keep polling, but allow other threads to do something useful first + Sleep(0); + // explicitly check for device loss + // some drivers seem to return S_FALSE even if the device is lost + // instead of D3DERR_DEVICELOST like they should + if (testDeviceLost(false)) + { + result = D3DERR_DEVICELOST; + } + } + } + while(block && result == S_FALSE); + + freeEventQuery(query); + + if (d3d9::isDeviceLostError(result)) + { + notifyDeviceLost(); + } +} + +SwapChain *Renderer9::createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) +{ + return new rx::SwapChain9(this, window, shareHandle, backBufferFormat, depthBufferFormat); +} + +IDirect3DQuery9* Renderer9::allocateEventQuery() +{ + IDirect3DQuery9 *query = NULL; + + if (mEventQueryPool.empty()) + { + HRESULT result = mDevice->CreateQuery(D3DQUERYTYPE_EVENT, &query); + ASSERT(SUCCEEDED(result)); + } + else + { + query = mEventQueryPool.back(); + mEventQueryPool.pop_back(); + } + + return query; +} + +void Renderer9::freeEventQuery(IDirect3DQuery9* query) +{ + if (mEventQueryPool.size() > 1000) + { + query->Release(); + } + else + { + mEventQueryPool.push_back(query); + } +} + +IDirect3DVertexShader9 *Renderer9::createVertexShader(const DWORD *function, size_t length) +{ + return mVertexShaderCache.create(function, length); +} + +IDirect3DPixelShader9 *Renderer9::createPixelShader(const DWORD *function, size_t length) +{ + return mPixelShaderCache.create(function, length); +} + +HRESULT Renderer9::createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer) +{ + D3DPOOL Pool = getBufferPool(Usage); + return mDevice->CreateVertexBuffer(Length, Usage, 0, Pool, ppVertexBuffer, NULL); +} + +VertexBuffer *Renderer9::createVertexBuffer() +{ + return new VertexBuffer9(this); +} + +HRESULT Renderer9::createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer) +{ + D3DPOOL Pool = getBufferPool(Usage); + return mDevice->CreateIndexBuffer(Length, Usage, Format, Pool, ppIndexBuffer, NULL); +} + +IndexBuffer *Renderer9::createIndexBuffer() +{ + return new IndexBuffer9(this); +} + +BufferStorage *Renderer9::createBufferStorage() +{ + return new BufferStorage9(); +} + +QueryImpl *Renderer9::createQuery(GLenum type) +{ + return new Query9(this, type); +} + +FenceImpl *Renderer9::createFence() +{ + return new Fence9(this); +} + +void Renderer9::setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &samplerState) +{ + bool *forceSetSamplers = (type == gl::SAMPLER_PIXEL) ? mForceSetPixelSamplerStates : mForceSetVertexSamplerStates; + gl::SamplerState *appliedSamplers = (type == gl::SAMPLER_PIXEL) ? mCurPixelSamplerStates: mCurVertexSamplerStates; + + if (forceSetSamplers[index] || memcmp(&samplerState, &appliedSamplers[index], sizeof(gl::SamplerState)) != 0) + { + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + 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_MAGFILTER, gl_d3d9::ConvertMagFilter(samplerState.magFilter, samplerState.maxAnisotropy)); + D3DTEXTUREFILTERTYPE d3dMinFilter, d3dMipFilter; + gl_d3d9::ConvertMinFilter(samplerState.minFilter, &d3dMinFilter, &d3dMipFilter, samplerState.maxAnisotropy); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MINFILTER, d3dMinFilter); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MIPFILTER, d3dMipFilter); + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXMIPLEVEL, samplerState.lodOffset); + if (mSupportsTextureFilterAnisotropy) + { + mDevice->SetSamplerState(d3dSampler, D3DSAMP_MAXANISOTROPY, (DWORD)samplerState.maxAnisotropy); + } + } + + forceSetSamplers[index] = false; + appliedSamplers[index] = samplerState; +} + +void Renderer9::setTexture(gl::SamplerType type, int index, gl::Texture *texture) +{ + int d3dSamplerOffset = (type == gl::SAMPLER_PIXEL) ? 0 : D3DVERTEXTEXTURESAMPLER0; + int d3dSampler = index + d3dSamplerOffset; + IDirect3DBaseTexture9 *d3dTexture = NULL; + unsigned int serial = 0; + bool forceSetTexture = false; + + unsigned int *appliedSerials = (type == gl::SAMPLER_PIXEL) ? mCurPixelTextureSerials : mCurVertexTextureSerials; + + if (texture) + { + TextureStorageInterface *texStorage = texture->getNativeTexture(); + if (texStorage) + { + TextureStorage9 *storage9 = TextureStorage9::makeTextureStorage9(texStorage->getStorageInstance()); + d3dTexture = storage9->getBaseTexture(); + } + // 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); + + serial = texture->getTextureSerial(); + forceSetTexture = texture->hasDirtyImages(); + } + + if (forceSetTexture || appliedSerials[index] != serial) + { + mDevice->SetTexture(d3dSampler, d3dTexture); + } + + appliedSerials[index] = serial; +} + +void Renderer9::setRasterizerState(const gl::RasterizerState &rasterState) +{ + bool rasterStateChanged = mForceSetRasterState || memcmp(&rasterState, &mCurRasterState, sizeof(gl::RasterizerState)) != 0; + + if (rasterStateChanged) + { + // Set the cull mode + if (rasterState.cullFace) + { + mDevice->SetRenderState(D3DRS_CULLMODE, gl_d3d9::ConvertCullMode(rasterState.cullMode, rasterState.frontFace)); + } + else + { + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + } + + if (rasterState.polygonOffsetFill) + { + if (mCurDepthSize > 0) + { + mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, *(DWORD*)&rasterState.polygonOffsetFactor); + + float depthBias = ldexp(rasterState.polygonOffsetUnits, -static_cast(mCurDepthSize)); + mDevice->SetRenderState(D3DRS_DEPTHBIAS, *(DWORD*)&depthBias); + } + } + else + { + mDevice->SetRenderState(D3DRS_SLOPESCALEDEPTHBIAS, 0); + mDevice->SetRenderState(D3DRS_DEPTHBIAS, 0); + } + + mCurRasterState = rasterState; + } + + mForceSetRasterState = false; +} + +void Renderer9::setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::Color &blendColor, unsigned int sampleMask) +{ + bool blendStateChanged = mForceSetBlendState || memcmp(&blendState, &mCurBlendState, sizeof(gl::BlendState)) != 0; + bool blendColorChanged = mForceSetBlendState || memcmp(&blendColor, &mCurBlendColor, sizeof(gl::Color)) != 0; + bool sampleMaskChanged = mForceSetBlendState || sampleMask != mCurSampleMask; + + if (blendStateChanged || blendColorChanged) + { + if (blendState.blend) + { + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + if (blendState.sourceBlendRGB != GL_CONSTANT_ALPHA && blendState.sourceBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA && + blendState.destBlendRGB != GL_CONSTANT_ALPHA && blendState.destBlendRGB != GL_ONE_MINUS_CONSTANT_ALPHA) + { + mDevice->SetRenderState(D3DRS_BLENDFACTOR, gl_d3d9::ConvertColor(blendColor)); + } + else + { + mDevice->SetRenderState(D3DRS_BLENDFACTOR, D3DCOLOR_RGBA(gl::unorm<8>(blendColor.alpha), + gl::unorm<8>(blendColor.alpha), + gl::unorm<8>(blendColor.alpha), + gl::unorm<8>(blendColor.alpha))); + } + + mDevice->SetRenderState(D3DRS_SRCBLEND, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendRGB)); + mDevice->SetRenderState(D3DRS_DESTBLEND, gl_d3d9::ConvertBlendFunc(blendState.destBlendRGB)); + mDevice->SetRenderState(D3DRS_BLENDOP, gl_d3d9::ConvertBlendOp(blendState.blendEquationRGB)); + + if (blendState.sourceBlendRGB != blendState.sourceBlendAlpha || + blendState.destBlendRGB != blendState.destBlendAlpha || + blendState.blendEquationRGB != blendState.blendEquationAlpha) + { + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + + mDevice->SetRenderState(D3DRS_SRCBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.sourceBlendAlpha)); + mDevice->SetRenderState(D3DRS_DESTBLENDALPHA, gl_d3d9::ConvertBlendFunc(blendState.destBlendAlpha)); + mDevice->SetRenderState(D3DRS_BLENDOPALPHA, gl_d3d9::ConvertBlendOp(blendState.blendEquationAlpha)); + } + else + { + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, FALSE); + } + } + else + { + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + } + + if (blendState.sampleAlphaToCoverage) + { + FIXME("Sample alpha to coverage is unimplemented."); + } + + // Set the color mask + bool zeroColorMaskAllowed = getAdapterVendor() != 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 + + DWORD colorMask = gl_d3d9::ConvertColorMask(blendState.colorMaskRed, blendState.colorMaskGreen, + blendState.colorMaskBlue, blendState.colorMaskAlpha); + if (colorMask == 0 && !zeroColorMaskAllowed) + { + // Enable green channel, but set blending so nothing will be drawn. + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, D3DCOLORWRITEENABLE_GREEN); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE); + + mDevice->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ZERO); + mDevice->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_ONE); + mDevice->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_ADD); + } + else + { + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, colorMask); + } + + mDevice->SetRenderState(D3DRS_DITHERENABLE, blendState.dither ? TRUE : FALSE); + + mCurBlendState = blendState; + mCurBlendColor = blendColor; + } + + if (sampleMaskChanged) + { + // Set the multisample mask + mDevice->SetRenderState(D3DRS_MULTISAMPLEANTIALIAS, TRUE); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, static_cast(sampleMask)); + + mCurSampleMask = sampleMask; + } + + mForceSetBlendState = false; +} + +void Renderer9::setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW) +{ + bool depthStencilStateChanged = mForceSetDepthStencilState || + memcmp(&depthStencilState, &mCurDepthStencilState, sizeof(gl::DepthStencilState)) != 0; + bool stencilRefChanged = mForceSetDepthStencilState || stencilRef != mCurStencilRef || + stencilBackRef != mCurStencilBackRef; + bool frontFaceCCWChanged = mForceSetDepthStencilState || frontFaceCCW != mCurFrontFaceCCW; + + if (depthStencilStateChanged) + { + if (depthStencilState.depthTest) + { + mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_TRUE); + mDevice->SetRenderState(D3DRS_ZFUNC, gl_d3d9::ConvertComparison(depthStencilState.depthFunc)); + } + else + { + mDevice->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + } + + mCurDepthStencilState = depthStencilState; + } + + if (depthStencilStateChanged || stencilRefChanged || frontFaceCCWChanged) + { + if (depthStencilState.stencilTest && mCurStencilSize > 0) + { + mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, TRUE); + + // FIXME: Unsupported by D3D9 + const D3DRENDERSTATETYPE D3DRS_CCW_STENCILREF = D3DRS_STENCILREF; + const D3DRENDERSTATETYPE D3DRS_CCW_STENCILMASK = D3DRS_STENCILMASK; + const D3DRENDERSTATETYPE D3DRS_CCW_STENCILWRITEMASK = D3DRS_STENCILWRITEMASK; + if (depthStencilState.stencilWritemask != depthStencilState.stencilBackWritemask || + stencilRef != stencilBackRef || + depthStencilState.stencilMask != depthStencilState.stencilBackMask) + { + ERR("Separate front/back stencil writemasks, reference values, or stencil mask values are invalid under WebGL."); + return gl::error(GL_INVALID_OPERATION); + } + + // get the maximum size of the stencil ref + unsigned int maxStencil = (1 << mCurStencilSize) - 1; + + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, + depthStencilState.stencilWritemask); + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + gl_d3d9::ConvertComparison(depthStencilState.stencilFunc)); + + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, + (stencilRef < (int)maxStencil) ? stencilRef : maxStencil); + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, + depthStencilState.stencilMask); + + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + gl_d3d9::ConvertStencilOp(depthStencilState.stencilFail)); + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthFail)); + mDevice->SetRenderState(frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + gl_d3d9::ConvertStencilOp(depthStencilState.stencilPassDepthPass)); + + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILWRITEMASK : D3DRS_CCW_STENCILWRITEMASK, + depthStencilState.stencilBackWritemask); + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFUNC : D3DRS_CCW_STENCILFUNC, + gl_d3d9::ConvertComparison(depthStencilState.stencilBackFunc)); + + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILREF : D3DRS_CCW_STENCILREF, + (stencilBackRef < (int)maxStencil) ? stencilBackRef : maxStencil); + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILMASK : D3DRS_CCW_STENCILMASK, + depthStencilState.stencilBackMask); + + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILFAIL : D3DRS_CCW_STENCILFAIL, + gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackFail)); + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILZFAIL : D3DRS_CCW_STENCILZFAIL, + gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthFail)); + mDevice->SetRenderState(!frontFaceCCW ? D3DRS_STENCILPASS : D3DRS_CCW_STENCILPASS, + gl_d3d9::ConvertStencilOp(depthStencilState.stencilBackPassDepthPass)); + } + else + { + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + } + + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, depthStencilState.depthMask ? TRUE : FALSE); + + mCurStencilRef = stencilRef; + mCurStencilBackRef = stencilBackRef; + mCurFrontFaceCCW = frontFaceCCW; + } + + mForceSetDepthStencilState = false; +} + +void Renderer9::setScissorRectangle(const gl::Rectangle &scissor, bool enabled) +{ + bool scissorChanged = mForceSetScissor || + memcmp(&scissor, &mCurScissor, sizeof(gl::Rectangle)) != 0 || + enabled != mScissorEnabled; + + if (scissorChanged) + { + if (enabled) + { + RECT rect; + rect.left = gl::clamp(scissor.x, 0, static_cast(mRenderTargetDesc.width)); + rect.top = gl::clamp(scissor.y, 0, static_cast(mRenderTargetDesc.height)); + rect.right = gl::clamp(scissor.x + scissor.width, 0, static_cast(mRenderTargetDesc.width)); + rect.bottom = gl::clamp(scissor.y + scissor.height, 0, static_cast(mRenderTargetDesc.height)); + mDevice->SetScissorRect(&rect); + } + + mDevice->SetRenderState(D3DRS_SCISSORTESTENABLE, enabled ? TRUE : FALSE); + + mScissorEnabled = enabled; + mCurScissor = scissor; + } + + mForceSetScissor = false; +} + +bool Renderer9::setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + bool ignoreViewport) +{ + gl::Rectangle actualViewport = viewport; + float actualZNear = gl::clamp01(zNear); + float actualZFar = gl::clamp01(zFar); + if (ignoreViewport) + { + actualViewport.x = 0; + actualViewport.y = 0; + actualViewport.width = mRenderTargetDesc.width; + actualViewport.height = mRenderTargetDesc.height; + actualZNear = 0.0f; + actualZFar = 1.0f; + } + + D3DVIEWPORT9 dxViewport; + dxViewport.X = gl::clamp(actualViewport.x, 0, static_cast(mRenderTargetDesc.width)); + dxViewport.Y = gl::clamp(actualViewport.y, 0, static_cast(mRenderTargetDesc.height)); + dxViewport.Width = gl::clamp(actualViewport.width, 0, static_cast(mRenderTargetDesc.width) - static_cast(dxViewport.X)); + dxViewport.Height = gl::clamp(actualViewport.height, 0, static_cast(mRenderTargetDesc.height) - static_cast(dxViewport.Y)); + dxViewport.MinZ = actualZNear; + dxViewport.MaxZ = actualZFar; + + if (dxViewport.Width <= 0 || dxViewport.Height <= 0) + { + return false; // Nothing to render + } + + float depthFront = !gl::IsTriangleMode(drawMode) ? 0.0f : (frontFace == GL_CCW ? 1.0f : -1.0f); + + bool viewportChanged = mForceSetViewport || memcmp(&actualViewport, &mCurViewport, sizeof(gl::Rectangle)) != 0 || + actualZNear != mCurNear || actualZFar != mCurFar || mCurDepthFront != depthFront; + if (viewportChanged) + { + mDevice->SetViewport(&dxViewport); + + mCurViewport = actualViewport; + mCurNear = actualZNear; + mCurFar = actualZFar; + mCurDepthFront = depthFront; + + dx_VertexConstants vc = {0}; + dx_PixelConstants pc = {0}; + + vc.viewAdjust[0] = (float)((actualViewport.width - (int)dxViewport.Width) + 2 * (actualViewport.x - (int)dxViewport.X) - 1) / dxViewport.Width; + vc.viewAdjust[1] = (float)((actualViewport.height - (int)dxViewport.Height) + 2 * (actualViewport.y - (int)dxViewport.Y) - 1) / dxViewport.Height; + vc.viewAdjust[2] = (float)actualViewport.width / dxViewport.Width; + vc.viewAdjust[3] = (float)actualViewport.height / dxViewport.Height; + + pc.viewCoords[0] = actualViewport.width * 0.5f; + pc.viewCoords[1] = actualViewport.height * 0.5f; + pc.viewCoords[2] = actualViewport.x + (actualViewport.width * 0.5f); + pc.viewCoords[3] = actualViewport.y + (actualViewport.height * 0.5f); + + pc.depthFront[0] = (actualZFar - actualZNear) * 0.5f; + pc.depthFront[1] = (actualZNear + actualZFar) * 0.5f; + pc.depthFront[2] = depthFront; + + vc.depthRange[0] = actualZNear; + vc.depthRange[1] = actualZFar; + vc.depthRange[2] = actualZFar - actualZNear; + + pc.depthRange[0] = actualZNear; + pc.depthRange[1] = actualZFar; + pc.depthRange[2] = actualZFar - actualZNear; + + if (memcmp(&vc, &mVertexConstants, sizeof(dx_VertexConstants)) != 0) + { + mVertexConstants = vc; + mDxUniformsDirty = true; + } + + if (memcmp(&pc, &mPixelConstants, sizeof(dx_PixelConstants)) != 0) + { + mPixelConstants = pc; + mDxUniformsDirty = true; + } + } + + mForceSetViewport = false; + return true; +} + +bool Renderer9::applyPrimitiveType(GLenum mode, GLsizei count) +{ + 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: + return gl::error(GL_INVALID_ENUM, false); + } + + return mPrimitiveCount > 0; +} + + +gl::Renderbuffer *Renderer9::getNullColorbuffer(gl::Renderbuffer *depthbuffer) +{ + if (!depthbuffer) + { + ERR("Unexpected null depthbuffer for depth-only FBO."); + return NULL; + } + + GLsizei width = depthbuffer->getWidth(); + GLsizei height = depthbuffer->getHeight(); + + // search cached nullcolorbuffers + for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + if (mNullColorbufferCache[i].buffer != NULL && + mNullColorbufferCache[i].width == width && + mNullColorbufferCache[i].height == height) + { + mNullColorbufferCache[i].lruCount = ++mMaxNullColorbufferLRU; + return mNullColorbufferCache[i].buffer; + } + } + + gl::Renderbuffer *nullbuffer = new gl::Renderbuffer(this, 0, new gl::Colorbuffer(this, width, height, GL_NONE, 0)); + + // add nullbuffer to the cache + NullColorbufferCacheEntry *oldest = &mNullColorbufferCache[0]; + for (int i = 1; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + if (mNullColorbufferCache[i].lruCount < oldest->lruCount) + { + oldest = &mNullColorbufferCache[i]; + } + } + + delete oldest->buffer; + oldest->buffer = nullbuffer; + oldest->lruCount = ++mMaxNullColorbufferLRU; + oldest->width = width; + oldest->height = height; + + return nullbuffer; +} + +bool Renderer9::applyRenderTarget(gl::Framebuffer *framebuffer) +{ + // 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. + gl::Renderbuffer *renderbufferObject = NULL; + if (framebuffer->getColorbufferType(0) != GL_NONE) + { + renderbufferObject = framebuffer->getColorbuffer(0); + } + else + { + renderbufferObject = getNullColorbuffer(framebuffer->getDepthbuffer()); + } + if (!renderbufferObject) + { + ERR("unable to locate renderbuffer for FBO."); + return false; + } + + bool renderTargetChanged = false; + unsigned int renderTargetSerial = renderbufferObject->getSerial(); + if (renderTargetSerial != mAppliedRenderTargetSerial) + { + // Apply the render target on the device + IDirect3DSurface9 *renderTargetSurface = NULL; + + RenderTarget *renderTarget = renderbufferObject->getRenderTarget(); + if (renderTarget) + { + renderTargetSurface = RenderTarget9::makeRenderTarget9(renderTarget)->getSurface(); + } + + if (!renderTargetSurface) + { + ERR("render target pointer unexpectedly null."); + return false; // Context must be lost + } + + mDevice->SetRenderTarget(0, renderTargetSurface); + renderTargetSurface->Release(); + + mAppliedRenderTargetSerial = renderTargetSerial; + renderTargetChanged = true; + } + + gl::Renderbuffer *depthStencil = NULL; + unsigned int depthbufferSerial = 0; + unsigned int stencilbufferSerial = 0; + if (framebuffer->getDepthbufferType() != GL_NONE) + { + depthStencil = framebuffer->getDepthbuffer(); + if (!depthStencil) + { + ERR("Depth stencil pointer unexpectedly null."); + return false; + } + + depthbufferSerial = depthStencil->getSerial(); + } + else if (framebuffer->getStencilbufferType() != GL_NONE) + { + depthStencil = framebuffer->getStencilbuffer(); + if (!depthStencil) + { + ERR("Depth stencil pointer unexpectedly null."); + return false; + } + + stencilbufferSerial = depthStencil->getSerial(); + } + + if (depthbufferSerial != mAppliedDepthbufferSerial || + stencilbufferSerial != mAppliedStencilbufferSerial || + !mDepthStencilInitialized) + { + unsigned int depthSize = 0; + unsigned int stencilSize = 0; + + // Apply the depth stencil on the device + if (depthStencil) + { + IDirect3DSurface9 *depthStencilSurface = NULL; + RenderTarget *depthStencilRenderTarget = depthStencil->getDepthStencil(); + + if (depthStencilRenderTarget) + { + depthStencilSurface = RenderTarget9::makeRenderTarget9(depthStencilRenderTarget)->getSurface(); + } + + if (!depthStencilSurface) + { + ERR("depth stencil pointer unexpectedly null."); + return false; // Context must be lost + } + + mDevice->SetDepthStencilSurface(depthStencilSurface); + depthStencilSurface->Release(); + + depthSize = depthStencil->getDepthSize(); + stencilSize = depthStencil->getStencilSize(); + } + else + { + mDevice->SetDepthStencilSurface(NULL); + } + + if (!mDepthStencilInitialized || depthSize != mCurDepthSize) + { + mCurDepthSize = depthSize; + mForceSetRasterState = true; + } + + if (!mDepthStencilInitialized || stencilSize != mCurStencilSize) + { + mCurStencilSize = stencilSize; + mForceSetDepthStencilState = true; + } + + mAppliedDepthbufferSerial = depthbufferSerial; + mAppliedStencilbufferSerial = stencilbufferSerial; + mDepthStencilInitialized = true; + } + + if (renderTargetChanged || !mRenderTargetDescInitialized) + { + mForceSetScissor = true; + mForceSetViewport = true; + + mRenderTargetDesc.width = renderbufferObject->getWidth(); + mRenderTargetDesc.height = renderbufferObject->getHeight(); + mRenderTargetDesc.format = renderbufferObject->getActualFormat(); + mRenderTargetDescInitialized = true; + } + + return true; +} + +GLenum Renderer9::applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances) +{ + TranslatedAttribute attributes[gl::MAX_VERTEX_ATTRIBS]; + GLenum err = mVertexDataManager->prepareVertexData(vertexAttributes, programBinary, first, count, attributes, instances); + if (err != GL_NO_ERROR) + { + return err; + } + + return mVertexDeclarationCache.applyDeclaration(mDevice, attributes, programBinary, instances, &mRepeatDraw); +} + +// Applies the indices and element array bindings to the Direct3D 9 device +GLenum Renderer9::applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo) +{ + GLenum err = mIndexDataManager->prepareIndexData(type, count, elementArrayBuffer, indices, indexInfo); + + if (err == GL_NO_ERROR) + { + // Directly binding the storage buffer is not supported for d3d9 + ASSERT(indexInfo->storage == NULL); + + if (indexInfo->serial != mAppliedIBSerial) + { + IndexBuffer9* indexBuffer = IndexBuffer9::makeIndexBuffer9(indexInfo->indexBuffer); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = indexInfo->serial; + } + } + + return err; +} + +void Renderer9::drawArrays(GLenum mode, GLsizei count, GLsizei instances) +{ + startScene(); + + if (mode == GL_LINE_LOOP) + { + drawLineLoop(count, GL_NONE, NULL, 0, NULL); + } + else if (instances > 0) + { + StaticIndexBufferInterface *countingIB = mIndexDataManager->getCountingIndices(count); + if (countingIB) + { + if (mAppliedIBSerial != countingIB->getSerial()) + { + IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(countingIB->getIndexBuffer()); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = countingIB->getSerial(); + } + + for (int i = 0; i < mRepeatDraw; i++) + { + mDevice->DrawIndexedPrimitive(mPrimitiveType, 0, 0, count, 0, mPrimitiveCount); + } + } + else + { + ERR("Could not create a counting index buffer for glDrawArraysInstanced."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + else // Regular case + { + mDevice->DrawPrimitive(mPrimitiveType, 0, mPrimitiveCount); + } +} + +void Renderer9::drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei /*instances*/) +{ + startScene(); + + if (mode == GL_POINTS) + { + drawIndexedPoints(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + } + else if (mode == GL_LINE_LOOP) + { + drawLineLoop(count, type, indices, indexInfo.minIndex, elementArrayBuffer); + } + else + { + for (int i = 0; i < mRepeatDraw; i++) + { + GLsizei vertexCount = indexInfo.maxIndex - indexInfo.minIndex + 1; + mDevice->DrawIndexedPrimitive(mPrimitiveType, -(INT)indexInfo.minIndex, indexInfo.minIndex, vertexCount, indexInfo.startIndex, mPrimitiveCount); + } + } +} + +void Renderer9::drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer) +{ + // Get the raw indices for an indexed draw + if (type != GL_NONE && elementArrayBuffer) + { + gl::Buffer *indexBuffer = elementArrayBuffer; + BufferStorage *storage = indexBuffer->getStorage(); + intptr_t offset = reinterpret_cast(indices); + indices = static_cast(storage->getData()) + offset; + } + + unsigned int startIndex = 0; + + if (get32BitIndexSupport()) + { + if (!mLineLoopIB) + { + mLineLoopIB = new StreamingIndexBufferInterface(this); + if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_INT)) + { + delete mLineLoopIB; + mLineLoopIB = NULL; + + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned int))) + { + ERR("Could not create a 32-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + + const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned int); + if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_INT)) + { + ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + void* mappedMemory = NULL; + unsigned int offset = 0; + if (!mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + { + ERR("Could not map index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + 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(); + } + + if (!mLineLoopIB->unmapBuffer()) + { + ERR("Could not unmap index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + else + { + if (!mLineLoopIB) + { + mLineLoopIB = new StreamingIndexBufferInterface(this); + if (!mLineLoopIB->reserveBufferSpace(INITIAL_INDEX_BUFFER_SIZE, GL_UNSIGNED_SHORT)) + { + delete mLineLoopIB; + mLineLoopIB = NULL; + + ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + // Checked by Renderer9::applyPrimitiveType + ASSERT(count >= 0); + + if (static_cast(count) + 1 > (std::numeric_limits::max() / sizeof(unsigned short))) + { + ERR("Could not create a 16-bit looping index buffer for GL_LINE_LOOP, too many indices required."); + return gl::error(GL_OUT_OF_MEMORY); + } + + const unsigned int spaceNeeded = (static_cast(count) + 1) * sizeof(unsigned short); + if (!mLineLoopIB->reserveBufferSpace(spaceNeeded, GL_UNSIGNED_SHORT)) + { + ERR("Could not reserve enough space in looping index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + void* mappedMemory = NULL; + unsigned int offset; + if (mLineLoopIB->mapBuffer(spaceNeeded, &mappedMemory, &offset)) + { + ERR("Could not map index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + + 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] = 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(); + } + + if (!mLineLoopIB->unmapBuffer()) + { + ERR("Could not unmap index buffer for GL_LINE_LOOP."); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + if (mAppliedIBSerial != mLineLoopIB->getSerial()) + { + IndexBuffer9 *indexBuffer = IndexBuffer9::makeIndexBuffer9(mLineLoopIB->getIndexBuffer()); + + mDevice->SetIndices(indexBuffer->getBuffer()); + mAppliedIBSerial = mLineLoopIB->getSerial(); + } + + mDevice->DrawIndexedPrimitive(D3DPT_LINESTRIP, -minIndex, minIndex, count, startIndex, count); +} + +template +static void drawPoints(IDirect3DDevice9* device, GLsizei count, const GLvoid *indices, int minIndex) +{ + for (int i = 0; i < count; i++) + { + unsigned int indexValue = static_cast(static_cast(indices)[i]) - minIndex; + device->DrawPrimitive(D3DPT_POINTLIST, indexValue, 1); + } +} + +void Renderer9::drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *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. + + if (elementArrayBuffer) + { + BufferStorage *storage = elementArrayBuffer->getStorage(); + intptr_t offset = reinterpret_cast(indices); + indices = static_cast(storage->getData()) + offset; + } + + switch (type) + { + case GL_UNSIGNED_BYTE: drawPoints(mDevice, count, indices, minIndex); break; + case GL_UNSIGNED_SHORT: drawPoints(mDevice, count, indices, minIndex); break; + case GL_UNSIGNED_INT: drawPoints(mDevice, count, indices, minIndex); break; + default: UNREACHABLE(); + } +} + +void Renderer9::applyShaders(gl::ProgramBinary *programBinary) +{ + unsigned int programBinarySerial = programBinary->getSerial(); + if (programBinarySerial != mAppliedProgramBinarySerial) + { + ShaderExecutable *vertexExe = programBinary->getVertexExecutable(); + ShaderExecutable *pixelExe = programBinary->getPixelExecutable(); + + IDirect3DVertexShader9 *vertexShader = NULL; + if (vertexExe) vertexShader = ShaderExecutable9::makeShaderExecutable9(vertexExe)->getVertexShader(); + + IDirect3DPixelShader9 *pixelShader = NULL; + if (pixelExe) pixelShader = ShaderExecutable9::makeShaderExecutable9(pixelExe)->getPixelShader(); + + mDevice->SetPixelShader(pixelShader); + mDevice->SetVertexShader(vertexShader); + programBinary->dirtyAllUniforms(); + mDxUniformsDirty = true; + + mAppliedProgramBinarySerial = programBinarySerial; + } +} + +void Renderer9::applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray) +{ + for (std::vector::const_iterator ub = uniformArray->begin(), ue = uniformArray->end(); ub != ue; ++ub) + { + gl::Uniform *targetUniform = *ub; + + if (targetUniform->dirty) + { + GLfloat *f = (GLfloat*)targetUniform->data; + GLint *i = (GLint*)targetUniform->data; + + switch (targetUniform->type) + { + case GL_SAMPLER_2D: + case GL_SAMPLER_CUBE: + break; + case GL_BOOL: + case GL_BOOL_VEC2: + case GL_BOOL_VEC3: + case GL_BOOL_VEC4: + applyUniformnbv(targetUniform, i); + break; + case GL_FLOAT: + case GL_FLOAT_VEC2: + case GL_FLOAT_VEC3: + case GL_FLOAT_VEC4: + case GL_FLOAT_MAT2: + case GL_FLOAT_MAT3: + case GL_FLOAT_MAT4: + applyUniformnfv(targetUniform, f); + break; + case GL_INT: + case GL_INT_VEC2: + case GL_INT_VEC3: + case GL_INT_VEC4: + applyUniformniv(targetUniform, i); + break; + default: + UNREACHABLE(); + } + + targetUniform->dirty = false; + } + } + + // Driver uniforms + if (mDxUniformsDirty) + { + mDevice->SetVertexShaderConstantF(0, (float*)&mVertexConstants, sizeof(dx_VertexConstants) / sizeof(float[4])); + mDevice->SetPixelShaderConstantF(0, (float*)&mPixelConstants, sizeof(dx_PixelConstants) / sizeof(float[4])); + mDxUniformsDirty = false; + } +} + +void Renderer9::applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v) +{ + if (targetUniform->psRegisterIndex >= 0) + { + mDevice->SetPixelShaderConstantF(targetUniform->psRegisterIndex, v, targetUniform->registerCount); + } + + if (targetUniform->vsRegisterIndex >= 0) + { + mDevice->SetVertexShaderConstantF(targetUniform->vsRegisterIndex, v, targetUniform->registerCount); + } +} + +void Renderer9::applyUniformniv(gl::Uniform *targetUniform, const GLint *v) +{ + ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); + GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; + + for (unsigned int i = 0; i < targetUniform->registerCount; i++) + { + vector[i][0] = (GLfloat)v[4 * i + 0]; + vector[i][1] = (GLfloat)v[4 * i + 1]; + vector[i][2] = (GLfloat)v[4 * i + 2]; + vector[i][3] = (GLfloat)v[4 * i + 3]; + } + + applyUniformnfv(targetUniform, (GLfloat*)vector); +} + +void Renderer9::applyUniformnbv(gl::Uniform *targetUniform, const GLint *v) +{ + ASSERT(targetUniform->registerCount <= MAX_VERTEX_CONSTANT_VECTORS_D3D9); + GLfloat vector[MAX_VERTEX_CONSTANT_VECTORS_D3D9][4]; + + for (unsigned int i = 0; i < targetUniform->registerCount; i++) + { + vector[i][0] = (v[4 * i + 0] == GL_FALSE) ? 0.0f : 1.0f; + vector[i][1] = (v[4 * i + 1] == GL_FALSE) ? 0.0f : 1.0f; + vector[i][2] = (v[4 * i + 2] == GL_FALSE) ? 0.0f : 1.0f; + vector[i][3] = (v[4 * i + 3] == GL_FALSE) ? 0.0f : 1.0f; + } + + applyUniformnfv(targetUniform, (GLfloat*)vector); +} + +void Renderer9::clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer) +{ + D3DCOLOR color = D3DCOLOR_ARGB(gl::unorm<8>(clearParams.colorClearValue.alpha), + gl::unorm<8>(clearParams.colorClearValue.red), + gl::unorm<8>(clearParams.colorClearValue.green), + gl::unorm<8>(clearParams.colorClearValue.blue)); + float depth = gl::clamp01(clearParams.depthClearValue); + int stencil = clearParams.stencilClearValue & 0x000000FF; + + unsigned int stencilUnmasked = 0x0; + if ((clearParams.mask & GL_STENCIL_BUFFER_BIT) && frameBuffer->hasStencil()) + { + unsigned int stencilSize = gl::GetStencilSize(frameBuffer->getStencilbuffer()->getActualFormat()); + stencilUnmasked = (0x1 << stencilSize) - 1; + } + + bool alphaUnmasked = (gl::GetAlphaSize(mRenderTargetDesc.format) == 0) || clearParams.colorMaskAlpha; + + const bool needMaskedStencilClear = (clearParams.mask & GL_STENCIL_BUFFER_BIT) && + (clearParams.stencilWriteMask & stencilUnmasked) != stencilUnmasked; + const bool needMaskedColorClear = (clearParams.mask & GL_COLOR_BUFFER_BIT) && + !(clearParams.colorMaskRed && clearParams.colorMaskGreen && + clearParams.colorMaskBlue && alphaUnmasked); + + if (needMaskedColorClear || needMaskedStencilClear) + { + // State which is altered in all paths from this point to the clear call is saved. + // 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) + { + hr = mDevice->BeginStateBlock(); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + mDevice->SetPixelShader(NULL); + mDevice->SetVertexShader(NULL); + mDevice->SetFVF(D3DFVF_XYZRHW | D3DFVF_DIFFUSE); + mDevice->SetStreamSource(0, NULL, 0, 0); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + + for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mDevice->SetStreamSourceFreq(i, 1); + } + + hr = mDevice->EndStateBlock(&mMaskedClearSavedState); + ASSERT(SUCCEEDED(hr) || hr == D3DERR_OUTOFVIDEOMEMORY || hr == E_OUTOFMEMORY); + } + + ASSERT(mMaskedClearSavedState != NULL); + + if (mMaskedClearSavedState != NULL) + { + hr = mMaskedClearSavedState->Capture(); + ASSERT(SUCCEEDED(hr)); + } + + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ZFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_ZENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + mDevice->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + mDevice->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + mDevice->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + mDevice->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + + if (clearParams.mask & GL_COLOR_BUFFER_BIT) + { + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, + gl_d3d9::ConvertColorMask(clearParams.colorMaskRed, + clearParams.colorMaskGreen, + clearParams.colorMaskBlue, + clearParams.colorMaskAlpha)); + } + else + { + mDevice->SetRenderState(D3DRS_COLORWRITEENABLE, 0); + } + + if (stencilUnmasked != 0x0 && (clearParams.mask & GL_STENCIL_BUFFER_BIT)) + { + mDevice->SetRenderState(D3DRS_STENCILENABLE, TRUE); + mDevice->SetRenderState(D3DRS_TWOSIDEDSTENCILMODE, FALSE); + mDevice->SetRenderState(D3DRS_STENCILFUNC, D3DCMP_ALWAYS); + mDevice->SetRenderState(D3DRS_STENCILREF, stencil); + mDevice->SetRenderState(D3DRS_STENCILWRITEMASK, clearParams.stencilWriteMask); + mDevice->SetRenderState(D3DRS_STENCILFAIL, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILZFAIL, D3DSTENCILOP_REPLACE); + mDevice->SetRenderState(D3DRS_STENCILPASS, D3DSTENCILOP_REPLACE); + } + else + { + mDevice->SetRenderState(D3DRS_STENCILENABLE, FALSE); + } + + mDevice->SetPixelShader(NULL); + mDevice->SetVertexShader(NULL); + mDevice->SetFVF(D3DFVF_XYZRHW); + mDevice->SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, TRUE); + mDevice->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TFACTOR); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAOP, D3DTOP_SELECTARG1); + mDevice->SetTextureStageState(0, D3DTSS_ALPHAARG1, D3DTA_TFACTOR); + mDevice->SetRenderState(D3DRS_TEXTUREFACTOR, color); + mDevice->SetRenderState(D3DRS_MULTISAMPLEMASK, 0xFFFFFFFF); + + for(int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mDevice->SetStreamSourceFreq(i, 1); + } + + float quad[4][4]; // A quadrilateral covering the target, aligned to match the edges + quad[0][0] = -0.5f; + quad[0][1] = mRenderTargetDesc.height - 0.5f; + quad[0][2] = 0.0f; + quad[0][3] = 1.0f; + + quad[1][0] = mRenderTargetDesc.width - 0.5f; + quad[1][1] = mRenderTargetDesc.height - 0.5f; + quad[1][2] = 0.0f; + quad[1][3] = 1.0f; + + quad[2][0] = -0.5f; + quad[2][1] = -0.5f; + quad[2][2] = 0.0f; + quad[2][3] = 1.0f; + + quad[3][0] = mRenderTargetDesc.width - 0.5f; + quad[3][1] = -0.5f; + quad[3][2] = 0.0f; + quad[3][3] = 1.0f; + + startScene(); + mDevice->DrawPrimitiveUP(D3DPT_TRIANGLESTRIP, 2, quad, sizeof(float[4])); + + if (clearParams.mask & GL_DEPTH_BUFFER_BIT) + { + mDevice->SetRenderState(D3DRS_ZENABLE, TRUE); + mDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE); + mDevice->Clear(0, NULL, D3DCLEAR_ZBUFFER, color, depth, stencil); + } + + if (mMaskedClearSavedState != NULL) + { + mMaskedClearSavedState->Apply(); + } + } + else if (clearParams.mask) + { + DWORD dxClearFlags = 0; + if (clearParams.mask & GL_COLOR_BUFFER_BIT) + { + dxClearFlags |= D3DCLEAR_TARGET; + } + if (clearParams.mask & GL_DEPTH_BUFFER_BIT) + { + dxClearFlags |= D3DCLEAR_ZBUFFER; + } + if (clearParams.mask & GL_STENCIL_BUFFER_BIT) + { + dxClearFlags |= D3DCLEAR_STENCIL; + } + + mDevice->Clear(0, NULL, dxClearFlags, color, depth, stencil); + } +} + +void Renderer9::markAllStateDirty() +{ + mAppliedRenderTargetSerial = 0; + mAppliedDepthbufferSerial = 0; + mAppliedStencilbufferSerial = 0; + mDepthStencilInitialized = false; + mRenderTargetDescInitialized = false; + + mForceSetDepthStencilState = true; + mForceSetRasterState = true; + mForceSetScissor = true; + mForceSetViewport = true; + mForceSetBlendState = true; + + for (unsigned int i = 0; i < gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS; i++) + { + mForceSetVertexSamplerStates[i] = true; + mCurVertexTextureSerials[i] = 0; + } + for (unsigned int i = 0; i < gl::MAX_TEXTURE_IMAGE_UNITS; i++) + { + mForceSetPixelSamplerStates[i] = true; + mCurPixelTextureSerials[i] = 0; + } + + mAppliedIBSerial = 0; + mAppliedProgramBinarySerial = 0; + mDxUniformsDirty = true; + + mVertexDeclarationCache.markStateDirty(); +} + +void Renderer9::releaseDeviceResources() +{ + while (!mEventQueryPool.empty()) + { + mEventQueryPool.back()->Release(); + mEventQueryPool.pop_back(); + } + + SafeRelease(mMaskedClearSavedState); + + mVertexShaderCache.clear(); + mPixelShaderCache.clear(); + + SafeDelete(mBlit); + SafeDelete(mVertexDataManager); + SafeDelete(mIndexDataManager); + SafeDelete(mLineLoopIB); + + for (int i = 0; i < NUM_NULL_COLORBUFFER_CACHE_ENTRIES; i++) + { + SafeDelete(mNullColorbufferCache[i].buffer); + } + +} + + +void Renderer9::notifyDeviceLost() +{ + mDeviceLost = true; + mDisplay->notifyDeviceLost(); +} + +bool Renderer9::isDeviceLost() +{ + return mDeviceLost; +} + +// set notify to true to broadcast a message to all contexts of the device loss +bool Renderer9::testDeviceLost(bool notify) +{ + 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; + if (notify) + { + notifyDeviceLost(); + } + } + + return isLost; +} + +HRESULT Renderer9::getDeviceStatusCode() +{ + HRESULT status = D3D_OK; + + if (mDeviceEx) + { + status = mDeviceEx->CheckDeviceState(NULL); + } + else if (mDevice) + { + status = mDevice->TestCooperativeLevel(); + } + + return status; +} + +bool Renderer9::testDeviceResettable() +{ + // On D3D9Ex, DEVICELOST represents a hung device that needs to be restarted + // 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; + } +} + +bool Renderer9::resetDevice() +{ + releaseDeviceResources(); + + D3DPRESENT_PARAMETERS presentParameters = getDefaultPresentParameters(); + + HRESULT result = D3D_OK; + bool lost = testDeviceLost(false); + bool removedDevice = (getDeviceStatusCode() == D3DERR_DEVICEREMOVED); + + // Device Removed is a feature which is only present with D3D9Ex + ASSERT(mDeviceEx != NULL || !removedDevice); + + for (int attempts = 3; lost && attempts > 0; attempts--) + { + if (removedDevice) + { + // Device removed, which may trigger on driver reinstallation, + // may cause a longer wait other reset attempts before the + // system is ready to handle creating a new device. + Sleep(800); + lost = !resetRemovedDevice(); + } + else if (mDeviceEx) + { + Sleep(500); // Give the graphics driver some CPU time + result = mDeviceEx->ResetEx(&presentParameters, NULL); + lost = testDeviceLost(false); + } + else + { + result = mDevice->TestCooperativeLevel(); + while (result == D3DERR_DEVICELOST) + { + Sleep(100); // Give the graphics driver some CPU time + result = mDevice->TestCooperativeLevel(); + } + + if (result == D3DERR_DEVICENOTRESET) + { + result = mDevice->Reset(&presentParameters); + } + lost = testDeviceLost(false); + } + } + + if (FAILED(result)) + { + ERR("Reset/ResetEx failed multiple times: 0x%08X", result); + return false; + } + + if (removedDevice && lost) + { + ERR("Device lost reset failed multiple times"); + return false; + } + + // If the device was removed, we already finished re-initialization in resetRemovedDevice + if (!removedDevice) + { + // reset device defaults + initializeDevice(); + } + + mDeviceLost = false; + + return true; +} + +bool Renderer9::isRemovedDeviceResettable() const +{ + bool success = false; + +#ifdef ANGLE_ENABLE_D3D9EX + IDirect3D9Ex *d3d9Ex = NULL; + 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); + } + + SafeRelease(d3d9Ex); +#else + ASSERT(UNREACHABLE()); +#endif + + return success; +} + +bool Renderer9::resetRemovedDevice() +{ + // From http://msdn.microsoft.com/en-us/library/windows/desktop/bb172554(v=vs.85).aspx: + // The hardware adapter has been removed. Application must destroy the device, do enumeration of + // adapters and create another Direct3D device. If application continues rendering without + // calling Reset, the rendering calls will succeed. Applies to Direct3D 9Ex only. + deinitialize(); + return (initialize() == EGL_SUCCESS); +} + +DWORD Renderer9::getAdapterVendor() const +{ + return mAdapterIdentifier.VendorId; +} + +std::string Renderer9::getRendererDescription() const +{ + std::ostringstream rendererString; + + rendererString << mAdapterIdentifier.Description; + if (getShareHandleSupport()) + { + rendererString << " Direct3D9Ex"; + } + else + { + 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); + + return rendererString.str(); +} + +GUID Renderer9::getAdapterIdentifier() const +{ + return mAdapterIdentifier.DeviceIdentifier; +} + +void Renderer9::getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray) +{ + for (int multiSampleIndex = 0; multiSampleIndex <= D3DMULTISAMPLE_16_SAMPLES; multiSampleIndex++) + { + HRESULT result = mD3d9->CheckDeviceMultiSampleType(mAdapter, mDeviceType, format, + TRUE, (D3DMULTISAMPLE_TYPE)multiSampleIndex, NULL); + + multiSampleArray[multiSampleIndex] = SUCCEEDED(result); + } +} + +bool Renderer9::getBGRATextureSupport() const +{ + // DirectX 9 always supports BGRA + return true; +} + +bool Renderer9::getDXT1TextureSupport() +{ + return mDXT1TextureSupport; +} + +bool Renderer9::getDXT3TextureSupport() +{ + return mDXT3TextureSupport; +} + +bool Renderer9::getDXT5TextureSupport() +{ + return mDXT5TextureSupport; +} + +bool Renderer9::getDepthTextureSupport() const +{ + return mDepthTextureSupport; +} + +bool Renderer9::getFloat32TextureSupport(bool *filtering, bool *renderable) +{ + *filtering = mFloat32FilterSupport; + *renderable = mFloat32RenderSupport; + return mFloat32TextureSupport; +} + +bool Renderer9::getFloat16TextureSupport(bool *filtering, bool *renderable) +{ + *filtering = mFloat16FilterSupport; + *renderable = mFloat16RenderSupport; + return mFloat16TextureSupport; +} + +bool Renderer9::getLuminanceTextureSupport() +{ + return mLuminanceTextureSupport; +} + +bool Renderer9::getLuminanceAlphaTextureSupport() +{ + return mLuminanceAlphaTextureSupport; +} + +bool Renderer9::getTextureFilterAnisotropySupport() const +{ + return mSupportsTextureFilterAnisotropy; +} + +float Renderer9::getTextureMaxAnisotropy() const +{ + if (mSupportsTextureFilterAnisotropy) + { + return static_cast(mDeviceCaps.MaxAnisotropy); + } + return 1.0f; +} + +bool Renderer9::getEventQuerySupport() +{ + return mEventQuerySupport; +} + +unsigned int Renderer9::getMaxVertexTextureImageUnits() const +{ + META_ASSERT(MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 <= gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS); + return mVertexTextureSupport ? MAX_TEXTURE_IMAGE_UNITS_VTF_SM3 : 0; +} + +unsigned int Renderer9::getMaxCombinedTextureImageUnits() const +{ + return gl::MAX_TEXTURE_IMAGE_UNITS + getMaxVertexTextureImageUnits(); +} + +unsigned int Renderer9::getReservedVertexUniformVectors() const +{ + return 2; // dx_ViewAdjust and dx_DepthRange. +} + +unsigned int Renderer9::getReservedFragmentUniformVectors() const +{ + return 3; // dx_ViewCoords, dx_DepthFront and dx_DepthRange. +} + +unsigned int Renderer9::getMaxVertexUniformVectors() const +{ + return MAX_VERTEX_CONSTANT_VECTORS_D3D9 - getReservedVertexUniformVectors(); +} + +unsigned int Renderer9::getMaxFragmentUniformVectors() const +{ + const int maxPixelConstantVectors = (getMajorShaderModel() >= 3) ? MAX_PIXEL_CONSTANT_VECTORS_SM3 : MAX_PIXEL_CONSTANT_VECTORS_SM2; + + return maxPixelConstantVectors - getReservedFragmentUniformVectors(); +} + +unsigned int Renderer9::getMaxVaryingVectors() const +{ + return (getMajorShaderModel() >= 3) ? MAX_VARYING_VECTORS_SM3 : MAX_VARYING_VECTORS_SM2; +} + +bool Renderer9::getNonPower2TextureSupport() const +{ + return mSupportsNonPower2Textures; +} + +bool Renderer9::getOcclusionQuerySupport() const +{ + return mOcclusionQuerySupport; +} + +bool Renderer9::getInstancingSupport() const +{ + return mDeviceCaps.PixelShaderVersion >= D3DPS_VERSION(3, 0); +} + +bool Renderer9::getShareHandleSupport() const +{ + // PIX doesn't seem to support using share handles, so disable them. + return (mD3d9Ex != NULL) && !gl::perfActive(); +} + +bool Renderer9::getDerivativeInstructionSupport() const +{ + return (mDeviceCaps.PS20Caps.Caps & D3DPS20CAPS_GRADIENTINSTRUCTIONS) != 0; +} + +bool Renderer9::getPostSubBufferSupport() const +{ + return true; +} + +int Renderer9::getMajorShaderModel() const +{ + return D3DSHADER_VERSION_MAJOR(mDeviceCaps.PixelShaderVersion); +} + +float Renderer9::getMaxPointSize() const +{ + // Point size clamped at 1.0f for SM2 + return getMajorShaderModel() == 3 ? mDeviceCaps.MaxPointSize : 1.0f; +} + +int Renderer9::getMaxViewportDimension() const +{ + int maxTextureDimension = std::min(std::min(getMaxTextureWidth(), getMaxTextureHeight()), + (int)gl::IMPLEMENTATION_MAX_TEXTURE_SIZE); + return maxTextureDimension; +} + +int Renderer9::getMaxTextureWidth() const +{ + return (int)mDeviceCaps.MaxTextureWidth; +} + +int Renderer9::getMaxTextureHeight() const +{ + return (int)mDeviceCaps.MaxTextureHeight; +} + +bool Renderer9::get32BitIndexSupport() const +{ + return mDeviceCaps.MaxVertexIndex >= (1 << 16); +} + +DWORD Renderer9::getCapsDeclTypes() const +{ + return mDeviceCaps.DeclTypes; +} + +int Renderer9::getMinSwapInterval() const +{ + return mMinSwapInterval; +} + +int Renderer9::getMaxSwapInterval() const +{ + return mMaxSwapInterval; +} + +int Renderer9::getMaxSupportedSamples() const +{ + return mMaxSupportedSamples; +} + +int Renderer9::getNearestSupportedSamples(D3DFORMAT format, int requested) const +{ + if (requested == 0) + { + return requested; + } + + std::map::const_iterator itr = mMultiSampleSupport.find(format); + if (itr == mMultiSampleSupport.end()) + { + if (format == D3DFMT_UNKNOWN) + return 0; + return -1; + } + + for (int i = requested; i <= D3DMULTISAMPLE_16_SAMPLES; ++i) + { + if (itr->second[i] && i != D3DMULTISAMPLE_NONMASKABLE) + { + return i; + } + } + + return -1; +} + +unsigned int Renderer9::getMaxRenderTargets() const +{ + // we do not support MRT in d3d9 + return 1; +} + +D3DFORMAT Renderer9::ConvertTextureInternalFormat(GLint internalformat) +{ + switch (internalformat) + { + case GL_DEPTH_COMPONENT16: + case GL_DEPTH_COMPONENT32_OES: + case GL_DEPTH24_STENCIL8_OES: + return D3DFMT_INTZ; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + return D3DFMT_DXT1; + case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: + return D3DFMT_DXT3; + case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: + return D3DFMT_DXT5; + case GL_RGBA32F_EXT: + case GL_RGB32F_EXT: + case GL_ALPHA32F_EXT: + case GL_LUMINANCE32F_EXT: + case GL_LUMINANCE_ALPHA32F_EXT: + return D3DFMT_A32B32G32R32F; + case GL_RGBA16F_EXT: + case GL_RGB16F_EXT: + case GL_ALPHA16F_EXT: + case GL_LUMINANCE16F_EXT: + case GL_LUMINANCE_ALPHA16F_EXT: + return D3DFMT_A16B16G16R16F; + case GL_LUMINANCE8_EXT: + if (getLuminanceTextureSupport()) + { + return D3DFMT_L8; + } + break; + case GL_LUMINANCE8_ALPHA8_EXT: + if (getLuminanceAlphaTextureSupport()) + { + return D3DFMT_A8L8; + } + break; + case GL_RGB8_OES: + case GL_RGB565: + return D3DFMT_X8R8G8B8; + } + + return D3DFMT_A8R8G8B8; +} + +bool Renderer9::copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source) +{ + bool result = false; + + if (source && dest) + { + TextureStorage9_2D *source9 = TextureStorage9_2D::makeTextureStorage9_2D(source->getStorageInstance()); + TextureStorage9_2D *dest9 = TextureStorage9_2D::makeTextureStorage9_2D(dest->getStorageInstance()); + + int levels = source9->levelCount(); + for (int i = 0; i < levels; ++i) + { + IDirect3DSurface9 *srcSurf = source9->getSurfaceLevel(i, false); + IDirect3DSurface9 *dstSurf = dest9->getSurfaceLevel(i, false); + + result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); + + if (srcSurf) srcSurf->Release(); + if (dstSurf) dstSurf->Release(); + + if (!result) + return false; + } + } + + return result; +} + +bool Renderer9::copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source) +{ + bool result = false; + + if (source && dest) + { + TextureStorage9_Cube *source9 = TextureStorage9_Cube::makeTextureStorage9_Cube(source->getStorageInstance()); + TextureStorage9_Cube *dest9 = TextureStorage9_Cube::makeTextureStorage9_Cube(dest->getStorageInstance()); + int levels = source9->levelCount(); + for (int f = 0; f < 6; f++) + { + for (int i = 0; i < levels; i++) + { + IDirect3DSurface9 *srcSurf = source9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, false); + IDirect3DSurface9 *dstSurf = dest9->getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + f, i, true); + + result = copyToRenderTarget(dstSurf, srcSurf, source9->isManaged()); + + if (srcSurf) srcSurf->Release(); + if (dstSurf) dstSurf->Release(); + + if (!result) + return false; + } + } + } + + return result; +} + +D3DPOOL Renderer9::getBufferPool(DWORD usage) const +{ + if (mD3d9Ex != NULL) + { + return D3DPOOL_DEFAULT; + } + else + { + if (!(usage & D3DUSAGE_DYNAMIC)) + { + return D3DPOOL_MANAGED; + } + } + + return D3DPOOL_DEFAULT; +} + +bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level) +{ + RECT rect; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; + rect.bottom = sourceRect.y + sourceRect.height; + + return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, level); +} + +bool Renderer9::copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level) +{ + RECT rect; + rect.left = sourceRect.x; + rect.top = sourceRect.y; + rect.right = sourceRect.x + sourceRect.width; + rect.bottom = sourceRect.y + sourceRect.height; + + return mBlit->copy(framebuffer, rect, destFormat, xoffset, yoffset, storage, target, level); +} + +bool Renderer9::blitRect(gl::Framebuffer *readFramebuffer, const gl::Rectangle &readRect, gl::Framebuffer *drawFramebuffer, const gl::Rectangle &drawRect, + bool blitRenderTarget, bool blitDepthStencil) +{ + endScene(); + + if (blitRenderTarget) + { + gl::Renderbuffer *readBuffer = readFramebuffer->getColorbuffer(0); + gl::Renderbuffer *drawBuffer = drawFramebuffer->getColorbuffer(0); + RenderTarget9 *readRenderTarget = NULL; + RenderTarget9 *drawRenderTarget = NULL; + IDirect3DSurface9* readSurface = NULL; + IDirect3DSurface9* drawSurface = NULL; + + if (readBuffer) + { + readRenderTarget = RenderTarget9::makeRenderTarget9(readBuffer->getRenderTarget()); + } + if (drawBuffer) + { + drawRenderTarget = RenderTarget9::makeRenderTarget9(drawBuffer->getRenderTarget()); + } + + if (readRenderTarget) + { + readSurface = readRenderTarget->getSurface(); + } + if (drawRenderTarget) + { + drawSurface = drawRenderTarget->getSurface(); + } + + if (!readSurface || !drawSurface) + { + ERR("Failed to retrieve the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + RECT srcRect; + srcRect.left = readRect.x; + srcRect.right = readRect.x + readRect.width; + srcRect.top = readRect.y; + srcRect.bottom = readRect.y + readRect.height; + + RECT dstRect; + dstRect.left = drawRect.x; + dstRect.right = drawRect.x + drawRect.width; + dstRect.top = drawRect.y; + dstRect.bottom = drawRect.y + drawRect.height; + + HRESULT result = mDevice->StretchRect(readSurface, &srcRect, drawSurface, &dstRect, D3DTEXF_NONE); + + readSurface->Release(); + drawSurface->Release(); + + if (FAILED(result)) + { + ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); + return false; + } + } + + if (blitDepthStencil) + { + gl::Renderbuffer *readBuffer = readFramebuffer->getDepthOrStencilbuffer(); + gl::Renderbuffer *drawBuffer = drawFramebuffer->getDepthOrStencilbuffer(); + RenderTarget9 *readDepthStencil = NULL; + RenderTarget9 *drawDepthStencil = NULL; + IDirect3DSurface9* readSurface = NULL; + IDirect3DSurface9* drawSurface = NULL; + + if (readBuffer) + { + readDepthStencil = RenderTarget9::makeRenderTarget9(readBuffer->getDepthStencil()); + } + if (drawBuffer) + { + drawDepthStencil = RenderTarget9::makeRenderTarget9(drawBuffer->getDepthStencil()); + } + + if (readDepthStencil) + { + readSurface = readDepthStencil->getSurface(); + } + if (drawDepthStencil) + { + drawSurface = drawDepthStencil->getSurface(); + } + + if (!readSurface || !drawSurface) + { + ERR("Failed to retrieve the render target."); + return gl::error(GL_OUT_OF_MEMORY, false); + } + + HRESULT result = mDevice->StretchRect(readSurface, NULL, drawSurface, NULL, D3DTEXF_NONE); + + readSurface->Release(); + drawSurface->Release(); + + if (FAILED(result)) + { + ERR("BlitFramebufferANGLE failed: StretchRect returned %x.", result); + return false; + } + } + + return true; +} + +void Renderer9::readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels) +{ + RenderTarget9 *renderTarget = NULL; + IDirect3DSurface9 *surface = NULL; + gl::Renderbuffer *colorbuffer = framebuffer->getColorbuffer(0); + + if (colorbuffer) + { + renderTarget = RenderTarget9::makeRenderTarget9(colorbuffer->getRenderTarget()); + } + + if (renderTarget) + { + surface = renderTarget->getSurface(); + } + + if (!surface) + { + // context must be lost + return; + } + + D3DSURFACE_DESC desc; + surface->GetDesc(&desc); + + if (desc.MultiSampleType != D3DMULTISAMPLE_NONE) + { + UNIMPLEMENTED(); // FIXME: Requires resolve using StretchRect into non-multisampled render target + surface->Release(); + return gl::error(GL_OUT_OF_MEMORY); + } + + HRESULT result; + IDirect3DSurface9 *systemSurface = NULL; + bool directToPixels = !packReverseRowOrder && packAlignment <= 4 && getShareHandleSupport() && + x == 0 && y == 0 && UINT(width) == desc.Width && UINT(height) == desc.Height && + desc.Format == D3DFMT_A8R8G8B8 && format == GL_BGRA_EXT && type == GL_UNSIGNED_BYTE; + if (directToPixels) + { + // Use the pixels ptr as a shared handle to write directly into client's memory + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &systemSurface, &pixels); + if (FAILED(result)) + { + // Try again without the shared handle + directToPixels = false; + } + } + + if (!directToPixels) + { + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, + D3DPOOL_SYSTEMMEM, &systemSurface, NULL); + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + surface->Release(); + return gl::error(GL_OUT_OF_MEMORY); + } + } + + result = mDevice->GetRenderTargetData(surface, systemSurface); + surface->Release(); + surface = NULL; + + if (FAILED(result)) + { + systemSurface->Release(); + + // It turns out that D3D will sometimes produce more error + // codes than those documented. + if (d3d9::isDeviceLostError(result)) + { + notifyDeviceLost(); + return gl::error(GL_OUT_OF_MEMORY); + } + else + { + UNREACHABLE(); + return; + } + + } + + if (directToPixels) + { + systemSurface->Release(); + return; + } + + RECT rect; + rect.left = gl::clamp(x, 0L, static_cast(desc.Width)); + rect.top = gl::clamp(y, 0L, static_cast(desc.Height)); + rect.right = gl::clamp(x + width, 0L, static_cast(desc.Width)); + rect.bottom = gl::clamp(y + height, 0L, static_cast(desc.Height)); + + D3DLOCKED_RECT lock; + result = systemSurface->LockRect(&lock, &rect, D3DLOCK_READONLY); + + if (FAILED(result)) + { + UNREACHABLE(); + systemSurface->Release(); + + return; // No sensible error to generate + } + + unsigned char *dest = (unsigned char*)pixels; + unsigned short *dest16 = (unsigned short*)pixels; + + unsigned char *source; + int inputPitch; + if (packReverseRowOrder) + { + source = ((unsigned char*)lock.pBits) + lock.Pitch * (rect.bottom - rect.top - 1); + inputPitch = -lock.Pitch; + } + else + { + source = (unsigned char*)lock.pBits; + inputPitch = lock.Pitch; + } + + unsigned int fastPixelSize = 0; + + if (desc.Format == D3DFMT_A8R8G8B8 && + format == GL_BGRA_EXT && + type == GL_UNSIGNED_BYTE) + { + fastPixelSize = 4; + } + else if ((desc.Format == D3DFMT_A4R4G4B4 && + format == GL_BGRA_EXT && + type == GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT) || + (desc.Format == D3DFMT_A1R5G5B5 && + format == GL_BGRA_EXT && + type == GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT)) + { + fastPixelSize = 2; + } + else if (desc.Format == D3DFMT_A16B16G16R16F && + format == GL_RGBA && + type == GL_HALF_FLOAT_OES) + { + fastPixelSize = 8; + } + else if (desc.Format == D3DFMT_A32B32G32R32F && + format == GL_RGBA && + type == GL_FLOAT) + { + fastPixelSize = 16; + } + + for (int j = 0; j < rect.bottom - rect.top; j++) + { + if (fastPixelSize != 0) + { + // Fast path for formats which require no translation: + // D3DFMT_A8R8G8B8 to BGRA/UNSIGNED_BYTE + // D3DFMT_A4R4G4B4 to BGRA/UNSIGNED_SHORT_4_4_4_4_REV_EXT + // D3DFMT_A1R5G5B5 to BGRA/UNSIGNED_SHORT_1_5_5_5_REV_EXT + // D3DFMT_A16B16G16R16F to RGBA/HALF_FLOAT_OES + // D3DFMT_A32B32G32R32F to RGBA/FLOAT + // + // Note that buffers with no alpha go through the slow path below. + memcpy(dest + j * outputPitch, + source + j * inputPitch, + (rect.right - rect.left) * fastPixelSize); + continue; + } + else if (desc.Format == D3DFMT_A8R8G8B8 && + format == GL_RGBA && + type == GL_UNSIGNED_BYTE) + { + // Fast path for swapping red with blue + for (int i = 0; i < rect.right - rect.left; i++) + { + unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); + *(unsigned int*)(dest + 4 * i + j * outputPitch) = + (argb & 0xFF00FF00) | // Keep alpha and green + (argb & 0x00FF0000) >> 16 | // Move red to blue + (argb & 0x000000FF) << 16; // Move blue to red + } + continue; + } + + for (int i = 0; i < rect.right - rect.left; i++) + { + float r; + float g; + float b; + float a; + + switch (desc.Format) + { + case D3DFMT_R5G6B5: + { + unsigned short rgb = *(unsigned short*)(source + 2 * i + j * inputPitch); + + a = 1.0f; + b = (rgb & 0x001F) * (1.0f / 0x001F); + g = (rgb & 0x07E0) * (1.0f / 0x07E0); + r = (rgb & 0xF800) * (1.0f / 0xF800); + } + break; + case D3DFMT_A1R5G5B5: + { + unsigned short argb = *(unsigned short*)(source + 2 * i + j * inputPitch); + + a = (argb & 0x8000) ? 1.0f : 0.0f; + b = (argb & 0x001F) * (1.0f / 0x001F); + g = (argb & 0x03E0) * (1.0f / 0x03E0); + r = (argb & 0x7C00) * (1.0f / 0x7C00); + } + break; + case D3DFMT_A8R8G8B8: + { + unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); + + a = (argb & 0xFF000000) * (1.0f / 0xFF000000); + b = (argb & 0x000000FF) * (1.0f / 0x000000FF); + g = (argb & 0x0000FF00) * (1.0f / 0x0000FF00); + r = (argb & 0x00FF0000) * (1.0f / 0x00FF0000); + } + break; + case D3DFMT_X8R8G8B8: + { + unsigned int xrgb = *(unsigned int*)(source + 4 * i + j * inputPitch); + + a = 1.0f; + b = (xrgb & 0x000000FF) * (1.0f / 0x000000FF); + g = (xrgb & 0x0000FF00) * (1.0f / 0x0000FF00); + r = (xrgb & 0x00FF0000) * (1.0f / 0x00FF0000); + } + break; + case D3DFMT_A2R10G10B10: + { + unsigned int argb = *(unsigned int*)(source + 4 * i + j * inputPitch); + + a = (argb & 0xC0000000) * (1.0f / 0xC0000000); + b = (argb & 0x000003FF) * (1.0f / 0x000003FF); + g = (argb & 0x000FFC00) * (1.0f / 0x000FFC00); + r = (argb & 0x3FF00000) * (1.0f / 0x3FF00000); + } + break; + case D3DFMT_A32B32G32R32F: + { + // float formats in D3D are stored rgba, rather than the other way round + r = *((float*)(source + 16 * i + j * inputPitch) + 0); + g = *((float*)(source + 16 * i + j * inputPitch) + 1); + b = *((float*)(source + 16 * i + j * inputPitch) + 2); + a = *((float*)(source + 16 * i + j * inputPitch) + 3); + } + break; + case D3DFMT_A16B16G16R16F: + { + // float formats in D3D are stored rgba, rather than the other way round + r = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 0)); + g = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 1)); + b = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 2)); + a = gl::float16ToFloat32(*((unsigned short*)(source + 8 * i + j * inputPitch) + 3)); + } + break; + default: + UNIMPLEMENTED(); // FIXME + UNREACHABLE(); + return; + } + + switch (format) + { + case GL_RGBA: + switch (type) + { + case GL_UNSIGNED_BYTE: + dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); + dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); + dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); + dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); + break; + default: UNREACHABLE(); + } + break; + case GL_BGRA_EXT: + switch (type) + { + case GL_UNSIGNED_BYTE: + dest[4 * i + j * outputPitch + 0] = (unsigned char)(255 * b + 0.5f); + dest[4 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); + dest[4 * i + j * outputPitch + 2] = (unsigned char)(255 * r + 0.5f); + dest[4 * i + j * outputPitch + 3] = (unsigned char)(255 * a + 0.5f); + break; + case GL_UNSIGNED_SHORT_4_4_4_4_REV_EXT: + // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section + // this type is packed as follows: + // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // -------------------------------------------------------------------------------- + // | 4th | 3rd | 2nd | 1st component | + // -------------------------------------------------------------------------------- + // in the case of BGRA_EXT, B is the first component, G the second, and so forth. + dest16[i + j * outputPitch / sizeof(unsigned short)] = + ((unsigned short)(15 * a + 0.5f) << 12)| + ((unsigned short)(15 * r + 0.5f) << 8) | + ((unsigned short)(15 * g + 0.5f) << 4) | + ((unsigned short)(15 * b + 0.5f) << 0); + break; + case GL_UNSIGNED_SHORT_1_5_5_5_REV_EXT: + // According to the desktop GL spec in the "Transfer of Pixel Rectangles" section + // this type is packed as follows: + // 15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 + // -------------------------------------------------------------------------------- + // | 4th | 3rd | 2nd | 1st component | + // -------------------------------------------------------------------------------- + // in the case of BGRA_EXT, B is the first component, G the second, and so forth. + dest16[i + j * outputPitch / sizeof(unsigned short)] = + ((unsigned short)( a + 0.5f) << 15) | + ((unsigned short)(31 * r + 0.5f) << 10) | + ((unsigned short)(31 * g + 0.5f) << 5) | + ((unsigned short)(31 * b + 0.5f) << 0); + break; + default: UNREACHABLE(); + } + break; + case GL_RGB: + switch (type) + { + case GL_UNSIGNED_SHORT_5_6_5: + dest16[i + j * outputPitch / sizeof(unsigned short)] = + ((unsigned short)(31 * b + 0.5f) << 0) | + ((unsigned short)(63 * g + 0.5f) << 5) | + ((unsigned short)(31 * r + 0.5f) << 11); + break; + case GL_UNSIGNED_BYTE: + dest[3 * i + j * outputPitch + 0] = (unsigned char)(255 * r + 0.5f); + dest[3 * i + j * outputPitch + 1] = (unsigned char)(255 * g + 0.5f); + dest[3 * i + j * outputPitch + 2] = (unsigned char)(255 * b + 0.5f); + break; + default: UNREACHABLE(); + } + break; + default: UNREACHABLE(); + } + } + } + + systemSurface->UnlockRect(); + + systemSurface->Release(); +} + +RenderTarget *Renderer9::createRenderTarget(SwapChain *swapChain, bool depth) +{ + SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); + IDirect3DSurface9 *surface = NULL; + if (depth) + { + surface = swapChain9->getDepthStencil(); + } + else + { + surface = swapChain9->getRenderTarget(); + } + + RenderTarget9 *renderTarget = new RenderTarget9(this, surface); + + return renderTarget; +} + +RenderTarget *Renderer9::createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth) +{ + RenderTarget9 *renderTarget = new RenderTarget9(this, width, height, format, samples); + return renderTarget; +} + +ShaderExecutable *Renderer9::loadExecutable(const void *function, size_t length, rx::ShaderType type) +{ + ShaderExecutable9 *executable = NULL; + + switch (type) + { + case rx::SHADER_VERTEX: + { + IDirect3DVertexShader9 *vshader = createVertexShader((DWORD*)function, length); + if (vshader) + { + executable = new ShaderExecutable9(function, length, vshader); + } + } + break; + case rx::SHADER_PIXEL: + { + IDirect3DPixelShader9 *pshader = createPixelShader((DWORD*)function, length); + if (pshader) + { + executable = new ShaderExecutable9(function, length, pshader); + } + } + break; + default: + UNREACHABLE(); + break; + } + + return executable; +} + +ShaderExecutable *Renderer9::compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround) +{ + const char *profile = NULL; + + switch (type) + { + case rx::SHADER_VERTEX: + profile = getMajorShaderModel() >= 3 ? "vs_3_0" : "vs_2_0"; + break; + case rx::SHADER_PIXEL: + profile = getMajorShaderModel() >= 3 ? "ps_3_0" : "ps_2_0"; + break; + default: + UNREACHABLE(); + return NULL; + } + + // ANGLE issue 486: + // Work-around a D3D9 compiler bug that presents itself when using conditional discard, by disabling optimization + UINT optimizationFlags = (workaround == ANGLE_D3D_WORKAROUND_SM3_OPTIMIZER ? D3DCOMPILE_SKIP_OPTIMIZATION : ANGLE_COMPILE_OPTIMIZATION_LEVEL); + + ID3DBlob *binary = (ID3DBlob*)compileToBinary(infoLog, shaderHLSL, profile, optimizationFlags, true); + if (!binary) + return NULL; + + ShaderExecutable *executable = loadExecutable(binary->GetBufferPointer(), binary->GetBufferSize(), type); + binary->Release(); + + return executable; +} + +bool Renderer9::boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest) +{ + return mBlit->boxFilter(source, dest); +} + +D3DPOOL Renderer9::getTexturePool(DWORD usage) const +{ + if (mD3d9Ex != NULL) + { + return D3DPOOL_DEFAULT; + } + else + { + if (!(usage & (D3DUSAGE_DEPTHSTENCIL | D3DUSAGE_RENDERTARGET))) + { + return D3DPOOL_MANAGED; + } + } + + return D3DPOOL_DEFAULT; +} + +bool Renderer9::copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged) +{ + if (source && dest) + { + HRESULT result = D3DERR_OUTOFVIDEOMEMORY; + + if (fromManaged) + { + D3DSURFACE_DESC desc; + source->GetDesc(&desc); + + IDirect3DSurface9 *surf = 0; + result = mDevice->CreateOffscreenPlainSurface(desc.Width, desc.Height, desc.Format, D3DPOOL_SYSTEMMEM, &surf, NULL); + + if (SUCCEEDED(result)) + { + Image9::copyLockableSurfaces(surf, source); + result = mDevice->UpdateSurface(surf, NULL, dest, NULL); + surf->Release(); + } + } + else + { + endScene(); + result = mDevice->StretchRect(source, NULL, dest, NULL, D3DTEXF_NONE); + } + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + return false; + } + } + + return true; +} + +Image *Renderer9::createImage() +{ + return new Image9(); +} + +void Renderer9::generateMipmap(Image *dest, Image *src) +{ + Image9 *src9 = Image9::makeImage9(src); + Image9 *dst9 = Image9::makeImage9(dest); + Image9::generateMipmap(dst9, src9); +} + +TextureStorage *Renderer9::createTextureStorage2D(SwapChain *swapChain) +{ + SwapChain9 *swapChain9 = SwapChain9::makeSwapChain9(swapChain); + return new TextureStorage9_2D(this, swapChain9); +} + +TextureStorage *Renderer9::createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) +{ + return new TextureStorage9_2D(this, levels, internalformat, usage, forceRenderable, width, height); +} + +TextureStorage *Renderer9::createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) +{ + return new TextureStorage9_Cube(this, levels, internalformat, usage, forceRenderable, size); +} + +bool Renderer9::getLUID(LUID *adapterLuid) const +{ + adapterLuid->HighPart = 0; + adapterLuid->LowPart = 0; + + if (mD3d9Ex) + { + mD3d9Ex->GetAdapterLUID(mAdapter, adapterLuid); + return true; + } + + return false; +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.h new file mode 100644 index 0000000000..24fd2bdd84 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/Renderer9.h @@ -0,0 +1,356 @@ +// +// Copyright (c) 2012-2013 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. +// + +// Renderer9.h: Defines a back-end specific class for the D3D9 renderer. + +#ifndef LIBGLESV2_RENDERER_RENDERER9_H_ +#define LIBGLESV2_RENDERER_RENDERER9_H_ + +#include "common/angleutils.h" +#include "libGLESv2/mathutil.h" +#include "libGLESv2/renderer/ShaderCache.h" +#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h" +#include "libGLESv2/renderer/Renderer.h" +#include "libGLESv2/renderer/RenderTarget.h" + +namespace gl +{ +class Renderbuffer; +} + +namespace rx +{ +class VertexDataManager; +class IndexDataManager; +class StreamingIndexBufferInterface; +struct TranslatedAttribute; + +class Renderer9 : public Renderer +{ + public: + Renderer9(egl::Display *display, HDC hDc, bool softwareDevice); + virtual ~Renderer9(); + + static Renderer9 *makeRenderer9(Renderer *renderer); + + virtual EGLint initialize(); + virtual bool resetDevice(); + + virtual int generateConfigs(ConfigDesc **configDescList); + virtual void deleteConfigs(ConfigDesc *configDescList); + + void startScene(); + void endScene(); + + virtual void sync(bool block); + + virtual SwapChain *createSwapChain(HWND window, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat); + + IDirect3DQuery9* allocateEventQuery(); + void freeEventQuery(IDirect3DQuery9* query); + + // resource creation + IDirect3DVertexShader9 *createVertexShader(const DWORD *function, size_t length); + IDirect3DPixelShader9 *createPixelShader(const DWORD *function, size_t length); + HRESULT createVertexBuffer(UINT Length, DWORD Usage, IDirect3DVertexBuffer9 **ppVertexBuffer); + HRESULT createIndexBuffer(UINT Length, DWORD Usage, D3DFORMAT Format, IDirect3DIndexBuffer9 **ppIndexBuffer); +#if 0 + void *createTexture2D(); + void *createTextureCube(); + void *createQuery(); + void *createIndexBuffer(); + void *createVertexbuffer(); + + // state setup + void applyShaders(); + void applyConstants(); +#endif + virtual void setSamplerState(gl::SamplerType type, int index, const gl::SamplerState &sampler); + virtual void setTexture(gl::SamplerType type, int index, gl::Texture *texture); + + virtual void setRasterizerState(const gl::RasterizerState &rasterState); + virtual void setBlendState(gl::Framebuffer *framebuffer, const gl::BlendState &blendState, const gl::Color &blendColor, + unsigned int sampleMask); + virtual void setDepthStencilState(const gl::DepthStencilState &depthStencilState, int stencilRef, + int stencilBackRef, bool frontFaceCCW); + + virtual void setScissorRectangle(const gl::Rectangle &scissor, bool enabled); + virtual bool setViewport(const gl::Rectangle &viewport, float zNear, float zFar, GLenum drawMode, GLenum frontFace, + bool ignoreViewport); + + virtual bool applyRenderTarget(gl::Framebuffer *frameBuffer); + virtual void applyShaders(gl::ProgramBinary *programBinary); + virtual void applyUniforms(gl::ProgramBinary *programBinary, gl::UniformArray *uniformArray); + virtual bool applyPrimitiveType(GLenum primitiveType, GLsizei elementCount); + virtual GLenum applyVertexBuffer(gl::ProgramBinary *programBinary, gl::VertexAttribute vertexAttributes[], GLint first, GLsizei count, GLsizei instances); + virtual GLenum applyIndexBuffer(const GLvoid *indices, gl::Buffer *elementArrayBuffer, GLsizei count, GLenum mode, GLenum type, TranslatedIndexData *indexInfo); + + virtual void drawArrays(GLenum mode, GLsizei count, GLsizei instances); + virtual void drawElements(GLenum mode, GLsizei count, GLenum type, const GLvoid *indices, gl::Buffer *elementArrayBuffer, const TranslatedIndexData &indexInfo, GLsizei instances); + + virtual void clear(const gl::ClearParameters &clearParams, gl::Framebuffer *frameBuffer); + + virtual void markAllStateDirty(); + + // lost device + void notifyDeviceLost(); + virtual bool isDeviceLost(); + virtual bool testDeviceLost(bool notify); + virtual bool testDeviceResettable(); + + // Renderer capabilities + IDirect3DDevice9 *getDevice() { return mDevice; } + virtual DWORD getAdapterVendor() const; + virtual std::string getRendererDescription() const; + virtual GUID getAdapterIdentifier() const; + + virtual bool getBGRATextureSupport() const; + virtual bool getDXT1TextureSupport(); + virtual bool getDXT3TextureSupport(); + virtual bool getDXT5TextureSupport(); + virtual bool getEventQuerySupport(); + virtual bool getFloat32TextureSupport(bool *filtering, bool *renderable); + virtual bool getFloat16TextureSupport(bool *filtering, bool *renderable); + virtual bool getLuminanceTextureSupport(); + virtual bool getLuminanceAlphaTextureSupport(); + virtual unsigned int getMaxVertexTextureImageUnits() const; + virtual unsigned int getMaxCombinedTextureImageUnits() const; + virtual unsigned int getReservedVertexUniformVectors() const; + virtual unsigned int getReservedFragmentUniformVectors() const; + virtual unsigned int getMaxVertexUniformVectors() const; + virtual unsigned int getMaxFragmentUniformVectors() const; + virtual unsigned int getMaxVaryingVectors() const; + virtual bool getNonPower2TextureSupport() const; + virtual bool getDepthTextureSupport() const; + virtual bool getOcclusionQuerySupport() const; + virtual bool getInstancingSupport() const; + virtual bool getTextureFilterAnisotropySupport() const; + virtual float getTextureMaxAnisotropy() const; + virtual bool getShareHandleSupport() const; + virtual bool getDerivativeInstructionSupport() const; + virtual bool getPostSubBufferSupport() const; + + virtual int getMajorShaderModel() const; + virtual float getMaxPointSize() const; + virtual int getMaxViewportDimension() const; + virtual int getMaxTextureWidth() const; + virtual int getMaxTextureHeight() const; + virtual bool get32BitIndexSupport() const; + DWORD getCapsDeclTypes() const; + virtual int getMinSwapInterval() const; + virtual int getMaxSwapInterval() const; + + virtual GLsizei getMaxSupportedSamples() const; + int getNearestSupportedSamples(D3DFORMAT format, int requested) const; + + virtual unsigned int getMaxRenderTargets() const; + + D3DFORMAT ConvertTextureInternalFormat(GLint internalformat); + + // Pixel operations + virtual bool copyToRenderTarget(TextureStorageInterface2D *dest, TextureStorageInterface2D *source); + virtual bool copyToRenderTarget(TextureStorageInterfaceCube *dest, TextureStorageInterfaceCube *source); + + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterface2D *storage, GLint level); + virtual bool copyImage(gl::Framebuffer *framebuffer, const gl::Rectangle &sourceRect, GLenum destFormat, + GLint xoffset, GLint yoffset, TextureStorageInterfaceCube *storage, GLenum target, GLint level); + + virtual bool blitRect(gl::Framebuffer *readTarget, const gl::Rectangle &readRect, gl::Framebuffer *drawTarget, const gl::Rectangle &drawRect, + bool blitRenderTarget, bool blitDepthStencil); + virtual void readPixels(gl::Framebuffer *framebuffer, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, + GLsizei outputPitch, bool packReverseRowOrder, GLint packAlignment, void* pixels); + + // RenderTarget creation + virtual RenderTarget *createRenderTarget(SwapChain *swapChain, bool depth); + virtual RenderTarget *createRenderTarget(int width, int height, GLenum format, GLsizei samples, bool depth); + + // Shader operations + virtual ShaderExecutable *loadExecutable(const void *function, size_t length, rx::ShaderType type); + virtual ShaderExecutable *compileToExecutable(gl::InfoLog &infoLog, const char *shaderHLSL, rx::ShaderType type, D3DWorkaroundType workaround); + + // Image operations + virtual Image *createImage(); + virtual void generateMipmap(Image *dest, Image *source); + virtual TextureStorage *createTextureStorage2D(SwapChain *swapChain); + virtual TextureStorage *createTextureStorage2D(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); + virtual TextureStorage *createTextureStorageCube(int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + + // Buffer creation + virtual VertexBuffer *createVertexBuffer(); + virtual IndexBuffer *createIndexBuffer(); + virtual BufferStorage *createBufferStorage(); + + // Query and Fence creation + virtual QueryImpl *createQuery(GLenum type); + virtual FenceImpl *createFence(); + + // D3D9-renderer specific methods + bool boxFilter(IDirect3DSurface9 *source, IDirect3DSurface9 *dest); + + D3DPOOL getTexturePool(DWORD usage) const; + + virtual bool getLUID(LUID *adapterLuid) const; + + private: + DISALLOW_COPY_AND_ASSIGN(Renderer9); + + void deinitialize(); + + void applyUniformnfv(gl::Uniform *targetUniform, const GLfloat *v); + void applyUniformniv(gl::Uniform *targetUniform, const GLint *v); + void applyUniformnbv(gl::Uniform *targetUniform, const GLint *v); + + void drawLineLoop(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + void drawIndexedPoints(GLsizei count, GLenum type, const GLvoid *indices, int minIndex, gl::Buffer *elementArrayBuffer); + + void getMultiSampleSupport(D3DFORMAT format, bool *multiSampleArray); + bool copyToRenderTarget(IDirect3DSurface9 *dest, IDirect3DSurface9 *source, bool fromManaged); + gl::Renderbuffer *getNullColorbuffer(gl::Renderbuffer *depthbuffer); + + D3DPOOL getBufferPool(DWORD usage) const; + + HMODULE mD3d9Module; + HDC mDc; + + void initializeDevice(); + D3DPRESENT_PARAMETERS getDefaultPresentParameters(); + void releaseDeviceResources(); + + HRESULT getDeviceStatusCode(); + bool isRemovedDeviceResettable() const; + bool resetRemovedDevice(); + + UINT mAdapter; + D3DDEVTYPE mDeviceType; + bool mSoftwareDevice; // FIXME: Deprecate + 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. + + Blit *mBlit; + + HWND mDeviceWindow; + + bool mDeviceLost; + D3DCAPS9 mDeviceCaps; + D3DADAPTER_IDENTIFIER9 mAdapterIdentifier; + + D3DPRIMITIVETYPE mPrimitiveType; + int mPrimitiveCount; + GLsizei mRepeatDraw; + + bool mSceneStarted; + bool mSupportsNonPower2Textures; + bool mSupportsTextureFilterAnisotropy; + int mMinSwapInterval; + int mMaxSwapInterval; + + bool mOcclusionQuerySupport; + bool mEventQuerySupport; + bool mVertexTextureSupport; + + bool mDepthTextureSupport; + + bool mFloat32TextureSupport; + bool mFloat32FilterSupport; + bool mFloat32RenderSupport; + + bool mFloat16TextureSupport; + bool mFloat16FilterSupport; + bool mFloat16RenderSupport; + + bool mDXT1TextureSupport; + bool mDXT3TextureSupport; + bool mDXT5TextureSupport; + + bool mLuminanceTextureSupport; + bool mLuminanceAlphaTextureSupport; + + std::map mMultiSampleSupport; + GLsizei mMaxSupportedSamples; + + // current render target states + unsigned int mAppliedRenderTargetSerial; + unsigned int mAppliedDepthbufferSerial; + unsigned int mAppliedStencilbufferSerial; + bool mDepthStencilInitialized; + bool mRenderTargetDescInitialized; + rx::RenderTarget::Desc mRenderTargetDesc; + unsigned int mCurStencilSize; + unsigned int mCurDepthSize; + + IDirect3DStateBlock9 *mMaskedClearSavedState; + + // previously set render states + bool mForceSetDepthStencilState; + gl::DepthStencilState mCurDepthStencilState; + int mCurStencilRef; + int mCurStencilBackRef; + bool mCurFrontFaceCCW; + + bool mForceSetRasterState; + gl::RasterizerState mCurRasterState; + + bool mForceSetScissor; + gl::Rectangle mCurScissor; + bool mScissorEnabled; + + bool mForceSetViewport; + gl::Rectangle mCurViewport; + float mCurNear; + float mCurFar; + float mCurDepthFront; + + bool mForceSetBlendState; + gl::BlendState mCurBlendState; + gl::Color mCurBlendColor; + GLuint mCurSampleMask; + + // Currently applied sampler states + bool mForceSetVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + gl::SamplerState mCurVertexSamplerStates[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + + bool mForceSetPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + gl::SamplerState mCurPixelSamplerStates[gl::MAX_TEXTURE_IMAGE_UNITS]; + + // Currently applied textures + unsigned int mCurVertexTextureSerials[gl::IMPLEMENTATION_MAX_VERTEX_TEXTURE_IMAGE_UNITS]; + unsigned int mCurPixelTextureSerials[gl::MAX_TEXTURE_IMAGE_UNITS]; + + unsigned int mAppliedIBSerial; + unsigned int mAppliedProgramBinarySerial; + + rx::dx_VertexConstants mVertexConstants; + rx::dx_PixelConstants mPixelConstants; + bool mDxUniformsDirty; + + // A pool of event queries that are currently unused. + std::vector mEventQueryPool; + VertexShaderCache mVertexShaderCache; + PixelShaderCache mPixelShaderCache; + + VertexDataManager *mVertexDataManager; + VertexDeclarationCache mVertexDeclarationCache; + + IndexDataManager *mIndexDataManager; + StreamingIndexBufferInterface *mLineLoopIB; + + enum { NUM_NULL_COLORBUFFER_CACHE_ENTRIES = 12 }; + struct NullColorbufferCacheEntry + { + UINT lruCount; + int width; + int height; + gl::Renderbuffer *buffer; + } mNullColorbufferCache[NUM_NULL_COLORBUFFER_CACHE_ENTRIES]; + UINT mMaxNullColorbufferLRU; + +}; + +} +#endif // LIBGLESV2_RENDERER_RENDERER9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp new file mode 100644 index 0000000000..5decf9664d --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.cpp @@ -0,0 +1,60 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// ShaderExecutable9.cpp: Implements a D3D9-specific class to contain shader +// executable implementation details. + +#include "libGLESv2/renderer/d3d9/ShaderExecutable9.h" + +#include "common/debug.h" + +namespace rx +{ + +ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable) + : ShaderExecutable(function, length) +{ + mPixelExecutable = executable; + mVertexExecutable = NULL; +} + +ShaderExecutable9::ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable) + : ShaderExecutable(function, length) +{ + mVertexExecutable = executable; + mPixelExecutable = NULL; +} + +ShaderExecutable9::~ShaderExecutable9() +{ + if (mVertexExecutable) + { + mVertexExecutable->Release(); + } + if (mPixelExecutable) + { + mPixelExecutable->Release(); + } +} + +ShaderExecutable9 *ShaderExecutable9::makeShaderExecutable9(ShaderExecutable *executable) +{ + ASSERT(HAS_DYNAMIC_TYPE(ShaderExecutable9*, executable)); + return static_cast(executable); +} + +IDirect3DVertexShader9 *ShaderExecutable9::getVertexShader() const +{ + return mVertexExecutable; +} + +IDirect3DPixelShader9 *ShaderExecutable9::getPixelShader() const +{ + return mPixelExecutable; +} + +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h new file mode 100644 index 0000000000..fa1e6c2844 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/ShaderExecutable9.h @@ -0,0 +1,39 @@ +// +// Copyright (c) 2012-2013 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. +// + +// ShaderExecutable9.h: Defines a D3D9-specific class to contain shader +// executable implementation details. + +#ifndef LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ +#define LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ + +#include "libGLESv2/renderer/ShaderExecutable.h" + +namespace rx +{ + +class ShaderExecutable9 : public ShaderExecutable +{ + public: + ShaderExecutable9(const void *function, size_t length, IDirect3DPixelShader9 *executable); + ShaderExecutable9(const void *function, size_t length, IDirect3DVertexShader9 *executable); + virtual ~ShaderExecutable9(); + + static ShaderExecutable9 *makeShaderExecutable9(ShaderExecutable *executable); + + IDirect3DPixelShader9 *getPixelShader() const; + IDirect3DVertexShader9 *getVertexShader() const; + + private: + DISALLOW_COPY_AND_ASSIGN(ShaderExecutable9); + + IDirect3DPixelShader9 *mPixelExecutable; + IDirect3DVertexShader9 *mVertexExecutable; +}; + +} + +#endif // LIBGLESV2_RENDERER_SHADEREXECUTABLE9_H_ \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.cpp new file mode 100644 index 0000000000..dd8895d18d --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.cpp @@ -0,0 +1,445 @@ +#include "precompiled.h" +// +// Copyright (c) 2012-2013 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. +// + +// SwapChain9.cpp: Implements a back-end specific class for the D3D9 swap chain. + +#include "libGLESv2/renderer/d3d9/SwapChain9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +namespace rx +{ + +SwapChain9::SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, + GLenum backBufferFormat, GLenum depthBufferFormat) + : mRenderer(renderer), SwapChain(window, shareHandle, backBufferFormat, depthBufferFormat) +{ + mSwapChain = NULL; + mBackBuffer = NULL; + mDepthStencil = NULL; + mRenderTarget = NULL; + mOffscreenTexture = NULL; + mWidth = -1; + mHeight = -1; + mSwapInterval = -1; +} + +SwapChain9::~SwapChain9() +{ + release(); +} + +void SwapChain9::release() +{ + if (mSwapChain) + { + mSwapChain->Release(); + mSwapChain = NULL; + } + + if (mBackBuffer) + { + mBackBuffer->Release(); + mBackBuffer = NULL; + } + + if (mDepthStencil) + { + mDepthStencil->Release(); + mDepthStencil = NULL; + } + + if (mRenderTarget) + { + mRenderTarget->Release(); + mRenderTarget = NULL; + } + + if (mOffscreenTexture) + { + mOffscreenTexture->Release(); + mOffscreenTexture = NULL; + } + + if (mWindow) + mShareHandle = NULL; +} + +static DWORD convertInterval(EGLint interval) +{ +#if ANGLE_FORCE_VSYNC_OFF + return D3DPRESENT_INTERVAL_IMMEDIATE; +#else + switch(interval) + { + case 0: return D3DPRESENT_INTERVAL_IMMEDIATE; + case 1: return D3DPRESENT_INTERVAL_ONE; + case 2: return D3DPRESENT_INTERVAL_TWO; + case 3: return D3DPRESENT_INTERVAL_THREE; + case 4: return D3DPRESENT_INTERVAL_FOUR; + default: UNREACHABLE(); + } + + return D3DPRESENT_INTERVAL_DEFAULT; +#endif +} + +EGLint SwapChain9::resize(int backbufferWidth, int backbufferHeight) +{ + // D3D9 does not support resizing swap chains without recreating them + return reset(backbufferWidth, backbufferHeight, mSwapInterval); +} + +EGLint SwapChain9::reset(int backbufferWidth, int backbufferHeight, EGLint swapInterval) +{ + IDirect3DDevice9 *device = mRenderer->getDevice(); + + if (device == NULL) + { + return EGL_BAD_ACCESS; + } + + // Evict all non-render target textures to system memory and release all resources + // before reallocating them to free up as much video memory as possible. + device->EvictManagedResources(); + + HRESULT result; + + // Release specific resources to free up memory for the new render target, while the + // old render target still exists for the purpose of preserving its contents. + if (mSwapChain) + { + mSwapChain->Release(); + mSwapChain = NULL; + } + + if (mBackBuffer) + { + mBackBuffer->Release(); + mBackBuffer = NULL; + } + + if (mOffscreenTexture) + { + mOffscreenTexture->Release(); + mOffscreenTexture = NULL; + } + + if (mDepthStencil) + { + mDepthStencil->Release(); + mDepthStencil = NULL; + } + + HANDLE *pShareHandle = NULL; + if (!mWindow && mRenderer->getShareHandleSupport()) + { + pShareHandle = &mShareHandle; + } + + result = device->CreateTexture(backbufferWidth, backbufferHeight, 1, D3DUSAGE_RENDERTARGET, + gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat), D3DPOOL_DEFAULT, + &mOffscreenTexture, pShareHandle); + if (FAILED(result)) + { + ERR("Could not create offscreen texture: %08lX", result); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + IDirect3DSurface9 *oldRenderTarget = mRenderTarget; + + result = mOffscreenTexture->GetSurfaceLevel(0, &mRenderTarget); + ASSERT(SUCCEEDED(result)); + + if (oldRenderTarget) + { + RECT rect = + { + 0, 0, + mWidth, mHeight + }; + + if (rect.right > static_cast(backbufferWidth)) + { + rect.right = backbufferWidth; + } + + if (rect.bottom > static_cast(backbufferHeight)) + { + rect.bottom = backbufferHeight; + } + + mRenderer->endScene(); + + result = device->StretchRect(oldRenderTarget, &rect, mRenderTarget, &rect, D3DTEXF_NONE); + ASSERT(SUCCEEDED(result)); + + oldRenderTarget->Release(); + } + + if (mWindow) + { + D3DPRESENT_PARAMETERS presentParameters = {0}; + presentParameters.AutoDepthStencilFormat = gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat); + presentParameters.BackBufferCount = 1; + presentParameters.BackBufferFormat = gl_d3d9::ConvertRenderbufferFormat(mBackBufferFormat); + presentParameters.EnableAutoDepthStencil = FALSE; + presentParameters.Flags = 0; + presentParameters.hDeviceWindow = mWindow; + presentParameters.MultiSampleQuality = 0; // FIXME: Unimplemented + presentParameters.MultiSampleType = D3DMULTISAMPLE_NONE; // FIXME: Unimplemented + presentParameters.PresentationInterval = convertInterval(swapInterval); + presentParameters.SwapEffect = D3DSWAPEFFECT_DISCARD; + presentParameters.Windowed = TRUE; + presentParameters.BackBufferWidth = backbufferWidth; + presentParameters.BackBufferHeight = backbufferHeight; + + // http://crbug.com/140239 + // http://crbug.com/143434 + // + // Some AMD/Intel switchable systems / drivers appear to round swap chain surfaces to a multiple of 64 pixels in width + // when using the integrated Intel. This rounds the width up rather than down. + // + // 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->getAdapterVendor() == VENDOR_ID_INTEL) + { + presentParameters.BackBufferWidth = (presentParameters.BackBufferWidth + 63) / 64 * 64; + } + + result = device->CreateAdditionalSwapChain(&presentParameters, &mSwapChain); + + if (FAILED(result)) + { + 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); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + + result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); + ASSERT(SUCCEEDED(result)); + InvalidateRect(mWindow, NULL, FALSE); + } + + if (mDepthBufferFormat != GL_NONE) + { + result = device->CreateDepthStencilSurface(backbufferWidth, backbufferHeight, + gl_d3d9::ConvertRenderbufferFormat(mDepthBufferFormat), + D3DMULTISAMPLE_NONE, 0, FALSE, &mDepthStencil, NULL); + + 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); + release(); + + if (d3d9::isDeviceLostError(result)) + { + return EGL_CONTEXT_LOST; + } + else + { + return EGL_BAD_ALLOC; + } + } + } + + mWidth = backbufferWidth; + mHeight = backbufferHeight; + mSwapInterval = swapInterval; + + return EGL_SUCCESS; +} + +// parameters should be validated/clamped by caller +EGLint SwapChain9::swapRect(EGLint x, EGLint y, EGLint width, EGLint height) +{ + if (!mSwapChain) + { + return EGL_SUCCESS; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + + // Disable all pipeline operations + device->SetRenderState(D3DRS_ZENABLE, D3DZB_FALSE); + device->SetRenderState(D3DRS_FILLMODE, D3DFILL_SOLID); + device->SetRenderState(D3DRS_ALPHATESTENABLE, FALSE); + device->SetRenderState(D3DRS_ALPHABLENDENABLE, FALSE); + device->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE); + device->SetRenderState(D3DRS_STENCILENABLE, FALSE); + device->SetRenderState(D3DRS_CLIPPLANEENABLE, 0); + 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->SetRenderTarget(0, mBackBuffer); + device->SetDepthStencilSurface(NULL); + + device->SetTexture(0, mOffscreenTexture); + device->SetTextureStageState(0, D3DTSS_COLOROP, D3DTOP_SELECTARG1); + device->SetTextureStageState(0, D3DTSS_COLORARG1, D3DTA_TEXTURE); + device->SetTextureStageState(1, D3DTSS_COLOROP, D3DTOP_DISABLE); + device->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT); + device->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + device->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + device->SetFVF(D3DFVF_XYZRHW | D3DFVF_TEX1); + + for (UINT streamIndex = 0; streamIndex < gl::MAX_VERTEX_ATTRIBS; streamIndex++) + { + device->SetStreamSourceFreq(streamIndex, 1); + } + + D3DVIEWPORT9 viewport = {0, 0, mWidth, mHeight, 0.0f, 1.0f}; + device->SetViewport(&viewport); + + float x1 = x - 0.5f; + float y1 = (mHeight - y - height) - 0.5f; + float x2 = (x + width) - 0.5f; + float y2 = (mHeight - y) - 0.5f; + + float u1 = x / float(mWidth); + float v1 = y / float(mHeight); + float u2 = (x + width) / float(mWidth); + float v2 = (y + height) / float(mHeight); + + float quad[4][6] = {{x1, y1, 0.0f, 1.0f, u1, v2}, + {x2, y1, 0.0f, 1.0f, u2, v2}, + {x2, y2, 0.0f, 1.0f, u2, v1}, + {x1, y2, 0.0f, 1.0f, u1, v1}}; // x, y, z, rhw, u, v + + mRenderer->startScene(); + device->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, quad, 6 * sizeof(float)); + mRenderer->endScene(); + + device->SetTexture(0, NULL); + + RECT rect = + { + x, mHeight - y - height, + x + width, mHeight - y + }; + + HRESULT result = mSwapChain->Present(&rect, &rect, NULL, NULL, 0); + + mRenderer->markAllStateDirty(); + + if (result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY || result == D3DERR_DRIVERINTERNALERROR) + { + return EGL_BAD_ALLOC; + } + + // http://crbug.com/313210 + // If our swap failed, trigger a device lost event. Resetting will work around an AMD-specific + // device removed bug with lost contexts when reinstalling drivers. + if (FAILED(result)) + { + mRenderer->notifyDeviceLost(); + return EGL_CONTEXT_LOST; + } + + return EGL_SUCCESS; +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *SwapChain9::getRenderTarget() +{ + if (mRenderTarget) + { + mRenderTarget->AddRef(); + } + + return mRenderTarget; +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *SwapChain9::getDepthStencil() +{ + if (mDepthStencil) + { + mDepthStencil->AddRef(); + } + + return mDepthStencil; +} + +// Increments refcount on texture. +// caller must Release() the returned texture +IDirect3DTexture9 *SwapChain9::getOffscreenTexture() +{ + if (mOffscreenTexture) + { + mOffscreenTexture->AddRef(); + } + + return mOffscreenTexture; +} + +SwapChain9 *SwapChain9::makeSwapChain9(SwapChain *swapChain) +{ + ASSERT(HAS_DYNAMIC_TYPE(rx::SwapChain9*, swapChain)); + return static_cast(swapChain); +} + +void SwapChain9::recreate() +{ + if (!mSwapChain) + { + return; + } + + IDirect3DDevice9 *device = mRenderer->getDevice(); + if (device == NULL) + { + return; + } + + D3DPRESENT_PARAMETERS presentParameters; + HRESULT result = mSwapChain->GetPresentParameters(&presentParameters); + ASSERT(SUCCEEDED(result)); + + IDirect3DSwapChain9* newSwapChain = NULL; + result = device->CreateAdditionalSwapChain(&presentParameters, &newSwapChain); + if (FAILED(result)) + { + return; + } + + mSwapChain->Release(); + mSwapChain = newSwapChain; + + mBackBuffer->Release(); + result = mSwapChain->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &mBackBuffer); + ASSERT(SUCCEEDED(result)); +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.h new file mode 100644 index 0000000000..16a62bd86f --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/SwapChain9.h @@ -0,0 +1,55 @@ +// +// Copyright (c) 2012 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. +// + +// SwapChain9.h: Defines a back-end specific class for the D3D9 swap chain. + +#ifndef LIBGLESV2_RENDERER_SWAPCHAIN9_H_ +#define LIBGLESV2_RENDERER_SWAPCHAIN9_H_ + +#include "common/angleutils.h" +#include "libGLESv2/renderer/SwapChain.h" + +namespace rx +{ +class Renderer9; + +class SwapChain9 : public SwapChain +{ + public: + SwapChain9(Renderer9 *renderer, HWND window, HANDLE shareHandle, + GLenum backBufferFormat, GLenum depthBufferFormat); + virtual ~SwapChain9(); + + 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(); + + virtual IDirect3DSurface9 *getRenderTarget(); + virtual IDirect3DSurface9 *getDepthStencil(); + virtual IDirect3DTexture9 *getOffscreenTexture(); + + static SwapChain9 *makeSwapChain9(SwapChain *swapChain); + + private: + DISALLOW_COPY_AND_ASSIGN(SwapChain9); + + void release(); + + Renderer9 *mRenderer; + EGLint mHeight; + EGLint mWidth; + EGLint mSwapInterval; + + IDirect3DSwapChain9 *mSwapChain; + IDirect3DSurface9 *mBackBuffer; + IDirect3DSurface9 *mRenderTarget; + IDirect3DSurface9 *mDepthStencil; + IDirect3DTexture9* mOffscreenTexture; +}; + +} +#endif // LIBGLESV2_RENDERER_SWAPCHAIN9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp new file mode 100644 index 0000000000..2486a9a5bf --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.cpp @@ -0,0 +1,328 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// TextureStorage9.cpp: Implements the abstract rx::TextureStorage9 class and its concrete derived +// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the +// D3D9 texture. + +#include "libGLESv2/main.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" +#include "libGLESv2/renderer/d3d9/TextureStorage9.h" +#include "libGLESv2/renderer/d3d9/SwapChain9.h" +#include "libGLESv2/renderer/d3d9/RenderTarget9.h" +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/Texture.h" + +namespace rx +{ +TextureStorage9::TextureStorage9(Renderer *renderer, DWORD usage) + : mLodOffset(0), + mRenderer(Renderer9::makeRenderer9(renderer)), + mD3DUsage(usage), + mD3DPool(mRenderer->getTexturePool(usage)) +{ +} + +TextureStorage9::~TextureStorage9() +{ +} + +TextureStorage9 *TextureStorage9::makeTextureStorage9(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9*, storage)); + return static_cast(storage); +} + +DWORD TextureStorage9::GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable) +{ + DWORD d3dusage = 0; + + if (d3dfmt == D3DFMT_INTZ) + { + d3dusage |= D3DUSAGE_DEPTHSTENCIL; + } + else if(forceRenderable || (TextureStorage9::IsTextureFormatRenderable(d3dfmt) && (glusage == GL_FRAMEBUFFER_ATTACHMENT_ANGLE))) + { + d3dusage |= D3DUSAGE_RENDERTARGET; + } + return d3dusage; +} + +bool TextureStorage9::IsTextureFormatRenderable(D3DFORMAT format) +{ + if (format == D3DFMT_INTZ) + { + return true; + } + switch(format) + { + case D3DFMT_L8: + case D3DFMT_A8L8: + case D3DFMT_DXT1: + case D3DFMT_DXT3: + case D3DFMT_DXT5: + return false; + case D3DFMT_A8R8G8B8: + case D3DFMT_X8R8G8B8: + case D3DFMT_A16B16G16R16F: + case D3DFMT_A32B32G32R32F: + return true; + default: + UNREACHABLE(); + } + + return false; +} + +bool TextureStorage9::isRenderTarget() const +{ + return (mD3DUsage & (D3DUSAGE_RENDERTARGET | D3DUSAGE_DEPTHSTENCIL)) != 0; +} + +bool TextureStorage9::isManaged() const +{ + return (mD3DPool == D3DPOOL_MANAGED); +} + +D3DPOOL TextureStorage9::getPool() const +{ + return mD3DPool; +} + +DWORD TextureStorage9::getUsage() const +{ + return mD3DUsage; +} + +int TextureStorage9::getLodOffset() const +{ + return mLodOffset; +} + +int TextureStorage9::levelCount() +{ + return getBaseTexture() ? getBaseTexture()->GetLevelCount() - getLodOffset() : 0; +} + +TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain) : TextureStorage9(renderer, D3DUSAGE_RENDERTARGET) +{ + IDirect3DTexture9 *surfaceTexture = swapchain->getOffscreenTexture(); + mTexture = surfaceTexture; + mRenderTarget = NULL; + + initializeRenderTarget(); +} + +TextureStorage9_2D::TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height) + : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) +{ + mTexture = NULL; + mRenderTarget = NULL; + // 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 (width > 0 && height > 0) + { + IDirect3DDevice9 *device = mRenderer->getDevice(); + gl::MakeValidSize(false, gl::IsCompressed(internalformat), &width, &height, &mLodOffset); + HRESULT result = device->CreateTexture(width, height, levels ? levels + mLodOffset : 0, getUsage(), + mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + gl::error(GL_OUT_OF_MEMORY); + } + } + + initializeRenderTarget(); +} + +TextureStorage9_2D::~TextureStorage9_2D() +{ + if (mTexture) + { + mTexture->Release(); + } + + delete mRenderTarget; +} + +TextureStorage9_2D *TextureStorage9_2D::makeTextureStorage9_2D(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_2D*, storage)); + return static_cast(storage); +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *TextureStorage9_2D::getSurfaceLevel(int level, bool dirty) +{ + IDirect3DSurface9 *surface = NULL; + + if (mTexture) + { + HRESULT result = mTexture->GetSurfaceLevel(level + mLodOffset, &surface); + ASSERT(SUCCEEDED(result)); + + // With managed textures the driver needs to be informed of updates to the lower mipmap levels + if (level + mLodOffset != 0 && isManaged() && dirty) + { + mTexture->AddDirtyRect(NULL); + } + } + + return surface; +} + +RenderTarget *TextureStorage9_2D::getRenderTarget() +{ + return mRenderTarget; +} + +void TextureStorage9_2D::generateMipmap(int level) +{ + IDirect3DSurface9 *upper = getSurfaceLevel(level - 1, false); + IDirect3DSurface9 *lower = getSurfaceLevel(level, true); + + if (upper != NULL && lower != NULL) + { + mRenderer->boxFilter(upper, lower); + } + + if (upper != NULL) upper->Release(); + if (lower != NULL) lower->Release(); +} + +IDirect3DBaseTexture9 *TextureStorage9_2D::getBaseTexture() const +{ + return mTexture; +} + +void TextureStorage9_2D::initializeRenderTarget() +{ + ASSERT(mRenderTarget == NULL); + + if (mTexture != NULL && isRenderTarget()) + { + IDirect3DSurface9 *surface = getSurfaceLevel(0, false); + + mRenderTarget = new RenderTarget9(mRenderer, surface); + } +} + +TextureStorage9_Cube::TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size) + : TextureStorage9(renderer, GetTextureUsage(Renderer9::makeRenderer9(renderer)->ConvertTextureInternalFormat(internalformat), usage, forceRenderable)) +{ + mTexture = NULL; + for (int i = 0; i < 6; ++i) + { + mRenderTarget[i] = NULL; + } + + // 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 (size > 0) + { + IDirect3DDevice9 *device = mRenderer->getDevice(); + int height = size; + gl::MakeValidSize(false, gl::IsCompressed(internalformat), &size, &height, &mLodOffset); + HRESULT result = device->CreateCubeTexture(size, levels ? levels + mLodOffset : 0, getUsage(), + mRenderer->ConvertTextureInternalFormat(internalformat), getPool(), &mTexture, NULL); + + if (FAILED(result)) + { + ASSERT(result == D3DERR_OUTOFVIDEOMEMORY || result == E_OUTOFMEMORY); + gl::error(GL_OUT_OF_MEMORY); + } + } + + initializeRenderTarget(); +} + +TextureStorage9_Cube::~TextureStorage9_Cube() +{ + if (mTexture) + { + mTexture->Release(); + } + + for (int i = 0; i < 6; ++i) + { + delete mRenderTarget[i]; + } +} + +TextureStorage9_Cube *TextureStorage9_Cube::makeTextureStorage9_Cube(TextureStorage *storage) +{ + ASSERT(HAS_DYNAMIC_TYPE(TextureStorage9_Cube*, storage)); + return static_cast(storage); +} + +// Increments refcount on surface. +// caller must Release() the returned surface +IDirect3DSurface9 *TextureStorage9_Cube::getCubeMapSurface(GLenum faceTarget, int level, bool dirty) +{ + IDirect3DSurface9 *surface = NULL; + + if (mTexture) + { + D3DCUBEMAP_FACES face = gl_d3d9::ConvertCubeFace(faceTarget); + HRESULT result = mTexture->GetCubeMapSurface(face, level + mLodOffset, &surface); + ASSERT(SUCCEEDED(result)); + + // With managed textures the driver needs to be informed of updates to the lower mipmap levels + if (level != 0 && isManaged() && dirty) + { + mTexture->AddDirtyRect(face, NULL); + } + } + + return surface; +} + +RenderTarget *TextureStorage9_Cube::getRenderTarget(GLenum faceTarget) +{ + return mRenderTarget[gl::TextureCubeMap::faceIndex(faceTarget)]; +} + +void TextureStorage9_Cube::generateMipmap(int face, int level) +{ + IDirect3DSurface9 *upper = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level - 1, false); + IDirect3DSurface9 *lower = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, level, true); + + if (upper != NULL && lower != NULL) + { + mRenderer->boxFilter(upper, lower); + } + + if (upper != NULL) upper->Release(); + if (lower != NULL) lower->Release(); +} + +IDirect3DBaseTexture9 *TextureStorage9_Cube::getBaseTexture() const +{ + return mTexture; +} + +void TextureStorage9_Cube::initializeRenderTarget() +{ + if (mTexture != NULL && isRenderTarget()) + { + IDirect3DSurface9 *surface = NULL; + + for (int i = 0; i < 6; ++i) + { + ASSERT(mRenderTarget[i] == NULL); + + surface = getCubeMapSurface(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, false); + + mRenderTarget[i] = new RenderTarget9(mRenderer, surface); + } + } +} + +} \ No newline at end of file diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.h new file mode 100644 index 0000000000..86f551a131 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/TextureStorage9.h @@ -0,0 +1,109 @@ +// +// Copyright (c) 2012 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. +// + +// TextureStorage9.h: Defines the abstract rx::TextureStorage9 class and its concrete derived +// classes TextureStorage9_2D and TextureStorage9_Cube, which act as the interface to the +// D3D9 texture. + +#ifndef LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_ +#define LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_ + +#include "libGLESv2/renderer/TextureStorage.h" +#include "common/debug.h" + +namespace rx +{ +class Renderer9; +class SwapChain9; +class RenderTarget; +class RenderTarget9; +class Blit; + +class TextureStorage9 : public TextureStorage +{ + public: + TextureStorage9(Renderer *renderer, DWORD usage); + virtual ~TextureStorage9(); + + static TextureStorage9 *makeTextureStorage9(TextureStorage *storage); + + static DWORD GetTextureUsage(D3DFORMAT d3dfmt, GLenum glusage, bool forceRenderable); + static bool IsTextureFormatRenderable(D3DFORMAT format); + + D3DPOOL getPool() const; + DWORD getUsage() const; + + virtual IDirect3DBaseTexture9 *getBaseTexture() const = 0; + virtual RenderTarget *getRenderTarget() { return NULL; } + virtual RenderTarget *getRenderTarget(GLenum faceTarget) { return NULL; } + virtual void generateMipmap(int level) {}; + virtual void generateMipmap(int face, int level) {}; + + virtual int getLodOffset() const; + virtual bool isRenderTarget() const; + virtual bool isManaged() const; + virtual int levelCount(); + + protected: + int mLodOffset; + Renderer9 *mRenderer; + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage9); + + const DWORD mD3DUsage; + const D3DPOOL mD3DPool; +}; + +class TextureStorage9_2D : public TextureStorage9 +{ + public: + TextureStorage9_2D(Renderer *renderer, SwapChain9 *swapchain); + TextureStorage9_2D(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, GLsizei width, GLsizei height); + virtual ~TextureStorage9_2D(); + + static TextureStorage9_2D *makeTextureStorage9_2D(TextureStorage *storage); + + IDirect3DSurface9 *getSurfaceLevel(int level, bool dirty); + virtual RenderTarget *getRenderTarget(); + virtual IDirect3DBaseTexture9 *getBaseTexture() const; + virtual void generateMipmap(int level); + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage9_2D); + + void initializeRenderTarget(); + + IDirect3DTexture9 *mTexture; + RenderTarget9 *mRenderTarget; +}; + +class TextureStorage9_Cube : public TextureStorage9 +{ + public: + TextureStorage9_Cube(Renderer *renderer, int levels, GLenum internalformat, GLenum usage, bool forceRenderable, int size); + virtual ~TextureStorage9_Cube(); + + static TextureStorage9_Cube *makeTextureStorage9_Cube(TextureStorage *storage); + + IDirect3DSurface9 *getCubeMapSurface(GLenum faceTarget, int level, bool dirty); + virtual RenderTarget *getRenderTarget(GLenum faceTarget); + virtual IDirect3DBaseTexture9 *getBaseTexture() const; + virtual void generateMipmap(int face, int level); + + private: + DISALLOW_COPY_AND_ASSIGN(TextureStorage9_Cube); + + void initializeRenderTarget(); + + IDirect3DCubeTexture9 *mTexture; + RenderTarget9 *mRenderTarget[6]; +}; + +} + +#endif // LIBGLESV2_RENDERER_TEXTURESTORAGE9_H_ + diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp new file mode 100644 index 0000000000..57f5bcd256 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.cpp @@ -0,0 +1,530 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2012 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. +// + +// VertexBuffer9.cpp: Defines the D3D9 VertexBuffer implementation. + +#include "libGLESv2/renderer/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d9/vertexconversion.h" +#include "libGLESv2/renderer/BufferStorage.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/renderer/d3d9/Renderer9.h" + +#include "libGLESv2/Buffer.h" + +namespace rx +{ + +bool VertexBuffer9::mTranslationsInitialized = false; +VertexBuffer9::FormatConverter VertexBuffer9::mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + +VertexBuffer9::VertexBuffer9(rx::Renderer9 *const renderer) : mRenderer(renderer) +{ + mVertexBuffer = NULL; + mBufferSize = 0; + mDynamicUsage = false; + + if (!mTranslationsInitialized) + { + initializeTranslations(renderer->getCapsDeclTypes()); + mTranslationsInitialized = true; + } +} + +VertexBuffer9::~VertexBuffer9() +{ + if (mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } +} + +bool VertexBuffer9::initialize(unsigned int size, bool dynamicUsage) +{ + if (mVertexBuffer) + { + mVertexBuffer->Release(); + mVertexBuffer = NULL; + } + + updateSerial(); + + if (size > 0) + { + DWORD flags = D3DUSAGE_WRITEONLY; + if (dynamicUsage) + { + flags |= D3DUSAGE_DYNAMIC; + } + + HRESULT result = mRenderer->createVertexBuffer(size, flags, &mVertexBuffer); + + if (FAILED(result)) + { + ERR("Out of memory allocating a vertex buffer of size %lu.", size); + return false; + } + } + + mBufferSize = size; + mDynamicUsage = dynamicUsage; + return true; +} + +VertexBuffer9 *VertexBuffer9::makeVertexBuffer9(VertexBuffer *vertexBuffer) +{ + ASSERT(HAS_DYNAMIC_TYPE(VertexBuffer9*, vertexBuffer)); + return static_cast(vertexBuffer); +} + +bool VertexBuffer9::storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, + GLsizei instances, unsigned int offset) +{ + if (mVertexBuffer) + { + gl::Buffer *buffer = attrib.mBoundBuffer.get(); + + int inputStride = attrib.stride(); + int elementSize = attrib.typeSize(); + const FormatConverter &converter = formatConverter(attrib); + + DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; + + void *mapPtr = NULL; + + unsigned int mapSize; + if (!spaceRequired(attrib, count, instances, &mapSize)) + { + return false; + } + + HRESULT result = mVertexBuffer->Lock(offset, mapSize, &mapPtr, lockFlags); + + if (FAILED(result)) + { + ERR("Lock failed with error 0x%08x", result); + return false; + } + + const char *input = NULL; + if (buffer) + { + BufferStorage *storage = buffer->getStorage(); + input = static_cast(storage->getData()) + static_cast(attrib.mOffset); + } + else + { + input = static_cast(attrib.mPointer); + } + + if (instances == 0 || attrib.mDivisor == 0) + { + input += inputStride * start; + } + + if (converter.identity && inputStride == elementSize) + { + memcpy(mapPtr, input, count * inputStride); + } + else + { + converter.convertArray(input, inputStride, count, mapPtr); + } + + mVertexBuffer->Unlock(); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +bool VertexBuffer9::storeRawData(const void* data, unsigned int size, unsigned int offset) +{ + if (mVertexBuffer) + { + DWORD lockFlags = mDynamicUsage ? D3DLOCK_NOOVERWRITE : 0; + + void *mapPtr = NULL; + HRESULT result = mVertexBuffer->Lock(offset, size, &mapPtr, lockFlags); + + if (FAILED(result)) + { + ERR("Lock failed with error 0x%08x", result); + return false; + } + + memcpy(mapPtr, data, size); + + mVertexBuffer->Unlock(); + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +bool VertexBuffer9::getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, + unsigned int *outSpaceRequired) const +{ + return spaceRequired(attrib, count, instances, outSpaceRequired); +} + +bool VertexBuffer9::requiresConversion(const gl::VertexAttribute &attrib) const +{ + return !formatConverter(attrib).identity; +} + +unsigned int VertexBuffer9::getVertexSize(const gl::VertexAttribute &attrib) const +{ + unsigned int spaceRequired; + return getSpaceRequired(attrib, 1, 0, &spaceRequired) ? spaceRequired : 0; +} + +D3DDECLTYPE VertexBuffer9::getDeclType(const gl::VertexAttribute &attrib) const +{ + return formatConverter(attrib).d3dDeclType; +} + +unsigned int VertexBuffer9::getBufferSize() const +{ + return mBufferSize; +} + +bool VertexBuffer9::setBufferSize(unsigned int size) +{ + if (size > mBufferSize) + { + return initialize(size, mDynamicUsage); + } + else + { + return true; + } +} + +bool VertexBuffer9::discard() +{ + if (mVertexBuffer) + { + void *dummy; + HRESULT result; + + result = mVertexBuffer->Lock(0, 1, &dummy, D3DLOCK_DISCARD); + if (FAILED(result)) + { + ERR("Discard lock failed with error 0x%08x", result); + return false; + } + + result = mVertexBuffer->Unlock(); + if (FAILED(result)) + { + ERR("Discard unlock failed with error 0x%08x", result); + return false; + } + + return true; + } + else + { + ERR("Vertex buffer not initialized."); + return false; + } +} + +IDirect3DVertexBuffer9 * VertexBuffer9::getBuffer() const +{ + return mVertexBuffer; +} + +// Mapping from OpenGL-ES vertex attrib type to D3D decl type: +// +// BYTE SHORT (Cast) +// BYTE-norm FLOAT (Normalize) (can't be exactly represented as SHORT-norm) +// UNSIGNED_BYTE UBYTE4 (Identity) or SHORT (Cast) +// UNSIGNED_BYTE-norm UBYTE4N (Identity) or FLOAT (Normalize) +// SHORT SHORT (Identity) +// SHORT-norm SHORT-norm (Identity) or FLOAT (Normalize) +// UNSIGNED_SHORT FLOAT (Cast) +// UNSIGNED_SHORT-norm USHORT-norm (Identity) or FLOAT (Normalize) +// FIXED (not in WebGL) FLOAT (FixedToFloat) +// FLOAT FLOAT (Identity) + +// GLToCType maps from GL type (as GLenum) to the C typedef. +template struct GLToCType { }; + +template <> struct GLToCType { typedef GLbyte type; }; +template <> struct GLToCType { typedef GLubyte type; }; +template <> struct GLToCType { typedef GLshort type; }; +template <> struct GLToCType { typedef GLushort type; }; +template <> struct GLToCType { typedef GLuint type; }; +template <> struct GLToCType { typedef GLfloat type; }; + +// This differs from D3DDECLTYPE in that it is unsized. (Size expansion is applied last.) +enum D3DVertexType +{ + D3DVT_FLOAT, + D3DVT_SHORT, + D3DVT_SHORT_NORM, + D3DVT_UBYTE, + D3DVT_UBYTE_NORM, + D3DVT_USHORT_NORM +}; + +// D3DToCType maps from D3D vertex type (as enum D3DVertexType) to the corresponding C type. +template struct D3DToCType { }; + +template <> struct D3DToCType { typedef float type; }; +template <> struct D3DToCType { typedef short type; }; +template <> struct D3DToCType { typedef short type; }; +template <> struct D3DToCType { typedef unsigned char type; }; +template <> struct D3DToCType { typedef unsigned char type; }; +template <> struct D3DToCType { typedef unsigned short type; }; + +// Encode the type/size combinations that D3D permits. For each type/size it expands to a widener that will provide the appropriate final size. +template struct WidenRule { }; + +template struct WidenRule : NoWiden { }; +template struct WidenRule : WidenToEven { }; +template struct WidenRule : WidenToEven { }; +template struct WidenRule : WidenToFour { }; +template struct WidenRule : WidenToFour { }; +template struct WidenRule : WidenToEven { }; + +// VertexTypeFlags encodes the D3DCAPS9::DeclType flag and vertex declaration flag for each D3D vertex type & size combination. +template struct VertexTypeFlags { }; + +template +struct VertexTypeFlagsHelper +{ + enum { capflag = _capflag }; + enum { declflag = _declflag }; +}; + +template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT1> { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT2> { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT3> { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_FLOAT4> { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT2> { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper<0, D3DDECLTYPE_SHORT4> { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; +template <> struct VertexTypeFlags : VertexTypeFlagsHelper { }; + + +// VertexTypeMapping maps GL type & normalized flag to preferred and fallback D3D vertex types (as D3DVertexType enums). +template struct VertexTypeMapping { }; + +template +struct VertexTypeMappingBase +{ + enum { preferred = Preferred }; + enum { fallback = Fallback }; +}; + +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Normalize +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity, Cast +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity, Normalize +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast, Normalize +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast +template <> struct VertexTypeMapping : VertexTypeMappingBase { }; // Cast, Normalize +template struct VertexTypeMapping : VertexTypeMappingBase { }; // FixedToFloat +template struct VertexTypeMapping : VertexTypeMappingBase { }; // Identity + + +// Given a GL type & norm flag and a D3D type, ConversionRule provides the type conversion rule (Cast, Normalize, Identity, FixedToFloat). +// The conversion rules themselves are defined in vertexconversion.h. + +// Almost all cases are covered by Cast (including those that are actually Identity since Cast knows it's an identity mapping). +template +struct ConversionRule : Cast::type, typename D3DToCType::type> { }; + +// All conversions from normalized types to float use the Normalize operator. +template struct ConversionRule : Normalize::type> { }; + +// Use a full specialization for this so that it preferentially matches ahead of the generic normalize-to-float rules. +template <> struct ConversionRule : FixedToFloat { }; +template <> struct ConversionRule : FixedToFloat { }; + +// A 2-stage construction is used for DefaultVertexValues because float must use SimpleDefaultValues (i.e. 0/1) +// whether it is normalized or not. +template struct DefaultVertexValuesStage2 { }; + +template struct DefaultVertexValuesStage2 : NormalizedDefaultValues { }; +template struct DefaultVertexValuesStage2 : SimpleDefaultValues { }; + +// Work out the default value rule for a D3D type (expressed as the C type) and +template struct DefaultVertexValues : DefaultVertexValuesStage2 { }; +template struct DefaultVertexValues : SimpleDefaultValues { }; + +// Policy rules for use with Converter, to choose whether to use the preferred or fallback conversion. +// The fallback conversion produces an output that all D3D9 devices must support. +template struct UsePreferred { enum { type = T::preferred }; }; +template struct UseFallback { enum { type = T::fallback }; }; + +// Converter ties it all together. Given an OpenGL type/norm/size and choice of preferred/fallback conversion, +// it provides all the members of the appropriate VertexDataConverter, the D3DCAPS9::DeclTypes flag in cap flag +// and the D3DDECLTYPE member needed for the vertex declaration in declflag. +template class PreferenceRule> +struct Converter + : VertexDataConverter::type, + WidenRule >::type, size>, + ConversionRule >::type>, + DefaultVertexValues >::type>::type, normalized > > +{ +private: + enum { d3dtype = PreferenceRule< VertexTypeMapping >::type }; + enum { d3dsize = WidenRule::finalWidth }; + +public: + enum { capflag = VertexTypeFlags::capflag }; + enum { declflag = VertexTypeFlags::declflag }; +}; + +// Initialize a TranslationInfo +#define TRANSLATION(type, norm, size, preferred) \ + { \ + Converter::identity, \ + Converter::finalSize, \ + Converter::convertArray, \ + static_cast(Converter::declflag) \ + } + +#define TRANSLATION_FOR_TYPE_NORM_SIZE(type, norm, size) \ + { \ + Converter::capflag, \ + TRANSLATION(type, norm, size, UsePreferred), \ + TRANSLATION(type, norm, size, UseFallback) \ + } + +#define TRANSLATIONS_FOR_TYPE(type) \ + { \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, true, 4) }, \ + } + +#define TRANSLATIONS_FOR_TYPE_NO_NORM(type) \ + { \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + { TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 1), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 2), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 3), TRANSLATION_FOR_TYPE_NORM_SIZE(type, false, 4) }, \ + } + +const VertexBuffer9::TranslationDescription VertexBuffer9::mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4] = // [GL types as enumerated by typeIndex()][normalized][size-1] +{ + TRANSLATIONS_FOR_TYPE(GL_BYTE), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_BYTE), + TRANSLATIONS_FOR_TYPE(GL_SHORT), + TRANSLATIONS_FOR_TYPE(GL_UNSIGNED_SHORT), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FIXED), + TRANSLATIONS_FOR_TYPE_NO_NORM(GL_FLOAT) +}; + +void VertexBuffer9::initializeTranslations(DWORD declTypes) +{ + for (unsigned int i = 0; i < NUM_GL_VERTEX_ATTRIB_TYPES; i++) + { + for (unsigned int j = 0; j < 2; j++) + { + for (unsigned int k = 0; k < 4; k++) + { + if (mPossibleTranslations[i][j][k].capsFlag == 0 || (declTypes & mPossibleTranslations[i][j][k].capsFlag) != 0) + { + mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].preferredConversion; + } + else + { + mFormatConverters[i][j][k] = mPossibleTranslations[i][j][k].fallbackConversion; + } + } + } + } +} + +unsigned int VertexBuffer9::typeIndex(GLenum type) +{ + switch (type) + { + case GL_BYTE: return 0; + case GL_UNSIGNED_BYTE: return 1; + case GL_SHORT: return 2; + case GL_UNSIGNED_SHORT: return 3; + case GL_FIXED: return 4; + case GL_FLOAT: return 5; + + default: UNREACHABLE(); return 5; + } +} + +const VertexBuffer9::FormatConverter &VertexBuffer9::formatConverter(const gl::VertexAttribute &attribute) +{ + return mFormatConverters[typeIndex(attribute.mType)][attribute.mNormalized][attribute.mSize - 1]; +} + +bool VertexBuffer9::spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired) +{ + unsigned int elementSize = formatConverter(attrib).outputElementSize; + + if (attrib.mArrayEnabled) + { + unsigned int elementCount = 0; + if (instances == 0 || attrib.mDivisor == 0) + { + elementCount = count; + } + else + { + if (static_cast(instances) < std::numeric_limits::max() - (attrib.mDivisor - 1)) + { + // Round up + elementCount = (static_cast(instances) + (attrib.mDivisor - 1)) / attrib.mDivisor; + } + else + { + elementCount = static_cast(instances) / attrib.mDivisor; + } + } + + if (elementSize <= std::numeric_limits::max() / elementCount) + { + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * elementCount; + } + return true; + } + else + { + return false; + } + } + else + { + const unsigned int elementSize = 4; + if (outSpaceRequired) + { + *outSpaceRequired = elementSize * 4; + } + return true; + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h new file mode 100644 index 0000000000..2f88117bda --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexBuffer9.h @@ -0,0 +1,91 @@ +// +// Copyright (c) 2002-2012 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. +// + +// VertexBuffer9.h: Defines the D3D9 VertexBuffer implementation. + +#ifndef LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ +#define LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ + +#include "libGLESv2/renderer/VertexBuffer.h" + +namespace rx +{ +class Renderer9; + +class VertexBuffer9 : public VertexBuffer +{ + public: + explicit VertexBuffer9(rx::Renderer9 *const renderer); + virtual ~VertexBuffer9(); + + virtual bool initialize(unsigned int size, bool dynamicUsage); + + static VertexBuffer9 *makeVertexBuffer9(VertexBuffer *vertexBuffer); + + virtual bool storeVertexAttributes(const gl::VertexAttribute &attrib, GLint start, GLsizei count, GLsizei instances, + unsigned int offset); + virtual bool storeRawData(const void* data, unsigned int size, unsigned int offset); + + virtual bool getSpaceRequired(const gl::VertexAttribute &attrib, GLsizei count, GLsizei instances, unsigned int *outSpaceRequired) const; + + virtual bool requiresConversion(const gl::VertexAttribute &attrib) const; + + unsigned int getVertexSize(const gl::VertexAttribute &attrib) const; + D3DDECLTYPE getDeclType(const gl::VertexAttribute &attrib) const; + + virtual unsigned int getBufferSize() const; + virtual bool setBufferSize(unsigned int size); + virtual bool discard(); + + IDirect3DVertexBuffer9 *getBuffer() const; + + private: + DISALLOW_COPY_AND_ASSIGN(VertexBuffer9); + + rx::Renderer9 *const mRenderer; + + IDirect3DVertexBuffer9 *mVertexBuffer; + unsigned int mBufferSize; + bool mDynamicUsage; + + // Attribute format conversion + enum { NUM_GL_VERTEX_ATTRIB_TYPES = 6 }; + + struct FormatConverter + { + bool identity; + std::size_t outputElementSize; + void (*convertArray)(const void *in, std::size_t stride, std::size_t n, void *out); + D3DDECLTYPE d3dDeclType; + }; + + static bool mTranslationsInitialized; + static void initializeTranslations(DWORD declTypes); + + // [GL types as enumerated by typeIndex()][normalized][size - 1] + static FormatConverter mFormatConverters[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + + struct TranslationDescription + { + DWORD capsFlag; + FormatConverter preferredConversion; + FormatConverter fallbackConversion; + }; + + // This table is used to generate mFormatConverters. + // [GL types as enumerated by typeIndex()][normalized][size - 1] + static const TranslationDescription mPossibleTranslations[NUM_GL_VERTEX_ATTRIB_TYPES][2][4]; + + static unsigned int typeIndex(GLenum type); + static const FormatConverter &formatConverter(const gl::VertexAttribute &attribute); + + static bool spaceRequired(const gl::VertexAttribute &attrib, std::size_t count, GLsizei instances, + unsigned int *outSpaceRequired); +}; + +} + +#endif // LIBGLESV2_RENDERER_VERTEXBUFFER9_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp new file mode 100644 index 0000000000..e5c8a14232 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.cpp @@ -0,0 +1,217 @@ +#include "precompiled.h" +// +// Copyright (c) 2012 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. +// + +// VertexDeclarationCache.cpp: Implements a helper class to construct and cache vertex declarations. + +#include "libGLESv2/ProgramBinary.h" +#include "libGLESv2/Context.h" +#include "libGLESv2/renderer/d3d9/VertexBuffer9.h" +#include "libGLESv2/renderer/d3d9/VertexDeclarationCache.h" + +namespace rx +{ + +VertexDeclarationCache::VertexDeclarationCache() : mMaxLru(0) +{ + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + mVertexDeclCache[i].vertexDeclaration = NULL; + mVertexDeclCache[i].lruCount = 0; + } + + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mAppliedVBs[i].serial = 0; + } + + mLastSetVDecl = NULL; + mInstancingEnabled = true; +} + +VertexDeclarationCache::~VertexDeclarationCache() +{ + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + if (mVertexDeclCache[i].vertexDeclaration) + { + mVertexDeclCache[i].vertexDeclaration->Release(); + } + } +} + +GLenum VertexDeclarationCache::applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw) +{ + *repeatDraw = 1; + + int indexedAttribute = gl::MAX_VERTEX_ATTRIBS; + int instancedAttribute = gl::MAX_VERTEX_ATTRIBS; + + if (instances > 0) + { + // Find an indexed attribute to be mapped to D3D stream 0 + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + if (attributes[i].active) + { + if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor == 0) + { + indexedAttribute = i; + } + else if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS && attributes[i].divisor != 0) + { + instancedAttribute = i; + } + if (indexedAttribute != gl::MAX_VERTEX_ATTRIBS && instancedAttribute != gl::MAX_VERTEX_ATTRIBS) + break; // Found both an indexed and instanced attribute + } + } + + if (indexedAttribute == gl::MAX_VERTEX_ATTRIBS) + { + return GL_INVALID_OPERATION; + } + } + + D3DVERTEXELEMENT9 elements[gl::MAX_VERTEX_ATTRIBS + 1]; + D3DVERTEXELEMENT9 *element = &elements[0]; + + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + if (attributes[i].active) + { + // Directly binding the storage buffer is not supported for d3d9 + ASSERT(attributes[i].storage == NULL); + + int stream = i; + + if (instances > 0) + { + // Due to a bug on ATI cards we can't enable instancing when none of the attributes are instanced. + if (instancedAttribute == gl::MAX_VERTEX_ATTRIBS) + { + *repeatDraw = instances; + } + else + { + if (i == indexedAttribute) + { + stream = 0; + } + else if (i == 0) + { + stream = indexedAttribute; + } + + UINT frequency = 1; + + if (attributes[i].divisor == 0) + { + frequency = D3DSTREAMSOURCE_INDEXEDDATA | instances; + } + else + { + frequency = D3DSTREAMSOURCE_INSTANCEDATA | attributes[i].divisor; + } + + device->SetStreamSourceFreq(stream, frequency); + mInstancingEnabled = true; + } + } + + VertexBuffer9 *vertexBuffer = VertexBuffer9::makeVertexBuffer9(attributes[i].vertexBuffer); + + if (mAppliedVBs[stream].serial != attributes[i].serial || + mAppliedVBs[stream].stride != attributes[i].stride || + mAppliedVBs[stream].offset != attributes[i].offset) + { + device->SetStreamSource(stream, vertexBuffer->getBuffer(), attributes[i].offset, attributes[i].stride); + mAppliedVBs[stream].serial = attributes[i].serial; + mAppliedVBs[stream].stride = attributes[i].stride; + mAppliedVBs[stream].offset = attributes[i].offset; + } + + element->Stream = stream; + element->Offset = 0; + element->Type = attributes[i].attribute->mArrayEnabled ? vertexBuffer->getDeclType(*attributes[i].attribute) : D3DDECLTYPE_FLOAT4; + element->Method = D3DDECLMETHOD_DEFAULT; + element->Usage = D3DDECLUSAGE_TEXCOORD; + element->UsageIndex = programBinary->getSemanticIndex(i); + element++; + } + } + + if (instances == 0 || instancedAttribute == gl::MAX_VERTEX_ATTRIBS) + { + if (mInstancingEnabled) + { + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + device->SetStreamSourceFreq(i, 1); + } + + mInstancingEnabled = false; + } + } + + static const D3DVERTEXELEMENT9 end = D3DDECL_END(); + *(element++) = end; + + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + VertexDeclCacheEntry *entry = &mVertexDeclCache[i]; + if (memcmp(entry->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)) == 0 && entry->vertexDeclaration) + { + entry->lruCount = ++mMaxLru; + if(entry->vertexDeclaration != mLastSetVDecl) + { + device->SetVertexDeclaration(entry->vertexDeclaration); + mLastSetVDecl = entry->vertexDeclaration; + } + + return GL_NO_ERROR; + } + } + + VertexDeclCacheEntry *lastCache = mVertexDeclCache; + + for (int i = 0; i < NUM_VERTEX_DECL_CACHE_ENTRIES; i++) + { + if (mVertexDeclCache[i].lruCount < lastCache->lruCount) + { + lastCache = &mVertexDeclCache[i]; + } + } + + if (lastCache->vertexDeclaration != NULL) + { + lastCache->vertexDeclaration->Release(); + lastCache->vertexDeclaration = NULL; + // mLastSetVDecl is set to the replacement, so we don't have to worry + // about it. + } + + memcpy(lastCache->cachedElements, elements, (element - elements) * sizeof(D3DVERTEXELEMENT9)); + device->CreateVertexDeclaration(elements, &lastCache->vertexDeclaration); + device->SetVertexDeclaration(lastCache->vertexDeclaration); + mLastSetVDecl = lastCache->vertexDeclaration; + lastCache->lruCount = ++mMaxLru; + + return GL_NO_ERROR; +} + +void VertexDeclarationCache::markStateDirty() +{ + for (int i = 0; i < gl::MAX_VERTEX_ATTRIBS; i++) + { + mAppliedVBs[i].serial = 0; + } + + mLastSetVDecl = NULL; + mInstancingEnabled = true; // Forces it to be disabled when not used +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h new file mode 100644 index 0000000000..3fc024a9ba --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/VertexDeclarationCache.h @@ -0,0 +1,58 @@ +// +// Copyright (c) 2012 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. +// + +// VertexDeclarationCache.h: Defines a helper class to construct and cache vertex declarations. + +#ifndef LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ +#define LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ + +#include "libGLESv2/renderer/VertexDataManager.h" + +namespace gl +{ +class VertexDataManager; +} + +namespace rx +{ + +class VertexDeclarationCache +{ + public: + VertexDeclarationCache(); + ~VertexDeclarationCache(); + + GLenum applyDeclaration(IDirect3DDevice9 *device, TranslatedAttribute attributes[], gl::ProgramBinary *programBinary, GLsizei instances, GLsizei *repeatDraw); + + void markStateDirty(); + + private: + UINT mMaxLru; + + enum { NUM_VERTEX_DECL_CACHE_ENTRIES = 32 }; + + struct VBData + { + unsigned int serial; + unsigned int stride; + unsigned int offset; + }; + + VBData mAppliedVBs[gl::MAX_VERTEX_ATTRIBS]; + IDirect3DVertexDeclaration9 *mLastSetVDecl; + bool mInstancingEnabled; + + struct VertexDeclCacheEntry + { + D3DVERTEXELEMENT9 cachedElements[gl::MAX_VERTEX_ATTRIBS + 1]; + UINT lruCount; + IDirect3DVertexDeclaration9 *vertexDeclaration; + } mVertexDeclCache[NUM_VERTEX_DECL_CACHE_ENTRIES]; +}; + +} + +#endif // LIBGLESV2_RENDERER_VERTEXDECLARATIONCACHE_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp new file mode 100644 index 0000000000..b7f2ffb1d9 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.cpp @@ -0,0 +1,500 @@ +#include "precompiled.h" +// +// Copyright (c) 2002-2012 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. +// + +// renderer9_utils.cpp: Conversion functions and other utility routines +// specific to the D3D9 renderer. + +#include "libGLESv2/renderer/d3d9/renderer9_utils.h" +#include "libGLESv2/mathutil.h" +#include "libGLESv2/Context.h" + +#include "common/debug.h" + +namespace gl_d3d9 +{ + +D3DCMPFUNC ConvertComparison(GLenum comparison) +{ + D3DCMPFUNC d3dComp = D3DCMP_ALWAYS; + switch (comparison) + { + case GL_NEVER: d3dComp = D3DCMP_NEVER; break; + case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break; + case GL_LESS: d3dComp = D3DCMP_LESS; break; + case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break; + case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break; + case GL_GREATER: d3dComp = D3DCMP_GREATER; break; + case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break; + case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break; + default: UNREACHABLE(); + } + + return d3dComp; +} + +D3DCOLOR ConvertColor(gl::Color color) +{ + return D3DCOLOR_RGBA(gl::unorm<8>(color.red), + gl::unorm<8>(color.green), + gl::unorm<8>(color.blue), + gl::unorm<8>(color.alpha)); +} + +D3DBLEND ConvertBlendFunc(GLenum blend) +{ + D3DBLEND d3dBlend = D3DBLEND_ZERO; + + switch (blend) + { + case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break; + case GL_ONE: d3dBlend = D3DBLEND_ONE; break; + case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break; + case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break; + case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break; + case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break; + case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break; + case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break; + case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break; + case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break; + case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break; + case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; + case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break; + case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; + case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break; + default: UNREACHABLE(); + } + + return d3dBlend; +} + +D3DBLENDOP ConvertBlendOp(GLenum blendOp) +{ + D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD; + + switch (blendOp) + { + case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break; + case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break; + case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break; + default: UNREACHABLE(); + } + + return d3dBlendOp; +} + +D3DSTENCILOP ConvertStencilOp(GLenum stencilOp) +{ + D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP; + + switch (stencilOp) + { + case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break; + case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break; + case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break; + case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break; + case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break; + case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break; + case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break; + case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break; + default: UNREACHABLE(); + } + + return d3dStencilOp; +} + +D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) +{ + D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP; + + switch (wrap) + { + case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break; + case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break; + case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break; + default: UNREACHABLE(); + } + + return d3dWrap; +} + +D3DCULL ConvertCullMode(GLenum 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(); + } + + return cull; +} + +D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) +{ + D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; + + switch (cubeFace) + { + case GL_TEXTURE_CUBE_MAP_POSITIVE_X: + face = D3DCUBEMAP_FACE_POSITIVE_X; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: + face = D3DCUBEMAP_FACE_NEGATIVE_X; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: + face = D3DCUBEMAP_FACE_POSITIVE_Y; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: + face = D3DCUBEMAP_FACE_NEGATIVE_Y; + break; + case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: + face = D3DCUBEMAP_FACE_POSITIVE_Z; + break; + case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: + face = D3DCUBEMAP_FACE_NEGATIVE_Z; + break; + default: UNREACHABLE(); + } + + return face; +} + +DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) +{ + return (red ? D3DCOLORWRITEENABLE_RED : 0) | + (green ? D3DCOLORWRITEENABLE_GREEN : 0) | + (blue ? D3DCOLORWRITEENABLE_BLUE : 0) | + (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0); +} + +D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) +{ + if (maxAnisotropy > 1.0f) + { + return D3DTEXF_ANISOTROPIC; + } + + D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT; + switch (magFilter) + { + case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break; + case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break; + default: UNREACHABLE(); + } + + return d3dMagFilter; +} + +void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy) +{ + switch (minFilter) + { + case GL_NEAREST: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_NONE; + break; + case GL_LINEAR: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_NONE; + break; + case GL_NEAREST_MIPMAP_NEAREST: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_POINT; + break; + case GL_LINEAR_MIPMAP_NEAREST: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_POINT; + break; + case GL_NEAREST_MIPMAP_LINEAR: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + *d3dMinFilter = D3DTEXF_LINEAR; + *d3dMipFilter = D3DTEXF_LINEAR; + break; + default: + *d3dMinFilter = D3DTEXF_POINT; + *d3dMipFilter = D3DTEXF_NONE; + UNREACHABLE(); + } + + if (maxAnisotropy > 1.0f) + { + *d3dMinFilter = D3DTEXF_ANISOTROPIC; + } +} + +D3DFORMAT ConvertRenderbufferFormat(GLenum format) +{ + switch (format) + { + case GL_NONE: return D3DFMT_NULL; + case GL_RGBA4: + case GL_RGB5_A1: + case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; + case GL_RGB565: return D3DFMT_R5G6B5; + case GL_RGB8_OES: return D3DFMT_X8R8G8B8; + case GL_DEPTH_COMPONENT16: + case GL_STENCIL_INDEX8: + case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8; + default: UNREACHABLE(); return D3DFMT_A8R8G8B8; + } +} + +D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples) +{ + if (samples <= 1) + return D3DMULTISAMPLE_NONE; + else + return (D3DMULTISAMPLE_TYPE)samples; +} + +} + +namespace d3d9_gl +{ + +unsigned int GetStencilSize(D3DFORMAT stencilFormat) +{ + if (stencilFormat == D3DFMT_INTZ) + { + return 8; + } + switch(stencilFormat) + { + case D3DFMT_D24FS8: + case D3DFMT_D24S8: + return 8; + case D3DFMT_D24X4S4: + return 4; + case D3DFMT_D15S1: + return 1; + case D3DFMT_D16_LOCKABLE: + case D3DFMT_D32: + case D3DFMT_D24X8: + case D3DFMT_D32F_LOCKABLE: + case D3DFMT_D16: + return 0; + //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only + //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only + default: + return 0; + } +} + +unsigned int GetAlphaSize(D3DFORMAT colorFormat) +{ + switch (colorFormat) + { + case D3DFMT_A16B16G16R16F: + return 16; + case D3DFMT_A32B32G32R32F: + return 32; + case D3DFMT_A2R10G10B10: + return 2; + case D3DFMT_A8R8G8B8: + return 8; + case D3DFMT_A1R5G5B5: + return 1; + case D3DFMT_X8R8G8B8: + case D3DFMT_R5G6B5: + return 0; + default: + return 0; + } +} + +GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) +{ + if (type == D3DMULTISAMPLE_NONMASKABLE) + return 0; + else + return type; +} + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) +{ + switch (d3dformat) + { + case D3DFMT_L8: + return (format == GL_LUMINANCE); + case D3DFMT_A8L8: + return (format == GL_LUMINANCE_ALPHA); + case D3DFMT_DXT1: + return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT); + case D3DFMT_DXT3: + return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); + case D3DFMT_DXT5: + return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); + case D3DFMT_A8R8G8B8: + case D3DFMT_A16B16G16R16F: + case D3DFMT_A32B32G32R32F: + return (format == GL_RGBA || format == GL_BGRA_EXT); + case D3DFMT_X8R8G8B8: + return (format == GL_RGB); + default: + if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format)) + return true; + return false; + } +} + +GLenum ConvertBackBufferFormat(D3DFORMAT format) +{ + switch (format) + { + case D3DFMT_A4R4G4B4: return GL_RGBA4; + case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; + case D3DFMT_A1R5G5B5: return GL_RGB5_A1; + case D3DFMT_R5G6B5: return GL_RGB565; + case D3DFMT_X8R8G8B8: return GL_RGB8_OES; + default: + UNREACHABLE(); + } + + return GL_RGBA4; +} + +GLenum ConvertDepthStencilFormat(D3DFORMAT format) +{ + if (format == D3DFMT_INTZ) + { + return GL_DEPTH24_STENCIL8_OES; + } + switch (format) + { + case D3DFMT_D16: + case D3DFMT_D24X8: + return GL_DEPTH_COMPONENT16; + case D3DFMT_D24S8: + return GL_DEPTH24_STENCIL8_OES; + case D3DFMT_UNKNOWN: + return GL_NONE; + default: + UNREACHABLE(); + } + + return GL_DEPTH24_STENCIL8_OES; +} + +GLenum ConvertRenderTargetFormat(D3DFORMAT format) +{ + if (format == D3DFMT_INTZ) + { + return GL_DEPTH24_STENCIL8_OES; + } + + switch (format) + { + case D3DFMT_A4R4G4B4: return GL_RGBA4; + case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; + case D3DFMT_A1R5G5B5: return GL_RGB5_A1; + case D3DFMT_R5G6B5: return GL_RGB565; + case D3DFMT_X8R8G8B8: return GL_RGB8_OES; + case D3DFMT_D16: + case D3DFMT_D24X8: + return GL_DEPTH_COMPONENT16; + case D3DFMT_D24S8: + return GL_DEPTH24_STENCIL8_OES; + case D3DFMT_UNKNOWN: + return GL_NONE; + default: + UNREACHABLE(); + } + + return GL_RGBA4; +} + +GLenum GetEquivalentFormat(D3DFORMAT format) +{ + if (format == D3DFMT_INTZ) + return GL_DEPTH24_STENCIL8_OES; + if (format == D3DFMT_NULL) + return GL_NONE; + + switch (format) + { + case D3DFMT_A4R4G4B4: return GL_RGBA4; + case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; + case D3DFMT_A1R5G5B5: return GL_RGB5_A1; + case D3DFMT_R5G6B5: return GL_RGB565; + case D3DFMT_X8R8G8B8: return GL_RGB8_OES; + case D3DFMT_D16: return GL_DEPTH_COMPONENT16; + case D3DFMT_D24S8: return GL_DEPTH24_STENCIL8_OES; + case D3DFMT_UNKNOWN: return GL_NONE; + case D3DFMT_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; + case D3DFMT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; + case D3DFMT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; + case D3DFMT_A32B32G32R32F: return GL_RGBA32F_EXT; + case D3DFMT_A16B16G16R16F: return GL_RGBA16F_EXT; + case D3DFMT_L8: return GL_LUMINANCE8_EXT; + case D3DFMT_A8L8: return GL_LUMINANCE8_ALPHA8_EXT; + default: UNREACHABLE(); + return GL_NONE; + } +} + +} + +namespace d3d9 +{ + +bool IsCompressedFormat(D3DFORMAT surfaceFormat) +{ + switch(surfaceFormat) + { + case D3DFMT_DXT1: + case D3DFMT_DXT2: + case D3DFMT_DXT3: + case D3DFMT_DXT4: + case D3DFMT_DXT5: + return true; + default: + return false; + } +} + +size_t ComputeRowSize(D3DFORMAT format, unsigned int width) +{ + if (format == D3DFMT_INTZ) + { + return 4 * width; + } + switch (format) + { + case D3DFMT_L8: + return 1 * width; + case D3DFMT_A8L8: + return 2 * width; + case D3DFMT_X8R8G8B8: + case D3DFMT_A8R8G8B8: + return 4 * width; + case D3DFMT_A16B16G16R16F: + return 8 * width; + case D3DFMT_A32B32G32R32F: + return 16 * width; + case D3DFMT_DXT1: + return 8 * ((width + 3) / 4); + case D3DFMT_DXT3: + case D3DFMT_DXT5: + return 16 * ((width + 3) / 4); + default: + UNREACHABLE(); + return 0; + } +} + +} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.h new file mode 100644 index 0000000000..bf6cdf1ea6 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/renderer9_utils.h @@ -0,0 +1,74 @@ +// +// Copyright (c) 2002-2012 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. +// + +// renderer9_utils.h: Conversion functions and other utility routines +// specific to the D3D9 renderer + +#ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H +#define LIBGLESV2_RENDERER_RENDERER9_UTILS_H + +#include "libGLESv2/utilities.h" + +const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); +const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); + +namespace gl_d3d9 +{ + +D3DCMPFUNC ConvertComparison(GLenum comparison); +D3DCOLOR ConvertColor(gl::Color color); +D3DBLEND ConvertBlendFunc(GLenum blend); +D3DBLENDOP ConvertBlendOp(GLenum blendOp); +D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); +D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); +D3DCULL ConvertCullMode(GLenum 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 maxAnisotropy); +D3DFORMAT ConvertRenderbufferFormat(GLenum format); +D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples); + +} + +namespace d3d9_gl +{ + +GLuint GetAlphaSize(D3DFORMAT colorFormat); +GLuint GetStencilSize(D3DFORMAT stencilFormat); + +GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type); + +bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); +GLenum ConvertBackBufferFormat(D3DFORMAT format); +GLenum ConvertDepthStencilFormat(D3DFORMAT format); +GLenum ConvertRenderTargetFormat(D3DFORMAT format); +GLenum GetEquivalentFormat(D3DFORMAT format); + +} + +namespace d3d9 +{ +bool IsCompressedFormat(D3DFORMAT format); +size_t ComputeRowSize(D3DFORMAT format, unsigned int width); + +inline bool isDeviceLostError(HRESULT errorCode) +{ + switch (errorCode) + { + case D3DERR_DRIVERINTERNALERROR: + case D3DERR_DEVICELOST: + case D3DERR_DEVICEHUNG: + case D3DERR_DEVICEREMOVED: + return true; + default: + return false; + } +} + +} + +#endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps new file mode 100644 index 0000000000..dcb3bd0e76 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.ps @@ -0,0 +1,39 @@ +// +// Copyright (c) 2012 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. +// + +sampler2D tex : s0; + +uniform float4 mode : c0; + +// Passthrough Pixel Shader +// Outputs texture 0 sampled at texcoord 0. +float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR +{ + return tex2D(tex, texcoord.xy); +}; + +// Luminance Conversion Pixel Shader +// Outputs sample(tex0, tc0).rrra. +// For LA output (pass A) set C0.X = 1, C0.Y = 0. +// For L output (A = 1) set C0.X = 0, C0.Y = 1. +float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 tmp = tex2D(tex, texcoord.xy); + tmp.w = tmp.w * mode.x + mode.y; + return tmp.xxxw; +}; + +// RGB/A Component Mask Pixel Shader +// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1. +// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1. +// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0. +float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR +{ + float4 tmp = tex2D(tex, texcoord.xy); + tmp.xyz = tmp.xyz * mode.x; + tmp.w = tmp.w * mode.z + mode.w; + return tmp; +}; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.vs b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.vs new file mode 100644 index 0000000000..3a36980b93 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/shaders/Blit.vs @@ -0,0 +1,43 @@ +// +// Copyright (c) 2012 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. +// + +struct VS_OUTPUT +{ + float4 position : POSITION; + float4 texcoord : TEXCOORD0; +}; + +uniform float4 halfPixelSize : c0; + +// Standard Vertex Shader +// Input 0 is the homogenous position. +// Outputs the homogenous position as-is. +// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right. +// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0. +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); + + return Out; +}; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/vertexconversion.h b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/vertexconversion.h new file mode 100644 index 0000000000..590b9d48a3 --- /dev/null +++ b/src/3rdparty/angle/src/libGLESv2/renderer/d3d9/vertexconversion.h @@ -0,0 +1,203 @@ +// +// Copyright (c) 2002-2010 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. +// + +// vertexconversion.h: A library of vertex conversion classes that can be used to build +// the FormatConverter objects used by the buffer conversion system. + +#ifndef LIBGLESV2_VERTEXCONVERSION_H_ +#define LIBGLESV2_VERTEXCONVERSION_H_ + +namespace rx +{ + +// Conversion types: +// static const bool identity: true if this is an identity transform, false otherwise +// static U convert(T): convert a single element from the input type to the output type +// typedef ... OutputType: the type produced by this conversion + +template +struct Identity +{ + static const bool identity = true; + + typedef T OutputType; + + static T convert(T x) + { + return x; + } +}; + +template +struct Cast +{ + static const bool identity = false; + + typedef ToT OutputType; + + static ToT convert(FromT x) + { + return static_cast(x); + } +}; + +template +struct Cast +{ + static const bool identity = true; + + typedef T OutputType; + + static T convert(T x) + { + return static_cast(x); + } +}; + +template +struct Normalize +{ + static const bool identity = false; + + typedef float OutputType; + + static float convert(T x) + { + typedef std::numeric_limits NL; + float f = static_cast(x); + + if (NL::is_signed) + { + // const float => VC2008 computes it at compile time + // static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that. + const float divisor = 1.0f/(2*static_cast(NL::max())+1); + return (2*f+1)*divisor; + } + else + { + return f/NL::max(); + } + } +}; + +template +struct FixedToFloat +{ + static const bool identity = false; + + typedef float OutputType; + + static float convert(FromType x) + { + const float divisor = 1.0f / static_cast(static_cast(1) << ScaleBits); + return static_cast(x) * divisor; + } +}; + +// Widen types: +// static const unsigned int initialWidth: number of components before conversion +// static const unsigned int finalWidth: number of components after conversion + +// Float is supported at any size. +template +struct NoWiden +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = N; +}; + +// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components +template +struct WidenToEven +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = N+(N&1); +}; + +template +struct WidenToFour +{ + static const std::size_t initialWidth = N; + static const std::size_t finalWidth = 4; +}; + +// Most types have 0 and 1 that are just that. +template +struct SimpleDefaultValues +{ + static T zero() { return static_cast(0); } + static T one() { return static_cast(1); } +}; + +// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value. +template +struct NormalizedDefaultValues +{ + static T zero() { return static_cast(0); } + static T one() { return std::numeric_limits::max(); } +}; + +// Converter: +// static const bool identity: true if this is an identity transform (with no widening) +// static const std::size_t finalSize: number of bytes per output vertex +// static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert an array of vertices. Input may be strided, but output will be unstrided. + +template > +struct VertexDataConverter +{ + typedef typename Converter::OutputType OutputType; + typedef InT InputType; + + static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; + static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); + + static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out) + { + for (std::size_t i = 0; i < n; i++) + { + const InputType *ein = pointerAddBytes(in, i * stride); + + copyComponent(out, ein, 0, static_cast(DefaultValueRule::zero())); + copyComponent(out, ein, 1, static_cast(DefaultValueRule::zero())); + copyComponent(out, ein, 2, static_cast(DefaultValueRule::zero())); + copyComponent(out, ein, 3, static_cast(DefaultValueRule::one())); + + out += WidenRule::finalWidth; + } + } + + static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out) + { + return convertArray(static_cast(in), stride, n, static_cast(out)); + } + + private: + // Advance the given pointer by a number of bytes (not pointed-to elements). + template + static T *pointerAddBytes(T *basePtr, std::size_t numBytes) + { + return reinterpret_cast(reinterpret_cast(basePtr) + numBytes); + } + + static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue) + { + if (WidenRule::finalWidth > elementindex) + { + if (WidenRule::initialWidth > elementindex) + { + out[elementindex] = Converter::convert(in[elementindex]); + } + else + { + out[elementindex] = defaultvalue; + } + } + } +}; + +} + +#endif // LIBGLESV2_VERTEXCONVERSION_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp deleted file mode 100644 index 0624a61160..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.cpp +++ /dev/null @@ -1,688 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2012 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. -// - -// renderer11_utils.cpp: Conversion functions and other utility routines -// specific to the D3D11 renderer. - -#include "libGLESv2/renderer/renderer11_utils.h" - -#include "common/debug.h" - -namespace gl_d3d11 -{ - -D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha) -{ - D3D11_BLEND d3dBlend = D3D11_BLEND_ZERO; - - switch (glBlend) - { - case GL_ZERO: d3dBlend = D3D11_BLEND_ZERO; break; - case GL_ONE: d3dBlend = D3D11_BLEND_ONE; break; - case GL_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_SRC_ALPHA : D3D11_BLEND_SRC_COLOR); break; - case GL_ONE_MINUS_SRC_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_SRC_ALPHA : D3D11_BLEND_INV_SRC_COLOR); break; - case GL_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_DEST_ALPHA : D3D11_BLEND_DEST_COLOR); break; - case GL_ONE_MINUS_DST_COLOR: d3dBlend = (isAlpha ? D3D11_BLEND_INV_DEST_ALPHA : D3D11_BLEND_INV_DEST_COLOR); break; - case GL_SRC_ALPHA: d3dBlend = D3D11_BLEND_SRC_ALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3D11_BLEND_INV_SRC_ALPHA; break; - case GL_DST_ALPHA: d3dBlend = D3D11_BLEND_DEST_ALPHA; break; - case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3D11_BLEND_INV_DEST_ALPHA; break; - case GL_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; - case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; - case GL_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_BLEND_FACTOR; break; - case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3D11_BLEND_INV_BLEND_FACTOR; break; - case GL_SRC_ALPHA_SATURATE: d3dBlend = D3D11_BLEND_SRC_ALPHA_SAT; break; - default: UNREACHABLE(); - } - - return d3dBlend; -} - -D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp) -{ - D3D11_BLEND_OP d3dBlendOp = D3D11_BLEND_OP_ADD; - - switch (glBlendOp) - { - case GL_FUNC_ADD: d3dBlendOp = D3D11_BLEND_OP_ADD; break; - case GL_FUNC_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_SUBTRACT; break; - case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3D11_BLEND_OP_REV_SUBTRACT; break; - default: UNREACHABLE(); - } - - return d3dBlendOp; -} - -UINT8 ConvertColorMask(bool red, bool green, bool blue, bool alpha) -{ - UINT8 mask = 0; - if (red) - { - mask |= D3D11_COLOR_WRITE_ENABLE_RED; - } - if (green) - { - mask |= D3D11_COLOR_WRITE_ENABLE_GREEN; - } - if (blue) - { - mask |= D3D11_COLOR_WRITE_ENABLE_BLUE; - } - if (alpha) - { - mask |= D3D11_COLOR_WRITE_ENABLE_ALPHA; - } - return mask; -} - -D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode) -{ - D3D11_CULL_MODE cull = D3D11_CULL_NONE; - - if (cullEnabled) - { - switch (cullMode) - { - case GL_FRONT: cull = D3D11_CULL_FRONT; break; - case GL_BACK: cull = D3D11_CULL_BACK; break; - case GL_FRONT_AND_BACK: cull = D3D11_CULL_NONE; break; - default: UNREACHABLE(); - } - } - else - { - cull = D3D11_CULL_NONE; - } - - return cull; -} - -D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison) -{ - D3D11_COMPARISON_FUNC d3dComp = D3D11_COMPARISON_NEVER; - switch (comparison) - { - case GL_NEVER: d3dComp = D3D11_COMPARISON_NEVER; break; - case GL_ALWAYS: d3dComp = D3D11_COMPARISON_ALWAYS; break; - case GL_LESS: d3dComp = D3D11_COMPARISON_LESS; break; - case GL_LEQUAL: d3dComp = D3D11_COMPARISON_LESS_EQUAL; break; - case GL_EQUAL: d3dComp = D3D11_COMPARISON_EQUAL; break; - case GL_GREATER: d3dComp = D3D11_COMPARISON_GREATER; break; - case GL_GEQUAL: d3dComp = D3D11_COMPARISON_GREATER_EQUAL; break; - case GL_NOTEQUAL: d3dComp = D3D11_COMPARISON_NOT_EQUAL; break; - default: UNREACHABLE(); - } - - return d3dComp; -} - -D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled) -{ - return depthWriteEnabled ? D3D11_DEPTH_WRITE_MASK_ALL : D3D11_DEPTH_WRITE_MASK_ZERO; -} - -UINT8 ConvertStencilMask(GLuint stencilmask) -{ - return static_cast(stencilmask); -} - -D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp) -{ - D3D11_STENCIL_OP d3dStencilOp = D3D11_STENCIL_OP_KEEP; - - switch (stencilOp) - { - case GL_ZERO: d3dStencilOp = D3D11_STENCIL_OP_ZERO; break; - case GL_KEEP: d3dStencilOp = D3D11_STENCIL_OP_KEEP; break; - case GL_REPLACE: d3dStencilOp = D3D11_STENCIL_OP_REPLACE; break; - case GL_INCR: d3dStencilOp = D3D11_STENCIL_OP_INCR_SAT; break; - case GL_DECR: d3dStencilOp = D3D11_STENCIL_OP_DECR_SAT; break; - case GL_INVERT: d3dStencilOp = D3D11_STENCIL_OP_INVERT; break; - case GL_INCR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_INCR; break; - case GL_DECR_WRAP: d3dStencilOp = D3D11_STENCIL_OP_DECR; break; - default: UNREACHABLE(); - } - - return d3dStencilOp; -} - -D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy) -{ - if (maxAnisotropy > 1.0f) - { - return D3D11_ENCODE_ANISOTROPIC_FILTER(false); - } - else - { - D3D11_FILTER_TYPE dxMin = D3D11_FILTER_TYPE_POINT; - D3D11_FILTER_TYPE dxMip = D3D11_FILTER_TYPE_POINT; - switch (minFilter) - { - case GL_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_NEAREST_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR_MIPMAP_NEAREST: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_POINT; break; - case GL_NEAREST_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_POINT; dxMip = D3D11_FILTER_TYPE_LINEAR; break; - case GL_LINEAR_MIPMAP_LINEAR: dxMin = D3D11_FILTER_TYPE_LINEAR; dxMip = D3D11_FILTER_TYPE_LINEAR; break; - default: UNREACHABLE(); - } - - D3D11_FILTER_TYPE dxMag = D3D11_FILTER_TYPE_POINT; - switch (magFilter) - { - case GL_NEAREST: dxMag = D3D11_FILTER_TYPE_POINT; break; - case GL_LINEAR: dxMag = D3D11_FILTER_TYPE_LINEAR; break; - default: UNREACHABLE(); - } - - return D3D11_ENCODE_BASIC_FILTER(dxMin, dxMag, dxMip, false); - } -} - -D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap) -{ - switch (wrap) - { - case GL_REPEAT: return D3D11_TEXTURE_ADDRESS_WRAP; - case GL_CLAMP_TO_EDGE: return D3D11_TEXTURE_ADDRESS_CLAMP; - case GL_MIRRORED_REPEAT: return D3D11_TEXTURE_ADDRESS_MIRROR; - default: UNREACHABLE(); - } - - return D3D11_TEXTURE_ADDRESS_WRAP; -} - -FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset) -{ - return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast(lodOffset) : -FLT_MAX; -} - -FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset) -{ - return (minFilter == GL_NEAREST || minFilter == GL_LINEAR) ? static_cast(lodOffset) : FLT_MAX; -} - -} - -namespace d3d11_gl -{ - -GLenum ConvertBackBufferFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: return GL_RGBA8_OES; - case DXGI_FORMAT_B8G8R8A8_UNORM: return GL_BGRA8_EXT; - default: - UNREACHABLE(); - } - - return GL_RGBA8_OES; -} - -GLenum ConvertDepthStencilFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_UNKNOWN: return GL_NONE; - case DXGI_FORMAT_D16_UNORM: return GL_DEPTH_COMPONENT16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return GL_DEPTH24_STENCIL8_OES; - default: - UNREACHABLE(); - } - - return GL_DEPTH24_STENCIL8_OES; -} - -GLenum ConvertRenderbufferFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_B8G8R8A8_UNORM: - return GL_BGRA8_EXT; - case DXGI_FORMAT_R8G8B8A8_UNORM: - return GL_RGBA8_OES; - case DXGI_FORMAT_D16_UNORM: - return GL_DEPTH_COMPONENT16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - return GL_DEPTH24_STENCIL8_OES; - default: - UNREACHABLE(); - } - - return GL_RGBA8_OES; -} - -GLenum ConvertTextureInternalFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - return GL_RGBA8_OES; - case DXGI_FORMAT_A8_UNORM: - return GL_ALPHA8_EXT; - case DXGI_FORMAT_BC1_UNORM: - return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case DXGI_FORMAT_BC2_UNORM: - return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; - case DXGI_FORMAT_BC3_UNORM: - return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; - case DXGI_FORMAT_R32G32B32A32_FLOAT: - return GL_RGBA32F_EXT; - case DXGI_FORMAT_R32G32B32_FLOAT: - return GL_RGB32F_EXT; - case DXGI_FORMAT_R16G16B16A16_FLOAT: - return GL_RGBA16F_EXT; - case DXGI_FORMAT_B8G8R8A8_UNORM: - return GL_BGRA8_EXT; - case DXGI_FORMAT_R8_UNORM: - return GL_R8_EXT; - case DXGI_FORMAT_R8G8_UNORM: - return GL_RG8_EXT; - case DXGI_FORMAT_R16_FLOAT: - return GL_R16F_EXT; - case DXGI_FORMAT_R16G16_FLOAT: - return GL_RG16F_EXT; - case DXGI_FORMAT_D16_UNORM: - return GL_DEPTH_COMPONENT16; - case DXGI_FORMAT_D24_UNORM_S8_UINT: - return GL_DEPTH24_STENCIL8_OES; - case DXGI_FORMAT_UNKNOWN: - return GL_NONE; - default: - UNREACHABLE(); - } - - return GL_RGBA8_OES; -} - -} - -namespace gl_d3d11 -{ - -DXGI_FORMAT ConvertRenderbufferFormat(GLenum format) -{ - switch (format) - { - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8_OES: - case GL_RGB565: - case GL_RGB8_OES: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case GL_BGRA8_EXT: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case GL_DEPTH_COMPONENT16: - return DXGI_FORMAT_D16_UNORM; - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - default: - UNREACHABLE(); - } - - return DXGI_FORMAT_R8G8B8A8_UNORM; -} - -DXGI_FORMAT ConvertTextureFormat(GLenum internalformat, D3D_FEATURE_LEVEL featureLevel) -{ - switch (internalformat) - { - case GL_RGB565: - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGB8_OES: - case GL_RGBA8_OES: - case GL_LUMINANCE8_EXT: - case GL_LUMINANCE8_ALPHA8_EXT: - return DXGI_FORMAT_R8G8B8A8_UNORM; - case GL_ALPHA8_EXT: - return featureLevel >= D3D_FEATURE_LEVEL_10_0 ? DXGI_FORMAT_A8_UNORM : DXGI_FORMAT_B8G8R8A8_UNORM; - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - return DXGI_FORMAT_BC1_UNORM; - case GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE: - return DXGI_FORMAT_BC2_UNORM; - case GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE: - return DXGI_FORMAT_BC3_UNORM; - case GL_RGBA32F_EXT: - case GL_ALPHA32F_EXT: - case GL_LUMINANCE_ALPHA32F_EXT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case GL_RGB32F_EXT: - case GL_LUMINANCE32F_EXT: - return DXGI_FORMAT_R32G32B32A32_FLOAT; - case GL_RGBA16F_EXT: - case GL_ALPHA16F_EXT: - case GL_LUMINANCE_ALPHA16F_EXT: - case GL_RGB16F_EXT: - case GL_LUMINANCE16F_EXT: - return DXGI_FORMAT_R16G16B16A16_FLOAT; - case GL_BGRA8_EXT: - return DXGI_FORMAT_B8G8R8A8_UNORM; - case GL_R8_EXT: - return DXGI_FORMAT_R8_UNORM; - case GL_RG8_EXT: - return DXGI_FORMAT_R8G8_UNORM; - case GL_R16F_EXT: - return DXGI_FORMAT_R16_FLOAT; - case GL_RG16F_EXT: - return DXGI_FORMAT_R16G16_FLOAT; - case GL_DEPTH_COMPONENT16: - return DXGI_FORMAT_D16_UNORM; - case GL_DEPTH_COMPONENT32_OES: - case GL_DEPTH24_STENCIL8_OES: - return DXGI_FORMAT_D24_UNORM_S8_UINT; - case GL_NONE: - return DXGI_FORMAT_UNKNOWN; - default: - UNREACHABLE(); - } - - return DXGI_FORMAT_R8G8B8A8_UNORM; -} - -} - -namespace d3d11 -{ - -void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v) -{ - vertex->x = x; - vertex->y = y; - vertex->u = u; - vertex->v = v; -} - -void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, - const gl::Color &color) -{ - vertex->x = x; - vertex->y = y; - vertex->z = z; - vertex->r = color.red; - vertex->g = color.green; - vertex->b = color.blue; - vertex->a = color.alpha; -} - -size_t ComputePixelSizeBits(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_R1_UNORM: - return 1; - - case DXGI_FORMAT_A8_UNORM: - case DXGI_FORMAT_R8_SINT: - case DXGI_FORMAT_R8_SNORM: - case DXGI_FORMAT_R8_TYPELESS: - case DXGI_FORMAT_R8_UINT: - case DXGI_FORMAT_R8_UNORM: - return 8; - - case DXGI_FORMAT_B5G5R5A1_UNORM: - case DXGI_FORMAT_B5G6R5_UNORM: - case DXGI_FORMAT_D16_UNORM: - case DXGI_FORMAT_R16_FLOAT: - case DXGI_FORMAT_R16_SINT: - case DXGI_FORMAT_R16_SNORM: - case DXGI_FORMAT_R16_TYPELESS: - case DXGI_FORMAT_R16_UINT: - case DXGI_FORMAT_R16_UNORM: - case DXGI_FORMAT_R8G8_SINT: - case DXGI_FORMAT_R8G8_SNORM: - case DXGI_FORMAT_R8G8_TYPELESS: - case DXGI_FORMAT_R8G8_UINT: - case DXGI_FORMAT_R8G8_UNORM: - return 16; - - case DXGI_FORMAT_B8G8R8X8_TYPELESS: - case DXGI_FORMAT_B8G8R8X8_UNORM: - case DXGI_FORMAT_B8G8R8X8_UNORM_SRGB: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_G8R8_G8B8_UNORM: - case DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM: - case DXGI_FORMAT_R10G10B10A2_TYPELESS: - case DXGI_FORMAT_R10G10B10A2_UINT: - case DXGI_FORMAT_R10G10B10A2_UNORM: - case DXGI_FORMAT_R11G11B10_FLOAT: - case DXGI_FORMAT_R16G16_FLOAT: - case DXGI_FORMAT_R16G16_SINT: - case DXGI_FORMAT_R16G16_SNORM: - case DXGI_FORMAT_R16G16_TYPELESS: - case DXGI_FORMAT_R16G16_UINT: - case DXGI_FORMAT_R16G16_UNORM: - case DXGI_FORMAT_R24_UNORM_X8_TYPELESS: - case DXGI_FORMAT_R24G8_TYPELESS: - case DXGI_FORMAT_R32_FLOAT: - case DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS: - case DXGI_FORMAT_R32_SINT: - case DXGI_FORMAT_R32_TYPELESS: - case DXGI_FORMAT_R32_UINT: - case DXGI_FORMAT_R8G8_B8G8_UNORM: - case DXGI_FORMAT_R8G8B8A8_SINT: - case DXGI_FORMAT_R8G8B8A8_SNORM: - case DXGI_FORMAT_R8G8B8A8_TYPELESS: - case DXGI_FORMAT_R8G8B8A8_UINT: - case DXGI_FORMAT_R8G8B8A8_UNORM: - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - case DXGI_FORMAT_B8G8R8A8_TYPELESS: - case DXGI_FORMAT_B8G8R8A8_UNORM: - case DXGI_FORMAT_B8G8R8A8_UNORM_SRGB: - case DXGI_FORMAT_R9G9B9E5_SHAREDEXP: - case DXGI_FORMAT_X24_TYPELESS_G8_UINT: - case DXGI_FORMAT_X32_TYPELESS_G8X24_UINT: - return 32; - - case DXGI_FORMAT_R16G16B16A16_FLOAT: - case DXGI_FORMAT_R16G16B16A16_SINT: - case DXGI_FORMAT_R16G16B16A16_SNORM: - case DXGI_FORMAT_R16G16B16A16_TYPELESS: - case DXGI_FORMAT_R16G16B16A16_UINT: - case DXGI_FORMAT_R16G16B16A16_UNORM: - case DXGI_FORMAT_R32G32_FLOAT: - case DXGI_FORMAT_R32G32_SINT: - case DXGI_FORMAT_R32G32_TYPELESS: - case DXGI_FORMAT_R32G32_UINT: - case DXGI_FORMAT_R32G8X24_TYPELESS: - return 64; - - case DXGI_FORMAT_R32G32B32_FLOAT: - case DXGI_FORMAT_R32G32B32_SINT: - case DXGI_FORMAT_R32G32B32_TYPELESS: - case DXGI_FORMAT_R32G32B32_UINT: - return 96; - - case DXGI_FORMAT_R32G32B32A32_FLOAT: - case DXGI_FORMAT_R32G32B32A32_SINT: - case DXGI_FORMAT_R32G32B32A32_TYPELESS: - case DXGI_FORMAT_R32G32B32A32_UINT: - return 128; - - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - return 4; - - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 8; - - default: - return 0; - } -} - -size_t ComputeBlockSizeBits(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return ComputePixelSizeBits(format) * 16; - default: - UNREACHABLE(); - return 0; - } -} - -bool IsCompressed(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return true; - case DXGI_FORMAT_UNKNOWN: - UNREACHABLE(); - return false; - default: - return false; - } -} - -unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_BC1_TYPELESS: - case DXGI_FORMAT_BC1_UNORM: - case DXGI_FORMAT_BC1_UNORM_SRGB: - case DXGI_FORMAT_BC4_SNORM: - case DXGI_FORMAT_BC4_TYPELESS: - case DXGI_FORMAT_BC4_UNORM: - case DXGI_FORMAT_BC2_TYPELESS: - case DXGI_FORMAT_BC2_UNORM: - case DXGI_FORMAT_BC2_UNORM_SRGB: - case DXGI_FORMAT_BC3_TYPELESS: - case DXGI_FORMAT_BC3_UNORM: - case DXGI_FORMAT_BC3_UNORM_SRGB: - case DXGI_FORMAT_BC5_SNORM: - case DXGI_FORMAT_BC5_TYPELESS: - case DXGI_FORMAT_BC5_UNORM: - case DXGI_FORMAT_BC6H_SF16: - case DXGI_FORMAT_BC6H_TYPELESS: - case DXGI_FORMAT_BC6H_UF16: - case DXGI_FORMAT_BC7_TYPELESS: - case DXGI_FORMAT_BC7_UNORM: - case DXGI_FORMAT_BC7_UNORM_SRGB: - return 4; - case DXGI_FORMAT_UNKNOWN: - UNREACHABLE(); - return 1; - default: - return 1; - } -} - -bool IsDepthStencilFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: - case DXGI_FORMAT_D32_FLOAT: - case DXGI_FORMAT_D24_UNORM_S8_UINT: - case DXGI_FORMAT_D16_UNORM: - return true; - default: - return false; - } -} - -DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32G8X24_TYPELESS; - case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_TYPELESS; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24G8_TYPELESS; - case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_TYPELESS; - default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; - } -} - -DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format) -{ - switch (format) - { - case DXGI_FORMAT_D32_FLOAT_S8X24_UINT: return DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS; - case DXGI_FORMAT_D32_FLOAT: return DXGI_FORMAT_R32_UINT; - case DXGI_FORMAT_D24_UNORM_S8_UINT: return DXGI_FORMAT_R24_UNORM_X8_TYPELESS; - case DXGI_FORMAT_D16_UNORM: return DXGI_FORMAT_R16_UNORM; - default: UNREACHABLE(); return DXGI_FORMAT_UNKNOWN; - } -} - -HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name) -{ -#if defined(_DEBUG) - return resource->SetPrivateData(WKPDID_D3DDebugObjectName, strlen(name), name); -#else - return S_OK; -#endif -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h deleted file mode 100644 index 70ad4fea2b..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer11_utils.h +++ /dev/null @@ -1,95 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -// renderer11_utils.h: Conversion functions and other utility routines -// specific to the D3D11 renderer. - -#ifndef LIBGLESV2_RENDERER_RENDERER11_UTILS_H -#define LIBGLESV2_RENDERER_RENDERER11_UTILS_H - -#include "libGLESv2/angletypes.h" - -namespace gl_d3d11 -{ - -D3D11_BLEND ConvertBlendFunc(GLenum glBlend, bool isAlpha); -D3D11_BLEND_OP ConvertBlendOp(GLenum glBlendOp); -UINT8 ConvertColorMask(bool maskRed, bool maskGreen, bool maskBlue, bool maskAlpha); - -D3D11_CULL_MODE ConvertCullMode(bool cullEnabled, GLenum cullMode); - -D3D11_COMPARISON_FUNC ConvertComparison(GLenum comparison); -D3D11_DEPTH_WRITE_MASK ConvertDepthMask(bool depthWriteEnabled); -UINT8 ConvertStencilMask(GLuint stencilmask); -D3D11_STENCIL_OP ConvertStencilOp(GLenum stencilOp); - -D3D11_FILTER ConvertFilter(GLenum minFilter, GLenum magFilter, float maxAnisotropy); -D3D11_TEXTURE_ADDRESS_MODE ConvertTextureWrap(GLenum wrap); -FLOAT ConvertMinLOD(GLenum minFilter, unsigned int lodOffset); -FLOAT ConvertMaxLOD(GLenum minFilter, unsigned int lodOffset); - -DXGI_FORMAT ConvertRenderbufferFormat(GLenum format); -DXGI_FORMAT ConvertTextureFormat(GLenum format, D3D_FEATURE_LEVEL featureLevel); -} - -namespace d3d11_gl -{ - -GLenum ConvertBackBufferFormat(DXGI_FORMAT format); -GLenum ConvertDepthStencilFormat(DXGI_FORMAT format); -GLenum ConvertRenderbufferFormat(DXGI_FORMAT format); -GLenum ConvertTextureInternalFormat(DXGI_FORMAT format); - -} - -namespace d3d11 -{ - -struct PositionTexCoordVertex -{ - float x, y; - float u, v; -}; -void SetPositionTexCoordVertex(PositionTexCoordVertex* vertex, float x, float y, float u, float v); - -struct PositionDepthColorVertex -{ - float x, y, z; - float r, g, b, a; -}; -void SetPositionDepthColorVertex(PositionDepthColorVertex* vertex, float x, float y, float z, - const gl::Color &color); - -size_t ComputePixelSizeBits(DXGI_FORMAT format); -size_t ComputeBlockSizeBits(DXGI_FORMAT format); - -bool IsCompressed(DXGI_FORMAT format); -unsigned int GetTextureFormatDimensionAlignment(DXGI_FORMAT format); - -bool IsDepthStencilFormat(DXGI_FORMAT format); -DXGI_FORMAT GetDepthTextureFormat(DXGI_FORMAT format); -DXGI_FORMAT GetDepthShaderResourceFormat(DXGI_FORMAT format); - -HRESULT SetDebugName(ID3D11DeviceChild *resource, const char *name); - -inline bool isDeviceLostError(HRESULT errorCode) -{ - switch (errorCode) - { - case DXGI_ERROR_DEVICE_HUNG: - case DXGI_ERROR_DEVICE_REMOVED: - case DXGI_ERROR_DEVICE_RESET: - case DXGI_ERROR_DRIVER_INTERNAL_ERROR: - case DXGI_ERROR_NOT_CURRENTLY_AVAILABLE: - return true; - default: - return false; - } -} - -} - -#endif // LIBGLESV2_RENDERER_RENDERER11_UTILS_H diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp b/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp deleted file mode 100644 index da75d465e3..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.cpp +++ /dev/null @@ -1,500 +0,0 @@ -#include "precompiled.h" -// -// Copyright (c) 2002-2012 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. -// - -// renderer9_utils.cpp: Conversion functions and other utility routines -// specific to the D3D9 renderer. - -#include "libGLESv2/renderer/renderer9_utils.h" -#include "libGLESv2/mathutil.h" -#include "libGLESv2/Context.h" - -#include "common/debug.h" - -namespace gl_d3d9 -{ - -D3DCMPFUNC ConvertComparison(GLenum comparison) -{ - D3DCMPFUNC d3dComp = D3DCMP_ALWAYS; - switch (comparison) - { - case GL_NEVER: d3dComp = D3DCMP_NEVER; break; - case GL_ALWAYS: d3dComp = D3DCMP_ALWAYS; break; - case GL_LESS: d3dComp = D3DCMP_LESS; break; - case GL_LEQUAL: d3dComp = D3DCMP_LESSEQUAL; break; - case GL_EQUAL: d3dComp = D3DCMP_EQUAL; break; - case GL_GREATER: d3dComp = D3DCMP_GREATER; break; - case GL_GEQUAL: d3dComp = D3DCMP_GREATEREQUAL; break; - case GL_NOTEQUAL: d3dComp = D3DCMP_NOTEQUAL; break; - default: UNREACHABLE(); - } - - return d3dComp; -} - -D3DCOLOR ConvertColor(gl::Color color) -{ - return D3DCOLOR_RGBA(gl::unorm<8>(color.red), - gl::unorm<8>(color.green), - gl::unorm<8>(color.blue), - gl::unorm<8>(color.alpha)); -} - -D3DBLEND ConvertBlendFunc(GLenum blend) -{ - D3DBLEND d3dBlend = D3DBLEND_ZERO; - - switch (blend) - { - case GL_ZERO: d3dBlend = D3DBLEND_ZERO; break; - case GL_ONE: d3dBlend = D3DBLEND_ONE; break; - case GL_SRC_COLOR: d3dBlend = D3DBLEND_SRCCOLOR; break; - case GL_ONE_MINUS_SRC_COLOR: d3dBlend = D3DBLEND_INVSRCCOLOR; break; - case GL_DST_COLOR: d3dBlend = D3DBLEND_DESTCOLOR; break; - case GL_ONE_MINUS_DST_COLOR: d3dBlend = D3DBLEND_INVDESTCOLOR; break; - case GL_SRC_ALPHA: d3dBlend = D3DBLEND_SRCALPHA; break; - case GL_ONE_MINUS_SRC_ALPHA: d3dBlend = D3DBLEND_INVSRCALPHA; break; - case GL_DST_ALPHA: d3dBlend = D3DBLEND_DESTALPHA; break; - case GL_ONE_MINUS_DST_ALPHA: d3dBlend = D3DBLEND_INVDESTALPHA; break; - case GL_CONSTANT_COLOR: d3dBlend = D3DBLEND_BLENDFACTOR; break; - case GL_ONE_MINUS_CONSTANT_COLOR: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; - case GL_CONSTANT_ALPHA: d3dBlend = D3DBLEND_BLENDFACTOR; break; - case GL_ONE_MINUS_CONSTANT_ALPHA: d3dBlend = D3DBLEND_INVBLENDFACTOR; break; - case GL_SRC_ALPHA_SATURATE: d3dBlend = D3DBLEND_SRCALPHASAT; break; - default: UNREACHABLE(); - } - - return d3dBlend; -} - -D3DBLENDOP ConvertBlendOp(GLenum blendOp) -{ - D3DBLENDOP d3dBlendOp = D3DBLENDOP_ADD; - - switch (blendOp) - { - case GL_FUNC_ADD: d3dBlendOp = D3DBLENDOP_ADD; break; - case GL_FUNC_SUBTRACT: d3dBlendOp = D3DBLENDOP_SUBTRACT; break; - case GL_FUNC_REVERSE_SUBTRACT: d3dBlendOp = D3DBLENDOP_REVSUBTRACT; break; - default: UNREACHABLE(); - } - - return d3dBlendOp; -} - -D3DSTENCILOP ConvertStencilOp(GLenum stencilOp) -{ - D3DSTENCILOP d3dStencilOp = D3DSTENCILOP_KEEP; - - switch (stencilOp) - { - case GL_ZERO: d3dStencilOp = D3DSTENCILOP_ZERO; break; - case GL_KEEP: d3dStencilOp = D3DSTENCILOP_KEEP; break; - case GL_REPLACE: d3dStencilOp = D3DSTENCILOP_REPLACE; break; - case GL_INCR: d3dStencilOp = D3DSTENCILOP_INCRSAT; break; - case GL_DECR: d3dStencilOp = D3DSTENCILOP_DECRSAT; break; - case GL_INVERT: d3dStencilOp = D3DSTENCILOP_INVERT; break; - case GL_INCR_WRAP: d3dStencilOp = D3DSTENCILOP_INCR; break; - case GL_DECR_WRAP: d3dStencilOp = D3DSTENCILOP_DECR; break; - default: UNREACHABLE(); - } - - return d3dStencilOp; -} - -D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap) -{ - D3DTEXTUREADDRESS d3dWrap = D3DTADDRESS_WRAP; - - switch (wrap) - { - case GL_REPEAT: d3dWrap = D3DTADDRESS_WRAP; break; - case GL_CLAMP_TO_EDGE: d3dWrap = D3DTADDRESS_CLAMP; break; - case GL_MIRRORED_REPEAT: d3dWrap = D3DTADDRESS_MIRROR; break; - default: UNREACHABLE(); - } - - return d3dWrap; -} - -D3DCULL ConvertCullMode(GLenum 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(); - } - - return cull; -} - -D3DCUBEMAP_FACES ConvertCubeFace(GLenum cubeFace) -{ - D3DCUBEMAP_FACES face = D3DCUBEMAP_FACE_POSITIVE_X; - - switch (cubeFace) - { - case GL_TEXTURE_CUBE_MAP_POSITIVE_X: - face = D3DCUBEMAP_FACE_POSITIVE_X; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_X: - face = D3DCUBEMAP_FACE_NEGATIVE_X; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Y: - face = D3DCUBEMAP_FACE_POSITIVE_Y; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Y: - face = D3DCUBEMAP_FACE_NEGATIVE_Y; - break; - case GL_TEXTURE_CUBE_MAP_POSITIVE_Z: - face = D3DCUBEMAP_FACE_POSITIVE_Z; - break; - case GL_TEXTURE_CUBE_MAP_NEGATIVE_Z: - face = D3DCUBEMAP_FACE_NEGATIVE_Z; - break; - default: UNREACHABLE(); - } - - return face; -} - -DWORD ConvertColorMask(bool red, bool green, bool blue, bool alpha) -{ - return (red ? D3DCOLORWRITEENABLE_RED : 0) | - (green ? D3DCOLORWRITEENABLE_GREEN : 0) | - (blue ? D3DCOLORWRITEENABLE_BLUE : 0) | - (alpha ? D3DCOLORWRITEENABLE_ALPHA : 0); -} - -D3DTEXTUREFILTERTYPE ConvertMagFilter(GLenum magFilter, float maxAnisotropy) -{ - if (maxAnisotropy > 1.0f) - { - return D3DTEXF_ANISOTROPIC; - } - - D3DTEXTUREFILTERTYPE d3dMagFilter = D3DTEXF_POINT; - switch (magFilter) - { - case GL_NEAREST: d3dMagFilter = D3DTEXF_POINT; break; - case GL_LINEAR: d3dMagFilter = D3DTEXF_LINEAR; break; - default: UNREACHABLE(); - } - - return d3dMagFilter; -} - -void ConvertMinFilter(GLenum minFilter, D3DTEXTUREFILTERTYPE *d3dMinFilter, D3DTEXTUREFILTERTYPE *d3dMipFilter, float maxAnisotropy) -{ - switch (minFilter) - { - case GL_NEAREST: - *d3dMinFilter = D3DTEXF_POINT; - *d3dMipFilter = D3DTEXF_NONE; - break; - case GL_LINEAR: - *d3dMinFilter = D3DTEXF_LINEAR; - *d3dMipFilter = D3DTEXF_NONE; - break; - case GL_NEAREST_MIPMAP_NEAREST: - *d3dMinFilter = D3DTEXF_POINT; - *d3dMipFilter = D3DTEXF_POINT; - break; - case GL_LINEAR_MIPMAP_NEAREST: - *d3dMinFilter = D3DTEXF_LINEAR; - *d3dMipFilter = D3DTEXF_POINT; - break; - case GL_NEAREST_MIPMAP_LINEAR: - *d3dMinFilter = D3DTEXF_POINT; - *d3dMipFilter = D3DTEXF_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - *d3dMinFilter = D3DTEXF_LINEAR; - *d3dMipFilter = D3DTEXF_LINEAR; - break; - default: - *d3dMinFilter = D3DTEXF_POINT; - *d3dMipFilter = D3DTEXF_NONE; - UNREACHABLE(); - } - - if (maxAnisotropy > 1.0f) - { - *d3dMinFilter = D3DTEXF_ANISOTROPIC; - } -} - -D3DFORMAT ConvertRenderbufferFormat(GLenum format) -{ - switch (format) - { - case GL_NONE: return D3DFMT_NULL; - case GL_RGBA4: - case GL_RGB5_A1: - case GL_RGBA8_OES: return D3DFMT_A8R8G8B8; - case GL_RGB565: return D3DFMT_R5G6B5; - case GL_RGB8_OES: return D3DFMT_X8R8G8B8; - case GL_DEPTH_COMPONENT16: - case GL_STENCIL_INDEX8: - case GL_DEPTH24_STENCIL8_OES: return D3DFMT_D24S8; - default: UNREACHABLE(); return D3DFMT_A8R8G8B8; - } -} - -D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples) -{ - if (samples <= 1) - return D3DMULTISAMPLE_NONE; - else - return (D3DMULTISAMPLE_TYPE)samples; -} - -} - -namespace d3d9_gl -{ - -unsigned int GetStencilSize(D3DFORMAT stencilFormat) -{ - if (stencilFormat == D3DFMT_INTZ) - { - return 8; - } - switch(stencilFormat) - { - case D3DFMT_D24FS8: - case D3DFMT_D24S8: - return 8; - case D3DFMT_D24X4S4: - return 4; - case D3DFMT_D15S1: - return 1; - case D3DFMT_D16_LOCKABLE: - case D3DFMT_D32: - case D3DFMT_D24X8: - case D3DFMT_D32F_LOCKABLE: - case D3DFMT_D16: - return 0; - //case D3DFMT_D32_LOCKABLE: return 0; // DirectX 9Ex only - //case D3DFMT_S8_LOCKABLE: return 8; // DirectX 9Ex only - default: - return 0; - } -} - -unsigned int GetAlphaSize(D3DFORMAT colorFormat) -{ - switch (colorFormat) - { - case D3DFMT_A16B16G16R16F: - return 16; - case D3DFMT_A32B32G32R32F: - return 32; - case D3DFMT_A2R10G10B10: - return 2; - case D3DFMT_A8R8G8B8: - return 8; - case D3DFMT_A1R5G5B5: - return 1; - case D3DFMT_X8R8G8B8: - case D3DFMT_R5G6B5: - return 0; - default: - return 0; - } -} - -GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type) -{ - if (type == D3DMULTISAMPLE_NONMASKABLE) - return 0; - else - return type; -} - -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format) -{ - switch (d3dformat) - { - case D3DFMT_L8: - return (format == GL_LUMINANCE); - case D3DFMT_A8L8: - return (format == GL_LUMINANCE_ALPHA); - case D3DFMT_DXT1: - return (format == GL_COMPRESSED_RGBA_S3TC_DXT1_EXT || format == GL_COMPRESSED_RGB_S3TC_DXT1_EXT); - case D3DFMT_DXT3: - return (format == GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE); - case D3DFMT_DXT5: - return (format == GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE); - case D3DFMT_A8R8G8B8: - case D3DFMT_A16B16G16R16F: - case D3DFMT_A32B32G32R32F: - return (format == GL_RGBA || format == GL_BGRA_EXT); - case D3DFMT_X8R8G8B8: - return (format == GL_RGB); - default: - if (d3dformat == D3DFMT_INTZ && gl::IsDepthTexture(format)) - return true; - return false; - } -} - -GLenum ConvertBackBufferFormat(D3DFORMAT format) -{ - switch (format) - { - case D3DFMT_A4R4G4B4: return GL_RGBA4; - case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; - case D3DFMT_A1R5G5B5: return GL_RGB5_A1; - case D3DFMT_R5G6B5: return GL_RGB565; - case D3DFMT_X8R8G8B8: return GL_RGB8_OES; - default: - UNREACHABLE(); - } - - return GL_RGBA4; -} - -GLenum ConvertDepthStencilFormat(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - { - return GL_DEPTH24_STENCIL8_OES; - } - switch (format) - { - case D3DFMT_D16: - case D3DFMT_D24X8: - return GL_DEPTH_COMPONENT16; - case D3DFMT_D24S8: - return GL_DEPTH24_STENCIL8_OES; - case D3DFMT_UNKNOWN: - return GL_NONE; - default: - UNREACHABLE(); - } - - return GL_DEPTH24_STENCIL8_OES; -} - -GLenum ConvertRenderTargetFormat(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - { - return GL_DEPTH24_STENCIL8_OES; - } - - switch (format) - { - case D3DFMT_A4R4G4B4: return GL_RGBA4; - case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; - case D3DFMT_A1R5G5B5: return GL_RGB5_A1; - case D3DFMT_R5G6B5: return GL_RGB565; - case D3DFMT_X8R8G8B8: return GL_RGB8_OES; - case D3DFMT_D16: - case D3DFMT_D24X8: - return GL_DEPTH_COMPONENT16; - case D3DFMT_D24S8: - return GL_DEPTH24_STENCIL8_OES; - case D3DFMT_UNKNOWN: - return GL_NONE; - default: - UNREACHABLE(); - } - - return GL_RGBA4; -} - -GLenum GetEquivalentFormat(D3DFORMAT format) -{ - if (format == D3DFMT_INTZ) - return GL_DEPTH24_STENCIL8_OES; - if (format == D3DFMT_NULL) - return GL_NONE; - - switch (format) - { - case D3DFMT_A4R4G4B4: return GL_RGBA4; - case D3DFMT_A8R8G8B8: return GL_RGBA8_OES; - case D3DFMT_A1R5G5B5: return GL_RGB5_A1; - case D3DFMT_R5G6B5: return GL_RGB565; - case D3DFMT_X8R8G8B8: return GL_RGB8_OES; - case D3DFMT_D16: return GL_DEPTH_COMPONENT16; - case D3DFMT_D24S8: return GL_DEPTH24_STENCIL8_OES; - case D3DFMT_UNKNOWN: return GL_NONE; - case D3DFMT_DXT1: return GL_COMPRESSED_RGBA_S3TC_DXT1_EXT; - case D3DFMT_DXT3: return GL_COMPRESSED_RGBA_S3TC_DXT3_ANGLE; - case D3DFMT_DXT5: return GL_COMPRESSED_RGBA_S3TC_DXT5_ANGLE; - case D3DFMT_A32B32G32R32F: return GL_RGBA32F_EXT; - case D3DFMT_A16B16G16R16F: return GL_RGBA16F_EXT; - case D3DFMT_L8: return GL_LUMINANCE8_EXT; - case D3DFMT_A8L8: return GL_LUMINANCE8_ALPHA8_EXT; - default: UNREACHABLE(); - return GL_NONE; - } -} - -} - -namespace d3d9 -{ - -bool IsCompressedFormat(D3DFORMAT surfaceFormat) -{ - switch(surfaceFormat) - { - case D3DFMT_DXT1: - case D3DFMT_DXT2: - case D3DFMT_DXT3: - case D3DFMT_DXT4: - case D3DFMT_DXT5: - return true; - default: - return false; - } -} - -size_t ComputeRowSize(D3DFORMAT format, unsigned int width) -{ - if (format == D3DFMT_INTZ) - { - return 4 * width; - } - switch (format) - { - case D3DFMT_L8: - return 1 * width; - case D3DFMT_A8L8: - return 2 * width; - case D3DFMT_X8R8G8B8: - case D3DFMT_A8R8G8B8: - return 4 * width; - case D3DFMT_A16B16G16R16F: - return 8 * width; - case D3DFMT_A32B32G32R32F: - return 16 * width; - case D3DFMT_DXT1: - return 8 * ((width + 3) / 4); - case D3DFMT_DXT3: - case D3DFMT_DXT5: - return 16 * ((width + 3) / 4); - default: - UNREACHABLE(); - return 0; - } -} - -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h b/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h deleted file mode 100644 index bf6cdf1ea6..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/renderer9_utils.h +++ /dev/null @@ -1,74 +0,0 @@ -// -// Copyright (c) 2002-2012 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. -// - -// renderer9_utils.h: Conversion functions and other utility routines -// specific to the D3D9 renderer - -#ifndef LIBGLESV2_RENDERER_RENDERER9_UTILS_H -#define LIBGLESV2_RENDERER_RENDERER9_UTILS_H - -#include "libGLESv2/utilities.h" - -const D3DFORMAT D3DFMT_INTZ = ((D3DFORMAT)(MAKEFOURCC('I','N','T','Z'))); -const D3DFORMAT D3DFMT_NULL = ((D3DFORMAT)(MAKEFOURCC('N','U','L','L'))); - -namespace gl_d3d9 -{ - -D3DCMPFUNC ConvertComparison(GLenum comparison); -D3DCOLOR ConvertColor(gl::Color color); -D3DBLEND ConvertBlendFunc(GLenum blend); -D3DBLENDOP ConvertBlendOp(GLenum blendOp); -D3DSTENCILOP ConvertStencilOp(GLenum stencilOp); -D3DTEXTUREADDRESS ConvertTextureWrap(GLenum wrap); -D3DCULL ConvertCullMode(GLenum 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 maxAnisotropy); -D3DFORMAT ConvertRenderbufferFormat(GLenum format); -D3DMULTISAMPLE_TYPE GetMultisampleTypeFromSamples(GLsizei samples); - -} - -namespace d3d9_gl -{ - -GLuint GetAlphaSize(D3DFORMAT colorFormat); -GLuint GetStencilSize(D3DFORMAT stencilFormat); - -GLsizei GetSamplesFromMultisampleType(D3DMULTISAMPLE_TYPE type); - -bool IsFormatChannelEquivalent(D3DFORMAT d3dformat, GLenum format); -GLenum ConvertBackBufferFormat(D3DFORMAT format); -GLenum ConvertDepthStencilFormat(D3DFORMAT format); -GLenum ConvertRenderTargetFormat(D3DFORMAT format); -GLenum GetEquivalentFormat(D3DFORMAT format); - -} - -namespace d3d9 -{ -bool IsCompressedFormat(D3DFORMAT format); -size_t ComputeRowSize(D3DFORMAT format, unsigned int width); - -inline bool isDeviceLostError(HRESULT errorCode) -{ - switch (errorCode) - { - case D3DERR_DRIVERINTERNALERROR: - case D3DERR_DEVICELOST: - case D3DERR_DEVICEHUNG: - case D3DERR_DEVICEREMOVED: - return true; - default: - return false; - } -} - -} - -#endif // LIBGLESV2_RENDERER_RENDERER9_UTILS_H diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps deleted file mode 100644 index dcb3bd0e76..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.ps +++ /dev/null @@ -1,39 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -sampler2D tex : s0; - -uniform float4 mode : c0; - -// Passthrough Pixel Shader -// Outputs texture 0 sampled at texcoord 0. -float4 passthroughps(float4 texcoord : TEXCOORD0) : COLOR -{ - return tex2D(tex, texcoord.xy); -}; - -// Luminance Conversion Pixel Shader -// Outputs sample(tex0, tc0).rrra. -// For LA output (pass A) set C0.X = 1, C0.Y = 0. -// For L output (A = 1) set C0.X = 0, C0.Y = 1. -float4 luminanceps(float4 texcoord : TEXCOORD0) : COLOR -{ - float4 tmp = tex2D(tex, texcoord.xy); - tmp.w = tmp.w * mode.x + mode.y; - return tmp.xxxw; -}; - -// RGB/A Component Mask Pixel Shader -// Outputs sample(tex0, tc0) with options to force RGB = 0 and/or A = 1. -// To force RGB = 0, set C0.X = 0, otherwise C0.X = 1. -// To force A = 1, set C0.Z = 0, C0.W = 1, otherwise C0.Z = 1, C0.W = 0. -float4 componentmaskps(float4 texcoord : TEXCOORD0) : COLOR -{ - float4 tmp = tex2D(tex, texcoord.xy); - tmp.xyz = tmp.xyz * mode.x; - tmp.w = tmp.w * mode.z + mode.w; - return tmp; -}; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs deleted file mode 100644 index 3a36980b93..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Blit.vs +++ /dev/null @@ -1,43 +0,0 @@ -// -// Copyright (c) 2012 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. -// - -struct VS_OUTPUT -{ - float4 position : POSITION; - float4 texcoord : TEXCOORD0; -}; - -uniform float4 halfPixelSize : c0; - -// Standard Vertex Shader -// Input 0 is the homogenous position. -// Outputs the homogenous position as-is. -// Outputs a tex coord with (0,0) in the upper-left corner of the screen and (1,1) in the bottom right. -// C0.X must be negative half-pixel width, C0.Y must be half-pixel height. C0.ZW must be 0. -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); - - return Out; -}; diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl deleted file mode 100644 index cb132dc99c..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Clear11.hlsl +++ /dev/null @@ -1,42 +0,0 @@ -void VS_Clear( in float3 inPosition : POSITION, in float4 inColor : COLOR, - out float4 outPosition : SV_POSITION, out float4 outColor : COLOR) -{ - outPosition = float4(inPosition, 1.0f); - outColor = inColor; -} - -// Assume we are in SM4+, which has 8 color outputs -struct PS_OutputMultiple -{ - float4 color0 : SV_TARGET0; - float4 color1 : SV_TARGET1; - float4 color2 : SV_TARGET2; - float4 color3 : SV_TARGET3; -#ifdef SM4 - float4 color4 : SV_TARGET4; - float4 color5 : SV_TARGET5; - float4 color6 : SV_TARGET6; - float4 color7 : SV_TARGET7; -#endif -}; - -PS_OutputMultiple PS_ClearMultiple(in float4 inPosition : SV_POSITION, in float4 inColor : COLOR) -{ - PS_OutputMultiple outColor; - outColor.color0 = inColor; - outColor.color1 = inColor; - outColor.color2 = inColor; - outColor.color3 = inColor; -#ifdef SM4 - outColor.color4 = inColor; - outColor.color5 = inColor; - outColor.color6 = inColor; - outColor.color7 = inColor; -#endif - return outColor; -} - -float4 PS_ClearSingle(in float4 inPosition : SV_Position, in float4 inColor : COLOR) : SV_Target0 -{ - return inColor; -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl b/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl deleted file mode 100644 index 43b7801efc..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/shaders/Passthrough11.hlsl +++ /dev/null @@ -1,29 +0,0 @@ -Texture2D Texture : register(t0); -SamplerState Sampler : register(s0); - -void VS_Passthrough( in float2 inPosition : POSITION, in float2 inTexCoord : TEXCOORD0, - out float4 outPosition : SV_POSITION, out float2 outTexCoord : TEXCOORD0) -{ - outPosition = float4(inPosition, 0.0f, 1.0f); - outTexCoord = inTexCoord; -} - -float4 PS_PassthroughRGBA(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return Texture.Sample(Sampler, inTexCoord).rgba; -} - -float4 PS_PassthroughRGB(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return float4(Texture.Sample(Sampler, inTexCoord).rgb, 1.0f); -} - -float4 PS_PassthroughLum(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return float4(Texture.Sample(Sampler, inTexCoord).rrr, 1.0f); -} - -float4 PS_PassthroughLumAlpha(in float4 inPosition : SV_POSITION, in float2 inTexCoord : TEXCOORD0) : SV_TARGET0 -{ - return Texture.Sample(Sampler, inTexCoord).rrra; -} diff --git a/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h b/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h deleted file mode 100644 index 590b9d48a3..0000000000 --- a/src/3rdparty/angle/src/libGLESv2/renderer/vertexconversion.h +++ /dev/null @@ -1,203 +0,0 @@ -// -// Copyright (c) 2002-2010 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. -// - -// vertexconversion.h: A library of vertex conversion classes that can be used to build -// the FormatConverter objects used by the buffer conversion system. - -#ifndef LIBGLESV2_VERTEXCONVERSION_H_ -#define LIBGLESV2_VERTEXCONVERSION_H_ - -namespace rx -{ - -// Conversion types: -// static const bool identity: true if this is an identity transform, false otherwise -// static U convert(T): convert a single element from the input type to the output type -// typedef ... OutputType: the type produced by this conversion - -template -struct Identity -{ - static const bool identity = true; - - typedef T OutputType; - - static T convert(T x) - { - return x; - } -}; - -template -struct Cast -{ - static const bool identity = false; - - typedef ToT OutputType; - - static ToT convert(FromT x) - { - return static_cast(x); - } -}; - -template -struct Cast -{ - static const bool identity = true; - - typedef T OutputType; - - static T convert(T x) - { - return static_cast(x); - } -}; - -template -struct Normalize -{ - static const bool identity = false; - - typedef float OutputType; - - static float convert(T x) - { - typedef std::numeric_limits NL; - float f = static_cast(x); - - if (NL::is_signed) - { - // const float => VC2008 computes it at compile time - // static const float => VC2008 computes it the first time we get here, stores it to memory with static guard and all that. - const float divisor = 1.0f/(2*static_cast(NL::max())+1); - return (2*f+1)*divisor; - } - else - { - return f/NL::max(); - } - } -}; - -template -struct FixedToFloat -{ - static const bool identity = false; - - typedef float OutputType; - - static float convert(FromType x) - { - const float divisor = 1.0f / static_cast(static_cast(1) << ScaleBits); - return static_cast(x) * divisor; - } -}; - -// Widen types: -// static const unsigned int initialWidth: number of components before conversion -// static const unsigned int finalWidth: number of components after conversion - -// Float is supported at any size. -template -struct NoWiden -{ - static const std::size_t initialWidth = N; - static const std::size_t finalWidth = N; -}; - -// SHORT, norm-SHORT, norm-UNSIGNED_SHORT are supported but only with 2 or 4 components -template -struct WidenToEven -{ - static const std::size_t initialWidth = N; - static const std::size_t finalWidth = N+(N&1); -}; - -template -struct WidenToFour -{ - static const std::size_t initialWidth = N; - static const std::size_t finalWidth = 4; -}; - -// Most types have 0 and 1 that are just that. -template -struct SimpleDefaultValues -{ - static T zero() { return static_cast(0); } - static T one() { return static_cast(1); } -}; - -// But normalised types only store [0,1] or [-1,1] so 1.0 is represented by the max value. -template -struct NormalizedDefaultValues -{ - static T zero() { return static_cast(0); } - static T one() { return std::numeric_limits::max(); } -}; - -// Converter: -// static const bool identity: true if this is an identity transform (with no widening) -// static const std::size_t finalSize: number of bytes per output vertex -// static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out): convert an array of vertices. Input may be strided, but output will be unstrided. - -template > -struct VertexDataConverter -{ - typedef typename Converter::OutputType OutputType; - typedef InT InputType; - - static const bool identity = (WidenRule::initialWidth == WidenRule::finalWidth) && Converter::identity; - static const std::size_t finalSize = WidenRule::finalWidth * sizeof(OutputType); - - static void convertArray(const InputType *in, std::size_t stride, std::size_t n, OutputType *out) - { - for (std::size_t i = 0; i < n; i++) - { - const InputType *ein = pointerAddBytes(in, i * stride); - - copyComponent(out, ein, 0, static_cast(DefaultValueRule::zero())); - copyComponent(out, ein, 1, static_cast(DefaultValueRule::zero())); - copyComponent(out, ein, 2, static_cast(DefaultValueRule::zero())); - copyComponent(out, ein, 3, static_cast(DefaultValueRule::one())); - - out += WidenRule::finalWidth; - } - } - - static void convertArray(const void *in, std::size_t stride, std::size_t n, void *out) - { - return convertArray(static_cast(in), stride, n, static_cast(out)); - } - - private: - // Advance the given pointer by a number of bytes (not pointed-to elements). - template - static T *pointerAddBytes(T *basePtr, std::size_t numBytes) - { - return reinterpret_cast(reinterpret_cast(basePtr) + numBytes); - } - - static void copyComponent(OutputType *out, const InputType *in, std::size_t elementindex, OutputType defaultvalue) - { - if (WidenRule::finalWidth > elementindex) - { - if (WidenRule::initialWidth > elementindex) - { - out[elementindex] = Converter::convert(in[elementindex]); - } - else - { - out[elementindex] = defaultvalue; - } - } - } -}; - -} - -#endif // LIBGLESV2_VERTEXCONVERSION_H_ diff --git a/src/3rdparty/angle/src/libGLESv2/utilities.cpp b/src/3rdparty/angle/src/libGLESv2/utilities.cpp index 8fd193b164..30765ffba0 100644 --- a/src/3rdparty/angle/src/libGLESv2/utilities.cpp +++ b/src/3rdparty/angle/src/libGLESv2/utilities.cpp @@ -9,13 +9,13 @@ #include "libGLESv2/utilities.h" #include "libGLESv2/mathutil.h" - #if defined(ANGLE_OS_WINRT) -#include -#include -#include -#include -using namespace ABI::Windows::Storage; +# include +# include +# include +# include + using namespace Microsoft::WRL; + using namespace ABI::Windows::Storage; #endif namespace gl @@ -745,29 +745,43 @@ bool IsTriangleMode(GLenum drawMode) std::string getTempPath() { -#if defined(ANGLE_OS_WINRT) +#if !defined(ANGLE_OS_WINRT) + char path[MAX_PATH]; + DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); + if (pathLen == 0) + { + UNREACHABLE(); + return std::string(); + } + UINT unique = GetTempFileNameA(path, "sh", 0, path); + if (unique == 0) + { + UNREACHABLE(); + return std::string(); + } +#else static std::string path; while (path.empty()) { - IApplicationDataStatics *applicationDataFactory; - HRESULT result = RoGetActivationFactory(Microsoft::WRL::Wrappers::HStringReference(RuntimeClass_Windows_Storage_ApplicationData).Get(), - IID_PPV_ARGS(&applicationDataFactory)); + ComPtr factory; + Wrappers::HStringReference classId(RuntimeClass_Windows_Storage_ApplicationData); + HRESULT result = RoGetActivationFactory(classId.Get(), IID_PPV_ARGS(&factory)); if (FAILED(result)) break; - IApplicationData *applicationData; - result = applicationDataFactory->get_Current(&applicationData); + ComPtr applicationData; + result = factory->get_Current(&applicationData); if (FAILED(result)) break; - IStorageFolder *storageFolder; + ComPtr storageFolder; result = applicationData->get_LocalFolder(&storageFolder); if (FAILED(result)) break; - IStorageItem *localFolder; - result = storageFolder->QueryInterface(IID_PPV_ARGS(&localFolder)); + ComPtr localFolder; + result = storageFolder.As(&localFolder); if (FAILED(result)) break; @@ -784,25 +798,6 @@ std::string getTempPath() break; } } - -#else - - char path[MAX_PATH]; - - DWORD pathLen = GetTempPathA(sizeof(path) / sizeof(path[0]), path); - if (pathLen == 0) - { - UNREACHABLE(); - return std::string(); - } - - UINT unique = GetTempFileNameA(path, "sh", 0, path); - if (unique == 0) - { - UNREACHABLE(); - return std::string(); - } - #endif return path; -- cgit v1.2.3