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
This commit is contained in:
Tim Sylvester
2023-04-18 12:31:41 -07:00
committed by Bart Louwers
parent e2bc75289c
commit aceb0394ba
13 changed files with 111 additions and 78 deletions

View File

@@ -47,6 +47,7 @@ public:
virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0; virtual void setVertexAttributes(gfx::VertexAttributeArray&&) = 0;
virtual std::vector<std::uint16_t>& getIndexData() const = 0; virtual std::vector<std::uint16_t>& getIndexData() const = 0;
virtual std::vector<std::uint8_t>& getVertexData() const = 0;
/// Attach a tweaker to be run on this drawable for each frame /// Attach a tweaker to be run on this drawable for each frame
void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); } void addTweaker(DrawableTweakerPtr tweaker) { tweakers.emplace_back(std::move(tweaker)); }

View File

@@ -27,7 +27,10 @@ public:
void draw(const PaintParameters &) const override; void draw(const PaintParameters &) const override;
void setVertData(std::vector<std::uint8_t> vertexData_, std::vector<uint16_t> indexes_); void setVertexData(std::vector<std::uint8_t> vertexData, std::vector<uint16_t> indexes,
std::size_t indexOffset, std::size_t indexLength);
std::vector<std::uint16_t>& getIndexData() const override;
std::vector<std::uint8_t>& getVertexData() const override;
const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; } const gfx::VertexAttributeArray& getVertexAttributes() const override { return vertexAttributes; }
void setVertexAttributes(const gfx::VertexAttributeArray& value) override { void setVertexAttributes(const gfx::VertexAttributeArray& value) override {
@@ -38,9 +41,8 @@ public:
} }
const gl::VertexArray& getVertexArray() const; const gl::VertexArray& getVertexArray() const;
void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&, gfx::IndexBuffer&&); void setVertexArray(gl::VertexArray&&, gfx::UniqueVertexBufferResource&&,
gfx::IndexBuffer&&, std::size_t attrOffset);
std::vector<std::uint16_t>& getIndexData() const override;
protected: protected:
class Impl; class Impl;

View File

@@ -89,14 +89,8 @@ public:
public: public:
const gfx::ShaderProgramBasePtr& getCurrentShader() const { return currentShader; }
virtual void setCurrentShader(ShaderProgramBasePtr) = 0;
/// Activate the shader, vertex attributes, etc., specified by the drawable /// Activate the shader, vertex attributes, etc., specified by the drawable
virtual void setupDraw(const gfx::Drawable&) = 0; virtual void setupDraw(const gfx::Drawable&) = 0;
protected:
ShaderProgramBasePtr currentShader;
}; };
} // namespace gfx } // namespace gfx

View File

@@ -59,10 +59,13 @@ public:
updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes()); updateIndexBufferResource(buffer.getResource(), v.data(), v.bytes());
} }
virtual std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>> virtual gfx::AttributeBindingArray buildAttributeBindings(
buildAttributeBindings(const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides, const gfx::VertexAttributeArray& overrides,
gfx::BufferUsageType) = 0; const std::vector<uint8_t>& vertexData,
gfx::BufferUsageType,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) = 0;
protected: protected:
virtual std::unique_ptr<VertexBufferResource> createVertexBufferResource(const void* data, virtual std::unique_ptr<VertexBufferResource> createVertexBufferResource(const void* data,

View File

@@ -448,12 +448,23 @@ void Context::setDirtyState() {
} }
void Context::setupDraw(const gfx::Drawable& drawable) { void Context::setupDraw(const gfx::Drawable& drawable) {
if (auto &shader = drawable.getShader()) { if (const auto &shader = drawable.getShader()) {
if (shader != currentShader) { const auto& shaderGL = static_cast<const ShaderProgramGL&>(*shader);
setCurrentShader(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<const DrawableGL&>(drawable); auto& drawableGL = static_cast<const DrawableGL&>(drawable);
auto& vao = drawableGL.getVertexArray(); auto& vao = drawableGL.getVertexArray();
if (vao.isValid()) { 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<ShaderProgramGL&>(*currentShader);
this->program = shaderGL.getGLProgramID();
} else {
this->program = value::Program::Default;
}
}
void Context::clear(std::optional<mbgl::Color> color, void Context::clear(std::optional<mbgl::Color> color,
std::optional<float> depth, std::optional<float> depth,
std::optional<int32_t> stencil) { std::optional<int32_t> stencil) {

View File

@@ -106,8 +106,6 @@ public:
void setupDraw(const gfx::Drawable&) override; void setupDraw(const gfx::Drawable&) override;
void setCurrentShader(gfx::ShaderProgramBasePtr) override;
private: private:
RendererBackend& backend; RendererBackend& backend;
bool cleanupOnDestruction = true; bool cleanupOnDestruction = true;

View File

@@ -16,25 +16,35 @@ void DrawableGL::draw(const PaintParameters &parameters) const
impl->draw(parameters); impl->draw(parameters);
} }
void DrawableGL::setVertData(std::vector<std::uint8_t> vertexData_, void DrawableGL::setVertexData(std::vector<std::uint8_t> vertexData,
std::vector<std::uint16_t> indexes_) { std::vector<std::uint16_t> indexes,
impl->vertData = std::move(vertexData_); const std::size_t indexOffset,
impl->indexes = std::move(indexes_); const std::size_t indexLength) {
impl->vertData = std::move(vertexData);
impl->indexes = std::move(indexes);
impl->indexOffset = indexOffset;
impl->indexLength = indexLength;
} }
std::vector<std::uint16_t>& DrawableGL::getIndexData() const { std::vector<std::uint16_t>& DrawableGL::getIndexData() const {
return impl->indexes; return impl->indexes;
} }
std::vector<std::uint8_t>& DrawableGL::getVertexData() const {
return impl->vertData;
}
const gl::VertexArray& DrawableGL::getVertexArray() const { const gl::VertexArray& DrawableGL::getVertexArray() const {
return impl->vertexArray; return impl->vertexArray;
} }
void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_, void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_,
gfx::UniqueVertexBufferResource&& attributeBuffer_, gfx::UniqueVertexBufferResource&& attributeBuffer_,
gfx::IndexBuffer&& indexBuffer_) { gfx::IndexBuffer&& indexBuffer_,
std::size_t attrOffset) {
impl->vertexArray = std::move(vertexArray_); impl->vertexArray = std::move(vertexArray_);
impl->attributeBuffer = std::move(attributeBuffer_); impl->attributeBuffer = std::move(attributeBuffer_);
impl->attributeOffset = attrOffset;
impl->indexBuffer = std::move(indexBuffer_); impl->indexBuffer = std::move(indexBuffer_);
} }

View File

@@ -12,10 +12,8 @@ gfx::DrawablePtr DrawableGLBuilder::createDrawable() const {
void DrawableGLBuilder::init() { void DrawableGLBuilder::init() {
const auto n = impl->vertices.elements(); const auto n = impl->vertices.elements();
assert(n <= impl->indexes.elements());
assert(n == impl->colors.size()); assert(n == impl->colors.size());
// temp
const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float); const auto vertSize = sizeof(Impl::VT) + 4 * sizeof(float);
std::vector<uint8_t> rawVert(n * vertSize); std::vector<uint8_t> rawVert(n * vertSize);
@@ -28,7 +26,10 @@ void DrawableGLBuilder::init() {
*(float*)p = impl->colors[i].a; p += sizeof(float); *(float*)p = impl->colors[i].a; p += sizeof(float);
} }
((DrawableGL*)currentDrawable.get())->setVertData(std::move(rawVert), impl->indexes.vector()); auto& drawableGL = static_cast<DrawableGL&>(*currentDrawable);
constexpr auto indexOffset = 0;
const auto indexCount = impl->indexes.elements();
drawableGL.setVertexData(std::move(rawVert), impl->indexes.vector(), indexOffset, indexCount);
} }
} // namespace gl } // namespace gl

View File

@@ -9,6 +9,7 @@
#include <mbgl/gl/program.hpp> #include <mbgl/gl/program.hpp>
#include <mbgl/gl/vertex_array.hpp> #include <mbgl/gl/vertex_array.hpp>
#include <mbgl/platform/gl_functions.hpp> #include <mbgl/platform/gl_functions.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
#include <mbgl/util/mat4.hpp> #include <mbgl/util/mat4.hpp>
#include <cstdint> #include <cstdint>
@@ -27,13 +28,10 @@ public:
} }
~Impl() = default; ~Impl() = default;
void draw(const PaintParameters& /*parameters*/) const { void draw(const PaintParameters& parameters) const {
MBGL_CHECK_ERROR(glDrawElements(
Enum<gfx::DrawModeType>::to(type), auto& glContext = static_cast<gl::Context&>(parameters.context);
static_cast<GLsizei>(indexLength), glContext.draw(gfx::Triangles(), indexOffset, indexLength);
GL_UNSIGNED_SHORT,
reinterpret_cast<GLvoid*>(sizeof(uint16_t) * indexOffset)));
} }
const gfx::DrawModeType type = gfx::DrawModeType::Triangles; const gfx::DrawModeType type = gfx::DrawModeType::Triangles;
@@ -50,6 +48,7 @@ public:
std::size_t indexOffset = 0; std::size_t indexOffset = 0;
std::size_t indexLength = 0; std::size_t indexLength = 0;
std::size_t attributeOffset = 0;
mat4 matrix; mat4 matrix;
gfx::DepthMode depthMode = gfx::DepthMode::disabled(); gfx::DepthMode depthMode = gfx::DepthMode::disabled();
gfx::StencilMode stencilMode; gfx::StencilMode stencilMode;

View File

@@ -84,8 +84,14 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
in mat2 f; in mat2 f;
in mat4 g; in mat4 g;
void main() { 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); 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"( constexpr auto frag = R"(
#version 300 es #version 300 es
@@ -93,7 +99,7 @@ void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
in vec4 pos; in vec4 pos;
out vec4 color; out vec4 color;
void main() { void main() {
color = vec4(1.0,0.0,0.0,1.0); color = vec4(0.5,0.0,0.0,0.5);
})"; })";
try { try {

View File

@@ -122,18 +122,30 @@ void UploadPass::updateTextureResourceSub(gfx::TextureResource& resource,
data)); data));
} }
template <typename T>
static void pad(std::vector<T>& vector, int size) {
vector.insert(vector.end(), size - vector.size() % size, 0);
}
std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>> gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
UploadPass::buildAttributeBindings(const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides, const gfx::VertexAttributeArray& overrides,
const gfx::BufferUsageType usage) { const std::vector<uint8_t>& vertexData,
const gfx::BufferUsageType usage,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) {
AttributeBindingArray bindings; AttributeBindingArray bindings;
bindings.reserve(defaults.size()); bindings.reserve(defaults.size());
std::vector<std::uint8_t> allData; std::vector<std::uint8_t> allData;
constexpr auto ExpectedSize = 32; 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*/, defaults.resolve(overrides, [&](const std::string& /*name*/,
const gfx::VertexAttribute& defaultAttr, const gfx::VertexAttribute& defaultAttr,
@@ -143,8 +155,7 @@ std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>
const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr); const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr);
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr); const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);
// Pad to 16 bytes pad(allData, 16);
allData.insert(allData.end(), 16 - allData.size() % 16, 0);
const auto offset = static_cast<uint8_t>(allData.size()); const auto offset = static_cast<uint8_t>(allData.size());
@@ -164,10 +175,8 @@ std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>
// Assign to each element // Assign to each element
std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); }); std::for_each(bindings.begin(), bindings.end(), [&](auto& b){ b->vertexBufferResource = vertBuf.get(); });
gfx::AttributeBindingArray& a = bindings; outBuffer = std::move(vertBuf);
std::unique_ptr<gfx::VertexBufferResource>& b = vertBuf; return bindings;
return std::make_pair(std::move(a), std::move(b));
//return std::make_pair(bindings, vertBuf);
} }
void UploadPass::pushDebugGroup(const char* name) { void UploadPass::pushDebugGroup(const char* name) {

View File

@@ -34,10 +34,13 @@ public:
gfx::BufferUsageType) override; gfx::BufferUsageType) override;
void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override; void updateIndexBufferResource(gfx::IndexBufferResource&, const void* data, std::size_t size) override;
std::pair<gfx::AttributeBindingArray, std::unique_ptr<gfx::VertexBufferResource>> gfx::AttributeBindingArray buildAttributeBindings(
buildAttributeBindings(const gfx::VertexAttributeArray& defaults, const gfx::VertexAttributeArray& defaults,
const gfx::VertexAttributeArray& overrides, const gfx::VertexAttributeArray& overrides,
gfx::BufferUsageType) override; const std::vector<uint8_t>& vertexData,
gfx::BufferUsageType,
/*out*/ std::unique_ptr<gfx::VertexBufferResource>& outBuffer,
/*out*/ std::size_t& outAttrOffset) override;
public: public:
std::unique_ptr<gfx::TextureResource> createTextureResource(Size, std::unique_ptr<gfx::TextureResource> createTextureResource(Size,

View File

@@ -130,15 +130,20 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
// Apply drawable values to shader defaults // Apply drawable values to shader defaults
const auto& defaults = shader->getVertexAttributes(); const auto& defaults = shader->getVertexAttributes();
const auto& overrides = drawable.getVertexAttributes(); const auto& overrides = drawable.getVertexAttributes();
auto bindingsAndBuffer = uploadPass->buildAttributeBindings(defaults, overrides, usage); const auto& vertexData = drawableGL.getVertexData();
std::unique_ptr<gfx::VertexBufferResource> vertexBuffer;
std::size_t attrOffset = 0;
auto bindings = uploadPass->buildAttributeBindings(defaults, overrides, vertexData, usage,
vertexBuffer, attrOffset);
auto& glContext = static_cast<gl::Context&>(context); auto& glContext = static_cast<gl::Context&>(context);
auto vertexArray = glContext.createVertexArray(); auto vertexArray = glContext.createVertexArray();
vertexArray.bind(glContext, indexBuffer, bindingsAndBuffer.first); vertexArray.bind(glContext, indexBuffer, bindings);
drawableGL.setVertexArray(std::move(vertexArray), drawableGL.setVertexArray(std::move(vertexArray),
std::move(bindingsAndBuffer.second), std::move(vertexBuffer),
std::move(indexBuffer)); std::move(indexBuffer),
attrOffset);
} }
} }
} }
@@ -193,21 +198,11 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
// Run changes // Run changes
orchestrator.processChanges(); orchestrator.processChanges();
// Draw Drawables
{
for (const auto &pair : orchestrator.getDrawables()) {
const auto& drawable = *pair.second;
context.setupDraw(drawable);
drawable.draw(parameters);
}
}
// - OPAQUE PASS ------------------------------------------------------------------------------- // - OPAQUE PASS -------------------------------------------------------------------------------
// Render everything top-to-bottom by using reverse iterators. Render opaque objects first. // Render everything top-to-bottom by using reverse iterators. Render opaque objects first.
{ {
parameters.pass = RenderPass::Opaque; parameters.pass = RenderPass::Opaque;
const auto debugGroup(parameters.renderPass->createDebugGroup("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. // Renders debug overlays.
{ {
const auto debugGroup(parameters.renderPass->createDebugGroup("debug")); const auto debugGroup(parameters.renderPass->createDebugGroup("debug"));