Disable stencil instancing (#1778)
This commit is contained in:
@@ -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);
|
||||
}
|
||||
)";
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user