mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-11-29 20:44:18 +01:00
disable writes for color attachments which are not in the active FBO
This commit is contained in:
parent
9c29acc635
commit
cda4799b54
@ -167,7 +167,7 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
|||||||
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 0 && attrib->isSigned == 0 )
|
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 0 && attrib->isSigned == 0 )
|
||||||
{
|
{
|
||||||
// seen in Minecraft Wii U Edition
|
// seen in Minecraft Wii U Edition
|
||||||
src->addFmt("attrDecoder.xyzw = as_type<uint>(float4(in.attrDataSem{}.wzyx)/255.0);" _CRLF, attributeInputIndex);
|
src->addFmt("attrDecoder.xyzw = as_type<uint4>(float4(in.attrDataSem{}.wzyx)/255.0);" _CRLF, attributeInputIndex);
|
||||||
}
|
}
|
||||||
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 0 && attrib->isSigned != 0 )
|
else if( attrib->format == FMT_8_8_8_8 && attrib->nfa == 0 && attrib->isSigned != 0 )
|
||||||
{
|
{
|
||||||
@ -190,7 +190,7 @@ void LatteDecompiler_emitAttributeDecodeMSL(LatteDecompilerShader* shaderContext
|
|||||||
else if (attrib->format == FMT_8_8_8_8 && attrib->nfa == 2 && attrib->isSigned == 0)
|
else if (attrib->format == FMT_8_8_8_8 && attrib->nfa == 2 && attrib->isSigned == 0)
|
||||||
{
|
{
|
||||||
// seen in Ben 10 Omniverse
|
// seen in Ben 10 Omniverse
|
||||||
src->addFmt("attrDecoder.xyzw = as_type<uint>(float4(in.attrDataSem{}.wzyx));" _CRLF, attributeInputIndex);
|
src->addFmt("attrDecoder.xyzw = as_type<uint4>(float4(in.attrDataSem{}.wzyx));" _CRLF, attributeInputIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "HW/Latte/Core/FetchShader.h"
|
#include "HW/Latte/Core/FetchShader.h"
|
||||||
#include "HW/Latte/ISA/RegDefines.h"
|
#include "HW/Latte/ISA/RegDefines.h"
|
||||||
|
#include "Metal/MTLRenderPipeline.hpp"
|
||||||
#include "config/ActiveSettings.h"
|
#include "config/ActiveSettings.h"
|
||||||
|
|
||||||
static void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister)
|
static void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister)
|
||||||
@ -189,7 +190,7 @@ extern std::atomic_int g_compiled_shaders_total;
|
|||||||
extern std::atomic_int g_compiled_shaders_async;
|
extern std::atomic_int g_compiled_shaders_async;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
void SetFragmentState(T* desc, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr)
|
void SetFragmentState(T* desc, CachedFBOMtl* lastUsedFBO, CachedFBOMtl* activeFBO, const LatteContextRegister& lcr)
|
||||||
{
|
{
|
||||||
// Color attachments
|
// Color attachments
|
||||||
const Latte::LATTE_CB_COLOR_CONTROL& colorControlReg = lcr.CB_COLOR_CONTROL;
|
const Latte::LATTE_CB_COLOR_CONTROL& colorControlReg = lcr.CB_COLOR_CONTROL;
|
||||||
@ -197,7 +198,7 @@ void SetFragmentState(T* desc, class CachedFBOMtl* activeFBO, const LatteContext
|
|||||||
uint32 renderTargetMask = lcr.CB_TARGET_MASK.get_MASK();
|
uint32 renderTargetMask = lcr.CB_TARGET_MASK.get_MASK();
|
||||||
for (uint8 i = 0; i < 8; i++)
|
for (uint8 i = 0; i < 8; i++)
|
||||||
{
|
{
|
||||||
const auto& colorBuffer = activeFBO->colorBuffer[i];
|
const auto& colorBuffer = lastUsedFBO->colorBuffer[i];
|
||||||
auto texture = static_cast<LatteTextureViewMtl*>(colorBuffer.texture);
|
auto texture = static_cast<LatteTextureViewMtl*>(colorBuffer.texture);
|
||||||
if (!texture)
|
if (!texture)
|
||||||
{
|
{
|
||||||
@ -205,6 +206,14 @@ void SetFragmentState(T* desc, class CachedFBOMtl* activeFBO, const LatteContext
|
|||||||
}
|
}
|
||||||
auto colorAttachment = desc->colorAttachments()->object(i);
|
auto colorAttachment = desc->colorAttachments()->object(i);
|
||||||
colorAttachment->setPixelFormat(texture->GetRGBAView()->pixelFormat());
|
colorAttachment->setPixelFormat(texture->GetRGBAView()->pixelFormat());
|
||||||
|
|
||||||
|
// Disable writes if not in the active FBO
|
||||||
|
if (!activeFBO->colorBuffer[i].texture)
|
||||||
|
{
|
||||||
|
colorAttachment->setWriteMask(MTL::ColorWriteMaskNone);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
colorAttachment->setWriteMask(GetMtlColorWriteMask((renderTargetMask >> (i * 4)) & 0xF));
|
colorAttachment->setWriteMask(GetMtlColorWriteMask((renderTargetMask >> (i * 4)) & 0xF));
|
||||||
|
|
||||||
// Blending
|
// Blending
|
||||||
@ -239,11 +248,11 @@ void SetFragmentState(T* desc, class CachedFBOMtl* activeFBO, const LatteContext
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Depth stencil attachment
|
// Depth stencil attachment
|
||||||
if (activeFBO->depthBuffer.texture)
|
if (lastUsedFBO->depthBuffer.texture)
|
||||||
{
|
{
|
||||||
auto texture = static_cast<LatteTextureViewMtl*>(activeFBO->depthBuffer.texture);
|
auto texture = static_cast<LatteTextureViewMtl*>(lastUsedFBO->depthBuffer.texture);
|
||||||
desc->setDepthAttachmentPixelFormat(texture->GetRGBAView()->pixelFormat());
|
desc->setDepthAttachmentPixelFormat(texture->GetRGBAView()->pixelFormat());
|
||||||
if (activeFBO->depthBuffer.hasStencil)
|
if (lastUsedFBO->depthBuffer.hasStencil)
|
||||||
{
|
{
|
||||||
desc->setStencilAttachmentPixelFormat(texture->GetRGBAView()->pixelFormat());
|
desc->setStencilAttachmentPixelFormat(texture->GetRGBAView()->pixelFormat());
|
||||||
}
|
}
|
||||||
@ -285,9 +294,9 @@ MetalPipelineCache::~MetalPipelineCache()
|
|||||||
m_binaryArchiveURL->release();
|
m_binaryArchiveURL->release();
|
||||||
}
|
}
|
||||||
|
|
||||||
MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, CachedFBOMtl* activeFBO, const LatteContextRegister& lcr)
|
MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, CachedFBOMtl* lastUsedFBO, CachedFBOMtl* activeFBO, const LatteContextRegister& lcr)
|
||||||
{
|
{
|
||||||
uint64 stateHash = CalculateRenderPipelineHash(fetchShader, vertexShader, pixelShader, activeFBO, lcr);
|
uint64 stateHash = CalculateRenderPipelineHash(fetchShader, vertexShader, pixelShader, lastUsedFBO, lcr);
|
||||||
auto& pipeline = m_pipelineCache[stateHash];
|
auto& pipeline = m_pipelineCache[stateHash];
|
||||||
if (pipeline)
|
if (pipeline)
|
||||||
return pipeline;
|
return pipeline;
|
||||||
@ -364,7 +373,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
debug_printf("no vertex function, skipping draw\n");
|
debug_printf("no vertex function, skipping draw\n");
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
mtlPixelShader->CompileFragmentFunction(activeFBO);
|
mtlPixelShader->CompileFragmentFunction(lastUsedFBO);
|
||||||
|
|
||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::RenderPipelineDescriptor* desc = MTL::RenderPipelineDescriptor::alloc()->init();
|
MTL::RenderPipelineDescriptor* desc = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
@ -373,7 +382,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
// TODO: don't always set the vertex descriptor?
|
// TODO: don't always set the vertex descriptor?
|
||||||
desc->setVertexDescriptor(vertexDescriptor);
|
desc->setVertexDescriptor(vertexDescriptor);
|
||||||
|
|
||||||
SetFragmentState(desc, activeFBO, lcr);
|
SetFragmentState(desc, lastUsedFBO, activeFBO, lcr);
|
||||||
|
|
||||||
TryLoadBinaryArchive();
|
TryLoadBinaryArchive();
|
||||||
|
|
||||||
@ -440,15 +449,15 @@ MTL::RenderPipelineState* MetalPipelineCache::GetRenderPipelineState(const Latte
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTL::RenderPipelineState* MetalPipelineCache::GetMeshPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, CachedFBOMtl* activeFBO, const LatteContextRegister& lcr, Renderer::INDEX_TYPE hostIndexType)
|
MTL::RenderPipelineState* MetalPipelineCache::GetMeshPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, CachedFBOMtl* lastUsedFBO, CachedFBOMtl* activeFBO, const LatteContextRegister& lcr, Renderer::INDEX_TYPE hostIndexType)
|
||||||
{
|
{
|
||||||
uint64 stateHash = CalculateRenderPipelineHash(fetchShader, vertexShader, pixelShader, activeFBO, lcr);
|
uint64 stateHash = CalculateRenderPipelineHash(fetchShader, vertexShader, pixelShader, lastUsedFBO, lcr);
|
||||||
|
|
||||||
stateHash += lcr.GetRawView()[mmVGT_PRIMITIVE_TYPE];
|
stateHash += lcr.GetRawView()[mmVGT_PRIMITIVE_TYPE];
|
||||||
stateHash = std::rotl<uint64>(stateHash, 7);
|
stateHash = std::rotl<uint64>(stateHash, 7);
|
||||||
|
|
||||||
stateHash += (uint8)hostIndexType;
|
stateHash += (uint8)hostIndexType;
|
||||||
stateHash = std::rotl<uint64>(stateHash, 7); // TODO: 7?s
|
stateHash = std::rotl<uint64>(stateHash, 7);
|
||||||
|
|
||||||
auto& pipeline = m_pipelineCache[stateHash];
|
auto& pipeline = m_pipelineCache[stateHash];
|
||||||
if (pipeline)
|
if (pipeline)
|
||||||
@ -467,7 +476,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetMeshPipelineState(const LatteFe
|
|||||||
}
|
}
|
||||||
auto mtlPixelShader = static_cast<RendererShaderMtl*>(pixelShader->shader);
|
auto mtlPixelShader = static_cast<RendererShaderMtl*>(pixelShader->shader);
|
||||||
mtlObjectShader->CompileObjectFunction(lcr, fetchShader, vertexShader, hostIndexType);
|
mtlObjectShader->CompileObjectFunction(lcr, fetchShader, vertexShader, hostIndexType);
|
||||||
mtlPixelShader->CompileFragmentFunction(activeFBO);
|
mtlPixelShader->CompileFragmentFunction(lastUsedFBO);
|
||||||
|
|
||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::MeshRenderPipelineDescriptor* desc = MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
MTL::MeshRenderPipelineDescriptor* desc = MTL::MeshRenderPipelineDescriptor::alloc()->init();
|
||||||
@ -475,7 +484,7 @@ MTL::RenderPipelineState* MetalPipelineCache::GetMeshPipelineState(const LatteFe
|
|||||||
desc->setMeshFunction(mtlMeshShader->GetFunction());
|
desc->setMeshFunction(mtlMeshShader->GetFunction());
|
||||||
desc->setFragmentFunction(mtlPixelShader->GetFunction());
|
desc->setFragmentFunction(mtlPixelShader->GetFunction());
|
||||||
|
|
||||||
SetFragmentState(desc, activeFBO, lcr);
|
SetFragmentState(desc, lastUsedFBO, activeFBO, lcr);
|
||||||
|
|
||||||
TryLoadBinaryArchive();
|
TryLoadBinaryArchive();
|
||||||
|
|
||||||
@ -498,13 +507,13 @@ MTL::RenderPipelineState* MetalPipelineCache::GetMeshPipelineState(const LatteFe
|
|||||||
return pipeline;
|
return pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint64 MetalPipelineCache::CalculateRenderPipelineHash(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr)
|
uint64 MetalPipelineCache::CalculateRenderPipelineHash(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* lastUsedFBO, const LatteContextRegister& lcr)
|
||||||
{
|
{
|
||||||
// Hash
|
// Hash
|
||||||
uint64 stateHash = 0;
|
uint64 stateHash = 0;
|
||||||
for (int i = 0; i < Latte::GPU_LIMITS::NUM_COLOR_ATTACHMENTS; ++i)
|
for (int i = 0; i < Latte::GPU_LIMITS::NUM_COLOR_ATTACHMENTS; ++i)
|
||||||
{
|
{
|
||||||
auto textureView = static_cast<LatteTextureViewMtl*>(activeFBO->colorBuffer[i].texture);
|
auto textureView = static_cast<LatteTextureViewMtl*>(lastUsedFBO->colorBuffer[i].texture);
|
||||||
if (!textureView)
|
if (!textureView)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -512,9 +521,9 @@ uint64 MetalPipelineCache::CalculateRenderPipelineHash(const LatteFetchShader* f
|
|||||||
stateHash = std::rotl<uint64>(stateHash, 7);
|
stateHash = std::rotl<uint64>(stateHash, 7);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (activeFBO->depthBuffer.texture)
|
if (lastUsedFBO->depthBuffer.texture)
|
||||||
{
|
{
|
||||||
auto textureView = static_cast<LatteTextureViewMtl*>(activeFBO->depthBuffer.texture);
|
auto textureView = static_cast<LatteTextureViewMtl*>(lastUsedFBO->depthBuffer.texture);
|
||||||
stateHash += textureView->GetRGBAView()->pixelFormat();
|
stateHash += textureView->GetRGBAView()->pixelFormat();
|
||||||
stateHash = std::rotl<uint64>(stateHash, 7);
|
stateHash = std::rotl<uint64>(stateHash, 7);
|
||||||
}
|
}
|
||||||
|
@ -16,9 +16,9 @@ public:
|
|||||||
MetalPipelineCache(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {}
|
MetalPipelineCache(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {}
|
||||||
~MetalPipelineCache();
|
~MetalPipelineCache();
|
||||||
|
|
||||||
MTL::RenderPipelineState* GetRenderPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr);
|
MTL::RenderPipelineState* GetRenderPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* lastUsedFBO, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr);
|
||||||
|
|
||||||
MTL::RenderPipelineState* GetMeshPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr, Renderer::INDEX_TYPE hostIndexType);
|
MTL::RenderPipelineState* GetMeshPipelineState(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* geometryShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* lastUsedFBO, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr, Renderer::INDEX_TYPE hostIndexType);
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
size_t GetPipelineCacheSize() const { return m_pipelineCache.size(); }
|
size_t GetPipelineCacheSize() const { return m_pipelineCache.size(); }
|
||||||
@ -31,7 +31,7 @@ private:
|
|||||||
NS::URL* m_binaryArchiveURL;
|
NS::URL* m_binaryArchiveURL;
|
||||||
MTL::BinaryArchive* m_binaryArchive;
|
MTL::BinaryArchive* m_binaryArchive;
|
||||||
|
|
||||||
uint64 CalculateRenderPipelineHash(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* activeFBO, const LatteContextRegister& lcr);
|
uint64 CalculateRenderPipelineHash(const LatteFetchShader* fetchShader, const LatteDecompilerShader* vertexShader, const LatteDecompilerShader* pixelShader, class CachedFBOMtl* lastUsedFBO, const LatteContextRegister& lcr);
|
||||||
|
|
||||||
void TryLoadBinaryArchive();
|
void TryLoadBinaryArchive();
|
||||||
};
|
};
|
||||||
|
@ -1145,9 +1145,9 @@ void MetalRenderer::draw_execute(uint32 baseVertex, uint32 baseInstance, uint32
|
|||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::RenderPipelineState* renderPipelineState;
|
MTL::RenderPipelineState* renderPipelineState;
|
||||||
if (usesGeometryShader)
|
if (usesGeometryShader)
|
||||||
renderPipelineState = m_pipelineCache->GetMeshPipelineState(fetchShader, vertexShader, geometryShader, pixelShader, m_state.m_lastUsedFBO, LatteGPUState.contextNew, hostIndexType);
|
renderPipelineState = m_pipelineCache->GetMeshPipelineState(fetchShader, vertexShader, geometryShader, pixelShader, m_state.m_lastUsedFBO, m_state.m_activeFBO, LatteGPUState.contextNew, hostIndexType);
|
||||||
else
|
else
|
||||||
renderPipelineState = m_pipelineCache->GetRenderPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_lastUsedFBO, LatteGPUState.contextNew);
|
renderPipelineState = m_pipelineCache->GetRenderPipelineState(fetchShader, vertexShader, pixelShader, m_state.m_lastUsedFBO, m_state.m_activeFBO, LatteGPUState.contextNew);
|
||||||
|
|
||||||
// HACK
|
// HACK
|
||||||
if (!renderPipelineState)
|
if (!renderPipelineState)
|
||||||
|
Loading…
Reference in New Issue
Block a user