set stencil state

This commit is contained in:
Samuliak 2024-08-07 20:59:05 +02:00
parent d3249dc324
commit 1bcdade83e
8 changed files with 79 additions and 44 deletions

View File

@ -3215,7 +3215,7 @@ static void _emitExportCode(LatteDecompilerShaderContext* shaderContext, LatteDe
cemu_assert_unimplemented(); // ukn
}
src->add("gl_FragDepth = ");
src->add("out.depth = ");
_emitExportGPRReadCode(shaderContext, cfInstruction, LATTE_DECOMPILER_DTYPE_FLOAT, 0);
src->add(".x");
src->add(";" _CRLF);

View File

@ -271,6 +271,12 @@ namespace LatteDecompiler
}
}
// generate depth output for pixel shader
if (decompilerContext->shader->pixelDepthOutputMask)
{
src->add("float passDepth [[depth(any)]];" _CRLF);
}
src->add("};" _CRLF _CRLF);
}
}

View File

@ -28,6 +28,15 @@ void CachedFBOMtl::CreateRenderPass()
depthAttachment->setTexture(textureView->GetRGBAView());
depthAttachment->setLoadAction(MTL::LoadActionLoad);
depthAttachment->setStoreAction(MTL::StoreActionStore);
// setup stencil attachment
if (depthBuffer.hasStencil)
{
auto stencilAttachment = m_renderPassDescriptor->stencilAttachment();
stencilAttachment->setTexture(textureView->GetRGBAView());
stencilAttachment->setLoadAction(MTL::LoadActionLoad);
stencilAttachment->setStoreAction(MTL::StoreActionStore);
}
}
}

View File

@ -452,3 +452,20 @@ MTL::TextureSwizzle GetMtlTextureSwizzle(uint32 swizzle)
cemu_assert_debug(swizzle < std::size(MTL_TEXTURE_SWIZZLES));
return MTL_TEXTURE_SWIZZLES[swizzle];
}
const MTL::StencilOperation MTL_STENCIL_OPERATIONS[8] = {
MTL::StencilOperationKeep,
MTL::StencilOperationZero,
MTL::StencilOperationReplace,
MTL::StencilOperationIncrementClamp,
MTL::StencilOperationDecrementClamp,
MTL::StencilOperationInvert,
MTL::StencilOperationIncrementWrap,
MTL::StencilOperationDecrementWrap
};
MTL::StencilOperation GetMtlStencilOp(Latte::LATTE_DB_DEPTH_CONTROL::E_STENCILACTION action)
{
cemu_assert_debug((uint32)action < std::size(MTL_STENCIL_OPERATIONS));
return MTL_STENCIL_OPERATIONS[(uint32)action];
}

View File

@ -53,3 +53,5 @@ MTL::CompareFunction GetMtlCompareFunc(Latte::E_COMPAREFUNC func);
MTL::SamplerAddressMode GetMtlSamplerAddressMode(Latte::LATTE_SQ_TEX_SAMPLER_WORD0_0::E_CLAMP clamp);
MTL::TextureSwizzle GetMtlTextureSwizzle(uint32 swizzle);
MTL::StencilOperation GetMtlStencilOp(Latte::LATTE_DB_DEPTH_CONTROL::E_STENCILACTION action);

View File

@ -37,8 +37,6 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
}
desc->setDepthCompareFunction(depthCompareFunc);
// TODO: stencil state
/*
// get stencil control parameters
bool stencilEnable = LatteGPUState.contextNew.DB_DEPTH_CONTROL.get_STENCIL_ENABLE();
bool backStencilEnable = LatteGPUState.contextNew.DB_DEPTH_CONTROL.get_BACK_STENCIL_ENABLE();
@ -58,48 +56,47 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
uint32 stencilWriteMaskBack = LatteGPUState.contextNew.DB_STENCILREFMASK_BF.get_STENCILWRITEMASK_B();
uint32 stencilRefBack = LatteGPUState.contextNew.DB_STENCILREFMASK_BF.get_STENCILREF_B();
static const VkStencilOp stencilOpTable[8] = {
VK_STENCIL_OP_KEEP,
VK_STENCIL_OP_ZERO,
VK_STENCIL_OP_REPLACE,
VK_STENCIL_OP_INCREMENT_AND_CLAMP,
VK_STENCIL_OP_DECREMENT_AND_CLAMP,
VK_STENCIL_OP_INVERT,
VK_STENCIL_OP_INCREMENT_AND_WRAP,
VK_STENCIL_OP_DECREMENT_AND_WRAP
};
depthStencilState.stencilTestEnable = stencilEnable ? VK_TRUE : VK_FALSE;
depthStencilState.front.reference = stencilRefFront;
depthStencilState.front.compareMask = stencilCompareMaskFront;
depthStencilState.front.writeMask = stencilWriteMaskBack;
depthStencilState.front.compareOp = vkDepthCompareTable[(size_t)frontStencilFunc];
depthStencilState.front.depthFailOp = stencilOpTable[(size_t)frontStencilZFail];
depthStencilState.front.failOp = stencilOpTable[(size_t)frontStencilFail];
depthStencilState.front.passOp = stencilOpTable[(size_t)frontStencilZPass];
if (backStencilEnable)
if (stencilEnable)
{
depthStencilState.back.reference = stencilRefBack;
depthStencilState.back.compareMask = stencilCompareMaskBack;
depthStencilState.back.writeMask = stencilWriteMaskBack;
depthStencilState.back.compareOp = vkDepthCompareTable[(size_t)backStencilFunc];
depthStencilState.back.depthFailOp = stencilOpTable[(size_t)backStencilZFail];
depthStencilState.back.failOp = stencilOpTable[(size_t)backStencilFail];
depthStencilState.back.passOp = stencilOpTable[(size_t)backStencilZPass];
MTL::StencilDescriptor* frontStencil = MTL::StencilDescriptor::alloc()->init();
// TODO: set reference
//depthStencilState.front.reference = stencilRefFront;
frontStencil->setReadMask(stencilCompareMaskFront);
frontStencil->setWriteMask(stencilWriteMaskFront);
frontStencil->setStencilCompareFunction(GetMtlCompareFunc(frontStencilFunc));
frontStencil->setDepthFailureOperation(GetMtlStencilOp(frontStencilZFail));
frontStencil->setStencilFailureOperation(GetMtlStencilOp(frontStencilFail));
frontStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass));
desc->setFrontFaceStencil(frontStencil);
MTL::StencilDescriptor* backStencil = MTL::StencilDescriptor::alloc()->init();
if (backStencilEnable)
{
// TODO: set reference
//depthStencilState.back.reference = stencilRefBack;
backStencil->setReadMask(stencilCompareMaskBack);
backStencil->setWriteMask(stencilWriteMaskBack);
backStencil->setStencilCompareFunction(GetMtlCompareFunc(backStencilFunc));
backStencil->setDepthFailureOperation(GetMtlStencilOp(backStencilZFail));
backStencil->setStencilFailureOperation(GetMtlStencilOp(backStencilFail));
backStencil->setDepthStencilPassOperation(GetMtlStencilOp(backStencilZPass));
}
else
{
// TODO: set reference
//depthStencilState.back.reference = stencilRefFront;
backStencil->setReadMask(stencilCompareMaskFront);
backStencil->setWriteMask(stencilWriteMaskFront);
backStencil->setStencilCompareFunction(GetMtlCompareFunc(frontStencilFunc));
backStencil->setDepthFailureOperation(GetMtlStencilOp(frontStencilZFail));
backStencil->setStencilFailureOperation(GetMtlStencilOp(frontStencilFail));
backStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass));
}
desc->setBackFaceStencil(backStencil);
frontStencil->release();
backStencil->release();
}
else
{
depthStencilState.back.reference = stencilRefFront;
depthStencilState.back.compareMask = stencilCompareMaskFront;
depthStencilState.back.writeMask = stencilWriteMaskFront;
depthStencilState.back.compareOp = vkDepthCompareTable[(size_t)frontStencilFunc];
depthStencilState.back.depthFailOp = stencilOpTable[(size_t)frontStencilZFail];
depthStencilState.back.failOp = stencilOpTable[(size_t)frontStencilFail];
depthStencilState.back.passOp = stencilOpTable[(size_t)frontStencilZPass];
}
*/
depthStencilState = m_mtlr->GetDevice()->newDepthStencilState(desc);
desc->release();

View File

@ -143,7 +143,10 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS
{
auto texture = static_cast<LatteTextureViewMtl*>(activeFBO->depthBuffer.texture);
desc->setDepthAttachmentPixelFormat(texture->GetRGBAView()->pixelFormat());
// TODO: stencil pixel format
if (activeFBO->depthBuffer.hasStencil)
{
desc->setStencilAttachmentPixelFormat(texture->GetRGBAView()->pixelFormat());
}
}
NS::Error* error = nullptr;

View File

@ -49,6 +49,7 @@ enum class MetalEncoderType
Blit,
};
// HACK: Dummy occlusion query object for Metal
class LatteQueryObjectMtl : public LatteQueryObject
{
public: