From a5ad40bee97e14a860335f0fb3a1f74d5fc981fd Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Jul 2015 14:07:28 -0700 Subject: [PATCH 1/9] INtroduce the resetStage command to clear up all cache and state in the gpu::Conference and make sure no more resource are linked --- interface/src/Application.cpp | 6 ++ libraries/gpu/src/gpu/Batch.cpp | 4 ++ libraries/gpu/src/gpu/Batch.h | 5 ++ libraries/gpu/src/gpu/Context.cpp | 1 + libraries/gpu/src/gpu/GLBackend.cpp | 20 +++++++ libraries/gpu/src/gpu/GLBackend.h | 45 ++++++++++---- libraries/gpu/src/gpu/GLBackendInput.cpp | 59 ++++++++++++++++--- libraries/gpu/src/gpu/GLBackendOutput.cpp | 5 ++ libraries/gpu/src/gpu/GLBackendPipeline.cpp | 22 +++++++ libraries/gpu/src/gpu/GLBackendQuery.cpp | 4 ++ libraries/gpu/src/gpu/GLBackendState.cpp | 2 +- libraries/gpu/src/gpu/GLBackendTransform.cpp | 4 +- .../render-utils/src/RenderDeferredTask.cpp | 1 - libraries/render/src/render/DrawTask.cpp | 40 ------------- libraries/render/src/render/DrawTask.h | 8 --- 15 files changed, 156 insertions(+), 70 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index c2be31cfb3..7bfad60eaf 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -996,6 +996,12 @@ void Application::paintGL() { _compositor.displayOverlayTexture(&renderArgs); } + // Reset the gpu::Context Stages + gpu::Batch batch; + batch.resetStages(); + renderArgs._context->render(batch); + + if (!OculusManager::isConnected() || OculusManager::allowSwap()) { PROFILE_RANGE(__FUNCTION__ "/bufferSwap"); _glWidget->swapBuffers(); diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 4ac33d8f14..8815c1bae1 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -288,6 +288,10 @@ void Batch::getQuery(const QueryPointer& query) { _params.push_back(_queries.cache(query)); } +void Batch::resetStages() { + ADD_COMMAND(resetStages); +} + void push_back(Batch::Params& params, const vec3& v) { params.push_back(v.x); params.push_back(v.y); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 58fe03c9cf..5f2c2dd089 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -113,6 +113,9 @@ public: void endQuery(const QueryPointer& query); void getQuery(const QueryPointer& query); + // Reset the stage caches and states + void resetStages(); + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API @@ -186,6 +189,8 @@ public: COMMAND_endQuery, COMMAND_getQuery, + COMMAND_resetStages, + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API diff --git a/libraries/gpu/src/gpu/Context.cpp b/libraries/gpu/src/gpu/Context.cpp index 604f39f46f..6730be33bb 100644 --- a/libraries/gpu/src/gpu/Context.cpp +++ b/libraries/gpu/src/gpu/Context.cpp @@ -45,3 +45,4 @@ void Context::syncCache() { void Context::downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) { _backend->downloadFramebuffer(srcFramebuffer, region, destImage); } + diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 6b1d552be9..51637462f1 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -46,6 +46,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_endQuery), (&::gpu::GLBackend::do_getQuery), + (&::gpu::GLBackend::do_resetStages), + (&::gpu::GLBackend::do_glEnable), (&::gpu::GLBackend::do_glDisable), @@ -128,6 +130,8 @@ GLBackend::GLBackend() : } GLBackend::~GLBackend() { + resetStages(); + killInput(); killTransform(); } @@ -246,6 +250,22 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void GLBackend::do_resetStages(Batch& batch, uint32 paramOffset) { + resetStages(); +} + +void GLBackend::resetStages() { + resetInputStage(); + resetPipelineStage(); + resetTransformStage(); + resetUniformStage(); + resetResourceStage(); + resetOutputStage(); + resetQueryStage(); + + (void) CHECK_GL_ERROR(); +} + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 9d8c9ef805..59a6c1ee7e 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -195,7 +195,7 @@ public: static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS; static const int MAX_NUM_INPUT_BUFFERS = 16; - uint32 getNumInputBuffers() const { return _input._buffersState.size(); } + uint32 getNumInputBuffers() const { return _input._invalidBuffers.size(); } // The State setters called by the GLState::Commands when a new state is assigned @@ -250,12 +250,16 @@ protected: void killInput(); void syncInputStateCache(); void updateInput(); + void resetInputStage(); struct InputStageState { bool _invalidFormat = true; Stream::FormatPointer _format; + typedef std::bitset ActivationCache; + ActivationCache _attributeActivation; + typedef std::bitset BuffersState; - BuffersState _buffersState; + BuffersState _invalidBuffers; Buffers _buffers; Offsets _bufferOffsets; @@ -266,23 +270,20 @@ protected: Offset _indexBufferOffset; Type _indexBufferType; - typedef std::bitset ActivationCache; - ActivationCache _attributeActivation; - GLuint _defaultVAO; InputStageState() : _invalidFormat(true), _format(0), - _buffersState(0), - _buffers(_buffersState.size(), BufferPointer(0)), - _bufferOffsets(_buffersState.size(), 0), - _bufferStrides(_buffersState.size(), 0), - _bufferVBOs(_buffersState.size(), 0), + _attributeActivation(0), + _invalidBuffers(0), + _buffers(_invalidBuffers.size(), BufferPointer(0)), + _bufferOffsets(_invalidBuffers.size(), 0), + _bufferStrides(_invalidBuffers.size(), 0), + _bufferVBOs(_invalidBuffers.size(), 0), _indexBuffer(0), _indexBufferOffset(0), _indexBufferType(UINT32), - _attributeActivation(0), _defaultVAO(0) {} } _input; @@ -298,6 +299,7 @@ protected: // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncTransformStateCache(); void updateTransform(); + void resetTransformStage(); struct TransformStageState { TransformObject _transformObject; TransformCamera _transformCamera; @@ -330,12 +332,20 @@ protected: // Uniform Stage void do_setUniformBuffer(Batch& batch, uint32 paramOffset); - void do_setResourceTexture(Batch& batch, uint32 paramOffset); + void resetUniformStage(); struct UniformStageState { }; + // Resource Stage + void do_setResourceTexture(Batch& batch, uint32 paramOffset); + + void resetResourceStage(); + struct ResourceStageState { + + }; + // Pipeline Stage void do_setPipeline(Batch& batch, uint32 paramOffset); void do_setStateBlendFactor(Batch& batch, uint32 paramOffset); @@ -349,6 +359,7 @@ protected: void syncPipelineStateCache(); // Grab the actual gl state into it's gpu::State equivalent. THis is used by the above call syncPipleineStateCache() void getCurrentGLState(State::Data& state); + void resetPipelineStage(); struct PipelineStageState { @@ -388,6 +399,7 @@ protected: // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncOutputStateCache(); + void resetOutputStage(); struct OutputStageState { @@ -402,6 +414,15 @@ protected: void do_endQuery(Batch& batch, uint32 paramOffset); void do_getQuery(Batch& batch, uint32 paramOffset); + void resetQueryStage(); + struct QueryStageState { + + }; + + // Reset stages + void do_resetStages(Batch& batch, uint32 paramOffset); + void resetStages(); + // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API diff --git a/libraries/gpu/src/gpu/GLBackendInput.cpp b/libraries/gpu/src/gpu/GLBackendInput.cpp index 229b29cd43..9014024914 100755 --- a/libraries/gpu/src/gpu/GLBackendInput.cpp +++ b/libraries/gpu/src/gpu/GLBackendInput.cpp @@ -52,7 +52,7 @@ void GLBackend::do_setInputBuffer(Batch& batch, uint32 paramOffset) { } if (isModified) { - _input._buffersState.set(channel); + _input._invalidBuffers.set(channel); } } } @@ -154,7 +154,7 @@ void GLBackend::updateInput() { _stats._ISNumFormatChanges++; } - if (_input._buffersState.any()) { + if (_input._invalidBuffers.any()) { int numBuffers = _input._buffers.size(); auto buffer = _input._buffers.data(); auto vbo = _input._bufferVBOs.data(); @@ -162,7 +162,7 @@ void GLBackend::updateInput() { auto stride = _input._bufferStrides.data(); for (int bufferNum = 0; bufferNum < numBuffers; bufferNum++) { - if (_input._buffersState.test(bufferNum)) { + if (_input._invalidBuffers.test(bufferNum)) { glBindVertexBuffer(bufferNum, (*vbo), (*offset), (*stride)); } buffer++; @@ -170,11 +170,11 @@ void GLBackend::updateInput() { offset++; stride++; } - _input._buffersState.reset(); + _input._invalidBuffers.reset(); (void) CHECK_GL_ERROR(); } #else - if (_input._invalidFormat || _input._buffersState.any()) { + if (_input._invalidFormat || _input._invalidBuffers.any()) { if (_input._invalidFormat) { InputStageState::ActivationCache newActivation; @@ -232,7 +232,7 @@ void GLBackend::updateInput() { if ((channelIt).first < buffers.size()) { int bufferNum = (channelIt).first; - if (_input._buffersState.test(bufferNum) || _input._invalidFormat) { + if (_input._invalidBuffers.test(bufferNum) || _input._invalidFormat) { // GLuint vbo = gpu::GLBackend::getBufferID((*buffers[bufferNum])); GLuint vbo = _input._bufferVBOs[bufferNum]; if (boundVBO != vbo) { @@ -240,7 +240,7 @@ void GLBackend::updateInput() { (void) CHECK_GL_ERROR(); boundVBO = vbo; } - _input._buffersState[bufferNum] = false; + _input._invalidBuffers[bufferNum] = false; for (unsigned int i = 0; i < channel._slots.size(); i++) { const Stream::Attribute& attrib = attributes.at(channel._slots[i]); @@ -285,6 +285,51 @@ void GLBackend::updateInput() { #endif } +void GLBackend::resetInputStage() { + // Reset index buffer + _input._indexBufferType = UINT32; + _input._indexBufferOffset = 0; + _input._indexBuffer.reset(); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + (void) CHECK_GL_ERROR(); + + +#if defined(SUPPORT_VAO) + // TODO +#else + glBindBuffer(GL_ARRAY_BUFFER, 0); + + size_t i = 0; +#if defined(SUPPORT_LEGACY_OPENGL) + for (; i < NUM_CLASSIC_ATTRIBS; i++) { + glDisableClientState(attributeSlotToClassicAttribName[i]); + } + glVertexPointer(4, GL_FLOAT, 0, 0); + glNormalPointer(GL_FLOAT, 0, 0); + glColorPointer(4, GL_FLOAT, 0, 0); + glTexCoordPointer(4, GL_FLOAT, 0, 0); +#endif + + for (; i < _input._attributeActivation.size(); i++) { + glDisableVertexAttribArray(i); + glVertexAttribPointer(i, 4, GL_FLOAT, GL_FALSE, 0, 0); + } +#endif + + // Reset vertex buffer and format + _input._format.reset(); + _input._invalidFormat = false; + _input._attributeActivation.reset(); + + for (int i = 0; i < _input._buffers.size(); i++) { + _input._buffers[i].reset(); + _input._bufferOffsets[i] = 0; + _input._bufferStrides[i] = 0; + _input._bufferVBOs[i] = 0; + } + _input._invalidBuffers.reset(); + +} void GLBackend::do_setIndexBuffer(Batch& batch, uint32 paramOffset) { _input._indexBufferType = (Type) batch._params[paramOffset + 2]._uint; diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index b37def48e7..6b0bfae635 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -177,6 +177,11 @@ void GLBackend::syncOutputStateCache() { _output._framebuffer.reset(); } +void GLBackend::resetOutputStage() { + _output._framebuffer.reset(); + _output._drawFBO = 0; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); +} void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) { auto framebuffer = batch._framebuffers.get(batch._params[paramOffset]._uint); diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 51a3a24e9b..4a54753af8 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -164,6 +164,24 @@ void GLBackend::updatePipeline() { #endif } +void GLBackend::resetPipelineStage() { + // First reset State to default + State::Signature resetSignature(0); + resetPipelineState(resetSignature); + _pipeline._state = nullptr; + _pipeline._invalidState = false; + + // Second the shader side + _pipeline._invalidProgram = false; + _pipeline._program = 0; + _pipeline._pipeline.reset(); + glUseProgram(0); +} + +void GLBackend::resetUniformStage() { + +} + void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { GLuint slot = batch._params[paramOffset + 3]._uint; BufferPointer uniformBuffer = batch._buffers.get(batch._params[paramOffset + 2]._uint); @@ -188,6 +206,10 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } +void GLBackend::resetResourceStage() { + +} + void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) { GLuint slot = batch._params[paramOffset + 1]._uint; TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); diff --git a/libraries/gpu/src/gpu/GLBackendQuery.cpp b/libraries/gpu/src/gpu/GLBackendQuery.cpp index 39db19dafd..2bdf7c86ad 100644 --- a/libraries/gpu/src/gpu/GLBackendQuery.cpp +++ b/libraries/gpu/src/gpu/GLBackendQuery.cpp @@ -104,3 +104,7 @@ void GLBackend::do_getQuery(Batch& batch, uint32 paramOffset) { (void)CHECK_GL_ERROR(); } } + +void GLBackend::resetQueryStage() { +} + diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index 18fc9ddd3c..618a13e2c4 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -484,7 +484,7 @@ void GLBackend::syncPipelineStateCache() { glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); getCurrentGLState(state); State::Signature signature = State::evalSignature(state); - + _pipeline._stateCache = state; _pipeline._stateSignatureCache = signature; } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 65d9c6ed75..e05e0fc1c0 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -184,4 +184,6 @@ void GLBackend::updateTransform() { _transform._invalidView = _transform._invalidProj = _transform._invalidModel = _transform._invalidViewport = false; } - +void GLBackend::resetTransformStage() { + +} diff --git a/libraries/render-utils/src/RenderDeferredTask.cpp b/libraries/render-utils/src/RenderDeferredTask.cpp index 0c8d19250b..30c8dffc0e 100755 --- a/libraries/render-utils/src/RenderDeferredTask.cpp +++ b/libraries/render-utils/src/RenderDeferredTask.cpp @@ -97,7 +97,6 @@ RenderDeferredTask::RenderDeferredTask() : Task() { _drawStatusJobIndex = _jobs.size() - 1; _jobs.push_back(Job(new DrawOverlay3D::JobModel("DrawOverlay3D"))); - _jobs.push_back(Job(new ResetGLState::JobModel())); // Give ourselves 3 frmaes of timer queries _timerQueries.push_back(std::make_shared()); diff --git a/libraries/render/src/render/DrawTask.cpp b/libraries/render/src/render/DrawTask.cpp index 0e3eba0b53..0aef913d50 100755 --- a/libraries/render/src/render/DrawTask.cpp +++ b/libraries/render/src/render/DrawTask.cpp @@ -216,46 +216,6 @@ void render::renderItems(const SceneContextPointer& sceneContext, const RenderCo } } -void addClearStateCommands(gpu::Batch& batch) { - batch._glDepthMask(true); - batch._glDepthFunc(GL_LESS); - batch._glDisable(GL_CULL_FACE); - - batch._glActiveTexture(GL_TEXTURE0 + 1); - batch._glBindTexture(GL_TEXTURE_2D, 0); - batch._glActiveTexture(GL_TEXTURE0 + 2); - batch._glBindTexture(GL_TEXTURE_2D, 0); - batch._glActiveTexture(GL_TEXTURE0 + 3); - batch._glBindTexture(GL_TEXTURE_2D, 0); - batch._glActiveTexture(GL_TEXTURE0); - batch._glBindTexture(GL_TEXTURE_2D, 0); - - - // deactivate vertex arrays after drawing - batch._glDisableClientState(GL_NORMAL_ARRAY); - batch._glDisableClientState(GL_VERTEX_ARRAY); - batch._glDisableClientState(GL_TEXTURE_COORD_ARRAY); - batch._glDisableClientState(GL_COLOR_ARRAY); - batch._glDisableVertexAttribArray(gpu::Stream::TANGENT); - batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_INDEX); - batch._glDisableVertexAttribArray(gpu::Stream::SKIN_CLUSTER_WEIGHT); - - // bind with 0 to switch back to normal operation - batch._glBindBuffer(GL_ARRAY_BUFFER, 0); - batch._glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - batch._glBindTexture(GL_TEXTURE_2D, 0); - - // Back to no program - batch._glUseProgram(0); -} -void ResetGLState::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { - - gpu::Batch theBatch; - addClearStateCommands(theBatch); - assert(renderContext->args); - renderContext->args->_context->render(theBatch); -} - void DrawLight::run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext) { assert(renderContext->args); assert(renderContext->args->_viewFrustum); diff --git a/libraries/render/src/render/DrawTask.h b/libraries/render/src/render/DrawTask.h index 62810d47f0..ec6656c0dc 100755 --- a/libraries/render/src/render/DrawTask.h +++ b/libraries/render/src/render/DrawTask.h @@ -260,14 +260,6 @@ public: typedef Job::Model JobModel; }; -class ResetGLState { -public: - void run(const SceneContextPointer& sceneContext, const RenderContextPointer& renderContext); - - typedef Job::Model JobModel; -}; - - class DrawSceneTask : public Task { public: From f525a8a245dd9f3f1fa647d3865f0e24ba88d683 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Jul 2015 17:17:56 -0700 Subject: [PATCH 2/9] Removing all the unecessary calls of Batch from the gl legacy time --- interface/src/Application.cpp | 12 +- interface/src/Stars.cpp | 5 +- interface/src/ui/ApplicationOverlay.cpp | 2 +- .../src/RenderableWebEntityItem.cpp | 3 +- libraries/gpu/src/gpu/Batch.h | 52 +--- libraries/gpu/src/gpu/GLBackend.cpp | 250 +----------------- libraries/gpu/src/gpu/GLBackend.h | 25 +- libraries/gpu/src/gpu/GLBackendOutput.cpp | 8 +- libraries/gpu/src/gpu/GLBackendState.cpp | 5 + 9 files changed, 34 insertions(+), 328 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7bfad60eaf..42868166d0 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -995,11 +995,6 @@ void Application::paintGL() { _compositor.displayOverlayTexture(&renderArgs); } - - // Reset the gpu::Context Stages - gpu::Batch batch; - batch.resetStages(); - renderArgs._context->render(batch); if (!OculusManager::isConnected() || OculusManager::allowSwap()) { @@ -1013,6 +1008,13 @@ void Application::paintGL() { _frameCount++; _numFramesSinceLastResize++; Stats::getInstance()->setRenderDetails(renderArgs._details); + + + // Reset the gpu::Context Stages + // Back to the default framebuffer; + gpu::Batch batch; + batch.resetStages(); + renderArgs._context->render(batch); } void Application::runTests() { diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index ebfddee38c..7d09b9b1c3 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -154,6 +154,7 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { auto state = gpu::StatePointer(new gpu::State()); // enable decal blend state->setDepthTest(gpu::State::DepthTest(false)); + state->setAntialiasedLineEnable(true); // line smoothing also smooth points state->setBlendFunction(true, gpu::State::SRC_ALPHA, gpu::State::BLEND_OP_ADD, gpu::State::INV_SRC_ALPHA); _starsPipeline.reset(gpu::Pipeline::create(program, state)); @@ -217,10 +218,10 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { // Render the stars batch.setPipeline(_starsPipeline); - batch._glEnable(GL_PROGRAM_POINT_SIZE_EXT); + /* batch._glEnable(GL_PROGRAM_POINT_SIZE_EXT); batch._glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); batch._glEnable(GL_POINT_SMOOTH); - + */ batch.setInputFormat(streamFormat); batch.setInputBuffer(VERTICES_SLOT, posView); batch.setInputBuffer(COLOR_SLOT, colView); diff --git a/interface/src/ui/ApplicationOverlay.cpp b/interface/src/ui/ApplicationOverlay.cpp index bc10b555e4..acc24ba2be 100644 --- a/interface/src/ui/ApplicationOverlay.cpp +++ b/interface/src/ui/ApplicationOverlay.cpp @@ -117,7 +117,7 @@ void ApplicationOverlay::renderQmlUi(RenderArgs* renderArgs) { batch.setProjectionTransform(mat4()); batch.setModelTransform(Transform()); batch.setViewTransform(Transform()); - batch._glBindTexture(GL_TEXTURE_2D, _uiTexture); + batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _uiTexture); geometryCache->renderUnitQuad(batch, glm::vec4(1)); } diff --git a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp index 7fa615073b..ee1fdfae45 100644 --- a/libraries/entities-renderer/src/RenderableWebEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableWebEntityItem.cpp @@ -178,8 +178,7 @@ void RenderableWebEntityItem::render(RenderArgs* args) { batch.setModelTransform(getTransformToCenter()); bool textured = false, culled = false, emissive = false; if (_texture) { - batch._glActiveTexture(GL_TEXTURE0); - batch._glBindTexture(GL_TEXTURE_2D, _texture); + batch._glActiveBindTexture(GL_TEXTURE0, GL_TEXTURE_2D, _texture); textured = emissive = true; } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 5f2c2dd089..5135d1ac4f 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -94,7 +94,7 @@ public: void setResourceTexture(uint32 slot, const TexturePointer& view); void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView - // Framebuffer Stage + // Ouput Stage void setFramebuffer(const FramebufferPointer& framebuffer); // Clear framebuffer layers @@ -122,28 +122,8 @@ public: // For now, instead of calling the raw gl Call, use the equivalent call on the batch so the call is beeing recorded // THe implementation of these functions is in GLBackend.cpp - void _glEnable(unsigned int cap); - void _glDisable(unsigned int cap); + void _glActiveBindTexture(unsigned int unit, unsigned int target, unsigned int texture); - void _glEnableClientState(unsigned int array); - void _glDisableClientState(unsigned int array); - - void _glCullFace(unsigned int mode); - void _glAlphaFunc(unsigned int func, float ref); - - void _glDepthFunc(unsigned int func); - void _glDepthMask(unsigned char flag); - void _glDepthRange(float zNear, float zFar); - - void _glBindBuffer(unsigned int target, unsigned int buffer); - - void _glBindTexture(unsigned int target, unsigned int texture); - void _glActiveTexture(unsigned int texture); - void _glTexParameteri(unsigned int target, unsigned int pname, int param); - - void _glDrawBuffers(int n, const unsigned int* bufs); - - void _glUseProgram(unsigned int program); void _glUniform1i(int location, int v0); void _glUniform1f(int location, float v0); void _glUniform2f(int location, float v0, float v1); @@ -153,9 +133,6 @@ public: void _glUniform4iv(int location, int count, const int* value); void _glUniformMatrix4fv(int location, int count, unsigned char transpose, const float* value); - void _glEnableVertexAttribArray(int location); - void _glDisableVertexAttribArray(int location); - void _glColor4f(float red, float green, float blue, float alpha); void _glLineWidth(float width); @@ -194,28 +171,8 @@ public: // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API - COMMAND_glEnable, - COMMAND_glDisable, + COMMAND_glActiveBindTexture, - COMMAND_glEnableClientState, - COMMAND_glDisableClientState, - - COMMAND_glCullFace, - COMMAND_glAlphaFunc, - - COMMAND_glDepthFunc, - COMMAND_glDepthMask, - COMMAND_glDepthRange, - - COMMAND_glBindBuffer, - - COMMAND_glBindTexture, - COMMAND_glActiveTexture, - COMMAND_glTexParameteri, - - COMMAND_glDrawBuffers, - - COMMAND_glUseProgram, COMMAND_glUniform1i, COMMAND_glUniform1f, COMMAND_glUniform2f, @@ -225,9 +182,6 @@ public: COMMAND_glUniform4iv, COMMAND_glUniformMatrix4fv, - COMMAND_glEnableVertexAttribArray, - COMMAND_glDisableVertexAttribArray, - COMMAND_glColor4f, COMMAND_glLineWidth, diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 51637462f1..8db192b827 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -48,28 +48,8 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_resetStages), - (&::gpu::GLBackend::do_glEnable), - (&::gpu::GLBackend::do_glDisable), + (&::gpu::GLBackend::do_glActiveBindTexture), - (&::gpu::GLBackend::do_glEnableClientState), - (&::gpu::GLBackend::do_glDisableClientState), - - (&::gpu::GLBackend::do_glCullFace), - (&::gpu::GLBackend::do_glAlphaFunc), - - (&::gpu::GLBackend::do_glDepthFunc), - (&::gpu::GLBackend::do_glDepthMask), - (&::gpu::GLBackend::do_glDepthRange), - - (&::gpu::GLBackend::do_glBindBuffer), - - (&::gpu::GLBackend::do_glBindTexture), - (&::gpu::GLBackend::do_glActiveTexture), - (&::gpu::GLBackend::do_glTexParameteri), - - (&::gpu::GLBackend::do_glDrawBuffers), - - (&::gpu::GLBackend::do_glUseProgram), (&::gpu::GLBackend::do_glUniform1i), (&::gpu::GLBackend::do_glUniform1f), (&::gpu::GLBackend::do_glUniform2f), @@ -79,9 +59,6 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_glUniform4iv), (&::gpu::GLBackend::do_glUniformMatrix4fv), - (&::gpu::GLBackend::do_glEnableVertexAttribArray), - (&::gpu::GLBackend::do_glDisableVertexAttribArray), - (&::gpu::GLBackend::do_glColor4f), (&::gpu::GLBackend::do_glLineWidth), }; @@ -275,211 +252,24 @@ void GLBackend::resetStages() { //#define DO_IT_NOW(call, offset) runLastCommand(); #define DO_IT_NOW(call, offset) - -void Batch::_glEnable(GLenum cap) { - ADD_COMMAND_GL(glEnable); - - _params.push_back(cap); - - DO_IT_NOW(_glEnable, 1); -} -void GLBackend::do_glEnable(Batch& batch, uint32 paramOffset) { - glEnable(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDisable(GLenum cap) { - ADD_COMMAND_GL(glDisable); - - _params.push_back(cap); - - DO_IT_NOW(_glDisable, 1); -} -void GLBackend::do_glDisable(Batch& batch, uint32 paramOffset) { - glDisable(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glEnableClientState(GLenum array) { - ADD_COMMAND_GL(glEnableClientState); - - _params.push_back(array); - - DO_IT_NOW(_glEnableClientState, 1); -} -void GLBackend::do_glEnableClientState(Batch& batch, uint32 paramOffset) { - glEnableClientState(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDisableClientState(GLenum array) { - ADD_COMMAND_GL(glDisableClientState); - - _params.push_back(array); - - DO_IT_NOW(_glDisableClientState, 1); -} -void GLBackend::do_glDisableClientState(Batch& batch, uint32 paramOffset) { - glDisableClientState(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glCullFace(GLenum mode) { - ADD_COMMAND_GL(glCullFace); - - _params.push_back(mode); - - DO_IT_NOW(_glCullFace, 1); -} -void GLBackend::do_glCullFace(Batch& batch, uint32 paramOffset) { - glCullFace(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glAlphaFunc(GLenum func, GLclampf ref) { - ADD_COMMAND_GL(glAlphaFunc); - - _params.push_back(ref); - _params.push_back(func); - - DO_IT_NOW(_glAlphaFunc, 2); -} -void GLBackend::do_glAlphaFunc(Batch& batch, uint32 paramOffset) { - glAlphaFunc( - batch._params[paramOffset + 1]._uint, - batch._params[paramOffset + 0]._float); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDepthFunc(GLenum func) { - ADD_COMMAND_GL(glDepthFunc); - - _params.push_back(func); - - DO_IT_NOW(_glDepthFunc, 1); -} -void GLBackend::do_glDepthFunc(Batch& batch, uint32 paramOffset) { - glDepthFunc(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDepthMask(GLboolean flag) { - ADD_COMMAND_GL(glDepthMask); - - _params.push_back(flag); - - DO_IT_NOW(_glDepthMask, 1); -} -void GLBackend::do_glDepthMask(Batch& batch, uint32 paramOffset) { - glDepthMask(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDepthRange(GLfloat zNear, GLfloat zFar) { - ADD_COMMAND_GL(glDepthRange); - - _params.push_back(zFar); - _params.push_back(zNear); - - DO_IT_NOW(_glDepthRange, 2); -} -void GLBackend::do_glDepthRange(Batch& batch, uint32 paramOffset) { - glDepthRange( - batch._params[paramOffset + 1]._float, - batch._params[paramOffset + 0]._float); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glBindBuffer(GLenum target, GLuint buffer) { - ADD_COMMAND_GL(glBindBuffer); - - _params.push_back(buffer); - _params.push_back(target); - - DO_IT_NOW(_glBindBuffer, 2); -} -void GLBackend::do_glBindBuffer(Batch& batch, uint32 paramOffset) { - glBindBuffer( - batch._params[paramOffset + 1]._uint, - batch._params[paramOffset + 0]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glBindTexture(GLenum target, GLuint texture) { - ADD_COMMAND_GL(glBindTexture); +void Batch::_glActiveBindTexture(GLenum unit, GLenum target, GLuint texture) { + ADD_COMMAND_GL(glActiveBindTexture); _params.push_back(texture); _params.push_back(target); + _params.push_back(unit); - DO_IT_NOW(_glBindTexture, 2); + + DO_IT_NOW(_glActiveBindTexture, 3); } -void GLBackend::do_glBindTexture(Batch& batch, uint32 paramOffset) { +void GLBackend::do_glActiveBindTexture(Batch& batch, uint32 paramOffset) { + glActiveTexture(batch._params[paramOffset + 2]._uint); glBindTexture( batch._params[paramOffset + 1]._uint, batch._params[paramOffset + 0]._uint); (void) CHECK_GL_ERROR(); } -void Batch::_glActiveTexture(GLenum texture) { - ADD_COMMAND_GL(glActiveTexture); - - _params.push_back(texture); - - DO_IT_NOW(_glActiveTexture, 1); -} -void GLBackend::do_glActiveTexture(Batch& batch, uint32 paramOffset) { - glActiveTexture(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glTexParameteri(GLenum target, GLenum pname, GLint param) { - ADD_COMMAND_GL(glTexParameteri); - - _params.push_back(param); - _params.push_back(pname); - _params.push_back(target); - - DO_IT_NOW(glTexParameteri, 3); -} -void GLBackend::do_glTexParameteri(Batch& batch, uint32 paramOffset) { - glTexParameteri(batch._params[paramOffset + 2]._uint, - batch._params[paramOffset + 1]._uint, - batch._params[paramOffset + 0]._int); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDrawBuffers(GLsizei n, const GLenum* bufs) { - ADD_COMMAND_GL(glDrawBuffers); - - _params.push_back(cacheData(n * sizeof(GLenum), bufs)); - _params.push_back(n); - - DO_IT_NOW(_glDrawBuffers, 2); -} -void GLBackend::do_glDrawBuffers(Batch& batch, uint32 paramOffset) { - glDrawBuffers( - batch._params[paramOffset + 1]._uint, - (const GLenum*)batch.editData(batch._params[paramOffset + 0]._uint)); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glUseProgram(GLuint program) { - ADD_COMMAND_GL(glUseProgram); - - _params.push_back(program); - - DO_IT_NOW(_glUseProgram, 1); -} -void GLBackend::do_glUseProgram(Batch& batch, uint32 paramOffset) { - - _pipeline._program = batch._params[paramOffset]._uint; - // for this call we still want to execute the glUseProgram in the order of the glCOmmand to avoid any issue - _pipeline._invalidProgram = false; - glUseProgram(_pipeline._program); - - (void) CHECK_GL_ERROR(); -} - void Batch::_glUniform1i(GLint location, GLint v0) { if (location < 0) { return; @@ -680,30 +470,6 @@ void GLBackend::do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); } -void Batch::_glEnableVertexAttribArray(GLint location) { - ADD_COMMAND_GL(glEnableVertexAttribArray); - - _params.push_back(location); - - DO_IT_NOW(_glEnableVertexAttribArray, 1); -} -void GLBackend::do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset) { - glEnableVertexAttribArray(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - -void Batch::_glDisableVertexAttribArray(GLint location) { - ADD_COMMAND_GL(glDisableVertexAttribArray); - - _params.push_back(location); - - DO_IT_NOW(_glDisableVertexAttribArray, 1); -} -void GLBackend::do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset) { - glDisableVertexAttribArray(batch._params[paramOffset]._uint); - (void) CHECK_GL_ERROR(); -} - void Batch::_glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { ADD_COMMAND_GL(glColor4f); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 59a6c1ee7e..843e5d2006 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -426,28 +426,8 @@ protected: // TODO: As long as we have gl calls explicitely issued from interface // code, we need to be able to record and batch these calls. THe long // term strategy is to get rid of any GL calls in favor of the HIFI GPU API - void do_glEnable(Batch& batch, uint32 paramOffset); - void do_glDisable(Batch& batch, uint32 paramOffset); + void do_glActiveBindTexture(Batch& batch, uint32 paramOffset); - void do_glEnableClientState(Batch& batch, uint32 paramOffset); - void do_glDisableClientState(Batch& batch, uint32 paramOffset); - - void do_glCullFace(Batch& batch, uint32 paramOffset); - void do_glAlphaFunc(Batch& batch, uint32 paramOffset); - - void do_glDepthFunc(Batch& batch, uint32 paramOffset); - void do_glDepthMask(Batch& batch, uint32 paramOffset); - void do_glDepthRange(Batch& batch, uint32 paramOffset); - - void do_glBindBuffer(Batch& batch, uint32 paramOffset); - - void do_glBindTexture(Batch& batch, uint32 paramOffset); - void do_glActiveTexture(Batch& batch, uint32 paramOffset); - void do_glTexParameteri(Batch& batch, uint32 paramOffset); - - void do_glDrawBuffers(Batch& batch, uint32 paramOffset); - - void do_glUseProgram(Batch& batch, uint32 paramOffset); void do_glUniform1i(Batch& batch, uint32 paramOffset); void do_glUniform1f(Batch& batch, uint32 paramOffset); void do_glUniform2f(Batch& batch, uint32 paramOffset); @@ -457,9 +437,6 @@ protected: void do_glUniform4iv(Batch& batch, uint32 paramOffset); void do_glUniformMatrix4fv(Batch& batch, uint32 paramOffset); - void do_glEnableVertexAttribArray(Batch& batch, uint32 paramOffset); - void do_glDisableVertexAttribArray(Batch& batch, uint32 paramOffset); - void do_glColor4f(Batch& batch, uint32 paramOffset); void do_glLineWidth(Batch& batch, uint32 paramOffset); diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index 6b0bfae635..d57ef57d78 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -178,9 +178,11 @@ void GLBackend::syncOutputStateCache() { } void GLBackend::resetOutputStage() { - _output._framebuffer.reset(); - _output._drawFBO = 0; - glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + if (_output._framebuffer) { + _output._framebuffer.reset(); + _output._drawFBO = 0; + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); + } } void GLBackend::do_setFramebuffer(Batch& batch, uint32 paramOffset) { diff --git a/libraries/gpu/src/gpu/GLBackendState.cpp b/libraries/gpu/src/gpu/GLBackendState.cpp index 618a13e2c4..bd683e0136 100644 --- a/libraries/gpu/src/gpu/GLBackendState.cpp +++ b/libraries/gpu/src/gpu/GLBackendState.cpp @@ -482,6 +482,11 @@ void GLBackend::syncPipelineStateCache() { State::Data state; glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); + + // Point size is always on + glEnable(GL_PROGRAM_POINT_SIZE_EXT); + glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); + getCurrentGLState(state); State::Signature signature = State::evalSignature(state); From 66c5aec744273781b735c10b5d625d761d3b95b5 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Mon, 27 Jul 2015 17:34:46 -0700 Subject: [PATCH 3/9] Remove commented dead code --- interface/src/Stars.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/interface/src/Stars.cpp b/interface/src/Stars.cpp index 7d09b9b1c3..c1e65086bf 100644 --- a/interface/src/Stars.cpp +++ b/interface/src/Stars.cpp @@ -218,10 +218,6 @@ void Stars::render(RenderArgs* renderArgs, float alpha) { // Render the stars batch.setPipeline(_starsPipeline); - /* batch._glEnable(GL_PROGRAM_POINT_SIZE_EXT); - batch._glEnable(GL_VERTEX_PROGRAM_POINT_SIZE); - batch._glEnable(GL_POINT_SMOOTH); - */ batch.setInputFormat(streamFormat); batch.setInputBuffer(VERTICES_SLOT, posView); batch.setInputBuffer(COLOR_SLOT, colView); From df9b66d2679c3740c8d885d5d02c2e37ea098e22 Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Tue, 28 Jul 2015 15:08:52 -0700 Subject: [PATCH 4/9] Implement the uniform buffer and resource texture cache and their reset --- libraries/gpu/src/gpu/GLBackend.h | 30 +++++-- libraries/gpu/src/gpu/GLBackendPipeline.cpp | 86 +++++++++++++++++++-- 2 files changed, 103 insertions(+), 13 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 843e5d2006..215e01689b 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -197,6 +197,15 @@ public: uint32 getNumInputBuffers() const { return _input._invalidBuffers.size(); } + // this is the maximum per shader stage on the low end apple + // TODO make it platform dependant at init time + static const int MAX_NUM_UNIFORM_BUFFERS = 12; + uint32 getMaxNumUniformBuffers() const { return MAX_NUM_UNIFORM_BUFFERS; } + + // this is the maximum per shader stage on the low end apple + // TODO make it platform dependant at init time + static const int MAX_NUM_RESOURCE_TEXTURES = 16; + uint32 getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; } // The State setters called by the GLState::Commands when a new state is assigned void do_setStateFillMode(int32 mode); @@ -332,19 +341,30 @@ protected: // Uniform Stage void do_setUniformBuffer(Batch& batch, uint32 paramOffset); - + + void releaseUniformBuffer(int slot); void resetUniformStage(); struct UniformStageState { - - }; + Buffers _buffers; + + UniformStageState(): + _buffers(MAX_NUM_UNIFORM_BUFFERS, nullptr) + {} + } _uniform; // Resource Stage void do_setResourceTexture(Batch& batch, uint32 paramOffset); + void releaseResourceTexture(int slot); void resetResourceStage(); struct ResourceStageState { - - }; + Textures _textures; + + ResourceStageState(): + _textures(MAX_NUM_RESOURCE_TEXTURES, nullptr) + {} + + } _resource; // Pipeline Stage void do_setPipeline(Batch& batch, uint32 paramOffset); diff --git a/libraries/gpu/src/gpu/GLBackendPipeline.cpp b/libraries/gpu/src/gpu/GLBackendPipeline.cpp index 4a54753af8..090dd4ad31 100755 --- a/libraries/gpu/src/gpu/GLBackendPipeline.cpp +++ b/libraries/gpu/src/gpu/GLBackendPipeline.cpp @@ -178,8 +178,27 @@ void GLBackend::resetPipelineStage() { glUseProgram(0); } + +void GLBackend::releaseUniformBuffer(int slot) { +#if (GPU_FEATURE_PROFILE == GPU_CORE) + auto& buf = _uniform._buffers[slot]; + if (buf) { + auto* object = Backend::getGPUObject(*buf); + if (object) { + GLuint bo = object->_buffer; + glBindBufferBase(GL_UNIFORM_BUFFER, slot, 0); // RELEASE + + (void) CHECK_GL_ERROR(); + } + buf.reset(); + } +#endif +} + void GLBackend::resetUniformStage() { - + for (int i = 0; i < _uniform._buffers.size(); i++) { + releaseUniformBuffer(i); + } } void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { @@ -188,9 +207,31 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { GLintptr rangeStart = batch._params[paramOffset + 1]._uint; GLsizeiptr rangeSize = batch._params[paramOffset + 0]._uint; + + + #if (GPU_FEATURE_PROFILE == GPU_CORE) - GLuint bo = getBufferID(*uniformBuffer); - glBindBufferRange(GL_UNIFORM_BUFFER, slot, bo, rangeStart, rangeSize); + if (!uniformBuffer) { + releaseUniformBuffer(slot); + return; + } + + // check cache before thinking + if (_uniform._buffers[slot] == uniformBuffer) { + return; + } + + // Sync BufferObject + auto* object = GLBackend::syncGPUObject(*uniformBuffer); + if (object) { + glBindBufferRange(GL_UNIFORM_BUFFER, slot, object->_buffer, rangeStart, rangeSize); + + _uniform._buffers[slot] = uniformBuffer; + (void) CHECK_GL_ERROR(); + } else { + releaseResourceTexture(slot); + return; + } #else // because we rely on the program uniform mechanism we need to have // the program bound, thank you MacOSX Legacy profile. @@ -202,23 +243,49 @@ void GLBackend::do_setUniformBuffer(Batch& batch, uint32 paramOffset) { // NOT working so we ll stick to the uniform float array until we move to core profile // GLuint bo = getBufferID(*uniformBuffer); //glUniformBufferEXT(_shader._program, slot, bo); -#endif + (void) CHECK_GL_ERROR(); + +#endif +} + +void GLBackend::releaseResourceTexture(int slot) { + auto& tex = _resource._textures[slot]; + if (tex) { + auto* object = Backend::getGPUObject(*tex); + if (object) { + GLuint to = object->_texture; + GLuint target = object->_target; + glActiveTexture(GL_TEXTURE0 + slot); + glBindTexture(target, 0); // RELEASE + + (void) CHECK_GL_ERROR(); + } + tex.reset(); + } } void GLBackend::resetResourceStage() { - + for (int i = 0; i < _resource._textures.size(); i++) { + releaseResourceTexture(i); + } } void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) { GLuint slot = batch._params[paramOffset + 1]._uint; - TexturePointer uniformTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); + TexturePointer resourceTexture = batch._textures.get(batch._params[paramOffset + 0]._uint); - if (!uniformTexture) { + if (!resourceTexture) { + releaseResourceTexture(slot); + return; + } + // check cache before thinking + if (_resource._textures[slot] == resourceTexture) { return; } - GLTexture* object = GLBackend::syncGPUObject(*uniformTexture); + // Always make sure the GLObject is in sync + GLTexture* object = GLBackend::syncGPUObject(*resourceTexture); if (object) { GLuint to = object->_texture; GLuint target = object->_target; @@ -227,7 +294,10 @@ void GLBackend::do_setResourceTexture(Batch& batch, uint32 paramOffset) { (void) CHECK_GL_ERROR(); + _resource._textures[slot] = resourceTexture; + } else { + releaseResourceTexture(slot); return; } } From 9cf3dfd3f7ef47469f87773daac5de87fba2b90f Mon Sep 17 00:00:00 2001 From: samcake Date: Tue, 28 Jul 2015 15:49:39 -0700 Subject: [PATCH 5/9] test this on windows ? --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index b7522633ba..8f0a0e864f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1014,7 +1014,7 @@ void Application::paintGL() { // Back to the default framebuffer; gpu::Batch batch; batch.resetStages(); - renderArgs._context->render(batch); + // renderArgs._context->render(batch); } void Application::runTests() { From 8b7ad9cfcbaa68ab360c0a7561e5af5da8ee3c6e Mon Sep 17 00:00:00 2001 From: Sam Gateau Date: Wed, 29 Jul 2015 17:13:48 -0700 Subject: [PATCH 6/9] merge with upstream --- interface/src/Application.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 5845267f72..1dc2878008 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1019,7 +1019,9 @@ void Application::paintGL() { // Back to the default framebuffer; gpu::Batch batch; batch.resetStages(); - // renderArgs._context->render(batch); + // TODO: Testing the water here, it is maybe not needed at all, + // i would like to keep it like that until we merge with DisplayPlugin + // renderArgs._context->render(batch); } void Application::runTests() { From ac46b2bd1733ba18fe6e1db99a1ee204c7408bdc Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 29 Jul 2015 17:38:23 -0700 Subject: [PATCH 7/9] Keep the resetstage in --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 1dc2878008..8f37174c18 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1021,7 +1021,7 @@ void Application::paintGL() { batch.resetStages(); // TODO: Testing the water here, it is maybe not needed at all, // i would like to keep it like that until we merge with DisplayPlugin - // renderArgs._context->render(batch); + renderArgs._context->render(batch); } void Application::runTests() { From e32e45ed2b8faefc74c0f884d96eb9e1ee3a8865 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 29 Jul 2015 18:06:46 -0700 Subject: [PATCH 8/9] make sure the writting mask is on for depth buffer --- interface/src/Application.cpp | 2 -- libraries/gpu/src/gpu/GLBackendOutput.cpp | 12 ++++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8f37174c18..1c91f9282c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1019,8 +1019,6 @@ void Application::paintGL() { // Back to the default framebuffer; gpu::Batch batch; batch.resetStages(); - // TODO: Testing the water here, it is maybe not needed at all, - // i would like to keep it like that until we merge with DisplayPlugin renderArgs._context->render(batch); } diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index d57ef57d78..c898b4a843 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -209,10 +209,17 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { int stencil = batch._params[paramOffset + 1]._int; int useScissor = batch._params[paramOffset + 0]._int; + bool restoreDepthMask = false; GLuint glmask = 0; if (masks & Framebuffer::BUFFER_STENCIL) { glClearStencil(stencil); glmask |= GL_STENCIL_BUFFER_BIT; + + bool cacheDepthMask = _pipeline._stateCache.depthTest.getWriteMask(); + if (!cacheDepthMask) { + restoreDepthMask = true; + glDepthMask(GL_TRUE); + } } if (masks & Framebuffer::BUFFER_DEPTH) { @@ -252,6 +259,11 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { glDisable(GL_SCISSOR_TEST); } + // REstore write mask + if (restoreDepthMask) { + glDepthMask(GL_FALSE); + } + // Restore the color draw buffers only if a frmaebuffer is bound if (_output._framebuffer && !drawBuffers.empty()) { auto glFramebuffer = syncGPUObject(*_output._framebuffer); From 70d64a7777f90d6ae2afabc20348adfceb00e5e1 Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 29 Jul 2015 18:27:10 -0700 Subject: [PATCH 9/9] Really fixing the depth write mask issue on clear... --- libraries/gpu/src/gpu/GLBackendOutput.cpp | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendOutput.cpp b/libraries/gpu/src/gpu/GLBackendOutput.cpp index c898b4a843..d75d0cf521 100755 --- a/libraries/gpu/src/gpu/GLBackendOutput.cpp +++ b/libraries/gpu/src/gpu/GLBackendOutput.cpp @@ -209,11 +209,18 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { int stencil = batch._params[paramOffset + 1]._int; int useScissor = batch._params[paramOffset + 0]._int; - bool restoreDepthMask = false; GLuint glmask = 0; if (masks & Framebuffer::BUFFER_STENCIL) { glClearStencil(stencil); glmask |= GL_STENCIL_BUFFER_BIT; + // TODO: we will probably need to also check the write mask of stencil like we do + // for depth buffer, but as would say a famous Fez owner "We'll cross that bridge when we come to it" + } + + bool restoreDepthMask = false; + if (masks & Framebuffer::BUFFER_DEPTH) { + glClearDepth(depth); + glmask |= GL_DEPTH_BUFFER_BIT; bool cacheDepthMask = _pipeline._stateCache.depthTest.getWriteMask(); if (!cacheDepthMask) { @@ -222,11 +229,6 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { } } - if (masks & Framebuffer::BUFFER_DEPTH) { - glClearDepth(depth); - glmask |= GL_DEPTH_BUFFER_BIT; - } - std::vector drawBuffers; if (masks & Framebuffer::BUFFER_COLORS) { for (unsigned int i = 0; i < Framebuffer::MAX_NUM_RENDER_BUFFERS; i++) { @@ -259,7 +261,7 @@ void GLBackend::do_clearFramebuffer(Batch& batch, uint32 paramOffset) { glDisable(GL_SCISSOR_TEST); } - // REstore write mask + // Restore write mask meaning turn back off if (restoreDepthMask) { glDepthMask(GL_FALSE); }