Merge pull request #915 from mendsley/vr_renderi

Combine OVRBufferI and OVRMirrorI into a single interface
This commit is contained in:
Branimir Karadžić 2016-09-14 19:21:56 -07:00 committed by GitHub
commit 80fcf18777
6 changed files with 399 additions and 398 deletions

View File

@ -24,11 +24,10 @@ namespace bgfx
OVR::OVR()
: m_hmd(NULL)
, m_enabled(false)
, m_mirror(NULL)
, m_render(NULL)
, m_frameIndex(0)
, m_sensorSampleTime(0)
{
memset(m_eyeBuffers, 0, sizeof(m_eyeBuffers));
}
OVR::~OVR()
@ -73,19 +72,10 @@ namespace bgfx
{
BX_CHECK(!m_enabled, "HMD not disabled.");
for (uint32_t ii = 0; ii < 2; ++ii)
if (NULL != m_render)
{
if (NULL != m_eyeBuffers[ii])
{
m_eyeBuffers[ii]->destroy(m_hmd);
m_eyeBuffers[ii] = NULL;
}
}
if (NULL != m_mirror)
{
m_mirror->destroy(m_hmd);
m_mirror = NULL;
m_render->destroy(m_hmd);
m_render = NULL;
}
ovr_Destroy(m_hmd);
@ -97,13 +87,13 @@ namespace bgfx
{
_viewport->m_x = 0;
_viewport->m_y = 0;
_viewport->m_width = m_eyeBuffers[_eye]->m_eyeTextureSize.w;
_viewport->m_height = m_eyeBuffers[_eye]->m_eyeTextureSize.h;
_viewport->m_width = m_render->m_eyeTextureSize[_eye].w;
_viewport->m_height = m_render->m_eyeTextureSize[_eye].h;
}
void OVR::renderEyeStart(uint8_t _eye)
{
m_eyeBuffers[_eye]->render(m_hmd);
m_render->startEyeRender(m_hmd, _eye);
}
bool OVR::postReset()
@ -128,8 +118,7 @@ namespace bgfx
if (m_enabled)
{
// on window resize this will recreate the mirror texture in ovrPostReset
m_mirror->destroy(m_hmd);
m_mirror = NULL;
m_render->preReset(m_hmd);
m_enabled = false;
}
}
@ -154,8 +143,8 @@ namespace bgfx
for (uint32_t ii = 0; ii < 2; ++ii)
{
m_eyeBuffers[ii]->postRender(m_hmd);
result = ovr_CommitTextureSwapChain(m_hmd, m_eyeBuffers[ii]->m_textureSwapChain);
m_render->postRender(m_hmd, ii);
result = ovr_CommitTextureSwapChain(m_hmd, m_render->m_textureSwapChain[ii]);
if (!OVR_SUCCESS(result) )
{
return DeviceLost;
@ -177,11 +166,11 @@ namespace bgfx
for (uint32_t ii = 0; ii < 2; ++ii)
{
eyeLayer.ColorTexture[ii] = m_eyeBuffers[ii]->m_textureSwapChain;
eyeLayer.ColorTexture[ii] = m_render->m_textureSwapChain[ii];
eyeLayer.Viewport[ii].Pos.x = 0;
eyeLayer.Viewport[ii].Pos.y = 0;
eyeLayer.Viewport[ii].Size.w = m_eyeBuffers[ii]->m_eyeTextureSize.w;
eyeLayer.Viewport[ii].Size.h = m_eyeBuffers[ii]->m_eyeTextureSize.h;
eyeLayer.Viewport[ii].Size.w = m_render->m_eyeTextureSize[ii].w;
eyeLayer.Viewport[ii].Size.h = m_render->m_eyeTextureSize[ii].h;
eyeLayer.Fov[ii] = m_hmdDesc.DefaultEyeFov[ii];
eyeLayer.RenderPose[ii] = m_pose[ii];
eyeLayer.SensorSampleTime = m_sensorSampleTime;
@ -199,7 +188,7 @@ namespace bgfx
// perform mirror texture blit right after the entire frame is submitted to HMD
if (result != ovrSuccess_NotVisible)
{
m_mirror->blit(m_hmd);
m_render->blitMirror(m_hmd);
}
m_hmdToEyeOffset[0] = m_erd[0].HmdToEyeOffset;

View File

@ -27,30 +27,27 @@
namespace bgfx
{
// single eye buffer
struct OVRBufferI
// render data for both eyes and mirrored output
struct BX_NO_VTABLE OVRRenderI
{
virtual ~OVRBufferI() {};
virtual void create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) = 0;
virtual ~OVRRenderI() = 0;
virtual void create(const ovrSession& _session, int _msaaSamples, int _mirrorWidth, int _mirrorHeight) = 0;
virtual void destroy(const ovrSession& _session) = 0;
virtual void render(const ovrSession& _session) = 0;
virtual void postRender(const ovrSession& _session) = 0;
ovrSizei m_eyeTextureSize;
ovrTextureSwapChain m_textureSwapChain;
};
virtual void preReset(const ovrSession& _session) = 0;
virtual void startEyeRender(const ovrSession& _session, int _eyeIdx) = 0;
virtual void postRender(const ovrSession& _session, int _eyeIdx) = 0;
virtual void blitMirror(const ovrSession& _session) = 0;
// mirrored window output
struct OVRMirrorI
{
virtual ~OVRMirrorI() {};
virtual void create(const ovrSession& _session, int windowWidth, int windowHeight) = 0;
virtual void destroy(const ovrSession& _session) = 0;
virtual void blit(const ovrSession& _session) = 0;
ovrMirrorTexture m_mirrorTexture;
ovrSizei m_eyeTextureSize[2];
ovrTextureSwapChain m_textureSwapChain[2];
ovrMirrorTexture m_mirrorTexture;
ovrMirrorTextureDesc m_mirrorTextureDesc;
};
inline OVRRenderI::~OVRRenderI()
{
}
struct OVR
{
enum Enum
@ -93,8 +90,7 @@ namespace bgfx
ovrPosef m_pose[2];
ovrVector3f m_hmdToEyeOffset[2];
ovrSizei m_hmdSize;
OVRBufferI *m_eyeBuffers[2];
OVRMirrorI *m_mirror;
OVRRenderI *m_render;
uint64_t m_frameIndex;
double m_sensorSampleTime;
bool m_enabled;

View File

@ -3152,19 +3152,8 @@ BX_PRAGMA_DIAGNOSTIC_POP();
{
const uint32_t msaaSamples = 1 << ((m_resolution.m_flags&BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT);
for (uint32_t ii = 0; ii < 2; ++ii)
{
// eye buffers need to be initialized only once during application lifetime
if (NULL == m_ovr.m_eyeBuffers[ii])
{
m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii];
m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii, msaaSamples);
}
}
// recreate mirror texture
m_ovr.m_mirror = &m_ovrMirror;
m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
m_ovr.m_render = &m_ovrRender;
m_ovr.m_render->create(m_ovr.m_hmd, msaaSamples, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@ -3566,8 +3555,7 @@ BX_PRAGMA_DIAGNOSTIC_POP();
OVR m_ovr;
#if BGFX_CONFIG_USE_OVR
OVRMirrorD3D11 m_ovrMirror;
OVRBufferD3D11 m_ovrBuffers[2];
OVRRenderD3D11 m_ovrRender;
#endif // BGFX_CONFIG_USE_OVR
};
@ -3622,204 +3610,228 @@ BX_PRAGMA_DIAGNOSTIC_POP();
}
#if BGFX_CONFIG_USE_OVR
void OVRBufferD3D11::create(const ovrSession& _session, int _eyeIdx, int _msaaSamples)
OVRRenderD3D11::OVRRenderD3D11()
{
m_mirrorTexture = NULL;
memset(m_textureSwapChain, 0, sizeof(m_textureSwapChain));
}
void OVRRenderD3D11::create(const ovrSession& _session, int _msaaSamples, int _mirrorWidth, int _mirrorHeight)
{
ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session);
m_eyeTextureSize = ovr_GetFovTextureSize(_session, (ovrEyeType)_eyeIdx, hmdDesc.DefaultEyeFov[_eyeIdx], 1.0f);
m_msaaTexture = NULL;
m_msaaRtv = NULL;
m_msaaSv = NULL;
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;
ID3D11Device* device = s_renderD3D11->m_device;
ovrResult result = ovr_CreateTextureSwapChainDX(_session, device, &desc, &m_textureSwapChain);
if (!OVR_SUCCESS(result) )
for (int eye = 0; eye < 2; ++eye)
{
BX_CHECK(false, "Could not create D3D11 OVR swap texture");
if (NULL == m_textureSwapChain[eye])
{
m_eyeTextureSize[eye] = ovr_GetFovTextureSize(_session, (ovrEyeType)eye, hmdDesc.DefaultEyeFov[eye], 1.0f);
m_msaaTexture[eye] = NULL;
m_msaaRtv[eye] = NULL;
m_msaaSv[eye] = NULL;
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.Width = m_eyeTextureSize[eye].w;
desc.Height = m_eyeTextureSize[eye].h;
desc.MipLevels = 1;
desc.SampleCount = 1;
desc.MiscFlags = ovrTextureMisc_DX_Typeless;
desc.BindFlags = ovrTextureBind_DX_RenderTarget;
desc.StaticImage = ovrFalse;
ID3D11Device* device = s_renderD3D11->m_device;
ovrResult result = ovr_CreateTextureSwapChainDX(_session, device, &desc, &m_textureSwapChain[eye]);
if (!OVR_SUCCESS(result) )
{
BX_CHECK(false, "Could not create D3D11 OVR swap texture");
}
memset(m_eyeRtv[eye], 0, sizeof(m_eyeRtv[eye]) );
int textureCount = 0;
ovr_GetTextureSwapChainLength(_session, m_textureSwapChain[eye], &textureCount);
for (int ii = 0; ii < textureCount; ++ii)
{
ID3D11Texture2D* tex = NULL;
ovr_GetTextureSwapChainBufferDX(_session, m_textureSwapChain[eye], ii, 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(device->CreateRenderTargetView(tex, &rtvd, &rtv) );
m_eyeRtv[eye][ii] = rtv;
DX_RELEASE(tex, 1);
}
// setup depth buffer
D3D11_TEXTURE2D_DESC dbDesc;
dbDesc.Width = m_eyeTextureSize[eye].w;
dbDesc.Height = m_eyeTextureSize[eye].h;
dbDesc.MipLevels = 1;
dbDesc.ArraySize = 1;
dbDesc.Format = DXGI_FORMAT_D32_FLOAT;
dbDesc.SampleDesc.Count = _msaaSamples;
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(device->CreateTexture2D(&dbDesc, NULL, &tex) );
DX_CHECK(device->CreateDepthStencilView(tex, NULL, &m_depthBuffer[eye]) );
DX_RELEASE(tex, 0);
// create MSAA render target
if (_msaaSamples > 1)
{
D3D11_TEXTURE2D_DESC dsDesc;
dsDesc.Width = m_eyeTextureSize[eye].w;
dsDesc.Height = m_eyeTextureSize[eye].h;
dsDesc.MipLevels = 1;
dsDesc.ArraySize = 1;
dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dsDesc.SampleDesc.Count = _msaaSamples;
dsDesc.SampleDesc.Quality = 0;
dsDesc.Usage = D3D11_USAGE_DEFAULT;
dsDesc.CPUAccessFlags = 0;
dsDesc.MiscFlags = 0;
dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
ID3D11Device* device = s_renderD3D11->m_device;
DX_CHECK(device->CreateTexture2D(&dsDesc, NULL, &m_msaaTexture[eye]));
DX_CHECK(device->CreateShaderResourceView(m_msaaTexture[eye], NULL, &m_msaaSv[eye]));
DX_CHECK(device->CreateRenderTargetView(m_msaaTexture[eye], NULL, &m_msaaRtv[eye]));
}
}
}
memset(m_eyeRtv, 0, sizeof(m_eyeRtv) );
int textureCount = 0;
ovr_GetTextureSwapChainLength(_session, m_textureSwapChain, &textureCount);
for (int ii = 0; ii < textureCount; ++ii)
if (NULL == m_mirrorTexture)
{
ID3D11Texture2D* tex = NULL;
ovr_GetTextureSwapChainBufferDX(_session, m_textureSwapChain, ii, 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(device->CreateRenderTargetView(tex, &rtvd, &rtv) );
m_eyeRtv[ii] = rtv;
DX_RELEASE(tex, 1);
}
// 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 = _msaaSamples;
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(device->CreateTexture2D(&dbDesc, NULL, &tex) );
DX_CHECK(device->CreateDepthStencilView(tex, NULL, &m_depthBuffer) );
DX_RELEASE(tex, 0);
// create MSAA render target
if (_msaaSamples > 1)
{
D3D11_TEXTURE2D_DESC dsDesc;
dsDesc.Width = m_eyeTextureSize.w;
dsDesc.Height = m_eyeTextureSize.h;
dsDesc.MipLevels = 1;
dsDesc.ArraySize = 1;
dsDesc.Format = DXGI_FORMAT_R8G8B8A8_UNORM;
dsDesc.SampleDesc.Count = _msaaSamples;
dsDesc.SampleDesc.Quality = 0;
dsDesc.Usage = D3D11_USAGE_DEFAULT;
dsDesc.CPUAccessFlags = 0;
dsDesc.MiscFlags = 0;
dsDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
ID3D11Device* device = s_renderD3D11->m_device;
DX_CHECK(device->CreateTexture2D(&dsDesc, NULL, &m_msaaTexture));
DX_CHECK(device->CreateShaderResourceView(m_msaaTexture, NULL, &m_msaaSv));
DX_CHECK(device->CreateRenderTargetView(m_msaaTexture, NULL, &m_msaaRtv));
m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
m_mirrorTextureDesc.Width = _mirrorWidth;
m_mirrorTextureDesc.Height = _mirrorHeight;
ovrResult result = ovr_CreateMirrorTextureDX(_session, s_renderD3D11->m_device, &m_mirrorTextureDesc, &m_mirrorTexture);
BX_WARN(OVR_SUCCESS(result), "Could not create D3D11 OVR mirror texture");
BX_UNUSED(result);
}
}
void OVRBufferD3D11::render(const ovrSession& _session)
void OVRRenderD3D11::startEyeRender(const ovrSession& _session, int _eyeIdx)
{
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
float black[] = { 0.0f, 0.0f, 0.0f, 0.0f }; // Important that alpha=0, if want pixels to be transparent, for manual layers
// render to MSAA target
if (NULL != m_msaaTexture)
if (NULL != m_msaaTexture[_eyeIdx])
{
deviceCtx->OMSetRenderTargets(1, &m_msaaRtv, m_depthBuffer);
deviceCtx->ClearRenderTargetView(m_msaaRtv, black);
deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
deviceCtx->OMSetRenderTargets(1, &m_msaaRtv[_eyeIdx], m_depthBuffer[_eyeIdx]);
deviceCtx->ClearRenderTargetView(m_msaaRtv[_eyeIdx], black);
deviceCtx->ClearDepthStencilView(m_depthBuffer[_eyeIdx], D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
}
else // MSAA disabled? render directly to eye buffer
{
int texIndex = 0;
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &texIndex);
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain[_eyeIdx], &texIndex);
deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[texIndex], m_depthBuffer);
deviceCtx->ClearRenderTargetView(m_eyeRtv[texIndex], black);
deviceCtx->ClearDepthStencilView(m_depthBuffer, D3D11_CLEAR_DEPTH | D3D11_CLEAR_STENCIL, 1, 0);
deviceCtx->OMSetRenderTargets(1, &m_eyeRtv[_eyeIdx][texIndex], m_depthBuffer[_eyeIdx]);
deviceCtx->ClearRenderTargetView(m_eyeRtv[_eyeIdx][texIndex], black);
deviceCtx->ClearDepthStencilView(m_depthBuffer[_eyeIdx], 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.Width = (FLOAT)m_eyeTextureSize[_eyeIdx].w;
D3Dvp.Height = (FLOAT)m_eyeTextureSize[_eyeIdx].h;
D3Dvp.MinDepth = 0;
D3Dvp.MaxDepth = 1;
deviceCtx->RSSetViewports(1, &D3Dvp);
}
}
void OVRBufferD3D11::postRender(const ovrSession& _session)
void OVRRenderD3D11::postRender(const ovrSession& _session, int _eyeIdx)
{
if (NULL != m_msaaTexture)
if (NULL != m_msaaTexture[_eyeIdx])
{
ID3D11DeviceContext* deviceCtx = s_renderD3D11->m_deviceCtx;
int destIndex = 0;
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &destIndex);
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain[_eyeIdx], &destIndex);
ID3D11Resource* dstTex = NULL;
ovr_GetTextureSwapChainBufferDX(_session, m_textureSwapChain, destIndex, IID_PPV_ARGS(&dstTex));
deviceCtx->ResolveSubresource(dstTex, 0, m_msaaTexture, 0, DXGI_FORMAT_R8G8B8A8_UNORM);
ovr_GetTextureSwapChainBufferDX(_session, m_textureSwapChain[_eyeIdx], destIndex, IID_PPV_ARGS(&dstTex));
deviceCtx->ResolveSubresource(dstTex, 0, m_msaaTexture[_eyeIdx], 0, DXGI_FORMAT_R8G8B8A8_UNORM);
dstTex->Release();
}
}
void OVRBufferD3D11::destroy(const ovrSession& _session)
void OVRRenderD3D11::destroy(const ovrSession& _session)
{
for (uint32_t ii = 0; ii < BX_COUNTOF(m_eyeRtv); ++ii)
for (int eye = 0; eye < 2; ++eye)
{
DX_RELEASE(m_eyeRtv[ii], 0);
}
ovr_DestroyTextureSwapChain(_session, m_textureSwapChain);
m_depthBuffer->Release();
if (NULL != m_msaaTexture)
{
m_msaaTexture->Release();
m_msaaTexture = NULL;
}
if (NULL != m_msaaSv)
{
m_msaaSv->Release();
m_msaaSv = NULL;
}
if (NULL != m_msaaRtv)
{
m_msaaRtv->Release();
m_msaaRtv = NULL;
}
}
void OVRMirrorD3D11::create(const ovrSession& _session, int _width, int _height)
{
m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
m_mirrorTextureDesc.Width = _width;
m_mirrorTextureDesc.Height = _height;
ovrResult result = ovr_CreateMirrorTextureDX(_session, s_renderD3D11->m_device, &m_mirrorTextureDesc, &m_mirrorTexture);
BX_WARN(OVR_SUCCESS(result), "Could not create D3D11 OVR mirror texture");
BX_UNUSED(result);
}
void OVRMirrorD3D11::destroy(const ovrSession& session)
{
if (NULL != m_mirrorTexture)
for (uint32_t ii = 0; ii < BX_COUNTOF(m_eyeRtv); ++ii)
{
ovr_DestroyMirrorTexture(session, m_mirrorTexture);
m_mirrorTexture = NULL;
DX_RELEASE(m_eyeRtv[eye][ii], 0);
}
ovr_DestroyTextureSwapChain(_session, m_textureSwapChain[eye]);
m_textureSwapChain[eye] = NULL;
m_depthBuffer[eye]->Release();
if (NULL != m_msaaTexture[eye])
{
m_msaaTexture[eye]->Release();
m_msaaTexture[eye] = NULL;
}
if (NULL != m_msaaSv[eye])
{
m_msaaSv[eye]->Release();
m_msaaSv[eye] = NULL;
}
if (NULL != m_msaaRtv[eye])
{
m_msaaRtv[eye]->Release();
m_msaaRtv[eye] = NULL;
}
}
void OVRMirrorD3D11::blit(const ovrSession& _session)
if (NULL != m_mirrorTexture)
{
if (NULL != m_mirrorTexture)
{
ID3D11Texture2D* tex = NULL;
ovr_GetMirrorTextureBufferDX(_session, m_mirrorTexture, IID_PPV_ARGS(&tex) );
ID3D11Texture2D* backBuffer;
DX_CHECK(s_renderD3D11->m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );
s_renderD3D11->m_deviceCtx->CopyResource(backBuffer, tex);
DX_CHECK(s_renderD3D11->m_swapChain->Present(0, 0) );
DX_RELEASE(tex, 1);
DX_RELEASE(backBuffer, 0);
}
ovr_DestroyMirrorTexture(_session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
}
void OVRRenderD3D11::blitMirror(const ovrSession& _session)
{
if (NULL != m_mirrorTexture)
{
ID3D11Texture2D* tex = NULL;
ovr_GetMirrorTextureBufferDX(_session, m_mirrorTexture, IID_PPV_ARGS(&tex) );
ID3D11Texture2D* backBuffer;
DX_CHECK(s_renderD3D11->m_swapChain->GetBuffer(0, IID_ID3D11Texture2D, (void**)&backBuffer) );
s_renderD3D11->m_deviceCtx->CopyResource(backBuffer, tex);
DX_CHECK(s_renderD3D11->m_swapChain->Present(0, 0) );
DX_RELEASE(tex, 1);
DX_RELEASE(backBuffer, 0);
}
}
void OVRRenderD3D11::preReset(const ovrSession& _session)
{
if (NULL != m_mirrorTexture)
{
ovr_DestroyMirrorTexture(_session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
}
#endif // BGFX_CONFIG_USE_OVR
struct UavFormat

View File

@ -61,26 +61,23 @@ BX_PRAGMA_DIAGNOSTIC_POP()
namespace bgfx { namespace d3d11
{
#if BGFX_CONFIG_USE_OVR
struct OVRBufferD3D11 : public OVRBufferI
struct OVRRenderD3D11 : public OVRRenderI
{
virtual void create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) BX_OVERRIDE;
virtual void destroy(const ovrSession& _session) BX_OVERRIDE;
virtual void render(const ovrSession& _session) BX_OVERRIDE;
virtual void postRender(const ovrSession& _session) BX_OVERRIDE;
OVRRenderD3D11();
virtual void create(const ovrSession& _session, int _msaaSamples, int _mirrorWidth, int _mirrorHeight);
virtual void destroy(const ovrSession& _session);
virtual void preReset(const ovrSession& _session);
virtual void startEyeRender(const ovrSession& _session, int _eyeIdx);
virtual void postRender(const ovrSession& _session, int _eyeIdx);
virtual void blitMirror(const ovrSession& _session);
ID3D11RenderTargetView* m_eyeRtv[4];
ID3D11DepthStencilView* m_depthBuffer;
ID3D11Texture2D* m_msaaTexture;
ID3D11ShaderResourceView* m_msaaSv;
ID3D11RenderTargetView* m_msaaRtv;
ID3D11RenderTargetView* m_eyeRtv[2][4];
ID3D11DepthStencilView* m_depthBuffer[2];
ID3D11Texture2D* m_msaaTexture[2];
ID3D11ShaderResourceView* m_msaaSv[2];
ID3D11RenderTargetView* m_msaaRtv[2];
};
struct OVRMirrorD3D11 : public OVRMirrorI
{
virtual void create(const ovrSession& _session, int _width, int _height) BX_OVERRIDE;
virtual void destroy(const ovrSession& session) BX_OVERRIDE;
virtual void blit(const ovrSession& session) BX_OVERRIDE;
};
#endif // BGFX_CONFIG_USE_OVR
struct BufferD3D11

View File

@ -2961,19 +2961,8 @@ namespace bgfx { namespace gl
{
const uint32_t msaaSamples = 1 << ((m_resolution.m_flags&BGFX_RESET_MSAA_MASK) >> BGFX_RESET_MSAA_SHIFT);
for (uint32_t ii = 0; ii < 2; ++ii)
{
// eye buffers need to be initialized only once during application lifetime
if (NULL == m_ovr.m_eyeBuffers[ii])
{
m_ovr.m_eyeBuffers[ii] = &m_ovrBuffers[ii];
m_ovr.m_eyeBuffers[ii]->create(m_ovr.m_hmd, ii, msaaSamples);
}
}
// recreate mirror texture
m_ovr.m_mirror = &m_ovrMirror;
m_ovr.m_mirror->create(m_ovr.m_hmd, m_resolution.m_width, m_resolution.m_height);
m_ovr.m_render = &m_ovrRender;
m_ovr.m_render->create(m_ovr.m_hmd, msaaSamples, m_resolution.m_width, m_resolution.m_height);
}
}
#endif // BGFX_CONFIG_USE_OVR
@ -3407,8 +3396,7 @@ namespace bgfx { namespace gl
OVR m_ovr;
#if BGFX_CONFIG_USE_OVR
OVRMirrorGL m_ovrMirror;
OVRBufferGL m_ovrBuffers[2];
OVRRenderGL m_ovrRender;
#endif // BGFX_CONFIG_USE_OVR
};
@ -3429,194 +3417,207 @@ namespace bgfx { namespace gl
}
#if BGFX_CONFIG_USE_OVR
void OVRBufferGL::create(const ovrSession& _session, int _eyeIdx, int _msaaSamples)
OVRRenderGL::OVRRenderGL()
{
m_eyeFbo = 0;
m_eyeTexId = 0;
m_depthBuffer = 0;
m_msaaEyeFbo = 0;
m_msaaEyeTexId = 0;
m_msaaDepthBuffer = 0;
memset(&m_eyeFbo, 0, sizeof(m_eyeFbo));
m_mirrorFBO = 0;
}
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.Width = m_eyeTextureSize.w;
desc.Height = m_eyeTextureSize.h;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovr_CreateTextureSwapChainGL(_session, &desc, &m_textureSwapChain);
int textureCount = 0;
ovr_GetTextureSwapChainLength(_session, m_textureSwapChain, &textureCount);
for (int j = 0; j < textureCount; ++j)
void OVRRenderGL::create(const ovrSession& _session, int _msaaSamples, int _mirrorWidth, int _mirrorHeight)
{
for (int eye = 0; eye < 2; ++eye)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, j, &chainTexId);
GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId) );
if (NULL == m_textureSwapChain[eye])
{
m_eyeFbo[eye] = 0;
m_eyeTexId[eye] = 0;
m_depthBuffer[eye] = 0;
m_msaaEyeFbo[eye] = 0;
m_msaaEyeTexId[eye] = 0;
m_msaaDepthBuffer[eye] = 0;
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
ovrHmdDesc hmdDesc = ovr_GetHmdDesc(_session);
m_eyeTextureSize[eye] = ovr_GetFovTextureSize(_session, ovrEyeType(eye), hmdDesc.DefaultEyeFov[eye], 1.0f);
ovrTextureSwapChainDesc desc = {};
desc.Type = ovrTexture_2D;
desc.ArraySize = 1;
desc.Width = m_eyeTextureSize[eye].w;
desc.Height = m_eyeTextureSize[eye].h;
desc.MipLevels = 1;
desc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
desc.SampleCount = 1;
desc.StaticImage = ovrFalse;
ovr_CreateTextureSwapChainGL(_session, &desc, &m_textureSwapChain[eye]);
int textureCount = 0;
ovr_GetTextureSwapChainLength(_session, m_textureSwapChain[eye], &textureCount);
for (int j = 0; j < textureCount; ++j)
{
GLuint chainTexId;
ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain[eye], j, &chainTexId);
GL_CHECK(glBindTexture(GL_TEXTURE_2D, chainTexId) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
}
GL_CHECK(glGenFramebuffers(1, &m_eyeFbo[eye]) );
// create depth buffer
GL_CHECK(glGenTextures(1, &m_depthBuffer[eye]) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer[eye]) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize[eye].w, m_eyeTextureSize[eye].h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL) );
// create MSAA buffers
if (_msaaSamples > 1)
{
GL_CHECK(glGenFramebuffers(1, &m_msaaEyeFbo[eye]) );
// create color MSAA texture
GL_CHECK(glGenTextures(1, &m_msaaEyeTexId[eye]) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId[eye]) );
GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_RGBA, m_eyeTextureSize[eye].w, m_eyeTextureSize[eye].h, false) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) );
// create MSAA depth buffer
GL_CHECK(glGenTextures(1, &m_msaaDepthBuffer[eye]) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer[eye]) );
GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_DEPTH_COMPONENT, m_eyeTextureSize[eye].w, m_eyeTextureSize[eye].h, false) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) );
}
}
}
GL_CHECK(glGenFramebuffers(1, &m_eyeFbo) );
// create depth buffer
GL_CHECK(glGenTextures(1, &m_depthBuffer) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D, m_depthBuffer) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE) );
GL_CHECK(glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, m_eyeTextureSize.w, m_eyeTextureSize.h, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, NULL) );
// create MSAA buffers
if (_msaaSamples > 1)
if (NULL == m_mirrorTexture)
{
GL_CHECK(glGenFramebuffers(1, &m_msaaEyeFbo) );
memset(&m_mirrorTextureDesc, 0, sizeof(m_mirrorTextureDesc) );
m_mirrorTextureDesc.Width = _mirrorWidth;
m_mirrorTextureDesc.Height = _mirrorHeight;
m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
// create color MSAA texture
GL_CHECK(glGenTextures(1, &m_msaaEyeTexId) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId) );
ovr_CreateMirrorTextureGL(_session, &m_mirrorTextureDesc, &m_mirrorTexture);
GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_RGBA, m_eyeTextureSize.w, m_eyeTextureSize.h, false) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_BORDER) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_BORDER) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) );
// Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes
if (!m_mirrorTexture)
return;
// create MSAA depth buffer
GL_CHECK(glGenTextures(1, &m_msaaDepthBuffer) );
GL_CHECK(glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer) );
// Configure the mirror read buffer
GLuint texId;
ovr_GetMirrorTextureBufferGL(_session, m_mirrorTexture, &texId);
GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO) );
GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0) );
GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
GL_CHECK(glTexImage2DMultisample(GL_TEXTURE_2D_MULTISAMPLE, _msaaSamples, GL_DEPTH_COMPONENT, m_eyeTextureSize.w, m_eyeTextureSize.h, false) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR) );
GL_CHECK(glTexParameteri(GL_TEXTURE_2D_MULTISAMPLE, GL_TEXTURE_MAX_LEVEL, 0) );
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
BX_CHECK(false, "Could not initialize VR buffers!");
}
}
}
void OVRBufferGL::render(const ovrSession& _session)
void OVRRenderGL::startEyeRender(const ovrSession& _session, int _eyeIdx)
{
// set the current eye texture in swap chain
int curIndex;
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain, &curIndex);
ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain, curIndex, &m_eyeTexId);
ovr_GetTextureSwapChainCurrentIndex(_session, m_textureSwapChain[_eyeIdx], &curIndex);
ovr_GetTextureSwapChainBufferGL(_session, m_textureSwapChain[_eyeIdx], curIndex, &m_eyeTexId[_eyeIdx]);
if (0 != m_msaaEyeFbo)
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaEyeFbo) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId, 0) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer, 0) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_msaaEyeFbo[_eyeIdx]) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId[_eyeIdx], 0) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, m_msaaDepthBuffer[_eyeIdx], 0) );
}
else // MSAA disabled? render directly to eye buffer
{
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer, 0) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, m_eyeFbo[_eyeIdx]) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId[_eyeIdx], 0) );
GL_CHECK(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, m_depthBuffer[_eyeIdx], 0) );
}
GL_CHECK(glViewport(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h) );
GL_CHECK(glViewport(0, 0, m_eyeTextureSize[_eyeIdx].w, m_eyeTextureSize[_eyeIdx].h) );
GL_CHECK(glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) );
}
void OVRBufferGL::postRender(const ovrSession& /*_sesion*/)
void OVRRenderGL::postRender(const ovrSession& /*_sesion*/, int _eyeIdx)
{
if (0 != m_msaaEyeFbo && 0 != m_eyeTexId)
if (0 != m_msaaEyeFbo[_eyeIdx] && 0 != m_eyeTexId[_eyeIdx])
{
// blit the contents of MSAA FBO to the regular eye buffer "connected" to the HMD
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_msaaEyeFbo));
GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId, 0) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_msaaEyeFbo[_eyeIdx]));
GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, m_msaaEyeTexId[_eyeIdx], 0) );
GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_READ_FRAMEBUFFER)
, "glCheckFramebufferStatus failed 0x%08x"
, glCheckFramebufferStatus(GL_READ_FRAMEBUFFER) );
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_eyeFbo));
GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId, 0) );
GL_CHECK(glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_eyeFbo[_eyeIdx]));
GL_CHECK(glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, m_eyeTexId[_eyeIdx], 0) );
GL_CHECK(glFramebufferRenderbuffer(GL_DRAW_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
BX_CHECK(GL_FRAMEBUFFER_COMPLETE == glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER)
, "glCheckFramebufferStatus failed 0x%08x"
, glCheckFramebufferStatus(GL_DRAW_FRAMEBUFFER) );
GL_CHECK(glBlitFramebuffer(0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h,
0, 0, m_eyeTextureSize.w, m_eyeTextureSize.h, GL_COLOR_BUFFER_BIT, GL_NEAREST) );
GL_CHECK(glBlitFramebuffer(0, 0, m_eyeTextureSize[_eyeIdx].w, m_eyeTextureSize[_eyeIdx].h,
0, 0, m_eyeTextureSize[_eyeIdx].w, m_eyeTextureSize[_eyeIdx].h, GL_COLOR_BUFFER_BIT, GL_NEAREST) );
GL_CHECK(glBindFramebuffer(GL_FRAMEBUFFER, 0) );
}
}
void OVRBufferGL::destroy(const ovrSession& _session)
void OVRRenderGL::destroy(const ovrSession& _session)
{
GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo) );
GL_CHECK(glDeleteTextures(1, &m_depthBuffer) );
ovr_DestroyTextureSwapChain(_session, m_textureSwapChain);
if (0 != m_msaaEyeFbo)
for (int eye = 0; eye < 2; ++eye)
{
GL_CHECK(glDeleteFramebuffers(1, &m_msaaEyeFbo) );
m_msaaEyeFbo = 0;
GL_CHECK(glDeleteFramebuffers(1, &m_eyeFbo[eye]) );
GL_CHECK(glDeleteTextures(1, &m_depthBuffer[eye]) );
ovr_DestroyTextureSwapChain(_session, m_textureSwapChain[eye]);
m_textureSwapChain[eye] = NULL;
if (0 != m_msaaEyeFbo[eye])
{
GL_CHECK(glDeleteFramebuffers(1, &m_msaaEyeFbo[eye]) );
m_msaaEyeFbo[eye] = 0;
}
if (0 != m_msaaEyeTexId[eye])
{
GL_CHECK(glDeleteTextures(1, &m_msaaEyeTexId[eye]));
m_msaaEyeTexId[eye] = 0;
}
if (0 != m_msaaDepthBuffer[eye])
{
GL_CHECK(glDeleteTextures(1, &m_msaaDepthBuffer[eye]));
m_msaaDepthBuffer[eye] = 0;
}
}
if (0 != m_msaaEyeTexId)
{
GL_CHECK(glDeleteTextures(1, &m_msaaEyeTexId));
m_msaaEyeTexId = 0;
}
if (0 != m_msaaDepthBuffer)
{
GL_CHECK(glDeleteTextures(1, &m_msaaDepthBuffer));
m_msaaDepthBuffer = 0;
}
}
void OVRMirrorGL::create(const ovrSession& _session, int _width, int _height)
{
memset(&m_mirrorTextureDesc, 0, sizeof(m_mirrorTextureDesc) );
m_mirrorTextureDesc.Width = _width;
m_mirrorTextureDesc.Height = _height;
m_mirrorTextureDesc.Format = OVR_FORMAT_R8G8B8A8_UNORM_SRGB;
ovr_CreateMirrorTextureGL(_session, &m_mirrorTextureDesc, &m_mirrorTexture);
// Fallback to doing nothing if mirror was not created. This is to prevent errors with fast window resizes
if (!m_mirrorTexture)
return;
// Configure the mirror read buffer
GLuint texId;
ovr_GetMirrorTextureBufferGL(_session, m_mirrorTexture, &texId);
GL_CHECK(glGenFramebuffers(1, &m_mirrorFBO) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, m_mirrorFBO) );
GL_CHECK(glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texId, 0) );
GL_CHECK(glFramebufferRenderbuffer(GL_READ_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, 0) );
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
BX_CHECK(false, "Could not initialize VR buffers!");
}
}
void OVRMirrorGL::destroy(const ovrSession& _session)
{
if (NULL != m_mirrorTexture)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
@ -3625,7 +3626,7 @@ namespace bgfx { namespace gl
}
}
void OVRMirrorGL::blit(const ovrSession& /*_session*/)
void OVRRenderGL::blitMirror(const ovrSession& /*_session*/)
{
if (NULL != m_mirrorTexture)
{
@ -3638,6 +3639,16 @@ namespace bgfx { namespace gl
GL_CHECK(glBindFramebuffer(GL_READ_FRAMEBUFFER, 0) );
}
}
void OVRRenderGL::preReset(const ovrSession& _session)
{
if (NULL != m_mirrorTexture)
{
GL_CHECK(glDeleteFramebuffers(1, &m_mirrorFBO) );
ovr_DestroyMirrorTexture(_session, m_mirrorTexture);
m_mirrorTexture = NULL;
}
}
#endif // BGFX_CONFIG_USE_OVR
const char* glslTypeName(GLuint _type)

View File

@ -951,29 +951,25 @@ namespace bgfx
namespace bgfx { namespace gl
{
#if BGFX_CONFIG_USE_OVR
struct OVRBufferGL : public OVRBufferI
struct OVRRenderGL : public OVRRenderI
{
virtual void create(const ovrSession& _session, int _eyeIdx, int _msaaSamples) BX_OVERRIDE;
virtual void destroy(const ovrSession& _session) BX_OVERRIDE;
virtual void render(const ovrSession& _session) BX_OVERRIDE;
virtual void postRender(const ovrSession& _sesion) BX_OVERRIDE;
GLuint m_eyeFbo;
GLuint m_eyeTexId;
GLuint m_depthBuffer;
GLuint m_msaaEyeFbo;
GLuint m_msaaEyeTexId;
GLuint m_msaaDepthBuffer;
};
struct OVRMirrorGL : public OVRMirrorI
{
virtual void create(const ovrSession& _session, int _width, int _height) BX_OVERRIDE;
virtual void destroy(const ovrSession& _session) BX_OVERRIDE;
virtual void blit(const ovrSession& _session) BX_OVERRIDE;
OVRRenderGL();
virtual void create(const ovrSession& _session, int _msaaSamples, int _mirrorWidth, int _mirrorHeight);
virtual void destroy(const ovrSession& _session);
virtual void preReset(const ovrSession& _session);
virtual void startEyeRender(const ovrSession& _session, int _eyeIdx);
virtual void postRender(const ovrSession& _session, int _eyeIdx);
virtual void blitMirror(const ovrSession& _session);
GLuint m_eyeFbo[2];
GLuint m_eyeTexId[2];
GLuint m_depthBuffer[2];
GLuint m_msaaEyeFbo[2];
GLuint m_msaaEyeTexId[2];
GLuint m_msaaDepthBuffer[2];
GLuint m_mirrorFBO;
};
#endif // BGFX_CONFIG_USE_OVR
void dumpExtensions(const char* _extensions);