Merge pull request #5885 from ZappoMan/batchOptimizations

Batch optimizations
This commit is contained in:
samcake 2015-09-23 19:30:51 -07:00
commit 46e9c463fc
14 changed files with 733 additions and 697 deletions

View file

@ -1035,13 +1035,6 @@ void Application::initializeUi() {
updateInputModes();
}
template<typename F>
void doInBatch(RenderArgs* args, F f) {
gpu::Batch batch;
f(batch);
args->_context->render(batch);
}
void Application::paintGL() {
PROFILE_RANGE(__FUNCTION__);
if (nullptr == _displayPlugin) {
@ -1095,12 +1088,12 @@ void Application::paintGL() {
auto mirrorRectDest = glm::ivec4(mirrorRect.z, mirrorRect.y, mirrorRect.x, mirrorRect.w);
auto selfieFbo = DependencyManager::get<FramebufferCache>()->getSelfieFramebuffer();
gpu::Batch batch;
doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
batch.setFramebuffer(selfieFbo);
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR0, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f));
batch.blit(primaryFbo, mirrorRect, selfieFbo, mirrorRectDest);
batch.setFramebuffer(nullptr);
renderArgs._context->render(batch);
});
}
}
@ -1224,7 +1217,7 @@ void Application::paintGL() {
}
displaySide(&renderArgs, _myCamera);
renderArgs._context->enableStereo(false);
doInBatch(&renderArgs, [](gpu::Batch& batch) {
doInBatch(renderArgs._context, [](gpu::Batch& batch) {
batch.setFramebuffer(nullptr);
});
}
@ -1288,9 +1281,9 @@ void Application::paintGL() {
// Reset the gpu::Context Stages
// Back to the default framebuffer;
gpu::Batch batch;
doInBatch(renderArgs._context, [=](gpu::Batch& batch) {
batch.resetStages();
renderArgs._context->render(batch);
});
}
void Application::runTests() {

View file

@ -207,7 +207,7 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
updateTooltips();
//Handle fading and deactivation/activation of UI
gpu::Batch batch;
doInBatch(renderArgs->_context, [=](gpu::Batch& batch) {
auto geometryCache = DependencyManager::get<GeometryCache>();
@ -236,7 +236,7 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
batch.setModelTransform(model);
bindCursorTexture(batch);
geometryCache->renderUnitQuad(batch, vec4(1));
renderArgs->_context->render(batch);
});
}
@ -278,13 +278,8 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
auto geometryCache = DependencyManager::get<GeometryCache>();
gpu::Batch batch;
doInBatch(renderArgs->_context, [=](gpu::Batch& batch) {
geometryCache->useSimpleDrawPipeline(batch);
//batch._glDisable(GL_DEPTH_TEST);
//batch._glDisable(GL_CULL_FACE);
//batch._glBindTexture(GL_TEXTURE_2D, texture);
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
//batch._glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
@ -303,8 +298,6 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
}
#else
{
//batch.setModelTransform(overlayXfm);
batch.setModelTransform(_modelTransform);
drawSphereSection(batch);
}
@ -345,8 +338,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
batch.setModelTransform(reticleXfm);
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
renderArgs->_context->render(batch);
});
}

View file

@ -94,6 +94,8 @@ void ApplicationOverlay::renderOverlay(RenderArgs* renderArgs) {
renderArgs->_context->render(batch);
qDebug() << "ApplicationOverlay::renderOverlay() batch:" << batch.getCacheState();
renderArgs->_batch = nullptr; // so future users of renderArgs don't try to use our batch
CHECK_GL_ERROR();

View file

@ -10,6 +10,7 @@
//
#include "Batch.h"
#include <QDebug>
#include <string.h>
#if defined(NSIGHT_FOUND)
@ -41,7 +42,21 @@ Batch::Batch() :
{
}
Batch::Batch(const CacheState& cacheState) : Batch() {
_commands.reserve(cacheState.commandsSize);
_commandOffsets.reserve(cacheState.offsetsSize);
_params.reserve(cacheState.paramsSize);
_data.reserve(cacheState.dataSize);
}
Batch::CacheState Batch::getCacheState() {
return CacheState(_commands.size(), _commandOffsets.size(), _params.size(), _data.size(),
_buffers.size(), _textures.size(), _streamFormats.size(), _transforms.size(), _pipelines.size(),
_framebuffers.size(), _queries.size());
}
Batch::~Batch() {
//qDebug() << "Batch::~Batch()... " << getCacheState();
}
void Batch::clear() {
@ -358,3 +373,14 @@ void Batch::preExecute() {
}
_namedData.clear();
}
QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) {
debug << "Batch::CacheState[ "
<< "commandsSize:" << cacheState.commandsSize
<< "offsetsSize:" << cacheState.offsetsSize
<< "paramsSize:" << cacheState.paramsSize
<< "dataSize:" << cacheState.dataSize
<< "]";
return debug;
}

View file

@ -22,6 +22,7 @@
#include "Texture.h"
#include "Transform.h"
#if defined(NSIGHT_FOUND)
class ProfileRange {
public:
@ -33,6 +34,8 @@
#define PROFILE_RANGE(name)
#endif
class QDebug;
namespace gpu {
enum ReservedSlot {
@ -70,7 +73,34 @@ public:
using NamedBatchDataMap = std::map<std::string, NamedBatchData>;
class CacheState {
public:
size_t commandsSize;
size_t offsetsSize;
size_t paramsSize;
size_t dataSize;
size_t buffersSize;
size_t texturesSize;
size_t streamFormatsSize;
size_t transformsSize;
size_t pipelinesSize;
size_t framebuffersSize;
size_t queriesSize;
CacheState() : commandsSize(0), offsetsSize(0), paramsSize(0), dataSize(0), buffersSize(0), texturesSize(0),
streamFormatsSize(0), transformsSize(0), pipelinesSize(0), framebuffersSize(0), queriesSize(0) { }
CacheState(size_t commandsSize, size_t offsetsSize, size_t paramsSize, size_t dataSize, size_t buffersSize,
size_t texturesSize, size_t streamFormatsSize, size_t transformsSize, size_t pipelinesSize,
size_t framebuffersSize, size_t queriesSize) :
commandsSize(commandsSize), offsetsSize(offsetsSize), paramsSize(paramsSize), dataSize(dataSize),
buffersSize(buffersSize), texturesSize(texturesSize), streamFormatsSize(streamFormatsSize),
transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { }
};
Batch();
Batch(const CacheState& cacheState);
explicit Batch(const Batch& batch);
~Batch();
@ -78,6 +108,9 @@ public:
void preExecute();
CacheState getCacheState();
// Batches may need to override the context level stereo settings
// if they're performing framebuffer copy operations, like the
// deferred lighting resolution mechanism
@ -307,6 +340,7 @@ public:
public:
std::vector< Cache<T> > _items;
size_t size() const { return _items.size(); }
uint32 cache(const Data& data) {
uint32 offset = _items.size();
_items.push_back(Cache<T>(data));
@ -373,4 +407,6 @@ protected:
}
QDebug& operator<<(QDebug& debug, const gpu::Batch::CacheState& cacheState);
#endif

View file

@ -217,4 +217,13 @@ typedef std::shared_ptr<Context> ContextPointer;
};
template<typename F>
void doInBatch(std::shared_ptr<gpu::Context> context, F f) {
static gpu::Batch::CacheState cacheState;
gpu::Batch batch(cacheState);
f(batch);
context->render(batch);
cacheState = batch.getCacheState();
}
#endif

View file

@ -173,7 +173,7 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint
UserInputMapper::PoseValue leftHand = _poseStateMap[makeInput(JointChannel::LEFT_HAND).getChannel()];
UserInputMapper::PoseValue rightHand = _poseStateMap[makeInput(JointChannel::RIGHT_HAND).getChannel()];
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
auto geometryCache = DependencyManager::get<GeometryCache>();
geometryCache->useSimpleDrawPipeline(batch);
DependencyManager::get<DeferredLightingEffect>()->bindSimpleProgram(batch, true);
@ -188,8 +188,7 @@ void ViveControllerManager::updateRendering(RenderArgs* args, render::ScenePoint
if (rightHand.isValid()) {
renderHand(rightHand, batch, RIGHT_HAND);
}
args->_context->render(batch);
});
}
}

View file

@ -178,9 +178,8 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
gpu::Batch batch;
RenderArgs* args = renderContext->args;
doInBatch(args->_context, [=](gpu::Batch& batch) {
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
float fbWidth = framebufferSize.width();
@ -283,7 +282,5 @@ void AmbientOcclusion::run(const render::SceneContextPointer& sceneContext, cons
batch.setPipeline(getBlendPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Ready to render
args->_context->render((batch));
});
}

View file

@ -100,11 +100,9 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
return;
}
gpu::Batch batch;
batch.enableStereo(false);
RenderArgs* args = renderContext->args;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
auto framebufferCache = DependencyManager::get<FramebufferCache>();
QSize framebufferSize = framebufferCache->getFrameBufferSize();
@ -159,7 +157,5 @@ void Antialiasing::run(const render::SceneContextPointer& sceneContext, const re
batch.setPipeline(getBlendPipeline());
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, texCoordTopLeft, texCoordBottomRight, color);
// Ready to render
args->_context->render((batch));
});
}

View file

@ -340,9 +340,8 @@ void DeferredLightingEffect::addSpotLight(const glm::vec3& position, float radiu
}
void DeferredLightingEffect::prepare(RenderArgs* args) {
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
batch.setStateScissorRect(args->_viewport);
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebuffer();
@ -352,14 +351,13 @@ void DeferredLightingEffect::prepare(RenderArgs* args) {
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR1, glm::vec4(0.0f, 0.0f, 0.0f, 0.0f), true);
const float MAX_SPECULAR_EXPONENT = 128.0f;
batch.clearColorFramebuffer(gpu::Framebuffer::BUFFER_COLOR2, glm::vec4(0.0f, 0.0f, 0.0f, 1.0f / MAX_SPECULAR_EXPONENT), true);
args->_context->render(batch);
});
}
gpu::FramebufferPointer _copyFBO;
void DeferredLightingEffect::render(RenderArgs* args) {
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
// Allocate the parameters buffer used by all the deferred shaders
if (!_deferredTransformBuffer[0]._buffer) {
@ -673,8 +671,7 @@ void DeferredLightingEffect::render(RenderArgs* args) {
batch.setResourceTexture(2, nullptr);
batch.setResourceTexture(3, nullptr);
batch.setUniformBuffer(_directionalLightLocations->deferredTransformBuffer, nullptr);
args->_context->render(batch);
});
// End of the Lighting pass
if (!_pointLights.empty()) {
@ -687,9 +684,9 @@ void DeferredLightingEffect::render(RenderArgs* args) {
void DeferredLightingEffect::copyBack(RenderArgs* args) {
gpu::Batch batch;
batch.enableStereo(false);
auto framebufferCache = DependencyManager::get<FramebufferCache>();
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.enableStereo(false);
QSize framebufferSize = framebufferCache->getFrameBufferSize();
// TODO why doesn't this blit work? It only seems to affect a small area below the rear view mirror.
@ -717,6 +714,7 @@ void DeferredLightingEffect::copyBack(RenderArgs* args) {
batch.draw(gpu::TRIANGLE_STRIP, 4);
args->_context->render(batch);
});
framebufferCache->releaseFramebuffer(_copyFBO);
}

View file

@ -63,7 +63,7 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
assert(renderContext->args);
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
@ -79,7 +79,6 @@ void HitEffect::run(const render::SceneContextPointer& sceneContext, const rende
glm::vec2 bottomLeft(-1.0f, -1.0f);
glm::vec2 topRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, bottomLeft, topRight, color);
args->_context->render((batch));
});
}

View file

@ -32,10 +32,10 @@ using namespace render;
void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
RenderArgs* args = renderContext->args;
doInBatch(args->_context, [=](gpu::Batch& batch) {
auto primaryFbo = DependencyManager::get<FramebufferCache>()->getPrimaryFramebufferDepthColor();
gpu::Batch batch;
batch.enableStereo(false);
batch.setFramebuffer(nullptr);
batch.setFramebuffer(primaryFbo);
@ -47,8 +47,7 @@ void SetupDeferred::run(const SceneContextPointer& sceneContext, const RenderCon
gpu::Framebuffer::BUFFER_COLOR0 |
gpu::Framebuffer::BUFFER_DEPTH,
vec4(vec3(0), 1), 1.0, 0.0, true);
args->_context->render(batch);
});
}
void PrepareDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) {
@ -167,7 +166,7 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
@ -186,11 +185,9 @@ void DrawOpaqueDeferred::run(const SceneContextPointer& sceneContext, const Rend
const float OPAQUE_ALPHA_THRESHOLD = 0.5f;
args->_alphaThreshold = OPAQUE_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOpaqueItems);
args->_context->render((*args->_batch));
args->_batch = nullptr;
});
}
void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext, const ItemIDsBounds& inItems) {
@ -198,7 +195,7 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
assert(renderContext->args->_viewFrustum);
RenderArgs* args = renderContext->args;
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
@ -213,16 +210,12 @@ void DrawTransparentDeferred::run(const SceneContextPointer& sceneContext, const
batch.setProjectionTransform(projMat);
batch.setViewTransform(viewMat);
{
const float TRANSPARENT_ALPHA_THRESHOLD = 0.0f;
args->_alphaThreshold = TRANSPARENT_ALPHA_THRESHOLD;
}
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnTransparentItems);
args->_context->render((*args->_batch));
args->_batch = nullptr;
});
}
gpu::PipelinePointer DrawOverlay3D::_opaquePipeline;
@ -274,8 +267,7 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
}
// Render the items
{
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
args->_whiteTexture = DependencyManager::get<TextureCache>()->getWhiteTexture();
@ -292,10 +284,8 @@ void DrawOverlay3D::run(const SceneContextPointer& sceneContext, const RenderCon
batch.setPipeline(getOpaquePipeline());
batch.setResourceTexture(0, args->_whiteTexture);
renderItems(sceneContext, renderContext, inItems, renderContext->_maxDrawnOverlay3DItems);
args->_context->render((*args->_batch));
});
args->_batch = nullptr;
args->_whiteTexture.reset();
}
}
}

View file

@ -126,8 +126,7 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
}
// Allright, something to render let's do it
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
glm::mat4 projMat;
Transform viewMat;
args->_viewFrustum->evalProjectionMatrix(projMat);
@ -160,6 +159,5 @@ void DrawStatus::run(const SceneContextPointer& sceneContext, const RenderContex
batch.draw(gpu::TRIANGLES, 24, 0);
}
args->_context->render(batch);
});
}

View file

@ -19,6 +19,7 @@
#include <ViewFrustum.h>
#include <gpu/Context.h>
using namespace render;
DrawSceneTask::DrawSceneTask() : Task() {
@ -235,10 +236,10 @@ void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContext
cullItems(sceneContext, renderContext, inItems, culledItems);
RenderArgs* args = renderContext->args;
gpu::Batch theBatch;
args->_batch = &theBatch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
renderItems(sceneContext, renderContext, culledItems);
args->_context->render((*args->_batch));
});
args->_batch = nullptr;
}
@ -257,11 +258,11 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo
inItems.emplace_back(id);
}
RenderArgs* args = renderContext->args;
gpu::Batch batch;
doInBatch(args->_context, [=](gpu::Batch& batch) {
args->_batch = &batch;
batch.enableSkybox(true);
batch.setViewportTransform(args->_viewport);
batch.setStateScissorRect(args->_viewport);
args->_batch = &batch;
glm::mat4 projMat;
Transform viewMat;
@ -272,7 +273,7 @@ void DrawBackground::run(const SceneContextPointer& sceneContext, const RenderCo
batch.setViewTransform(viewMat);
renderItems(sceneContext, renderContext, inItems);
args->_context->render((*args->_batch));
});
args->_batch = nullptr;
}