From d41f34ce8d3da5005f1ebfaba63f6631b00873ea Mon Sep 17 00:00:00 2001 From: samcake Date: Wed, 12 Apr 2017 19:07:27 -0700 Subject: [PATCH] Adding support for the resource buffer --- libraries/gpu-gl/src/gpu/gl/GLBackend.cpp | 1 + libraries/gpu-gl/src/gpu/gl/GLBackend.h | 11 +++++- .../gpu-gl/src/gpu/gl/GLBackendPipeline.cpp | 34 +++++++++++++++++++ libraries/gpu-gl/src/gpu/gl/GLShader.cpp | 6 ++-- libraries/gpu-gl/src/gpu/gl/GLShared.cpp | 20 ++++++++++- libraries/gpu-gl/src/gpu/gl/GLShared.h | 2 +- libraries/gpu-gl/src/gpu/gl41/GL41Backend.h | 4 +++ .../gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 23 +++++++++++++ libraries/gpu-gl/src/gpu/gl45/GL45Backend.h | 4 +++ .../gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp | 26 ++++++++++++++ libraries/gpu/src/gpu/Batch.cpp | 8 +++++ libraries/gpu/src/gpu/Batch.h | 6 +++- libraries/gpu/src/gpu/Context.h | 1 + .../render/src/render/drawItemBounds.slv | 9 ++++- 14 files changed, 148 insertions(+), 7 deletions(-) diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp index 0800c27839..5b80c68912 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.cpp @@ -101,6 +101,7 @@ GLBackend::CommandCall GLBackend::_commandCalls[Batch::NUM_COMMANDS] = (&::gpu::gl::GLBackend::do_setStateScissorRect), (&::gpu::gl::GLBackend::do_setUniformBuffer), + (&::gpu::gl::GLBackend::do_setResourceBuffer), (&::gpu::gl::GLBackend::do_setResourceTexture), (&::gpu::gl::GLBackend::do_setFramebuffer), diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackend.h b/libraries/gpu-gl/src/gpu/gl/GLBackend.h index 76c950ec2b..c34cb16376 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackend.h +++ b/libraries/gpu-gl/src/gpu/gl/GLBackend.h @@ -93,6 +93,8 @@ public: // this is the maximum per shader stage on the low end apple // TODO make it platform dependant at init time + static const int MAX_NUM_RESOURCE_BUFFERS = 16; + size_t getMaxNumResourceBuffers() const { return MAX_NUM_RESOURCE_BUFFERS; } static const int MAX_NUM_RESOURCE_TEXTURES = 16; size_t getMaxNumResourceTextures() const { return MAX_NUM_RESOURCE_TEXTURES; } @@ -122,6 +124,7 @@ public: virtual void do_setUniformBuffer(const Batch& batch, size_t paramOffset) final; // Resource Stage + virtual void do_setResourceBuffer(const Batch& batch, size_t paramOffset) final; virtual void do_setResourceTexture(const Batch& batch, size_t paramOffset) final; // Pipeline Stage @@ -357,13 +360,19 @@ protected: void releaseUniformBuffer(uint32_t slot); void resetUniformStage(); - + + // update resource cache and do the gl bind/unbind call with the current gpu::Buffer cached at slot s + // This is using different gl object depending on the gl version + virtual bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) = 0; + virtual void releaseResourceBuffer(uint32_t slot) = 0; + // update resource cache and do the gl unbind call with the current gpu::Texture cached at slot s void releaseResourceTexture(uint32_t slot); void resetResourceStage(); struct ResourceStageState { + std::array _buffers; std::array _textures; //Textures _textures { { MAX_NUM_RESOURCE_TEXTURES } }; int findEmptyTextureSlot() const; diff --git a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp index 1dad72dbc1..1d1f92b297 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLBackendPipeline.cpp @@ -191,11 +191,45 @@ void GLBackend::releaseResourceTexture(uint32_t slot) { } void GLBackend::resetResourceStage() { + for (uint32_t i = 0; i < _resource._buffers.size(); i++) { + releaseResourceBuffer(i); + } for (uint32_t i = 0; i < _resource._textures.size(); i++) { releaseResourceTexture(i); } } + +void GLBackend::do_setResourceBuffer(const Batch& batch, size_t paramOffset) { + GLuint slot = batch._params[paramOffset + 1]._uint; + if (slot >= (GLuint)MAX_NUM_RESOURCE_BUFFERS) { + // "GLBackend::do_setResourceBuffer: Trying to set a resource Buffer at slot #" + slot + " which doesn't exist. MaxNumResourceBuffers = " + getMaxNumResourceBuffers()); + return; + } + + auto resourceBuffer = batch._buffers.get(batch._params[paramOffset + 0]._uint); + + if (!resourceBuffer) { + releaseResourceBuffer(slot); + return; + } + // check cache before thinking + if (_resource._buffers[slot] == resourceBuffer) { + return; + } + + // One more True Buffer bound + _stats._RSNumResourceBufferBounded++; + + // If successful bind then cache it + if (bindResourceBuffer(slot, resourceBuffer)) { + _resource._buffers[slot] = resourceBuffer; + } else { // else clear slot and cache + releaseResourceBuffer(slot); + return; + } +} + void GLBackend::do_setResourceTexture(const Batch& batch, size_t paramOffset) { GLuint slot = batch._params[paramOffset + 1]._uint; if (slot >= (GLuint) MAX_NUM_RESOURCE_TEXTURES) { diff --git a/libraries/gpu-gl/src/gpu/gl/GLShader.cpp b/libraries/gpu-gl/src/gpu/gl/GLShader.cpp index 5020ad38a4..1eaecb5570 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLShader.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLShader.cpp @@ -32,7 +32,8 @@ GLShader::~GLShader() { // GLSL version static const std::string glslVersion { - "#version 410 core" +// "#version 410 core" + "#version 450 core" }; // Shader domain @@ -185,7 +186,8 @@ bool GLShader::makeProgram(GLBackend& backend, Shader& shader, const Shader::Bin Shader::SlotSet uniforms; Shader::SlotSet textures; Shader::SlotSet samplers; - makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers); + Shader::SlotSet resourceBuffers; + makeUniformSlots(shaderObject.glprogram, slotBindings, uniforms, textures, samplers, resourceBuffers); Shader::SlotSet inputs; makeInputSlots(shaderObject.glprogram, slotBindings, inputs); diff --git a/libraries/gpu-gl/src/gpu/gl/GLShared.cpp b/libraries/gpu-gl/src/gpu/gl/GLShared.cpp index 7acdc0ec79..8cc22126db 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLShared.cpp +++ b/libraries/gpu-gl/src/gpu/gl/GLShared.cpp @@ -510,7 +510,7 @@ ElementResource getFormatFromGLUniform(GLenum gltype) { }; int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, - Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers) { + Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers, Shader::SlotSet& resourceBuffers) { GLint uniformsCount = 0; glGetProgramiv(glprogram, GL_ACTIVE_UNIFORMS, &uniformsCount); @@ -565,6 +565,24 @@ int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, } } + GLint ssboCount = 0; + glGetProgramInterfaceiv(glprogram, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &ssboCount); + if (ssboCount > 0) { + GLint maxNameLength = 0; + glGetProgramInterfaceiv(glprogram, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &maxNameLength); + std::vector nameBytes(maxNameLength); + + for (GLint b = 0; b < ssboCount; b++) { + GLint length; + glGetProgramResourceName(glprogram, GL_SHADER_STORAGE_BLOCK, b, maxNameLength, &length, nameBytes.data()); + + std::string bufferName(nameBytes.data()); + qCWarning(gpugllogging) << "GLShader::makeBindings - " << bufferName.c_str(); + + + } + } + return uniformsCount; } diff --git a/libraries/gpu-gl/src/gpu/gl/GLShared.h b/libraries/gpu-gl/src/gpu/gl/GLShared.h index b0eec23448..f453329493 100644 --- a/libraries/gpu-gl/src/gpu/gl/GLShared.h +++ b/libraries/gpu-gl/src/gpu/gl/GLShared.h @@ -42,7 +42,7 @@ struct ShaderObject { }; int makeUniformSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, - Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers); + Shader::SlotSet& uniforms, Shader::SlotSet& textures, Shader::SlotSet& samplers, Shader::SlotSet& resourceBuffers); int makeUniformBlockSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& buffers); int makeInputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& inputs); int makeOutputSlots(GLuint glprogram, const Shader::BindingSet& slotBindings, Shader::SlotSet& outputs); diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h index 93d65b74dd..a0efe4ea55 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h +++ b/libraries/gpu-gl/src/gpu/gl41/GL41Backend.h @@ -123,6 +123,10 @@ protected: void initTransform() override; void updateTransform(const Batch& batch) override; + // Resource Stage + bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) override; + void releaseResourceBuffer(uint32_t slot) override; + // Output stage void do_blit(const Batch& batch, size_t paramOffset) override; }; diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index b739bfaf89..daa1274c6b 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -66,3 +66,26 @@ GLuint GL41Backend::getBufferID(const Buffer& buffer) { GLBuffer* GL41Backend::syncGPUObject(const Buffer& buffer) { return GL41Buffer::sync(*this, buffer); } + +bool GL41Backend::bindResourceBuffer(uint32_t slot, BufferPointer& buffer) { + GLBuffer* object = syncGPUObject((*buffer)); + if (object) { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, object->_id); + + (void)CHECK_GL_ERROR(); + + _resource._buffers[slot] = buffer; + + return true; + } + + return false; +} + +void GL41Backend::releaseResourceBuffer(uint32_t slot) { + auto& buf = _resource._buffers[slot]; + if (buf) { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, 0); + buf.reset(); + } +} diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h index ca8028aff6..8ce567e08a 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h +++ b/libraries/gpu-gl/src/gpu/gl45/GL45Backend.h @@ -277,6 +277,10 @@ protected: void initTransform() override; void updateTransform(const Batch& batch) override; + // Resource Stage + bool bindResourceBuffer(uint32_t slot, BufferPointer& buffer) override; + void releaseResourceBuffer(uint32_t slot) override; + // Output stage void do_blit(const Batch& batch, size_t paramOffset) override; diff --git a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp index cd69c03691..b4a6410612 100644 --- a/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl45/GL45BackendBuffer.cpp @@ -54,3 +54,29 @@ GLuint GL45Backend::getBufferID(const Buffer& buffer) { GLBuffer* GL45Backend::syncGPUObject(const Buffer& buffer) { return GL45Buffer::sync(*this, buffer); } + + +bool GL45Backend::bindResourceBuffer(uint32_t slot, BufferPointer& buffer) { + GLBuffer* object = syncGPUObject((*buffer)); + if (object) { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, object->_id); + + (void)CHECK_GL_ERROR(); + + _resource._buffers[slot] = buffer; + + return true; + } + + return false; +} + +void GL45Backend::releaseResourceBuffer(uint32_t slot) { + auto& buf = _resource._buffers[slot]; + if (buf) { + glBindBufferBase(GL_SHADER_STORAGE_BUFFER, slot, 0); + buf.reset(); + } +} + + diff --git a/libraries/gpu/src/gpu/Batch.cpp b/libraries/gpu/src/gpu/Batch.cpp index f822da129b..0d5036c202 100644 --- a/libraries/gpu/src/gpu/Batch.cpp +++ b/libraries/gpu/src/gpu/Batch.cpp @@ -292,8 +292,16 @@ void Batch::setUniformBuffer(uint32 slot, const BufferView& view) { setUniformBuffer(slot, view._buffer, view._offset, view._size); } +void Batch::setResourceBuffer(uint32 slot, const BufferPointer& buffer) { + ADD_COMMAND(setResourceBuffer); + + _params.emplace_back(_buffers.cache(buffer)); + _params.emplace_back(slot); +} + void Batch::setResourceTexture(uint32 slot, const TexturePointer& texture) { ADD_COMMAND(setResourceTexture); + _params.emplace_back(_textures.cache(texture)); _params.emplace_back(slot); } diff --git a/libraries/gpu/src/gpu/Batch.h b/libraries/gpu/src/gpu/Batch.h index 598680a745..b4af57d687 100644 --- a/libraries/gpu/src/gpu/Batch.h +++ b/libraries/gpu/src/gpu/Batch.h @@ -189,9 +189,12 @@ public: void setUniformBuffer(uint32 slot, const BufferPointer& buffer, Offset offset, Offset size); void setUniformBuffer(uint32 slot, const BufferView& view); // not a command, just a shortcut from a BufferView - void setResourceTexture(uint32 slot, const TexturePointer& view); + void setResourceBuffer(uint32 slot, const BufferPointer& buffer); + + void setResourceTexture(uint32 slot, const TexturePointer& texture); void setResourceTexture(uint32 slot, const TextureView& view); // not a command, just a shortcut from a TextureView + // Ouput Stage void setFramebuffer(const FramebufferPointer& framebuffer); @@ -290,6 +293,7 @@ public: COMMAND_setStateScissorRect, COMMAND_setUniformBuffer, + COMMAND_setResourceBuffer, COMMAND_setResourceTexture, COMMAND_setFramebuffer, diff --git a/libraries/gpu/src/gpu/Context.h b/libraries/gpu/src/gpu/Context.h index 102c754cd7..b56255f862 100644 --- a/libraries/gpu/src/gpu/Context.h +++ b/libraries/gpu/src/gpu/Context.h @@ -34,6 +34,7 @@ public: int _ISNumInputBufferChanges = 0; int _ISNumIndexBufferChanges = 0; + int _RSNumResourceBufferBounded = 0; int _RSNumTextureBounded = 0; int _RSAmountTextureMemoryBounded = 0; diff --git a/libraries/render/src/render/drawItemBounds.slv b/libraries/render/src/render/drawItemBounds.slv index cf1eab7163..d09a957ddc 100644 --- a/libraries/render/src/render/drawItemBounds.slv +++ b/libraries/render/src/render/drawItemBounds.slv @@ -22,6 +22,11 @@ uniform vec3 inBoundPos; uniform vec3 inBoundDim; uniform ivec4 inCellLocation; +layout(std140) buffer ssbo0Buffer { + vec4 perBoundData[]; +}; + + out vec4 varColor; out vec2 varTexcoord; @@ -52,6 +57,8 @@ void main(void) { ); vec4 cubeVec = UNIT_BOX[UNIT_BOX_LINE_INDICES[gl_VertexID]]; + vec4 offset = perBoundData[gl_VertexID]; + vec4 pos = vec4(inBoundPos + inBoundDim * cubeVec.xyz, 1.0); // standard transform @@ -61,7 +68,7 @@ void main(void) { bool subcell = bool((inCellLocation.z)); float cellDepth = float(inCellLocation.w); - varColor = vec4(colorWheel(fract(cellDepth / 5.0)), 1.0 - float(subcell)); + varColor = vec4(colorWheel(fract(cellDepth / 5.0)), 1.0 - float(subcell)) + offset; varTexcoord = vec2(cubeVec.w, length(inBoundDim)); } \ No newline at end of file