emulate unsupported shadow sampler types

This commit is contained in:
Samo Z 2024-09-01 14:36:39 +02:00
parent f9f6260580
commit 5d07d115a6
3 changed files with 55 additions and 17 deletions

View File

@ -2246,6 +2246,7 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
}
bool isCompare = shaderContext->shader->textureUsesDepthCompare[texInstruction->textureFetch.textureIndex];
bool emulateCompare = (isCompare && !IsValidDepthTextureType(texDim));
bool isGather = (texOpcode == GPU7_TEX_INST_FETCH4);
bool unnormalizationHandled = false;
@ -2265,25 +2266,40 @@ static void _emitTEXSampleTextureCode(LatteDecompilerShaderContext* shaderContex
return;
}
src->addFmt("tex{}.", texInstruction->textureFetch.textureIndex);
if ((texOpcode == GPU7_TEX_INST_SAMPLE && (texInstruction->textureFetch.unnormalized[0] && texInstruction->textureFetch.unnormalized[1] && texInstruction->textureFetch.unnormalized[2] && texInstruction->textureFetch.unnormalized[3])) ||
texOpcode == GPU7_TEX_INST_LD)
if (emulateCompare)
{
if (hasOffset)
cemu_assert_unimplemented();
src->add("read(");
unnormalizationHandled = true;
useTexelCoordinates = true;
cemu_assert_debug(!isGather);
src->add("sampleCompareEmulate(");
}
src->addFmt("tex{}", texInstruction->textureFetch.textureIndex);
if (!emulateCompare)
{
src->add(".");
if ((texOpcode == GPU7_TEX_INST_SAMPLE && (texInstruction->textureFetch.unnormalized[0] && texInstruction->textureFetch.unnormalized[1] && texInstruction->textureFetch.unnormalized[2] && texInstruction->textureFetch.unnormalized[3])) ||
texOpcode == GPU7_TEX_INST_LD)
{
if (hasOffset)
cemu_assert_unimplemented();
src->add("read(");
unnormalizationHandled = true;
useTexelCoordinates = true;
}
else
{
if (isGather)
src->add("gather");
else
src->add("sample");
if (isCompare)
src->add("_compare");
src->addFmt("(samplr{}, ", texInstruction->textureFetch.textureIndex);
}
}
else
{
if (isGather)
src->add("gather");
else
src->add("sample");
if (isCompare)
src->add("_compare");
src->addFmt("(samplr{}, ", texInstruction->textureFetch.textureIndex);
src->addFmt(", samplr{}, ", texInstruction->textureFetch.textureIndex);
}
// for textureGather() add shift (todo: depends on rounding mode set in sampler registers?)
@ -3719,6 +3735,19 @@ void LatteDecompiler_emitHelperFunctions(LatteDecompilerShaderContext* shaderCon
"}\r\n");
}
// Sample compare emulate
// TODO: only add when needed
// TODO: lod_options overload
// TODO: when the sampler has linear min mag filter, use gather and filter manually
// TODO: offset?
fCStr_shaderSource->add(""
"template<typename TextureT, typename CoordT>\r\n"
"float sampleCompareEmulate(TextureT tex, sampler samplr, CoordT coord, float compareValue) {\r\n"
"return compareValue < tex.sample(samplr, coord).x ? 1.0 : 0.0;\r\n"
"}\r\n"
);
// clamp
fCStr_shaderSource->add(""
"int clampFI32(int v)\r\n"

View File

@ -1,7 +1,8 @@
#pragma once
#include "Common/precompiled.h"
#include "HW/Latte/Core/LatteConst.h"
#include "Cafe/HW/Latte/Renderer/Metal/MetalCommon.h"
namespace LatteDecompiler
{
static void _emitUniformVariables(LatteDecompilerShaderContext* decompilerContext)
@ -442,7 +443,8 @@ namespace LatteDecompiler
src->add(", ");
if (shaderContext->shader->textureUsesDepthCompare[i])
// Only 2D and 2D array textures can be used with comparison samplers
if (shaderContext->shader->textureUsesDepthCompare[i] && IsValidDepthTextureType(shaderContext->shader->textureUnitDim[i]))
src->add("depth");
else
src->add("texture");

View File

@ -3,6 +3,8 @@
#include <Foundation/Foundation.hpp>
#include <Metal/Metal.hpp>
#include "Cafe/HW/Latte/Core/LatteConst.h"
struct MetalPixelFormatSupport
{
bool m_supportsR8Unorm_sRGB;
@ -62,3 +64,8 @@ inline NS::String* GetLabel(const std::string& label, const void* identifier)
}
constexpr MTL::RenderStages ALL_MTL_RENDER_STAGES = MTL::RenderStageVertex | MTL::RenderStageObject | MTL::RenderStageMesh | MTL::RenderStageFragment;
inline bool IsValidDepthTextureType(Latte::E_DIM dim)
{
return (dim == Latte::E_DIM::DIM_2D || dim == Latte::E_DIM::DIM_2D_MSAA || dim == Latte::E_DIM::DIM_2D_ARRAY || dim == Latte::E_DIM::DIM_2D_ARRAY_MSAA || dim == Latte::E_DIM::DIM_CUBEMAP);
}