From aceb0394bada8dcd647e9936a05b26320898e78d Mon Sep 17 00:00:00 2001 From: Tim Sylvester Date: Tue, 18 Apr 2023 12:31:41 -0700 Subject: [PATCH] Topic/drawable 2 (#1032) More vertex attribute work Move drawables above existing layer rendering. Use context for the actual draw call. Fake the vertexes in the shader to get something actually showing up. Simplify shader state management --- include/mbgl/gfx/drawable.hpp | 1 + include/mbgl/gl/drawable_gl.hpp | 10 ++++--- src/mbgl/gfx/context.hpp | 6 ----- src/mbgl/gfx/upload_pass.hpp | 11 +++++--- src/mbgl/gl/context.cpp | 26 +++++++++--------- src/mbgl/gl/context.hpp | 2 -- src/mbgl/gl/drawable_gl.cpp | 20 ++++++++++---- src/mbgl/gl/drawable_gl_builder.cpp | 7 ++--- src/mbgl/gl/drawable_gl_impl.hpp | 13 +++++---- src/mbgl/gl/renderer_backend.cpp | 10 +++++-- src/mbgl/gl/upload_pass.cpp | 31 ++++++++++++++-------- src/mbgl/gl/upload_pass.hpp | 11 +++++--- src/mbgl/renderer/renderer_impl.cpp | 41 ++++++++++++++++------------- 13 files changed, 111 insertions(+), 78 deletions(-) diff --git a/include/mbgl/gfx/drawable.hpp b/include/mbgl/gfx/drawable.hpp index 00e7d1ed3..91f7d6c7e 100644 --- a/include/mbgl/gfx/drawable.hpp +++ b/include/mbgl/gfx/drawable.hpp @@ -47,6 +47,7 @@ public: virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0; virtual std::vector& getIndexData() const = 0; + virtual std::vector& getVertexData() const = 0; /// Attach a tweaker to be run on this drawable for each frame void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); } diff --git a/include/mbgl/gl/drawable_gl.hpp b/include/mbgl/gl/drawable_gl.hpp index 68e11d437..0898b88fc 100644 --- a/include/mbgl/gl/drawable_gl.hpp +++ b/include/mbgl/gl/drawable_gl.hpp @@ -27,7 +27,10 @@ public: void draw(const PaintParameters &) const override; - void setVertData(std::vector vertexData_, std::vector indexes_); + void setVertexData(std::vector vertexData, std::vector indexes, + std::size_t indexOffset, std::size_t indexLength); + std::vector& getIndexData() const override; + std::vector& getVertexData() const override; const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; } void setVertexAttributes(const gfx::VertexAttributeArray& value) override { @@ -38,9 +41,8 @@ public: } const gl::VertexArray& getVertexArray() const; - void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, gfx::IndexBuffer&&); - - std::vector& getIndexData() const override; + void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, + gfx::IndexBuffer&&, std::size_t attrOffset); protected: class Impl; diff --git a/src/mbgl/gfx/context.hpp b/src/mbgl/gfx/context.hpp index d8dfa8320..29ed3f80a 100644 --- a/src/mbgl/gfx/context.hpp +++ b/src/mbgl/gfx/context.hpp @@ -89,14 +89,8 @@ public: public: - const gfx::ShaderProgramBasePtr& getCurrentShader() const { return currentShader; } - virtual void setCurrentShader(ShaderProgramBasePtr) = 0; - /// Activate the shader, vertex attributes, etc., specified by the drawable virtual void setupDraw(const gfx::Drawable&) = 0; - -protected: - ShaderProgramBasePtr currentShader; }; } // namespace gfx diff --git a/src/mbgl/gfx/upload_pass.hpp b/src/mbgl/gfx/upload_pass.hpp index d48c37be7..302bc462a 100644 --- a/src/mbgl/gfx/upload_pass.hpp +++ b/src/mbgl/gfx/upload_pass.hpp @@ -59,10 +59,13 @@ public: updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes()); } - virtual std::pair> - buildAttributeBindings(const gfx::VertexAttributeArray& defaults, - const gfx::VertexAttributeArray& overrides, - gfx::BufferUsageType) = 0; + virtual gfx::AttributeBindingArray buildAttributeBindings( + const gfx::VertexAttributeArray& defaults, + const gfx::VertexAttributeArray& overrides, + const std::vector& vertexData, + gfx::BufferUsageType, + /*out*/ std::unique_ptr& outBuffer, + /*out*/ std::size_t& outAttrOffset) = 0; protected: virtual std::unique_ptr createVertexBufferResource(const void* data, diff --git a/src/mbgl/gl/context.cpp b/src/mbgl/gl/context.cpp index e57e59578..0691cfe3e 100644 --- a/src/mbgl/gl/context.cpp +++ b/src/mbgl/gl/context.cpp @@ -448,12 +448,23 @@ void Context::setDirtyState() { } void Context::setupDraw(const gfx::Drawable& drawable) { - if (auto &shader = drawable.getShader()) { - if (shader != currentShader) { - setCurrentShader(shader); + if (const auto &shader = drawable.getShader()) { + const auto& shaderGL = static_cast(*shader); + if (shaderGL.getGLProgramID() != program.getCurrentValue()) { + program = shaderGL.getGLProgramID(); } + } else if (program != value::Program::Default) { + program = value::Program::Default; } + // setDepthMode(depthMode); + // setStencilMode(stencilMode); + // setColorMode(colorMode); + // setCullFaceMode(cullFaceMode); + + // uniformStates.bind(uniformValues); + // textureStates.bind(context, textureBindings); + auto& drawableGL = static_cast(drawable); auto& vao = drawableGL.getVertexArray(); if (vao.isValid()) { @@ -463,15 +474,6 @@ void Context::setupDraw(const gfx::Drawable& drawable) { } } -void Context::setCurrentShader(gfx::ShaderProgramBasePtr value) { - if ((currentShader = std::move(value))) { - auto& shaderGL = static_cast(*currentShader); - this->program = shaderGL.getGLProgramID(); - } else { - this->program = value::Program::Default; - } -} - void Context::clear(std::optional color, std::optional depth, std::optional stencil) { diff --git a/src/mbgl/gl/context.hpp b/src/mbgl/gl/context.hpp index 1819492b7..1b7fc1f3d 100644 --- a/src/mbgl/gl/context.hpp +++ b/src/mbgl/gl/context.hpp @@ -106,8 +106,6 @@ public: void setupDraw(const gfx::Drawable&) override; - void setCurrentShader(gfx::ShaderProgramBasePtr) override; - private: RendererBackend& backend; bool cleanupOnDestruction = true; diff --git a/src/mbgl/gl/drawable_gl.cpp b/src/mbgl/gl/drawable_gl.cpp index 3e76e22c9..415da321e 100644 --- a/src/mbgl/gl/drawable_gl.cpp +++ b/src/mbgl/gl/drawable_gl.cpp @@ -16,25 +16,35 @@ void DrawableGL::draw(const PaintParameters ¶meters) const impl->draw(parameters); } -void DrawableGL::setVertData(std::vector vertexData_, - std::vector indexes_) { - impl->vertData = std::move(vertexData_); - impl->indexes = std::move(indexes_); +void DrawableGL::setVertexData(std::vector vertexData, + std::vector indexes, + const std::size_t indexOffset, + const std::size_t indexLength) { + impl->vertData = std::move(vertexData); + impl->indexes = std::move(indexes); + impl->indexOffset = indexOffset; + impl->indexLength = indexLength; } std::vector& DrawableGL::getIndexData() const { return impl->indexes; } +std::vector& DrawableGL::getVertexData() const { + return impl->vertData; +} + const gl::VertexArray& DrawableGL::getVertexArray() const { return impl->vertexArray; } void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_, gfx::UniqueVertexBufferResource&& attributeBuffer_, - gfx::IndexBuffer&& indexBuffer_) { + gfx::IndexBuffer&& indexBuffer_, + std::size_t attrOffset) { impl->vertexArray = std::move(vertexArray_); impl->attributeBuffer = std::move(attributeBuffer_); + impl->attributeOffset = attrOffset; impl->indexBuffer = std::move(indexBuffer_); } diff --git a/src/mbgl/gl/drawable_gl_builder.cpp b/src/mbgl/gl/drawable_gl_builder.cpp index 1e344ffad..498d1f407 100644 --- a/src/mbgl/gl/drawable_gl_builder.cpp +++ b/src/mbgl/gl/drawable_gl_builder.cpp @@ -12,10 +12,8 @@ gfx::DrawablePtr DrawableGLBuilder::createDrawable() const { void DrawableGLBuilder::init() { const auto n = impl->vertices.elements(); - assert(n <= impl->indexes.elements()); assert(n == impl->colors.size()); - // temp const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float); std::vector rawVert(n * vertSize); @@ -28,7 +26,10 @@ void DrawableGLBuilder::init() { *(float*)p = impl->colors[i].a; p += sizeof(float); } - ((DrawableGL*)currentDrawable.get())->setVertData(std::move(rawVert), impl->indexes.vector()); + auto& drawableGL = static_cast(*currentDrawable); + constexpr auto indexOffset = 0; + const auto indexCount = impl->indexes.elements(); + drawableGL.setVertexData(std::move(rawVert), impl->indexes.vector(), indexOffset, indexCount); } } // namespace gl diff --git a/src/mbgl/gl/drawable_gl_impl.hpp b/src/mbgl/gl/drawable_gl_impl.hpp index 43d1890f3..4623c37d1 100644 --- a/src/mbgl/gl/drawable_gl_impl.hpp +++ b/src/mbgl/gl/drawable_gl_impl.hpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -27,13 +28,10 @@ public: } ~Impl() = default; - void draw(const PaintParameters& /*parameters*/) const { - MBGL_CHECK_ERROR(glDrawElements( - Enum::to(type), - static_cast(indexLength), - GL_UNSIGNED_SHORT, - reinterpret_cast(sizeof(uint16_t) * indexOffset))); - + void draw(const PaintParameters& parameters) const { + + auto& glContext = static_cast(parameters.context); + glContext.draw(gfx::Triangles(), indexOffset, indexLength); } const gfx::DrawModeType type = gfx::DrawModeType::Triangles; @@ -50,6 +48,7 @@ public: std::size_t indexOffset = 0; std::size_t indexLength = 0; + std::size_t attributeOffset = 0; mat4 matrix; gfx::DepthMode depthMode = gfx::DepthMode::disabled(); gfx::StencilMode stencilMode; diff --git a/src/mbgl/gl/renderer_backend.cpp b/src/mbgl/gl/renderer_backend.cpp index cee61b53a..0235458eb 100644 --- a/src/mbgl/gl/renderer_backend.cpp +++ b/src/mbgl/gl/renderer_backend.cpp @@ -84,8 +84,14 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) { in mat2 f; in mat4 g; void main() { - gl_Position = vec4(d, float(e), f[0][0], a)/1.0e12; + gl_Position = vec4(d, float(e), f[0][0], a)/1.0e12; // optimized away if unused gl_Position = vec4(pos, 1.0); + switch (gl_VertexID) { // fake it for now + case 0: gl_Position = vec4(-1.0, -1.0, 1.0, 1.0); break; + case 1: gl_Position = vec4( 1.0, -1.0, 1.0, 1.0); break; + case 2: gl_Position = vec4( 1.0, 1.0, 1.0, 1.0); break; + case 3: gl_Position = vec4(-1.0, 1.0, 1.0, 1.0); break; + } })"; constexpr auto frag = R"( #version 300 es @@ -93,7 +99,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) { in vec4 pos; out vec4 color; void main() { - color = vec4(1.0,0.0,0.0,1.0); + color = vec4(0.5,0.0,0.0,0.5); })"; try { diff --git a/src/mbgl/gl/upload_pass.cpp b/src/mbgl/gl/upload_pass.cpp index 9f6d9f876..1e375acbe 100644 --- a/src/mbgl/gl/upload_pass.cpp +++ b/src/mbgl/gl/upload_pass.cpp @@ -122,18 +122,30 @@ void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource, data)); } +template +static void pad(std::vector& vector, int size) { + vector.insert(vector.end(), size - vector.size() % size, 0); +} -std::pair> - UploadPass::buildAttributeBindings(const gfx::VertexAttributeArray& defaults, - const gfx::VertexAttributeArray& overrides, - const gfx::BufferUsageType usage) { +gfx::AttributeBindingArray UploadPass::buildAttributeBindings( + const gfx::VertexAttributeArray& defaults, + const gfx::VertexAttributeArray& overrides, + const std::vector& vertexData, + const gfx::BufferUsageType usage, + /*out*/ std::unique_ptr& outBuffer, + /*out*/ std::size_t& outAttrOffset) { AttributeBindingArray bindings; bindings.reserve(defaults.size()); std::vector allData; constexpr auto ExpectedSize = 32; - allData.reserve(defaults.size() * ExpectedSize); + allData.reserve(vertexData.size() + defaults.size() * ExpectedSize); + + allData.insert(allData.end(), vertexData.begin(), vertexData.end()); + + pad(allData, 16); + outAttrOffset = allData.size(); defaults.resolve(overrides, [&](const std::string& /*name*/, const gfx::VertexAttribute& defaultAttr, @@ -143,8 +155,7 @@ std::pair const auto& effectiveGL = static_cast(effectiveAttr); const auto& defaultGL = static_cast(defaultAttr); - // Pad to 16 bytes - allData.insert(allData.end(), 16 - allData.size() % 16, 0); + pad(allData, 16); const auto offset = static_cast(allData.size()); @@ -164,10 +175,8 @@ std::pair // Assign to each element std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); }); - gfx::AttributeBindingArray& a = bindings; - std::unique_ptr& b = vertBuf; - return std::make_pair(std::move(a), std::move(b)); - //return std::make_pair(bindings, vertBuf); + outBuffer = std::move(vertBuf); + return bindings; } void UploadPass::pushDebugGroup(const char* name) { diff --git a/src/mbgl/gl/upload_pass.hpp b/src/mbgl/gl/upload_pass.hpp index 0beb9a034..72b9b2a00 100644 --- a/src/mbgl/gl/upload_pass.hpp +++ b/src/mbgl/gl/upload_pass.hpp @@ -34,10 +34,13 @@ public: gfx::BufferUsageType) override; void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; - std::pair> - buildAttributeBindings(const gfx::VertexAttributeArray& defaults, - const gfx::VertexAttributeArray& overrides, - gfx::BufferUsageType) override; + gfx::AttributeBindingArray buildAttributeBindings( + const gfx::VertexAttributeArray& defaults, + const gfx::VertexAttributeArray& overrides, + const std::vector& vertexData, + gfx::BufferUsageType, + /*out*/ std::unique_ptr& outBuffer, + /*out*/ std::size_t& outAttrOffset) override; public: std::unique_ptr createTextureResource(Size, diff --git a/src/mbgl/renderer/renderer_impl.cpp b/src/mbgl/renderer/renderer_impl.cpp index 8348b6a4e..405557f5c 100644 --- a/src/mbgl/renderer/renderer_impl.cpp +++ b/src/mbgl/renderer/renderer_impl.cpp @@ -130,15 +130,20 @@ void Renderer::Impl::render(const RenderTree& renderTree) { // Apply drawable values to shader defaults const auto& defaults = shader->getVertexAttributes(); const auto& overrides = drawable.getVertexAttributes(); - auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage); + const auto& vertexData = drawableGL.getVertexData(); + std::unique_ptr vertexBuffer; + std::size_t attrOffset = 0; + auto bindings = uploadPass->buildAttributeBindings(defaults, overrides, vertexData, usage, + vertexBuffer, attrOffset); auto& glContext = static_cast(context); auto vertexArray = glContext.createVertexArray(); - vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first); - + vertexArray.bind(glContext, indexBuffer, bindings); + drawableGL.setVertexArray(std::move(vertexArray), - std::move(bindingsAndBuffer.second), - std::move(indexBuffer)); + std::move(vertexBuffer), + std::move(indexBuffer), + attrOffset); } } } @@ -193,21 +198,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) { // Run changes orchestrator.processChanges(); - - // Draw Drawables - { - for (const auto &pair : orchestrator.getDrawables()) { - const auto& drawable = *pair.second; - context.setupDraw(drawable); - - drawable.draw(parameters); - } - } - // - OPAQUE PASS ------------------------------------------------------------------------------- // Render everything top-to-bottom by using reverse iterators. Render opaque objects first. { + parameters.pass = RenderPass::Opaque; const auto debugGroup(parameters.renderPass->createDebugGroup("opaque")); @@ -239,8 +234,18 @@ void Renderer::Impl::render(const RenderTree& renderTree) { } } - // - DEBUG PASS - // -------------------------------------------------------------------------------- + // Draw Drawables + { + for (const auto &pair : orchestrator.getDrawables()) { + const auto& drawable = *pair.second; + + context.setupDraw(drawable); + + drawable.draw(parameters); + } + } + + // - DEBUG PASS -------------------------------------------------------------------------------- // Renders debug overlays. { const auto debugGroup(parameters.renderPass->createDebugGroup("debug"));