summaryrefslogtreecommitdiffstats
path: root/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterD3D11.cpp
blob: b10cc22f85495e656d718f0a31587441219f01c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#include <d3d11.h>
#include <dxgi1_2.h>

#include "DiligentGraphicsAdapterD3D11.h"
#include "UnityGraphicsD3D11Emulator.h"
#include "EngineFactoryD3D11.h"
#include "SwapChainBase.hpp"
#include "SwapChainD3D11.h"
#include "DefaultRawMemoryAllocator.hpp"
#include "UnityGraphicsD3D11Impl.h"
#include "DXGITypeConversions.hpp"
#include "RenderDeviceD3D11.h"

using namespace Diligent;

namespace
{

class ProxySwapChainD3D11 : public SwapChainBase<ISwapChainD3D11>
{
public:
    using TBase = SwapChainBase<ISwapChainD3D11>;

    ProxySwapChainD3D11(IReferenceCounters*  pRefCounters,
                        IRenderDevice*       pDevice,
                        IDeviceContext*      pDeviceContext,
                        const SwapChainDesc& SCDesc) :
        TBase(pRefCounters, pDevice, pDeviceContext, SCDesc)
    {}

    IMPLEMENT_QUERY_INTERFACE_IN_PLACE(IID_SwapChainD3D11, TBase)

    virtual IDXGISwapChain* DILIGENT_CALL_TYPE GetDXGISwapChain() override final
    {
        UNEXPECTED("DXGI swap chain cannot be requested through the proxy swap chain");
        return nullptr;
    }

    virtual void DILIGENT_CALL_TYPE Present(Uint32 SyncInterval) override final
    {
        UNEXPECTED("Present is not expected to be called directly");
    }

    virtual void DILIGENT_CALL_TYPE Resize(Uint32 NewWidth, Uint32 NewHeight, SURFACE_TRANSFORM NewPreTransform) override final
    {
        TBase::Resize(NewWidth, NewHeight, NewPreTransform, 0);
    }

    void ReleaseViews()
    {
        m_pRTV.Release();
        m_pDSV.Release();
    }

    void CreateViews(ID3D11RenderTargetView* pd3d11RTV, ID3D11DepthStencilView* pd3d11DSV)
    {
        CComPtr<ID3D11Resource> pd3dBackBuffer;
        pd3d11RTV->GetResource(&pd3dBackBuffer);
        CComPtr<ID3D11Texture2D> pd3dTex2DBackBuffer;
        pd3dBackBuffer->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pd3dTex2DBackBuffer));

        CComPtr<ID3D11Resource> pd3dDepthBuffer;
        pd3d11DSV->GetResource(&pd3dDepthBuffer);
        CComPtr<ID3D11Texture2D> pd3dTex2DDepthBuffer;
        pd3dDepthBuffer->QueryInterface(__uuidof(ID3D11Texture2D), reinterpret_cast<void**>(&pd3dTex2DDepthBuffer));

        RefCntAutoPtr<IRenderDeviceD3D11> pRenderDeviceD3D11(m_pRenderDevice, IID_RenderDeviceD3D11);
        RefCntAutoPtr<ITexture>           pBackBuffer;
        pRenderDeviceD3D11->CreateTexture2DFromD3DResource(pd3dTex2DBackBuffer, RESOURCE_STATE_UNDEFINED, &pBackBuffer);
        TextureViewDesc RTVDesc;
        RTVDesc.ViewType = TEXTURE_VIEW_RENDER_TARGET;
        RTVDesc.Format   = m_SwapChainDesc.ColorBufferFormat;
        RefCntAutoPtr<ITextureView> pRTV;
        pBackBuffer->CreateView(RTVDesc, &pRTV);
        m_pRTV = RefCntAutoPtr<ITextureViewD3D11>(pRTV, IID_TextureViewD3D11);

        RefCntAutoPtr<ITexture> pDepthBuffer;
        pRenderDeviceD3D11->CreateTexture2DFromD3DResource(pd3dTex2DDepthBuffer, RESOURCE_STATE_UNDEFINED, &pDepthBuffer);
        m_pDSV = RefCntAutoPtr<ITextureViewD3D11>(pDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL), IID_TextureViewD3D11);
    }

    virtual void DILIGENT_CALL_TYPE SetFullscreenMode(const DisplayModeAttribs& DisplayMode) override final
    {
        UNEXPECTED("Fullscreen mode cannot be set through the proxy swap chain");
    }

    virtual void DILIGENT_CALL_TYPE SetWindowedMode() override final
    {
        UNEXPECTED("Windowed mode cannot be set through the proxy swap chain");
    }

    virtual ITextureViewD3D11* DILIGENT_CALL_TYPE GetCurrentBackBufferRTV() override final { return m_pRTV; }
    virtual ITextureViewD3D11* DILIGENT_CALL_TYPE GetDepthBufferDSV() override final { return m_pDSV; }

    bool BuffersInitialized() const { return m_pRTV && m_pDSV; }

private:
    RefCntAutoPtr<ITextureViewD3D11> m_pRTV;
    RefCntAutoPtr<ITextureViewD3D11> m_pDSV;
};

} // namespace

DiligentGraphicsAdapterD3D11::DiligentGraphicsAdapterD3D11(const UnityGraphicsD3D11Emulator& UnityGraphicsD3D11) noexcept :
    m_UnityGraphicsD3D11(UnityGraphicsD3D11)
{
    auto*                 GraphicsD3D11Impl = m_UnityGraphicsD3D11.GetGraphicsImpl();
    ID3D11Device*         pd3d11Device      = GraphicsD3D11Impl->GetD3D11Device();
    ID3D11DeviceContext*  pd3d11Context     = GraphicsD3D11Impl->GetD3D11Context();
    auto*                 pFactoryD3d11     = GetEngineFactoryD3D11();
    EngineD3D11CreateInfo Attribs;
    pFactoryD3d11->AttachToD3D11Device(pd3d11Device, pd3d11Context, Attribs, &m_pDevice, &m_pDeviceCtx);
}

void DiligentGraphicsAdapterD3D11::InitProxySwapChain()
{
    auto*                         GraphicsD3D11Impl = m_UnityGraphicsD3D11.GetGraphicsImpl();
    D3D11_RENDER_TARGET_VIEW_DESC RTVDesc;
    auto*                         pBackBufferRTV = GraphicsD3D11Impl->GetRTV();
    pBackBufferRTV->GetDesc(&RTVDesc);
    D3D11_DEPTH_STENCIL_VIEW_DESC DSVDesc;
    auto*                         pDepthBufferDSV = GraphicsD3D11Impl->GetDSV();
    pDepthBufferDSV->GetDesc(&DSVDesc);

    SwapChainDesc SCDesc;
    SCDesc.ColorBufferFormat = DXGI_FormatToTexFormat(RTVDesc.Format);
    SCDesc.DepthBufferFormat = DXGI_FormatToTexFormat(DSVDesc.Format);
    SCDesc.Width             = GraphicsD3D11Impl->GetBackBufferWidth();
    SCDesc.Height            = GraphicsD3D11Impl->GetBackBufferHeight();
    // This field is irrelevant
    SCDesc.BufferCount = 0;

    auto& DefaultAllocator     = DefaultRawMemoryAllocator::GetAllocator();
    auto  pProxySwapChainD3D11 = NEW_RC_OBJ(DefaultAllocator, "ProxySwapChainD3D11 instance", ProxySwapChainD3D11)(m_pDevice, m_pDeviceCtx, SCDesc);
    pProxySwapChainD3D11->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(static_cast<ISwapChain**>(&m_pProxySwapChain)));
    pProxySwapChainD3D11->CreateViews(pBackBufferRTV, pDepthBufferDSV);
}

void DiligentGraphicsAdapterD3D11::BeginFrame()
{
}

void DiligentGraphicsAdapterD3D11::PreSwapChainResize()
{
    auto* pProxySwapChainD3D11 = m_pProxySwapChain.RawPtr<ProxySwapChainD3D11>();
    pProxySwapChainD3D11->ReleaseViews();
}

void DiligentGraphicsAdapterD3D11::PostSwapChainResize()
{
    auto* GraphicsD3D11Impl    = m_UnityGraphicsD3D11.GetGraphicsImpl();
    auto* pProxySwapChainD3D11 = m_pProxySwapChain.RawPtr<ProxySwapChainD3D11>();
    pProxySwapChainD3D11->Resize(GraphicsD3D11Impl->GetBackBufferWidth(), GraphicsD3D11Impl->GetBackBufferHeight(), SURFACE_TRANSFORM_OPTIMAL);
    pProxySwapChainD3D11->CreateViews(GraphicsD3D11Impl->GetRTV(), GraphicsD3D11Impl->GetDSV());
}

void DiligentGraphicsAdapterD3D11::EndFrame()
{
    m_pDeviceCtx->InvalidateState();
}

bool DiligentGraphicsAdapterD3D11::UsesReverseZ()
{
    return m_UnityGraphicsD3D11.UsesReverseZ();
}