make a workaround for streamout with no fbo

This commit is contained in:
Samuliak 2024-09-14 22:06:30 +02:00
parent 2961151f25
commit 358567ad4a
4 changed files with 29 additions and 9 deletions

View File

@ -7,6 +7,7 @@ CachedFBOMtl::CachedFBOMtl(class MetalRenderer* metalRenderer, uint64 key) : Lat
{
m_renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
bool hasAttachment = false;
for (int i = 0; i < 8; ++i)
{
const auto& buffer = colorBuffer[i];
@ -19,6 +20,8 @@ CachedFBOMtl::CachedFBOMtl(class MetalRenderer* metalRenderer, uint64 key) : Lat
colorAttachment->setTexture(textureView->GetRGBAView());
colorAttachment->setLoadAction(MTL::LoadActionLoad);
colorAttachment->setStoreAction(MTL::StoreActionStore);
hasAttachment = true;
}
// setup depth attachment
@ -38,6 +41,17 @@ CachedFBOMtl::CachedFBOMtl(class MetalRenderer* metalRenderer, uint64 key) : Lat
stencilAttachment->setLoadAction(MTL::LoadActionLoad);
stencilAttachment->setStoreAction(MTL::StoreActionStore);
}
hasAttachment = true;
}
// HACK: setup a dummy color attachment to prevent Metal from discarding draws for stremout draws in Super Smash Bros. for Wii U (works fine on MoltenVK without this hack though)
if (!hasAttachment)
{
auto colorAttachment = m_renderPassDescriptor->colorAttachments()->object(0);
colorAttachment->setTexture(metalRenderer->GetNullTexture2D());
colorAttachment->setLoadAction(MTL::LoadActionDontCare);
colorAttachment->setStoreAction(MTL::StoreActionDontCare);
}
// Visibility buffer

View File

@ -10,6 +10,7 @@
#include "Cafe/HW/Latte/Core/FetchShader.h"
#include "Cafe/HW/Latte/ISA/RegDefines.h"
#include "Cemu/Logging/CemuLogging.h"
#include "HW/Latte/Core/LatteConst.h"
#include "config/ActiveSettings.h"
static void rectsEmulationGS_outputSingleVertex(std::string& gsSrc, const LatteDecompilerShader* vertexShader, LatteShaderPSInputTable* psInputTable, sint32 vIdx, const LatteContextRegister& latteRegister)
@ -206,20 +207,21 @@ void SetFragmentState(T* desc, CachedFBOMtl* lastUsedFBO, CachedFBOMtl* activeFB
if (cullFront && cullBack)
rasterizationEnabled = false;
if (!rasterizationEnabled)
auto pixelShaderMtl = static_cast<RendererShaderMtl*>(pixelShader->shader);
if (!rasterizationEnabled || !pixelShaderMtl)
{
desc->setRasterizationEnabled(false);
return;
}
auto pixelShaderMtl = static_cast<RendererShaderMtl*>(pixelShader->shader);
desc->setFragmentFunction(pixelShaderMtl->GetFunction());
desc->setFragmentFunction(pixelShaderMtl->GetFunction());
// Color attachments
const Latte::LATTE_CB_COLOR_CONTROL& colorControlReg = lcr.CB_COLOR_CONTROL;
uint32 blendEnableMask = colorControlReg.get_BLEND_MASK();
uint32 renderTargetMask = lcr.CB_TARGET_MASK.get_MASK();
for (uint8 i = 0; i < 8; i++)
for (uint8 i = 0; i < LATTE_NUM_COLOR_TARGET; i++)
{
const auto& colorBuffer = lastUsedFBO->colorBuffer[i];
auto texture = static_cast<LatteTextureViewMtl*>(colorBuffer.texture);

View File

@ -863,7 +863,6 @@ void MetalRenderer::draw_beginSequence()
return; // no render target
}
// TODO: not checking for !streamoutEnable fixes Super Smash Bros. for Wii U, investigate why
if (!hasValidFramebufferAttached && !streamoutEnable)
{
debug_printf("Drawcall with no color buffer or depth buffer attached\n");
@ -1476,10 +1475,6 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecr
auto commandBuffer = GetCommandBuffer();
// Update state
m_state.m_lastUsedFBO = m_state.m_activeFBO;
m_state.m_isFirstDrawInRenderPass = true;
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(m_state.m_activeFBO->GetRenderPassDescriptor());
#ifdef CEMU_DEBUG_ASSERT
renderCommandEncoder->setLabel(GetLabel("Render command encoder", renderCommandEncoder));
@ -1487,6 +1482,10 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecr
m_commandEncoder = renderCommandEncoder;
m_encoderType = MetalEncoderType::Render;
// Update state
m_state.m_lastUsedFBO = m_state.m_activeFBO;
m_state.m_isFirstDrawInRenderPass = true;
ResetEncoderState();
// Debug

View File

@ -380,6 +380,11 @@ public:
return (m_hasUnifiedMemory ? MTL::ResourceStorageModeShared : MTL::ResourceStorageModeManaged);
}
MTL::Texture* GetNullTexture2D() const
{
return m_nullTexture2D;
}
MTL::Buffer* GetTextureReadbackBuffer()
{
if (!m_readbackBuffer)