diff options
| author | assiduous <assiduous@diligentgraphics.com> | 2019-12-16 05:31:46 +0000 |
|---|---|---|
| committer | assiduous <assiduous@diligentgraphics.com> | 2019-12-16 05:31:46 +0000 |
| commit | 05d9bfb4dd6d94d4ef80f582305aa383da295483 (patch) | |
| tree | 62773b4ea6a96883cba2322dd11d8001178d1365 /UnitTests | |
| parent | readme: added codacy bage (diff) | |
| download | DiligentCore-05d9bfb4dd6d94d4ef80f582305aa383da295483.tar.gz DiligentCore-05d9bfb4dd6d94d4ef80f582305aa383da295483.zip | |
Added testing framework for rendering commands. Added initial draw command test in D3D11 and D3D12
Diffstat (limited to 'UnitTests')
56 files changed, 2727 insertions, 27 deletions
diff --git a/UnitTests/DiligentCoreAPITest/CMakeLists.txt b/UnitTests/DiligentCoreAPITest/CMakeLists.txt index 7e96699f..aa786314 100644 --- a/UnitTests/DiligentCoreAPITest/CMakeLists.txt +++ b/UnitTests/DiligentCoreAPITest/CMakeLists.txt @@ -38,6 +38,13 @@ if(PLATFORM_WIN32) list(APPEND SOURCE ${SOURCE_WIN32}) endif() +if(D3D11_SUPPORTED) + file(GLOB D3D11_SOURCE LIST_DIRECTORIES false src/D3D11/*) + file(GLOB D3D11_INCLUDE LIST_DIRECTORIES false include/D3D11/*) + list(APPEND INCLUDE ${D3D11_INCLUDE}) + list(APPEND SOURCE ${D3D11_SOURCE}) +endif() + if(D3D12_SUPPORTED) file(GLOB D3D12_SOURCE LIST_DIRECTORIES false src/D3D12/*) file(GLOB D3D12_INCLUDE LIST_DIRECTORIES false include/D3D12/*) @@ -45,6 +52,19 @@ if(D3D12_SUPPORTED) list(APPEND SOURCE ${D3D12_SOURCE}) endif() +if(VULKAN_SUPPORTED) + file(GLOB VK_SOURCE LIST_DIRECTORIES false src/Vulkan/*) + file(GLOB VK_INCLUDE LIST_DIRECTORIES false include/Vulkan/*) + list(APPEND INCLUDE ${VK_INCLUDE}) + list(APPEND SOURCE ${VK_SOURCE}) +endif() + +if(GL_SUPPORTED OR GLES_SUPPORTED) + file(GLOB GL_SOURCE LIST_DIRECTORIES false src/GL/*) + file(GLOB GL_INCLUDE LIST_DIRECTORIES false include/GL/*) + list(APPEND INCLUDE ${GL_INCLUDE}) + list(APPEND SOURCE ${GL_SOURCE}) +endif() add_executable(DiligentCoreAPITest ${SOURCE} ${INCLUDE} ${SHADERS}) set_common_target_properties(DiligentCoreAPITest) @@ -62,6 +82,10 @@ PRIVATE ${ENGINE_LIBRARIES} ) +if(D3D11_SUPPORTED OR D3D12_SUPPORTED) + target_link_libraries(DiligentCoreAPITest PRIVATE d3dcompiler.lib) +endif() + if(GL_SUPPORTED OR GLES_SUPPORTED) target_link_libraries(DiligentCoreAPITest PRIVATE Diligent-HLSL2GLSLConverterLib) endif() diff --git a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResTestBase.h b/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResTestBase.h index 5f9f23f8..4e6bfc25 100644 --- a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResTestBase.h +++ b/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResTestBase.h @@ -31,6 +31,9 @@ namespace Diligent { +namespace Testing +{ + class CreateObjFromNativeResTestBase { public: @@ -47,4 +50,6 @@ protected: RefCntAutoPtr<IRenderDevice> m_pDevice; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResD3D11.h b/UnitTests/DiligentCoreAPITest/include/D3D11/CreateObjFromNativeResD3D11.h index 2dad233b..579ed6aa 100644 --- a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResD3D11.h +++ b/UnitTests/DiligentCoreAPITest/include/D3D11/CreateObjFromNativeResD3D11.h @@ -28,6 +28,9 @@ namespace Diligent { +namespace Testing +{ + class TestCreateObjFromNativeResD3D11 : public CreateObjFromNativeResTestBase { public: @@ -39,4 +42,6 @@ public: virtual void CreateBuffer(IBuffer* pBuffer) override final; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/D3D11/TestingEnvironmentD3D11.h b/UnitTests/DiligentCoreAPITest/include/D3D11/TestingEnvironmentD3D11.h new file mode 100644 index 00000000..7d5b883c --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/D3D11/TestingEnvironmentD3D11.h @@ -0,0 +1,115 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TestingEnvironment.h" + +#ifndef NOMINMAX +# define NOMINMAX +#endif + +#include <d3d11.h> +#include <atlcomcli.h> + +namespace Diligent +{ + +namespace Testing +{ + +HRESULT CompileD3DShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile, + ID3DBlob** ppBlobOut); + +class TestingEnvironmentD3D11 final : public TestingEnvironment +{ +public: + TestingEnvironmentD3D11(DeviceType deviceType, ADAPTER_TYPE AdapterType); + + ID3D11Device* GetD3D11Device() + { + return m_pd3d11Device; + } + + ID3D11DeviceContext* GetD3D11Context() + { + return m_pd3d11Context; + } + + ID3D11RasterizerState* GetNoCullRS() + { + return m_pd3d11NoCullRS; + } + + ID3D11DepthStencilState* GetDisableDepthDSS() + { + return m_pd3d11DisableDepthDSS; + } + + ID3D11BlendState* GetDefaultBS() + { + return m_pd3d11DefaultBS; + } + + CComPtr<ID3D11VertexShader> CreateVertexShader(const char* Source, + LPCSTR strFunctionName = "main", + const D3D_SHADER_MACRO* pDefines = nullptr, + LPCSTR profile = "vs_5_0"); + + CComPtr<ID3D11PixelShader> CreatePixelShader(const char* Source, + LPCSTR strFunctionName = "main", + const D3D_SHADER_MACRO* pDefines = nullptr, + LPCSTR profile = "ps_5_0"); + + CComPtr<ID3D11GeometryShader> CreateGeometryShader(const char* Source, + LPCSTR strFunctionName = "main", + const D3D_SHADER_MACRO* pDefines = nullptr, + LPCSTR profile = "gs_5_0"); + + CComPtr<ID3D11DomainShader> CreateDomainShader(const char* Source, + LPCSTR strFunctionName = "main", + const D3D_SHADER_MACRO* pDefines = nullptr, + LPCSTR profile = "ds_5_0"); + + CComPtr<ID3D11HullShader> CreateHullShader(const char* Source, + LPCSTR strFunctionName = "main", + const D3D_SHADER_MACRO* pDefines = nullptr, + LPCSTR profile = "gs_5_0"); + + static TestingEnvironmentD3D11* GetInstance() { return ValidatedCast<TestingEnvironmentD3D11>(TestingEnvironment::GetInstance()); } + +private: + CComPtr<ID3D11Device> m_pd3d11Device; + CComPtr<ID3D11DeviceContext> m_pd3d11Context; + + CComPtr<ID3D11RasterizerState> m_pd3d11NoCullRS; + CComPtr<ID3D11DepthStencilState> m_pd3d11DisableDepthDSS; + CComPtr<ID3D11BlendState> m_pd3d11DefaultBS; +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/D3D11/TestingSwapChainD3D11.h b/UnitTests/DiligentCoreAPITest/include/D3D11/TestingSwapChainD3D11.h new file mode 100644 index 00000000..33815257 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/D3D11/TestingSwapChainD3D11.h @@ -0,0 +1,81 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "TestingSwapChainBase.h" + +#ifndef NOMINMAX +# define NOMINMAX +#endif + +#include <d3d11.h> +#include <atlcomcli.h> + +namespace Diligent +{ + +namespace Testing +{ + +class TestingSwapChainD3D11 final : public TestingSwapChainBase<ISwapChain> +{ +public: + using TBase = TestingSwapChainBase<ISwapChain>; + TestingSwapChainD3D11(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc); + + virtual void TakeSnapshot() override final; + + ID3D11Texture2D* GetD3D11RenderTarget() + { + return m_pd3d11RenderTarget; + } + + ID3D11Texture2D* GetD3D11DepthBuffer() + { + return m_pd3d11DepthBuffer; + } + + ID3D11RenderTargetView* GetD3D11RTV() + { + return m_pd3d11RTV; + } + + ID3D11DepthStencilView* GetD3D11DSV() + { + return m_pd3d11DSV; + } + +private: + CComPtr<ID3D11DeviceContext> m_pd3d11Context; + CComPtr<ID3D11Texture2D> m_pd3d11RenderTarget; + CComPtr<ID3D11Texture2D> m_pd3d11DepthBuffer; + CComPtr<ID3D11RenderTargetView> m_pd3d11RTV; + CComPtr<ID3D11DepthStencilView> m_pd3d11DSV; + CComPtr<ID3D11Texture2D> m_pd3d11StagingTex; +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResD3D12.h b/UnitTests/DiligentCoreAPITest/include/D3D12/CreateObjFromNativeResD3D12.h index 96a47004..b00c9676 100644 --- a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResD3D12.h +++ b/UnitTests/DiligentCoreAPITest/include/D3D12/CreateObjFromNativeResD3D12.h @@ -28,6 +28,9 @@ namespace Diligent { +namespace Testing +{ + class TestCreateObjFromNativeResD3D12 : public CreateObjFromNativeResTestBase { public: @@ -39,4 +42,6 @@ public: virtual void CreateBuffer(IBuffer* pBuffer) override final; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/D3D12/D3D12DebugLayerSetNameBugWorkaround.h b/UnitTests/DiligentCoreAPITest/include/D3D12/D3D12DebugLayerSetNameBugWorkaround.h index 9243cdf7..a2d06acb 100644 --- a/UnitTests/DiligentCoreAPITest/include/D3D12/D3D12DebugLayerSetNameBugWorkaround.h +++ b/UnitTests/DiligentCoreAPITest/include/D3D12/D3D12DebugLayerSetNameBugWorkaround.h @@ -28,6 +28,9 @@ namespace Diligent { +namespace Testing +{ + // There is a bug in D3D12 debug layer as of build version 10.0.18362: SetName() method // is not protected by a mutex internally. This, in combination with the fact that root signatures are // de-duplicated by D3D12 runtime, causes the following problem: @@ -49,4 +52,6 @@ private: std::unique_ptr<RootSignatureWrapper> m_RootSignature; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/D3D12/TestingEnvironmentD3D12.h b/UnitTests/DiligentCoreAPITest/include/D3D12/TestingEnvironmentD3D12.h new file mode 100644 index 00000000..1d042e12 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/D3D12/TestingEnvironmentD3D12.h @@ -0,0 +1,79 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TestingEnvironment.h" + +#ifndef NOMINMAX +# define NOMINMAX +#endif + +#include <d3d12.h> +#include <d3dcompiler.h> +#include <atlcomcli.h> + +namespace Diligent +{ + +namespace Testing +{ + +// Implemented in TestingEnvironmentD3D11.cpp +HRESULT CompileD3DShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile, + ID3DBlob** ppBlobOut); + +class TestingEnvironmentD3D12 final : public TestingEnvironment +{ +public: + TestingEnvironmentD3D12(DeviceType deviceType, ADAPTER_TYPE AdapterType); + ~TestingEnvironmentD3D12(); + + static TestingEnvironmentD3D12* GetInstance() { return ValidatedCast<TestingEnvironmentD3D12>(TestingEnvironment::GetInstance()); } + + ID3D12Device* GetD3D12Device() + { + return m_pd3d12Device; + } + + // The allocator is currently never reset, which is not an issue in this testing system. + CComPtr<ID3D12GraphicsCommandList> CreateGraphicsCommandList(); + + void IdleCommandQueue(ID3D12CommandQueue* pd3d12Queue); + +private: + CComPtr<ID3D12Device> m_pd3d12Device; + CComPtr<ID3D12CommandAllocator> m_pd3d12CmdAllocator; + CComPtr<ID3D12Fence> m_pd3d12Fence; + + UINT64 m_NextFenceValue = 1; + + HANDLE m_WaitForGPUEventHandle = {}; +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/D3D12/TestingSwapChainD3D12.h b/UnitTests/DiligentCoreAPITest/include/D3D12/TestingSwapChainD3D12.h new file mode 100644 index 00000000..3eb1549e --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/D3D12/TestingSwapChainD3D12.h @@ -0,0 +1,87 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "TestingSwapChainBase.h" + +#ifndef NOMINMAX +# define NOMINMAX +#endif + +#include <d3d12.h> +#include <atlcomcli.h> + +namespace Diligent +{ + +namespace Testing +{ + +class TestingSwapChainD3D12 : public TestingSwapChainBase<ISwapChain> +{ +public: + using TBase = TestingSwapChainBase<ISwapChain>; + TestingSwapChainD3D12(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc); + + virtual void TakeSnapshot() override final; + + void TransitionRenderTarget(ID3D12GraphicsCommandList* pCmdList, + D3D12_RESOURCE_STATES RTVState); + + void TransitionBuffers(ID3D12GraphicsCommandList* pCmdList, + D3D12_RESOURCE_STATES RTVState, + D3D12_RESOURCE_STATES DSVState); + + D3D12_CPU_DESCRIPTOR_HANDLE GetRTVDescriptorHandle() + { + return m_RTVDescriptorHandle; + } + + D3D12_CPU_DESCRIPTOR_HANDLE GetDSVDescriptorHandle() + { + return m_DSVDescriptorHandle; + } + +private: + CComPtr<ID3D12Resource> m_pd3d12RenderTaget; + CComPtr<ID3D12Resource> m_pd3d12DepthBuffer; + CComPtr<ID3D12Resource> m_pd3d12StagingBuffer; + + CComPtr<ID3D12DescriptorHeap> m_pd3d12RTVDescriptorHeap; + CComPtr<ID3D12DescriptorHeap> m_pd3d12DSVDescriptorHeap; + + D3D12_RESOURCE_STATES m_RenderTargetState = D3D12_RESOURCE_STATE_RENDER_TARGET; + D3D12_RESOURCE_STATES m_DepthBufferState = D3D12_RESOURCE_STATE_DEPTH_WRITE; + + D3D12_CPU_DESCRIPTOR_HANDLE m_RTVDescriptorHandle = {}; + D3D12_CPU_DESCRIPTOR_HANDLE m_DSVDescriptorHandle = {}; + + D3D12_PLACED_SUBRESOURCE_FOOTPRINT m_StagingBufferFootprint = {}; + UINT64 m_StagingBufferSize = 0; +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResGL.h b/UnitTests/DiligentCoreAPITest/include/GL/CreateObjFromNativeResGL.h index decfc131..2584e426 100644 --- a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResGL.h +++ b/UnitTests/DiligentCoreAPITest/include/GL/CreateObjFromNativeResGL.h @@ -28,6 +28,9 @@ namespace Diligent { +namespace Testing +{ + class TestCreateObjFromNativeResGL : public CreateObjFromNativeResTestBase { public: @@ -39,4 +42,6 @@ public: virtual void CreateBuffer(IBuffer* pBuffer) override final; }; +} // namespace Testing + } // namespace Diligent
\ No newline at end of file diff --git a/UnitTests/DiligentCoreAPITest/include/GL/TestingEnvironmentGL.h b/UnitTests/DiligentCoreAPITest/include/GL/TestingEnvironmentGL.h new file mode 100644 index 00000000..b8d7d9e6 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/GL/TestingEnvironmentGL.h @@ -0,0 +1,46 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TestingEnvironment.h" + +namespace Diligent +{ + +namespace Testing +{ + +class TestingEnvironmentGL final : public TestingEnvironment +{ +public: + TestingEnvironmentGL(DeviceType deviceType, ADAPTER_TYPE AdapterType); + + static TestingEnvironmentGL* GetInstance() { return ValidatedCast<TestingEnvironmentGL>(TestingEnvironment::GetInstance()); } + +private: +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/GL/TestingSwapChainGL.h b/UnitTests/DiligentCoreAPITest/include/GL/TestingSwapChainGL.h new file mode 100644 index 00000000..3a5058e8 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/GL/TestingSwapChainGL.h @@ -0,0 +1,48 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "TestingSwapChainBase.h" + +namespace Diligent +{ + +namespace Testing +{ + +class TestingSwapChainGL : public TestingSwapChainBase<ISwapChain> +{ +public: + using TBase = TestingSwapChainBase<ISwapChain>; + TestingSwapChainGL(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc); + + virtual void TakeSnapshot() override final; + +private: +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/PSOTestBase.h b/UnitTests/DiligentCoreAPITest/include/PSOTestBase.h index afd75881..a66a5cf6 100644 --- a/UnitTests/DiligentCoreAPITest/include/PSOTestBase.h +++ b/UnitTests/DiligentCoreAPITest/include/PSOTestBase.h @@ -29,6 +29,9 @@ namespace Diligent { +namespace Testing +{ + class PSOTestBase { protected: @@ -54,4 +57,6 @@ private: static Resources sm_Resources; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/TestingEnvironment.h b/UnitTests/DiligentCoreAPITest/include/TestingEnvironment.h index bb3d1025..f2440987 100644 --- a/UnitTests/DiligentCoreAPITest/include/TestingEnvironment.h +++ b/UnitTests/DiligentCoreAPITest/include/TestingEnvironment.h @@ -21,6 +21,8 @@ * of the possibility of such damages. */ +#pragma once + #include <atomic> #include "RenderDevice.h" @@ -34,7 +36,10 @@ namespace Diligent { -class TestingEnvironment final : public ::testing::Environment +namespace Testing +{ + +class TestingEnvironment : public ::testing::Environment { public: struct NativeWindow @@ -82,6 +87,7 @@ public: IRenderDevice* GetDevice() { return m_pDevice; } IDeviceContext* GetDeviceContext() { return m_pDeviceContext; } + ISwapChain* GetSwapChain() { return m_pSwapChain; } static TestingEnvironment* GetInstance() { return m_pTheEnvironment; } @@ -89,8 +95,7 @@ public: static void SetErrorAllowance(int NumErrorsToAllow, const char* InfoMessage = nullptr); - -private: +protected: NativeWindow CreateNativeWindow(); static void MessageCallback(DebugMessageSeverity Severity, @@ -110,4 +115,6 @@ private: static std::atomic_int m_NumAllowedErrors; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/TestingSwapChainBase.h b/UnitTests/DiligentCoreAPITest/include/TestingSwapChainBase.h new file mode 100644 index 00000000..3191f6c8 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/TestingSwapChainBase.h @@ -0,0 +1,213 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include <vector> + +#include "ObjectBase.h" +#include "RefCntAutoPtr.h" +#include "RenderDevice.h" +#include "DeviceContext.h" +#include "SwapChain.h" +#include "Texture.h" +#include "TextureView.h" +#include "TestingEnvironment.h" + +namespace Diligent +{ + +namespace Testing +{ + +void CompareTestImages(const Uint8* pReferencePixels, + Uint32 RefPixelsStride, + const Uint8* pPixels, + Uint32 PixelsStride, + Uint32 Width, + Uint32 Height, + TEXTURE_FORMAT Format); + +// {41BF4655-9B33-4E6C-9300-0CB45FBFE104} +static constexpr INTERFACE_ID IID_TestingSwapChain = + {0x41bf4655, 0x9b33, 0x4e6c, {0x93, 0x0, 0xc, 0xb4, 0x5f, 0xbf, 0xe1, 0x4}}; + +class ITestingSwapChain : public IObject +{ +public: + virtual void TakeSnapshot() = 0; +}; + +template <typename SwapChainInterface> +class SwapChainCombinedBaseInterface : public ITestingSwapChain, public SwapChainInterface +{}; + +template <class TSwapChainInterface> +class TestingSwapChainBase : public RefCountedObject<SwapChainCombinedBaseInterface<TSwapChainInterface>> +{ +public: + using TObjectBase = RefCountedObject<SwapChainCombinedBaseInterface<TSwapChainInterface>>; + + TestingSwapChainBase(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc) : + TObjectBase{pRefCounters}, + m_pDevice{pDevice}, + m_pContext{pContext}, + m_SwapChainDesc{SCDesc} + { + VERIFY_EXPR(m_SwapChainDesc.ColorBufferFormat != TEX_FORMAT_UNKNOWN); + VERIFY_EXPR(m_SwapChainDesc.Width != 0); + VERIFY_EXPR(m_SwapChainDesc.Height != 0); + + { + TextureDesc RenderTargetDesc; + RenderTargetDesc.Name = "Testing color buffer"; + RenderTargetDesc.Type = RESOURCE_DIM_TEX_2D; + RenderTargetDesc.Width = m_SwapChainDesc.Width; + RenderTargetDesc.Height = m_SwapChainDesc.Height; + RenderTargetDesc.Format = m_SwapChainDesc.ColorBufferFormat; + RenderTargetDesc.SampleCount = 1; + RenderTargetDesc.Usage = USAGE_DEFAULT; + RenderTargetDesc.BindFlags = BIND_RENDER_TARGET; + m_pDevice->CreateTexture(RenderTargetDesc, nullptr, static_cast<ITexture**>(&m_pRenderTarget)); + VERIFY_EXPR(m_pRenderTarget != nullptr); + m_pRTV = m_pRenderTarget->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET); + VERIFY_EXPR(m_pRTV != nullptr); + + RenderTargetDesc.Usage = USAGE_STAGING; + RenderTargetDesc.CPUAccessFlags = CPU_ACCESS_READ; + RenderTargetDesc.BindFlags = BIND_NONE; + m_pDevice->CreateTexture(RenderTargetDesc, nullptr, static_cast<ITexture**>(&m_pStagingTexture)); + } + + if (m_SwapChainDesc.DepthBufferFormat != TEX_FORMAT_UNKNOWN) + { + TextureDesc DepthBufferDesc; + DepthBufferDesc.Name = "Testing depth buffer"; + DepthBufferDesc.Type = RESOURCE_DIM_TEX_2D; + DepthBufferDesc.Width = m_SwapChainDesc.Width; + DepthBufferDesc.Height = m_SwapChainDesc.Height; + DepthBufferDesc.Format = m_SwapChainDesc.DepthBufferFormat; + DepthBufferDesc.SampleCount = 1; + DepthBufferDesc.Usage = USAGE_DEFAULT; + DepthBufferDesc.BindFlags = BIND_DEPTH_STENCIL; + + DepthBufferDesc.ClearValue.Format = DepthBufferDesc.Format; + DepthBufferDesc.ClearValue.DepthStencil.Depth = m_SwapChainDesc.DefaultDepthValue; + DepthBufferDesc.ClearValue.DepthStencil.Stencil = m_SwapChainDesc.DefaultStencilValue; + + m_pDevice->CreateTexture(DepthBufferDesc, nullptr, &m_pDepthBuffer); + VERIFY_EXPR(m_pDepthBuffer != nullptr); + m_pDSV = m_pDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL); + VERIFY_EXPR(m_pDSV != nullptr); + } + } + + void QueryInterface(const INTERFACE_ID& IID, IObject** ppInterface) + { + if (ppInterface == nullptr) + return; + + if (IID == IID_SwapChain || IID == IID_Unknown) + { + *ppInterface = static_cast<TSwapChainInterface*>(this); + (*ppInterface)->AddRef(); + } + if (IID == IID_TestingSwapChain) + { + *ppInterface = static_cast<ITestingSwapChain*>(this); + (*ppInterface)->AddRef(); + } + } + + virtual void Present(Uint32 SyncInterval = 1) override + { + CopyTextureAttribs CopyInfo // + { + m_pRenderTarget, + RESOURCE_STATE_TRANSITION_MODE_TRANSITION, + m_pStagingTexture, + RESOURCE_STATE_TRANSITION_MODE_TRANSITION // + }; + m_pContext->CopyTexture(CopyInfo); + m_pContext->WaitForIdle(); + MappedTextureSubresource MapData; + m_pContext->MapTextureSubresource(m_pStagingTexture, 0, 0, MAP_READ, MAP_FLAG_DO_NOT_SYNCHRONIZE, nullptr, MapData); + CompareTestImages(m_ReferenceData.data(), m_ReferenceDataPitch, reinterpret_cast<const Uint8*>(MapData.pData), MapData.Stride, + m_SwapChainDesc.Width, m_SwapChainDesc.Height, m_SwapChainDesc.ColorBufferFormat); + + m_pContext->UnmapTextureSubresource(m_pStagingTexture, 0, 0); + } + + virtual void Resize(Uint32 NewWidth, Uint32 NewHeight) override final + { + UNEXPECTED("Resizing testing swap chains is not supported"); + } + + virtual void SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final + { + UNEXPECTED("Testing swap chain can't go into full screen mode"); + } + + virtual void SetWindowedMode() override final + { + UNEXPECTED("Testing swap chain can't switch between windowed and full screen modes"); + } + + virtual ITextureView* GetCurrentBackBufferRTV() override final + { + return m_pRTV; + } + + virtual ITextureView* GetDepthBufferDSV() override final + { + return m_pDSV; + } + + virtual const SwapChainDesc& GetDesc() const override final + { + return m_SwapChainDesc; + } + +protected: + const SwapChainDesc m_SwapChainDesc; + RefCntAutoPtr<IRenderDevice> m_pDevice; + RefCntAutoPtr<IDeviceContext> m_pContext; + RefCntAutoPtr<ITexture> m_pRenderTarget; + RefCntAutoPtr<ITexture> m_pDepthBuffer; + RefCntAutoPtr<ITextureView> m_pRTV; + RefCntAutoPtr<ITextureView> m_pDSV; + RefCntAutoPtr<ITexture> m_pStagingTexture; + + std::vector<Uint8> m_ReferenceData; + Uint32 m_ReferenceDataPitch = 0; +}; + +void CreateTestingSwapChain(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain); + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResVK.h b/UnitTests/DiligentCoreAPITest/include/Vulkan/CreateObjFromNativeResVK.h index 4db3bd8e..f3b36403 100644 --- a/UnitTests/DiligentCoreAPITest/include/CreateObjFromNativeResVK.h +++ b/UnitTests/DiligentCoreAPITest/include/Vulkan/CreateObjFromNativeResVK.h @@ -28,6 +28,8 @@ namespace Diligent { +namespace Testing +{ class TestCreateObjFromNativeResVK : public CreateObjFromNativeResTestBase { @@ -40,4 +42,6 @@ public: virtual void CreateBuffer(IBuffer* pBuffer) override final; }; +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/Vulkan/TestingEnvironmentVk.h b/UnitTests/DiligentCoreAPITest/include/Vulkan/TestingEnvironmentVk.h new file mode 100644 index 00000000..14334a83 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/Vulkan/TestingEnvironmentVk.h @@ -0,0 +1,46 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#pragma once + +#include "TestingEnvironment.h" + +namespace Diligent +{ + +namespace Testing +{ + +class TestingEnvironmentVk final : public TestingEnvironment +{ +public: + TestingEnvironmentVk(DeviceType deviceType, ADAPTER_TYPE AdapterType); + + static TestingEnvironmentVk* GetInstance() { return ValidatedCast<TestingEnvironmentVk>(TestingEnvironment::GetInstance()); } + +private: +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/include/Vulkan/TestingSwapChainVk.h b/UnitTests/DiligentCoreAPITest/include/Vulkan/TestingSwapChainVk.h new file mode 100644 index 00000000..e4261e69 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/include/Vulkan/TestingSwapChainVk.h @@ -0,0 +1,48 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "TestingSwapChainBase.h" + +namespace Diligent +{ + +namespace Testing +{ + +class TestingSwapChainVk : public TestingSwapChainBase<ISwapChain> +{ +public: + using TBase = TestingSwapChainBase<ISwapChain>; + TestingSwapChainVk(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc); + + virtual void TakeSnapshot() override final; + +private: +}; + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/BlendStateTest.cpp b/UnitTests/DiligentCoreAPITest/src/BlendStateTest.cpp index b033b136..7a33f10f 100644 --- a/UnitTests/DiligentCoreAPITest/src/BlendStateTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/BlendStateTest.cpp @@ -29,6 +29,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/BrokenShaderTest.cpp b/UnitTests/DiligentCoreAPITest/src/BrokenShaderTest.cpp index bacaaf45..d6eed1cd 100644 --- a/UnitTests/DiligentCoreAPITest/src/BrokenShaderTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/BrokenShaderTest.cpp @@ -26,6 +26,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/BufferCreationTest.cpp b/UnitTests/DiligentCoreAPITest/src/BufferCreationTest.cpp index 03ca4710..3af7125c 100644 --- a/UnitTests/DiligentCoreAPITest/src/BufferCreationTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/BufferCreationTest.cpp @@ -22,19 +22,19 @@ */ #if D3D11_SUPPORTED -# include "CreateObjFromNativeResD3D11.h" +# include "D3D11/CreateObjFromNativeResD3D11.h" #endif #if D3D12_SUPPORTED -# include "CreateObjFromNativeResD3D12.h" +# include "D3D12/CreateObjFromNativeResD3D12.h" #endif #if GL_SUPPORTED || GLES_SUPPORTED -# include "CreateObjFromNativeResGL.h" +# include "GL/CreateObjFromNativeResGL.h" #endif #if VULKAN_SUPPORTED -# include "CreateObjFromNativeResVK.h" +# include "Vulkan/CreateObjFromNativeResVK.h" #endif #include "GraphicsAccessories.h" @@ -44,6 +44,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResD3D11.cpp b/UnitTests/DiligentCoreAPITest/src/D3D11/CreateObjFromNativeResD3D11.cpp index 407c4939..08b9b6fd 100644 --- a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResD3D11.cpp +++ b/UnitTests/DiligentCoreAPITest/src/D3D11/CreateObjFromNativeResD3D11.cpp @@ -21,7 +21,7 @@ * of the possibility of such damages. */ -#include "CreateObjFromNativeResD3D11.h" +#include "D3D11/CreateObjFromNativeResD3D11.h" #include <d3d11.h> #include "RenderDeviceD3D11.h" @@ -34,6 +34,9 @@ namespace Diligent { +namespace Testing +{ + void TestCreateObjFromNativeResD3D11::CreateTexture(ITexture* pTexture) { RefCntAutoPtr<IRenderDeviceD3D11> pDeviceD3D11(m_pDevice, IID_RenderDeviceD3D11); @@ -128,4 +131,6 @@ void TestCreateObjFromNativeResD3D11::CreateBuffer(IBuffer* pBuffer) } } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D11/DrawCommandRefenceD3D11.cpp b/UnitTests/DiligentCoreAPITest/src/D3D11/DrawCommandRefenceD3D11.cpp new file mode 100644 index 00000000..7ed16a68 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/D3D11/DrawCommandRefenceD3D11.cpp @@ -0,0 +1,119 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "D3D11/TestingEnvironmentD3D11.h" +#include "D3D11/TestingSwapChainD3D11.h" + +namespace Diligent +{ + +namespace Testing +{ + +static const char* VSSource = R"( +struct PSInput +{ + float4 Pos : SV_POSITION; + float3 Color : COLOR; +}; + +void main(in uint VertId : SV_VertexID, + out PSInput PSIn) +{ + float4 Pos[3]; + Pos[0] = float4(-0.5, -0.5, 0.0, 1.0); + Pos[1] = float4( 0.0, +0.5, 0.0, 1.0); + Pos[2] = float4(+0.5, -0.5, 0.0, 1.0); + + float3 Col[3]; + Col[0] = float3(1.0, 0.0, 0.0); // red + Col[1] = float3(0.0, 1.0, 0.0); // green + Col[2] = float3(0.0, 0.0, 1.0); // blue + + PSIn.Pos = Pos[VertId]; + PSIn.Color = Col[VertId]; +} +)"; + +static const char* PSSource = R"( +struct PSInput +{ + float4 Pos : SV_POSITION; + float3 Color : COLOR; +}; + +struct PSOutput +{ + float4 Color : SV_TARGET; +}; + +void main(in PSInput PSIn, + out PSOutput PSOut) +{ + PSOut.Color = float4(PSIn.Color.rgb, 1.0); +} +)"; + +void RenderDrawCommandRefenceTriangleD3D11(ISwapChain* pSwapChain) +{ + auto* pEnvD3D11 = TestingEnvironmentD3D11::GetInstance(); + auto* pd3d11Context = pEnvD3D11->GetD3D11Context(); + auto* pTestingSwapChainD3D11 = ValidatedCast<TestingSwapChainD3D11>(pSwapChain); + + pd3d11Context->ClearState(); + + auto pVS = pEnvD3D11->CreateVertexShader(VSSource); + ASSERT_NE(pVS, nullptr); + + auto pPS = pEnvD3D11->CreatePixelShader(PSSource); + ASSERT_NE(pPS, nullptr); + + pd3d11Context->VSSetShader(pVS, nullptr, 0); + pd3d11Context->PSSetShader(pPS, nullptr, 0); + pd3d11Context->RSSetState(pEnvD3D11->GetNoCullRS()); + pd3d11Context->OMSetBlendState(pEnvD3D11->GetDefaultBS(), nullptr, 0xFFFFFFFF); + pd3d11Context->OMSetDepthStencilState(pEnvD3D11->GetDisableDepthDSS(), 0); + pd3d11Context->IASetInputLayout(nullptr); + + ID3D11RenderTargetView* pd3d11RTVs[] = {pTestingSwapChainD3D11->GetD3D11RTV()}; + pd3d11Context->OMSetRenderTargets(1, pd3d11RTVs, nullptr); + float ClearColor[] = {0, 0, 0, 0}; + pd3d11Context->ClearRenderTargetView(pd3d11RTVs[0], ClearColor); + + D3D11_VIEWPORT d3dVP = {}; + + const auto& SCDesc = pTestingSwapChainD3D11->GetDesc(); + d3dVP.Width = static_cast<float>(SCDesc.Width); + d3dVP.Height = static_cast<float>(SCDesc.Height); + d3dVP.MaxDepth = 1; + pd3d11Context->RSSetViewports(1, &d3dVP); + + pd3d11Context->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + pd3d11Context->Draw(3, 0); + + pd3d11Context->ClearState(); +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D11/TestingEnvironmentD3D11.cpp b/UnitTests/DiligentCoreAPITest/src/D3D11/TestingEnvironmentD3D11.cpp new file mode 100644 index 00000000..2abfbdbc --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/D3D11/TestingEnvironmentD3D11.cpp @@ -0,0 +1,233 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "D3D11/TestingEnvironmentD3D11.h" + +#include "RenderDeviceD3D11.h" +#include "DeviceContextD3D11.h" + +#include <d3dcompiler.h> + +namespace Diligent +{ + +namespace Testing +{ + +TestingEnvironmentD3D11::TestingEnvironmentD3D11(DeviceType deviceType, ADAPTER_TYPE AdapterType) : + TestingEnvironment{deviceType, AdapterType} +{ + RefCntAutoPtr<IRenderDeviceD3D11> pRenderDeviceD3D11{m_pDevice, IID_RenderDeviceD3D11}; + RefCntAutoPtr<IDeviceContextD3D11> pContextD3D11{m_pDeviceContext, IID_DeviceContextD3D11}; + + m_pd3d11Device = pRenderDeviceD3D11->GetD3D11Device(); + m_pd3d11Context = pContextD3D11->GetD3D11DeviceContext(); + + { + D3D11_RASTERIZER_DESC RSDesc = {}; + + RSDesc.CullMode = D3D11_CULL_NONE; + RSDesc.FillMode = D3D11_FILL_SOLID; + auto hr = m_pd3d11Device->CreateRasterizerState(&RSDesc, &m_pd3d11NoCullRS); + VERIFY_EXPR(SUCCEEDED(hr)); + } + + { + D3D11_DEPTH_STENCIL_DESC DSDesc = {}; + + DSDesc.DepthEnable = False; + auto hr = m_pd3d11Device->CreateDepthStencilState(&DSDesc, &m_pd3d11DisableDepthDSS); + VERIFY_EXPR(SUCCEEDED(hr)); + } + + { + D3D11_BLEND_DESC BSDesc = {}; + + BSDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; + + auto hr = m_pd3d11Device->CreateBlendState(&BSDesc, &m_pd3d11DefaultBS); + VERIFY_EXPR(SUCCEEDED(hr)); + } +} + +HRESULT CompileD3DShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile, + ID3DBlob** ppBlobOut) +{ + DWORD dwShaderFlags = D3DCOMPILE_ENABLE_STRICTNESS; +#if defined(DEBUG) || defined(_DEBUG) + // Set the D3D10_SHADER_DEBUG flag to embed debug information in the shaders. + // Setting this flag improves the shader debugging experience, but still allows + // the shaders to be optimized and to run exactly the way they will run in + // the release configuration of this program. + dwShaderFlags |= D3DCOMPILE_DEBUG; +#else + // Warning: do not use this flag as it causes shader compiler to fail the compilation and + // report strange errors: + // dwShaderFlags |= D3D10_SHADER_OPTIMIZATION_LEVEL3; +#endif + + CComPtr<ID3DBlob> pCompilerOutput; + + auto SourceLen = strlen(Source); + + auto hr = D3DCompile(Source, SourceLen, NULL, pDefines, nullptr, strFunctionName, profile, dwShaderFlags, 0, ppBlobOut, &pCompilerOutput); + + const char* CompilerMsg = pCompilerOutput ? reinterpret_cast<const char*>(pCompilerOutput->GetBufferPointer()) : nullptr; + if (FAILED(hr)) + { + LOG_ERROR_AND_THROW("Failed to compile D3D shader :\n", (CompilerMsg != nullptr ? CompilerMsg : "<no compiler log available>")); + } + else if (CompilerMsg != nullptr) + { + LOG_INFO_MESSAGE("Shader compiler output:\n", CompilerMsg); + } + + return hr; +} + +CComPtr<ID3D11VertexShader> TestingEnvironmentD3D11::CreateVertexShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile) +{ + CComPtr<ID3DBlob> pByteCode; + CComPtr<ID3D11VertexShader> pVS; + + auto hr = CompileD3DShader(Source, strFunctionName, pDefines, profile, &pByteCode); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to compile vertex shader"; + return pVS; + } + + hr = m_pd3d11Device->CreateVertexShader(pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), NULL, &pVS); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to create vertex shader"; + } + return pVS; +} + +CComPtr<ID3D11PixelShader> TestingEnvironmentD3D11::CreatePixelShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile) +{ + CComPtr<ID3DBlob> pByteCode; + CComPtr<ID3D11PixelShader> pPS; + + auto hr = CompileD3DShader(Source, strFunctionName, pDefines, profile, &pByteCode); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to compile pixel shader"; + return pPS; + } + + hr = m_pd3d11Device->CreatePixelShader(pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), NULL, &pPS); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to create pixel shader"; + } + return pPS; +} + +CComPtr<ID3D11GeometryShader> TestingEnvironmentD3D11::CreateGeometryShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile) +{ + CComPtr<ID3DBlob> pByteCode; + CComPtr<ID3D11GeometryShader> pGS; + + auto hr = CompileD3DShader(Source, strFunctionName, pDefines, profile, &pByteCode); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to compile geometry shader"; + return pGS; + } + + hr = m_pd3d11Device->CreateGeometryShader(pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), NULL, &pGS); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to create geometry shader"; + } + return pGS; +} + +CComPtr<ID3D11DomainShader> TestingEnvironmentD3D11::CreateDomainShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile) +{ + CComPtr<ID3DBlob> pByteCode; + CComPtr<ID3D11DomainShader> pDS; + + auto hr = CompileD3DShader(Source, strFunctionName, pDefines, profile, &pByteCode); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to compile domain shader"; + return pDS; + } + + hr = m_pd3d11Device->CreateDomainShader(pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), NULL, &pDS); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to create domain shader"; + } + return pDS; +} + +CComPtr<ID3D11HullShader> TestingEnvironmentD3D11::CreateHullShader(const char* Source, + LPCSTR strFunctionName, + const D3D_SHADER_MACRO* pDefines, + LPCSTR profile) +{ + CComPtr<ID3DBlob> pByteCode; + CComPtr<ID3D11HullShader> pDS; + + auto hr = CompileD3DShader(Source, strFunctionName, pDefines, profile, &pByteCode); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to compile hull shader"; + return pDS; + } + + hr = m_pd3d11Device->CreateHullShader(pByteCode->GetBufferPointer(), pByteCode->GetBufferSize(), NULL, &pDS); + if (FAILED(hr)) + { + ADD_FAILURE() << "Failed to create hull shader"; + } + return pDS; +} + +TestingEnvironment* CreateTestingEnvironmentD3D11(DeviceType deviceType, ADAPTER_TYPE AdapterType) +{ + return new TestingEnvironmentD3D11{deviceType, AdapterType}; +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D11/TestingSwapChainD3D11.cpp b/UnitTests/DiligentCoreAPITest/src/D3D11/TestingSwapChainD3D11.cpp new file mode 100644 index 00000000..675dd134 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/D3D11/TestingSwapChainD3D11.cpp @@ -0,0 +1,134 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "../include/D3D11/TestingSwapChainD3D11.h" +#include "../include/DXGITypeConversions.h" + +#include "RenderDeviceD3D11.h" +#include "DeviceContextD3D11.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingSwapChainD3D11::TestingSwapChainD3D11(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc) : + TBase // + { + pRefCounters, + pDevice, + pContext, + SCDesc // + } +{ + RefCntAutoPtr<IRenderDeviceD3D11> pRenderDeviceD3D11{pDevice, IID_RenderDeviceD3D11}; + RefCntAutoPtr<IDeviceContextD3D11> pContextD3D11{pContext, IID_DeviceContextD3D11}; + + auto* pd3d11Device = pRenderDeviceD3D11->GetD3D11Device(); + m_pd3d11Context = pContextD3D11->GetD3D11DeviceContext(); + + D3D11_TEXTURE2D_DESC TexDesc = {}; + + TexDesc.Width = SCDesc.Width; + TexDesc.Height = SCDesc.Height; + TexDesc.MipLevels = 1; + TexDesc.ArraySize = 1; + TexDesc.Format = TexFormatToDXGI_Format(SCDesc.ColorBufferFormat); + TexDesc.SampleDesc.Count = 1; + TexDesc.SampleDesc.Quality = 0; + TexDesc.Usage = D3D11_USAGE_DEFAULT; + TexDesc.BindFlags = BIND_RENDER_TARGET; + TexDesc.CPUAccessFlags = 0; + TexDesc.MiscFlags = 0; + + auto hr = pd3d11Device->CreateTexture2D(&TexDesc, nullptr, &m_pd3d11RenderTarget); + VERIFY(SUCCEEDED(hr), "Failed to create D3D11 render target"); + + hr = pd3d11Device->CreateRenderTargetView(m_pd3d11RenderTarget, nullptr, &m_pd3d11RTV); + VERIFY(SUCCEEDED(hr), "Failed to create D3D11 render target view"); + + TexDesc.BindFlags = 0; + TexDesc.Usage = D3D11_USAGE_STAGING; + TexDesc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + + hr = pd3d11Device->CreateTexture2D(&TexDesc, nullptr, &m_pd3d11StagingTex); + VERIFY(SUCCEEDED(hr), "Failed to create staging D3D11 texture"); + + if (SCDesc.DepthBufferFormat != TEX_FORMAT_UNKNOWN) + { + TexDesc.Usage = D3D11_USAGE_DEFAULT; + TexDesc.Format = TexFormatToDXGI_Format(SCDesc.DepthBufferFormat); + TexDesc.BindFlags = BIND_DEPTH_STENCIL; + TexDesc.CPUAccessFlags = 0; + + hr = pd3d11Device->CreateTexture2D(&TexDesc, nullptr, &m_pd3d11DepthBuffer); + VERIFY(SUCCEEDED(hr), "Failed to create D3D11 depth buffer"); + + hr = pd3d11Device->CreateDepthStencilView(m_pd3d11DepthBuffer, nullptr, &m_pd3d11DSV); + VERIFY(SUCCEEDED(hr), "Failed to create D3D11 depth-stencil view"); + } +} + +void TestingSwapChainD3D11::TakeSnapshot() +{ + m_pd3d11Context->CopyResource(m_pd3d11StagingTex, m_pd3d11RenderTarget); + D3D11_MAPPED_SUBRESOURCE MappedData; + + auto hr = m_pd3d11Context->Map(m_pd3d11StagingTex, 0, D3D11_MAP_READ, 0, &MappedData); + if (SUCCEEDED(hr)) + { + m_ReferenceDataPitch = MappedData.RowPitch; + m_ReferenceData.resize(m_ReferenceDataPitch * m_SwapChainDesc.Height); + for (Uint32 row = 0; row < m_SwapChainDesc.Height; ++row) + { + memcpy(&m_ReferenceData[row * m_ReferenceDataPitch], + reinterpret_cast<const Uint8*>(MappedData.pData) + row * m_ReferenceDataPitch, + m_ReferenceDataPitch); + } + } + else + { + ADD_FAILURE() << "Failed to map stagin texture"; + return; + } + + m_pd3d11Context->Unmap(m_pd3d11StagingTex, 0); + m_pd3d11Context->ClearState(); +} + +void CreateTestingSwapChainD3D11(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) +{ + TestingSwapChainD3D11* pTestingSC(MakeNewRCObj<TestingSwapChainD3D11>()(pDevice, pContext, SCDesc)); + pTestingSC->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain)); +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResD3D12.cpp b/UnitTests/DiligentCoreAPITest/src/D3D12/CreateObjFromNativeResD3D12.cpp index f1d1de3d..d76e084d 100644 --- a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResD3D12.cpp +++ b/UnitTests/DiligentCoreAPITest/src/D3D12/CreateObjFromNativeResD3D12.cpp @@ -21,7 +21,7 @@ * of the possibility of such damages. */ -#include "CreateObjFromNativeResD3D12.h" +#include "D3D12/CreateObjFromNativeResD3D12.h" #include <d3d12.h> #include "RenderDeviceD3D12.h" #include "TextureD3D12.h" @@ -33,6 +33,9 @@ namespace Diligent { +namespace Testing +{ + void TestCreateObjFromNativeResD3D12::CreateTexture(Diligent::ITexture* pTexture) { RefCntAutoPtr<IRenderDeviceD3D12> pDeviceD3D12(m_pDevice, IID_RenderDeviceD3D12); @@ -96,4 +99,6 @@ void TestCreateObjFromNativeResD3D12::CreateBuffer(Diligent::IBuffer* pBuffer) } } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D12/D3D12DebugLayerSetNameBugWorkaround.cpp b/UnitTests/DiligentCoreAPITest/src/D3D12/D3D12DebugLayerSetNameBugWorkaround.cpp index b0ef512f..e186dbfd 100644 --- a/UnitTests/DiligentCoreAPITest/src/D3D12/D3D12DebugLayerSetNameBugWorkaround.cpp +++ b/UnitTests/DiligentCoreAPITest/src/D3D12/D3D12DebugLayerSetNameBugWorkaround.cpp @@ -21,7 +21,7 @@ * of the possibility of such damages. */ -#include "../include/D3D12/D3D12DebugLayerSetNameBugWorkaround.h" +#include "D3D12/D3D12DebugLayerSetNameBugWorkaround.h" #include "RefCntAutoPtr.h" @@ -37,6 +37,9 @@ namespace Diligent { +namespace Testing +{ + struct D3D12DebugLayerSetNameBugWorkaround::RootSignatureWrapper { CComPtr<ID3D12RootSignature> pRootSignature; @@ -68,4 +71,6 @@ D3D12DebugLayerSetNameBugWorkaround::~D3D12DebugLayerSetNameBugWorkaround() { } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D12/DrawCommandRefenceD3D12.cpp b/UnitTests/DiligentCoreAPITest/src/D3D12/DrawCommandRefenceD3D12.cpp new file mode 100644 index 00000000..ae7ff0fe --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/D3D12/DrawCommandRefenceD3D12.cpp @@ -0,0 +1,178 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "D3D12/TestingEnvironmentD3D12.h" +#include "D3D12/TestingSwapChainD3D12.h" +#include "../include/DXGITypeConversions.h" +#include "../include/d3dx12_win.h" + +#include "RenderDeviceD3D12.h" +#include "DeviceContextD3D12.h" + +namespace Diligent +{ + +namespace Testing +{ + +static const char* VSSource = R"( +struct PSInput +{ + float4 Pos : SV_POSITION; + float3 Color : COLOR; +}; + +void main(in uint VertId : SV_VertexID, + out PSInput PSIn) +{ + float4 Pos[3]; + Pos[0] = float4(-0.5, -0.5, 0.5, 1.0); + Pos[1] = float4( 0.0, +0.5, 0.5, 1.0); + Pos[2] = float4(+0.5, -0.5, 0.5, 1.0); + + float3 Col[3]; + Col[0] = float3(1.0, 0.0, 0.0); // red + Col[1] = float3(0.0, 1.0, 0.0); // green + Col[2] = float3(0.0, 0.0, 1.0); // blue + + PSIn.Pos = Pos[VertId]; + PSIn.Color = Col[VertId]; +} +)"; + +static const char* PSSource = R"( +struct PSInput +{ + float4 Pos : SV_POSITION; + float3 Color : COLOR; +}; + +struct PSOutput +{ + float4 Color : SV_TARGET; +}; + +void main(in PSInput PSIn, + out PSOutput PSOut) +{ + PSOut.Color = float4(PSIn.Color.rgb, 1.0); +} +)"; + +void RenderDrawCommandRefenceTriangleD3D12(ISwapChain* pSwapChain) +{ + auto* pEnv = TestingEnvironmentD3D12::GetInstance(); + auto* pContext = pEnv->GetDeviceContext(); + auto* pd3d12Device = pEnv->GetD3D12Device(); + auto* pTestingSwapChainD3D12 = ValidatedCast<TestingSwapChainD3D12>(pSwapChain); + + const auto& SCDesc = pSwapChain->GetDesc(); + + CComPtr<ID3DBlob> pVSByteCode, pPSByteCode; + + auto hr = CompileD3DShader(VSSource, "main", nullptr, "vs_5_0", &pVSByteCode); + ASSERT_HRESULT_SUCCEEDED(hr) << "Failed to compile vertex shader"; + + hr = CompileD3DShader(PSSource, "main", nullptr, "ps_5_0", &pPSByteCode); + ASSERT_HRESULT_SUCCEEDED(hr) << "Failed to compile pixel shader"; + + + D3D12_ROOT_SIGNATURE_DESC RootSignatureDesc = {}; + + RootSignatureDesc.Flags = D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT; + + CComPtr<ID3DBlob> signature; + CComPtr<ID3D12RootSignature> pd3d12RootSignature; + D3D12SerializeRootSignature(&RootSignatureDesc, D3D_ROOT_SIGNATURE_VERSION_1, &signature, nullptr); + pd3d12Device->CreateRootSignature(0, signature->GetBufferPointer(), signature->GetBufferSize(), __uuidof(pd3d12RootSignature), reinterpret_cast<void**>(static_cast<ID3D12RootSignature**>(&pd3d12RootSignature))); + + D3D12_GRAPHICS_PIPELINE_STATE_DESC PSODesc = {}; + + PSODesc.pRootSignature = pd3d12RootSignature; + PSODesc.VS.pShaderBytecode = pVSByteCode->GetBufferPointer(); + PSODesc.VS.BytecodeLength = pVSByteCode->GetBufferSize(); + PSODesc.PS.pShaderBytecode = pPSByteCode->GetBufferPointer(); + PSODesc.PS.BytecodeLength = pPSByteCode->GetBufferSize(); + + PSODesc.BlendState = CD3DX12_BLEND_DESC{D3D12_DEFAULT}; + PSODesc.RasterizerState = CD3DX12_RASTERIZER_DESC{D3D12_DEFAULT}; + PSODesc.DepthStencilState = CD3DX12_DEPTH_STENCIL_DESC{D3D12_DEFAULT}; + + PSODesc.RasterizerState.CullMode = D3D12_CULL_MODE_NONE; + PSODesc.DepthStencilState.DepthEnable = FALSE; + PSODesc.DepthStencilState.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ZERO; + + PSODesc.SampleMask = 0xFFFFFFFF; + + PSODesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE; + PSODesc.NumRenderTargets = 1; + PSODesc.RTVFormats[0] = TexFormatToDXGI_Format(SCDesc.ColorBufferFormat); + PSODesc.SampleDesc.Count = 1; + PSODesc.SampleDesc.Quality = 0; + PSODesc.NodeMask = 0; + PSODesc.Flags = D3D12_PIPELINE_STATE_FLAG_NONE; + + CComPtr<ID3D12PipelineState> pd3d12PSO; + hr = pd3d12Device->CreateGraphicsPipelineState(&PSODesc, __uuidof(pd3d12PSO), reinterpret_cast<void**>(static_cast<ID3D12PipelineState**>(&pd3d12PSO))); + ASSERT_HRESULT_SUCCEEDED(hr) << "Failed to create pipeline state"; + + auto pCmdList = pEnv->CreateGraphicsCommandList(); + pTestingSwapChainD3D12->TransitionRenderTarget(pCmdList, D3D12_RESOURCE_STATE_RENDER_TARGET); + + D3D12_VIEWPORT d3d12VP = {}; + d3d12VP.Width = static_cast<float>(SCDesc.Width); + d3d12VP.Height = static_cast<float>(SCDesc.Height); + d3d12VP.MaxDepth = 1; + pCmdList->RSSetViewports(1, &d3d12VP); + D3D12_RECT Rect = {0, 0, static_cast<LONG>(SCDesc.Width), static_cast<LONG>(SCDesc.Height)}; + pCmdList->RSSetScissorRects(1, &Rect); + + auto RTVDesriptorHandle = pTestingSwapChainD3D12->GetRTVDescriptorHandle(); + + pCmdList->OMSetRenderTargets(1, &RTVDesriptorHandle, FALSE, nullptr); + + float ClearColor[] = {0, 0, 0, 0}; + pCmdList->ClearRenderTargetView(RTVDesriptorHandle, ClearColor, 0, nullptr); + + pCmdList->SetPipelineState(pd3d12PSO); + pCmdList->SetGraphicsRootSignature(pd3d12RootSignature); + pCmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); + pCmdList->DrawInstanced(3, 1, 0, 0); + + pCmdList->Close(); + ID3D12CommandList* pCmdLits[] = {pCmdList}; + + RefCntAutoPtr<IDeviceContextD3D12> pContextD3D12{pContext, IID_DeviceContextD3D12}; + + auto* pQeueD3D12 = pContextD3D12->LockCommandQueue(); + auto* pd3d12Queue = pQeueD3D12->GetD3D12CommandQueue(); + + pd3d12Queue->ExecuteCommandLists(_countof(pCmdLits), pCmdLits); + pEnv->IdleCommandQueue(pd3d12Queue); + + pContextD3D12->UnlockCommandQueue(); +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp b/UnitTests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp new file mode 100644 index 00000000..0b221539 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/D3D12/TestingEnvironmentD3D12.cpp @@ -0,0 +1,84 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "D3D12/TestingEnvironmentD3D12.h" +#include "RenderDeviceD3D12.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingEnvironmentD3D12::TestingEnvironmentD3D12(DeviceType deviceType, ADAPTER_TYPE AdapterType) : + TestingEnvironment{deviceType, AdapterType}, + m_WaitForGPUEventHandle{CreateEvent(nullptr, false, false, nullptr)} +{ + RefCntAutoPtr<IRenderDeviceD3D12> pRenderDeviceD3D12{m_pDevice, IID_RenderDeviceD3D12}; + m_pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); + auto hr = + m_pd3d12Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, __uuidof(m_pd3d12CmdAllocator), + reinterpret_cast<void**>(static_cast<ID3D12CommandAllocator**>(&m_pd3d12CmdAllocator))); + VERIFY_EXPR(SUCCEEDED(hr)); + + hr = m_pd3d12Device->CreateFence(0, D3D12_FENCE_FLAG_NONE, __uuidof(m_pd3d12Fence), + reinterpret_cast<void**>(static_cast<ID3D12Fence**>(&m_pd3d12Fence))); + VERIFY_EXPR(SUCCEEDED(hr)); +} + +TestingEnvironmentD3D12::~TestingEnvironmentD3D12() +{ + CloseHandle(m_WaitForGPUEventHandle); +} + +CComPtr<ID3D12GraphicsCommandList> TestingEnvironmentD3D12::CreateGraphicsCommandList() +{ + CComPtr<ID3D12GraphicsCommandList> pd3d12CmdList; + m_pd3d12Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, m_pd3d12CmdAllocator, nullptr, __uuidof(pd3d12CmdList), + reinterpret_cast<void**>(static_cast<ID3D12GraphicsCommandList**>(&pd3d12CmdList))); + return pd3d12CmdList; +} + +void TestingEnvironmentD3D12::IdleCommandQueue(ID3D12CommandQueue* pd3d12Queue) +{ + Uint64 LastSignaledFenceValue = m_NextFenceValue; + ++m_NextFenceValue; + + pd3d12Queue->Signal(m_pd3d12Fence, LastSignaledFenceValue); + + if (m_pd3d12Fence->GetCompletedValue() < LastSignaledFenceValue) + { + m_pd3d12Fence->SetEventOnCompletion(LastSignaledFenceValue, m_WaitForGPUEventHandle); + WaitForSingleObject(m_WaitForGPUEventHandle, INFINITE); + VERIFY(m_pd3d12Fence->GetCompletedValue() == LastSignaledFenceValue, "Unexpected signaled fence value"); + } +} + +TestingEnvironment* CreateTestingEnvironmentD3D12(DeviceType deviceType, ADAPTER_TYPE AdapterType) +{ + return new TestingEnvironmentD3D12{deviceType, AdapterType}; +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/D3D12/TestingSwapChainD3D12.cpp b/UnitTests/DiligentCoreAPITest/src/D3D12/TestingSwapChainD3D12.cpp new file mode 100644 index 00000000..e893a1c0 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/D3D12/TestingSwapChainD3D12.cpp @@ -0,0 +1,257 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include <vector> + +#include "D3D12/TestingEnvironmentD3D12.h" +#include "D3D12/TestingSwapChainD3D12.h" +#include "../include/DXGITypeConversions.h" + +#include "RenderDeviceD3D12.h" +#include "DeviceContextD3D12.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingSwapChainD3D12::TestingSwapChainD3D12(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc) : + TBase // + { + pRefCounters, + pDevice, + pContext, + SCDesc // + } +{ + RefCntAutoPtr<IRenderDeviceD3D12> pRenderDeviceD3D12{pDevice, IID_RenderDeviceD3D12}; + + auto* pd3d12Device = pRenderDeviceD3D12->GetD3D12Device(); + + D3D12_HEAP_PROPERTIES HeapProps = {}; + HeapProps.Type = D3D12_HEAP_TYPE_DEFAULT; + HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + HeapProps.CreationNodeMask = 1; + HeapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC TexDesc = {}; + TexDesc.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D; + TexDesc.Alignment = 0; + TexDesc.Width = m_SwapChainDesc.Width; + TexDesc.Height = m_SwapChainDesc.Height; + TexDesc.DepthOrArraySize = 1; + TexDesc.MipLevels = 1; + TexDesc.Format = TexFormatToDXGI_Format(SCDesc.ColorBufferFormat); + TexDesc.SampleDesc.Count = 1; + TexDesc.SampleDesc.Quality = 0; + TexDesc.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; + TexDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET; + + D3D12_CLEAR_VALUE ClearColorValue = {}; + ClearColorValue.Format = TexDesc.Format; + auto hr = + pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, &TexDesc, m_RenderTargetState, &ClearColorValue, + __uuidof(m_pd3d12RenderTaget), + reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12RenderTaget))); + VERIFY(SUCCEEDED(hr), "Failed to create D3D12 render target"); + + { + pd3d12Device->GetCopyableFootprints(&TexDesc, 0, 1, 0, &m_StagingBufferFootprint, nullptr, nullptr, &m_StagingBufferSize); + + D3D12_HEAP_PROPERTIES DownloadHeapProps; + DownloadHeapProps.Type = D3D12_HEAP_TYPE_READBACK; + DownloadHeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN; + DownloadHeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN; + DownloadHeapProps.CreationNodeMask = 1; + DownloadHeapProps.VisibleNodeMask = 1; + + D3D12_RESOURCE_DESC BufferDesc; + BufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER; + BufferDesc.Alignment = 0; + BufferDesc.Width = m_StagingBufferSize; + BufferDesc.Height = 1; + BufferDesc.DepthOrArraySize = 1; + BufferDesc.MipLevels = 1; + BufferDesc.Format = DXGI_FORMAT_UNKNOWN; + BufferDesc.SampleDesc.Count = 1; + BufferDesc.SampleDesc.Quality = 0; + BufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR; + BufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE; + + hr = pd3d12Device->CreateCommittedResource(&DownloadHeapProps, D3D12_HEAP_FLAG_NONE, + &BufferDesc, D3D12_RESOURCE_STATE_COPY_DEST, + nullptr, __uuidof(m_pd3d12StagingBuffer), + reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12StagingBuffer))); + if (FAILED(hr)) + LOG_ERROR_AND_THROW("Failed to create committed staging buffer in an upload heap"); + } + + if (SCDesc.DepthBufferFormat != TEX_FORMAT_UNKNOWN) + { + TexDesc.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; + TexDesc.Format = TexFormatToDXGI_Format(SCDesc.DepthBufferFormat); + + D3D12_CLEAR_VALUE ClearDepthValue = {}; + ClearDepthValue.Format = TexDesc.Format; + ClearDepthValue.DepthStencil.Depth = 1; + hr = + pd3d12Device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE, &TexDesc, m_DepthBufferState, &ClearDepthValue, + __uuidof(m_pd3d12DepthBuffer), + reinterpret_cast<void**>(static_cast<ID3D12Resource**>(&m_pd3d12DepthBuffer))); + VERIFY(SUCCEEDED(hr), "Failed to create D3D12 depth buffer"); + } + + D3D12_DESCRIPTOR_HEAP_DESC DescriptorHeapDesc = {}; + DescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV; + DescriptorHeapDesc.NumDescriptors = 1; + DescriptorHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE; + DescriptorHeapDesc.NodeMask = 0; + hr = + pd3d12Device->CreateDescriptorHeap(&DescriptorHeapDesc, + __uuidof(m_pd3d12RTVDescriptorHeap), + reinterpret_cast<void**>(static_cast<ID3D12DescriptorHeap**>(&m_pd3d12RTVDescriptorHeap))); + VERIFY(SUCCEEDED(hr), "Failed to create D3D12 RTV descriptor heap"); + m_RTVDescriptorHandle = m_pd3d12RTVDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + pd3d12Device->CreateRenderTargetView(m_pd3d12RenderTaget, nullptr, m_RTVDescriptorHandle); + + DescriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; + hr = + pd3d12Device->CreateDescriptorHeap(&DescriptorHeapDesc, + __uuidof(m_pd3d12DSVDescriptorHeap), + reinterpret_cast<void**>(static_cast<ID3D12DescriptorHeap**>(&m_pd3d12DSVDescriptorHeap))); + VERIFY(SUCCEEDED(hr), "Failed to create D3D12 DSV descriptor heap"); + m_DSVDescriptorHandle = m_pd3d12DSVDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); + pd3d12Device->CreateDepthStencilView(m_pd3d12DepthBuffer, nullptr, m_DSVDescriptorHandle); +} + +void TestingSwapChainD3D12::TransitionBuffers(ID3D12GraphicsCommandList* pCmdList, + D3D12_RESOURCE_STATES RTVState, + D3D12_RESOURCE_STATES DSVState) +{ + std::vector<D3D12_RESOURCE_BARRIER> Barriers; + if (m_RenderTargetState != RTVState) + { + D3D12_RESOURCE_BARRIER Barrier = {}; + Barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + Barrier.Transition.pResource = m_pd3d12RenderTaget; + Barrier.Transition.StateBefore = m_RenderTargetState; + Barrier.Transition.StateAfter = RTVState; + Barrier.Transition.Subresource = 0; + + m_RenderTargetState = RTVState; + + Barriers.emplace_back(Barrier); + } + + if (m_DepthBufferState != DSVState) + { + D3D12_RESOURCE_BARRIER Barrier = {}; + Barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION; + Barrier.Transition.pResource = m_pd3d12DepthBuffer; + Barrier.Transition.StateBefore = m_DepthBufferState; + Barrier.Transition.StateAfter = DSVState; + Barrier.Transition.Subresource = 0; + + m_DepthBufferState = DSVState; + + Barriers.emplace_back(Barrier); + } + + if (!Barriers.empty()) + { + pCmdList->ResourceBarrier(static_cast<UINT>(Barriers.size()), Barriers.data()); + } +} + +void TestingSwapChainD3D12::TransitionRenderTarget(ID3D12GraphicsCommandList* pCmdList, + D3D12_RESOURCE_STATES RTVState) +{ + TransitionBuffers(pCmdList, RTVState, m_DepthBufferState); +} + +void TestingSwapChainD3D12::TakeSnapshot() +{ + auto* pEnv = TestingEnvironmentD3D12::GetInstance(); + auto* pContext = pEnv->GetDeviceContext(); + auto pCmdList = pEnv->CreateGraphicsCommandList(); + + TransitionRenderTarget(pCmdList, D3D12_RESOURCE_STATE_COPY_SOURCE); + + D3D12_TEXTURE_COPY_LOCATION SrcLocation = {}; + + SrcLocation.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; + SrcLocation.pResource = m_pd3d12RenderTaget; + SrcLocation.SubresourceIndex = 0; + + D3D12_TEXTURE_COPY_LOCATION DstLocation = {}; + + DstLocation.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; + DstLocation.pResource = m_pd3d12StagingBuffer; + DstLocation.PlacedFootprint = m_StagingBufferFootprint; + + pCmdList->CopyTextureRegion(&DstLocation, 0, 0, 0, &SrcLocation, nullptr); + + pCmdList->Close(); + ID3D12CommandList* pCmdLits[] = {pCmdList}; + + RefCntAutoPtr<IDeviceContextD3D12> pContextD3D12{pContext, IID_DeviceContextD3D12}; + + auto* pQeueD3D12 = pContextD3D12->LockCommandQueue(); + auto* pd3d12Queue = pQeueD3D12->GetD3D12CommandQueue(); + + pd3d12Queue->ExecuteCommandLists(1, pCmdLits); + pEnv->IdleCommandQueue(pd3d12Queue); + + D3D12_RANGE InvalidateRange = {0, m_StagingBufferSize}; + void* pStagingDataPtr = nullptr; + m_pd3d12StagingBuffer->Map(0, &InvalidateRange, &pStagingDataPtr); + m_ReferenceDataPitch = m_SwapChainDesc.Width * 4; + m_ReferenceData.resize(m_SwapChainDesc.Height * m_ReferenceDataPitch); + for (Uint32 row = 0; row < m_SwapChainDesc.Height; ++row) + { + memcpy(&m_ReferenceData[row * m_ReferenceDataPitch], + reinterpret_cast<const Uint8*>(pStagingDataPtr) + m_StagingBufferFootprint.Footprint.RowPitch * row, + m_ReferenceDataPitch); + } + m_pd3d12StagingBuffer->Unmap(0, nullptr); + + pContextD3D12->UnlockCommandQueue(); +} + +void CreateTestingSwapChainD3D12(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) +{ + TestingSwapChainD3D12* pTestingSC(MakeNewRCObj<TestingSwapChainD3D12>()(pDevice, pContext, SCDesc)); + pTestingSC->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain)); +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/DepthStencilStateTest.cpp b/UnitTests/DiligentCoreAPITest/src/DepthStencilStateTest.cpp index ff8c20cf..421c9872 100644 --- a/UnitTests/DiligentCoreAPITest/src/DepthStencilStateTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/DepthStencilStateTest.cpp @@ -28,6 +28,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/DrawCommandTest.cpp b/UnitTests/DiligentCoreAPITest/src/DrawCommandTest.cpp new file mode 100644 index 00000000..e00dd0b5 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/DrawCommandTest.cpp @@ -0,0 +1,254 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "TestingEnvironment.h" +#include "TestingSwapChainBase.h" + +#include "gtest/gtest.h" + +namespace Diligent +{ + +namespace Testing +{ + +#if D3D11_SUPPORTED +void RenderDrawCommandRefenceTriangleD3D11(ISwapChain* pSwapChain); +#endif + +#if D3D12_SUPPORTED +void RenderDrawCommandRefenceTriangleD3D12(ISwapChain* pSwapChain); +#endif + +#if GL_SUPPORTED || GLES_SUPPORTED +void RenderDrawCommandRefenceTriangleGL(ISwapChain* pSwapChain); +#endif + +#if VULKAN_SUPPORTED +void RenderDrawCommandRefenceTriangleVk(ISwapChain* pSwapChain); +#endif + +#if METAL_SUPPORTED + +#endif + +} // namespace Testing + +} // namespace Diligent + +using namespace Diligent; +using namespace Diligent::Testing; + +namespace +{ + +const char* ProceduralVSSource = R"( +struct PSInput +{ + float4 Pos : SV_POSITION; + float3 Color : COLOR; +}; + +void main(in uint VertId : SV_VertexID, + out PSInput PSIn) +{ + float4 Pos[3]; + Pos[0] = float4(-0.5, -0.5, 0.0, 1.0); + Pos[1] = float4( 0.0, +0.5, 0.0, 1.0); + Pos[2] = float4(+0.5, -0.5, 0.0, 1.0); + + float3 Col[3]; + Col[0] = float3(1.0, 0.0, 0.0); // red + Col[1] = float3(0.0, 1.0, 0.0); // green + Col[2] = float3(0.0, 0.0, 1.0); // blue + + PSIn.Pos = Pos[VertId]; + PSIn.Color = Col[VertId]; +} +)"; + +const char* PSSource = R"( +struct PSInput +{ + float4 Pos : SV_POSITION; + float3 Color : COLOR; +}; + +struct PSOutput +{ + float4 Color : SV_TARGET; +}; + +void main(in PSInput PSIn, + out PSOutput PSOut) +{ + PSOut.Color = float4(PSIn.Color.rgb, 1.0); +} +)"; + +class DrawCommandTest : public ::testing::Test +{ +protected: + static void SetUpTestSuite() + { + auto* pEnv = TestingEnvironment::GetInstance(); + auto* pDevice = pEnv->GetDevice(); + auto* pSwapChain = pEnv->GetSwapChain(); + auto* pConext = pEnv->GetDeviceContext(); + + RefCntAutoPtr<ITestingSwapChain> pTestingSwapChain(pSwapChain, IID_TestingSwapChain); + if (pTestingSwapChain) + { + pConext->Flush(); + pConext->InvalidateState(); + + auto deviceType = pDevice->GetDeviceCaps().DevType; + switch (deviceType) + { +#if D3D11_SUPPORTED + case DeviceType::D3D11: + RenderDrawCommandRefenceTriangleD3D11(pSwapChain); + break; +#endif + +#if D3D12_SUPPORTED + case DeviceType::D3D12: + RenderDrawCommandRefenceTriangleD3D12(pSwapChain); + break; +#endif + +#if GL_SUPPORTED || GLES_SUPPORTED + case DeviceType::OpenGL: + case DeviceType::OpenGLES: + RenderDrawCommandRefenceTriangleGL(pSwapChain); + break; + +#endif + +#if VULKAN_SUPPORTED + case DeviceType::Vulkan: + RenderDrawCommandRefenceTriangleVk(pSwapChain); + break; + +#endif + + default: + LOG_ERROR_AND_THROW("Unsupported device type"); + } + + pTestingSwapChain->TakeSnapshot(); + } + TestingEnvironment::ScopedReleaseResources EnvironmentAutoReset; + + PipelineStateDesc PSODesc; + PSODesc.Name = "Procedural triangle PSO"; + + PSODesc.IsComputePipeline = false; + PSODesc.GraphicsPipeline.NumRenderTargets = 1; + PSODesc.GraphicsPipeline.RTVFormats[0] = pSwapChain->GetDesc().ColorBufferFormat; + PSODesc.GraphicsPipeline.PrimitiveTopology = PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; + PSODesc.GraphicsPipeline.RasterizerDesc.CullMode = CULL_MODE_NONE; + PSODesc.GraphicsPipeline.DepthStencilDesc.DepthEnable = False; + + ShaderCreateInfo ShaderCI; + ShaderCI.SourceLanguage = SHADER_SOURCE_LANGUAGE_HLSL; + ShaderCI.UseCombinedTextureSamplers = true; + + RefCntAutoPtr<IShader> pProceduralVS; + { + ShaderCI.Desc.ShaderType = SHADER_TYPE_VERTEX; + ShaderCI.EntryPoint = "main"; + ShaderCI.Desc.Name = "Draw command test procedural vertex shader"; + ShaderCI.Source = ProceduralVSSource; + pDevice->CreateShader(ShaderCI, &pProceduralVS); + ASSERT_NE(pProceduralVS, nullptr); + } + + RefCntAutoPtr<IShader> pPS; + { + ShaderCI.Desc.ShaderType = SHADER_TYPE_PIXEL; + ShaderCI.EntryPoint = "main"; + ShaderCI.Desc.Name = "Draw command test pixel shader"; + ShaderCI.Source = PSSource; + pDevice->CreateShader(ShaderCI, &pPS); + ASSERT_NE(pPS, nullptr); + } + + PSODesc.GraphicsPipeline.pVS = pProceduralVS; + PSODesc.GraphicsPipeline.pPS = pPS; + pDevice->CreatePipelineState(PSODesc, &sm_pDrawProceduralPSO); + ASSERT_NE(sm_pDrawProceduralPSO, nullptr); + } + + static void TearDownTestSuite() + { + sm_pDrawProceduralPSO.Release(); + + auto* pEnv = TestingEnvironment::GetInstance(); + pEnv->Reset(); + } + + static void SetRenderTargets() + { + auto* pEnv = TestingEnvironment::GetInstance(); + auto* pContext = pEnv->GetDeviceContext(); + auto* pSwapChain = pEnv->GetSwapChain(); + + ITextureView* pRTVs[] = {pSwapChain->GetCurrentBackBufferRTV()}; + pContext->SetRenderTargets(1, pRTVs, nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + + const float ClearColor[] = {0.f, 0.f, 0.f, 0.0f}; + pContext->ClearRenderTarget(pRTVs[0], ClearColor, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + } + + static void DrawTriangle(IPipelineState* pPSO) + { + auto* pEnv = TestingEnvironment::GetInstance(); + auto* pContext = pEnv->GetDeviceContext(); + auto* pSwapChain = pEnv->GetSwapChain(); + + pContext->SetPipelineState(pPSO); + // Commit shader resources. we don't really have any resources, this call also sets the shaders in OpenGL backend. + pContext->CommitShaderResources(nullptr, RESOURCE_STATE_TRANSITION_MODE_TRANSITION); + + DrawAttribs drawAttrs; + drawAttrs.NumVertices = 3; + pContext->Draw(drawAttrs); + + pSwapChain->Present(); + } + + static RefCntAutoPtr<IPipelineState> sm_pDrawProceduralPSO; +}; + +RefCntAutoPtr<IPipelineState> DrawCommandTest::sm_pDrawProceduralPSO; + +TEST_F(DrawCommandTest, DrawProcedural) +{ + TestingEnvironment::ScopedReset EnvironmentAutoReset; + + SetRenderTargets(); + DrawTriangle(sm_pDrawProceduralPSO); +} + +} // namespace diff --git a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResGL.cpp b/UnitTests/DiligentCoreAPITest/src/GL/CreateObjFromNativeResGL.cpp index 973a54cd..ad265eaf 100644 --- a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResGL.cpp +++ b/UnitTests/DiligentCoreAPITest/src/GL/CreateObjFromNativeResGL.cpp @@ -84,13 +84,16 @@ #include "BufferGL.h" #include "GraphicsAccessories.h" -#include "CreateObjFromNativeResGL.h" +#include "GL/CreateObjFromNativeResGL.h" #include "gtest/gtest.h" namespace Diligent { +namespace Testing +{ + void TestCreateObjFromNativeResGL::CreateTexture(Diligent::ITexture* pTexture) { #if PLATFORM_WIN32 || PLATFORM_LINUX || PLATFORM_ANDROID @@ -159,4 +162,6 @@ void TestCreateObjFromNativeResGL::CreateBuffer(Diligent::IBuffer* pBuffer) #endif } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/GL/DrawCommandRefenceGL.cpp b/UnitTests/DiligentCoreAPITest/src/GL/DrawCommandRefenceGL.cpp new file mode 100644 index 00000000..5a02a310 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/GL/DrawCommandRefenceGL.cpp @@ -0,0 +1,44 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "GL/TestingEnvironmentGL.h" + +namespace Diligent +{ + +namespace Testing +{ + +static const char* VSSource = R"( +)"; + +static const char* PSSource = R"( +)"; + +void RenderDrawCommandRefenceTriangleGL(ISwapChain* pSwapChain) +{ +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/GL/TestingEnvironmentGL.cpp b/UnitTests/DiligentCoreAPITest/src/GL/TestingEnvironmentGL.cpp new file mode 100644 index 00000000..d0707184 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/GL/TestingEnvironmentGL.cpp @@ -0,0 +1,44 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "GL/TestingEnvironmentGL.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingEnvironmentGL::TestingEnvironmentGL(DeviceType deviceType, ADAPTER_TYPE AdapterType) : + TestingEnvironment{deviceType, AdapterType} +{ +} + +TestingEnvironment* CreateTestingEnvironmentGL(DeviceType deviceType, ADAPTER_TYPE AdapterType) +{ + return new TestingEnvironmentGL{deviceType, AdapterType}; +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/GL/TestingSwapChainGL.cpp b/UnitTests/DiligentCoreAPITest/src/GL/TestingSwapChainGL.cpp new file mode 100644 index 00000000..b5e36936 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/GL/TestingSwapChainGL.cpp @@ -0,0 +1,61 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "GL/TestingSwapChainGL.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingSwapChainGL::TestingSwapChainGL(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc) : + TBase // + { + pRefCounters, + pDevice, + pContext, + SCDesc // + } +{ +} + +void TestingSwapChainGL::TakeSnapshot() +{ +} + +void CreateTestingSwapChainGL(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) +{ + TestingSwapChainGL* pTestingSC(MakeNewRCObj<TestingSwapChainGL>()(pDevice, pContext, SCDesc)); + pTestingSC->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain)); +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/GenerateMipsTest.cpp b/UnitTests/DiligentCoreAPITest/src/GenerateMipsTest.cpp index 1bcab569..5e3acc50 100644 --- a/UnitTests/DiligentCoreAPITest/src/GenerateMipsTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/GenerateMipsTest.cpp @@ -26,6 +26,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/HLSL2GLSLConverterTest.cpp b/UnitTests/DiligentCoreAPITest/src/HLSL2GLSLConverterTest.cpp index ee78313f..50358d06 100644 --- a/UnitTests/DiligentCoreAPITest/src/HLSL2GLSLConverterTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/HLSL2GLSLConverterTest.cpp @@ -27,6 +27,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/MTResourceCreationTest.cpp b/UnitTests/DiligentCoreAPITest/src/MTResourceCreationTest.cpp index 7e105fdc..1a7e4e5f 100644 --- a/UnitTests/DiligentCoreAPITest/src/MTResourceCreationTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/MTResourceCreationTest.cpp @@ -34,6 +34,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/PSOCompatibilityTest.cpp b/UnitTests/DiligentCoreAPITest/src/PSOCompatibilityTest.cpp index 6ec93b28..8e8f261d 100644 --- a/UnitTests/DiligentCoreAPITest/src/PSOCompatibilityTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/PSOCompatibilityTest.cpp @@ -26,6 +26,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/PSOTestBase.cpp b/UnitTests/DiligentCoreAPITest/src/PSOTestBase.cpp index 91840c80..5b0bc8d0 100644 --- a/UnitTests/DiligentCoreAPITest/src/PSOTestBase.cpp +++ b/UnitTests/DiligentCoreAPITest/src/PSOTestBase.cpp @@ -27,6 +27,9 @@ namespace Diligent { +namespace Testing +{ + PSOTestBase::Resources PSOTestBase::sm_Resources; static const char g_ShaderSource[] = R"( @@ -91,4 +94,6 @@ RefCntAutoPtr<IPipelineState> PSOTestBase::CreateTestPSO(const PipelineStateDesc return pPSO; } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/RasterizerStateTest.cpp b/UnitTests/DiligentCoreAPITest/src/RasterizerStateTest.cpp index dd064074..aea21319 100644 --- a/UnitTests/DiligentCoreAPITest/src/RasterizerStateTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/RasterizerStateTest.cpp @@ -28,6 +28,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/SamplerCreationTest.cpp b/UnitTests/DiligentCoreAPITest/src/SamplerCreationTest.cpp index dbe643ae..59450ef1 100644 --- a/UnitTests/DiligentCoreAPITest/src/SamplerCreationTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/SamplerCreationTest.cpp @@ -31,6 +31,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/SeparateTextureSamplerTest.cpp b/UnitTests/DiligentCoreAPITest/src/SeparateTextureSamplerTest.cpp index c8750706..c842cf02 100644 --- a/UnitTests/DiligentCoreAPITest/src/SeparateTextureSamplerTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/SeparateTextureSamplerTest.cpp @@ -26,6 +26,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/ShaderResourceArrayTest.cpp b/UnitTests/DiligentCoreAPITest/src/ShaderResourceArrayTest.cpp index 1e373448..515ecbbc 100644 --- a/UnitTests/DiligentCoreAPITest/src/ShaderResourceArrayTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/ShaderResourceArrayTest.cpp @@ -26,6 +26,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp b/UnitTests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp index f92be608..76a6b71f 100644 --- a/UnitTests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/ShaderResourceLayoutTest.cpp @@ -32,6 +32,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace Diligent { diff --git a/UnitTests/DiligentCoreAPITest/src/ShaderVariableAccessTest.cpp b/UnitTests/DiligentCoreAPITest/src/ShaderVariableAccessTest.cpp index 56e97c53..052d8371 100644 --- a/UnitTests/DiligentCoreAPITest/src/ShaderVariableAccessTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/ShaderVariableAccessTest.cpp @@ -29,6 +29,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace Diligent { diff --git a/UnitTests/DiligentCoreAPITest/src/TestingEnvironment.cpp b/UnitTests/DiligentCoreAPITest/src/TestingEnvironment.cpp index bb078469..a51dbd1a 100644 --- a/UnitTests/DiligentCoreAPITest/src/TestingEnvironment.cpp +++ b/UnitTests/DiligentCoreAPITest/src/TestingEnvironment.cpp @@ -23,6 +23,7 @@ #include "TestingEnvironment.h" #include "PlatformDebug.h" +#include "TestingSwapChainBase.h" #if D3D11_SUPPORTED # include "EngineFactoryD3D11.h" @@ -47,6 +48,9 @@ namespace Diligent { +namespace Testing +{ + TestingEnvironment* TestingEnvironment::m_pTheEnvironment = nullptr; std::atomic_int TestingEnvironment::m_NumAllowedErrors; @@ -227,7 +231,7 @@ TestingEnvironment::TestingEnvironment(DeviceType deviceType, ADAPTER_TYPE Adapt } } CreateInfo.EnableDebugLayer = true; - //CreateInfo.EnableGPUBasedValidation = true; + //CreateInfo.EnableGPUBasedValidation = true; CreateInfo.CPUDescriptorHeapAllocationSize[0] = 64; // D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV CreateInfo.CPUDescriptorHeapAllocationSize[1] = 32; // D3D12_DESCRIPTOR_HEAP_TYPE_SAMPLER CreateInfo.CPUDescriptorHeapAllocationSize[2] = 16; // D3D12_DESCRIPTOR_HEAP_TYPE_RTV @@ -341,8 +345,14 @@ TestingEnvironment::TestingEnvironment(DeviceType deviceType, ADAPTER_TYPE Adapt LOG_ERROR_AND_THROW("Unknown device type"); break; } - m_pDeviceContext.Attach(ppContexts[0]); + + SCDesc.Width = 512; + SCDesc.Height = 512; + SCDesc.ColorBufferFormat = TEX_FORMAT_RGBA8_UNORM; + SCDesc.DepthBufferFormat = TEX_FORMAT_D32_FLOAT; + + CreateTestingSwapChain(m_pDevice, m_pDeviceContext, SCDesc, &m_pSwapChain); } TestingEnvironment::~TestingEnvironment() @@ -399,4 +409,6 @@ RefCntAutoPtr<ITexture> TestingEnvironment::CreateTexture(const char* Name, TEXT return pTexture; } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp b/UnitTests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp new file mode 100644 index 00000000..7721b6a0 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/TestingSwapChainBase.cpp @@ -0,0 +1,184 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include <cstring> +#include <cstdlib> +#include <algorithm> + +#include "TestingSwapChainBase.h" +#include "GraphicsAccessories.h" + +#define STB_IMAGE_WRITE_IMPLEMENTATION +#include "../../../ThirdParty/stb/stb_image_write.h" + +namespace Diligent +{ + +namespace Testing +{ + +#if D3D11_SUPPORTED +void CreateTestingSwapChainD3D11(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain); +#endif + +#if D3D12_SUPPORTED +void CreateTestingSwapChainD3D12(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain); +#endif + +#if GL_SUPPORTED || GLES_SUPPORTED +void CreateTestingSwapChainGL(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain); +#endif + +#if VULKAN_SUPPORTED +void CreateTestingSwapChainVk(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain); +#endif + +#if METAL_SUPPORTED + +#endif + +void CreateTestingSwapChain(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) +{ + auto deviceType = pDevice->GetDeviceCaps().DevType; + switch (deviceType) + { +#if D3D11_SUPPORTED + case DeviceType::D3D11: + CreateTestingSwapChainD3D11(pDevice, pContext, SCDesc, ppSwapChain); + break; +#endif + +#if D3D12_SUPPORTED + case DeviceType::D3D12: + CreateTestingSwapChainD3D12(pDevice, pContext, SCDesc, ppSwapChain); + break; +#endif + +#if GL_SUPPORTED || GLES_SUPPORTED + case DeviceType::OpenGL: + case DeviceType::OpenGLES: + CreateTestingSwapChainGL(pDevice, pContext, SCDesc, ppSwapChain); + break; + +#endif + +#if VULKAN_SUPPORTED + case DeviceType::Vulkan: + CreateTestingSwapChainVk(pDevice, pContext, SCDesc, ppSwapChain); + break; + +#endif + + default: + UNSUPPORTED("Unsupported device type"); + } +} + +void CompareTestImages(const Uint8* pReferencePixels, + Uint32 RefPixelsStride, + const Uint8* pPixels, + Uint32 PixelsStride, + Uint32 Width, + Uint32 Height, + TEXTURE_FORMAT Format) +{ + VERIFY_EXPR(pReferencePixels != nullptr); + VERIFY_EXPR(pPixels != nullptr); + VERIFY_EXPR(Width != 0); + VERIFY_EXPR(Height != 0); + VERIFY_EXPR(PixelsStride != 0); + VERIFY_EXPR(RefPixelsStride != 0); + VERIFY(Format == TEX_FORMAT_RGBA8_UNORM, GetTextureFormatAttribs(Format).Name, " is not supported"); + + bool bIsIdentical = true; + + std::vector<Uint8> Delta(Width * Height * 4); + for (Uint32 row = 0; row < Height; ++row) + { + if (memcmp(pReferencePixels + row * RefPixelsStride, + pPixels + row * PixelsStride, + Width * 4) != 0) + { + bIsIdentical = false; + } + } + + if (bIsIdentical) + { + } + else + { + auto ReportImageStride = (Width * 2) * 3; + + std::vector<Uint8> ReportImage(ReportImageStride * (Height * 2)); + for (Uint32 row = 0; row < Height; ++row) + { + for (Uint32 col = 0; col < Width; ++col) + { + for (Uint32 c = 0; c < 3; ++c) + { + auto RefVal = pReferencePixels[row * RefPixelsStride + col * 4 + c]; + auto Val = pPixels[row * PixelsStride + col * 4 + c]; + auto diff = static_cast<Uint8>(std::min(std::abs(int{RefVal} - int{Val}), 255)); + + // clang-format off + ReportImage[row * ReportImageStride + col * 3 + c] = RefVal; + ReportImage[row * ReportImageStride + (Width + col) * 3 + c] = Val; + ReportImage[(row + Height) * ReportImageStride + col * 3 + c] = diff; + ReportImage[(row + Height) * ReportImageStride + (Width + col) * 3 + c] = static_cast<Uint8>(std::min(diff*16, 255)); + // clang-format on + } + } + } + const auto* const TestInfo = ::testing::UnitTest::GetInstance()->current_test_info(); + + std::string FileName = TestInfo->test_suite_name(); + FileName += '.'; + FileName += TestInfo->name(); + FileName += "_FAIL_.png"; + if (stbi_write_png(FileName.c_str(), Width * 2, Height * 2, 3, ReportImage.data(), (Width * 2) * 3) == 0) + { + LOG_ERROR_MESSAGE("Failed to write ", FileName); + } + ADD_FAILURE() << "Captured image is not identical to the reference image"; + } +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/TextureCreationTest.cpp b/UnitTests/DiligentCoreAPITest/src/TextureCreationTest.cpp index 90146e53..7fe667a4 100644 --- a/UnitTests/DiligentCoreAPITest/src/TextureCreationTest.cpp +++ b/UnitTests/DiligentCoreAPITest/src/TextureCreationTest.cpp @@ -25,22 +25,21 @@ #include "RenderDevice.h" #include "GraphicsAccessories.h" -//#include "GraphicsUtilities.h" #if D3D11_SUPPORTED -# include "CreateObjFromNativeResD3D11.h" +# include "D3D11/CreateObjFromNativeResD3D11.h" #endif #if D3D12_SUPPORTED -# include "CreateObjFromNativeResD3D12.h" +# include "D3D12/CreateObjFromNativeResD3D12.h" #endif #if GL_SUPPORTED || GLES_SUPPORTED -# include "CreateObjFromNativeResGL.h" +# include "GL/CreateObjFromNativeResGL.h" #endif #if VULKAN_SUPPORTED -# include "CreateObjFromNativeResVK.h" +# include "Vulkan/CreateObjFromNativeResVK.h" #endif #include "TestingEnvironment.h" @@ -48,6 +47,7 @@ #include "gtest/gtest.h" using namespace Diligent; +using namespace Diligent::Testing; namespace { diff --git a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResVK.cpp b/UnitTests/DiligentCoreAPITest/src/Vulkan/CreateObjFromNativeResVK.cpp index 11fe0b7a..a003b8c9 100644 --- a/UnitTests/DiligentCoreAPITest/src/CreateObjFromNativeResVK.cpp +++ b/UnitTests/DiligentCoreAPITest/src/Vulkan/CreateObjFromNativeResVK.cpp @@ -30,13 +30,16 @@ #include "BufferVk.h" #include "GraphicsAccessories.h" -#include "CreateObjFromNativeResVK.h" +#include "Vulkan/CreateObjFromNativeResVK.h" #include "gtest/gtest.h" namespace Diligent { +namespace Testing +{ + void TestCreateObjFromNativeResVK::CreateTexture(Diligent::ITexture* pTexture) { #if VULKAN_SUPPORTED @@ -95,4 +98,6 @@ void TestCreateObjFromNativeResVK::CreateBuffer(Diligent::IBuffer* pBuffer) #endif } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/Vulkan/DrawCommandRefenceVk.cpp b/UnitTests/DiligentCoreAPITest/src/Vulkan/DrawCommandRefenceVk.cpp new file mode 100644 index 00000000..fb580307 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/Vulkan/DrawCommandRefenceVk.cpp @@ -0,0 +1,46 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "Vulkan/TestingEnvironmentVk.h" + +namespace Diligent +{ + +namespace Testing +{ + +static const char* VSSource = R"( + +)"; + +static const char* PSSource = R"( + +)"; + +void RenderDrawCommandRefenceTriangleVk(ISwapChain* pSwapChain) +{ +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/Vulkan/TestingEnvironmentVk.cpp b/UnitTests/DiligentCoreAPITest/src/Vulkan/TestingEnvironmentVk.cpp new file mode 100644 index 00000000..efb7ca30 --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/Vulkan/TestingEnvironmentVk.cpp @@ -0,0 +1,44 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "Vulkan/TestingEnvironmentVk.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingEnvironmentVk::TestingEnvironmentVk(DeviceType deviceType, ADAPTER_TYPE AdapterType) : + TestingEnvironment{deviceType, AdapterType} +{ +} + +TestingEnvironment* CreateTestingEnvironmentVk(DeviceType deviceType, ADAPTER_TYPE AdapterType) +{ + return new TestingEnvironmentVk{deviceType, AdapterType}; +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/Vulkan/TestingSwapChainVk.cpp b/UnitTests/DiligentCoreAPITest/src/Vulkan/TestingSwapChainVk.cpp new file mode 100644 index 00000000..7c8b42af --- /dev/null +++ b/UnitTests/DiligentCoreAPITest/src/Vulkan/TestingSwapChainVk.cpp @@ -0,0 +1,61 @@ +/* Copyright 2019 Diligent Graphics LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT OF ANY PROPRIETARY RIGHTS. + * + * In no event and under no legal theory, whether in tort (including negligence), + * contract, or otherwise, unless required by applicable law (such as deliberate + * and grossly negligent acts) or agreed to in writing, shall any Contributor be + * liable for any damages, including any direct, indirect, special, incidental, + * or consequential damages of any character arising as a result of this License or + * out of the use or inability to use the software (including but not limited to damages + * for loss of goodwill, work stoppage, computer failure or malfunction, or any and + * all other commercial damages or losses), even if such Contributor has been advised + * of the possibility of such damages. + */ + +#include "Vulkan/TestingSwapChainVk.h" + +namespace Diligent +{ + +namespace Testing +{ + +TestingSwapChainVk::TestingSwapChainVk(IReferenceCounters* pRefCounters, + IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc) : + TBase // + { + pRefCounters, + pDevice, + pContext, + SCDesc // + } +{ +} + +void TestingSwapChainVk::TakeSnapshot() +{ +} + +void CreateTestingSwapChainVk(IRenderDevice* pDevice, + IDeviceContext* pContext, + const SwapChainDesc& SCDesc, + ISwapChain** ppSwapChain) +{ + TestingSwapChainVk* pTestingSC(MakeNewRCObj<TestingSwapChainVk>()(pDevice, pContext, SCDesc)); + pTestingSC->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(ppSwapChain)); +} + +} // namespace Testing + +} // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/Win32/TestingEnvironmentWin32.cpp b/UnitTests/DiligentCoreAPITest/src/Win32/TestingEnvironmentWin32.cpp index 474163be..bc241ffc 100644 --- a/UnitTests/DiligentCoreAPITest/src/Win32/TestingEnvironmentWin32.cpp +++ b/UnitTests/DiligentCoreAPITest/src/Win32/TestingEnvironmentWin32.cpp @@ -31,6 +31,9 @@ namespace Diligent { +namespace Testing +{ + TestingEnvironment::NativeWindow TestingEnvironment::CreateNativeWindow() { #ifdef UNICODE @@ -61,4 +64,6 @@ TestingEnvironment::NativeWindow TestingEnvironment::CreateNativeWindow() return NativeWnd; } +} // namespace Testing + } // namespace Diligent diff --git a/UnitTests/DiligentCoreAPITest/src/main.cpp b/UnitTests/DiligentCoreAPITest/src/main.cpp index d012300f..b0f35b4d 100644 --- a/UnitTests/DiligentCoreAPITest/src/main.cpp +++ b/UnitTests/DiligentCoreAPITest/src/main.cpp @@ -30,7 +30,40 @@ # include <crtdbg.h> #endif + +namespace Diligent +{ + +namespace Testing +{ + +#if D3D11_SUPPORTED +TestingEnvironment* CreateTestingEnvironmentD3D11(DeviceType deviceType, ADAPTER_TYPE AdapterType); +#endif + +#if D3D12_SUPPORTED +TestingEnvironment* CreateTestingEnvironmentD3D12(DeviceType deviceType, ADAPTER_TYPE AdapterType); +#endif + +#if GL_SUPPORTED || GLES_SUPPORTED +TestingEnvironment* CreateTestingEnvironmentGL(DeviceType deviceType, ADAPTER_TYPE AdapterType); +#endif + +#if VULKAN_SUPPORTED +TestingEnvironment* CreateTestingEnvironmentVk(DeviceType deviceType, ADAPTER_TYPE AdapterType); +#endif + +#if METAL_SUPPORTED + +#endif + +} // namespace Testing + +} // namespace Diligent + + using namespace Diligent; +using namespace Diligent::Testing; int main(int argc, char** argv) { @@ -48,34 +81,28 @@ int main(int argc, char** argv) if (strcmp(arg, "--mode=d3d11") == 0) { deviceType = DeviceType::D3D11; - std::cout << "\n\n\n================== Testing Diligent Core API in Direct3D11 mode ==================\n\n"; } else if (strcmp(arg, "--mode=d3d11_sw") == 0) { deviceType = DeviceType::D3D11; AdapterType = ADAPTER_TYPE_SOFTWARE; - std::cout << "\n\n\n================ Testing Diligent Core API in Direct3D11-SW mode =================\n\n"; } else if (strcmp(arg, "--mode=d3d12") == 0) { deviceType = DeviceType::D3D12; - std::cout << "\n\n\n================== Testing Diligent Core API in Direct3D12 mode ==================\n\n"; } else if (strcmp(arg, "--mode=d3d12_sw") == 0) { deviceType = DeviceType::D3D12; AdapterType = ADAPTER_TYPE_SOFTWARE; - std::cout << "\n\n\n================ Testing Diligent Core API in Direct3D12-SW mode =================\n\n"; } else if (strcmp(arg, "--mode=vk") == 0) { deviceType = DeviceType::Vulkan; - std::cout << "\n\n\n==================== Testing Diligent Core API in Vulkan mode ====================\n\n"; } else if (strcmp(arg, "--mode=gl") == 0) { deviceType = DeviceType::OpenGL; - std::cout << "\n\n\n==================== Testing Diligent Core API in OpenGL mode ====================\n\n"; } } @@ -85,10 +112,51 @@ int main(int argc, char** argv) return -1; } - Diligent::TestingEnvironment* pEnv = nullptr; + Diligent::Testing::TestingEnvironment* pEnv = nullptr; try { - pEnv = new Diligent::TestingEnvironment{deviceType, AdapterType}; + switch (deviceType) + { +#if D3D11_SUPPORTED + case DeviceType::D3D11: + pEnv = CreateTestingEnvironmentD3D11(deviceType, AdapterType); + if (AdapterType == ADAPTER_TYPE_SOFTWARE) + std::cout << "\n\n\n================ Testing Diligent Core API in Direct3D11-SW mode =================\n\n"; + else + std::cout << "\n\n\n================== Testing Diligent Core API in Direct3D11 mode ==================\n\n"; + break; +#endif + +#if D3D12_SUPPORTED + case DeviceType::D3D12: + pEnv = CreateTestingEnvironmentD3D12(deviceType, AdapterType); + if (AdapterType == ADAPTER_TYPE_SOFTWARE) + std::cout << "\n\n\n================ Testing Diligent Core API in Direct3D12-SW mode =================\n\n"; + else + std::cout << "\n\n\n================== Testing Diligent Core API in Direct3D12 mode ==================\n\n"; + break; +#endif + +#if GL_SUPPORTED || GLES_SUPPORTED + case DeviceType::OpenGL: + case DeviceType::OpenGLES: + pEnv = CreateTestingEnvironmentGL(deviceType, AdapterType); + std::cout << "\n\n\n==================== Testing Diligent Core API in OpenGL mode ====================\n\n"; + break; + +#endif + +#if VULKAN_SUPPORTED + case DeviceType::Vulkan: + pEnv = CreateTestingEnvironmentVk(deviceType, AdapterType); + std::cout << "\n\n\n==================== Testing Diligent Core API in Vulkan mode ====================\n\n"; + break; + +#endif + + default: + LOG_ERROR_AND_THROW("Unsupported device type"); + } } catch (...) { |
