mirror of
https://github.com/overte-org/overte.git
synced 2025-04-17 08:56:36 +02:00
Defer batch execution to the end of the frame generation
This commit is contained in:
parent
fa20898285
commit
a9740b803f
6 changed files with 147 additions and 74 deletions
|
@ -1689,6 +1689,17 @@ void Application::paintGL() {
|
|||
renderArgs._context->syncCache();
|
||||
}
|
||||
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
// Final framebuffer that will be handled to the display-plugin
|
||||
auto finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
|
||||
_gpuContext->beginFrame(finalFramebuffer, getHMDSensorPose());
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::doInBatch(_gpuContext, [&](gpu::Batch& batch) {
|
||||
batch.resetStages();
|
||||
});
|
||||
|
||||
auto inputs = AvatarInputs::getInstance();
|
||||
if (inputs->mirrorVisible()) {
|
||||
PerformanceTimer perfTimer("Mirror");
|
||||
|
@ -1711,10 +1722,6 @@ void Application::paintGL() {
|
|||
QSize size = getDeviceSize();
|
||||
renderArgs._viewport = glm::ivec4(0, 0, size.width(), size.height());
|
||||
_applicationOverlay.renderOverlay(&renderArgs);
|
||||
auto overlayTexture = _applicationOverlay.acquireOverlay();
|
||||
if (overlayTexture) {
|
||||
displayPlugin->submitOverlayTexture(overlayTexture);
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 boomOffset;
|
||||
|
@ -1816,12 +1823,8 @@ void Application::paintGL() {
|
|||
getApplicationCompositor().setFrameInfo(_frameCount, _myCamera.getTransform());
|
||||
|
||||
// Primary rendering pass
|
||||
auto framebufferCache = DependencyManager::get<FramebufferCache>();
|
||||
const QSize size = framebufferCache->getFrameBufferSize();
|
||||
|
||||
// Final framebuffer that will be handled to the display-plugin
|
||||
auto finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
|
||||
{
|
||||
PROFILE_RANGE(__FUNCTION__ "/mainRender");
|
||||
PerformanceTimer perfTimer("mainRender");
|
||||
|
@ -1880,6 +1883,13 @@ void Application::paintGL() {
|
|||
renderArgs._context->enableStereo(false);
|
||||
}
|
||||
|
||||
_gpuContext->endFrame();
|
||||
|
||||
gpu::TexturePointer overlayTexture = _applicationOverlay.acquireOverlay();
|
||||
if (overlayTexture) {
|
||||
displayPlugin->submitOverlayTexture(overlayTexture);
|
||||
}
|
||||
|
||||
// deliver final composited scene to the display plugin
|
||||
{
|
||||
PROFILE_RANGE(__FUNCTION__ "/pluginOutput");
|
||||
|
@ -1900,11 +1910,6 @@ void Application::paintGL() {
|
|||
|
||||
{
|
||||
Stats::getInstance()->setRenderDetails(renderArgs._details);
|
||||
// Reset the gpu::Context Stages
|
||||
// Back to the default framebuffer;
|
||||
gpu::doInBatch(renderArgs._context, [&](gpu::Batch& batch) {
|
||||
batch.resetStages();
|
||||
});
|
||||
}
|
||||
|
||||
uint64_t lastPaintDuration = usecTimestampNow() - lastPaintBegin;
|
||||
|
|
|
@ -46,6 +46,33 @@ Batch::Batch() {
|
|||
_drawCallInfos.reserve(_drawCallInfosMax);
|
||||
}
|
||||
|
||||
Batch::Batch(const Batch& batch_) {
|
||||
Batch& batch = *const_cast<Batch*>(&batch_);
|
||||
_commands.swap(batch._commands);
|
||||
_commandOffsets.swap(batch._commandOffsets);
|
||||
_params.swap(batch._params);
|
||||
_data.swap(batch._data);
|
||||
_invalidModel = batch._invalidModel;
|
||||
_currentModel = batch._currentModel;
|
||||
_objects.swap(batch._objects);
|
||||
_currentNamedCall = batch._currentNamedCall;
|
||||
|
||||
_buffers._items.swap(batch._buffers._items);
|
||||
_textures._items.swap(batch._textures._items);
|
||||
_streamFormats._items.swap(batch._streamFormats._items);
|
||||
_transforms._items.swap(batch._transforms._items);
|
||||
_pipelines._items.swap(batch._pipelines._items);
|
||||
_framebuffers._items.swap(batch._framebuffers._items);
|
||||
_drawCallInfos.swap(batch._drawCallInfos);
|
||||
_queries._items.swap(batch._queries._items);
|
||||
_lambdas._items.swap(batch._lambdas._items);
|
||||
_profileRanges._items.swap(batch._profileRanges._items);
|
||||
_names._items.swap(batch._names._items);
|
||||
_namedData.swap(batch._namedData);
|
||||
_enableStereo = batch._enableStereo;
|
||||
_enableSkybox = batch._enableSkybox;
|
||||
}
|
||||
|
||||
Batch::~Batch() {
|
||||
_commandsMax = std::max(_commands.size(), _commandsMax);
|
||||
_commandOffsetsMax = std::max(_commandOffsets.size(), _commandOffsetsMax);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
#include "Context.h"
|
||||
|
||||
#include "Frame.h"
|
||||
using namespace gpu;
|
||||
|
||||
Context::CreateBackend Context::_createBackendCallback = nullptr;
|
||||
|
@ -20,6 +20,13 @@ Context::Context() {
|
|||
if (_createBackendCallback) {
|
||||
_backend.reset(_createBackendCallback());
|
||||
}
|
||||
|
||||
_frameHandler = [this](Frame& frame){
|
||||
for (size_t i = 0; i < frame.batches.size(); ++i) {
|
||||
_backend->_stereo = frame.stereoStates[i];
|
||||
_backend->render(frame.batches[i]);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
Context::Context(const Context& context) {
|
||||
|
@ -28,6 +35,43 @@ Context::Context(const Context& context) {
|
|||
Context::~Context() {
|
||||
}
|
||||
|
||||
void Context::setFrameHandler(FrameHandler handler) {
|
||||
_frameHandler = handler;
|
||||
}
|
||||
|
||||
#define DEFERRED_RENDERING
|
||||
|
||||
void Context::beginFrame(const FramebufferPointer& outputFramebuffer, const glm::mat4& renderPose) {
|
||||
_currentFrame = Frame();
|
||||
_currentFrame.framebuffer = outputFramebuffer;
|
||||
_currentFrame.pose = renderPose;
|
||||
_frameActive = true;
|
||||
}
|
||||
|
||||
void Context::append(Batch& batch) {
|
||||
if (!_frameActive) {
|
||||
qWarning() << "Batch executed outside of frame boundaries";
|
||||
}
|
||||
#ifdef DEFERRED_RENDERING
|
||||
_currentFrame.batches.emplace_back(batch);
|
||||
_currentFrame.stereoStates.emplace_back(_stereo);
|
||||
#else
|
||||
_backend->_stereo = _stereo;
|
||||
_backend->render(batch);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Context::endFrame() {
|
||||
#ifdef DEFERRED_RENDERING
|
||||
if (_frameHandler) {
|
||||
_frameHandler(_currentFrame);
|
||||
}
|
||||
#endif
|
||||
_currentFrame = Frame();
|
||||
_frameActive = false;
|
||||
}
|
||||
|
||||
|
||||
bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) {
|
||||
if (shader.isProgram() && _makeProgramCallback) {
|
||||
return _makeProgramCallback(shader, bindings);
|
||||
|
@ -35,36 +79,38 @@ bool Context::makeProgram(Shader& shader, const Shader::BindingSet& bindings) {
|
|||
return false;
|
||||
}
|
||||
|
||||
void Context::render(Batch& batch) {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
_backend->render(batch);
|
||||
}
|
||||
|
||||
void Context::enableStereo(bool enable) {
|
||||
_backend->enableStereo(enable);
|
||||
_stereo._enable = enable;
|
||||
}
|
||||
|
||||
bool Context::isStereo() {
|
||||
return _backend->isStereo();
|
||||
return _stereo._enable;
|
||||
}
|
||||
|
||||
void Context::setStereoProjections(const mat4 eyeProjections[2]) {
|
||||
_backend->setStereoProjections(eyeProjections);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
_stereo._eyeProjections[i] = eyeProjections[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Context::setStereoViews(const mat4 eyeViews[2]) {
|
||||
_backend->setStereoViews(eyeViews);
|
||||
void Context::setStereoViews(const mat4 views[2]) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
_stereo._eyeViews[i] = views[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Context::getStereoProjections(mat4* eyeProjections) const {
|
||||
_backend->getStereoProjections(eyeProjections);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
eyeProjections[i] = _stereo._eyeProjections[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Context::getStereoViews(mat4* eyeViews) const {
|
||||
_backend->getStereoViews(eyeViews);
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
eyeViews[i] = _stereo._eyeViews[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Context::syncCache() {
|
||||
PROFILE_RANGE(__FUNCTION__);
|
||||
_backend->syncCache();
|
||||
|
@ -103,12 +149,12 @@ Backend::TransformCamera Backend::TransformCamera::getEyeCamera(int eye, const S
|
|||
if (!_stereo._skybox) {
|
||||
offsetTransform.postTranslate(-Vec3(_stereo._eyeViews[eye][3]));
|
||||
} else {
|
||||
// FIXME: If "skybox" the ipd is set to 0 for now, let s try to propose a better solution for this in the future
|
||||
// FIXME: If "skybox" the ipd is set to 0 for now, let s try to propose a better solution for this in the future
|
||||
}
|
||||
result._projection = _stereo._eyeProjections[eye];
|
||||
result.recomputeDerived(offsetTransform);
|
||||
|
||||
result._stereoInfo = Vec4(1.0f, (float) eye, 0.0f, 0.0f);
|
||||
result._stereoInfo = Vec4(1.0f, (float)eye, 0.0f, 0.0f);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -125,7 +171,7 @@ std::atomic<uint32_t> Context::_textureGPUTransferCount{ 0 };
|
|||
void Context::incrementBufferGPUCount() {
|
||||
_bufferGPUCount++;
|
||||
}
|
||||
void Context::decrementBufferGPUCount() {
|
||||
void Context::decrementBufferGPUCount() {
|
||||
_bufferGPUCount--;
|
||||
}
|
||||
void Context::updateBufferGPUMemoryUsage(Size prevObjectSize, Size newObjectSize) {
|
||||
|
|
|
@ -16,12 +16,13 @@
|
|||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
#include "Forward.h"
|
||||
#include "Batch.h"
|
||||
|
||||
#include "Resource.h"
|
||||
#include "Texture.h"
|
||||
#include "Pipeline.h"
|
||||
#include "Framebuffer.h"
|
||||
#include "Frame.h"
|
||||
|
||||
class QImage;
|
||||
|
||||
|
@ -46,51 +47,11 @@ public:
|
|||
ContextStats(const ContextStats& stats) = default;
|
||||
};
|
||||
|
||||
struct StereoState {
|
||||
bool _enable{ false };
|
||||
bool _skybox{ false };
|
||||
// 0 for left eye, 1 for right eye
|
||||
uint8_t _pass{ 0 };
|
||||
mat4 _eyeViews[2];
|
||||
mat4 _eyeProjections[2];
|
||||
};
|
||||
|
||||
class Backend {
|
||||
public:
|
||||
virtual~ Backend() {};
|
||||
|
||||
virtual void render(Batch& batch) = 0;
|
||||
virtual void enableStereo(bool enable) {
|
||||
_stereo._enable = enable;
|
||||
}
|
||||
|
||||
virtual bool isStereo() {
|
||||
return _stereo._enable;
|
||||
}
|
||||
|
||||
void setStereoProjections(const mat4 eyeProjections[2]) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
_stereo._eyeProjections[i] = eyeProjections[i];
|
||||
}
|
||||
}
|
||||
|
||||
void setStereoViews(const mat4 views[2]) {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
_stereo._eyeViews[i] = views[i];
|
||||
}
|
||||
}
|
||||
|
||||
void getStereoProjections(mat4* eyeProjections) const {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
eyeProjections[i] = _stereo._eyeProjections[i];
|
||||
}
|
||||
}
|
||||
|
||||
void getStereoViews(mat4* eyeViews) const {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
eyeViews[i] = _stereo._eyeViews[i];
|
||||
}
|
||||
}
|
||||
|
||||
virtual void syncCache() = 0;
|
||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||
|
@ -137,8 +98,25 @@ public:
|
|||
static void decrementTextureGPUTransferCount();
|
||||
|
||||
protected:
|
||||
StereoState _stereo;
|
||||
virtual bool isStereo() {
|
||||
return _stereo._enable;
|
||||
}
|
||||
|
||||
void getStereoProjections(mat4* eyeProjections) const {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
eyeProjections[i] = _stereo._eyeProjections[i];
|
||||
}
|
||||
}
|
||||
|
||||
void getStereoViews(mat4* eyeViews) const {
|
||||
for (int i = 0; i < 2; ++i) {
|
||||
eyeViews[i] = _stereo._eyeViews[i];
|
||||
}
|
||||
}
|
||||
|
||||
friend class Context;
|
||||
ContextStats _stats;
|
||||
StereoState _stereo;
|
||||
};
|
||||
|
||||
class Context {
|
||||
|
@ -161,7 +139,10 @@ public:
|
|||
Context();
|
||||
~Context();
|
||||
|
||||
void render(Batch& batch);
|
||||
void setFrameHandler(FrameHandler handler);
|
||||
void beginFrame(const FramebufferPointer& outputFramebuffer, const glm::mat4& renderPose = glm::mat4());
|
||||
void append(Batch& batch);
|
||||
void endFrame();
|
||||
|
||||
void enableStereo(bool enable = true);
|
||||
bool isStereo();
|
||||
|
@ -191,6 +172,10 @@ protected:
|
|||
Context(const Context& context);
|
||||
|
||||
std::unique_ptr<Backend> _backend;
|
||||
bool _frameActive { false };
|
||||
Frame _currentFrame;
|
||||
FrameHandler _frameHandler;
|
||||
StereoState _stereo;
|
||||
|
||||
// This function can only be called by "static Shader::makeProgram()"
|
||||
// makeProgramShader(...) make a program shader ready to be used in a Batch.
|
||||
|
@ -234,7 +219,7 @@ template<typename F>
|
|||
void doInBatch(std::shared_ptr<gpu::Context> context, F f) {
|
||||
gpu::Batch batch;
|
||||
f(batch);
|
||||
context->render(batch);
|
||||
context->append(batch);
|
||||
}
|
||||
|
||||
};
|
||||
|
|
|
@ -86,6 +86,15 @@ namespace gpu {
|
|||
class TextureView;
|
||||
using TextureViews = std::vector<TextureView>;
|
||||
|
||||
struct StereoState {
|
||||
bool _enable{ false };
|
||||
bool _skybox{ false };
|
||||
// 0 for left eye, 1 for right eye
|
||||
uint8 _pass{ 0 };
|
||||
Mat4 _eyeViews[2];
|
||||
Mat4 _eyeProjections[2];
|
||||
};
|
||||
|
||||
namespace gl {
|
||||
class GLBuffer;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ public:
|
|||
glm::mat4 pose;
|
||||
/// The collection of batches which make up the frame
|
||||
std::vector<Batch> batches;
|
||||
std::vector<StereoState> stereoStates;
|
||||
/// The destination framebuffer in which the results will be placed
|
||||
FramebufferPointer framebuffer;
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue