summaryrefslogtreecommitdiffstats
path: root/unityplugin/UnityEmulator/src/DiligentGraphicsAdapterGL.cpp
blob: 85534474a29d4a71e4f1bebd58ebbc6acda97f75 (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
#include "DiligentGraphicsAdapterGL.h"

#if GL_SUPPORTED || GLES_SUPPORTED

#include "UnityGraphicsGLCoreES_Emulator.h"
#include "EngineFactoryOpenGL.h"
#include "SwapChainBase.hpp"
#include "DefaultRawMemoryAllocator.hpp"

#include "UnityGraphicsGL_Impl.h"
#include "SwapChainGL.h"
#include "RenderDeviceGL.h"
#include "DeviceContextGL.h"

using namespace Diligent;

namespace
{

class ProxySwapChainGL : public SwapChainBase<ISwapChainGL>
{
public:
    using TBase = SwapChainBase<ISwapChainGL>;

    ProxySwapChainGL( IReferenceCounters *pRefCounters,
                      const UnityGraphicsGLCoreES_Emulator& UnityGraphicsGL,
                      IRenderDevice *pDevice,
                      IDeviceContext *pDeviceContext,
                      const SwapChainDesc& SCDesc ) : 
        TBase(pRefCounters, pDevice, pDeviceContext,SCDesc),
        m_UnityGraphicsGL(UnityGraphicsGL)
    {
        CreateDummyBuffers();
    }

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

    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 void DILIGENT_CALL_TYPE Resize(Uint32 NewWidth, Uint32 NewHeight, SURFACE_TRANSFORM NewPreTransform)override final
    {
        if (TBase::Resize(NewWidth, NewHeight, NewPreTransform))
        {
            CreateDummyBuffers();
        }
    }

    virtual GLuint DILIGENT_CALL_TYPE GetDefaultFBO()const override final
    {
        return m_UnityGraphicsGL.GetGraphicsImpl()->GetDefaultFBO();
    }

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

private:
    void CreateDummyBuffers()
    {
        if (m_SwapChainDesc.Width == 0 || m_SwapChainDesc.Height == 0)
            return;

        TextureDesc DummyTexDesc;
        DummyTexDesc.Name      = "Back buffer proxy";
        DummyTexDesc.Type      = RESOURCE_DIM_TEX_2D;
        DummyTexDesc.Format    = m_SwapChainDesc.ColorBufferFormat;
        DummyTexDesc.Width     = m_SwapChainDesc.Width;
        DummyTexDesc.Height    = m_SwapChainDesc.Height;
        DummyTexDesc.BindFlags = BIND_RENDER_TARGET;
        RefCntAutoPtr<IRenderDeviceGL> pDeviceGL(m_pRenderDevice, IID_RenderDeviceGL);
        RefCntAutoPtr<ITexture> pDummyRenderTarget;
        pDeviceGL->CreateDummyTexture(DummyTexDesc, RESOURCE_STATE_RENDER_TARGET, &pDummyRenderTarget);
        m_pRTV = pDummyRenderTarget->GetDefaultView(TEXTURE_VIEW_RENDER_TARGET);

        DummyTexDesc.Name      = "Depth buffer proxy";
        DummyTexDesc.Format    = m_SwapChainDesc.DepthBufferFormat;
        DummyTexDesc.BindFlags = BIND_DEPTH_STENCIL;
        RefCntAutoPtr<ITexture> pDummyDepthBuffer;
        pDeviceGL->CreateDummyTexture(DummyTexDesc, RESOURCE_STATE_DEPTH_WRITE, &pDummyDepthBuffer);
        m_pDSV = pDummyDepthBuffer->GetDefaultView(TEXTURE_VIEW_DEPTH_STENCIL);
    }

    const UnityGraphicsGLCoreES_Emulator& m_UnityGraphicsGL;
    RefCntAutoPtr<ITextureView> m_pRTV;
    RefCntAutoPtr<ITextureView> m_pDSV;
};

}

DiligentGraphicsAdapterGL::DiligentGraphicsAdapterGL(const UnityGraphicsGLCoreES_Emulator& UnityGraphicsGL)noexcept :
    m_UnityGraphicsGL(UnityGraphicsGL)
{
    auto *UnityGraphicsGLImpl = UnityGraphicsGL.GetGraphicsImpl();

    auto *pFactoryGL = GetEngineFactoryOpenGL();
    EngineGLCreateInfo Attribs;
    pFactoryGL->AttachToActiveGLContext(Attribs, &m_pDevice, &m_pDeviceCtx);

    auto BackBufferGLFormat = UnityGraphicsGLImpl->GetBackBufferFormat();
    auto DepthBufferGLFormat = UnityGraphicsGLImpl->GetDepthBufferFormat();

    SwapChainDesc SCDesc;
    if(BackBufferGLFormat == GL_RGBA8)
        SCDesc.ColorBufferFormat = TEX_FORMAT_RGBA8_UNORM_SRGB;
    else
    {
        UNEXPECTED("Unexpected back buffer format");
    }

    if (DepthBufferGLFormat == GL_DEPTH_COMPONENT32F)
        SCDesc.DepthBufferFormat = TEX_FORMAT_D32_FLOAT;
    else if (DepthBufferGLFormat == GL_DEPTH_COMPONENT24)
        SCDesc.DepthBufferFormat = TEX_FORMAT_D24_UNORM_S8_UINT;
    else if (DepthBufferGLFormat == GL_DEPTH_COMPONENT16)
        SCDesc.DepthBufferFormat = TEX_FORMAT_D16_UNORM;
    else
    {
        UNEXPECTED("Unexpected depth buffer format");
    }

    SCDesc.Width = UnityGraphicsGLImpl->GetBackBufferWidth();
    SCDesc.Height = UnityGraphicsGLImpl->GetBackBufferHeight();
    // This field is irrelevant
    SCDesc.BufferCount = 0;

    auto &DefaultAllocator = DefaultRawMemoryAllocator::GetAllocator();
    auto pProxySwapChainGL = NEW_RC_OBJ(DefaultAllocator, "ProxySwapChainGL instance", ProxySwapChainGL)(m_UnityGraphicsGL, m_pDevice, m_pDeviceCtx, SCDesc);
    pProxySwapChainGL->QueryInterface(IID_SwapChain, reinterpret_cast<IObject**>(static_cast<ISwapChain**>(&m_pProxySwapChain)));

    RefCntAutoPtr<IDeviceContextGL>(m_pDeviceCtx, IID_DeviceContextGL)->SetSwapChain(pProxySwapChainGL);
}

void DiligentGraphicsAdapterGL::BeginFrame()
{
    auto *UnityGraphicsGLImpl = m_UnityGraphicsGL.GetGraphicsImpl();
    Uint32 Width = UnityGraphicsGLImpl->GetBackBufferWidth();
    Uint32 Height = UnityGraphicsGLImpl->GetBackBufferHeight();
    m_pProxySwapChain.RawPtr<ProxySwapChainGL>()->Resize(Width, Height, SURFACE_TRANSFORM_OPTIMAL);
}
    
void DiligentGraphicsAdapterGL::EndFrame()
{
    m_pDeviceCtx->InvalidateState();
}

bool DiligentGraphicsAdapterGL::UsesReverseZ()
{ 
    return m_UnityGraphicsGL.UsesReverseZ(); 
}

#endif // GL_SUPPORTED || GLES_SUPPORTED