mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01: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();
|
||||
_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);
|
||||
}
|
||||
|
||||
|
|
|
@ -795,5 +795,7 @@ private:
|
|||
bool _prevShowTrackedObjects { false };
|
||||
|
||||
std::shared_ptr<ProceduralSkybox> _splashScreen { std::make_shared<ProceduralSkybox>() };
|
||||
std::atomic<bool> _programsCompiled { false };
|
||||
|
||||
};
|
||||
#endif // hifi_Application_h
|
||||
|
|
|
@ -115,7 +115,7 @@ void Application::paintGL() {
|
|||
finalFramebuffer = framebufferCache->getFramebuffer();
|
||||
}
|
||||
|
||||
if (!displayPlugin->areAllProgramsLoaded()) {
|
||||
if (!_programsCompiled.load()) {
|
||||
gpu::doInBatch("splashFrame", _gpuContext, [&](gpu::Batch& batch) {
|
||||
batch.setFramebuffer(finalFramebuffer);
|
||||
batch.enableSkybox(true);
|
||||
|
|
|
@ -525,6 +525,9 @@ void OpenGLDisplayPlugin::updateFrameData() {
|
|||
if (_newFrameQueue.size() > 1) {
|
||||
_droppedFrameRate.increment(_newFrameQueue.size() - 1);
|
||||
}
|
||||
|
||||
_gpuContext->processProgramsToSync();
|
||||
|
||||
while (!_newFrameQueue.empty()) {
|
||||
_currentFrame = _newFrameQueue.front();
|
||||
_newFrameQueue.pop();
|
||||
|
@ -633,29 +636,11 @@ void OpenGLDisplayPlugin::internalPresent() {
|
|||
_presentRate.increment();
|
||||
}
|
||||
|
||||
std::atomic<bool> OpenGLDisplayPlugin::_allProgramsLoaded { false };
|
||||
unsigned int OpenGLDisplayPlugin::_currentLoadingProgramIndex { 0 };
|
||||
|
||||
bool OpenGLDisplayPlugin::areAllProgramsLoaded() const {
|
||||
return OpenGLDisplayPlugin::_allProgramsLoaded.load();
|
||||
}
|
||||
|
||||
void OpenGLDisplayPlugin::present() {
|
||||
auto frameId = (uint64_t)presentCount();
|
||||
PROFILE_RANGE_EX(render, __FUNCTION__, 0xffffff00, frameId)
|
||||
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)
|
||||
updateFrameData();
|
||||
|
|
|
@ -83,8 +83,6 @@ public:
|
|||
|
||||
void copyTextureToQuickFramebuffer(NetworkTexturePointer source, QOpenGLFramebufferObject* target, GLsync* fenceSync) override;
|
||||
|
||||
bool areAllProgramsLoaded() const override;
|
||||
|
||||
protected:
|
||||
friend class PresentThread;
|
||||
|
||||
|
@ -182,8 +180,5 @@ protected:
|
|||
// be serialized through this mutex
|
||||
mutable Mutex _presentMutex;
|
||||
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_popProfileRange),
|
||||
|
||||
(&::gpu::gl::GLBackend::do_createAndSyncProgram),
|
||||
};
|
||||
|
||||
#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 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 {
|
||||
Lock lock(_trashMutex);
|
||||
_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->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!
|
||||
void syncCache() final override;
|
||||
|
||||
void syncProgram(const gpu::ShaderPointer& program) override;
|
||||
|
||||
// This is the ugly "download the pixels to sysmem for taking a snapshot"
|
||||
// Just avoid using it, it's ugly and will break performances
|
||||
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_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 getTextureID(const TexturePointer& texture) final;
|
||||
virtual GLuint getBufferID(const Buffer& buffer) = 0;
|
||||
|
|
|
@ -759,10 +759,4 @@ void Batch::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 createAndSyncProgram(unsigned int programID);
|
||||
|
||||
// Maybe useful but shoudln't be public. Please convince me otherwise
|
||||
// Well porting to gles i need it...
|
||||
void runLambda(std::function<void()> f);
|
||||
|
@ -370,8 +368,6 @@ public:
|
|||
COMMAND_pushProfileRange,
|
||||
COMMAND_popProfileRange,
|
||||
|
||||
COMMAND_createAndSyncProgram,
|
||||
|
||||
NUM_COMMANDS,
|
||||
};
|
||||
typedef std::vector<Command> Commands;
|
||||
|
|
|
@ -335,6 +335,39 @@ Size Context::getTextureResourceIdealGPUMemSize() {
|
|||
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) {
|
||||
Batch* rawBatch = nullptr;
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
#include <mutex>
|
||||
#include <queue>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
|
@ -61,6 +62,7 @@ public:
|
|||
|
||||
virtual void render(const Batch& batch) = 0;
|
||||
virtual void syncCache() = 0;
|
||||
virtual void syncProgram(const gpu::ShaderPointer& program) = 0;
|
||||
virtual void recycle() const = 0;
|
||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0;
|
||||
|
||||
|
@ -245,6 +247,20 @@ public:
|
|||
static Size getTextureResourcePopulatedGPUMemSize();
|
||||
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:
|
||||
Context(const Context& context);
|
||||
|
||||
|
@ -256,6 +272,11 @@ protected:
|
|||
RangeTimerPointer _frameRangeTimer;
|
||||
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
|
||||
mutable ContextStats _frameStats;
|
||||
|
||||
|
|
|
@ -43,6 +43,8 @@ public:
|
|||
// Let's try to avoid to do that as much as possible!
|
||||
void syncCache() final { }
|
||||
|
||||
void syncProgram(const gpu::ShaderPointer& program) final {}
|
||||
|
||||
// This is the ugly "download the pixels to sysmem for taking a snapshot"
|
||||
// Just avoid using it, it's ugly and will break performances
|
||||
virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) final { }
|
||||
|
|
|
@ -217,8 +217,6 @@ public:
|
|||
|
||||
static const QString& MENU_PATH();
|
||||
|
||||
virtual bool areAllProgramsLoaded() const { return true; }
|
||||
|
||||
signals:
|
||||
void recommendedFramebufferSizeChanged(const QSize& size);
|
||||
void resetSensorsRequested();
|
||||
|
|
Loading…
Reference in a new issue