mirror of
https://github.com/cemu-project/Cemu.git
synced 2025-07-04 05:51:19 +12:00
create stack scoped helper macro
This commit is contained in:
parent
b50b9135a0
commit
14f42fc653
10 changed files with 39 additions and 64 deletions
|
@ -7,7 +7,7 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM
|
||||||
Latte::E_HWTILEMODE tileMode, bool isDepth)
|
Latte::E_HWTILEMODE tileMode, bool isDepth)
|
||||||
: LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth), m_mtlr(mtlRenderer)
|
: LatteTexture(dim, physAddress, physMipAddress, format, width, height, depth, pitch, mipLevels, swizzle, tileMode, isDepth), m_mtlr(mtlRenderer)
|
||||||
{
|
{
|
||||||
MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init();
|
||||||
desc->setStorageMode(MTL::StorageModePrivate);
|
desc->setStorageMode(MTL::StorageModePrivate);
|
||||||
//desc->setCpuCacheMode(MTL::CPUCacheModeWriteCombined);
|
//desc->setCpuCacheMode(MTL::CPUCacheModeWriteCombined);
|
||||||
|
|
||||||
|
@ -83,7 +83,6 @@ LatteTextureMtl::LatteTextureMtl(class MetalRenderer* mtlRenderer, Latte::E_DIM
|
||||||
desc->setUsage(usage);
|
desc->setUsage(usage);
|
||||||
|
|
||||||
m_texture = mtlRenderer->GetDevice()->newTexture(desc);
|
m_texture = mtlRenderer->GetDevice()->newTexture(desc);
|
||||||
desc->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LatteTextureMtl::~LatteTextureMtl()
|
LatteTextureMtl::~LatteTextureMtl()
|
||||||
|
|
|
@ -50,10 +50,12 @@ inline size_t Align(size_t size, size_t alignment)
|
||||||
return (size + alignment - 1) & ~(alignment - 1);
|
return (size + alignment - 1) & ~(alignment - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
//inline std::string GetColorAttachmentTypeStr(uint32 index)
|
__attribute__((unused)) static inline void ETStackAutoRelease(void* object)
|
||||||
//{
|
{
|
||||||
// return "COLOR_ATTACHMENT" + std::to_string(index) + "_TYPE";
|
(*(NS::Object**)object)->release();
|
||||||
//}
|
}
|
||||||
|
|
||||||
|
#define NS_STACK_SCOPED __attribute__((cleanup(ETStackAutoRelease))) __attribute__((unused))
|
||||||
|
|
||||||
// Cast from const char* to NS::String*
|
// Cast from const char* to NS::String*
|
||||||
inline NS::String* ToNSString(const char* str)
|
inline NS::String* ToNSString(const char* str)
|
||||||
|
|
|
@ -25,7 +25,7 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
|
||||||
auto depthFunc = lcr.DB_DEPTH_CONTROL.get_Z_FUNC();
|
auto depthFunc = lcr.DB_DEPTH_CONTROL.get_Z_FUNC();
|
||||||
bool depthWriteEnable = lcr.DB_DEPTH_CONTROL.get_Z_WRITE_ENABLE();
|
bool depthWriteEnable = lcr.DB_DEPTH_CONTROL.get_Z_WRITE_ENABLE();
|
||||||
|
|
||||||
MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::DepthStencilDescriptor* desc = MTL::DepthStencilDescriptor::alloc()->init();
|
||||||
if (depthEnable)
|
if (depthEnable)
|
||||||
{
|
{
|
||||||
desc->setDepthWriteEnabled(depthWriteEnable);
|
desc->setDepthWriteEnabled(depthWriteEnable);
|
||||||
|
@ -52,7 +52,7 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
|
||||||
uint32 stencilCompareMaskBack = lcr.DB_STENCILREFMASK_BF.get_STENCILMASK_B();
|
uint32 stencilCompareMaskBack = lcr.DB_STENCILREFMASK_BF.get_STENCILMASK_B();
|
||||||
uint32 stencilWriteMaskBack = lcr.DB_STENCILREFMASK_BF.get_STENCILWRITEMASK_B();
|
uint32 stencilWriteMaskBack = lcr.DB_STENCILREFMASK_BF.get_STENCILWRITEMASK_B();
|
||||||
|
|
||||||
MTL::StencilDescriptor* frontStencil = MTL::StencilDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::StencilDescriptor* frontStencil = MTL::StencilDescriptor::alloc()->init();
|
||||||
frontStencil->setReadMask(stencilCompareMaskFront);
|
frontStencil->setReadMask(stencilCompareMaskFront);
|
||||||
frontStencil->setWriteMask(stencilWriteMaskFront);
|
frontStencil->setWriteMask(stencilWriteMaskFront);
|
||||||
frontStencil->setStencilCompareFunction(GetMtlCompareFunc(frontStencilFunc));
|
frontStencil->setStencilCompareFunction(GetMtlCompareFunc(frontStencilFunc));
|
||||||
|
@ -61,7 +61,7 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
|
||||||
frontStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass));
|
frontStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass));
|
||||||
desc->setFrontFaceStencil(frontStencil);
|
desc->setFrontFaceStencil(frontStencil);
|
||||||
|
|
||||||
MTL::StencilDescriptor* backStencil = MTL::StencilDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::StencilDescriptor* backStencil = MTL::StencilDescriptor::alloc()->init();
|
||||||
if (backStencilEnable)
|
if (backStencilEnable)
|
||||||
{
|
{
|
||||||
backStencil->setReadMask(stencilCompareMaskBack);
|
backStencil->setReadMask(stencilCompareMaskBack);
|
||||||
|
@ -81,13 +81,9 @@ MTL::DepthStencilState* MetalDepthStencilCache::GetDepthStencilState(const Latte
|
||||||
backStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass));
|
backStencil->setDepthStencilPassOperation(GetMtlStencilOp(frontStencilZPass));
|
||||||
}
|
}
|
||||||
desc->setBackFaceStencil(backStencil);
|
desc->setBackFaceStencil(backStencil);
|
||||||
|
|
||||||
frontStencil->release();
|
|
||||||
backStencil->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
depthStencilState = m_mtlr->GetDevice()->newDepthStencilState(desc);
|
depthStencilState = m_mtlr->GetDevice()->newDepthStencilState(desc);
|
||||||
desc->release();
|
|
||||||
|
|
||||||
return depthStencilState;
|
return depthStencilState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,14 +21,13 @@ MTL::RenderPipelineState* MetalOutputShaderCache::GetPipeline(RendererOutputShad
|
||||||
auto vertexShaderMtl = static_cast<RendererShaderMtl*>(shader->GetVertexShader())->GetFunction();
|
auto vertexShaderMtl = static_cast<RendererShaderMtl*>(shader->GetVertexShader())->GetFunction();
|
||||||
auto fragmentShaderMtl = static_cast<RendererShaderMtl*>(shader->GetFragmentShader())->GetFunction();
|
auto fragmentShaderMtl = static_cast<RendererShaderMtl*>(shader->GetFragmentShader())->GetFunction();
|
||||||
|
|
||||||
auto renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
NS_STACK_SCOPED auto renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
renderPipelineDescriptor->setVertexFunction(vertexShaderMtl);
|
renderPipelineDescriptor->setVertexFunction(vertexShaderMtl);
|
||||||
renderPipelineDescriptor->setFragmentFunction(fragmentShaderMtl);
|
renderPipelineDescriptor->setFragmentFunction(fragmentShaderMtl);
|
||||||
renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(usesSRGB ? MTL::PixelFormatBGRA8Unorm_sRGB : MTL::PixelFormatBGRA8Unorm);
|
renderPipelineDescriptor->colorAttachments()->object(0)->setPixelFormat(usesSRGB ? MTL::PixelFormatBGRA8Unorm_sRGB : MTL::PixelFormatBGRA8Unorm);
|
||||||
|
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
renderPipelineState = m_mtlr->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error);
|
renderPipelineState = m_mtlr->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error);
|
||||||
renderPipelineDescriptor->release();
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "error creating output render pipeline state: {}", error->localizedDescription()->utf8String());
|
cemuLog_log(LogType::Force, "error creating output render pipeline state: {}", error->localizedDescription()->utf8String());
|
||||||
|
|
|
@ -413,7 +413,7 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha
|
||||||
// Vertex descriptor
|
// Vertex descriptor
|
||||||
if (!fetchShader->mtlFetchVertexManually)
|
if (!fetchShader->mtlFetchVertexManually)
|
||||||
{
|
{
|
||||||
MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::VertexDescriptor* vertexDescriptor = MTL::VertexDescriptor::alloc()->init();
|
||||||
for (auto& bufferGroup : fetchShader->bufferGroups)
|
for (auto& bufferGroup : fetchShader->bufferGroups)
|
||||||
{
|
{
|
||||||
std::optional<LatteConst::VertexFetchType2> fetchType;
|
std::optional<LatteConst::VertexFetchType2> fetchType;
|
||||||
|
@ -476,7 +476,6 @@ void MetalPipelineCompiler::InitFromStateRender(const LatteFetchShader* fetchSha
|
||||||
}
|
}
|
||||||
|
|
||||||
desc->setVertexDescriptor(vertexDescriptor);
|
desc->setVertexDescriptor(vertexDescriptor);
|
||||||
vertexDescriptor->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, m_rasterizationEnabled, lcr);
|
SetFragmentState(desc, lastUsedAttachmentsInfo, activeAttachmentsInfo, m_rasterizationEnabled, lcr);
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "Cemu/Logging/CemuLogging.h"
|
#include "Cemu/Logging/CemuLogging.h"
|
||||||
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
#include "Cafe/HW/Latte/Core/FetchShader.h"
|
||||||
#include "Cafe/HW/Latte/Core/LatteConst.h"
|
#include "Cafe/HW/Latte/Core/LatteConst.h"
|
||||||
#include "HW/Latte/Renderer/Metal/MetalBufferAllocator.h"
|
|
||||||
#include "HW/Latte/Renderer/Metal/MetalCommon.h"
|
#include "HW/Latte/Renderer/Metal/MetalCommon.h"
|
||||||
#include "config/CemuConfig.h"
|
#include "config/CemuConfig.h"
|
||||||
#include "gui/guiWrapper.h"
|
#include "gui/guiWrapper.h"
|
||||||
|
@ -41,7 +40,7 @@ void LatteDraw_handleSpecialState8_clearAsDepth();
|
||||||
|
|
||||||
std::vector<MetalRenderer::DeviceInfo> MetalRenderer::GetDevices()
|
std::vector<MetalRenderer::DeviceInfo> MetalRenderer::GetDevices()
|
||||||
{
|
{
|
||||||
auto devices = MTL::CopyAllDevices();
|
NS_STACK_SCOPED auto devices = MTL::CopyAllDevices();
|
||||||
std::vector<MetalRenderer::DeviceInfo> result;
|
std::vector<MetalRenderer::DeviceInfo> result;
|
||||||
result.reserve(devices->count());
|
result.reserve(devices->count());
|
||||||
for (uint32 i = 0; i < devices->count(); i++)
|
for (uint32 i = 0; i < devices->count(); i++)
|
||||||
|
@ -49,7 +48,6 @@ std::vector<MetalRenderer::DeviceInfo> MetalRenderer::GetDevices()
|
||||||
MTL::Device* device = static_cast<MTL::Device*>(devices->object(i));
|
MTL::Device* device = static_cast<MTL::Device*>(devices->object(i));
|
||||||
result.emplace_back(std::string(device->name()->utf8String()), device->registryID());
|
result.emplace_back(std::string(device->name()->utf8String()), device->registryID());
|
||||||
}
|
}
|
||||||
devices->release();
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -126,7 +124,7 @@ MetalRenderer::MetalRenderer()
|
||||||
// If a device is set, try to find it
|
// If a device is set, try to find it
|
||||||
if (hasDeviceSet)
|
if (hasDeviceSet)
|
||||||
{
|
{
|
||||||
auto devices = MTL::CopyAllDevices();
|
NS_STACK_SCOPED auto devices = MTL::CopyAllDevices();
|
||||||
for (uint32 i = 0; i < devices->count(); i++)
|
for (uint32 i = 0; i < devices->count(); i++)
|
||||||
{
|
{
|
||||||
MTL::Device* device = static_cast<MTL::Device*>(devices->object(i));
|
MTL::Device* device = static_cast<MTL::Device*>(devices->object(i));
|
||||||
|
@ -136,7 +134,6 @@ MetalRenderer::MetalRenderer()
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
devices->release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_device)
|
if (!m_device)
|
||||||
|
@ -167,7 +164,7 @@ MetalRenderer::MetalRenderer()
|
||||||
m_event = m_device->newEvent();
|
m_event = m_device->newEvent();
|
||||||
|
|
||||||
// Resources
|
// Resources
|
||||||
MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init();
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
samplerDescriptor->setLabel(GetLabel("Nearest sampler state", samplerDescriptor));
|
samplerDescriptor->setLabel(GetLabel("Nearest sampler state", samplerDescriptor));
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,10 +176,9 @@ MetalRenderer::MetalRenderer()
|
||||||
samplerDescriptor->setLabel(GetLabel("Linear sampler state", samplerDescriptor));
|
samplerDescriptor->setLabel(GetLabel("Linear sampler state", samplerDescriptor));
|
||||||
#endif
|
#endif
|
||||||
m_linearSampler = m_device->newSamplerState(samplerDescriptor);
|
m_linearSampler = m_device->newSamplerState(samplerDescriptor);
|
||||||
samplerDescriptor->release();
|
|
||||||
|
|
||||||
// Null resources
|
// Null resources
|
||||||
MTL::TextureDescriptor* textureDescriptor = MTL::TextureDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::TextureDescriptor* textureDescriptor = MTL::TextureDescriptor::alloc()->init();
|
||||||
textureDescriptor->setTextureType(MTL::TextureType1D);
|
textureDescriptor->setTextureType(MTL::TextureType1D);
|
||||||
textureDescriptor->setWidth(1);
|
textureDescriptor->setWidth(1);
|
||||||
textureDescriptor->setUsage(MTL::TextureUsageShaderRead);
|
textureDescriptor->setUsage(MTL::TextureUsageShaderRead);
|
||||||
|
@ -198,7 +194,6 @@ MetalRenderer::MetalRenderer()
|
||||||
#ifdef CEMU_DEBUG_ASSERT
|
#ifdef CEMU_DEBUG_ASSERT
|
||||||
m_nullTexture2D->setLabel(GetLabel("Null texture 2D", m_nullTexture2D));
|
m_nullTexture2D->setLabel(GetLabel("Null texture 2D", m_nullTexture2D));
|
||||||
#endif
|
#endif
|
||||||
textureDescriptor->release();
|
|
||||||
|
|
||||||
m_memoryManager = new MetalMemoryManager(this);
|
m_memoryManager = new MetalMemoryManager(this);
|
||||||
m_outputShaderCache = new MetalOutputShaderCache(this);
|
m_outputShaderCache = new MetalOutputShaderCache(this);
|
||||||
|
@ -233,28 +228,24 @@ MetalRenderer::MetalRenderer()
|
||||||
|
|
||||||
// Create the library
|
// Create the library
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
MTL::Library* utilityLibrary = m_device->newLibrary(ToNSString(utilityShaderSource), nullptr, &error);
|
NS_STACK_SCOPED MTL::Library* utilityLibrary = m_device->newLibrary(ToNSString(utilityShaderSource), nullptr, &error);
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "failed to create utility library (error: {})", error->localizedDescription()->utf8String());
|
cemuLog_log(LogType::Force, "failed to create utility library (error: {})", error->localizedDescription()->utf8String());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pipelines
|
// Pipelines
|
||||||
MTL::Function* vertexFullscreenFunction = utilityLibrary->newFunction(ToNSString("vertexFullscreen"));
|
NS_STACK_SCOPED MTL::Function* vertexFullscreenFunction = utilityLibrary->newFunction(ToNSString("vertexFullscreen"));
|
||||||
MTL::Function* fragmentCopyDepthToColorFunction = utilityLibrary->newFunction(ToNSString("fragmentCopyDepthToColor"));
|
NS_STACK_SCOPED MTL::Function* fragmentCopyDepthToColorFunction = utilityLibrary->newFunction(ToNSString("fragmentCopyDepthToColor"));
|
||||||
|
|
||||||
m_copyDepthToColorDesc = MTL::RenderPipelineDescriptor::alloc()->init();
|
m_copyDepthToColorDesc = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
m_copyDepthToColorDesc->setVertexFunction(vertexFullscreenFunction);
|
m_copyDepthToColorDesc->setVertexFunction(vertexFullscreenFunction);
|
||||||
m_copyDepthToColorDesc->setFragmentFunction(fragmentCopyDepthToColorFunction);
|
m_copyDepthToColorDesc->setFragmentFunction(fragmentCopyDepthToColorFunction);
|
||||||
vertexFullscreenFunction->release();
|
|
||||||
fragmentCopyDepthToColorFunction->release();
|
|
||||||
|
|
||||||
// Void vertex pipelines
|
// Void vertex pipelines
|
||||||
if (m_isAppleGPU)
|
if (m_isAppleGPU)
|
||||||
m_copyBufferToBufferPipeline = new MetalVoidVertexPipeline(this, utilityLibrary, "vertexCopyBufferToBuffer");
|
m_copyBufferToBufferPipeline = new MetalVoidVertexPipeline(this, utilityLibrary, "vertexCopyBufferToBuffer");
|
||||||
|
|
||||||
utilityLibrary->release();
|
|
||||||
|
|
||||||
// HACK: for some reason, this variable ends up being initialized to some garbage data, even though its declared as bool m_captureFrame = false;
|
// HACK: for some reason, this variable ends up being initialized to some garbage data, even though its declared as bool m_captureFrame = false;
|
||||||
m_occlusionQuery.m_lastCommandBuffer = nullptr;
|
m_occlusionQuery.m_lastCommandBuffer = nullptr;
|
||||||
m_captureFrame = false;
|
m_captureFrame = false;
|
||||||
|
@ -414,13 +405,12 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV
|
||||||
uint32 bytesPerRow = GetMtlTextureBytesPerRow(texMtl->format, texMtl->isDepth, width);
|
uint32 bytesPerRow = GetMtlTextureBytesPerRow(texMtl->format, texMtl->isDepth, width);
|
||||||
uint32 size = GetMtlTextureBytesPerImage(texMtl->format, texMtl->isDepth, height, bytesPerRow);
|
uint32 size = GetMtlTextureBytesPerImage(texMtl->format, texMtl->isDepth, height, bytesPerRow);
|
||||||
|
|
||||||
// TODO: get a buffer from the memory manager
|
|
||||||
MTL::Buffer* buffer = m_device->newBuffer(size, MTL::ResourceStorageModeShared);
|
|
||||||
|
|
||||||
auto blitCommandEncoder = GetBlitCommandEncoder();
|
auto blitCommandEncoder = GetBlitCommandEncoder();
|
||||||
blitCommandEncoder->copyFromTexture(texMtl->GetTexture(), 0, 0, MTL::Origin(0, 0, 0), MTL::Size(width, height, 1), buffer, 0, bytesPerRow, 0);
|
|
||||||
|
|
||||||
uint8* bufferPtr = (uint8*)buffer->contents();
|
auto& bufferAllocator = m_memoryManager->GetStagingAllocator();
|
||||||
|
auto buffer = bufferAllocator.AllocateBufferMemory(size, 1);
|
||||||
|
|
||||||
|
blitCommandEncoder->copyFromTexture(texMtl->GetTexture(), 0, 0, MTL::Origin(0, 0, 0), MTL::Size(width, height, 1), buffer.mtlBuffer, buffer.bufferOffset, bytesPerRow, 0);
|
||||||
|
|
||||||
bool formatValid = true;
|
bool formatValid = true;
|
||||||
std::vector<uint8> rgb_data;
|
std::vector<uint8> rgb_data;
|
||||||
|
@ -431,7 +421,7 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV
|
||||||
switch (pixelFormat)
|
switch (pixelFormat)
|
||||||
{
|
{
|
||||||
case MTL::PixelFormatRGBA8Unorm:
|
case MTL::PixelFormatRGBA8Unorm:
|
||||||
for (auto ptr = bufferPtr; ptr < bufferPtr + size; ptr += 4)
|
for (auto ptr = buffer.memPtr; ptr < buffer.memPtr + size; ptr += 4)
|
||||||
{
|
{
|
||||||
rgb_data.emplace_back(*ptr);
|
rgb_data.emplace_back(*ptr);
|
||||||
rgb_data.emplace_back(*(ptr + 1));
|
rgb_data.emplace_back(*(ptr + 1));
|
||||||
|
@ -439,7 +429,7 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MTL::PixelFormatRGBA8Unorm_sRGB:
|
case MTL::PixelFormatRGBA8Unorm_sRGB:
|
||||||
for (auto ptr = bufferPtr; ptr < bufferPtr + size; ptr += 4)
|
for (auto ptr = buffer.memPtr; ptr < buffer.memPtr + size; ptr += 4)
|
||||||
{
|
{
|
||||||
rgb_data.emplace_back(SRGBComponentToRGB(*ptr));
|
rgb_data.emplace_back(SRGBComponentToRGB(*ptr));
|
||||||
rgb_data.emplace_back(SRGBComponentToRGB(*(ptr + 1)));
|
rgb_data.emplace_back(SRGBComponentToRGB(*(ptr + 1)));
|
||||||
|
@ -452,8 +442,6 @@ void MetalRenderer::HandleScreenshotRequest(LatteTextureView* texView, bool padV
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer->release();
|
|
||||||
|
|
||||||
if (formatValid)
|
if (formatValid)
|
||||||
SaveScreenshot(rgb_data, width, height, !padView);
|
SaveScreenshot(rgb_data, width, height, !padView);
|
||||||
}
|
}
|
||||||
|
@ -470,14 +458,13 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
|
||||||
// Create render pass
|
// Create render pass
|
||||||
auto& layer = GetLayer(!padView);
|
auto& layer = GetLayer(!padView);
|
||||||
|
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||||
colorAttachment->setTexture(layer.GetDrawable()->texture());
|
colorAttachment->setTexture(layer.GetDrawable()->texture());
|
||||||
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionLoad);
|
colorAttachment->setLoadAction(clearBackground ? MTL::LoadActionClear : MTL::LoadActionLoad);
|
||||||
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
colorAttachment->setStoreAction(MTL::StoreActionStore);
|
||||||
|
|
||||||
auto renderCommandEncoder = GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
auto renderCommandEncoder = GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
renderPassDescriptor->release();
|
|
||||||
|
|
||||||
// Get a render pipeline
|
// Get a render pipeline
|
||||||
|
|
||||||
|
@ -557,7 +544,7 @@ bool MetalRenderer::ImguiBegin(bool mainWindow)
|
||||||
auto& layer = GetLayer(mainWindow);
|
auto& layer = GetLayer(mainWindow);
|
||||||
|
|
||||||
// Render pass descriptor
|
// Render pass descriptor
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||||
colorAttachment->setTexture(layer.GetDrawable()->texture());
|
colorAttachment->setTexture(layer.GetDrawable()->texture());
|
||||||
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
colorAttachment->setLoadAction(MTL::LoadActionLoad);
|
||||||
|
@ -570,7 +557,6 @@ bool MetalRenderer::ImguiBegin(bool mainWindow)
|
||||||
|
|
||||||
if (m_encoderType != MetalEncoderType::Render)
|
if (m_encoderType != MetalEncoderType::Render)
|
||||||
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
renderPassDescriptor->release();
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -605,7 +591,7 @@ ImTextureID MetalRenderer::GenerateTexture(const std::vector<uint8>& data, const
|
||||||
tmp[(i * 4) + 3] = 0xFF;
|
tmp[(i * 4) + 3] = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::TextureDescriptor* desc = MTL::TextureDescriptor::alloc()->init();
|
||||||
desc->setTextureType(MTL::TextureType2D);
|
desc->setTextureType(MTL::TextureType2D);
|
||||||
desc->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
desc->setPixelFormat(MTL::PixelFormatRGBA8Unorm);
|
||||||
desc->setWidth(size.x);
|
desc->setWidth(size.x);
|
||||||
|
@ -614,7 +600,6 @@ ImTextureID MetalRenderer::GenerateTexture(const std::vector<uint8>& data, const
|
||||||
desc->setUsage(MTL::TextureUsageShaderRead);
|
desc->setUsage(MTL::TextureUsageShaderRead);
|
||||||
|
|
||||||
MTL::Texture* texture = m_device->newTexture(desc);
|
MTL::Texture* texture = m_device->newTexture(desc);
|
||||||
desc->release();
|
|
||||||
|
|
||||||
// TODO: do a GPU copy?
|
// TODO: do a GPU copy?
|
||||||
texture->replaceRegion(MTL::Region(0, 0, size.x, size.y), 0, 0, tmp.data(), size.x * 4, 0);
|
texture->replaceRegion(MTL::Region(0, 0, size.x, size.y), 0, 0, tmp.data(), size.x * 4, 0);
|
||||||
|
@ -768,11 +753,8 @@ void MetalRenderer::texture_loadSlice(LatteTexture* hostTexture, sint32 width, s
|
||||||
// Allocate a temporary buffer
|
// Allocate a temporary buffer
|
||||||
auto& bufferAllocator = m_memoryManager->GetStagingAllocator();
|
auto& bufferAllocator = m_memoryManager->GetStagingAllocator();
|
||||||
auto allocation = bufferAllocator.AllocateBufferMemory(compressedImageSize, 1);
|
auto allocation = bufferAllocator.AllocateBufferMemory(compressedImageSize, 1);
|
||||||
bufferAllocator.FlushReservation(allocation);
|
|
||||||
|
|
||||||
// Copy the data to the temporary buffer
|
|
||||||
memcpy(allocation.memPtr, pixelData, compressedImageSize);
|
memcpy(allocation.memPtr, pixelData, compressedImageSize);
|
||||||
//buffer->didModifyRange(NS::Range(allocation.offset, allocation.size));
|
bufferAllocator.FlushReservation(allocation);
|
||||||
|
|
||||||
// TODO: specify blit options when copying to a depth stencil texture?
|
// TODO: specify blit options when copying to a depth stencil texture?
|
||||||
// Copy the data from the temporary buffer to the texture
|
// Copy the data from the temporary buffer to the texture
|
||||||
|
@ -804,7 +786,7 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
|
||||||
|
|
||||||
auto mtlTexture = static_cast<LatteTextureMtl*>(hostTexture)->GetTexture();
|
auto mtlTexture = static_cast<LatteTextureMtl*>(hostTexture)->GetTexture();
|
||||||
|
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
if (clearDepth)
|
if (clearDepth)
|
||||||
{
|
{
|
||||||
auto depthAttachment = renderPassDescriptor->depthAttachment();
|
auto depthAttachment = renderPassDescriptor->depthAttachment();
|
||||||
|
@ -827,7 +809,6 @@ void MetalRenderer::texture_clearDepthSlice(LatteTexture* hostTexture, uint32 sl
|
||||||
}
|
}
|
||||||
|
|
||||||
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
renderPassDescriptor->release();
|
|
||||||
EndEncoding();
|
EndEncoding();
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
@ -2195,7 +2176,7 @@ void MetalRenderer::BindStageResources(MTL::RenderCommandEncoder* renderCommandE
|
||||||
|
|
||||||
void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a)
|
void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a)
|
||||||
{
|
{
|
||||||
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc()->init();
|
||||||
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
auto colorAttachment = renderPassDescriptor->colorAttachments()->object(0);
|
||||||
colorAttachment->setTexture(mtlTexture);
|
colorAttachment->setTexture(mtlTexture);
|
||||||
colorAttachment->setClearColor(MTL::ClearColor(r, g, b, a));
|
colorAttachment->setClearColor(MTL::ClearColor(r, g, b, a));
|
||||||
|
@ -2205,7 +2186,6 @@ void MetalRenderer::ClearColorTextureInternal(MTL::Texture* mtlTexture, sint32 s
|
||||||
colorAttachment->setLevel(mipIndex);
|
colorAttachment->setLevel(mipIndex);
|
||||||
|
|
||||||
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
GetTemporaryRenderCommandEncoder(renderPassDescriptor);
|
||||||
renderPassDescriptor->release();
|
|
||||||
EndEncoding();
|
EndEncoding();
|
||||||
|
|
||||||
// Debug
|
// Debug
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalPerformanceMonitor.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalOutputShaderCache.h"
|
||||||
#include "Cafe/HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h"
|
#include "Cafe/HW/Latte/Renderer/Metal/MetalAttachmentsInfo.h"
|
||||||
|
#include "Foundation/NSAutoreleasePool.hpp"
|
||||||
|
|
||||||
enum MetalGeneralShaderType
|
enum MetalGeneralShaderType
|
||||||
{
|
{
|
||||||
|
@ -527,6 +528,9 @@ private:
|
||||||
MTL::CommandBuffer* m_lastCommandBuffer = nullptr;
|
MTL::CommandBuffer* m_lastCommandBuffer = nullptr;
|
||||||
} m_occlusionQuery;
|
} m_occlusionQuery;
|
||||||
|
|
||||||
|
// Autorelease pool
|
||||||
|
NS::AutoreleasePool* m_autoreleasePool;
|
||||||
|
|
||||||
// Active objects
|
// Active objects
|
||||||
MetalCommandBuffer m_currentCommandBuffer{};
|
MetalCommandBuffer m_currentCommandBuffer{};
|
||||||
std::vector<MTL::CommandBuffer*> m_executingCommandBuffers;
|
std::vector<MTL::CommandBuffer*> m_executingCommandBuffers;
|
||||||
|
|
|
@ -21,7 +21,7 @@ MTL::SamplerState* MetalSamplerCache::GetSamplerState(const LatteContextRegister
|
||||||
// Sampler state
|
// Sampler state
|
||||||
const _LatteRegisterSetSampler* samplerWords = lcr.SQ_TEX_SAMPLER + samplerIndex;
|
const _LatteRegisterSetSampler* samplerWords = lcr.SQ_TEX_SAMPLER + samplerIndex;
|
||||||
|
|
||||||
MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init();
|
||||||
|
|
||||||
// lod
|
// lod
|
||||||
uint32 iMinLOD = samplerWords->WORD1.get_MIN_LOD();
|
uint32 iMinLOD = samplerWords->WORD1.get_MIN_LOD();
|
||||||
|
@ -115,7 +115,6 @@ MTL::SamplerState* MetalSamplerCache::GetSamplerState(const LatteContextRegister
|
||||||
}
|
}
|
||||||
|
|
||||||
samplerState = m_mtlr->GetDevice()->newSamplerState(samplerDescriptor);
|
samplerState = m_mtlr->GetDevice()->newSamplerState(samplerDescriptor);
|
||||||
samplerDescriptor->release();
|
|
||||||
|
|
||||||
return samplerState;
|
return samplerState;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,14 @@
|
||||||
MetalVoidVertexPipeline::MetalVoidVertexPipeline(class MetalRenderer* mtlRenderer, MTL::Library* library, const std::string& vertexFunctionName)
|
MetalVoidVertexPipeline::MetalVoidVertexPipeline(class MetalRenderer* mtlRenderer, MTL::Library* library, const std::string& vertexFunctionName)
|
||||||
{
|
{
|
||||||
// Render pipeline state
|
// Render pipeline state
|
||||||
MTL::Function* vertexFunction = library->newFunction(ToNSString(vertexFunctionName));
|
NS_STACK_SCOPED MTL::Function* vertexFunction = library->newFunction(ToNSString(vertexFunctionName));
|
||||||
|
|
||||||
MTL::RenderPipelineDescriptor* renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
NS_STACK_SCOPED MTL::RenderPipelineDescriptor* renderPipelineDescriptor = MTL::RenderPipelineDescriptor::alloc()->init();
|
||||||
renderPipelineDescriptor->setVertexFunction(vertexFunction);
|
renderPipelineDescriptor->setVertexFunction(vertexFunction);
|
||||||
renderPipelineDescriptor->setRasterizationEnabled(false);
|
renderPipelineDescriptor->setRasterizationEnabled(false);
|
||||||
|
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
m_renderPipelineState = mtlRenderer->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error);
|
m_renderPipelineState = mtlRenderer->GetDevice()->newRenderPipelineState(renderPipelineDescriptor, &error);
|
||||||
renderPipelineDescriptor->release();
|
|
||||||
vertexFunction->release();
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "error creating hybrid render pipeline state: {}", error->localizedDescription()->utf8String());
|
cemuLog_log(LogType::Force, "error creating hybrid render pipeline state: {}", error->localizedDescription()->utf8String());
|
||||||
|
|
|
@ -276,7 +276,7 @@ bool RendererShaderMtl::ShouldCountCompilation() const
|
||||||
MTL::Library* RendererShaderMtl::LibraryFromSource()
|
MTL::Library* RendererShaderMtl::LibraryFromSource()
|
||||||
{
|
{
|
||||||
// Compile from source
|
// Compile from source
|
||||||
MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init();
|
NS_STACK_SCOPED MTL::CompileOptions* options = MTL::CompileOptions::alloc()->init();
|
||||||
if (g_current_game_profile->GetFastMath())
|
if (g_current_game_profile->GetFastMath())
|
||||||
options->setFastMathEnabled(true);
|
options->setFastMathEnabled(true);
|
||||||
|
|
||||||
|
@ -288,7 +288,6 @@ MTL::Library* RendererShaderMtl::LibraryFromSource()
|
||||||
|
|
||||||
NS::Error* error = nullptr;
|
NS::Error* error = nullptr;
|
||||||
MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(m_mslCode), options, &error);
|
MTL::Library* library = m_mtlr->GetDevice()->newLibrary(ToNSString(m_mslCode), options, &error);
|
||||||
options->release();
|
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
cemuLog_log(LogType::Force, "failed to create library from source: {} -> {}", error->localizedDescription()->utf8String(), m_mslCode.c_str());
|
cemuLog_log(LogType::Force, "failed to create library from source: {} -> {}", error->localizedDescription()->utf8String(), m_mslCode.c_str());
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue