mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-03 06:24:18 +01:00
make a workaround for streamout with no fbo
This commit is contained in:
parent
2961151f25
commit
358567ad4a
@ -7,6 +7,7 @@ CachedFBOMtl::CachedFBOMtl(class MetalRenderer* metalRenderer, uint64 key) : Lat
|
|||||||
{
|
{
|
||||||
m_renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
m_renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
|
|
||||||
|
bool hasAttachment = false;
|
||||||
for (int i = 0; i < 8; ++i)
|
for (int i = 0; i < 8; ++i)
|
||||||
{
|
{
|
||||||
const auto& buffer = colorBuffer[i];
|
const auto& buffer = colorBuffer[i];
|
||||||
@ -19,6 +20,8 @@ CachedFBOMtl::CachedFBOMtl(class MetalRenderer* metalRenderer, uint64 key) : Lat
|
|||||||
colorAttachment->setTexture(textureView->GetRGBAView());
|
colorAttachment->setTexture(textureView->GetRGBAView());
|
||||||
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
|
hasAttachment = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// setup depth attachment
|
// setup depth attachment
|
||||||
@ -38,6 +41,17 @@ CachedFBOMtl::CachedFBOMtl(class MetalRenderer* metalRenderer, uint64 key) : Lat
|
|||||||
stencilAttachment->setLoadAction(MTL::LoadActionLoad);
|
stencilAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||||
stencilAttachment->setStoreAction(MTL::StoreActionStore);
|
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
|
// Visibility buffer
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
||||||
#include "Cafe/HW/Latte/ISA/RegDefines.h"
|
#include "Cafe/HW/Latte/ISA/RegDefines.h"
|
||||||
#include "Cemu/Logging/CemuLogging.h"
|
#include "Cemu/Logging/CemuLogging.h"
|
||||||
|
#include "HW/Latte/Core/LatteConst.h"
|
||||||
#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)
|
||||||
@ -206,20 +207,21 @@ void SetFragmentState(T* desc, CachedFBOMtl* lastUsedFBO, CachedFBOMtl* activeFB
|
|||||||
if (cullFront && cullBack)
|
if (cullFront && cullBack)
|
||||||
rasterizationEnabled = false;
|
rasterizationEnabled = false;
|
||||||
|
|
||||||
if (!rasterizationEnabled)
|
auto pixelShaderMtl = static_cast<RendererShaderMtl*>(pixelShader->shader);
|
||||||
|
|
||||||
|
if (!rasterizationEnabled || !pixelShaderMtl)
|
||||||
{
|
{
|
||||||
desc->setRasterizationEnabled(false);
|
desc->setRasterizationEnabled(false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto pixelShaderMtl = static_cast<RendererShaderMtl*>(pixelShader->shader);
|
desc->setFragmentFunction(pixelShaderMtl->GetFunction());
|
||||||
desc->setFragmentFunction(pixelShaderMtl->GetFunction());
|
|
||||||
|
|
||||||
// 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;
|
||||||
uint32 blendEnableMask = colorControlReg.get_BLEND_MASK();
|
uint32 blendEnableMask = colorControlReg.get_BLEND_MASK();
|
||||||
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 < LATTE_NUM_COLOR_TARGET; i++)
|
||||||
{
|
{
|
||||||
const auto& colorBuffer = lastUsedFBO->colorBuffer[i];
|
const auto& colorBuffer = lastUsedFBO->colorBuffer[i];
|
||||||
auto texture = static_cast<LatteTextureViewMtl*>(colorBuffer.texture);
|
auto texture = static_cast<LatteTextureViewMtl*>(colorBuffer.texture);
|
||||||
|
@ -863,7 +863,6 @@ void MetalRenderer::draw_beginSequence()
|
|||||||
return; // no render target
|
return; // no render target
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: not checking for !streamoutEnable fixes Super Smash Bros. for Wii U, investigate why
|
|
||||||
if (!hasValidFramebufferAttached && !streamoutEnable)
|
if (!hasValidFramebufferAttached && !streamoutEnable)
|
||||||
{
|
{
|
||||||
debug_printf("Drawcall with no color buffer or depth buffer attached\n");
|
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();
|
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());
|
auto renderCommandEncoder = commandBuffer->renderCommandEncoder(m_state.m_activeFBO->GetRenderPassDescriptor());
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
renderCommandEncoder->setLabel(GetLabel("Render command encoder", renderCommandEncoder));
|
renderCommandEncoder->setLabel(GetLabel("Render command encoder", renderCommandEncoder));
|
||||||
@ -1487,6 +1482,10 @@ MTL::RenderCommandEncoder* MetalRenderer::GetRenderCommandEncoder(bool forceRecr
|
|||||||
m_commandEncoder = renderCommandEncoder;
|
m_commandEncoder = renderCommandEncoder;
|
||||||
m_encoderType = MetalEncoderType::Render;
|
m_encoderType = MetalEncoderType::Render;
|
||||||
|
|
||||||
|
// Update state
|
||||||
|
m_state.m_lastUsedFBO = m_state.m_activeFBO;
|
||||||
|
m_state.m_isFirstDrawInRenderPass = true;
|
||||||
|
|
||||||
ResetEncoderState();
|
ResetEncoderState();
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
@ -380,6 +380,11 @@ public:
|
|||||||
return (m_hasUnifiedMemory ? MTL::ResourceStorageModeShared : MTL::ResourceStorageModeManaged);
|
return (m_hasUnifiedMemory ? MTL::ResourceStorageModeShared : MTL::ResourceStorageModeManaged);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTL::Texture* GetNullTexture2D() const
|
||||||
|
{
|
||||||
|
return m_nullTexture2D;
|
||||||
|
}
|
||||||
|
|
||||||
MTL::Buffer* GetTextureReadbackBuffer()
|
MTL::Buffer* GetTextureReadbackBuffer()
|
||||||
{
|
{
|
||||||
if (!m_readbackBuffer)
|
if (!m_readbackBuffer)
|
||||||
|
Loading…
Reference in New Issue
Block a user