Reduce number of blits required in stereo 3D by tracking current eye.

This commit is contained in:
Christopher Bruns 2019-03-03 09:35:38 -08:00 committed by Christoph Oelckers
parent 43ec2cf8f2
commit 0fb940632a
5 changed files with 40 additions and 26 deletions

View file

@ -121,20 +121,11 @@ void FGLRenderer::BlurScene(float gameinfobluramount)
mBuffers->UpdateEffectTextures();
auto vrmode = VRMode::GetVRMode(true);
if (vrmode->mEyeCount == 1)
int eyeCount = vrmode->mEyeCount;
for (int i = 0; i < eyeCount; ++i)
{
mBuffers->RenderEffect("BlurScene");
}
else
{
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
{
FGLDebug::PushGroup("EyeBlur");
mBuffers->BlitFromEyeTexture(eye_ix);
mBuffers->RenderEffect("BlurScene");
mBuffers->BlitToEyeTexture(eye_ix);
FGLDebug::PopGroup();
}
if (eyeCount - i > 1) mBuffers->NextEye(eyeCount);
}
}
@ -159,13 +150,12 @@ void FGLRenderer::Flush()
else
{
// Render 2D to eye textures
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
int eyeCount = vrmode->mEyeCount;
for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix)
{
FGLDebug::PushGroup("Eye2D");
mBuffers->BlitFromEyeTexture(eye_ix);
screen->Draw2D();
mBuffers->BlitToEyeTexture(eye_ix);
FGLDebug::PopGroup();
if (eyeCount - eye_ix > 1)
mBuffers->NextEye(eyeCount);
}
screen->Clear2D();

View file

@ -532,7 +532,7 @@ void FGLRenderBuffers::BlitSceneToTexture()
//
//==========================================================================
void FGLRenderBuffers::BlitToEyeTexture(int eye)
void FGLRenderBuffers::BlitToEyeTexture(int eye, bool allowInvalidate)
{
CreateEyeBuffers(eye);
@ -540,7 +540,7 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye)
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mEyeFBs[eye].handle);
glBlitFramebuffer(0, 0, mWidth, mHeight, 0, 0, mWidth, mHeight, GL_COLOR_BUFFER_BIT, GL_NEAREST);
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0)
if ((gl.flags & RFL_INVALIDATE_BUFFER) != 0 && allowInvalidate)
{
GLenum attachments[2] = { GL_COLOR_ATTACHMENT0, GL_DEPTH_STENCIL_ATTACHMENT };
glInvalidateFramebuffer(GL_READ_FRAMEBUFFER, 2, attachments);
@ -552,7 +552,7 @@ void FGLRenderBuffers::BlitToEyeTexture(int eye)
void FGLRenderBuffers::BlitFromEyeTexture(int eye)
{
CreateEyeBuffers(eye);
if (mEyeFBs.Size() <= unsigned(eye)) return;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, mPipelineFB[mCurrentPipelineTexture].handle);
glBindFramebuffer(GL_READ_FRAMEBUFFER, mEyeFBs[eye].handle);
@ -1002,4 +1002,17 @@ void FGLRenderBuffers::RenderEffect(const FString &name)
FGLDebug::PopGroup();
}
// Store the current stereo 3D eye buffer, and Load the next one
int FGLRenderBuffers::NextEye(int eyeCount)
{
int nextEye = (mCurrentEye + 1) % eyeCount;
if (nextEye == mCurrentEye) return mCurrentEye;
BlitToEyeTexture(mCurrentEye);
mCurrentEye = nextEye;
BlitFromEyeTexture(mCurrentEye);
return mCurrentEye;
}
} // namespace OpenGLRenderer

View file

@ -87,9 +87,11 @@ public:
void BindOutputFB();
void BlitToEyeTexture(int eye);
void BlitToEyeTexture(int eye, bool allowInvalidate=true);
void BlitFromEyeTexture(int eye);
void BindEyeTexture(int eye, int texunit);
int NextEye(int eyeCount);
int & CurrentEye() { return mCurrentEye; }
void BindDitherTexture(int texunit);
@ -156,6 +158,7 @@ private:
// Eye buffers
TArray<PPGLTexture> mEyeTextures;
TArray<PPGLFrameBuffer> mEyeFBs;
int mCurrentEye = 0;
// Shadow map texture
PPGLTexture mShadowMapTexture;

View file

@ -163,9 +163,11 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
// Render (potentially) multiple views for stereo 3d
// Fixme. The view offsetting should be done with a static table and not require setup of the entire render state for the mode.
auto vrmode = VRMode::GetVRMode(mainview && toscreen);
for (int eye_ix = 0; eye_ix < vrmode->mEyeCount; ++eye_ix)
const int eyeCount = vrmode->mEyeCount;
mBuffers->CurrentEye() = 0; // always begin at zero, in case eye count changed
for (int eye_ix = 0; eye_ix < eyeCount; ++eye_ix)
{
const auto &eye = vrmode->mEyes[eye_ix];
const auto &eye = vrmode->mEyes[mBuffers->CurrentEye()];
screen->SetViewportRects(bounds);
if (mainview) // Bind the scene frame buffer and turn on draw buffers used by ssao
@ -218,8 +220,8 @@ sector_t * FGLRenderer::RenderViewpoint (FRenderViewpoint &mainvp, AActor * came
PostProcess.Unclock();
}
di->EndDrawInfo();
if (vrmode->mEyeCount > 1)
mBuffers->BlitToEyeTexture(eye_ix);
if (eyeCount - eye_ix > 1)
mBuffers->NextEye(eyeCount);
}
return mainvp.sector;

View file

@ -327,6 +327,12 @@ void FGLRenderer::PresentQuadStereo()
void FGLRenderer::PresentStereo()
{
auto vrmode = VRMode::GetVRMode(true);
const int eyeCount = vrmode->mEyeCount;
// Don't invalidate the bound framebuffer (..., false)
if (eyeCount > 1)
mBuffers->BlitToEyeTexture(mBuffers->CurrentEye(), false);
switch (vr_mode)
{
default: