mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 13:14:18 +02:00
Make threaded submit in OpenVR controllable from menu
This commit is contained in:
parent
857f5a69d6
commit
1c89fa2291
4 changed files with 90 additions and 89 deletions
|
@ -338,6 +338,9 @@ Menu::Menu() {
|
|||
// Developer > Render > Throttle FPS If Not Focus
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::ThrottleFPSIfNotFocus, 0, true);
|
||||
|
||||
// Developer > Render > OpenVR threaded submit
|
||||
addCheckableActionToQMenuAndActionHash(renderOptionsMenu, MenuOption::OpenVrThreadedSubmit, 0, true);
|
||||
|
||||
// Developer > Render > Resolution
|
||||
MenuWrapper* resolutionMenu = renderOptionsMenu->addMenu(MenuOption::RenderResolution);
|
||||
QActionGroup* resolutionGroup = new QActionGroup(resolutionMenu);
|
||||
|
|
|
@ -136,6 +136,7 @@ namespace MenuOption {
|
|||
const QString OctreeStats = "Entity Statistics";
|
||||
const QString OnePointCalibration = "1 Point Calibration";
|
||||
const QString OnlyDisplayTopTen = "Only Display Top Ten";
|
||||
const QString OpenVrThreadedSubmit = "OpenVR Threaded Submit";
|
||||
const QString OutputMenu = "Display";
|
||||
const QString Overlays = "Overlays";
|
||||
const QString PackageModel = "Package Model...";
|
||||
|
|
|
@ -35,6 +35,7 @@ Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
|||
|
||||
const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)");
|
||||
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probably shouldn't be hardcoded here
|
||||
const QString OpenVrThreadedSubmit = "OpenVR Threaded Submit"; // this probably shouldn't be hardcoded here
|
||||
|
||||
PoseData _nextRenderPoseData;
|
||||
PoseData _nextSimPoseData;
|
||||
|
@ -49,8 +50,6 @@ bool _openVrDisplayActive { false };
|
|||
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_LEFT{ 0, 0, 0.5f, 1 };
|
||||
static vr::VRTextureBounds_t OPENVR_TEXTURE_BOUNDS_RIGHT{ 0.5f, 0, 1, 1 };
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
|
||||
#define REPROJECTION_BINDING 1
|
||||
|
||||
static const char* HMD_REPROJECTION_VERT = R"SHADER(
|
||||
|
@ -351,8 +350,6 @@ public:
|
|||
OpenVrDisplayPlugin& _plugin;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
bool OpenVrDisplayPlugin::isSupported() const {
|
||||
return openVrSupported();
|
||||
}
|
||||
|
@ -394,6 +391,9 @@ bool OpenVrDisplayPlugin::internalActivate() {
|
|||
return false;
|
||||
}
|
||||
|
||||
_threadedSubmit = _container->isOptionChecked(OpenVrThreadedSubmit);
|
||||
qDebug() << "OpenVR Threaded submit enabled: " << _threadedSubmit;
|
||||
|
||||
_openVrDisplayActive = true;
|
||||
_container->setIsOptionChecked(StandingHMDSensorMode, true);
|
||||
|
||||
|
@ -434,16 +434,16 @@ bool OpenVrDisplayPlugin::internalActivate() {
|
|||
#endif
|
||||
}
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
_submitThread = std::make_shared<OpenVrSubmitThread>(*this);
|
||||
if (!_submitCanvas) {
|
||||
withMainThreadContext([&] {
|
||||
_submitCanvas = std::make_shared<gl::OffscreenContext>();
|
||||
_submitCanvas->create();
|
||||
_submitCanvas->doneCurrent();
|
||||
});
|
||||
if (_threadedSubmit) {
|
||||
_submitThread = std::make_shared<OpenVrSubmitThread>(*this);
|
||||
if (!_submitCanvas) {
|
||||
withMainThreadContext([&] {
|
||||
_submitCanvas = std::make_shared<gl::OffscreenContext>();
|
||||
_submitCanvas->create();
|
||||
_submitCanvas->doneCurrent();
|
||||
});
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return Parent::internalActivate();
|
||||
}
|
||||
|
@ -473,27 +473,27 @@ void OpenVrDisplayPlugin::customizeContext() {
|
|||
|
||||
Parent::customizeContext();
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
_compositeInfos[0].texture = _compositeFramebuffer->getRenderBuffer(0);
|
||||
for (size_t i = 0; i < COMPOSITING_BUFFER_SIZE; ++i) {
|
||||
if (0 != i) {
|
||||
_compositeInfos[i].texture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x, _renderTargetSize.y, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT)));
|
||||
if (_threadedSubmit) {
|
||||
_compositeInfos[0].texture = _compositeFramebuffer->getRenderBuffer(0);
|
||||
for (size_t i = 0; i < COMPOSITING_BUFFER_SIZE; ++i) {
|
||||
if (0 != i) {
|
||||
_compositeInfos[i].texture = gpu::TexturePointer(gpu::Texture::create2D(gpu::Element::COLOR_RGBA_32, _renderTargetSize.x, _renderTargetSize.y, gpu::Sampler(gpu::Sampler::FILTER_MIN_MAG_POINT)));
|
||||
}
|
||||
_compositeInfos[i].textureID = getGLBackend()->getTextureID(_compositeInfos[i].texture, false);
|
||||
}
|
||||
_compositeInfos[i].textureID = getGLBackend()->getTextureID(_compositeInfos[i].texture, false);
|
||||
_submitThread->_canvas = _submitCanvas;
|
||||
_submitThread->start(QThread::HighPriority);
|
||||
}
|
||||
_submitThread->_canvas = _submitCanvas;
|
||||
_submitThread->start(QThread::HighPriority);
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::uncustomizeContext() {
|
||||
Parent::uncustomizeContext();
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
_submitThread->_quit = true;
|
||||
_submitThread->wait();
|
||||
_submitThread.reset();
|
||||
#endif
|
||||
if (_threadedSubmit) {
|
||||
_submitThread->_quit = true;
|
||||
_submitThread->wait();
|
||||
_submitThread.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::resetSensors() {
|
||||
|
@ -582,76 +582,77 @@ bool OpenVrDisplayPlugin::beginFrameRender(uint32_t frameIndex) {
|
|||
}
|
||||
|
||||
void OpenVrDisplayPlugin::compositeLayers() {
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
++_renderingIndex;
|
||||
_renderingIndex %= COMPOSITING_BUFFER_SIZE;
|
||||
if (_threadedSubmit) {
|
||||
++_renderingIndex;
|
||||
_renderingIndex %= COMPOSITING_BUFFER_SIZE;
|
||||
|
||||
auto& newComposite = _compositeInfos[_renderingIndex];
|
||||
newComposite.pose = _currentPresentFrameInfo.presentPose;
|
||||
_compositeFramebuffer->setRenderBuffer(0, newComposite.texture);
|
||||
#endif
|
||||
auto& newComposite = _compositeInfos[_renderingIndex];
|
||||
newComposite.pose = _currentPresentFrameInfo.presentPose;
|
||||
_compositeFramebuffer->setRenderBuffer(0, newComposite.texture);
|
||||
}
|
||||
|
||||
Parent::compositeLayers();
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
newComposite.fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
// https://www.opengl.org/registry/specs/ARB/sync.txt:
|
||||
// > The simple flushing behavior defined by
|
||||
// > SYNC_FLUSH_COMMANDS_BIT will not help when waiting for a fence
|
||||
// > command issued in another context's command stream to complete.
|
||||
// > Applications which block on a fence sync object must take
|
||||
// > additional steps to assure that the context from which the
|
||||
// > corresponding fence command was issued has flushed that command
|
||||
// > to the graphics pipeline.
|
||||
glFlush();
|
||||
if (_threadedSubmit) {
|
||||
auto& newComposite = _compositeInfos[_renderingIndex];
|
||||
newComposite.fence = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
|
||||
// https://www.opengl.org/registry/specs/ARB/sync.txt:
|
||||
// > The simple flushing behavior defined by
|
||||
// > SYNC_FLUSH_COMMANDS_BIT will not help when waiting for a fence
|
||||
// > command issued in another context's command stream to complete.
|
||||
// > Applications which block on a fence sync object must take
|
||||
// > additional steps to assure that the context from which the
|
||||
// > corresponding fence command was issued has flushed that command
|
||||
// > to the graphics pipeline.
|
||||
glFlush();
|
||||
|
||||
if (!newComposite.textureID) {
|
||||
newComposite.textureID = getGLBackend()->getTextureID(newComposite.texture, false);
|
||||
if (!newComposite.textureID) {
|
||||
newComposite.textureID = getGLBackend()->getTextureID(newComposite.texture, false);
|
||||
}
|
||||
withPresentThreadLock([&] {
|
||||
_submitThread->update(newComposite);
|
||||
});
|
||||
}
|
||||
withPresentThreadLock([&] {
|
||||
_submitThread->update(newComposite);
|
||||
});
|
||||
#endif
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::hmdPresent() {
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
_submitThread->waitForPresent();
|
||||
#else
|
||||
GLuint glTexId = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0), false);
|
||||
vr::Texture_t vrTexture{ (void*)glTexId, vr::API_OpenGL, vr::ColorSpace_Auto };
|
||||
vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT);
|
||||
vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT);
|
||||
vr::VRCompositor()->PostPresentHandoff();
|
||||
_presentRate.increment();
|
||||
#endif
|
||||
if (_threadedSubmit) {
|
||||
_submitThread->waitForPresent();
|
||||
} else {
|
||||
GLuint glTexId = getGLBackend()->getTextureID(_compositeFramebuffer->getRenderBuffer(0), false);
|
||||
vr::Texture_t vrTexture { (void*)glTexId, vr::API_OpenGL, vr::ColorSpace_Auto };
|
||||
vr::VRCompositor()->Submit(vr::Eye_Left, &vrTexture, &OPENVR_TEXTURE_BOUNDS_LEFT);
|
||||
vr::VRCompositor()->Submit(vr::Eye_Right, &vrTexture, &OPENVR_TEXTURE_BOUNDS_RIGHT);
|
||||
vr::VRCompositor()->PostPresentHandoff();
|
||||
_presentRate.increment();
|
||||
}
|
||||
}
|
||||
|
||||
void OpenVrDisplayPlugin::postPreview() {
|
||||
PROFILE_RANGE_EX(__FUNCTION__, 0xff00ff00, (uint64_t)_currentFrame->frameIndex)
|
||||
PoseData nextRender, nextSim;
|
||||
nextRender.frameIndex = presentCount();
|
||||
#if !OPENVR_THREADED_SUBMIT
|
||||
vr::VRCompositor()->WaitGetPoses(nextRender.vrPoses, vr::k_unMaxTrackedDeviceCount, nextSim.vrPoses, vr::k_unMaxTrackedDeviceCount);
|
||||
if (_threadedSubmit) {
|
||||
_hmdActivityLevel = _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd);
|
||||
} else {
|
||||
vr::VRCompositor()->WaitGetPoses(nextRender.vrPoses, vr::k_unMaxTrackedDeviceCount, nextSim.vrPoses, vr::k_unMaxTrackedDeviceCount);
|
||||
|
||||
glm::mat4 resetMat;
|
||||
withPresentThreadLock([&] {
|
||||
resetMat = _sensorResetMat;
|
||||
});
|
||||
nextRender.update(resetMat);
|
||||
nextSim.update(resetMat);
|
||||
withPresentThreadLock([&] {
|
||||
_nextSimPoseData = nextSim;
|
||||
});
|
||||
_nextRenderPoseData = nextRender;
|
||||
glm::mat4 resetMat;
|
||||
withPresentThreadLock([&] {
|
||||
resetMat = _sensorResetMat;
|
||||
});
|
||||
nextRender.update(resetMat);
|
||||
nextSim.update(resetMat);
|
||||
withPresentThreadLock([&] {
|
||||
_nextSimPoseData = nextSim;
|
||||
});
|
||||
_nextRenderPoseData = nextRender;
|
||||
|
||||
// FIXME - this looks wrong!
|
||||
_hmdActivityLevel = vr::k_EDeviceActivityLevel_UserInteraction; // _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd);
|
||||
#else
|
||||
_hmdActivityLevel = _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd);
|
||||
#endif
|
||||
// FIXME - this looks wrong!
|
||||
_hmdActivityLevel = vr::k_EDeviceActivityLevel_UserInteraction; // _system->GetTrackedDeviceActivityLevel(vr::k_unTrackedDeviceIndex_Hmd);
|
||||
}
|
||||
}
|
||||
|
||||
bool OpenVrDisplayPlugin::isHmdMounted() const {
|
||||
|
@ -685,3 +686,7 @@ void OpenVrDisplayPlugin::unsuppressKeyboard() {
|
|||
bool OpenVrDisplayPlugin::isKeyboardVisible() {
|
||||
return isOpenVrKeyboardShown();
|
||||
}
|
||||
|
||||
int OpenVrDisplayPlugin::getRequiredThreadCount() const {
|
||||
return Parent::getRequiredThreadCount() + (_threadedSubmit ? 1 : 0);
|
||||
}
|
|
@ -15,9 +15,6 @@
|
|||
|
||||
const float TARGET_RATE_OpenVr = 90.0f; // FIXME: get from sdk tracked device property? This number is vive-only.
|
||||
|
||||
#define OPENVR_THREADED_SUBMIT 0
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
namespace gl {
|
||||
class OffscreenContext;
|
||||
}
|
||||
|
@ -34,7 +31,6 @@ struct CompositeInfo {
|
|||
glm::mat4 pose;
|
||||
GLsync fence{ 0 };
|
||||
};
|
||||
#endif
|
||||
|
||||
class OpenVrDisplayPlugin : public HmdDisplayPlugin {
|
||||
using Parent = HmdDisplayPlugin;
|
||||
|
@ -58,10 +54,8 @@ public:
|
|||
void unsuppressKeyboard() override;
|
||||
bool isKeyboardVisible() override;
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
// Needs an additional thread for VR submission
|
||||
int getRequiredThreadCount() const override { return Parent::getRequiredThreadCount() + 1; }
|
||||
#endif
|
||||
// Possibly needs an additional thread for VR submission
|
||||
int getRequiredThreadCount() const override;
|
||||
|
||||
protected:
|
||||
bool internalActivate() override;
|
||||
|
@ -73,7 +67,6 @@ protected:
|
|||
bool isHmdMounted() const override;
|
||||
void postPreview() override;
|
||||
|
||||
|
||||
private:
|
||||
vr::IVRSystem* _system { nullptr };
|
||||
std::atomic<vr::EDeviceActivityLevel> _hmdActivityLevel { vr::k_EDeviceActivityLevel_Unknown };
|
||||
|
@ -82,12 +75,11 @@ private:
|
|||
|
||||
vr::HmdMatrix34_t _lastGoodHMDPose;
|
||||
mat4 _sensorResetMat;
|
||||
bool _threadedSubmit { true };
|
||||
|
||||
#if OPENVR_THREADED_SUBMIT
|
||||
CompositeInfo::Array _compositeInfos;
|
||||
size_t _renderingIndex { 0 };
|
||||
std::shared_ptr<OpenVrSubmitThread> _submitThread;
|
||||
std::shared_ptr<gl::OffscreenContext> _submitCanvas;
|
||||
friend class OpenVrSubmitThread;
|
||||
#endif
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue