From 4d6931c5a8ff300357336072332f8a055cda4661 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 13 Jan 2016 18:31:45 -0800 Subject: [PATCH 01/29] Add private start/stopNamedCall batch commands --- libraries/gpu/src/gpu/Batch.cpp | 17 ++++++++++++++++- libraries/gpu/src/gpu/Batch.h | 11 +++++++++-- libraries/gpu/src/gpu/GLBackend.cpp | 11 +++++++++++ libraries/gpu/src/gpu/GLBackend.h | 5 +++++ 4 files changed, 41 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 999e528a94..9d12e10301 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -344,6 +344,15 @@ void Batch::runLambda(std::function f) { _params.push_back(_lambdas.cache(f)); } +void Batch::startNamedCall(const std::string& name) { + ADD_COMMAND(startNamedCall); + _params.push_back(_names.cache(name)); +} + +void Batch::stopNamedCall() { + ADD_COMMAND(stopNamedCall); +} + void Batch::enableStereo(bool enable) { _enableStereo = enable; } @@ -383,8 +392,14 @@ BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t ind void Batch::preExecute() { for (auto& mapItem : _namedData) { - mapItem.second.process(*this); + auto& name = mapItem.first; + auto& instance = mapItem.second; + + startNamedCall(name); + instance.process(*this); + stopNamedCall(); } + _namedData.clear(); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index aa2fc1622c..e28334896e 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -304,6 +304,9 @@ public: COMMAND_runLambda, + COMMAND_startNamedCall, + COMMAND_stopNamedCall, + // 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 @@ -395,7 +398,7 @@ public: typedef Cache::Vector PipelineCaches; typedef Cache::Vector FramebufferCaches; typedef Cache::Vector QueryCaches; - typedef Cache::Vector ProfileRangeCaches; + typedef Cache::Vector StringCaches; typedef Cache>::Vector LambdaCache; // Cache Data in a byte array if too big to fit in Param @@ -423,7 +426,8 @@ public: FramebufferCaches _framebuffers; QueryCaches _queries; LambdaCache _lambdas; - ProfileRangeCaches _profileRanges; + StringCaches _profileRanges; + StringCaches _names; NamedBatchDataMap _namedData; @@ -431,6 +435,9 @@ public: bool _enableSkybox{ false }; protected: + void startNamedCall(const std::string& name); + void stopNamedCall(); + // Maybe useful but shoudln't be public. Please convince me otherwise void runLambda(std::function f); }; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index a730c06bd9..025990df73 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -62,6 +62,9 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::GLBackend::do_runLambda), + (&::gpu::GLBackend::do_startNamedCall), + (&::gpu::GLBackend::do_stopNamedCall), + (&::gpu::GLBackend::do_glActiveBindTexture), (&::gpu::GLBackend::do_glUniform1i), @@ -423,6 +426,14 @@ void GLBackend::do_runLambda(Batch& batch, size_t paramOffset) { f(); } +void GLBackend::do_startNamedCall(Batch& batch, size_t paramOffset) { + _currentNamedCall = batch._names.get(batch._params[paramOffset]._uint); +} + +void GLBackend::do_stopNamedCall(Batch& batch, size_t paramOffset) { + _currentNamedCall.clear(); +} + void GLBackend::resetStages() { resetInputStage(); resetPipelineStage(); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 400c9f08f8..d8c93feda6 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -245,6 +245,8 @@ protected: void renderPassTransfer(Batch& batch); void renderPassDraw(Batch& batch); + std::string _currentNamedCall; + Stats _stats; // Draw Stage @@ -465,6 +467,9 @@ protected: void do_runLambda(Batch& batch, size_t paramOffset); + void do_startNamedCall(Batch& batch, size_t paramOffset); + void do_stopNamedCall(Batch& batch, size_t paramOffset); + void resetStages(); // TODO: As long as we have gl calls explicitely issued from interface From bd8f62504d789e99a61f21260eaeb143083b8b2d Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 13 Jan 2016 18:32:27 -0800 Subject: [PATCH 02/29] Capture DrawCallInfo during renderPassTransfer --- libraries/gpu/src/gpu/GLBackend.cpp | 33 +++++++++++++++-------------- libraries/gpu/src/gpu/GLBackend.h | 31 +++++++++++++++++++++++++++ 2 files changed, 48 insertions(+), 16 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 025990df73..b03346e96b 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -165,24 +165,25 @@ void GLBackend::renderPassTransfer(Batch& batch) { for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { switch (*command) { - case Batch::COMMAND_draw: - case Batch::COMMAND_drawIndexed: - case Batch::COMMAND_drawInstanced: - case Batch::COMMAND_drawIndexedInstanced: - _transform.preUpdate(_commandIndex, _stereo); - break; + case Batch::COMMAND_draw: + case Batch::COMMAND_drawIndexed: + case Batch::COMMAND_drawInstanced: + case Batch::COMMAND_drawIndexedInstanced: + _transform.preUpdate(_commandIndex, _stereo); + captureDrawCallInfo(); + break; - case Batch::COMMAND_setModelTransform: - case Batch::COMMAND_setViewportTransform: - case Batch::COMMAND_setViewTransform: - case Batch::COMMAND_setProjectionTransform: { - CommandCall call = _commandCalls[(*command)]; - (this->*(call))(batch, *offset); - break; - } + case Batch::COMMAND_setModelTransform: + case Batch::COMMAND_setViewportTransform: + case Batch::COMMAND_setViewTransform: + case Batch::COMMAND_setProjectionTransform: { + CommandCall call = _commandCalls[(*command)]; + (this->*(call))(batch, *offset); + break; + } - default: - break; + default: + break; } command++; offset++; diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index d8c93feda6..8cda7e444b 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -245,8 +245,39 @@ protected: void renderPassTransfer(Batch& batch); void renderPassDraw(Batch& batch); + class DrawCallInfo { + public: + using Index = uint16_t; + + DrawCallInfo(Index idx) : index(idx) {} + + Index index; + uint16_t unused; // Reserved space for later + }; + // Make sure DrawCallInfo has no extra padding + static_assert(sizeof(DrawCallInfo) == 4, "DrawCallInfo size is incorrect."); + + using DrawCallInfoBuffer = std::vector; + using NamedDrawCallInfoBuffer = std::map; + + DrawCallInfoBuffer _drawCallInfos; + NamedDrawCallInfoBuffer _namedDrawCallInfos; + std::string _currentNamedCall; + DrawCallInfoBuffer& getDrawCallInfoBuffer() { + if (_currentNamedCall.empty()) { + return _drawCallInfos; + } else { + return _namedDrawCallInfos[_currentNamedCall]; + } + } + + void captureDrawCallInfo() { + auto& drawCallInfos = getDrawCallInfoBuffer(); + drawCallInfos.push_back(_transform._objects.size() - 1); + } + Stats _stats; // Draw Stage From 646313624062da404e5c82d89e62ba093d2f64a2 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 13 Jan 2016 18:37:24 -0800 Subject: [PATCH 03/29] start/stopNamedCall run in renderPassTransfer too --- libraries/gpu/src/gpu/GLBackend.cpp | 16 ++++++++++++++++ libraries/gpu/src/gpu/GLBackend.h | 14 ++------------ 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index b03346e96b..7f2f98e656 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -173,6 +173,8 @@ void GLBackend::renderPassTransfer(Batch& batch) { captureDrawCallInfo(); break; + case Batch::COMMAND_startNamedCall: + case Batch::COMMAND_stopNamedCall: case Batch::COMMAND_setModelTransform: case Batch::COMMAND_setViewportTransform: case Batch::COMMAND_setViewTransform: @@ -258,6 +260,20 @@ void GLBackend::render(Batch& batch) { _stereo._enable = savedStereo; } + +GLBackend::DrawCallInfoBuffer& GLBackend::getDrawCallInfoBuffer() { + if (_currentNamedCall.empty()) { + return _drawCallInfos; + } else { + return _namedDrawCallInfos[_currentNamedCall]; + } +} + +void GLBackend::captureDrawCallInfo() { + auto& drawCallInfos = getDrawCallInfoBuffer(); + drawCallInfos.push_back(_transform._objects.size() - 1); +} + bool GLBackend::checkGLError(const char* name) { GLenum error = glGetError(); if (!error) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 8cda7e444b..86d06b9605 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -265,18 +265,8 @@ protected: std::string _currentNamedCall; - DrawCallInfoBuffer& getDrawCallInfoBuffer() { - if (_currentNamedCall.empty()) { - return _drawCallInfos; - } else { - return _namedDrawCallInfos[_currentNamedCall]; - } - } - - void captureDrawCallInfo() { - auto& drawCallInfos = getDrawCallInfoBuffer(); - drawCallInfos.push_back(_transform._objects.size() - 1); - } + DrawCallInfoBuffer& getDrawCallInfoBuffer(); + void captureDrawCallInfo(); Stats _stats; From bff2a2a8e52f0a84cf22c87e351c4379f0a49d0b Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 12:32:15 -0800 Subject: [PATCH 04/29] Factor draw call updates --- libraries/gpu/src/gpu/GLBackend.cpp | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 7f2f98e656..bd8439c8be 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -215,6 +215,15 @@ void GLBackend::renderPassDraw(Batch& batch) { case Batch::COMMAND_setProjectionTransform: break; + case Batch::COMMAND_draw: + case Batch::COMMAND_drawIndexed: + case Batch::COMMAND_drawInstanced: + case Batch::COMMAND_drawIndexedInstanced: + // updates for draw calls + updateInput(); + updateTransform(); + updatePipeline(); + // Fallthrough to next case default: { CommandCall call = _commandCalls[(*command)]; (this->*(call))(batch, *offset); @@ -326,10 +335,6 @@ void GLBackend::syncCache() { } void GLBackend::do_draw(Batch& batch, size_t paramOffset) { - updateInput(); - updateTransform(); - updatePipeline(); - Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; GLenum mode = _primitiveToGLmode[primitiveType]; uint32 numVertices = batch._params[paramOffset + 1]._uint; @@ -339,10 +344,6 @@ void GLBackend::do_draw(Batch& batch, size_t paramOffset) { } void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) { - updateInput(); - updateTransform(); - updatePipeline(); - Primitive primitiveType = (Primitive)batch._params[paramOffset + 2]._uint; GLenum mode = _primitiveToGLmode[primitiveType]; uint32 numIndices = batch._params[paramOffset + 1]._uint; @@ -358,10 +359,6 @@ void GLBackend::do_drawIndexed(Batch& batch, size_t paramOffset) { } void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) { - updateInput(); - updateTransform(); - updatePipeline(); - GLint numInstances = batch._params[paramOffset + 4]._uint; Primitive primitiveType = (Primitive)batch._params[paramOffset + 3]._uint; GLenum mode = _primitiveToGLmode[primitiveType]; @@ -373,10 +370,6 @@ void GLBackend::do_drawInstanced(Batch& batch, size_t paramOffset) { } void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) { - updateInput(); - updateTransform(); - updatePipeline(); - GLint numInstances = batch._params[paramOffset + 4]._uint; GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 3]._uint]; uint32 numIndices = batch._params[paramOffset + 2]._uint; From 9e0af63441e009ee682f8f4ce12fc05a412b1114 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 12:35:20 -0800 Subject: [PATCH 05/29] Bind model transform as single buffer --- libraries/gpu/src/gpu/GLBackend.cpp | 8 ++--- libraries/gpu/src/gpu/GLBackend.h | 5 +-- libraries/gpu/src/gpu/GLBackendTransform.cpp | 38 +++++++------------- libraries/gpu/src/gpu/Transform.slh | 4 ++- 4 files changed, 20 insertions(+), 35 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index bd8439c8be..4664557f2e 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -158,10 +158,9 @@ void GLBackend::renderPassTransfer(Batch& batch) { { // Sync all the buffers PROFILE_RANGE("syncCPUTransform"); - _transform._cameras.resize(0); + _transform._cameras.clear(); _transform._cameraOffsets.clear(); - _transform._objects.resize(0); - _transform._objectOffsets.clear(); + _transform._objects.clear(); for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { switch (*command) { @@ -196,10 +195,11 @@ void GLBackend::renderPassTransfer(Batch& batch) { PROFILE_RANGE("syncGPUTransform"); _transform.transfer(); } + + } void GLBackend::renderPassDraw(Batch& batch) { - _transform._objectsItr = _transform._objectOffsets.begin(); _transform._camerasItr = _transform._cameraOffsets.begin(); const size_t numCommands = batch.getCommands().size(); const Batch::Commands::value_type* command = batch.getCommands().data(); diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 86d06b9605..a5bdba9788 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -355,10 +355,9 @@ protected: TransformObjects _objects; TransformCameras _cameras; - size_t _cameraUboSize{ 0 }; - size_t _objectUboSize{ 0 }; GLuint _objectBuffer{ 0 }; GLuint _cameraBuffer{ 0 }; + size_t _cameraUboSize{ 0 }; Transform _model; Transform _view; Mat4 _projection; @@ -372,8 +371,6 @@ protected: using Pair = std::pair; using List = std::list; List _cameraOffsets; - List _objectOffsets; - mutable List::const_iterator _objectsItr; mutable List::const_iterator _camerasItr; void preUpdate(size_t commandIndex, const StereoState& stereo); diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 9bfd258833..7f7a2b2c4a 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -67,10 +67,6 @@ void GLBackend::initTransform() { while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; } - size_t objectSize = sizeof(TransformObject); - while (_transform._objectUboSize < objectSize) { - _transform._objectUboSize += _uboAlignment; - } } void GLBackend::killTransform() { @@ -116,6 +112,8 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo // of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works. //_model.getInverseMatrix(_object._modelInverse); _object._modelInverse = glm::inverse(_object._model); + + _objects.push_back(_object); } if (_invalidView || _invalidProj || _invalidViewport) { @@ -131,12 +129,6 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo } } - if (_invalidModel) { - size_t offset = _objectUboSize * _objects.size(); - _objectOffsets.push_back(TransformStageState::Pair(commandIndex, offset)); - _objects.push_back(_object); - } - // Flags are clean _invalidView = _invalidProj = _invalidModel = _invalidViewport = false; } @@ -145,42 +137,33 @@ void GLBackend::TransformStageState::transfer() const { // FIXME not thread safe static std::vector bufferData; if (!_cameras.empty()) { - glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); bufferData.resize(_cameraUboSize * _cameras.size()); for (size_t i = 0; i < _cameras.size(); ++i) { memcpy(bufferData.data() + (_cameraUboSize * i), &_cameras[i], sizeof(TransformCamera)); } + glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } if (!_objects.empty()) { + auto byteSize = _objects.size() * sizeof(TransformObject); + bufferData.resize(byteSize); + memcpy(bufferData.data(), _objects.data(), byteSize); + glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); - bufferData.resize(_objectUboSize * _objects.size()); - for (size_t i = 0; i < _objects.size(); ++i) { - memcpy(bufferData.data() + (_objectUboSize * i), &_objects[i], sizeof(TransformObject)); - } glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); } - if (!_cameras.empty() || !_objects.empty()) { + if (!_objects.empty() || !_cameras.empty()) { glBindBuffer(GL_UNIFORM_BUFFER, 0); } + CHECK_GL_ERROR(); } void GLBackend::TransformStageState::update(size_t commandIndex, const StereoState& stereo) const { static const size_t INVALID_OFFSET = (size_t)-1; size_t offset = INVALID_OFFSET; - while ((_objectsItr != _objectOffsets.end()) && (commandIndex >= (*_objectsItr).first)) { - offset = (*_objectsItr).second; - ++_objectsItr; - } - if (offset != INVALID_OFFSET) { - glBindBufferRange(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, - _objectBuffer, offset, sizeof(Backend::TransformObject)); - } - - offset = INVALID_OFFSET; while ((_camerasItr != _cameraOffsets.end()) && (commandIndex >= (*_camerasItr).first)) { offset = (*_camerasItr).second; ++_camerasItr; @@ -194,6 +177,9 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta _cameraBuffer, offset, sizeof(Backend::TransformCamera)); } + glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); + + (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 26ea9784be..e7ddc051c5 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -25,8 +25,10 @@ struct TransformCamera { vec4 _viewport; }; +const int MAX_OBJECTS = 512; // NEEDS to match GLBackend::TransformStageState::update's MAX_OBJECT + layout(std140) uniform transformObjectBuffer { - TransformObject _object; + TransformObject _object[MAX_OBJECTS]; }; TransformObject getTransformObject() { return _object; From ccb183e518671673473b364b4393a6362da477bd Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 12:37:09 -0800 Subject: [PATCH 06/29] Unify Named/Normal calls --- libraries/gpu/src/gpu/GLBackend.h | 1 + libraries/gpu/src/gpu/GLBackendShader.cpp | 6 +-- libraries/gpu/src/gpu/GLBackendTransform.cpp | 3 ++ libraries/gpu/src/gpu/Inputs.slh | 1 - libraries/gpu/src/gpu/Stream.h | 6 +-- libraries/gpu/src/gpu/Transform.slh | 46 ++------------------ libraries/render-utils/src/GeometryCache.cpp | 14 ++---- libraries/render-utils/src/simple.slv | 11 +---- tests/gpu-test/src/main.cpp | 6 --- tests/gpu-test/src/unlit.slv | 11 +---- 10 files changed, 20 insertions(+), 85 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index a5bdba9788..70e4489304 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -260,6 +260,7 @@ protected: using DrawCallInfoBuffer = std::vector; using NamedDrawCallInfoBuffer = std::map; + int _currentDraw = 0; DrawCallInfoBuffer _drawCallInfos; NamedDrawCallInfoBuffer _namedDrawCallInfos; diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index 19fa94524e..ece1a980d4 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -75,9 +75,9 @@ void makeBindings(GLBackend::GLShader* shader) { glBindAttribLocation(glprogram, gpu::Stream::SKIN_CLUSTER_WEIGHT, "inSkinClusterWeight"); } - loc = glGetAttribLocation(glprogram, "inInstanceTransform"); - if (loc >= 0 && loc != gpu::Stream::INSTANCE_XFM) { - glBindAttribLocation(glprogram, gpu::Stream::INSTANCE_XFM, "inInstanceTransform"); + loc = glGetAttribLocation(glprogram, "_drawCallInfo"); + if (loc >= 0 && loc != gpu::Stream::DRAW_CALL_INFO) { + glBindAttribLocation(glprogram, gpu::Stream::DRAW_CALL_INFO, "_drawCallInfo"); } // Link again to take into account the assigned attrib location diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 7f7a2b2c4a..68c29dac25 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -185,6 +185,9 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta void GLBackend::updateTransform() const { _transform.update(_commandIndex, _stereo); + + auto& drawCallInfo = _drawCallInfos[_currentDraw]; + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } void GLBackend::resetTransformStage() { diff --git a/libraries/gpu/src/gpu/Inputs.slh b/libraries/gpu/src/gpu/Inputs.slh index 99e1e1d6d5..8f90b6ebee 100644 --- a/libraries/gpu/src/gpu/Inputs.slh +++ b/libraries/gpu/src/gpu/Inputs.slh @@ -18,5 +18,4 @@ in vec4 inTangent; in vec4 inSkinClusterIndex; in vec4 inSkinClusterWeight; in vec4 inTexCoord1; -in mat4 inInstanceTransform; <@endif@> diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 8c0833dd42..faaac82b63 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -39,10 +39,10 @@ public: TEXCOORD1 = 7, INSTANCE_SCALE = 8, INSTANCE_TRANSLATE = 9, - INSTANCE_XFM = 10, - // Instance XFM is a mat4, and as such takes up 4 slots - NUM_INPUT_SLOTS = INSTANCE_XFM + 4, + + DRAW_CALL_INFO = 15, // Reserve last input slot for draw call infos + NUM_INPUT_SLOTS = DRAW_CALL_INFO + 1, }; typedef uint8 Slot; diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index e7ddc051c5..2dc2ba9515 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -27,11 +27,13 @@ struct TransformCamera { const int MAX_OBJECTS = 512; // NEEDS to match GLBackend::TransformStageState::update's MAX_OBJECT +in ivec2 _drawCallInfo; + layout(std140) uniform transformObjectBuffer { TransformObject _object[MAX_OBJECTS]; }; TransformObject getTransformObject() { - return _object; + return _object[_drawCallInfo.x]; } layout(std140) uniform transformCameraBuffer { @@ -55,15 +57,6 @@ TransformCamera getTransformCamera() { } <@endfunc@> -<@func transformInstancedModelToClipPos(cameraTransform, objectTransform, modelPos, clipPos)@> - - { // transformModelToClipPos - vec4 _eyepos = (inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0); - <$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos; - } -<@endfunc@> - <@func $transformModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@> @@ -76,30 +69,12 @@ TransformCamera getTransformCamera() { } <@endfunc@> -<@func $transformInstancedModelToEyeAndClipPos(cameraTransform, objectTransform, modelPos, eyePos, clipPos)@> - - { // transformModelToClipPos - vec4 _worldpos = (inInstanceTransform * <$modelPos$>); - <$eyePos$> = (<$cameraTransform$>._view * _worldpos); - vec4 _eyepos =(inInstanceTransform * <$modelPos$>) + vec4(-<$modelPos$>.w * <$cameraTransform$>._viewInverse[3].xyz, 0.0); - <$clipPos$> = <$cameraTransform$>._projectionViewUntranslated * _eyepos; - // <$eyePos$> = (<$cameraTransform$>._projectionInverse * <$clipPos$>); - } -<@endfunc@> - <@func transformModelToWorldPos(objectTransform, modelPos, worldPos)@> { // transformModelToWorldPos <$worldPos$> = (<$objectTransform$>._model * <$modelPos$>); } <@endfunc@> -<@func transformInstancedModelToWorldPos(objectTransform, modelPos, worldPos)@> - { // transformModelToWorldPos - <$worldPos$> = (inInstanceTransform * <$modelPos$>); - } -<@endfunc@> - <@func transformModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@> { // transformModelToEyeDir vec3 mr0 = vec3(<$objectTransform$>._modelInverse[0].x, <$objectTransform$>._modelInverse[1].x, <$objectTransform$>._modelInverse[2].x); @@ -114,21 +89,6 @@ TransformCamera getTransformCamera() { } <@endfunc@> -<@func transformInstancedModelToEyeDir(cameraTransform, objectTransform, modelDir, eyeDir)@> - { // transformModelToEyeDir - mat4 modelInverse = inverse(inInstanceTransform); - vec3 mr0 = vec3(modelInverse[0].x, modelInverse[1].x, modelInverse[2].x); - vec3 mr1 = vec3(modelInverse[0].y, modelInverse[1].y, modelInverse[2].y); - vec3 mr2 = vec3(modelInverse[0].z, modelInverse[1].z, modelInverse[2].z); - - vec3 mvc0 = vec3(dot(<$cameraTransform$>._viewInverse[0].xyz, mr0), dot(<$cameraTransform$>._viewInverse[0].xyz, mr1), dot(<$cameraTransform$>._viewInverse[0].xyz, mr2)); - vec3 mvc1 = vec3(dot(<$cameraTransform$>._viewInverse[1].xyz, mr0), dot(<$cameraTransform$>._viewInverse[1].xyz, mr1), dot(<$cameraTransform$>._viewInverse[1].xyz, mr2)); - vec3 mvc2 = vec3(dot(<$cameraTransform$>._viewInverse[2].xyz, mr0), dot(<$cameraTransform$>._viewInverse[2].xyz, mr1), dot(<$cameraTransform$>._viewInverse[2].xyz, mr2)); - - <$eyeDir$> = vec3(dot(mvc0, <$modelDir$>), dot(mvc1, <$modelDir$>), dot(mvc2, <$modelDir$>)); - } -<@endfunc@> - <@func transformEyeToWorldDir(cameraTransform, eyeDir, worldDir)@> { // transformEyeToWorldDir <$worldDir$> = vec3(<$cameraTransform$>._viewInverse * vec4(<$eyeDir$>.xyz, 0.0)); diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 35773e8748..209f3bab2f 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -43,7 +43,6 @@ static const int VERTICES_PER_TRIANGLE = 3; static const gpu::Element POSITION_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element NORMAL_ELEMENT{ gpu::VEC3, gpu::FLOAT, gpu::XYZ }; static const gpu::Element COLOR_ELEMENT{ gpu::VEC4, gpu::NUINT8, gpu::RGBA }; -static const gpu::Element TRANSFORM_ELEMENT{ gpu::MAT4, gpu::FLOAT, gpu::XYZW }; static gpu::Stream::FormatPointer SOLID_STREAM_FORMAT; static gpu::Stream::FormatPointer INSTANCED_SOLID_STREAM_FORMAT; @@ -491,7 +490,6 @@ gpu::Stream::FormatPointer& getInstancedSolidStreamFormat() { INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::POSITION, gpu::Stream::POSITION, POSITION_ELEMENT); INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::NORMAL, gpu::Stream::NORMAL, NORMAL_ELEMENT); INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::COLOR, gpu::Stream::COLOR, COLOR_ELEMENT, 0, gpu::Stream::PER_INSTANCE); - INSTANCED_SOLID_STREAM_FORMAT->setAttribute(gpu::Stream::INSTANCE_XFM, gpu::Stream::INSTANCE_XFM, TRANSFORM_ELEMENT, 0, gpu::Stream::PER_INSTANCE); } return INSTANCED_SOLID_STREAM_FORMAT; } @@ -511,11 +509,9 @@ GeometryCache::~GeometryCache() { #endif //def WANT_DEBUG } -void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) { +void setupBatchInstance(gpu::Batch& batch, gpu::BufferPointer colorBuffer) { gpu::BufferView colorView(colorBuffer, COLOR_ELEMENT); batch.setInputBuffer(gpu::Stream::COLOR, colorView); - gpu::BufferView instanceXfmView(transformBuffer, 0, transformBuffer->getSize(), TRANSFORM_ELEMENT); - batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView); } void GeometryCache::renderShape(gpu::Batch& batch, Shape shape) { @@ -530,13 +526,13 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) { void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) { batch.setInputFormat(getInstancedSolidStreamFormat()); - setupBatchInstance(batch, transformBuffer, colorBuffer); + setupBatchInstance(batch, colorBuffer); _shapes[shape].drawInstances(batch, count); } void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) { batch.setInputFormat(getInstancedSolidStreamFormat()); - setupBatchInstance(batch, transformBuffer, colorBuffer); + setupBatchInstance(batch, colorBuffer); _shapes[shape].drawWireInstances(batch, count); } @@ -1871,11 +1867,7 @@ void renderInstances(const std::string& name, gpu::Batch& batch, const Transform batch.setupNamedCalls(name, [f](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { auto pipeline = DependencyManager::get()->bindSimpleProgram(batch); - auto location = pipeline->getProgram()->getUniforms().findLocation("Instanced"); - - batch._glUniform1i(location, 1); f(batch, data); - batch._glUniform1i(location, 0); }); } diff --git a/libraries/render-utils/src/simple.slv b/libraries/render-utils/src/simple.slv index 59b16cf0e5..46127d6752 100644 --- a/libraries/render-utils/src/simple.slv +++ b/libraries/render-utils/src/simple.slv @@ -17,9 +17,7 @@ <@include gpu/Transform.slh@> <$declareStandardTransform()$> -uniform bool Instanced = false; // the interpolated normal - out vec3 _normal; out vec3 _modelNormal; out vec3 _color; @@ -35,11 +33,6 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - if (Instanced) { - <$transformInstancedModelToClipPos(cam, obj, inPosition, gl_Position)$> - <$transformInstancedModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> - } else { - <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> - <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> - } + <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> + <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> } \ No newline at end of file diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index de5aa877eb..4142c4f521 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -124,7 +124,6 @@ class QTestWindow : public QWindow { glm::mat4 _projectionMatrix; RateCounter fps; QTime _time; - int _instanceLocation{ -1 }; protected: void renderText(); @@ -164,7 +163,6 @@ public: state->setMultisampleEnable(true); state->setDepthTest(gpu::State::DepthTest { true }); _pipeline = gpu::Pipeline::create(shader, state); - _instanceLocation = _pipeline->getProgram()->getUniforms().findLocation("Instanced"); // Clear screen gpu::Batch batch; @@ -245,9 +243,7 @@ public: batch.setViewTransform(camera); batch.setModelTransform(Transform()); batch.setPipeline(_pipeline); - batch._glUniform1i(_instanceLocation, 1); geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count, transformBuffer, colorBuffer); - batch._glUniform1i(_instanceLocation, 0); }); } @@ -316,14 +312,12 @@ public: batch.setViewTransform(camera); batch.setModelTransform(Transform()); batch.setPipeline(_pipeline); - batch._glUniform1i(_instanceLocation, 1); batch.setInputFormat(getInstancedSolidStreamFormat()); batch.setInputBuffer(gpu::Stream::COLOR, colorView); batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView); batch.setIndirectBuffer(indirectBuffer); shapeData.setupBatch(batch); batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES); - batch._glUniform1i(_instanceLocation, 0); } #else batch.setViewTransform(camera); diff --git a/tests/gpu-test/src/unlit.slv b/tests/gpu-test/src/unlit.slv index 3271d0ee90..d51d817429 100644 --- a/tests/gpu-test/src/unlit.slv +++ b/tests/gpu-test/src/unlit.slv @@ -19,8 +19,6 @@ <$declareStandardTransform()$> // the interpolated normal -uniform bool Instanced = false; - out vec3 _normal; out vec3 _color; out vec2 _texCoord0; @@ -32,12 +30,7 @@ void main(void) { // standard transform TransformCamera cam = getTransformCamera(); TransformObject obj = getTransformObject(); - if (Instanced) { - <$transformInstancedModelToClipPos(cam, obj, inPosition, gl_Position)$> - <$transformInstancedModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> - } else { - <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> - <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> - } + <$transformModelToClipPos(cam, obj, inPosition, gl_Position)$> + <$transformModelToEyeDir(cam, obj, inNormal.xyz, _normal)$> _normal = vec3(0.0, 0.0, 1.0); } \ No newline at end of file From 6464fabd71c6a3192267b1265c1bde5c17e005e9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 13:23:26 -0800 Subject: [PATCH 07/29] Update current draw call --- libraries/gpu/src/gpu/GLBackend.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 4664557f2e..25a3abccd3 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -200,6 +200,7 @@ void GLBackend::renderPassTransfer(Batch& batch) { } void GLBackend::renderPassDraw(Batch& batch) { + _currentDraw = -1; _transform._camerasItr = _transform._cameraOffsets.begin(); const size_t numCommands = batch.getCommands().size(); const Batch::Commands::value_type* command = batch.getCommands().data(); @@ -220,6 +221,7 @@ void GLBackend::renderPassDraw(Batch& batch) { case Batch::COMMAND_drawInstanced: case Batch::COMMAND_drawIndexedInstanced: // updates for draw calls + ++_currentDraw; updateInput(); updateTransform(); updatePipeline(); @@ -438,6 +440,7 @@ void GLBackend::do_runLambda(Batch& batch, size_t paramOffset) { void GLBackend::do_startNamedCall(Batch& batch, size_t paramOffset) { _currentNamedCall = batch._names.get(batch._params[paramOffset]._uint); + _currentDraw = 0; } void GLBackend::do_stopNamedCall(Batch& batch, size_t paramOffset) { From 23cf72bd6c1b2233957061f40294e4d85be37c73 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 13:37:14 -0800 Subject: [PATCH 08/29] Add multi draw to factored setup --- libraries/gpu/src/gpu/GLBackend.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 25a3abccd3..7c662ada41 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -168,6 +168,8 @@ void GLBackend::renderPassTransfer(Batch& batch) { case Batch::COMMAND_drawIndexed: case Batch::COMMAND_drawInstanced: case Batch::COMMAND_drawIndexedInstanced: + case Batch::COMMAND_multiDrawIndirect: + case Batch::COMMAND_multiDrawIndexedIndirect: _transform.preUpdate(_commandIndex, _stereo); captureDrawCallInfo(); break; @@ -220,6 +222,8 @@ void GLBackend::renderPassDraw(Batch& batch) { case Batch::COMMAND_drawIndexed: case Batch::COMMAND_drawInstanced: case Batch::COMMAND_drawIndexedInstanced: + case Batch::COMMAND_multiDrawIndirect: + case Batch::COMMAND_multiDrawIndexedIndirect: // updates for draw calls ++_currentDraw; updateInput(); @@ -396,10 +400,6 @@ void GLBackend::do_drawIndexedInstanced(Batch& batch, size_t paramOffset) { void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) { #if (GPU_INPUT_PROFILE == GPU_CORE_43) - updateInput(); - updateTransform(); - updatePipeline(); - uint commandCount = batch._params[paramOffset + 0]._uint; GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint]; @@ -413,10 +413,6 @@ void GLBackend::do_multiDrawIndirect(Batch& batch, size_t paramOffset) { void GLBackend::do_multiDrawIndexedIndirect(Batch& batch, size_t paramOffset) { #if (GPU_INPUT_PROFILE == GPU_CORE_43) - updateInput(); - updateTransform(); - updatePipeline(); - uint commandCount = batch._params[paramOffset + 0]._uint; GLenum mode = _primitiveToGLmode[(Primitive)batch._params[paramOffset + 1]._uint]; GLenum indexType = _elementTypeToGLType[_input._indexBufferType]; From 3e027fc5c5c3bbcd6f3fbf5519ef7d28a5b50e25 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 15:28:17 -0800 Subject: [PATCH 09/29] Use ssbo for model transforms --- libraries/gpu/src/gpu/Config.slh | 2 +- libraries/gpu/src/gpu/GLBackendTransform.cpp | 13 +++++-------- libraries/gpu/src/gpu/Transform.slh | 6 ++---- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/libraries/gpu/src/gpu/Config.slh b/libraries/gpu/src/gpu/Config.slh index 3da92df7c1..5a96a7eafe 100644 --- a/libraries/gpu/src/gpu/Config.slh +++ b/libraries/gpu/src/gpu/Config.slh @@ -13,7 +13,7 @@ <@if GLPROFILE == PC_GL @> <@def GPU_FEATURE_PROFILE GPU_CORE@> - <@def VERSION_HEADER #version 410 core@> + <@def VERSION_HEADER #version 430 core@> <@elif GLPROFILE == MAC_GL @> <@def GPU_FEATURE_PROFILE GPU_CORE@> <@def VERSION_HEADER #version 410 core@> diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 68c29dac25..cffe066e6d 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -143,6 +143,7 @@ void GLBackend::TransformStageState::transfer() const { } glBindBuffer(GL_UNIFORM_BUFFER, _cameraBuffer); glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_UNIFORM_BUFFER, 0); } if (!_objects.empty()) { @@ -150,12 +151,9 @@ void GLBackend::TransformStageState::transfer() const { bufferData.resize(byteSize); memcpy(bufferData.data(), _objects.data(), byteSize); - glBindBuffer(GL_UNIFORM_BUFFER, _objectBuffer); - glBufferData(GL_UNIFORM_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); - } - - if (!_objects.empty() || !_cameras.empty()) { - glBindBuffer(GL_UNIFORM_BUFFER, 0); + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); + glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } CHECK_GL_ERROR(); @@ -177,8 +175,7 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta _cameraBuffer, offset, sizeof(Backend::TransformCamera)); } - glBindBufferBase(GL_UNIFORM_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); - + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); (void)CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 2dc2ba9515..692e345e0d 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -25,12 +25,10 @@ struct TransformCamera { vec4 _viewport; }; -const int MAX_OBJECTS = 512; // NEEDS to match GLBackend::TransformStageState::update's MAX_OBJECT - in ivec2 _drawCallInfo; -layout(std140) uniform transformObjectBuffer { - TransformObject _object[MAX_OBJECTS]; +layout(std430, binding=6) buffer transformObjectBuffer { + TransformObject _object[]; }; TransformObject getTransformObject() { return _object[_drawCallInfo.x]; From 6ff38bc32f056bd31ce25c14f1dbdfda753825ab Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 15:28:45 -0800 Subject: [PATCH 10/29] Make sure _currentDraw has correct value --- libraries/gpu/src/gpu/GLBackend.cpp | 2 +- libraries/gpu/src/gpu/GLBackend.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 7c662ada41..e429ae7ef1 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -436,7 +436,7 @@ void GLBackend::do_runLambda(Batch& batch, size_t paramOffset) { void GLBackend::do_startNamedCall(Batch& batch, size_t paramOffset) { _currentNamedCall = batch._names.get(batch._params[paramOffset]._uint); - _currentDraw = 0; + _currentDraw = -1; } void GLBackend::do_stopNamedCall(Batch& batch, size_t paramOffset) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 70e4489304..5fcf5316a9 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -260,7 +260,7 @@ protected: using DrawCallInfoBuffer = std::vector; using NamedDrawCallInfoBuffer = std::map; - int _currentDraw = 0; + int _currentDraw{ -1 }; DrawCallInfoBuffer _drawCallInfos; NamedDrawCallInfoBuffer _namedDrawCallInfos; From eb55e55367ed5c343cb2416ac390fa6c1389dfb4 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 14 Jan 2016 16:08:06 -0800 Subject: [PATCH 11/29] Clear buffers between each batch render --- libraries/gpu/src/gpu/GLBackend.cpp | 4 +++- libraries/gpu/src/gpu/GLBackend.h | 6 +++--- libraries/gpu/src/gpu/GLBackendTransform.cpp | 4 ++-- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index e429ae7ef1..dbabee65ff 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -161,6 +161,8 @@ void GLBackend::renderPassTransfer(Batch& batch) { _transform._cameras.clear(); _transform._cameraOffsets.clear(); _transform._objects.clear(); + _drawCallInfos.clear(); + _namedDrawCallInfos.clear(); for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { switch (*command) { @@ -286,7 +288,7 @@ GLBackend::DrawCallInfoBuffer& GLBackend::getDrawCallInfoBuffer() { void GLBackend::captureDrawCallInfo() { auto& drawCallInfos = getDrawCallInfoBuffer(); - drawCallInfos.push_back(_transform._objects.size() - 1); + drawCallInfos.push_back((uint16)_transform._objects.size() - 1); } bool GLBackend::checkGLError(const char* name) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 5fcf5316a9..85fada4016 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -251,8 +251,8 @@ protected: DrawCallInfo(Index idx) : index(idx) {} - Index index; - uint16_t unused; // Reserved space for later + Index index { 0 }; + uint16_t unused { 0 }; // Reserved space for later }; // Make sure DrawCallInfo has no extra padding static_assert(sizeof(DrawCallInfo) == 4, "DrawCallInfo size is incorrect."); @@ -344,7 +344,7 @@ protected: void killTransform(); // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncTransformStateCache(); - void updateTransform() const; + void updateTransform(); void resetTransformStage(); struct TransformStageState { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index cffe066e6d..b2f2e414ff 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -180,10 +180,10 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta (void)CHECK_GL_ERROR(); } -void GLBackend::updateTransform() const { +void GLBackend::updateTransform() { _transform.update(_commandIndex, _stereo); - auto& drawCallInfo = _drawCallInfos[_currentDraw]; + auto& drawCallInfo = getDrawCallInfoBuffer()[_currentDraw]; glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } From 78cd4407dba8c2286904288a02ede582e6314610 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 15 Jan 2016 14:19:19 -0800 Subject: [PATCH 12/29] Don't pass binding manually, link named call correctly --- libraries/gpu/src/gpu/GLBackendShader.cpp | 4 ++-- libraries/gpu/src/gpu/GLBackendTransform.cpp | 10 ++++++++-- libraries/gpu/src/gpu/Stream.h | 1 - libraries/gpu/src/gpu/Transform.slh | 2 +- 4 files changed, 11 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index ece1a980d4..45bd67f70c 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -92,9 +92,9 @@ void makeBindings(GLBackend::GLShader* shader) { // now assign the ubo binding, then DON't relink! //Check for gpu specific uniform slotBindings - loc = glGetUniformBlockIndex(glprogram, "transformObjectBuffer"); + loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer"); if (loc >= 0) { - glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); + glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT; } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index b2f2e414ff..33d60eaac5 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -183,8 +183,14 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta void GLBackend::updateTransform() { _transform.update(_commandIndex, _stereo); - auto& drawCallInfo = getDrawCallInfoBuffer()[_currentDraw]; - glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); + auto& drawCallInfoBuffer = getDrawCallInfoBuffer(); + if (_currentNamedCall.empty()) { + auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused); + } else { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_SHORT, 4, drawCallInfoBuffer.data()); + } } void GLBackend::resetTransformStage() { diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index faaac82b63..4214b99b74 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -40,7 +40,6 @@ public: INSTANCE_SCALE = 8, INSTANCE_TRANSLATE = 9, - DRAW_CALL_INFO = 15, // Reserve last input slot for draw call infos NUM_INPUT_SLOTS = DRAW_CALL_INFO + 1, }; diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 692e345e0d..109af2835f 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -27,7 +27,7 @@ struct TransformCamera { in ivec2 _drawCallInfo; -layout(std430, binding=6) buffer transformObjectBuffer { +layout(std140) buffer transformObjectBuffer { TransformObject _object[]; }; TransformObject getTransformObject() { From 1658c15ccabe9521d6a1b3532cd4d2b8678819c9 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Fri, 15 Jan 2016 14:25:16 -0800 Subject: [PATCH 13/29] Reserve last input slot for draw call info --- libraries/gpu/src/gpu/GLBackend.h | 2 +- libraries/gpu/src/gpu/Stream.cpp | 5 +---- libraries/gpu/src/gpu/Stream.h | 3 ++- 3 files changed, 4 insertions(+), 6 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 85fada4016..31adb84040 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -193,7 +193,7 @@ public: static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS; - static const int MAX_NUM_INPUT_BUFFERS = 16; + static const int MAX_NUM_INPUT_BUFFERS = Stream::NUM_INPUT_SLOTS; size_t getNumInputBuffers() const { return _input._invalidBuffers.size(); } diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index ff765f3250..9bb12862d8 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -38,10 +38,7 @@ const ElementArray& getDefaultElements() { //INSTANCE_SCALE = 8, Element::VEC3F_XYZ, //INSTANCE_TRANSLATE = 9, - Element::VEC3F_XYZ, - //INSTANCE_XFM = 10, - // FIXME make a matrix element - Element::VEC4F_XYZW + Element::VEC3F_XYZ }}; return defaultElements; } diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 4214b99b74..f73eb1adbc 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -40,8 +40,9 @@ public: INSTANCE_SCALE = 8, INSTANCE_TRANSLATE = 9, + DRAW_CALL_INFO = 15, // Reserve last input slot for draw call infos - NUM_INPUT_SLOTS = DRAW_CALL_INFO + 1, + NUM_INPUT_SLOTS = DRAW_CALL_INFO }; typedef uint8 Slot; From 7e8ea4dc77fa91adcd7ba21711cc043010ee010a Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jan 2016 14:04:37 -0800 Subject: [PATCH 14/29] Update primitive instance rendering calls --- interface/src/Util.cpp | 17 ++++-- interface/src/avatar/Avatar.cpp | 11 ++-- interface/src/avatar/Hand.cpp | 6 +- interface/src/avatar/Head.cpp | 3 +- interface/src/avatar/SkeletonModel.cpp | 10 ++-- interface/src/ui/overlays/Cube3DOverlay.cpp | 7 ++- interface/src/ui/overlays/Sphere3DOverlay.cpp | 7 +-- .../src/RenderableBoxEntityItem.cpp | 4 +- .../src/RenderableModelEntityItem.cpp | 4 +- .../src/RenderableSphereEntityItem.cpp | 5 +- .../src/RenderableZoneEntityItem.cpp | 7 ++- libraries/render-utils/src/GeometryCache.cpp | 60 ++++++++----------- libraries/render-utils/src/GeometryCache.h | 36 +++++------ 13 files changed, 87 insertions(+), 90 deletions(-) diff --git a/interface/src/Util.cpp b/interface/src/Util.cpp index 4983983c02..43c52916fe 100644 --- a/interface/src/Util.cpp +++ b/interface/src/Util.cpp @@ -96,26 +96,31 @@ void renderWorldBox(gpu::Batch& batch) { glm::vec3(HALF_TREE_SCALE, 0.0f, HALF_TREE_SCALE), GREY); - geometryCache->renderWireCubeInstance(batch, Transform(), GREY4); + geometryCache->renderWireCubeInstance(batch, GREY4); // Draw meter markers along the 3 axis to help with measuring things const float MARKER_DISTANCE = 1.0f; const float MARKER_RADIUS = 0.05f; transform = Transform().setScale(MARKER_RADIUS); - geometryCache->renderSolidSphereInstance(batch, transform, RED); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(batch, RED); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, 0.0f)).setScale(MARKER_RADIUS); - geometryCache->renderSolidSphereInstance(batch, transform, RED); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(batch, RED); transform = Transform().setTranslation(glm::vec3(0.0f, MARKER_DISTANCE, 0.0f)).setScale(MARKER_RADIUS); - geometryCache->renderSolidSphereInstance(batch, transform, GREEN); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(batch, GREEN); transform = Transform().setTranslation(glm::vec3(0.0f, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); - geometryCache->renderSolidSphereInstance(batch, transform, BLUE); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(batch, BLUE); transform = Transform().setTranslation(glm::vec3(MARKER_DISTANCE, 0.0f, MARKER_DISTANCE)).setScale(MARKER_RADIUS); - geometryCache->renderSolidSphereInstance(batch, transform, GREY); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(batch, GREY); } // Return a random vector of average length 1 diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 7fd24ea6b7..c87db819d9 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -456,7 +456,8 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { Transform transform; transform.setTranslation(position); transform.postScale(INDICATOR_RADIUS); - DependencyManager::get()->renderSolidSphereInstance(batch, transform, LOOK_AT_INDICATOR_COLOR); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphereInstance(batch, LOOK_AT_INDICATOR_COLOR); } // If the avatar is looking at me, indicate that they are @@ -484,9 +485,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { eyeDiameter = DEFAULT_EYE_DIAMETER; } + batch.setModelTransform(Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT)); DependencyManager::get()->renderSolidSphereInstance(batch, - Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT), - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); position = getHead()->getRightEyePosition(); transform.setTranslation(position); @@ -494,9 +495,9 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { if (eyeDiameter == 0.0f) { eyeDiameter = DEFAULT_EYE_DIAMETER; } + batch.setModelTransform(Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT)); DependencyManager::get()->renderSolidSphereInstance(batch, - Transform(transform).postScale(eyeDiameter * getUniformScale() / 2.0f + RADIUS_INCREMENT), - glm::vec4(LOOKING_AT_ME_COLOR, alpha)); + glm::vec4(LOOKING_AT_ME_COLOR, alpha)); } } diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp index fba5e1ab13..5371fe5736 100644 --- a/interface/src/avatar/Hand.cpp +++ b/interface/src/avatar/Hand.cpp @@ -60,7 +60,8 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { transform.setTranslation(position); transform.setRotation(palm.getRotation()); transform.postScale(SPHERE_RADIUS); - DependencyManager::get()->renderSolidSphereInstance(batch, transform, grayColor); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphereInstance(batch, grayColor); // draw a green sphere at the old "finger tip" transform = Transform(); @@ -68,7 +69,8 @@ void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { transform.setTranslation(position); transform.setRotation(palm.getRotation()); transform.postScale(SPHERE_RADIUS); - DependencyManager::get()->renderSolidSphereInstance(batch, transform, greenColor); + batch.setModelTransform(transform); + DependencyManager::get()->renderSolidSphereInstance(batch, greenColor); } } diff --git a/interface/src/avatar/Head.cpp b/interface/src/avatar/Head.cpp index 61bc5c861e..b97fd2b0ea 100644 --- a/interface/src/avatar/Head.cpp +++ b/interface/src/avatar/Head.cpp @@ -467,5 +467,6 @@ void Head::renderLookatTarget(RenderArgs* renderArgs, glm::vec3 lookatPosition) const float LOOK_AT_TARGET_RADIUS = 0.075f; transform.postScale(LOOK_AT_TARGET_RADIUS); const glm::vec4 LOOK_AT_TARGET_COLOR = { 0.8f, 0.0f, 0.0f, 0.75f }; - geometryCache->renderSolidSphereInstance(batch, transform, LOOK_AT_TARGET_COLOR); + batch.setModelTransform(transform); + geometryCache->renderSolidSphereInstance(batch, LOOK_AT_TARGET_COLOR); } diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index ad434f6b61..d5ec58c070 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -349,17 +349,15 @@ void SkeletonModel::renderBoundingCollisionShapes(gpu::Batch& batch, float scale // draw a blue sphere at the capsule top point glm::vec3 topPoint = _translation + getRotation() * (scale * (_boundingCapsuleLocalOffset + (0.5f * _boundingCapsuleHeight) * Vectors::UNIT_Y)); - geometryCache->renderSolidSphereInstance(batch, - Transform().setTranslation(topPoint).postScale(scale * _boundingCapsuleRadius), - glm::vec4(0.6f, 0.6f, 0.8f, alpha)); + batch.setModelTransform(Transform().setTranslation(topPoint).postScale(scale * _boundingCapsuleRadius)); + geometryCache->renderSolidSphereInstance(batch, glm::vec4(0.6f, 0.6f, 0.8f, alpha)); // draw a yellow sphere at the capsule bottom point glm::vec3 bottomPoint = topPoint - glm::vec3(0.0f, scale * _boundingCapsuleHeight, 0.0f); glm::vec3 axis = topPoint - bottomPoint; - geometryCache->renderSolidSphereInstance(batch, - Transform().setTranslation(bottomPoint).postScale(scale * _boundingCapsuleRadius), - glm::vec4(0.8f, 0.8f, 0.6f, alpha)); + batch.setModelTransform(Transform().setTranslation(bottomPoint).postScale(scale * _boundingCapsuleRadius)); + geometryCache->renderSolidSphereInstance(batch, glm::vec4(0.8f, 0.8f, 0.6f, alpha)); // draw a green cylinder between the two points glm::vec3 origin(0.0f); diff --git a/interface/src/ui/overlays/Cube3DOverlay.cpp b/interface/src/ui/overlays/Cube3DOverlay.cpp index 7688bce985..e291882161 100644 --- a/interface/src/ui/overlays/Cube3DOverlay.cpp +++ b/interface/src/ui/overlays/Cube3DOverlay.cpp @@ -60,7 +60,8 @@ void Cube3DOverlay::render(RenderArgs* args) { // } transform.setScale(dimensions); - DependencyManager::get()->renderSolidCubeInstance(*batch, transform, cubeColor); + batch->setModelTransform(transform); + DependencyManager::get()->renderSolidCubeInstance(*batch, cubeColor); } else { if (getIsDashedLine()) { @@ -96,9 +97,9 @@ void Cube3DOverlay::render(RenderArgs* args) { geometryCache->renderDashedLine(*batch, bottomRightFar, topRightFar, cubeColor); } else { - batch->setModelTransform(Transform()); transform.setScale(dimensions); - DependencyManager::get()->renderWireCubeInstance(*batch, transform, cubeColor); + batch->setModelTransform(transform); + DependencyManager::get()->renderWireCubeInstance(*batch, cubeColor); } } } diff --git a/interface/src/ui/overlays/Sphere3DOverlay.cpp b/interface/src/ui/overlays/Sphere3DOverlay.cpp index 63ed7fe31d..dcd1460ff4 100644 --- a/interface/src/ui/overlays/Sphere3DOverlay.cpp +++ b/interface/src/ui/overlays/Sphere3DOverlay.cpp @@ -39,14 +39,13 @@ void Sphere3DOverlay::render(RenderArgs* args) { auto batch = args->_batch; if (batch) { - batch->setModelTransform(Transform()); - Transform transform = _transform; transform.postScale(getDimensions() * SPHERE_OVERLAY_SCALE); + batch->setModelTransform(transform); if (_isSolid) { - DependencyManager::get()->renderSolidSphereInstance(*batch, transform, sphereColor); + DependencyManager::get()->renderSolidSphereInstance(*batch, sphereColor); } else { - DependencyManager::get()->renderWireSphereInstance(*batch, transform, sphereColor); + DependencyManager::get()->renderWireSphereInstance(*batch, sphereColor); } } } diff --git a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp index 1b1437a7d9..2d054ec31b 100644 --- a/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableBoxEntityItem.cpp @@ -61,14 +61,14 @@ void RenderableBoxEntityItem::render(RenderArgs* args) { return; } + batch.setModelTransform(transToCenter); // we want to include the scale as well if (_procedural->ready()) { - batch.setModelTransform(transToCenter); // we want to include the scale as well _procedural->prepare(batch, getPosition(), getDimensions()); auto color = _procedural->getColor(cubeColor); batch._glColor4f(color.r, color.g, color.b, color.a); DependencyManager::get()->renderCube(batch); } else { - DependencyManager::get()->renderSolidCubeInstance(batch, transToCenter, cubeColor); + DependencyManager::get()->renderSolidCubeInstance(batch, cubeColor); } static const auto triCount = DependencyManager::get()->getCubeTriangleCount(); args->_details._trianglesRendered += (int)triCount; diff --git a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp index a788a76905..84c53e05da 100644 --- a/libraries/entities-renderer/src/RenderableModelEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableModelEntityItem.cpp @@ -440,8 +440,8 @@ void RenderableModelEntityItem::render(RenderArgs* args) { bool success; auto shapeTransform = getTransformToCenter(success); if (success) { - batch.setModelTransform(Transform()); // we want to include the scale as well - DependencyManager::get()->renderWireCubeInstance(batch, shapeTransform, greenColor); + batch.setModelTransform(shapeTransform); // we want to include the scale as well + DependencyManager::get()->renderWireCubeInstance(batch, greenColor); } } } diff --git a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp index 9f16de0db1..b5867fb1ee 100644 --- a/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableSphereEntityItem.cpp @@ -64,15 +64,14 @@ void RenderableSphereEntityItem::render(RenderArgs* args) { return; } modelTransform.postScale(SPHERE_ENTITY_SCALE); + batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation if (_procedural->ready()) { - batch.setModelTransform(modelTransform); // use a transform with scale, rotation, registration point and translation _procedural->prepare(batch, getPosition(), getDimensions()); auto color = _procedural->getColor(sphereColor); batch._glColor4f(color.r, color.g, color.b, color.a); DependencyManager::get()->renderSphere(batch); } else { - batch.setModelTransform(Transform()); - DependencyManager::get()->renderSolidSphereInstance(batch, modelTransform, sphereColor); + DependencyManager::get()->renderSolidSphereInstance(batch, sphereColor); } static const auto triCount = DependencyManager::get()->getSphereTriangleCount(); args->_details._trianglesRendered += (int)triCount; diff --git a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp index 9396933fc6..530c4f5063 100644 --- a/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableZoneEntityItem.cpp @@ -132,7 +132,6 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { Q_ASSERT(args->_batch); gpu::Batch& batch = *args->_batch; - batch.setModelTransform(Transform()); bool success; auto shapeTransform = getTransformToCenter(success); @@ -142,9 +141,11 @@ void RenderableZoneEntityItem::render(RenderArgs* args) { auto geometryCache = DependencyManager::get(); if (getShapeType() == SHAPE_TYPE_SPHERE) { shapeTransform.postScale(SPHERE_ENTITY_SCALE); - geometryCache->renderWireSphereInstance(batch, shapeTransform, DEFAULT_COLOR); + batch.setModelTransform(shapeTransform); + geometryCache->renderWireSphereInstance(batch, DEFAULT_COLOR); } else { - geometryCache->renderWireCubeInstance(batch, shapeTransform, DEFAULT_COLOR); + batch.setModelTransform(shapeTransform); + geometryCache->renderWireCubeInstance(batch, DEFAULT_COLOR); } break; } diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 209f3bab2f..5810e68009 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -524,24 +524,24 @@ void GeometryCache::renderWireShape(gpu::Batch& batch, Shape shape) { _shapes[shape].drawWire(batch); } -void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) { +void GeometryCache::renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer) { batch.setInputFormat(getInstancedSolidStreamFormat()); setupBatchInstance(batch, colorBuffer); _shapes[shape].drawInstances(batch, count); } -void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer) { +void GeometryCache::renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer) { batch.setInputFormat(getInstancedSolidStreamFormat()); setupBatchInstance(batch, colorBuffer); _shapes[shape].drawWireInstances(batch, count); } -void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) { - renderShapeInstances(batch, Cube, count, transformBuffer, colorBuffer); +void GeometryCache::renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) { + renderShapeInstances(batch, Cube, count, colorBuffer); } -void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) { - renderWireShapeInstances(batch, Cube, count, transformBuffer, colorBuffer); +void GeometryCache::renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) { + renderWireShapeInstances(batch, Cube, count, colorBuffer); } void GeometryCache::renderCube(gpu::Batch& batch) { @@ -552,8 +552,8 @@ void GeometryCache::renderWireCube(gpu::Batch& batch) { renderWireShape(batch, Cube); } -void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer) { - renderShapeInstances(batch, Sphere, count, transformBuffer, colorBuffer); +void GeometryCache::renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer) { + renderShapeInstances(batch, Sphere, count, colorBuffer); } void GeometryCache::renderSphere(gpu::Batch& batch) { @@ -1854,37 +1854,31 @@ static const size_t INSTANCE_TRANSFORM_BUFFER = 0; static const size_t INSTANCE_COLOR_BUFFER = 1; template -void renderInstances(const std::string& name, gpu::Batch& batch, const Transform& transform, const glm::vec4& color, F f) { +void renderInstances(const std::string& name, gpu::Batch& batch, const glm::vec4& color, F f) { { - gpu::BufferPointer instanceTransformBuffer = batch.getNamedBuffer(name, INSTANCE_TRANSFORM_BUFFER); - glm::mat4 glmTransform; - instanceTransformBuffer->append(transform.getMatrix(glmTransform)); - gpu::BufferPointer instanceColorBuffer = batch.getNamedBuffer(name, INSTANCE_COLOR_BUFFER); auto compactColor = toCompactColor(color); instanceColorBuffer->append(compactColor); } batch.setupNamedCalls(name, [f](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - auto pipeline = DependencyManager::get()->bindSimpleProgram(batch); + DependencyManager::get()->bindSimpleProgram(batch); f(batch, data); }); } -void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { +void GeometryCache::renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color) { static const std::string INSTANCE_NAME = __FUNCTION__; - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderShapeInstances(batch, GeometryCache::Sphere, data.count, - data.buffers[INSTANCE_TRANSFORM_BUFFER], + renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderShapeInstances(batch, GeometryCache::Sphere, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]); }); } -void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { +void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color) { static const std::string INSTANCE_NAME = __FUNCTION__; - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderWireShapeInstances(batch, GeometryCache::Sphere, data.count, - data.buffers[INSTANCE_TRANSFORM_BUFFER], + renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderWireShapeInstances(batch, GeometryCache::Sphere, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]); }); } @@ -1893,12 +1887,12 @@ void GeometryCache::renderWireSphereInstance(gpu::Batch& batch, const Transform& // available shape types, both solid and wireframes //#define DEBUG_SHAPES -void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { +void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color) { static const std::string INSTANCE_NAME = __FUNCTION__; #ifdef DEBUG_SHAPES static auto startTime = usecTimestampNow(); - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { auto usecs = usecTimestampNow(); usecs -= startTime; @@ -1923,29 +1917,25 @@ void GeometryCache::renderSolidCubeInstance(gpu::Batch& batch, const Transform& // For the first half second for a given shape, show the wireframe, for the second half, show the solid. if (fractionalSeconds > 0.5f) { - DependencyManager::get()->renderShapeInstances(batch, shape, data.count, - data.buffers[INSTANCE_TRANSFORM_BUFFER], + DependencyManager::get()->renderShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]); } else { - DependencyManager::get()->renderWireShapeInstances(batch, shape, data.count, - data.buffers[INSTANCE_TRANSFORM_BUFFER], + DependencyManager::get()->renderWireShapeInstances(batch, shape, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]); } }); #else - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderCubeInstances(batch, data.count, - data.buffers[INSTANCE_TRANSFORM_BUFFER], + renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderCubeInstances(batch, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]); }); #endif } -void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const Transform& transform, const glm::vec4& color) { +void GeometryCache::renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color) { static const std::string INSTANCE_NAME = __FUNCTION__; - renderInstances(INSTANCE_NAME, batch, transform, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - DependencyManager::get()->renderWireCubeInstances(batch, data.count, - data.buffers[INSTANCE_TRANSFORM_BUFFER], + renderInstances(INSTANCE_NAME, batch, color, [](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + DependencyManager::get()->renderWireCubeInstances(batch, data.count(), data.buffers[INSTANCE_COLOR_BUFFER]); }); } diff --git a/libraries/render-utils/src/GeometryCache.h b/libraries/render-utils/src/GeometryCache.h index 90ba3be978..81b8dfb325 100644 --- a/libraries/render-utils/src/GeometryCache.h +++ b/libraries/render-utils/src/GeometryCache.h @@ -154,41 +154,41 @@ public: gpu::PipelinePointer bindSimpleProgram(gpu::Batch& batch, bool textured = false, bool culled = true, bool emissive = false, bool depthBias = false); - void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderSolidSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderSolidSphereInstance(batch, xfm, glm::vec4(color, 1.0)); + void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec4& color); + void renderSolidSphereInstance(gpu::Batch& batch, const glm::vec3& color) { + renderSolidSphereInstance(batch, glm::vec4(color, 1.0)); } - void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderWireSphereInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderWireSphereInstance(batch, xfm, glm::vec4(color, 1.0)); + void renderWireSphereInstance(gpu::Batch& batch, const glm::vec4& color); + void renderWireSphereInstance(gpu::Batch& batch, const glm::vec3& color) { + renderWireSphereInstance(batch, glm::vec4(color, 1.0)); } - void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderSolidCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderSolidCubeInstance(batch, xfm, glm::vec4(color, 1.0)); + void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec4& color); + void renderSolidCubeInstance(gpu::Batch& batch, const glm::vec3& color) { + renderSolidCubeInstance(batch, glm::vec4(color, 1.0)); } - void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec4& color); - void renderWireCubeInstance(gpu::Batch& batch, const Transform& xfm, const glm::vec3& color) { - renderWireCubeInstance(batch, xfm, glm::vec4(color, 1.0)); + void renderWireCubeInstance(gpu::Batch& batch, const glm::vec4& color); + void renderWireCubeInstance(gpu::Batch& batch, const glm::vec3& color) { + renderWireCubeInstance(batch, glm::vec4(color, 1.0)); } - void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer); - void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& transformBuffer, gpu::BufferPointer& colorBuffer); + void renderShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer); + void renderWireShapeInstances(gpu::Batch& batch, Shape shape, size_t count, gpu::BufferPointer& colorBuffer); void renderShape(gpu::Batch& batch, Shape shape); void renderWireShape(gpu::Batch& batch, Shape shape); size_t getShapeTriangleCount(Shape shape); - void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); - void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); + void renderCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer); + void renderWireCubeInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer); void renderCube(gpu::Batch& batch); void renderWireCube(gpu::Batch& batch); size_t getCubeTriangleCount(); - void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); - void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer transformBuffer, gpu::BufferPointer colorBuffer); + void renderSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer); + void renderWireSphereInstances(gpu::Batch& batch, size_t count, gpu::BufferPointer colorBuffer); void renderSphere(gpu::Batch& batch); void renderWireSphere(gpu::Batch& batch); size_t getSphereTriangleCount(); From 670cfc263bb311d9193e4e7815c2f197a2f7b5e6 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jan 2016 14:05:51 -0800 Subject: [PATCH 15/29] Capture draw call info and model xfm in batch --- libraries/gpu/src/gpu/Batch.cpp | 88 +++++++++++++++----- libraries/gpu/src/gpu/Batch.h | 47 +++++++++-- libraries/gpu/src/gpu/Context.h | 7 -- libraries/gpu/src/gpu/GLBackend.cpp | 31 +------ libraries/gpu/src/gpu/GLBackend.h | 36 ++------ libraries/gpu/src/gpu/GLBackendTransform.cpp | 30 ++----- 6 files changed, 120 insertions(+), 119 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 9d12e10301..e4e76cb134 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -29,20 +29,6 @@ ProfileRangeBatch::~ProfileRangeBatch() { using namespace gpu; -Batch::Batch() : - _commands(), - _commandOffsets(), - _params(), - _data(), - _buffers(), - _textures(), - _streamFormats(), - _transforms(), - _pipelines(), - _framebuffers() -{ -} - Batch::Batch(const CacheState& cacheState) : Batch() { _commands.reserve(cacheState.commandsSize); _commandOffsets.reserve(cacheState.offsetsSize); @@ -88,6 +74,8 @@ void Batch::draw(Primitive primitiveType, uint32 numVertices, uint32 startVertex _params.push_back(startVertex); _params.push_back(numVertices); _params.push_back(primitiveType); + + captureDrawCallInfo(); } void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 startIndex) { @@ -96,6 +84,8 @@ void Batch::drawIndexed(Primitive primitiveType, uint32 numIndices, uint32 start _params.push_back(startIndex); _params.push_back(numIndices); _params.push_back(primitiveType); + + captureDrawCallInfo(); } void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 numVertices, uint32 startVertex, uint32 startInstance) { @@ -106,6 +96,8 @@ void Batch::drawInstanced(uint32 numInstances, Primitive primitiveType, uint32 n _params.push_back(numVertices); _params.push_back(primitiveType); _params.push_back(numInstances); + + captureDrawCallInfo(); } void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, uint32 numIndices, uint32 startIndex, uint32 startInstance) { @@ -116,6 +108,8 @@ void Batch::drawIndexedInstanced(uint32 numInstances, Primitive primitiveType, u _params.push_back(numIndices); _params.push_back(primitiveType); _params.push_back(numInstances); + + captureDrawCallInfo(); } @@ -123,12 +117,16 @@ void Batch::multiDrawIndirect(uint32 numCommands, Primitive primitiveType) { ADD_COMMAND(multiDrawIndirect); _params.push_back(numCommands); _params.push_back(primitiveType); + + captureDrawCallInfo(); } void Batch::multiDrawIndexedIndirect(uint32 nbCommands, Primitive primitiveType) { ADD_COMMAND(multiDrawIndexedIndirect); _params.push_back(nbCommands); _params.push_back(primitiveType); + + captureDrawCallInfo(); } void Batch::setInputFormat(const Stream::FormatPointer& format) { @@ -185,7 +183,8 @@ void Batch::setIndirectBuffer(const BufferPointer& buffer, Offset offset, Offset void Batch::setModelTransform(const Transform& model) { ADD_COMMAND(setModelTransform); - _params.push_back(_transforms.cache(model)); + _currentModel = model; + _invalidModel = true; } void Batch::setViewTransform(const Transform& view) { @@ -347,10 +346,14 @@ void Batch::runLambda(std::function f) { void Batch::startNamedCall(const std::string& name) { ADD_COMMAND(startNamedCall); _params.push_back(_names.cache(name)); + + _currentNamedCall = name; } void Batch::stopNamedCall() { ADD_COMMAND(stopNamedCall); + + _currentNamedCall.clear(); } void Batch::enableStereo(bool enable) { @@ -369,14 +372,13 @@ bool Batch::isSkyboxEnabled() const { return _enableSkybox; } -void Batch::setupNamedCalls(const std::string& instanceName, size_t count, NamedBatchData::Function function) { - NamedBatchData& instance = _namedData[instanceName]; - instance.count += count; - instance.function = function; -} - void Batch::setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function) { - setupNamedCalls(instanceName, 1, function); + NamedBatchData& instance = _namedData[instanceName]; + if (!instance.function) { + instance.function = function; + } + + captureDrawCallInfo(); } BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t index) { @@ -385,11 +387,51 @@ BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t ind instance.buffers.resize(index + 1); } if (!instance.buffers[index]) { - instance.buffers[index].reset(new Buffer()); + instance.buffers[index] = std::make_shared(); } return instance.buffers[index]; } +Batch::DrawCallInfoBuffer& Batch::getDrawCallInfoBuffer() { + if (_currentNamedCall.empty()) { + return _drawCallInfos; + } else { + return _namedData[_currentNamedCall].drawCallInfos; + } +} + +const Batch::DrawCallInfoBuffer& Batch::getDrawCallInfoBuffer() const { + if (_currentNamedCall.empty()) { + return _drawCallInfos; + } else { + auto it = _namedData.find(_currentNamedCall); + Q_ASSERT_X(it != _namedData.end(), Q_FUNC_INFO, (_currentNamedCall + " not in _namedData.").data()); + return it->second.drawCallInfos; + } +} + +void Batch::captureDrawCallInfo() { + TransformObject object; + + if (_invalidModel) { + _currentModel.getMatrix(object._model); + + // FIXME - we don't want to be using glm::inverse() here but it fixes the flickering issue we are + // seeing with planky blocks in toybox. Our implementation of getInverseMatrix() is buggy in cases + // of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works. + //_model.getInverseMatrix(_object._modelInverse); + object._modelInverse = glm::inverse(object._model); + + _objects.push_back(object); + } + + // Flags are clean + _invalidModel = false; + + auto& drawCallInfos = getDrawCallInfoBuffer(); + drawCallInfos.push_back((uint16)_objects.size() - 1); +} + void Batch::preExecute() { for (auto& mapItem : _namedData) { auto& name = mapItem.first; diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index e28334896e..88b78de4f8 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -45,13 +45,31 @@ class Batch { public: typedef Stream::Slot Slot; + + class DrawCallInfo { + public: + using Index = uint16_t; + + DrawCallInfo(Index idx) : index(idx) {} + + Index index{0}; + uint16_t unused{0}; // Reserved space for later + + }; + // Make sure DrawCallInfo has no extra padding + static_assert(sizeof(DrawCallInfo) == 4, "DrawCallInfo size is incorrect."); + + using DrawCallInfoBuffer = std::vector; + struct NamedBatchData { using BufferPointers = std::vector; using Function = std::function; BufferPointers buffers; - size_t count { 0 }; Function function; + DrawCallInfoBuffer drawCallInfos; + + size_t count() const { return drawCallInfos.size(); } void process(Batch& batch) { if (function) { @@ -62,6 +80,14 @@ public: using NamedBatchDataMap = std::map; + DrawCallInfoBuffer _drawCallInfos; + + std::string _currentNamedCall; + + const DrawCallInfoBuffer& getDrawCallInfoBuffer() const; + DrawCallInfoBuffer& getDrawCallInfoBuffer(); + void captureDrawCallInfo(); + class CacheState { public: size_t commandsSize; @@ -88,7 +114,7 @@ public: transformsSize(transformsSize), pipelinesSize(pipelinesSize), framebuffersSize(framebuffersSize), queriesSize(queriesSize) { } }; - Batch(); + Batch() {} Batch(const CacheState& cacheState); explicit Batch(const Batch& batch); ~Batch(); @@ -121,13 +147,8 @@ public: void multiDrawIndirect(uint32 numCommands, Primitive primitiveType); void multiDrawIndexedIndirect(uint32 numCommands, Primitive primitiveType); - - void setupNamedCalls(const std::string& instanceName, size_t count, NamedBatchData::Function function); void setupNamedCalls(const std::string& instanceName, NamedBatchData::Function function); BufferPointer getNamedBuffer(const std::string& instanceName, uint8_t index = 0); - void setNamedBuffer(const std::string& instanceName, BufferPointer& buffer, uint8_t index = 0); - - // Input Stage // InputFormat @@ -418,6 +439,18 @@ public: Params _params; Bytes _data; + // SSBO class... layout MUST match the layout in TransformCamera.slh + class TransformObject { + public: + Mat4 _model; + Mat4 _modelInverse; + }; + + using TransformObjects = std::vector; + bool _invalidModel { false }; + Transform _currentModel; + TransformObjects _objects; + BufferCaches _buffers; TextureCaches _textures; StreamFormatCaches _streamFormats; diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index ed2afe91eb..dceb606f20 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -76,13 +76,6 @@ public: virtual void syncCache() = 0; virtual void downloadFramebuffer(const FramebufferPointer& srcFramebuffer, const Vec4i& region, QImage& destImage) = 0; - // UBO class... layout MUST match the layout in TransformCamera.slh - class TransformObject { - public: - Mat4 _model; - Mat4 _modelInverse; - }; - // UBO class... layout MUST match the layout in TransformCamera.slh class TransformCamera { public: diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index dbabee65ff..7d3ac78c57 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -124,11 +124,7 @@ Backend* GLBackend::createBackend() { return new GLBackend(); } -GLBackend::GLBackend() : - _input(), - _pipeline(), - _output() -{ +GLBackend::GLBackend() { glGetIntegerv(GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT, &_uboAlignment); initInput(); initTransform(); @@ -160,9 +156,6 @@ void GLBackend::renderPassTransfer(Batch& batch) { PROFILE_RANGE("syncCPUTransform"); _transform._cameras.clear(); _transform._cameraOffsets.clear(); - _transform._objects.clear(); - _drawCallInfos.clear(); - _namedDrawCallInfos.clear(); for (_commandIndex = 0; _commandIndex < numCommands; ++_commandIndex) { switch (*command) { @@ -173,12 +166,8 @@ void GLBackend::renderPassTransfer(Batch& batch) { case Batch::COMMAND_multiDrawIndirect: case Batch::COMMAND_multiDrawIndexedIndirect: _transform.preUpdate(_commandIndex, _stereo); - captureDrawCallInfo(); break; - case Batch::COMMAND_startNamedCall: - case Batch::COMMAND_stopNamedCall: - case Batch::COMMAND_setModelTransform: case Batch::COMMAND_setViewportTransform: case Batch::COMMAND_setViewTransform: case Batch::COMMAND_setProjectionTransform: { @@ -197,7 +186,7 @@ void GLBackend::renderPassTransfer(Batch& batch) { { // Sync the transform buffers PROFILE_RANGE("syncGPUTransform"); - _transform.transfer(); + _transform.transfer(batch); } @@ -229,7 +218,7 @@ void GLBackend::renderPassDraw(Batch& batch) { // updates for draw calls ++_currentDraw; updateInput(); - updateTransform(); + updateTransform(batch); updatePipeline(); // Fallthrough to next case default: { @@ -277,20 +266,6 @@ void GLBackend::render(Batch& batch) { _stereo._enable = savedStereo; } - -GLBackend::DrawCallInfoBuffer& GLBackend::getDrawCallInfoBuffer() { - if (_currentNamedCall.empty()) { - return _drawCallInfos; - } else { - return _namedDrawCallInfos[_currentNamedCall]; - } -} - -void GLBackend::captureDrawCallInfo() { - auto& drawCallInfos = getDrawCallInfoBuffer(); - drawCallInfos.push_back((uint16)_transform._objects.size() - 1); -} - bool GLBackend::checkGLError(const char* name) { GLenum error = glGetError(); if (!error) { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 31adb84040..20612a3d4a 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -245,30 +245,6 @@ protected: void renderPassTransfer(Batch& batch); void renderPassDraw(Batch& batch); - class DrawCallInfo { - public: - using Index = uint16_t; - - DrawCallInfo(Index idx) : index(idx) {} - - Index index { 0 }; - uint16_t unused { 0 }; // Reserved space for later - }; - // Make sure DrawCallInfo has no extra padding - static_assert(sizeof(DrawCallInfo) == 4, "DrawCallInfo size is incorrect."); - - using DrawCallInfoBuffer = std::vector; - using NamedDrawCallInfoBuffer = std::map; - - int _currentDraw{ -1 }; - DrawCallInfoBuffer _drawCallInfos; - NamedDrawCallInfoBuffer _namedDrawCallInfos; - - std::string _currentNamedCall; - - DrawCallInfoBuffer& getDrawCallInfoBuffer(); - void captureDrawCallInfo(); - Stats _stats; // Draw Stage @@ -344,27 +320,22 @@ protected: void killTransform(); // Synchronize the state cache of this Backend with the actual real state of the GL Context void syncTransformStateCache(); - void updateTransform(); + void updateTransform(const Batch& batch); void resetTransformStage(); struct TransformStageState { - using TransformObjects = std::vector; using TransformCameras = std::vector; - TransformObject _object; TransformCamera _camera; - TransformObjects _objects; TransformCameras _cameras; GLuint _objectBuffer{ 0 }; GLuint _cameraBuffer{ 0 }; size_t _cameraUboSize{ 0 }; - Transform _model; Transform _view; Mat4 _projection; Vec4i _viewport{ 0, 0, 1, 1 }; Vec2 _depthRange{ 0.0f, 1.0f }; - bool _invalidModel{true}; bool _invalidView{false}; bool _invalidProj{false}; bool _invalidViewport{ false }; @@ -376,7 +347,7 @@ protected: void preUpdate(size_t commandIndex, const StereoState& stereo); void update(size_t commandIndex, const StereoState& stereo) const; - void transfer() const; + void transfer(const Batch& batch) const; } _transform; int32_t _uboAlignment{ 0 }; @@ -510,6 +481,9 @@ protected: void do_pushProfileRange(Batch& batch, size_t paramOffset); void do_popProfileRange(Batch& batch, size_t paramOffset); + + std::string _currentNamedCall; + int _currentDraw { -1 }; typedef void (GLBackend::*CommandCall)(Batch&, size_t); static CommandCall _commandCalls[Batch::NUM_COMMANDS]; diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 33d60eaac5..5c811e5820 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -16,8 +16,6 @@ using namespace gpu; // Transform Stage void GLBackend::do_setModelTransform(Batch& batch, size_t paramOffset) { - _transform._model = batch._transforms.get(batch._params[paramOffset]._uint); - _transform._invalidModel = true; } void GLBackend::do_setViewTransform(Batch& batch, size_t paramOffset) { @@ -78,7 +76,6 @@ void GLBackend::syncTransformStateCache() { _transform._invalidViewport = true; _transform._invalidProj = true; _transform._invalidView = true; - _transform._invalidModel = true; glGetIntegerv(GL_VIEWPORT, (GLint*) &_transform._viewport); @@ -87,7 +84,6 @@ void GLBackend::syncTransformStateCache() { Mat4 modelView; auto modelViewInv = glm::inverse(modelView); _transform._view.evalFromRawMatrix(modelViewInv); - _transform._model.setIdentity(); } void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const StereoState& stereo) { @@ -104,18 +100,6 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo _view.getInverseMatrix(_camera._view); } - if (_invalidModel) { - _model.getMatrix(_object._model); - - // FIXME - we don't want to be using glm::inverse() here but it fixes the flickering issue we are - // seeing with planky blocks in toybox. Our implementation of getInverseMatrix() is buggy in cases - // of non-uniform scale. We need to fix that. In the mean time, glm::inverse() works. - //_model.getInverseMatrix(_object._modelInverse); - _object._modelInverse = glm::inverse(_object._model); - - _objects.push_back(_object); - } - if (_invalidView || _invalidProj || _invalidViewport) { size_t offset = _cameraUboSize * _cameras.size(); if (stereo._enable) { @@ -130,10 +114,10 @@ void GLBackend::TransformStageState::preUpdate(size_t commandIndex, const Stereo } // Flags are clean - _invalidView = _invalidProj = _invalidModel = _invalidViewport = false; + _invalidView = _invalidProj = _invalidViewport = false; } -void GLBackend::TransformStageState::transfer() const { +void GLBackend::TransformStageState::transfer(const Batch& batch) const { // FIXME not thread safe static std::vector bufferData; if (!_cameras.empty()) { @@ -146,10 +130,10 @@ void GLBackend::TransformStageState::transfer() const { glBindBuffer(GL_UNIFORM_BUFFER, 0); } - if (!_objects.empty()) { - auto byteSize = _objects.size() * sizeof(TransformObject); + if (!batch._objects.empty()) { + auto byteSize = batch._objects.size() * sizeof(Batch::TransformObject); bufferData.resize(byteSize); - memcpy(bufferData.data(), _objects.data(), byteSize); + memcpy(bufferData.data(), batch._objects.data(), byteSize); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); @@ -180,10 +164,10 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta (void)CHECK_GL_ERROR(); } -void GLBackend::updateTransform() { +void GLBackend::updateTransform(const Batch& batch) { _transform.update(_commandIndex, _stereo); - auto& drawCallInfoBuffer = getDrawCallInfoBuffer(); + auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); if (_currentNamedCall.empty()) { auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused); From d639a838ad1a5bdabc9e3911bc7249838b0c4018 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jan 2016 15:42:41 -0800 Subject: [PATCH 16/29] set currentNamedCall during setupNamedCalls --- libraries/gpu/src/gpu/Batch.cpp | 11 ++++++----- libraries/gpu/src/gpu/Batch.h | 2 +- libraries/gpu/src/gpu/GLBackend.cpp | 4 ++-- libraries/gpu/src/gpu/GLBackend.h | 1 - libraries/gpu/src/gpu/GLBackendTransform.cpp | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index e4e76cb134..438455ff89 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -378,7 +378,9 @@ void Batch::setupNamedCalls(const std::string& instanceName, NamedBatchData::Fun instance.function = function; } + _currentNamedCall = instanceName; captureDrawCallInfo(); + _currentNamedCall.clear(); } BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t index) { @@ -411,9 +413,8 @@ const Batch::DrawCallInfoBuffer& Batch::getDrawCallInfoBuffer() const { } void Batch::captureDrawCallInfo() { - TransformObject object; - if (_invalidModel) { + TransformObject object; _currentModel.getMatrix(object._model); // FIXME - we don't want to be using glm::inverse() here but it fixes the flickering issue we are @@ -423,10 +424,10 @@ void Batch::captureDrawCallInfo() { object._modelInverse = glm::inverse(object._model); _objects.push_back(object); - } - // Flags are clean - _invalidModel = false; + // Flag is clean + _invalidModel = false; + } auto& drawCallInfos = getDrawCallInfoBuffer(); drawCallInfos.push_back((uint16)_objects.size() - 1); diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 88b78de4f8..51e384ee61 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -447,7 +447,7 @@ public: }; using TransformObjects = std::vector; - bool _invalidModel { false }; + bool _invalidModel { true }; Transform _currentModel; TransformObjects _objects; diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 7d3ac78c57..6f37a81622 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -412,12 +412,12 @@ void GLBackend::do_runLambda(Batch& batch, size_t paramOffset) { } void GLBackend::do_startNamedCall(Batch& batch, size_t paramOffset) { - _currentNamedCall = batch._names.get(batch._params[paramOffset]._uint); + batch._currentNamedCall = batch._names.get(batch._params[paramOffset]._uint); _currentDraw = -1; } void GLBackend::do_stopNamedCall(Batch& batch, size_t paramOffset) { - _currentNamedCall.clear(); + batch._currentNamedCall.clear(); } void GLBackend::resetStages() { diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 20612a3d4a..f9a7f8626a 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -482,7 +482,6 @@ protected: void do_pushProfileRange(Batch& batch, size_t paramOffset); void do_popProfileRange(Batch& batch, size_t paramOffset); - std::string _currentNamedCall; int _currentDraw { -1 }; typedef void (GLBackend::*CommandCall)(Batch&, size_t); diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 5c811e5820..746b49d327 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -168,7 +168,7 @@ void GLBackend::updateTransform(const Batch& batch) { _transform.update(_commandIndex, _stereo); auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); - if (_currentNamedCall.empty()) { + if (batch._currentNamedCall.empty()) { auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused); } else { From 74716465690cf1620c1ada7ee0e18e1f5ad04169 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jan 2016 16:55:16 -0800 Subject: [PATCH 17/29] Disable attrib vertex on normal passes --- libraries/gpu/src/gpu/Batch.cpp | 2 -- libraries/gpu/src/gpu/GLBackendTransform.cpp | 1 + 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 438455ff89..9efef54fce 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -442,8 +442,6 @@ void Batch::preExecute() { instance.process(*this); stopNamedCall(); } - - _namedData.clear(); } QDebug& operator<<(QDebug& debug, const Batch::CacheState& cacheState) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 746b49d327..dd4f4837e0 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -169,6 +169,7 @@ void GLBackend::updateTransform(const Batch& batch) { auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); if (batch._currentNamedCall.empty()) { + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused); } else { From 6ee88c15ecfbd98b944d776ef23bff4aad26e657 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 18 Jan 2016 18:55:31 -0800 Subject: [PATCH 18/29] Use vbo for draw call infos --- libraries/gpu/src/gpu/Batch.h | 5 +-- libraries/gpu/src/gpu/GLBackend.h | 19 ++++++----- libraries/gpu/src/gpu/GLBackendTransform.cpp | 34 +++++++++++++++++--- 3 files changed, 44 insertions(+), 14 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 51e384ee61..f6cddc1c5b 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -52,8 +52,8 @@ public: DrawCallInfo(Index idx) : index(idx) {} - Index index{0}; - uint16_t unused{0}; // Reserved space for later + Index index { 0 }; + uint16_t unused { 0 }; // Reserved space for later }; // Make sure DrawCallInfo has no extra padding @@ -68,6 +68,7 @@ public: BufferPointers buffers; Function function; DrawCallInfoBuffer drawCallInfos; + size_t numVertices; size_t count() const { return drawCallInfos.size(); } diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index f9a7f8626a..d30e4e69a6 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -329,16 +329,19 @@ protected: TransformCamera _camera; TransformCameras _cameras; - GLuint _objectBuffer{ 0 }; - GLuint _cameraBuffer{ 0 }; - size_t _cameraUboSize{ 0 }; + mutable std::map _drawCallInfoOffsets; + + GLuint _objectBuffer { 0 }; + GLuint _cameraBuffer { 0 }; + GLuint _drawCallInfoBuffer { 0 }; + size_t _cameraUboSize { 0 }; Transform _view; Mat4 _projection; - Vec4i _viewport{ 0, 0, 1, 1 }; - Vec2 _depthRange{ 0.0f, 1.0f }; - bool _invalidView{false}; - bool _invalidProj{false}; - bool _invalidViewport{ false }; + Vec4i _viewport { 0, 0, 1, 1 }; + Vec2 _depthRange { 0.0f, 1.0f }; + bool _invalidView { false }; + bool _invalidProj { false }; + bool _invalidViewport { false }; using Pair = std::pair; using List = std::list; diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index dd4f4837e0..e4a07948c5 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -61,6 +61,7 @@ void GLBackend::do_setDepthRangeTransform(Batch& batch, size_t paramOffset) { void GLBackend::initTransform() { glGenBuffers(1, &_transform._objectBuffer); glGenBuffers(1, &_transform._cameraBuffer); + glGenBuffers(1, &_transform._drawCallInfoBuffer); size_t cameraSize = sizeof(TransformCamera); while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; @@ -70,6 +71,7 @@ void GLBackend::initTransform() { void GLBackend::killTransform() { glDeleteBuffers(1, &_transform._objectBuffer); glDeleteBuffers(1, &_transform._cameraBuffer); + glDeleteBuffers(1, &_transform._drawCallInfoBuffer); } void GLBackend::syncTransformStateCache() { @@ -140,6 +142,21 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } + if (!batch._namedData.empty()) { + bufferData.clear(); + for (auto& data : batch._namedData) { + auto currentSize = bufferData.size(); + auto bytesToCopy = data.second.drawCallInfos.size() * sizeof(Batch::DrawCallInfo); + bufferData.resize(currentSize + bytesToCopy); + memcpy(bufferData.data() + currentSize, data.second.drawCallInfos.data(), bytesToCopy); + _drawCallInfoOffsets[data.first] = (GLvoid*)currentSize; + } + + glBindBuffer(GL_ARRAY_BUFFER, _drawCallInfoBuffer); + glBufferData(GL_ARRAY_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_ARRAY_BUFFER, 0); + } + CHECK_GL_ERROR(); } @@ -169,12 +186,21 @@ void GLBackend::updateTransform(const Batch& batch) { auto& drawCallInfoBuffer = batch.getDrawCallInfoBuffer(); if (batch._currentNamedCall.empty()) { - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); auto& drawCallInfo = drawCallInfoBuffer[_currentDraw]; - glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, (GLint)drawCallInfo.index, (GLint)drawCallInfo.unused); + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } else { - glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); - glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_SHORT, 4, drawCallInfoBuffer.data()); + if (false) { + auto& drawCallInfo = drawCallInfoBuffer[0]; + glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled + glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); + } else { + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, + _transform._drawCallInfoOffsets[batch._currentNamedCall]); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 100000); + } } } From 71ecd1662cd769a1cbb1acaf7067f843c897ca9c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 19 Jan 2016 10:33:15 -0800 Subject: [PATCH 19/29] Add correct vertex attrib divisor --- libraries/gpu/src/gpu/Batch.h | 1 - libraries/gpu/src/gpu/GLBackendTransform.cpp | 16 +++++----------- 2 files changed, 5 insertions(+), 12 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index f6cddc1c5b..4b77ce21be 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -68,7 +68,6 @@ public: BufferPointers buffers; Function function; DrawCallInfoBuffer drawCallInfos; - size_t numVertices; size_t count() const { return drawCallInfos.size(); } diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index e4a07948c5..d678990f80 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -190,17 +190,11 @@ void GLBackend::updateTransform(const Batch& batch) { glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); } else { - if (false) { - auto& drawCallInfo = drawCallInfoBuffer[0]; - glDisableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is disabled - glVertexAttribI2i(gpu::Stream::DRAW_CALL_INFO, drawCallInfo.index, drawCallInfo.unused); - } else { - glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled - glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); - glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, - _transform._drawCallInfoOffsets[batch._currentNamedCall]); - glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 100000); - } + glEnableVertexAttribArray(gpu::Stream::DRAW_CALL_INFO); // Make sure attrib array is enabled + glBindBuffer(GL_ARRAY_BUFFER, _transform._drawCallInfoBuffer); + glVertexAttribIPointer(gpu::Stream::DRAW_CALL_INFO, 2, GL_UNSIGNED_SHORT, 0, + _transform._drawCallInfoOffsets[batch._currentNamedCall]); + glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); } } From 38a223b2703ea8cb0797c5ff303622aa35ad6d49 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 19 Jan 2016 14:43:13 -0800 Subject: [PATCH 20/29] Split declareStandardTransform --- libraries/gpu/src/gpu/Transform.slh | 35 ++++++++++++------- .../render-utils/src/model_translucent.slf | 2 +- 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 109af2835f..9dd641d54b 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -10,13 +10,8 @@ <@if not GPU_TRANSFORM_STATE_SLH@> <@def GPU_TRANSFORM_STATE_SLH@> -<@func declareStandardTransform()@> -struct TransformObject { - mat4 _model; - mat4 _modelInverse; -}; - -struct TransformCamera { +<@func declareStandardCameraTransform()@> +struct TransformCamera { mat4 _view; mat4 _viewInverse; mat4 _projectionViewUntranslated; @@ -25,6 +20,21 @@ struct TransformCamera { vec4 _viewport; }; +layout(std140) uniform transformCameraBuffer { + TransformCamera _camera; +}; +TransformCamera getTransformCamera() { + return _camera; +} +<@endfunc@> + + +<@func declareStandardObjectTransform()@> +struct TransformObject { + mat4 _model; + mat4 _modelInverse; +}; + in ivec2 _drawCallInfo; layout(std140) buffer transformObjectBuffer { @@ -33,13 +43,12 @@ layout(std140) buffer transformObjectBuffer { TransformObject getTransformObject() { return _object[_drawCallInfo.x]; } +<@endfunc@> -layout(std140) uniform transformCameraBuffer { - TransformCamera _camera; -}; -TransformCamera getTransformCamera() { - return _camera; -} + +<@func declareStandardTransform()@> +<$declareStandardObjectTransform()$> +<$declareStandardCameraTransform()$> <@endfunc@> <@func transformCameraViewport(cameraTransform, viewport)@> diff --git a/libraries/render-utils/src/model_translucent.slf b/libraries/render-utils/src/model_translucent.slf index 12e841399b..1a17258408 100755 --- a/libraries/render-utils/src/model_translucent.slf +++ b/libraries/render-utils/src/model_translucent.slf @@ -17,7 +17,7 @@ <@include DeferredLighting.slh@> <@include gpu/Transform.slh@> -<$declareStandardTransform()$> +<$declareStandardCameraTransform()$> // Everything about light From 9e8a3f19e91392f40ed3e96a1f26120020dc4096 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 19 Jan 2016 18:13:20 -0800 Subject: [PATCH 21/29] Revert max input slot changes --- libraries/gpu/src/gpu/GLBackend.h | 2 +- libraries/gpu/src/gpu/GLBackendShader.cpp | 2 ++ libraries/gpu/src/gpu/GLBackendTransform.cpp | 4 +++- libraries/gpu/src/gpu/Stream.h | 2 +- 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index d30e4e69a6..27e1548180 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -193,7 +193,7 @@ public: static const int MAX_NUM_ATTRIBUTES = Stream::NUM_INPUT_SLOTS; - static const int MAX_NUM_INPUT_BUFFERS = Stream::NUM_INPUT_SLOTS; + static const int MAX_NUM_INPUT_BUFFERS = 16; size_t getNumInputBuffers() const { return _input._invalidBuffers.size(); } diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index 45bd67f70c..ab8dbaf021 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -103,6 +103,8 @@ void makeBindings(GLBackend::GLShader* shader) { glUniformBlockBinding(glprogram, loc, gpu::TRANSFORM_CAMERA_SLOT); shader->_transformCameraSlot = gpu::TRANSFORM_CAMERA_SLOT; } + + (void)CHECK_GL_ERROR(); } GLBackend::GLShader* compileShader(const Shader& shader) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index d678990f80..1aec853796 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -173,7 +173,7 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta offset += _cameraUboSize; } glBindBufferRange(GL_UNIFORM_BUFFER, TRANSFORM_CAMERA_SLOT, - _cameraBuffer, offset, sizeof(Backend::TransformCamera)); + _cameraBuffer, offset, sizeof(Backend::TransformCamera)); } glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); @@ -196,6 +196,8 @@ void GLBackend::updateTransform(const Batch& batch) { _transform._drawCallInfoOffsets[batch._currentNamedCall]); glVertexAttribDivisor(gpu::Stream::DRAW_CALL_INFO, 1); } + + (void)CHECK_GL_ERROR(); } void GLBackend::resetTransformStage() { diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index f73eb1adbc..2d591a7105 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -39,10 +39,10 @@ public: TEXCOORD1 = 7, INSTANCE_SCALE = 8, INSTANCE_TRANSLATE = 9, + NUM_INPUT_SLOTS = INSTANCE_TRANSLATE + 1, DRAW_CALL_INFO = 15, // Reserve last input slot for draw call infos - NUM_INPUT_SLOTS = DRAW_CALL_INFO }; typedef uint8 Slot; From 8d4dab19c7d26fbb2b3be99835b4a77ed7af8ab3 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Tue, 19 Jan 2016 18:53:18 -0800 Subject: [PATCH 22/29] Only bind once per render batch --- libraries/gpu/src/gpu/GLBackendTransform.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 1aec853796..c8e9d51ff9 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -137,7 +137,7 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { bufferData.resize(byteSize); memcpy(bufferData.data(), batch._objects.data(), byteSize); - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); + glBindBuffer(GL_SHADER_STORAGE_BUFFER, _objectBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); } @@ -157,6 +157,8 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { glBindBuffer(GL_ARRAY_BUFFER, 0); } + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); + CHECK_GL_ERROR(); } @@ -176,8 +178,6 @@ void GLBackend::TransformStageState::update(size_t commandIndex, const StereoSta _cameraBuffer, offset, sizeof(Backend::TransformCamera)); } - glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); - (void)CHECK_GL_ERROR(); } From 8cf393bb594ac399683de69a2b873a9a115dc1f8 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 20 Jan 2016 10:28:01 -0800 Subject: [PATCH 23/29] Mac compatibility --- libraries/gpu/src/gpu/Batch.h | 5 +++++ libraries/gpu/src/gpu/GLBackend.h | 1 + libraries/gpu/src/gpu/GLBackendShader.cpp | 8 ++++++++ libraries/gpu/src/gpu/GLBackendTransform.cpp | 18 ++++++++++++++++++ libraries/gpu/src/gpu/Transform.slh | 20 ++++++++++++++++++++ 5 files changed, 52 insertions(+) diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 4b77ce21be..a77201591b 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -29,7 +29,12 @@ class QDebug; namespace gpu { enum ReservedSlot { + +#ifdef WIN32 TRANSFORM_OBJECT_SLOT = 6, +#else + TRANSFORM_OBJECT_SLOT = 31, +#endif TRANSFORM_CAMERA_SLOT = 7, }; diff --git a/libraries/gpu/src/gpu/GLBackend.h b/libraries/gpu/src/gpu/GLBackend.h index 27e1548180..7f37a73c57 100644 --- a/libraries/gpu/src/gpu/GLBackend.h +++ b/libraries/gpu/src/gpu/GLBackend.h @@ -334,6 +334,7 @@ protected: GLuint _objectBuffer { 0 }; GLuint _cameraBuffer { 0 }; GLuint _drawCallInfoBuffer { 0 }; + GLuint _objectBufferTexture { 0 }; size_t _cameraUboSize { 0 }; Transform _view; Mat4 _projection; diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index ab8dbaf021..8bd0d0927c 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -92,11 +92,19 @@ void makeBindings(GLBackend::GLShader* shader) { // now assign the ubo binding, then DON't relink! //Check for gpu specific uniform slotBindings +#ifdef WIN32 loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer"); if (loc >= 0) { glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT; } +#else + loc = glGetUniformLocation(glprogram, "transformObjectBuffer"); + if (loc >= 0) { + glProgramUniform1i(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); + shader->_transformObjectSlot = gpu::TRANSFORM_OBJECT_SLOT; + } +#endif loc = glGetUniformBlockIndex(glprogram, "transformCameraBuffer"); if (loc >= 0) { diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index c8e9d51ff9..52d1f071f7 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -62,6 +62,9 @@ void GLBackend::initTransform() { glGenBuffers(1, &_transform._objectBuffer); glGenBuffers(1, &_transform._cameraBuffer); glGenBuffers(1, &_transform._drawCallInfoBuffer); +#ifndef WIN32 + glGenTextures(1, &_transform._objectBufferTexture); +#endif size_t cameraSize = sizeof(TransformCamera); while (_transform._cameraUboSize < cameraSize) { _transform._cameraUboSize += _uboAlignment; @@ -72,6 +75,9 @@ void GLBackend::killTransform() { glDeleteBuffers(1, &_transform._objectBuffer); glDeleteBuffers(1, &_transform._cameraBuffer); glDeleteBuffers(1, &_transform._drawCallInfoBuffer); +#ifndef WIN32 + glDeleteTextures(1, &_transform._objectBufferTexture); +#endif } void GLBackend::syncTransformStateCache() { @@ -137,9 +143,15 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { bufferData.resize(byteSize); memcpy(bufferData.data(), batch._objects.data(), byteSize); +#ifdef WIN32 glBindBuffer(GL_SHADER_STORAGE_BUFFER, _objectBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); +#else + glBindBuffer(GL_TEXTURE_BUFFER, _objectBuffer); + glBufferData(GL_TEXTURE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); + glBindBuffer(GL_TEXTURE_BUFFER, 0); +#endif } if (!batch._namedData.empty()) { @@ -157,7 +169,13 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { glBindBuffer(GL_ARRAY_BUFFER, 0); } +#ifdef WIN32 glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); +#else + glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT); + glBindTexture(GL_TEXTURE_BUFFER, _objectBufferTexture); + glTexBuffer(GL_TEXTURE_BUFFER, GL_RGBA32F, _objectBuffer); +#endif CHECK_GL_ERROR(); } diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 9dd641d54b..4708c20a55 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -37,12 +37,32 @@ struct TransformObject { in ivec2 _drawCallInfo; +<@if GLPROFILE == PC_GL @> layout(std140) buffer transformObjectBuffer { TransformObject _object[]; }; TransformObject getTransformObject() { return _object[_drawCallInfo.x]; } +<@else@> +uniform samplerBuffer transformObjectBuffer; + +TransformObject getTransformObject() { + int offset = 8 * _drawCallInfo.x; + TransformObject object; + object._model[0] = texelFetch(transformObjectBuffer, offset); + object._model[1] = texelFetch(transformObjectBuffer, offset + 1); + object._model[2] = texelFetch(transformObjectBuffer, offset + 2); + object._model[3] = texelFetch(transformObjectBuffer, offset + 3); + + object._modelInverse[0] = texelFetch(transformObjectBuffer, offset + 4); + object._modelInverse[1] = texelFetch(transformObjectBuffer, offset + 5); + object._modelInverse[2] = texelFetch(transformObjectBuffer, offset + 6); + object._modelInverse[3] = texelFetch(transformObjectBuffer, offset + 7); + + return object; +} +<@endif@> <@endfunc@> From 72790d361b6f431184bb335f1af23fe88bfc311c Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 20 Jan 2016 11:13:09 -0800 Subject: [PATCH 24/29] Update gpu-test --- tests/gpu-test/src/main.cpp | 27 ++++++++++++++------------- 1 file changed, 14 insertions(+), 13 deletions(-) diff --git a/tests/gpu-test/src/main.cpp b/tests/gpu-test/src/main.cpp index 4142c4f521..b1ca3d0448 100644 --- a/tests/gpu-test/src/main.cpp +++ b/tests/gpu-test/src/main.cpp @@ -216,16 +216,16 @@ public: static const std::string GRID_INSTANCE = "Grid"; static auto compactColor1 = toCompactColor(vec4{ 0.35f, 0.25f, 0.15f, 1.0f }); static auto compactColor2 = toCompactColor(vec4{ 0.15f, 0.25f, 0.35f, 1.0f }); - static gpu::BufferPointer transformBuffer; + static std::vector transforms; static gpu::BufferPointer colorBuffer; - if (!transformBuffer) { - transformBuffer = std::make_shared(); + if (!transforms.empty()) { + transforms.reserve(200); colorBuffer = std::make_shared(); for (int i = 0; i < 100; ++i) { { glm::mat4 transform = glm::translate(mat4(), vec3(0, -1, -50 + i)); transform = glm::scale(transform, vec3(100, 1, 1)); - transformBuffer->append(transform); + transforms.push_back(transform); colorBuffer->append(compactColor1); } @@ -233,18 +233,20 @@ public: glm::mat4 transform = glm::mat4_cast(quat(vec3(0, PI / 2.0f, 0))); transform = glm::translate(transform, vec3(0, -1, -50 + i)); transform = glm::scale(transform, vec3(100, 1, 1)); - transformBuffer->append(transform); + transforms.push_back(transform); colorBuffer->append(compactColor2); } } } - - batch.setupNamedCalls(GRID_INSTANCE, 200, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { - batch.setViewTransform(camera); - batch.setModelTransform(Transform()); - batch.setPipeline(_pipeline); - geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count, transformBuffer, colorBuffer); - }); + + for (auto& transform : transforms) { + batch.setModelTransform(transform); + batch.setupNamedCalls(GRID_INSTANCE, [=](gpu::Batch& batch, gpu::Batch::NamedBatchData& data) { + batch.setViewTransform(camera); + batch.setPipeline(_pipeline); + geometryCache->renderWireShapeInstances(batch, GeometryCache::Line, data.count(), colorBuffer); + }); + } } { @@ -314,7 +316,6 @@ public: batch.setPipeline(_pipeline); batch.setInputFormat(getInstancedSolidStreamFormat()); batch.setInputBuffer(gpu::Stream::COLOR, colorView); - batch.setInputBuffer(gpu::Stream::INSTANCE_XFM, instanceXfmView); batch.setIndirectBuffer(indirectBuffer); shapeData.setupBatch(batch); batch.multiDrawIndexedIndirect(TYPE_COUNT, gpu::TRIANGLES); From a5603140deb3d1b5f43e0f034283cce50b51a627 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 20 Jan 2016 12:28:14 -0800 Subject: [PATCH 25/29] Fix for mac --- libraries/gpu/src/gpu/Inputs.slh | 16 ++++++++-------- libraries/gpu/src/gpu/Stream.cpp | 6 +----- libraries/gpu/src/gpu/Stream.h | 4 +--- libraries/gpu/src/gpu/Transform.slh | 2 +- libraries/render-utils/src/GeometryCache.cpp | 3 +-- 5 files changed, 12 insertions(+), 19 deletions(-) diff --git a/libraries/gpu/src/gpu/Inputs.slh b/libraries/gpu/src/gpu/Inputs.slh index 8f90b6ebee..ce5e4227eb 100644 --- a/libraries/gpu/src/gpu/Inputs.slh +++ b/libraries/gpu/src/gpu/Inputs.slh @@ -10,12 +10,12 @@ !> <@if not GPU_INPUTS_SLH@> <@def GPU_INPUTS_SLH@> -in vec4 inPosition; -in vec4 inNormal; -in vec4 inColor; -in vec4 inTexCoord0; -in vec4 inTangent; -in vec4 inSkinClusterIndex; -in vec4 inSkinClusterWeight; -in vec4 inTexCoord1; +layout(location = 0) in vec4 inPosition; +layout(location = 1) in vec4 inNormal; +layout(location = 2) in vec4 inColor; +layout(location = 3) in vec4 inTexCoord0; +layout(location = 4) in vec4 inTangent; +layout(location = 5) in vec4 inSkinClusterIndex; +layout(location = 6) in vec4 inSkinClusterWeight; +layout(location = 7) in vec4 inTexCoord1; <@endif@> diff --git a/libraries/gpu/src/gpu/Stream.cpp b/libraries/gpu/src/gpu/Stream.cpp index 9bb12862d8..90f2327fc8 100644 --- a/libraries/gpu/src/gpu/Stream.cpp +++ b/libraries/gpu/src/gpu/Stream.cpp @@ -34,11 +34,7 @@ const ElementArray& getDefaultElements() { //SKIN_CLUSTER_WEIGHT = 6, Element::VEC4F_XYZW, //TEXCOORD1 = 7, - Element::VEC2F_UV, - //INSTANCE_SCALE = 8, - Element::VEC3F_XYZ, - //INSTANCE_TRANSLATE = 9, - Element::VEC3F_XYZ + Element::VEC2F_UV }}; return defaultElements; } diff --git a/libraries/gpu/src/gpu/Stream.h b/libraries/gpu/src/gpu/Stream.h index 2d591a7105..c8d9335bf7 100644 --- a/libraries/gpu/src/gpu/Stream.h +++ b/libraries/gpu/src/gpu/Stream.h @@ -37,9 +37,7 @@ public: SKIN_CLUSTER_INDEX = 5, SKIN_CLUSTER_WEIGHT = 6, TEXCOORD1 = 7, - INSTANCE_SCALE = 8, - INSTANCE_TRANSLATE = 9, - NUM_INPUT_SLOTS = INSTANCE_TRANSLATE + 1, + NUM_INPUT_SLOTS = TEXCOORD1 + 1, DRAW_CALL_INFO = 15, // Reserve last input slot for draw call infos diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 4708c20a55..6e73834aed 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -35,7 +35,7 @@ struct TransformObject { mat4 _modelInverse; }; -in ivec2 _drawCallInfo; +layout(location=15) in ivec2 _drawCallInfo; <@if GLPROFILE == PC_GL @> layout(std140) buffer transformObjectBuffer { diff --git a/libraries/render-utils/src/GeometryCache.cpp b/libraries/render-utils/src/GeometryCache.cpp index 5810e68009..aa82232524 100644 --- a/libraries/render-utils/src/GeometryCache.cpp +++ b/libraries/render-utils/src/GeometryCache.cpp @@ -1850,8 +1850,7 @@ uint32_t toCompactColor(const glm::vec4& color) { return compactColor; } -static const size_t INSTANCE_TRANSFORM_BUFFER = 0; -static const size_t INSTANCE_COLOR_BUFFER = 1; +static const size_t INSTANCE_COLOR_BUFFER = 0; template void renderInstances(const std::string& name, gpu::Batch& batch, const glm::vec4& color, F f) { From 838b6375913af94f5316f04a5ff5c64dc646f929 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Wed, 20 Jan 2016 13:25:38 -0800 Subject: [PATCH 26/29] Don't capture raw draw calls during named calls processing --- libraries/gpu/src/gpu/Batch.cpp | 21 +++++++++++++++++---- libraries/gpu/src/gpu/Batch.h | 4 ++++ 2 files changed, 21 insertions(+), 4 deletions(-) diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index 9efef54fce..18e923831f 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -378,9 +378,7 @@ void Batch::setupNamedCalls(const std::string& instanceName, NamedBatchData::Fun instance.function = function; } - _currentNamedCall = instanceName; - captureDrawCallInfo(); - _currentNamedCall.clear(); + captureNamedDrawCallInfo(instanceName); } BufferPointer Batch::getNamedBuffer(const std::string& instanceName, uint8_t index) { @@ -412,7 +410,7 @@ const Batch::DrawCallInfoBuffer& Batch::getDrawCallInfoBuffer() const { } } -void Batch::captureDrawCallInfo() { +void Batch::captureDrawCallInfoImpl() { if (_invalidModel) { TransformObject object; _currentModel.getMatrix(object._model); @@ -433,6 +431,21 @@ void Batch::captureDrawCallInfo() { drawCallInfos.push_back((uint16)_objects.size() - 1); } +void Batch::captureDrawCallInfo() { + if (!_currentNamedCall.empty()) { + // If we are processing a named call, we don't want to register the raw draw calls + return; + } + + captureDrawCallInfoImpl(); +} + +void Batch::captureNamedDrawCallInfo(std::string name) { + std::swap(_currentNamedCall, name); // Set and save _currentNamedCall + captureDrawCallInfoImpl(); + std::swap(_currentNamedCall, name); // Restore _currentNamedCall +} + void Batch::preExecute() { for (auto& mapItem : _namedData) { auto& name = mapItem.first; diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index a77201591b..2d1f9d070d 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -91,7 +91,9 @@ public: const DrawCallInfoBuffer& getDrawCallInfoBuffer() const; DrawCallInfoBuffer& getDrawCallInfoBuffer(); + void captureDrawCallInfo(); + void captureNamedDrawCallInfo(std::string name); class CacheState { public: @@ -478,6 +480,8 @@ protected: // Maybe useful but shoudln't be public. Please convince me otherwise void runLambda(std::function f); + + void captureDrawCallInfoImpl(); }; } From 52885545ea1cd6cf558dfe891b5e2b6686079ef5 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 21 Jan 2016 11:53:41 -0800 Subject: [PATCH 27/29] Use feature name for ifdef --- libraries/gl/src/gl/Config.h | 11 +++++++---- libraries/gpu/src/gpu/Batch.h | 2 +- libraries/gpu/src/gpu/GLBackendShader.cpp | 2 +- libraries/gpu/src/gpu/GLBackendTransform.cpp | 8 ++++---- 4 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libraries/gl/src/gl/Config.h b/libraries/gl/src/gl/Config.h index 2e42e85122..5c04fe0cf8 100644 --- a/libraries/gl/src/gl/Config.h +++ b/libraries/gl/src/gl/Config.h @@ -9,8 +9,8 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -#ifndef gpu__GPUConfig__ -#define gpu__GPUConfig__ +#ifndef hifi_gpu_GPUConfig_h +#define hifi_gpu_GPUConfig_h #define GL_GLEXT_PROTOTYPES 1 @@ -38,8 +38,6 @@ #define GPU_FEATURE_PROFILE GPU_CORE #define GPU_INPUT_PROFILE GPU_CORE_43 -#elif defined(ANDROID) - #else #include @@ -50,4 +48,9 @@ #endif +#if (GPU_INPUT_PROFILE == GPU_CORE_43) +#define GPU_SSBO_DRAW_CALL_INFO #endif + + +#endif // hifi_gpu_GPUConfig_h diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 2d1f9d070d..a2ee57759f 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -30,7 +30,7 @@ namespace gpu { enum ReservedSlot { -#ifdef WIN32 +#ifdef GPU_SSBO_DRAW_CALL_INFO TRANSFORM_OBJECT_SLOT = 6, #else TRANSFORM_OBJECT_SLOT = 31, diff --git a/libraries/gpu/src/gpu/GLBackendShader.cpp b/libraries/gpu/src/gpu/GLBackendShader.cpp index 8bd0d0927c..ca9c014c00 100755 --- a/libraries/gpu/src/gpu/GLBackendShader.cpp +++ b/libraries/gpu/src/gpu/GLBackendShader.cpp @@ -92,7 +92,7 @@ void makeBindings(GLBackend::GLShader* shader) { // now assign the ubo binding, then DON't relink! //Check for gpu specific uniform slotBindings -#ifdef WIN32 +#ifdef GPU_SSBO_DRAW_CALL_INFO loc = glGetProgramResourceIndex(glprogram, GL_SHADER_STORAGE_BLOCK, "transformObjectBuffer"); if (loc >= 0) { glShaderStorageBlockBinding(glprogram, loc, gpu::TRANSFORM_OBJECT_SLOT); diff --git a/libraries/gpu/src/gpu/GLBackendTransform.cpp b/libraries/gpu/src/gpu/GLBackendTransform.cpp index 52d1f071f7..d5bcfa3321 100755 --- a/libraries/gpu/src/gpu/GLBackendTransform.cpp +++ b/libraries/gpu/src/gpu/GLBackendTransform.cpp @@ -62,7 +62,7 @@ void GLBackend::initTransform() { glGenBuffers(1, &_transform._objectBuffer); glGenBuffers(1, &_transform._cameraBuffer); glGenBuffers(1, &_transform._drawCallInfoBuffer); -#ifndef WIN32 +#ifndef GPU_SSBO_DRAW_CALL_INFO glGenTextures(1, &_transform._objectBufferTexture); #endif size_t cameraSize = sizeof(TransformCamera); @@ -75,7 +75,7 @@ void GLBackend::killTransform() { glDeleteBuffers(1, &_transform._objectBuffer); glDeleteBuffers(1, &_transform._cameraBuffer); glDeleteBuffers(1, &_transform._drawCallInfoBuffer); -#ifndef WIN32 +#ifndef GPU_SSBO_DRAW_CALL_INFO glDeleteTextures(1, &_transform._objectBufferTexture); #endif } @@ -143,7 +143,7 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { bufferData.resize(byteSize); memcpy(bufferData.data(), batch._objects.data(), byteSize); -#ifdef WIN32 +#ifdef GPU_SSBO_DRAW_CALL_INFO glBindBuffer(GL_SHADER_STORAGE_BUFFER, _objectBuffer); glBufferData(GL_SHADER_STORAGE_BUFFER, bufferData.size(), bufferData.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_SHADER_STORAGE_BUFFER, 0); @@ -169,7 +169,7 @@ void GLBackend::TransformStageState::transfer(const Batch& batch) const { glBindBuffer(GL_ARRAY_BUFFER, 0); } -#ifdef WIN32 +#ifdef GPU_SSBO_DRAW_CALL_INFO glBindBufferBase(GL_SHADER_STORAGE_BUFFER, TRANSFORM_OBJECT_SLOT, _objectBuffer); #else glActiveTexture(GL_TEXTURE0 + TRANSFORM_OBJECT_SLOT); From 5ac0350993581dd275cbdc818e33a3a4f0ed17bf Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 21 Jan 2016 11:56:08 -0800 Subject: [PATCH 28/29] Don't fall through in switch case --- libraries/gpu/src/gpu/GLBackend.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/gpu/src/gpu/GLBackend.cpp b/libraries/gpu/src/gpu/GLBackend.cpp index 6f37a81622..14e4397b83 100644 --- a/libraries/gpu/src/gpu/GLBackend.cpp +++ b/libraries/gpu/src/gpu/GLBackend.cpp @@ -214,13 +214,17 @@ void GLBackend::renderPassDraw(Batch& batch) { case Batch::COMMAND_drawInstanced: case Batch::COMMAND_drawIndexedInstanced: case Batch::COMMAND_multiDrawIndirect: - case Batch::COMMAND_multiDrawIndexedIndirect: + case Batch::COMMAND_multiDrawIndexedIndirect: { // updates for draw calls ++_currentDraw; updateInput(); updateTransform(batch); updatePipeline(); - // Fallthrough to next case + + CommandCall call = _commandCalls[(*command)]; + (this->*(call))(batch, *offset); + break; + } default: { CommandCall call = _commandCalls[(*command)]; (this->*(call))(batch, *offset); From ad215f23c6477bc91addc827e1df3ed15a9a8192 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 1 Feb 2016 18:49:38 +0100 Subject: [PATCH 29/29] Deactivate SSBOs for now --- libraries/gl/src/gl/Config.h | 4 +++- libraries/gpu/src/gpu/Config.slh | 2 +- libraries/gpu/src/gpu/Transform.slh | 3 ++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/libraries/gl/src/gl/Config.h b/libraries/gl/src/gl/Config.h index 5c04fe0cf8..8f7582c271 100644 --- a/libraries/gl/src/gl/Config.h +++ b/libraries/gl/src/gl/Config.h @@ -49,7 +49,9 @@ #if (GPU_INPUT_PROFILE == GPU_CORE_43) -#define GPU_SSBO_DRAW_CALL_INFO +// Deactivate SSBO for now, we've run into some issues +// on GL 4.3 capable GPUs not behaving as expected +//#define GPU_SSBO_DRAW_CALL_INFO #endif diff --git a/libraries/gpu/src/gpu/Config.slh b/libraries/gpu/src/gpu/Config.slh index 5a96a7eafe..3da92df7c1 100644 --- a/libraries/gpu/src/gpu/Config.slh +++ b/libraries/gpu/src/gpu/Config.slh @@ -13,7 +13,7 @@ <@if GLPROFILE == PC_GL @> <@def GPU_FEATURE_PROFILE GPU_CORE@> - <@def VERSION_HEADER #version 430 core@> + <@def VERSION_HEADER #version 410 core@> <@elif GLPROFILE == MAC_GL @> <@def GPU_FEATURE_PROFILE GPU_CORE@> <@def VERSION_HEADER #version 410 core@> diff --git a/libraries/gpu/src/gpu/Transform.slh b/libraries/gpu/src/gpu/Transform.slh index 6e73834aed..ea5ee06a7b 100644 --- a/libraries/gpu/src/gpu/Transform.slh +++ b/libraries/gpu/src/gpu/Transform.slh @@ -37,7 +37,8 @@ struct TransformObject { layout(location=15) in ivec2 _drawCallInfo; -<@if GLPROFILE == PC_GL @> +<@if FALSE @> +// Disable SSBOs for now layout(std140) buffer transformObjectBuffer { TransformObject _object[]; };