Skip to content

Commit

Permalink
Metal layer depth range support (#2013)
Browse files Browse the repository at this point in the history
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Alex Cristici <[email protected]>
  • Loading branch information
3 people authored Jan 16, 2024
1 parent 29c16a4 commit d6c2b14
Show file tree
Hide file tree
Showing 28 changed files with 109 additions and 31 deletions.
4 changes: 4 additions & 0 deletions include/mbgl/gfx/drawable.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,9 @@ class Drawable {
/// Set sub-layer index
virtual void setSubLayerIndex(int32_t value) { subLayerIndex = value; }

void setLayerIndex(int32_t value) { layerIndex = value; }
int32_t getLayerIndex() const { return layerIndex; }

/// Depth writability for 2D drawables
DepthMaskType getDepthType() const { return depthType; }

Expand Down Expand Up @@ -252,6 +255,7 @@ class Drawable {
DrawPriority drawPriority = 0;
int32_t lineWidth = 1;
int32_t subLayerIndex = 0;
int32_t layerIndex = 0;
DepthMaskType depthType; // = DepthMaskType::ReadOnly;
UniqueDrawableData drawableData{};
gfx::VertexAttributeArrayPtr vertexAttributes;
Expand Down
16 changes: 15 additions & 1 deletion include/mbgl/renderer/layer_group.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ class LayerGroupBase : public util::SimpleIdentifiable {
int32_t getLayerIndex() const { return layerIndex; }

/// Update the layer index to a new value
void updateLayerIndex(int32_t value) { layerIndex = value; }
virtual void updateLayerIndex(int32_t value) { layerIndex = value; }

/// Get the number of drawables contained
virtual std::size_t getDrawableCount() const = 0;
Expand Down Expand Up @@ -163,6 +163,13 @@ class TileLayerGroup : public LayerGroupBase {

void setStencilTiles(RenderTiles);

void updateLayerIndex(int32_t value) override {
layerIndex = value;
for (auto* drawable : sortedDrawables) {
drawable->setLayerIndex(value);
}
}

protected:
// When stencil clipping is enabled for the layer, this is the set
// of tile IDs that need to be rendered to the stencil buffer.
Expand Down Expand Up @@ -232,6 +239,13 @@ class LayerGroup : public LayerGroupBase {

std::size_t clearDrawables() override;

void updateLayerIndex(int32_t value) override {
layerIndex = value;
for (auto& drawable : drawables) {
drawable->setLayerIndex(value);
}
}

protected:
using DrawableCollection = std::set<gfx::UniqueDrawable, gfx::DrawableLessByPriority>;
DrawableCollection drawables;
Expand Down
1 change: 1 addition & 0 deletions include/mbgl/renderer/layer_tweaker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class LayerTweaker {
style::TranslateAnchorType,
bool nearClipped,
bool inViewportPixelUnits,
const gfx::Drawable& drawable,
bool aligned = false);

protected:
Expand Down
6 changes: 6 additions & 0 deletions src/mbgl/gfx/depth_mode.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,15 @@ class DepthMode {
public:
DepthFunctionType func;
DepthMaskType mask;
#if MLN_RENDER_BACKEND_OPENGL
Range<float> range;
#endif

#if MLN_RENDER_BACKEND_OPENGL
static DepthMode disabled() { return DepthMode{DepthFunctionType::Always, DepthMaskType::ReadOnly, {0.0, 1.0}}; }
#else
static DepthMode disabled() { return DepthMode{DepthFunctionType::Always, DepthMaskType::ReadOnly}; }
#endif
};

} // namespace gfx
Expand Down
6 changes: 6 additions & 0 deletions src/mbgl/gl/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,9 @@ void Context::setDirtyState() {
stencilMask.setDirty();
stencilTest.setDirty();
stencilOp.setDirty();
#if MLN_RENDER_BACKEND_OPENGL
depthRange.setDirty();
#endif
depthMask.setDirty();
depthTest.setDirty();
depthFunc.setDirty();
Expand Down Expand Up @@ -615,12 +617,16 @@ void Context::setDepthMode(const gfx::DepthMode& depth) {
// https://github.com/mapbox/mapbox-gl-native/issues/9164
depthFunc = depth.func;
depthMask = depth.mask;
#if MLN_RENDER_BACKEND_OPENGL
depthRange = depth.range;
#endif
} else {
depthTest = true;
depthFunc = depth.func;
depthMask = depth.mask;
#if MLN_RENDER_BACKEND_OPENGL
depthRange = depth.range;
#endif
}
}

Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/gl/context.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ class Context final : public gfx::Context {
State<value::StencilMask> stencilMask;
State<value::StencilTest> stencilTest;
State<value::StencilOp> stencilOp;
#if MLN_RENDER_BACKEND_OPENGL
State<value::DepthRange> depthRange;
#endif
State<value::DepthMask> depthMask;
State<value::DepthTest> depthTest;
State<value::DepthFunc> depthFunc;
Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/gl/value.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ StencilOp::Type StencilOp::Get() {
Enum<gfx::StencilOpType>::from(dppass)};
}

#if MLN_RENDER_BACKEND_OPENGL
const constexpr DepthRange::Type DepthRange::Default;

void DepthRange::Set(const Type& value) {
Expand All @@ -144,6 +145,7 @@ DepthRange::Type DepthRange::Get() {
MBGL_CHECK_ERROR(glGetFloatv(GL_DEPTH_RANGE, floats));
return {floats[0], floats[1]};
}
#endif

const constexpr DepthTest::Type DepthTest::Default;

Expand Down
2 changes: 2 additions & 0 deletions src/mbgl/gl/value.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,14 @@ constexpr bool operator!=(const StencilOp::Type& a, const StencilOp::Type& b) {
return a.sfail != b.sfail || a.dpfail != b.dpfail || a.dppass != b.dppass;
}

#if MLN_RENDER_BACKEND_OPENGL
struct DepthRange {
using Type = Range<float>;
static const constexpr Type Default = {0, 1};
static void Set(const Type&);
static Type Get();
};
#endif

struct DepthTest {
using Type = bool;
Expand Down
7 changes: 2 additions & 5 deletions src/mbgl/mtl/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,11 +269,8 @@ const auto clipMaskStencilMode = gfx::StencilMode{
/*.depthFail=*/gfx::StencilOpType::Keep,
/*.pass=*/gfx::StencilOpType::Replace,
};
const auto clipMaskDepthMode = gfx::DepthMode{
/*.func=*/gfx::DepthFunctionType::Always,
/*.mask=*/gfx::DepthMaskType::ReadOnly,
/*.range=*/{0, 1},
};
const auto clipMaskDepthMode = gfx::DepthMode{/*.func=*/gfx::DepthFunctionType::Always,
/*.mask=*/gfx::DepthMaskType::ReadOnly};
} // namespace

bool Context::renderTileClippingMasks(gfx::RenderPass& renderPass,
Expand Down
1 change: 1 addition & 0 deletions src/mbgl/renderer/layer_group.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
namespace mbgl {

void LayerGroupBase::addDrawable(gfx::UniqueDrawable& drawable) {
drawable->setLayerIndex(layerIndex);
// init their tweakers
for (const auto& tweaker : drawable->getTweakers()) {
tweaker->init(*drawable);
Expand Down
17 changes: 14 additions & 3 deletions src/mbgl/renderer/layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,26 @@ mat4 LayerTweaker::getTileMatrix(const UnwrappedTileID& tileID,
style::TranslateAnchorType anchor,
bool nearClipped,
bool inViewportPixelUnits,
[[maybe_unused]] const gfx::Drawable& drawable,
bool aligned) {
// from RenderTile::prepare
mat4 tileMatrix;
parameters.state.matrixFor(/*out*/ tileMatrix, tileID);

// nearClippedMatrix has near plane moved further, to enhance depth buffer precision
const auto& projMatrix = aligned ? parameters.transformParams.alignedProjMatrix
: (nearClipped ? parameters.transformParams.nearClippedProjMatrix
: parameters.transformParams.projMatrix);
auto projMatrix = aligned ? parameters.transformParams.alignedProjMatrix
: (nearClipped ? parameters.transformParams.nearClippedProjMatrix
: parameters.transformParams.projMatrix);

#if !MLN_RENDER_BACKEND_OPENGL
// Offset the projection matrix NDC depth range for the drawable's layer and sublayer.
if (!drawable.getIs3D()) {
projMatrix[14] -= ((1 + drawable.getLayerIndex()) * PaintParameters::numSublayers -
drawable.getSubLayerIndex()) *
PaintParameters::depthEpsilon;
}
#endif

matrix::multiply(tileMatrix, projMatrix, tileMatrix);

return RenderTile::translateVtxMatrix(
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/layers/background_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ void BackgroundLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintPara
(shader == context.getGenericShader(parameters.shaders, std::string(BackgroundPatternShaderName))));

const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
const auto matrix = parameters.matrixForTile(tileID);
const auto matrix = getTileMatrix(
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, false, false, drawable);

const BackgroundDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix)};

Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/layers/circle_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ void CircleLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
const auto anchor = evaluated.get<CircleTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
constexpr bool nearClipped = false;
const auto matrix = getTileMatrix(tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits);
const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);

const auto pixelsToTileUnits = tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom));
const auto extrudeScale = pitchWithMap ? std::array<float, 2>{pixelsToTileUnits, pixelsToTileUnits}
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/layers/collision_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,8 @@ void CollisionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParam
const auto anchor = data.translateAnchor;
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false;
const auto matrix = getTileMatrix(tileID, parameters, translate, anchor, nearClipped, inViewportPixelUnits);
const auto matrix = getTileMatrix(
tileID, parameters, translate, anchor, nearClipped, inViewportPixelUnits, drawable);

// extrude scale
const auto pixelRatio = tileID.pixelsToTileUnits(1.0f, static_cast<float>(parameters.state.getZoom()));
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/layers/fill_extrusion_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,8 @@ void FillExtrusionLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintP
const auto anchor = evaluated.get<FillExtrusionTranslateAnchor>();
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
constexpr bool nearClipped = true;
const auto matrix = getTileMatrix(tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits);
const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);

const auto tileRatio = 1 / tileID.pixelsToTileUnits(1, state.getIntegerZoom());
const auto zoomScale = state.zoomScale(tileID.canonical.z);
Expand Down
4 changes: 3 additions & 1 deletion src/mbgl/renderer/layers/fill_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,9 @@ void FillLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters

constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
constexpr bool nearClipped = false;
const auto matrix = getTileMatrix(tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits);

const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);

// from FillPatternProgram::layoutUniformValues
const auto tileRatio = 1.0f / tileID.pixelsToTileUnits(1.0f, intZoom);
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/layers/heatmap_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ void HeatmapLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamet
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false;
const auto matrix = getTileMatrix(
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, nearClipped, inViewportPixelUnits);
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, nearClipped, inViewportPixelUnits, drawable);
const HeatmapDrawableUBO drawableUBO = {
/* .matrix = */ util::cast<float>(matrix),
/* .extrude_scale = */ tileID.pixelsToTileUnits(1.0f, static_cast<float>(zoom)),
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/layers/hillshade_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ void HillshadeLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParam
drawable.mutableUniformBuffers().addOrReplace(idHillshadeEvaluatedPropsUBOName, evaluatedPropsUniformBuffer);

const auto matrix = getTileMatrix(
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, false, false, true);
tileID, parameters, {0.f, 0.f}, TranslateAnchorType::Viewport, false, false, drawable, true);
HillshadeDrawableUBO drawableUBO = {/* .matrix = */ util::cast<float>(matrix),
/* .latrange = */ getLatRange(tileID),
/* .light = */ getLight(parameters, evaluated)};
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/layers/line_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,8 @@ void LineLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParameters
constexpr bool inViewportPixelUnits = false; // from RenderTile::translatedMatrix
auto& uniforms = drawable.mutableUniformBuffers();

const auto matrix = getTileMatrix(tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits);
const auto matrix = getTileMatrix(
tileID, parameters, translation, anchor, nearClipped, inViewportPixelUnits, drawable);

uniforms.addOrReplace(idLineDynamicUBOName, dynamicBuffer);

Expand Down
9 changes: 8 additions & 1 deletion src/mbgl/renderer/layers/raster_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,14 @@ void RasterLayerTweaker::execute([[maybe_unused]] LayerGroupBase& layerGroup,
} else {
// this is a tile drawable
const UnwrappedTileID tileID = drawable.getTileID()->toUnwrapped();
matrix = parameters.matrixForTile(tileID, !parameters.state.isChanging());
matrix = getTileMatrix(tileID,
parameters,
{0.f, 0.f},
TranslateAnchorType::Viewport,
false,
false,
drawable,
!parameters.state.isChanging());
}

const RasterDrawableUBO drawableUBO{
Expand Down
2 changes: 1 addition & 1 deletion src/mbgl/renderer/layers/render_fill_layer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -368,7 +368,7 @@ class OutlineDrawableTweaker : public gfx::DrawableTweaker {
static const StringIdentity idLineUBOName = stringIndexer().get("LineBasicUBO");
{
const auto matrix = LayerTweaker::getTileMatrix(
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, false);
tileID, parameters, {{0, 0}}, style::TranslateAnchorType::Viewport, false, false, drawable, false);

const shaders::LineBasicUBO lineUBO{
/*matrix = */ util::cast<float>(matrix),
Expand Down
3 changes: 2 additions & 1 deletion src/mbgl/renderer/layers/symbol_layer_tweaker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,8 @@ void SymbolLayerTweaker::execute(LayerGroupBase& layerGroup, const PaintParamete
: evaluated.get<style::IconTranslateAnchor>();
constexpr bool nearClipped = false;
constexpr bool inViewportPixelUnits = false;
const auto matrix = getTileMatrix(tileID, parameters, translate, anchor, nearClipped, inViewportPixelUnits);
const auto matrix = getTileMatrix(
tileID, parameters, translate, anchor, nearClipped, inViewportPixelUnits, drawable);

// from symbol_program, makeValues
const auto currentZoom = static_cast<float>(parameters.state.getZoom());
Expand Down
11 changes: 10 additions & 1 deletion src/mbgl/renderer/paint_parameters.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,16 +82,25 @@ mat4 PaintParameters::matrixForTile(const UnwrappedTileID& tileID, bool aligned)
return matrix;
}

gfx::DepthMode PaintParameters::depthModeForSublayer(uint8_t n, gfx::DepthMaskType mask) const {
gfx::DepthMode PaintParameters::depthModeForSublayer([[maybe_unused]] uint8_t n, gfx::DepthMaskType mask) const {
if (currentLayer < opaquePassCutoff) {
return gfx::DepthMode::disabled();
}

#if MLN_RENDER_BACKEND_OPENGL
float depth = depthRangeSize + ((1 + currentLayer) * numSublayers + n) * depthEpsilon;
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask, {depth, depth}};
#else
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, mask};
#endif
}

gfx::DepthMode PaintParameters::depthModeFor3D() const {
#if MLN_RENDER_BACKEND_OPENGL
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite, {0.0, depthRangeSize}};
#else
return gfx::DepthMode{gfx::DepthFunctionType::LessEqual, gfx::DepthMaskType::ReadWrite};
#endif
}

namespace {
Expand Down
6 changes: 5 additions & 1 deletion src/mbgl/renderer/paint_parameters.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,14 +121,18 @@ class PaintParameters {
int32_t nextStencilID = 1;

public:
const int numSublayers = 3;
uint32_t currentLayer;
float depthRangeSize;
uint32_t opaquePassCutoff = 0;
float symbolFadeChange;
const uint64_t frameCount;

static constexpr int numSublayers = 3;
#if MLN_RENDER_BACKEND_OPENGL
static constexpr float depthEpsilon = 1.0f / (1 << 16);
#else
static constexpr float depthEpsilon = 1.0f / (1 << 12);
#endif
static constexpr int maxStencilValue = 255;
};

Expand Down
6 changes: 4 additions & 2 deletions src/mbgl/renderer/render_target.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,8 @@ void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& re
// draw layer groups, opaque pass
parameters.pass = RenderPass::Opaque;
parameters.currentLayer = 0;
parameters.depthRangeSize = 1 - (numLayerGroups() + 2) * parameters.numSublayers * PaintParameters::depthEpsilon;
parameters.depthRangeSize = 1 -
(numLayerGroups() + 2) * PaintParameters::numSublayers * PaintParameters::depthEpsilon;

visitLayerGroups([&](LayerGroupBase& layerGroup) {
layerGroup.render(orchestrator, parameters);
Expand All @@ -84,7 +85,8 @@ void RenderTarget::render(RenderOrchestrator& orchestrator, const RenderTree& re
// draw layer groups, translucent pass
parameters.pass = RenderPass::Translucent;
parameters.currentLayer = static_cast<int32_t>(numLayerGroups()) - 1;
parameters.depthRangeSize = 1 - (numLayerGroups() + 2) * parameters.numSublayers * PaintParameters::depthEpsilon;
parameters.depthRangeSize = 1 -
(numLayerGroups() + 2) * PaintParameters::numSublayers * PaintParameters::depthEpsilon;

visitLayerGroups([&](LayerGroupBase& layerGroup) {
layerGroup.render(orchestrator, parameters);
Expand Down
Loading

0 comments on commit d6c2b14

Please sign in to comment.