Skip to content

Commit

Permalink
Disable stencil instancing
Browse files Browse the repository at this point in the history
  • Loading branch information
TimSylvester committed Oct 18, 2023
1 parent b40032e commit f80d64f
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 15 deletions.
20 changes: 5 additions & 15 deletions include/mbgl/shaders/mtl/clipping_mask.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,30 +44,20 @@ struct VertexStage {
struct FragmentStage {
float4 position [[position, invariant]];
uint8_t stencil_ref;
};
struct FragmentResult {
// color output is only needed because we're using implicit stencil writes
half4 color [[color(0)]];
// target is `..._stencil8`, but using `uint8_t` here causes a compile error
uint16_t stencil_ref [[stencil]];
};
FragmentStage vertex vertexMain(VertexStage in [[stage_in]],
uint16_t instanceID [[instance_id]],
device const ClipUBO* clipUBOs [[buffer(1)]]) {
device const ClipUBO& clipUBO = clipUBOs[instanceID];
return {
.position = clipUBO.matrix * float4(float2(in.position.xy), 0, 1),
.stencil_ref = static_cast<uint8_t>(clipUBO.stencil_ref),
};
device const ClipUBO& clipUBO [[buffer(1)]]) {
return { clipUBO.matrix * float4(float2(in.position.xy), 0, 1) };
}
FragmentResult fragment fragmentMain(FragmentStage in [[stage_in]]) {
return {
.color = half4(1.0),
.stencil_ref = static_cast<uint16_t>(in.stencil_ref),
};
half4 fragment fragmentMain(FragmentStage in [[stage_in]]) {
return half4(1.0);
}
)";
};
Expand Down
22 changes: 22 additions & 0 deletions src/mbgl/mtl/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,13 @@ bool Context::renderTileClippingMasks(gfx::RenderPass& renderPass,

encoder->setCullMode(MTL::CullModeNone);
encoder->setVertexBuffer(vertexRes.getMetalBuffer().get(), /*offset=*/0, ShaderClass::attributes[0].index);

// Instancing is disabled for now because the `[[stencil]]` attribute in the fragment shader output
// that we need to apply a different stencil value for each tile causes a problem on some older (A8-A11)
// devices, specifically `XPC_ERROR_CONNECTION_INTERRUPTED` when creating a render pipeline state.
// Adding a `[[depth(...)]]` output to the shader prevents this error, but the stencil value is
// still not written to the stencil attachment on those same devices.
#if STENCIL_INSTANCING
encoder->setVertexBuffer(uboBuffer.getMetalBuffer().get(), /*offset=*/0, ShaderClass::uniforms[0].index);
encoder->drawIndexedPrimitives(MTL::PrimitiveType::PrimitiveTypeTriangle,
indexCount,
Expand All @@ -339,6 +346,21 @@ bool Context::renderTileClippingMasks(gfx::RenderPass& renderPass,
/*instanceCount=*/static_cast<NS::UInteger>(tileUBOs.size()),
/*baseVertex=*/0,
/*baseInstance=*/0);
#else
for (std::size_t ii = 0; ii < tileUBOs.size(); ++ii) {
encoder->setStencilReferenceValue(tileUBOs[ii].stencil_ref);
encoder->setVertexBuffer(
uboBuffer.getMetalBuffer().get(), /*offset=*/ii * uboSize, ShaderClass::uniforms[0].index);
encoder->drawIndexedPrimitives(MTL::PrimitiveType::PrimitiveTypeTriangle,
indexCount,
MTL::IndexType::IndexTypeUInt16,
indexRes->getMetalBuffer().get(),
/*indexOffset=*/0,
/*instanceCount=*/1,
/*baseVertex=*/0,
/*baseInstance=*/0);
}
#endif

return true;
}
Expand Down

0 comments on commit f80d64f

Please sign in to comment.