diff options
Diffstat (limited to '3rdparty/bgfx/src/renderer_d3d11.cpp')
-rw-r--r-- | 3rdparty/bgfx/src/renderer_d3d11.cpp | 273 |
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 { |