mirror of
https://github.com/cemu-project/Cemu.git
synced 2024-12-01 13:34:18 +01:00
cache output shaders
This commit is contained in:
parent
b088ddcfab
commit
28e553eb1a
@ -558,6 +558,8 @@ if(ENABLE_METAL)
|
||||
HW/Latte/Renderer/Metal/MetalBufferAllocator.h
|
||||
HW/Latte/Renderer/Metal/MetalMemoryManager.cpp
|
||||
HW/Latte/Renderer/Metal/MetalMemoryManager.h
|
||||
HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp
|
||||
HW/Latte/Renderer/Metal/MetalOutputShaderCache.h
|
||||
HW/Latte/Renderer/Metal/MetalPipelineCache.cpp
|
||||
HW/Latte/Renderer/Metal/MetalPipelineCache.h
|
||||
HW/Latte/Renderer/Metal/MetalDepthStencilCache.cpp
|
||||
|
38
src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp
Normal file
38
src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h"
|
||||
|
||||
MetalOutputShaderCache::~MetalOutputShaderCache()
|
||||
{
|
||||
for (uint8 i = 0; i < METAL_OUTPUT_SHADER_CACHE_SIZE; i++)
|
||||
{
|
||||
if (m_cache[i])
|
||||
m_cache[i]->release();
|
||||
}
|
||||
}
|
||||
|
||||
MTL::RenderPipelineState* MetalOutputShaderCache::GetPipeline(RendererOutputShader* shader, uint8 shaderIndex, bool usesSRGB)
|
||||
{
|
||||
uint8 cacheIndex = (usesSRGB ? METAL_SHADER_TYPE_COUNT : 0) + shaderIndex;
|
||||
auto& renderPipelineState = m_cache[cacheIndex];
|
||||
if (renderPipelineState)
|
||||
return renderPipelineState;
|
||||
|
||||
// Create a new render pipeline state
|
||||
auto vertexShaderMtl = static_cast<RendererShaderMtl*>(shader->GetVertexShader())->GetFunction();
|
||||
auto fragmentShaderMtl = static_cast<RendererShaderMtl*>(shader->GetFragmentShader())->GetFunction();
|
||||
|
||||
auto renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
renderPipelineDescriptor->setVertexFunction(vertexShaderMtl);
|
||||
renderPipelineDescriptor->setFragmentFunction(fragmentShaderMtl);
|
||||
renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(usesSRGB ? MTL::PixelFormatBGRA8Unorm_sRGB : MTL::PixelFormatBGRA8Unorm);
|
||||
|
||||
NS::Error* error = nullptr;
|
||||
renderPipelineState = m_mtlr->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error);
|
||||
if (error)
|
||||
{
|
||||
cemuLog_log(LogType::Force, "error creating output render pipeline state: {}", error->localizedDescription()->utf8String());
|
||||
error->release();
|
||||
}
|
||||
|
||||
return renderPipelineState;
|
||||
}
|
20
src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h
Normal file
20
src/Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h
Normal file
@ -0,0 +1,20 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h"
|
||||
|
||||
constexpr uint8 METAL_SHADER_TYPE_COUNT = 6;
|
||||
constexpr uint8 METAL_OUTPUT_SHADER_CACHE_SIZE = 2 * METAL_SHADER_TYPE_COUNT;
|
||||
|
||||
class MetalOutputShaderCache
|
||||
{
|
||||
public:
|
||||
MetalOutputShaderCache(class MetalRenderer* metalRenderer) : m_mtlr{metalRenderer} {}
|
||||
~MetalOutputShaderCache();
|
||||
|
||||
MTL::RenderPipelineState* GetPipeline(RendererOutputShader* shader, uint8 shaderIndex, bool usesSRGB);
|
||||
|
||||
private:
|
||||
class MetalRenderer* m_mtlr;
|
||||
|
||||
MTL::RenderPipelineState* m_cache[METAL_OUTPUT_SHADER_CACHE_SIZE] = {nullptr};
|
||||
};
|
@ -4,6 +4,7 @@
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/RendererShaderMtl.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/CachedFBOMtl.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalDepthStencilCache.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalSamplerCache.h"
|
||||
@ -81,6 +82,7 @@ MetalRenderer::MetalRenderer()
|
||||
textureDescriptor->release();
|
||||
|
||||
m_memoryManager = new MetalMemoryManager(this);
|
||||
m_outputShaderCache = new MetalOutputShaderCache(this);
|
||||
m_pipelineCache = new MetalPipelineCache(this);
|
||||
m_depthStencilCache = new MetalDepthStencilCache(this);
|
||||
m_samplerCache = new MetalSamplerCache(this);
|
||||
@ -174,6 +176,7 @@ MetalRenderer::~MetalRenderer()
|
||||
m_presentPipelineLinear->release();
|
||||
m_presentPipelineSRGB->release();
|
||||
|
||||
delete m_outputShaderCache;
|
||||
delete m_pipelineCache;
|
||||
delete m_depthStencilCache;
|
||||
delete m_samplerCache;
|
||||
@ -276,7 +279,6 @@ void MetalRenderer::SwapBuffers(bool swapTV, bool swapDRC)
|
||||
m_performanceMonitor.ResetPerFrameData();
|
||||
}
|
||||
|
||||
// TODO: use `shader` for drawing
|
||||
void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutputShader* shader, bool useLinearTexFilter,
|
||||
sint32 imageX, sint32 imageY, sint32 imageWidth, sint32 imageHeight,
|
||||
bool padView, bool clearBackground)
|
||||
@ -299,21 +301,20 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
||||
renderPassDescriptor->release();
|
||||
|
||||
// Get a render pipeline
|
||||
auto vertexShaderMtl = static_cast<RendererShaderMtl*>(shader->GetVertexShader())->GetFunction();
|
||||
auto fragmentShaderMtl = static_cast<RendererShaderMtl*>(shader->GetFragmentShader())->GetFunction();
|
||||
|
||||
auto renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||
renderPipelineDescriptor->setVertexFunction(vertexShaderMtl);
|
||||
renderPipelineDescriptor->setFragmentFunction(fragmentShaderMtl);
|
||||
renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(m_state.m_usesSRGB ? MTL::PixelFormatBGRA8Unorm_sRGB : MTL::PixelFormatBGRA8Unorm);
|
||||
// Find out which shader we are using
|
||||
uint8 shaderIndex = 255;
|
||||
if (shader == RendererOutputShader::s_copy_shader) shaderIndex = 0;
|
||||
else if (shader == RendererOutputShader::s_bicubic_shader) shaderIndex = 1;
|
||||
else if (shader == RendererOutputShader::s_hermit_shader) shaderIndex = 2;
|
||||
else if (shader == RendererOutputShader::s_copy_shader_ud) shaderIndex = 3;
|
||||
else if (shader == RendererOutputShader::s_bicubic_shader_ud) shaderIndex = 4;
|
||||
else if (shader == RendererOutputShader::s_hermit_shader_ud) shaderIndex = 5;
|
||||
|
||||
NS::Error* error = nullptr;
|
||||
auto renderPipelineState = m_device->newRenderPipelineState(renderPipelineDescriptor, &error);
|
||||
if (error)
|
||||
{
|
||||
printf("AAA: %s\n", error->localizedDescription()->utf8String());
|
||||
error->release();
|
||||
}
|
||||
uint8 shaderType = shaderIndex % 3;
|
||||
|
||||
// Get the render pipeline state
|
||||
auto renderPipelineState = m_outputShaderCache->GetPipeline(shader, shaderIndex, m_state.m_usesSRGB);
|
||||
|
||||
// Draw to Metal layer
|
||||
renderCommandEncoder->setRenderPipelineState(renderPipelineState);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalLayerHandle.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h"
|
||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h"
|
||||
|
||||
struct MetalBufferAllocation
|
||||
{
|
||||
@ -460,6 +461,7 @@ private:
|
||||
|
||||
// Managers and caches
|
||||
class MetalMemoryManager* m_memoryManager;
|
||||
class MetalOutputShaderCache* m_outputShaderCache;
|
||||
class MetalPipelineCache* m_pipelineCache;
|
||||
class MetalDepthStencilCache* m_depthStencilCache;
|
||||
class MetalSamplerCache* m_samplerCache;
|
||||
|
Loading…
Reference in New Issue
Block a user