mirror of
https://github.com/overte-org/overte.git
synced 2025-08-07 00:44:38 +02:00
rework shader pre-compilation
This commit is contained in:
parent
372f4390e8
commit
1f354f813c
13 changed files with 75 additions and 45 deletions
|
@ -2862,6 +2862,13 @@ void Application::initializeGL() {
|
||||||
_glWidget->makeCurrent();
|
_glWidget->makeCurrent();
|
||||||
_gpuContext = std::make_shared<gpu::Context>();
|
_gpuContext = std::make_shared<gpu::Context>();
|
||||||
|
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
_gpuContext->pushProgramsToSync(shader::allPrograms(), [this] {
|
||||||
|
_programsCompiled.store(true);
|
||||||
|
}, 1);
|
||||||
|
});
|
||||||
|
|
||||||
DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext);
|
DependencyManager::get<TextureCache>()->setGPUContext(_gpuContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -795,5 +795,7 @@ private:
|
||||||
bool _prevShowTrackedObjects { false };
|
bool _prevShowTrackedObjects { false };
|
||||||
|
|
||||||
std::shared_ptr<ProceduralSkybox> _splashScreen { std::make_shared<ProceduralSkybox>() };
|
std::shared_ptr<ProceduralSkybox> _splashScreen { std::make_shared<ProceduralSkybox>() };
|
||||||
|
std::atomic<bool> _programsCompiled { false };
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif // hifi_Application_h
|
#endif // hifi_Application_h
|
||||||
|
|
|
@ -115,7 +115,7 @@ void Application::paintGL() {
|
||||||
finalFramebuffer = framebufferCache->getFramebuffer();
|
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!displayPlugin->areAllProgramsLoaded()) {
|
if (!_programsCompiled.load()) {
|
||||||
gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) {
|
gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) {
|
||||||
batch.setFramebuffer(finalFramebuffer);
|
batch.setFramebuffer(finalFramebuffer);
|
||||||
batch.enableSkybox(true);
|
batch.enableSkybox(true);
|
||||||
|
|
|
@ -525,6 +525,9 @@ void OpenGLDisplayPlugin::updateFrameData() {
|
||||||
if (_newFrameQueue.size() > 1) {
|
if (_newFrameQueue.size() > 1) {
|
||||||
_droppedFrameRate.increment(_newFrameQueue.size() - 1);
|
_droppedFrameRate.increment(_newFrameQueue.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_gpuContext->processProgramsToSync();
|
||||||
|
|
||||||
while (!_newFrameQueue.empty()) {
|
while (!_newFrameQueue.empty()) {
|
||||||
_currentFrame = _newFrameQueue.front();
|
_currentFrame = _newFrameQueue.front();
|
||||||
_newFrameQueue.pop();
|
_newFrameQueue.pop();
|
||||||
|
@ -633,29 +636,11 @@ void OpenGLDisplayPlugin::internalPresent() {
|
||||||
_presentRate.increment();
|
_presentRate.increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::atomic<bool> OpenGLDisplayPlugin::_allProgramsLoaded { false };
|
|
||||||
unsigned int OpenGLDisplayPlugin::_currentLoadingProgramIndex { 0 };
|
|
||||||
|
|
||||||
bool OpenGLDisplayPlugin::areAllProgramsLoaded() const {
|
|
||||||
return OpenGLDisplayPlugin::_allProgramsLoaded.load();
|
|
||||||
}
|
|
||||||
|
|
||||||
void OpenGLDisplayPlugin::present() {
|
void OpenGLDisplayPlugin::present() {
|
||||||
auto frameId = (uint64_t)presentCount();
|
auto frameId = (uint64_t)presentCount();
|
||||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
|
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
|
||||||
uint64_t startPresent = usecTimestampNow();
|
uint64_t startPresent = usecTimestampNow();
|
||||||
|
|
||||||
if (!OpenGLDisplayPlugin::_allProgramsLoaded.load()) {
|
|
||||||
const auto& programIDs = shader::allPrograms();
|
|
||||||
if (OpenGLDisplayPlugin::_currentLoadingProgramIndex < programIDs.size()) {
|
|
||||||
gpu::doInBatch("createAndSyncProgram", _gpuContext, [&programIDs](gpu::Batch& batch) {
|
|
||||||
batch.createAndSyncProgram(programIDs.at(OpenGLDisplayPlugin::_currentLoadingProgramIndex++));
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
OpenGLDisplayPlugin::_allProgramsLoaded.store(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
{
|
||||||
PROFILE_RANGE_EX(render, "updateFrameData", 0xff00ff00, frameId)
|
PROFILE_RANGE_EX(render, "updateFrameData", 0xff00ff00, frameId)
|
||||||
updateFrameData();
|
updateFrameData();
|
||||||
|
|
|
@ -83,8 +83,6 @@ public:
|
||||||
|
|
||||||
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override;
|
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override;
|
||||||
|
|
||||||
bool areAllProgramsLoaded() const override;
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
friend class PresentThread;
|
friend class PresentThread;
|
||||||
|
|
||||||
|
@ -182,8 +180,5 @@ protected:
|
||||||
// be serialized through this mutex
|
// be serialized through this mutex
|
||||||
mutable Mutex _presentMutex;
|
mutable Mutex _presentMutex;
|
||||||
float _hudAlpha{ 1.0f };
|
float _hudAlpha{ 1.0f };
|
||||||
|
|
||||||
static std::atomic<bool> _allProgramsLoaded;
|
|
||||||
static unsigned int _currentLoadingProgramIndex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -102,8 +102,6 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] =
|
||||||
|
|
||||||
(&::gpu::gl::GLBackend::do_pushProfileRange),
|
(&::gpu::gl::GLBackend::do_pushProfileRange),
|
||||||
(&::gpu::gl::GLBackend::do_popProfileRange),
|
(&::gpu::gl::GLBackend::do_popProfileRange),
|
||||||
|
|
||||||
(&::gpu::gl::GLBackend::do_createAndSyncProgram),
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#define GL_GET_INTEGER(NAME) glGetIntegerv(GL_##NAME, &const_cast<GLint&>(NAME));
|
#define GL_GET_INTEGER(NAME) glGetIntegerv(GL_##NAME, &const_cast<GLint&>(NAME));
|
||||||
|
@ -708,11 +706,6 @@ void GLBackend::do_glColor4f(const Batch& batch, size_t paramOffset) {
|
||||||
(void)CHECK_GL_ERROR();
|
(void)CHECK_GL_ERROR();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLBackend::do_createAndSyncProgram(const Batch& batch, size_t paramOffset) {
|
|
||||||
auto shader = gpu::Shader::createProgram(batch._params[paramOffset + 0]._uint);
|
|
||||||
gpu::gl::GLShader::sync(*this, *shader);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GLBackend::releaseBuffer(GLuint id, Size size) const {
|
void GLBackend::releaseBuffer(GLuint id, Size size) const {
|
||||||
Lock lock(_trashMutex);
|
Lock lock(_trashMutex);
|
||||||
_currentFrameTrash.buffersTrash.push_back({ id, size });
|
_currentFrameTrash.buffersTrash.push_back({ id, size });
|
||||||
|
@ -866,3 +859,7 @@ void GLBackend::setCameraCorrection(const Mat4& correction, const Mat4& prevRend
|
||||||
_pipeline._cameraCorrectionBuffer._buffer->setSubData(0, _transform._correction);
|
_pipeline._cameraCorrectionBuffer._buffer->setSubData(0, _transform._correction);
|
||||||
_pipeline._cameraCorrectionBuffer._buffer->flush();
|
_pipeline._cameraCorrectionBuffer._buffer->flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void GLBackend::syncProgram(const gpu::ShaderPointer& program) {
|
||||||
|
gpu::gl::GLShader::sync(*this, *program);
|
||||||
|
}
|
|
@ -249,6 +249,8 @@ public:
|
||||||
// Let's try to avoid to do that as much as possible!
|
// Let's try to avoid to do that as much as possible!
|
||||||
void syncCache() final override;
|
void syncCache() final override;
|
||||||
|
|
||||||
|
void syncProgram(const gpu::ShaderPointer& program) override;
|
||||||
|
|
||||||
// This is the ugly "download the pixels to sysmem for taking a snapshot"
|
// This is the ugly "download the pixels to sysmem for taking a snapshot"
|
||||||
// Just avoid using it, it's ugly and will break performances
|
// Just avoid using it, it's ugly and will break performances
|
||||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer,
|
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer,
|
||||||
|
@ -380,8 +382,6 @@ public:
|
||||||
virtual void do_setStateBlendFactor(const Batch& batch, size_t paramOffset) final;
|
virtual void do_setStateBlendFactor(const Batch& batch, size_t paramOffset) final;
|
||||||
virtual void do_setStateScissorRect(const Batch& batch, size_t paramOffset) final;
|
virtual void do_setStateScissorRect(const Batch& batch, size_t paramOffset) final;
|
||||||
|
|
||||||
virtual void do_createAndSyncProgram(const Batch& batch, size_t paramOffset) final;
|
|
||||||
|
|
||||||
virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0;
|
virtual GLuint getFramebufferID(const FramebufferPointer& framebuffer) = 0;
|
||||||
virtual GLuint getTextureID(const TexturePointer& texture) final;
|
virtual GLuint getTextureID(const TexturePointer& texture) final;
|
||||||
virtual GLuint getBufferID(const Buffer& buffer) = 0;
|
virtual GLuint getBufferID(const Buffer& buffer) = 0;
|
||||||
|
|
|
@ -759,10 +759,4 @@ void Batch::flush() {
|
||||||
}
|
}
|
||||||
buffer->flush();
|
buffer->flush();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void Batch::createAndSyncProgram(unsigned int programID) {
|
|
||||||
ADD_COMMAND(createAndSyncProgram);
|
|
||||||
|
|
||||||
_params.emplace_back(programID);
|
|
||||||
}
|
}
|
|
@ -289,8 +289,6 @@ public:
|
||||||
|
|
||||||
void _glColor4f(float red, float green, float blue, float alpha);
|
void _glColor4f(float red, float green, float blue, float alpha);
|
||||||
|
|
||||||
void createAndSyncProgram(unsigned int programID);
|
|
||||||
|
|
||||||
// Maybe useful but shoudln't be public. Please convince me otherwise
|
// Maybe useful but shoudln't be public. Please convince me otherwise
|
||||||
// Well porting to gles i need it...
|
// Well porting to gles i need it...
|
||||||
void runLambda(std::function<void()> f);
|
void runLambda(std::function<void()> f);
|
||||||
|
@ -370,8 +368,6 @@ public:
|
||||||
COMMAND_pushProfileRange,
|
COMMAND_pushProfileRange,
|
||||||
COMMAND_popProfileRange,
|
COMMAND_popProfileRange,
|
||||||
|
|
||||||
COMMAND_createAndSyncProgram,
|
|
||||||
|
|
||||||
NUM_COMMANDS,
|
NUM_COMMANDS,
|
||||||
};
|
};
|
||||||
typedef std::vector<Command> Commands;
|
typedef std::vector<Command> Commands;
|
||||||
|
|
|
@ -335,6 +335,39 @@ Size Context::getTextureResourceIdealGPUMemSize() {
|
||||||
return Backend::textureResourceIdealGPUMemSize.getValue();
|
return Backend::textureResourceIdealGPUMemSize.getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Context::pushProgramsToSync(const std::vector<uint32_t>& programIDs, std::function<void()> callback, size_t rate) {
|
||||||
|
std::vector<gpu::ShaderPointer> programs;
|
||||||
|
for (auto programID : programIDs) {
|
||||||
|
programs.push_back(gpu::Shader::createProgram(programID));
|
||||||
|
}
|
||||||
|
pushProgramsToSync(programs, callback, rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::pushProgramsToSync(const std::vector<gpu::ShaderPointer>& programs, std::function<void()> callback, size_t rate) {
|
||||||
|
Lock lock(_programsToSyncMutex);
|
||||||
|
_programsToSyncQueue.emplace(programs, callback, rate == 0 ? programs.size() : rate);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Context::processProgramsToSync() {
|
||||||
|
Lock lock(_programsToSyncMutex);
|
||||||
|
if (!_programsToSyncQueue.empty()) {
|
||||||
|
ProgramsToSync programsToSync = _programsToSyncQueue.front();
|
||||||
|
int numSynced = 0;
|
||||||
|
while (_nextProgramToSyncIndex < programsToSync.programs.size() && numSynced < programsToSync.rate) {
|
||||||
|
auto nextProgram = programsToSync.programs.at(_nextProgramToSyncIndex);
|
||||||
|
_backend->syncProgram(nextProgram);
|
||||||
|
_syncedPrograms.push_back(nextProgram);
|
||||||
|
_nextProgramToSyncIndex++;
|
||||||
|
numSynced++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_nextProgramToSyncIndex == programsToSync.programs.size()) {
|
||||||
|
programsToSync.callback();
|
||||||
|
_nextProgramToSyncIndex = 0;
|
||||||
|
_programsToSyncQueue.pop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
BatchPointer Context::acquireBatch(const char* name) {
|
BatchPointer Context::acquireBatch(const char* name) {
|
||||||
Batch* rawBatch = nullptr;
|
Batch* rawBatch = nullptr;
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
|
@ -61,6 +62,7 @@ public:
|
||||||
|
|
||||||
virtual void render(const Batch& batch) = 0;
|
virtual void render(const Batch& batch) = 0;
|
||||||
virtual void syncCache() = 0;
|
virtual void syncCache() = 0;
|
||||||
|
virtual void syncProgram(const gpu::ShaderPointer& program) = 0;
|
||||||
virtual void recycle() const = 0;
|
virtual void recycle() const = 0;
|
||||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||||
|
|
||||||
|
@ -245,6 +247,20 @@ public:
|
||||||
static Size getTextureResourcePopulatedGPUMemSize();
|
static Size getTextureResourcePopulatedGPUMemSize();
|
||||||
static Size getTextureResourceIdealGPUMemSize();
|
static Size getTextureResourceIdealGPUMemSize();
|
||||||
|
|
||||||
|
struct ProgramsToSync {
|
||||||
|
ProgramsToSync(const std::vector<gpu::ShaderPointer>& programs, std::function<void()> callback, size_t rate) :
|
||||||
|
programs(programs), callback(callback), rate(rate) {}
|
||||||
|
|
||||||
|
std::vector<gpu::ShaderPointer> programs;
|
||||||
|
std::function<void()> callback;
|
||||||
|
size_t rate;
|
||||||
|
};
|
||||||
|
|
||||||
|
void pushProgramsToSync(const std::vector<uint32_t>& programIDs, std::function<void()> callback, size_t rate = 0);
|
||||||
|
void pushProgramsToSync(const std::vector<gpu::ShaderPointer>& programs, std::function<void()> callback, size_t rate = 0);
|
||||||
|
|
||||||
|
void processProgramsToSync();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Context(const Context& context);
|
Context(const Context& context);
|
||||||
|
|
||||||
|
@ -256,6 +272,11 @@ protected:
|
||||||
RangeTimerPointer _frameRangeTimer;
|
RangeTimerPointer _frameRangeTimer;
|
||||||
StereoState _stereo;
|
StereoState _stereo;
|
||||||
|
|
||||||
|
std::mutex _programsToSyncMutex;
|
||||||
|
std::queue<ProgramsToSync> _programsToSyncQueue;
|
||||||
|
gpu::Shaders _syncedPrograms;
|
||||||
|
size_t _nextProgramToSyncIndex { 0 };
|
||||||
|
|
||||||
// Sampled at the end of every frame, the stats of all the counters
|
// Sampled at the end of every frame, the stats of all the counters
|
||||||
mutable ContextStats _frameStats;
|
mutable ContextStats _frameStats;
|
||||||
|
|
||||||
|
|
|
@ -43,6 +43,8 @@ public:
|
||||||
// Let's try to avoid to do that as much as possible!
|
// Let's try to avoid to do that as much as possible!
|
||||||
void syncCache() final { }
|
void syncCache() final { }
|
||||||
|
|
||||||
|
void syncProgram(const gpu::ShaderPointer& program) final {}
|
||||||
|
|
||||||
// This is the ugly "download the pixels to sysmem for taking a snapshot"
|
// This is the ugly "download the pixels to sysmem for taking a snapshot"
|
||||||
// Just avoid using it, it's ugly and will break performances
|
// Just avoid using it, it's ugly and will break performances
|
||||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) final { }
|
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) final { }
|
||||||
|
|
|
@ -217,8 +217,6 @@ public:
|
||||||
|
|
||||||
static const QString& MENU_PATH();
|
static const QString& MENU_PATH();
|
||||||
|
|
||||||
virtual bool areAllProgramsLoaded() const { return true; }
|
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void recommendedFramebufferSizeChanged(const QSize& size);
|
void recommendedFramebufferSizeChanged(const QSize& size);
|
||||||
void resetSensorsRequested();
|
void resetSensorsRequested();
|
||||||
|
|
Loading…
Reference in a new issue