Uniform buffer objects (#1127)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
This commit is contained in:
Alex Cristici
2023-05-11 20:33:58 +03:00
committed by Bart Louwers
parent bbb8bf3c1e
commit d8ea91de98
34 changed files with 634 additions and 163 deletions

View File

@@ -6,6 +6,7 @@
#include <mbgl/gfx/program.hpp>
#include <mbgl/gfx/renderbuffer.hpp>
#include <mbgl/gfx/rendering_stats.hpp>
#include <mbgl/gfx/uniform_buffer.hpp>
#include <mbgl/gfx/texture.hpp>
#include <mbgl/gfx/types.hpp>
@@ -29,6 +30,7 @@ class ShaderRegistry;
using DrawablePtr = std::shared_ptr<Drawable>;
using UniqueDrawableBuilder = std::unique_ptr<DrawableBuilder>;
using DrawableTweakerPtr = std::shared_ptr<DrawableTweaker>;
using UniformBufferPtr = std::shared_ptr<UniformBuffer>;
using ShaderProgramBasePtr = std::shared_ptr<ShaderProgramBase>;
class Context {
@@ -106,6 +108,9 @@ public:
/// Create a new drawable tweaker
virtual DrawableTweakerPtr createDrawableTweaker() = 0;
/// Create a new uniform buffer
virtual UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) = 0;
/// Get the generic shader with the specified name
virtual gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) = 0;
};

View File

@@ -0,0 +1,43 @@
#include <mbgl/gfx/uniform_block.hpp>
namespace mbgl {
namespace gfx {
std::unique_ptr<UniformBlock> UniformBlockArray::nullref = nullptr;
UniformBlockArray::UniformBlockArray(int initCapacity)
: uniformBlockMap(initCapacity) {}
UniformBlockArray::UniformBlockArray(UniformBlockArray&& other)
: uniformBlockMap(std::move(other.uniformBlockMap)) {}
UniformBlockArray& UniformBlockArray::operator=(UniformBlockArray&& other) {
uniformBlockMap = std::move(other.uniformBlockMap);
return *this;
}
UniformBlockArray& UniformBlockArray::operator=(const UniformBlockArray& other) {
uniformBlockMap.clear();
for (const auto& kv : other.uniformBlockMap) {
add(kv.first, copy(*kv.second));
}
return *this;
}
const std::unique_ptr<UniformBlock>& UniformBlockArray::get(const std::string& name) const {
const auto result = uniformBlockMap.find(name);
return (result != uniformBlockMap.end()) ? result->second : nullref;
}
const std::unique_ptr<UniformBlock>& UniformBlockArray::add(std::string name, int index, std::size_t size) {
const auto result = uniformBlockMap.insert(std::make_pair(std::move(name), std::unique_ptr<UniformBlock>()));
if (result.second) {
result.first->second = create(index, size);
return result.first->second;
} else {
return nullref;
}
}
} // namespace gfx
} // namespace mbgl

View File

@@ -0,0 +1,40 @@
#include <mbgl/gfx/uniform_buffer.hpp>
namespace mbgl {
namespace gfx {
std::shared_ptr<UniformBuffer> UniformBufferArray::nullref = nullptr;
UniformBufferArray::UniformBufferArray(int initCapacity)
: uniformBufferMap(initCapacity) {}
UniformBufferArray::UniformBufferArray(UniformBufferArray&& other)
: uniformBufferMap(std::move(other.uniformBufferMap)) {}
UniformBufferArray& UniformBufferArray::operator=(UniformBufferArray&& other) {
uniformBufferMap = std::move(other.uniformBufferMap);
return *this;
}
UniformBufferArray& UniformBufferArray::operator=(const UniformBufferArray& other) {
uniformBufferMap.clear();
for (const auto& kv : other.uniformBufferMap) {
add(kv.first, copy(*kv.second));
}
return *this;
}
const std::shared_ptr<UniformBuffer>& UniformBufferArray::get(const std::string& name) const {
const auto result = uniformBufferMap.find(name);
return (result != uniformBufferMap.end()) ? result->second : nullref;
}
const std::shared_ptr<UniformBuffer>& UniformBufferArray::addOrReplace(
std::string name, const std::shared_ptr<UniformBuffer>& uniformBuffer) {
const auto result = uniformBufferMap.insert(std::make_pair(std::move(name), std::shared_ptr<UniformBuffer>()));
result.first->second = std::move(uniformBuffer);
return result.first->second;
}
} // namespace gfx
} // namespace mbgl

View File

@@ -7,6 +7,8 @@
namespace mbgl {
namespace gfx {
std::unique_ptr<VertexAttribute> VertexAttributeArray::nullref = nullptr;
VertexAttributeArray::VertexAttributeArray(int initCapacity)
: attrs(initCapacity) {}
@@ -26,23 +28,23 @@ VertexAttributeArray& VertexAttributeArray::operator=(const VertexAttributeArray
return *this;
}
VertexAttribute* VertexAttributeArray::get(const std::string& name) const {
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::get(const std::string& name) const {
const auto result = attrs.find(name);
return (result != attrs.end()) ? result->second.get() : nullptr;
return (result != attrs.end()) ? result->second : nullref;
}
VertexAttribute* VertexAttributeArray::add(
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::add(
std::string name, int index, AttributeDataType dataType, int size, std::size_t count) {
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
if (result.second) {
result.first->second = create(index, dataType, size, count);
return result.first->second.get();
return result.first->second;
} else {
return nullptr;
return nullref;
}
}
VertexAttribute* VertexAttributeArray::getOrAdd(
const std::unique_ptr<VertexAttribute>& VertexAttributeArray::getOrAdd(
std::string name, int index, AttributeDataType dataType, int size, std::size_t count) {
// attrs.emplace_back(std::make_unique<VertexAttribute>(dataType, count));
const auto result = attrs.insert(std::make_pair(std::move(name), std::unique_ptr<VertexAttribute>()));
@@ -50,9 +52,9 @@ VertexAttribute* VertexAttributeArray::getOrAdd(
result.first->second = create(index, dataType, size, count);
} else if (result.first->second->getDataType() != dataType ||
result.first->second->getSize() != (std::size_t)size || result.first->second->getCount() != count) {
return nullptr;
return nullref;
}
return result.first->second.get();
return result.first->second;
}
std::size_t VertexAttributeArray::getTotalSize() const {

View File

@@ -10,6 +10,7 @@
#include <mbgl/gl/enum.hpp>
#include <mbgl/gl/renderer_backend.hpp>
#include <mbgl/gl/renderbuffer_resource.hpp>
#include <mbgl/gl/uniform_buffer_gl.hpp>
#include <mbgl/gl/texture_resource.hpp>
#include <mbgl/gl/texture.hpp>
#include <mbgl/gl/offscreen_texture.hpp>
@@ -497,6 +498,10 @@ gfx::DrawableTweakerPtr Context::createDrawableTweaker() {
return std::make_shared<gl::DrawableGLTweaker>();
}
gfx::UniformBufferPtr Context::createUniformBuffer(const void* data, std::size_t size) {
return std::make_shared<gl::UniformBufferGL>(data, size);
}
gfx::ShaderProgramBasePtr Context::getGenericShader(gfx::ShaderRegistry& shaders, const std::string& name) {
return shaders.get<gl::ShaderProgramGL>(name);
}

View File

@@ -106,6 +106,7 @@ public:
gfx::UniqueDrawableBuilder createDrawableBuilder(std::string name) override;
gfx::DrawableTweakerPtr createDrawableTweaker() override;
gfx::UniformBufferPtr createUniformBuffer(const void* data, std::size_t size) override;
gfx::ShaderProgramBasePtr getGenericShader(gfx::ShaderRegistry&, const std::string& name) override;

View File

@@ -2,6 +2,8 @@
#include <mbgl/gl/drawable_gl_impl.hpp>
#include <mbgl/gl/vertex_buffer_resource.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
namespace mbgl {
namespace gl {
@@ -16,7 +18,9 @@ DrawableGL::~DrawableGL() {
}
void DrawableGL::draw(const PaintParameters& parameters) const {
bindUniformBuffers();
impl->draw(parameters);
unbindUniformBuffers();
}
void DrawableGL::setIndexData(std::vector<std::uint16_t> indexes,
@@ -67,12 +71,42 @@ void DrawableGL::setVertexArray(gl::VertexArray&& vertexArray_,
impl->indexBuffer = std::move(indexBuffer_);
}
const gfx::UniformBufferArray& DrawableGL::getUniformBuffers() const {
return impl->uniformBuffers;
}
gfx::UniformBufferArray& DrawableGL::mutableUniformBuffers() {
return impl->uniformBuffers;
}
void DrawableGL::resetColor(const Color& newColor) {
if (auto* colorAttr = impl->vertexAttributes.get("a_color")) {
if (const auto& colorAttr = impl->vertexAttributes.get("a_color")) {
colorAttr->clear();
colorAttr->set(0, colorAttrValue(newColor));
}
}
void DrawableGL::bindUniformBuffers() const {
if (shader) {
const auto& shaderGL = static_cast<const ShaderProgramGL&>(*shader);
for (const auto& element : shaderGL.getUniformBlocks().getMap()) {
const auto& uniformBuffer = getUniformBuffers().get(element.first);
if (!uniformBuffer) {
continue;
}
element.second->bindBuffer(*uniformBuffer);
}
}
}
void DrawableGL::unbindUniformBuffers() const {
if (shader) {
const auto& shaderGL = static_cast<const ShaderProgramGL&>(*shader);
for (const auto& element : shaderGL.getUniformBlocks().getMap()) {
element.second->unbindBuffer();
}
}
}
} // namespace gl
} // namespace mbgl

View File

@@ -15,13 +15,13 @@ void DrawableGLBuilder::init() {
auto& drawableGL = static_cast<DrawableGL&>(*currentDrawable);
auto& attrs = drawableGL.mutableVertexAttributes();
if (auto posAttr = attrs.getOrAdd("a_pos")) {
if (const auto& posAttr = attrs.getOrAdd("a_pos")) {
std::size_t index = 0;
for (const auto& vert : impl->vertices.vector()) {
posAttr->set(index++, gfx::VertexAttribute::int2{vert.a1[0], vert.a1[1]});
}
}
if (auto colorAttr = attrs.getOrAdd("a_color")) {
if (const auto& colorAttr = attrs.getOrAdd("a_color")) {
// We should have either a single color or one per vertex. Otherwise,
// the color mode was probably changed after vertexes were added.
if (impl->colors.size() > 1 && impl->colors.size() != impl->vertices.elements()) {

View File

@@ -7,6 +7,7 @@
#include <mbgl/gl/defines.hpp>
#include <mbgl/gl/enum.hpp>
#include <mbgl/gl/program.hpp>
#include <mbgl/gl/uniform_buffer_gl.hpp>
#include <mbgl/gl/vertex_array.hpp>
#include <mbgl/platform/gl_functions.hpp>
#include <mbgl/renderer/paint_parameters.hpp>
@@ -47,6 +48,8 @@ public:
gfx::IndexBuffer indexBuffer = {0, nullptr};
gfx::UniqueVertexBufferResource attributeBuffer;
UniformBufferArrayGL uniformBuffers;
std::size_t indexOffset = 0;
std::size_t indexLength = 0;
std::size_t attributeOffset = 0;

View File

@@ -3,6 +3,7 @@
#include <mbgl/gfx/shader_registry.hpp>
#include <mbgl/gl/context.hpp>
#include <mbgl/gl/extension.hpp>
#include <mbgl/shaders/shader_manifest.hpp>
#include <mbgl/shaders/gl/shader_program_gl.hpp>
#include <mbgl/util/logging.hpp>
@@ -66,33 +67,14 @@ void RendererBackend::setScissorTest(bool enabled) {
RendererBackend::~RendererBackend() = default;
void RendererBackend::initShaders(gfx::ShaderRegistry& shaders) {
constexpr auto shaderName = "background_generic";
constexpr auto shaderName = "BackgroundProgramUBO";
gl::Context& glContext = static_cast<gl::Context&>(*context);
auto shader = shaders.get<gl::ShaderProgramGL>(shaderName);
if (!shader) {
constexpr auto vert = R"(#version 300 es
precision highp float;
uniform mat4 u_matrix;
layout (location = 0) in vec2 a_pos;
layout (location = 1) in vec4 a_color;
out vec4 v_color;
void main() {
v_color = a_color;
gl_Position = u_matrix * vec4(a_pos, 0, 1);
})";
constexpr auto frag = R"(#version 300 es
precision highp float;
in vec4 v_color;
out vec4 fragColor;
void main() {
fragColor = v_color;
})";
auto vert = shaders::ShaderSource<shaders::BuiltIn::BackgroundProgramUBO, gfx::Backend::Type::OpenGL>::vertex;
auto frag = shaders::ShaderSource<shaders::BuiltIn::BackgroundProgramUBO, gfx::Backend::Type::OpenGL>::fragment;
try {
// Compile
shader = gl::ShaderProgramGL::create(glContext, shaderName, vert, frag);

View File

@@ -0,0 +1,27 @@
#include <mbgl/gl/uniform_block_gl.hpp>
#include <mbgl/gl/uniform_buffer_gl.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/platform/gl_functions.hpp>
#include <cassert>
namespace mbgl {
namespace gl {
using namespace platform;
void UniformBlockGL::bindBuffer(const gfx::UniformBuffer& uniformBuffer) {
assert(size == uniformBuffer.getSize());
GLint binding = index;
const auto& uniformBufferGL = static_cast<const UniformBufferGL&>(uniformBuffer);
MBGL_CHECK_ERROR(glBindBufferBase(GL_UNIFORM_BUFFER, binding, uniformBufferGL.getID()));
}
void UniformBlockGL::unbindBuffer() {
GLint binding = index;
MBGL_CHECK_ERROR(glBindBufferBase(GL_UNIFORM_BUFFER, binding, 0));
}
} // namespace gl
} // namespace mbgl

View File

@@ -0,0 +1,20 @@
#include <mbgl/gl/uniform_buffer_gl.hpp>
#include <mbgl/gl/defines.hpp>
#include <mbgl/platform/gl_functions.hpp>
namespace mbgl {
namespace gl {
using namespace platform;
UniformBufferGL::UniformBufferGL(const void* data, std::size_t size_)
: UniformBuffer(size_) {
MBGL_CHECK_ERROR(glGenBuffers(1, &id));
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, id));
MBGL_CHECK_ERROR(glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW));
MBGL_CHECK_ERROR(glBindBuffer(GL_UNIFORM_BUFFER, 0));
}
} // namespace gl
} // namespace mbgl

View File

@@ -148,9 +148,7 @@ gfx::AttributeBindingArray UploadPass::buildAttributeBindings(
// For each attribute in the program, with the corresponding default and optional override...
defaults.resolve(overrides,
[&](const std::string& name,
const gfx::VertexAttribute& defaultAttr,
const gfx::VertexAttribute* overrideAttr) -> void {
[&](const std::string& name, const auto& defaultAttr, const auto& overrideAttr) -> void {
const auto& effectiveAttr = overrideAttr ? *overrideAttr : defaultAttr;
const auto& effectiveGL = static_cast<const gl::VertexAttributeGL&>(effectiveAttr);
const auto& defaultGL = static_cast<const gl::VertexAttributeGL&>(defaultAttr);

View File

@@ -169,57 +169,5 @@ const std::vector<std::uint8_t>& VertexAttributeGL::getRaw(platform::GLenum type
return rawData;
}
namespace {
template <typename T>
void applyUniform(GLint, const T&);
template <>
void applyUniform(GLint, const std::int32_t&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::int2&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::int3&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::int4&) {}
template <>
void applyUniform(GLint, const float&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::float2&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::float3&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::float4&) {}
template <>
void applyUniform(GLint, const gfx::VertexAttribute::matf3&) {}
template <>
void applyUniform(GLint location, const gfx::VertexAttribute::matf4& value) {
MBGL_CHECK_ERROR(glUniformMatrix4fv(location, 1, GL_FALSE, value.data()));
}
} // namespace
struct ApplyUniform {
GLint location;
template <typename T>
void operator()(const T& value) {
applyUniform(location, value);
}
};
void VertexAttributeArrayGL::applyUniforms(const gfx::ShaderProgramBase& shader) {
const auto& glShader = static_cast<const ShaderProgramGL&>(shader);
const auto program = glShader.getGLProgramID();
for (auto& kv : attrs) {
const auto& name = kv.first;
auto& uniform = kv.second;
if (uniform->getIndex() < 0) {
const auto index = MBGL_CHECK_ERROR(glGetUniformLocation(program, name.c_str()));
Log::Warning(Event::General, "Uniform '" + name + "' = " + std::to_string(index));
uniform->setIndex(index);
}
std::visit(ApplyUniform{uniform->getIndex()}, uniform->get(0));
}
}
} // namespace gl
} // namespace mbgl

View File

@@ -18,6 +18,7 @@
#include <mbgl/shaders/shader_program_base.hpp>
#include <mbgl/util/tile_cover.hpp>
#include <mbgl/map/transform_state.hpp>
#include <mbgl/util/convert.hpp>
#include <mbgl/util/logging.hpp>
#include <unordered_set>
@@ -60,6 +61,7 @@ void RenderBackgroundLayer::evaluate(const PropertyEvaluationParameters& paramet
properties->renderPasses = mbgl::underlying_type(passes);
evaluatedProperties = std::move(properties);
evaluatedPropertiesChange = true;
}
bool RenderBackgroundLayer::hasTransition() const {
@@ -194,7 +196,7 @@ void RenderBackgroundLayer::prepare(const LayerPrepareParameters& params) {
}
}
constexpr auto shaderName = "background_generic";
constexpr auto shaderName = "BackgroundProgramUBO";
void RenderBackgroundLayer::layerRemoved(UniqueChangeRequestVec& changes) {
// TODO: This isn't happening on style change, so old tile drawables are being left active
@@ -235,25 +237,23 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
// unevaluated.hasTransition();
// getCrossfade<BackgroundLayerProperties>(evaluatedProperties).t != 1;
std::optional<Color> color;
if (evaluated.get<BackgroundPattern>().from.empty()) {
const auto opacity = evaluated.get<style::BackgroundOpacity>();
if (opacity > 0.0f) {
color = evaluated.get<BackgroundColor>() * evaluated.get<BackgroundOpacity>();
}
}
// If the result is transparent or missing, just remove any existing drawables and stop
if (!color) {
if (!evaluated.get<BackgroundPattern>().from.empty() || evaluated.get<style::BackgroundOpacity>() <= 0.0f) {
removeDrawables<decltype(tileDrawables)::const_iterator>(
tileDrawables.cbegin(), tileDrawables.cend(), changes, [](auto& ii) { return ii->second->getId(); });
tileDrawables.clear();
return;
}
const bool colorChange = (color != lastColor);
if (evaluatedPropertiesChange) {
BackgroundLayerUBO backgroundLayerUBO;
backgroundLayerUBO.color = evaluated.get<BackgroundColor>();
backgroundLayerUBO.opacity = evaluated.get<BackgroundOpacity>();
uniformBuffer = context.createUniformBuffer(&backgroundLayerUBO, sizeof(backgroundLayerUBO));
evaluatedPropertiesChange = false;
}
const bool layerChange = (layerIndex != lastLayerIndex);
lastColor = color;
lastLayerIndex = layerIndex;
const auto zoom = state.getIntegerZoom();
@@ -283,10 +283,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
}
++iter;
// If the color evaluated to a new value, update all vertexes of the drawable to the new color
if (colorChange) {
drawable->resetColor(*color);
}
if (layerChange) {
drawable->setLayerIndex(layerIndex);
}
@@ -302,6 +298,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
if (!result.second) {
// Already present
// TODO: Update matrix here or in the tweaker?
result.first->second->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
continue;
}
@@ -311,7 +308,6 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
builder->setRenderPass(drawPasses);
builder->setShader(shader);
builder->addTweaker(context.createDrawableTweaker());
builder->setColor(*color);
builder->setColorMode(gfx::DrawableBuilder::ColorMode::PerDrawable);
builder->setDepthType(gfx::DepthMaskType::ReadWrite);
builder->setLayerIndex(layerIndex);
@@ -329,6 +325,7 @@ void RenderBackgroundLayer::update(const int32_t layerIndex,
if (!newDrawables.empty()) {
auto& drawable = newDrawables[0];
drawable->setTileID(tileID);
drawable->mutableUniformBuffers().addOrReplace("BackgroundLayerUBO", uniformBuffer);
result.first->second = drawable;
changes.emplace_back(std::make_unique<AddDrawableRequest>(std::move(drawable)));
++stats.tileDrawablesAdded;

View File

@@ -50,4 +50,26 @@ private:
std::shared_ptr<BackgroundPatternProgram> backgroundPatternProgram;
};
struct alignas(16) BackgroundLayerUBO {
Color color;
float opacity;
};
struct alignas(16) BackgroundPatternLayerUBO {
std::array<float, 2> pattern_tl_a;
std::array<float, 2> pattern_br_a;
std::array<float, 2> pattern_tl_b;
std::array<float, 2> pattern_br_b;
std::array<float, 2> texsize;
std::array<float, 2> pattern_size_a;
std::array<float, 2> pattern_size_b;
std::array<float, 2> pixel_coord_upper;
std::array<float, 2> pixel_coord_lower;
float tile_units_to_pixels;
float scale_a;
float scale_b;
float mix;
float opacity;
};
} // namespace mbgl

View File

@@ -260,7 +260,7 @@ bool RenderFillLayer::queryIntersectsFeature(const GeometryCoordinates& queryGeo
feature.getGeometries());
}
constexpr auto shaderName = "background_generic";
constexpr auto shaderName = "BackgroundProgramUBO";
void RenderFillLayer::layerRemoved(UniqueChangeRequestVec& changes) {
// Remove everything

View File

@@ -180,8 +180,9 @@ protected:
std::mutex mutex;
gfx::ShaderProgramBasePtr shader;
std::unordered_map<OverscaledTileID, gfx::DrawablePtr> tileDrawables;
std::optional<Color> lastColor;
int32_t lastLayerIndex = -1;
bool evaluatedPropertiesChange = false;
gfx::UniformBufferPtr uniformBuffer = nullptr;
struct Stats {
size_t propertyEvaluations = 0;

View File

@@ -234,10 +234,10 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
matrix = tileMat;
}
if (auto& shader = drawable.getShader()) {
shader->setUniform("u_matrix", 0, util::convert<float>(matrix));
shader->updateUniforms();
}
gfx::DrawableUBO drawableUBO;
drawableUBO.matrix = util::convert<float>(matrix);
auto uniformBuffer = context.createUniformBuffer(&drawableUBO, sizeof(drawableUBO));
drawable.mutableUniformBuffers().addOrReplace("DrawableUBO", uniformBuffer);
drawable.draw(parameters);
}
@@ -261,7 +261,7 @@ void Renderer::Impl::render(const RenderTree& renderTree) {
for (auto it = layerRenderItems.rbegin(); it != layerRenderItems.rend(); ++it, ++i) {
parameters.currentLayer = i;
const RenderItem& renderItem = it->get();
if (renderItem.getName() == "background") { // Replaced by drawables, above
if (renderItem.getName() == "background") {
continue;
}
if (renderItem.hasRenderPass(parameters.pass)) {

View File

@@ -82,17 +82,17 @@ ShaderProgramGL::ShaderProgramGL(UniqueProgram&& glProgram_)
glProgram(std::move(glProgram_)) {}
ShaderProgramGL::ShaderProgramGL(UniqueProgram&& program,
VertexAttributeArrayGL&& uniforms_,
UniformBlockArrayGL&& uniformBlocks_,
VertexAttributeArrayGL&& attributes_)
: ShaderProgramBase(),
glProgram(std::move(program)),
uniforms(std::move(uniforms_)),
uniformBlocks(std::move(uniformBlocks_)),
vertexAttributes(std::move(attributes_)) {}
ShaderProgramGL::ShaderProgramGL(ShaderProgramGL&& other)
: ShaderProgramBase(std::forward<ShaderProgramBase&&>(other)),
glProgram(std::move(other.glProgram)),
uniforms(std::move(other.uniforms)),
uniformBlocks(std::move(other.uniformBlocks)),
vertexAttributes(std::move(other.vertexAttributes)) {}
using namespace platform;
@@ -102,8 +102,8 @@ static void addAttr(
const auto elementType = mapType(glType);
const auto elementCount = mapCount(glType); // number of `elementType`, hopefully temporary
if (elementType != gfx::AttributeDataType::Invalid && length > 0) {
if (auto newAttr = attrs.add(name, index, elementType, elementCount, count)) {
auto* glAttr = static_cast<VertexAttributeGL*>(newAttr);
if (const auto& newAttr = attrs.add(name, index, elementType, elementCount, count)) {
const auto& glAttr = static_cast<VertexAttributeGL*>(newAttr.get());
glAttr->setGLType(glType);
}
}
@@ -125,21 +125,23 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(Context& context,
// GLint numAttribs;
// glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &numAttribs);
VertexAttributeArrayGL uniforms;
UniformBlockArrayGL uniformBlocks;
GLint count = 0;
GLint maxLength = 0;
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORMS, &count));
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_MAX_LENGTH, &maxLength));
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCKS, &count));
MBGL_CHECK_ERROR(glGetProgramiv(program, GL_ACTIVE_UNIFORM_BLOCK_MAX_NAME_LENGTH, &maxLength));
auto name = std::vector<GLchar>(maxLength);
for (GLint index = 0; index < count; ++index) {
GLsizei length = 0;
GLint size = 0;
GLenum glType = 0;
MBGL_CHECK_ERROR(glGetActiveUniform(program, index, maxLength, &length, &size, &glType, name.data()));
const GLint location = MBGL_CHECK_ERROR(glGetUniformLocation(program, name.data()));
addAttr(uniforms, name.data(), location, length, size, glType);
GLint binding = index;
MBGL_CHECK_ERROR(glGetActiveUniformBlockName(program, index, maxLength, &length, name.data()));
MBGL_CHECK_ERROR(glGetActiveUniformBlockiv(program, index, GL_UNIFORM_BLOCK_DATA_SIZE, &size));
assert(length > 0 && size > 0);
MBGL_CHECK_ERROR(glUniformBlockBinding(program, index, binding));
uniformBlocks.add(name.data(), index, size);
}
VertexAttributeArrayGL attrs;
@@ -160,7 +162,7 @@ std::shared_ptr<ShaderProgramGL> ShaderProgramGL::create(Context& context,
addAttr(attrs, name.data(), location, length, size, glType);
}
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(uniforms), std::move(attrs));
return std::make_shared<ShaderProgramGL>(std::move(program), std::move(uniformBlocks), std::move(attrs));
}
} // namespace gl