summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/renderer_d3d11.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d11.cpp')
-rw-r--r--3rdparty/bgfx/src/renderer_d3d11.cpp273
1 files changed, 183 insertions, 90 deletions
diff --git a/3rdparty/bgfx/src/renderer_d3d11.cpp b/3rdparty/bgfx/src/renderer_d3d11.cpp
index cd794028c30..6d21d13612d 100644
--- a/3rdparty/bgfx/src/renderer_d3d11.cpp
+++ b/3rdparty/bgfx/src/renderer_d3d11.cpp
@@ -601,6 +601,170 @@ namespace bgfx { namespace d3d11
static PFN_GET_DEBUG_INTERFACE1 DXGIGetDebugInterface1;
#endif // USE_D3D11_DYNAMIC_LIB
+
+#if BGFX_CONFIG_USE_OVR
+
+#include <tinystl/vector.h>
+
+ // Oculus Rift eye buffer
+ struct OVRBufferDX11 : public OVRBufferI
+ {
+ OVRBufferDX11(const ovrSession& session, int eyeIdx, ID3D11Device* d3dDevice, ID3D11DeviceContext* d3dCtx)
+ {
+ m_d3dDevice = d3dDevice;
+ m_d3dContext = d3dCtx;
+ ovrHmdDesc hmdDesc = ovr_GetHmdDesc(session);
+ m_eyeTextureSize = ovr_GetFovTextureSize(session, (ovrEyeType)eyeIdx, hmdDesc.DefaultEyeFov[eyeIdx], 1.0f);
+
+ ovrTextureSwapChainDesc desc = {};
+ desc.Type = ovrTexture_2D;
+ desc.ArraySize = 1;
+ desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+ desc.Width = m_eyeTextureSize.w;
+ desc.Height = m_eyeTextureSize.h;
+ desc.MipLevels = 1;
+ desc.SampleCount = 1;
+ desc.MiscFlags = ovrTextureMisc_DX_Typeless;
+ desc.BindFlags = ovrTextureBind_DX_RenderTarget;
+ desc.StaticImage = ovrFalse;
+
+ ovrResult result = ovr_CreateTextureSwapChainDX(session, d3dDevice, &desc, &m_swapTextureChain);
+
+ if (!OVR_SUCCESS(result))
+ {
+ BX_CHECK(false, "Could not create D3D11 OVR swap texture");
+ }
+
+ int textureCount = 0;
+ ovr_GetTextureSwapChainLength(session, m_swapTextureChain, &textureCount);
+
+ for (int i = 0; i < textureCount; ++i)
+ {
+ ID3D11Texture2D* tex = NULL;
+ ovr_GetTextureSwapChainBufferDX(session, m_swapTextureChain, i, IID_PPV_ARGS(&tex));
+ D3D11_RENDER_TARGET_VIEW_DESC rtvd = {};
+ rtvd.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
+ rtvd.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
+
+ ID3D11RenderTargetView* rtv;
+ DX_CHECK(d3dDevice->CreateRenderTargetView(tex, &rtvd, &rtv));
+ m_eyeRtv.push_back(rtv);
+ tex->Release();
+ }
+
+ // setup depth buffer
+ D3D11_TEXTURE2D_DESC dbDesc;
+ dbDesc.Width = m_eyeTextureSize.w;
+ dbDesc.Height = m_eyeTextureSize.h;
+ dbDesc.MipLevels = 1;
+ dbDesc.ArraySize = 1;
+ dbDesc.Format = DXGI_FORMAT_D32_FLOAT;
+ dbDesc.SampleDesc.Count = 1;
+ dbDesc.SampleDesc.Quality = 0;
+ dbDesc.Usage = D3D11_USAGE_DEFAULT;
+ dbDesc.CPUAccessFlags = 0;
+ dbDesc.MiscFlags = 0;
+ dbDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
+ ID3D11Texture2D* tex;
+ DX_CHECK(d3dDevice->CreateTexture2D(&dbDesc, NULL, &tex));
+ DX_CHECK(d3dDevice->CreateDepthStencilView(tex, NULL, &m_depthBuffer));
+ tex->Release();
+ }
+
+ void onRender(const ovrSession& session)
+ {
+ // Clear and set up rendertarget
+ int texIndex = 0;
+ ovr_GetTextureSwapChainCurrentIndex(session, m_swapTextureChain, &texIndex);
+
+ float black[] = { 0.f, 0.f, 0.f, 0.f }; // Important that alpha=0, if want pixels to be transparent, for manual layers
+ m_d3dContext->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer);
+ m_d3dContext->ClearRenderTargetView(m_eyeRtv[texIndex], black);
+ m_d3dContext->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
+
+ D3D11_VIEWPORT D3Dvp;
+ D3Dvp.TopLeftX = 0;
+ D3Dvp.TopLeftY = 0;
+ D3Dvp.Width = (FLOAT)m_eyeTextureSize.w;
+ D3Dvp.Height = (FLOAT)m_eyeTextureSize.h;
+ D3Dvp.MinDepth = 0;
+ D3Dvp.MaxDepth = 1;
+ m_d3dContext->RSSetViewports(1, &D3Dvp);
+ }
+
+ void destroy(const ovrSession& session)
+ {
+ for (size_t i = 0; i < m_eyeRtv.size(); ++i)
+ {
+ m_eyeRtv[i]->Release();
+ }
+
+ ovr_DestroyTextureSwapChain(session, m_swapTextureChain);
+ m_depthBuffer->Release();
+ }
+
+ ID3D11Device* m_d3dDevice;
+ ID3D11DeviceContext* m_d3dContext;
+ stl::vector<ID3D11RenderTargetView *> m_eyeRtv;
+ ID3D11DepthStencilView* m_depthBuffer;
+ };
+
+ // Oculus Rift mirror
+ struct OVRMirrorDX11 : public OVRMirrorI
+ {
+ OVRMirrorDX11(ID3D11Device* d3dDevice,
+ ID3D11DeviceContext* d3dCtx,
+ IDXGISwapChain* d3dSc) : m_d3dDevice(d3dDevice)
+ , m_d3dContext(d3dCtx)
+ , m_d3dSwapChain(d3dSc)
+ {
+ }
+
+ void init(const ovrSession& session, int windowWidth, int windowHeight)
+ {
+ m_mirrorDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
+ m_mirrorDesc.Width = windowWidth;
+ m_mirrorDesc.Height = windowHeight;
+ ovrResult result = ovr_CreateMirrorTextureDX(session, m_d3dDevice, &m_mirrorDesc, &m_mirrorTexture);
+
+ if (!OVR_SUCCESS(result))
+ {
+ BX_CHECK(false, "Could not create D3D11 OVR mirror texture");
+ }
+ }
+
+ void destroy(const ovrSession& session)
+ {
+ if (!m_mirrorTexture)
+ return;
+
+ ovr_DestroyMirrorTexture(session, m_mirrorTexture);
+ m_mirrorTexture = NULL;
+ }
+
+ void blit(const ovrSession& session)
+ {
+ if (!m_mirrorTexture)
+ return;
+
+ ID3D11Texture2D* tex = NULL;
+ ovr_GetMirrorTextureBufferDX(session, m_mirrorTexture, IID_PPV_ARGS(&tex));
+ ID3D11Texture2D* backBuffer;
+ DX_CHECK(m_d3dSwapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer));
+
+ m_d3dContext->CopyResource(backBuffer, tex);
+ DX_CHECK(m_d3dSwapChain->Present(0, 0));
+
+ tex->Release();
+ backBuffer->Release();
+ }
+
+ ID3D11Device* m_d3dDevice;
+ ID3D11DeviceContext* m_d3dContext;
+ IDXGISwapChain* m_d3dSwapChain;
+ };
+#endif // BGFX_CONFIG_USE_OVR
+
struct RendererContextD3D11 : public RendererContextI
{
RendererContextD3D11()
@@ -635,8 +799,6 @@ namespace bgfx { namespace d3d11
, m_fsChanges(0)
, m_rtMsaa(false)
, m_timerQuerySupport(false)
- , m_ovrRtv(NULL)
- , m_ovrDsv(NULL)
{
m_fbh.idx = invalidHandle;
memset(&m_adapterDesc, 0, sizeof(m_adapterDesc) );
@@ -2001,10 +2163,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
uint32_t width = getBufferWidth();
uint32_t height = getBufferHeight();
- if (m_ovr.isEnabled() )
- {
- m_ovr.getSize(width, height);
- }
FrameBufferHandle fbh = BGFX_INVALID_HANDLE;
setFrameBuffer(fbh, false);
@@ -2192,7 +2350,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (SUCCEEDED(hr) )
{
- if (!m_ovr.swap(_hmd) )
+ if (!m_ovr.swap(_hmd, false) )
{
hr = m_swapChain->Present(syncInterval, 0);
}
@@ -3083,77 +3241,22 @@ BX_PRAGMA_DIAGNOSTIC_POP();
void ovrPostReset()
{
#if BGFX_CONFIG_USE_OVR
- if (m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
+ if (m_resolution.m_flags & (BGFX_RESET_HMD|BGFX_RESET_HMD_DEBUG) )
{
- ovrD3D11Config config;
- config.D3D11.Header.API = ovrRenderAPI_D3D11;
-# if OVR_VERSION > OVR_VERSION_043
- config.D3D11.Header.BackBufferSize.w = m_scd.BufferDesc.Width;
- config.D3D11.Header.BackBufferSize.h = m_scd.BufferDesc.Height;
- config.D3D11.pBackBufferUAV = NULL;
-# else
- config.D3D11.Header.RTSize.w = m_scd.BufferDesc.Width;
- config.D3D11.Header.RTSize.h = m_scd.BufferDesc.Height;
-# endif // OVR_VERSION > OVR_VERSION_042
- config.D3D11.Header.Multisample = 0;
- config.D3D11.pDevice = m_device;
- config.D3D11.pDeviceContext = m_deviceCtx;
- config.D3D11.pBackBufferRT = m_backBufferColor;
- config.D3D11.pSwapChain = m_swapChain;
- if (m_ovr.postReset(g_platformData.nwh, &config.Config, !!(m_flags & BGFX_RESET_HMD_DEBUG) ) )
+ if (m_ovr.postReset())
{
- uint32_t size = sizeof(uint32_t) + sizeof(TextureCreate);
- const Memory* mem = alloc(size);
-
- bx::StaticMemoryBlockWriter writer(mem->data, mem->size);
- uint32_t magic = BGFX_CHUNK_MAGIC_TEX;
- bx::write(&writer, magic);
-
- TextureCreate tc;
- tc.m_flags = BGFX_TEXTURE_RT|( ((m_flags & BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT) << BGFX_TEXTURE_RT_MSAA_SHIFT);
- tc.m_width = m_ovr.m_rtSize.w;
- tc.m_height = m_ovr.m_rtSize.h;
- tc.m_sides = 0;
- tc.m_depth = 0;
- tc.m_numMips = 1;
- tc.m_format = uint8_t(bgfx::TextureFormat::BGRA8);
- tc.m_cubeMap = false;
- tc.m_mem = NULL;
- bx::write(&writer, tc);
- m_ovrRT.create(mem, tc.m_flags, 0);
-
- release(mem);
-
- DX_CHECK(m_device->CreateRenderTargetView(m_ovrRT.m_ptr, NULL, &m_ovrRtv) );
-
- D3D11_TEXTURE2D_DESC dsd;
- dsd.Width = m_ovr.m_rtSize.w;
- dsd.Height = m_ovr.m_rtSize.h;
- dsd.MipLevels = 1;
- dsd.ArraySize = 1;
- dsd.Format = DXGI_FORMAT_D24_UNORM_S8_UINT;
- dsd.SampleDesc = m_scd.SampleDesc;
- dsd.Usage = D3D11_USAGE_DEFAULT;
- dsd.BindFlags = D3D11_BIND_DEPTH_STENCIL;
- dsd.CPUAccessFlags = 0;
- dsd.MiscFlags = 0;
-
- ID3D11Texture2D* depthStencil;
- DX_CHECK(m_device->CreateTexture2D(&dsd, NULL, &depthStencil) );
- DX_CHECK(m_device->CreateDepthStencilView(depthStencil, NULL, &m_ovrDsv) );
- DX_RELEASE(depthStencil, 0);
-
- ovrD3D11Texture texture;
- texture.D3D11.Header.API = ovrRenderAPI_D3D11;
- texture.D3D11.Header.TextureSize = m_ovr.m_rtSize;
- texture.D3D11.pTexture = m_ovrRT.m_texture2d;
- texture.D3D11.pSRView = m_ovrRT.m_srv;
- m_ovr.postReset(texture.Texture);
-
- bx::xchg(m_ovrRtv, m_backBufferColor);
-
- BX_CHECK(NULL == m_backBufferDepthStencil, "");
- bx::xchg(m_ovrDsv, m_backBufferDepthStencil);
+ for (int eyeIdx = 0; eyeIdx < ovrEye_Count; eyeIdx++)
+ {
+ // eye buffers need to be initialized only once during application lifetime
+ if (!m_ovr.m_eyeBuffers[eyeIdx])
+ {
+ m_ovr.m_eyeBuffers[eyeIdx] = BX_NEW(g_allocator, OVRBufferDX11(m_ovr.m_hmd, eyeIdx, m_device, m_deviceCtx));
+ }
+ }
+
+ // recreate mirror texture
+ m_ovr.m_mirror = BX_NEW(g_allocator, OVRMirrorDX11(m_device, m_deviceCtx, m_swapChain));
+ m_ovr.m_mirror->init(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@@ -3163,16 +3266,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
{
#if BGFX_CONFIG_USE_OVR
m_ovr.preReset();
- if (NULL != m_ovrRtv)
- {
- bx::xchg(m_ovrRtv, m_backBufferColor);
- bx::xchg(m_ovrDsv, m_backBufferDepthStencil);
- BX_CHECK(NULL == m_backBufferDepthStencil, "");
-
- DX_RELEASE(m_ovrRtv, 0);
- DX_RELEASE(m_ovrDsv, 0);
- m_ovrRT.destroy();
- }
#endif // BGFX_CONFIG_USE_OVR
}
@@ -3564,9 +3657,6 @@ BX_PRAGMA_DIAGNOSTIC_POP();
bool m_timerQuerySupport;
OVR m_ovr;
- TextureD3D11 m_ovrRT;
- ID3D11RenderTargetView* m_ovrRtv;
- ID3D11DepthStencilView* m_ovrDsv;
};
static RendererContextD3D11* s_renderD3D11;
@@ -4864,7 +4954,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
_render->m_hmdInitialized = m_ovr.isInitialized();
- const bool hmdEnabled = m_ovr.isEnabled() || m_ovr.isDebug();
+ const bool hmdEnabled = m_ovr.isEnabled();
ViewState viewState(_render, hmdEnabled);
bool wireframe = !!(_render->m_debug&BGFX_DEBUG_WIREFRAME);
@@ -4987,6 +5077,9 @@ BX_PRAGMA_DIAGNOSTIC_POP();
if (m_ovr.isEnabled() )
{
m_ovr.getViewport(eye, &viewState.m_rect);
+ // commit previous eye to HMD and start rendering new frame
+ m_ovr.commitEye(eye);
+ m_ovr.renderEyeStart(eye);
}
else
{