16
16
#include " Cafe/HW/Latte/Core/LatteIndices.h"
17
17
#include " Cemu/Logging/CemuDebugLogging.h"
18
18
#include " Common/precompiled.h"
19
- #include " Metal/MTLPixelFormat.hpp"
20
19
#include " gui/guiWrapper.h"
21
20
22
21
#define COMMIT_TRESHOLD 256
@@ -32,6 +31,10 @@ MetalRenderer::MetalRenderer()
32
31
33
32
MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc ()->init ();
34
33
m_nearestSampler = m_device->newSamplerState (samplerDescriptor);
34
+
35
+ samplerDescriptor->setMinFilter (MTL::SamplerMinMagFilterLinear);
36
+ samplerDescriptor->setMagFilter (MTL::SamplerMinMagFilterLinear);
37
+ m_linearSampler = m_device->newSamplerState (samplerDescriptor);
35
38
samplerDescriptor->release ();
36
39
37
40
m_memoryManager = new MetalMemoryManager (this );
@@ -109,6 +112,7 @@ MetalRenderer::~MetalRenderer()
109
112
delete m_memoryManager;
110
113
111
114
m_nearestSampler->release ();
115
+ m_linearSampler->release ();
112
116
113
117
m_readbackBuffer->release ();
114
118
@@ -200,25 +204,26 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
200
204
if (!AcquireNextDrawable (!padView))
201
205
return ;
202
206
203
- if (clearBackground)
204
- ClearColorbuffer (padView);
205
-
206
207
MTL::Texture* presentTexture = static_cast <LatteTextureViewMtl*>(texView)->GetRGBAView ();
207
208
208
209
// Create render pass
209
210
MTL::RenderPassDescriptor* renderPassDescriptor = MTL::RenderPassDescriptor::alloc ()->init ();
210
- renderPassDescriptor->colorAttachments ()->object (0 )->setTexture (m_drawable->texture ());
211
+ auto colorAttachment = renderPassDescriptor->colorAttachments ()->object (0 );
212
+ colorAttachment->setTexture (m_drawable->texture ());
213
+ // TODO: shouldn't it be LoadActionLoad when not clearing?
214
+ colorAttachment->setLoadAction (clearBackground ? MTL::LoadActionClear : MTL::LoadActionDontCare);
215
+ colorAttachment->setStoreAction (MTL::StoreActionStore);
211
216
212
217
MTL::Texture* colorRenderTargets[8 ] = {nullptr };
213
218
colorRenderTargets[0 ] = m_drawable->texture ();
214
219
// If there was already an encoder with these attachment, we should set the viewport and scissor to default, but that shouldn't happen
215
- auto renderCommandEncoder = GetRenderCommandEncoder (renderPassDescriptor, colorRenderTargets, nullptr , false , false );
220
+ auto renderCommandEncoder = GetRenderCommandEncoder (renderPassDescriptor, colorRenderTargets, nullptr , clearBackground , false );
216
221
renderPassDescriptor->release ();
217
222
218
223
// Draw to Metal layer
219
224
renderCommandEncoder->setRenderPipelineState (m_state.m_usesSRGB ? m_presentPipelineSRGB : m_presentPipelineLinear);
220
225
renderCommandEncoder->setFragmentTexture (presentTexture, 0 );
221
- renderCommandEncoder->setFragmentSamplerState (m_nearestSampler, 0 );
226
+ renderCommandEncoder->setFragmentSamplerState ((useLinearTexFilter ? m_linearSampler : m_nearestSampler) , 0 );
222
227
223
228
renderCommandEncoder->drawPrimitives (MTL::PrimitiveTypeTriangle, NS::UInteger (0 ), NS::UInteger (3 ));
224
229
}
@@ -314,11 +319,19 @@ void MetalRenderer::texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIn
314
319
315
320
void MetalRenderer::texture_loadSlice (LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void * pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize)
316
321
{
317
- auto mtlTexture = (LatteTextureMtl*)hostTexture;
322
+ auto textureMtl = (LatteTextureMtl*)hostTexture;
323
+
324
+ uint32 offsetZ = 0 ;
325
+ if (textureMtl->Is3DTexture ())
326
+ {
327
+ offsetZ = sliceIndex;
328
+ sliceIndex = 0 ;
329
+ }
318
330
319
- size_t bytesPerRow = GetMtlTextureBytesPerRow (mtlTexture->GetFormat (), mtlTexture->IsDepth (), width);
320
- size_t bytesPerImage = GetMtlTextureBytesPerImage (mtlTexture->GetFormat (), mtlTexture->IsDepth (), height, bytesPerRow);
321
- mtlTexture->GetTexture ()->replaceRegion (MTL::Region (0 , 0 , width, height), mipIndex, sliceIndex, pixelData, bytesPerRow, bytesPerImage);
331
+ size_t bytesPerRow = GetMtlTextureBytesPerRow (textureMtl->GetFormat (), textureMtl->IsDepth (), width);
332
+ // No need to calculate bytesPerImage for 3D textures, since we always load just one slice
333
+ // size_t bytesPerImage = GetMtlTextureBytesPerImage(textureMtl->GetFormat(), textureMtl->IsDepth(), height, bytesPerRow);
334
+ textureMtl->GetTexture ()->replaceRegion (MTL::Region (0 , 0 , offsetZ, width, height, 1 ), mipIndex, sliceIndex, pixelData, bytesPerRow, 0 );
322
335
}
323
336
324
337
void MetalRenderer::texture_clearColorSlice (LatteTexture* hostTexture, sint32 sliceIndex, sint32 mipIndex, float r, float g, float b, float a)
@@ -409,19 +422,20 @@ void MetalRenderer::texture_copyImageSubData(LatteTexture* src, sint32 srcMip, s
409
422
410
423
// If copying whole textures, we can do a more efficient copy
411
424
if (effectiveSrcX == 0 && effectiveSrcY == 0 && effectiveDstX == 0 && effectiveDstY == 0 &&
412
- effectiveCopyWidth == src->GetMipWidth (srcMip) && effectiveCopyHeight == src->GetMipHeight (srcMip) &&
413
- effectiveCopyWidth == dst->GetMipWidth (dstMip) && effectiveCopyHeight == dst->GetMipHeight (dstMip) &&
425
+ srcOffsetZ == 0 && dstOffsetZ == 0 &&
426
+ effectiveCopyWidth == src->GetMipWidth (srcMip) && effectiveCopyHeight == src->GetMipHeight (srcMip) && srcDepth == src->GetMipDepth (srcMip) &&
427
+ effectiveCopyWidth == dst->GetMipWidth (dstMip) && effectiveCopyHeight == dst->GetMipHeight (dstMip) && dstDepth == dst->GetMipDepth (dstMip) &&
414
428
srcLayerCount == dstLayerCount)
415
429
{
416
- blitCommandEncoder->copyFromTexture (mtlSrc, srcSlice , srcMip, mtlDst, dstSlice , dstMip, srcLayerCount, 1 );
430
+ blitCommandEncoder->copyFromTexture (mtlSrc, srcBaseLayer , srcMip, mtlDst, dstBaseLayer , dstMip, srcLayerCount, 1 );
417
431
}
418
432
else
419
433
{
420
434
if (srcLayerCount == dstLayerCount)
421
435
{
422
436
for (uint32 i = 0 ; i < srcLayerCount; i++)
423
437
{
424
- blitCommandEncoder->copyFromTexture (mtlSrc, srcSlice + i, srcMip, MTL::Origin (effectiveSrcX, effectiveSrcY, srcOffsetZ), MTL::Size (effectiveCopyWidth, effectiveCopyHeight, 1 ), mtlDst, dstSlice + i, dstMip, MTL::Origin (effectiveDstX, effectiveDstY, dstOffsetZ));
438
+ blitCommandEncoder->copyFromTexture (mtlSrc, srcBaseLayer + i, srcMip, MTL::Origin (effectiveSrcX, effectiveSrcY, srcOffsetZ), MTL::Size (effectiveCopyWidth, effectiveCopyHeight, srcDepth ), mtlDst, dstBaseLayer + i, dstMip, MTL::Origin (effectiveDstX, effectiveDstY, dstOffsetZ));
425
439
}
426
440
}
427
441
else
@@ -438,7 +452,7 @@ void MetalRenderer::texture_copyImageSubData(LatteTexture* src, sint32 srcMip, s
438
452
else
439
453
dstSlice++;
440
454
441
- blitCommandEncoder->copyFromTexture (mtlSrc, srcSlice , srcMip, MTL::Origin (effectiveSrcX, effectiveSrcY, srcOffsetZ), MTL::Size (effectiveCopyWidth, effectiveCopyHeight, 1 ), mtlDst, dstSlice , dstMip, MTL::Origin (effectiveDstX, effectiveDstY, dstOffsetZ));
455
+ blitCommandEncoder->copyFromTexture (mtlSrc, srcBaseLayer , srcMip, MTL::Origin (effectiveSrcX, effectiveSrcY, srcOffsetZ), MTL::Size (effectiveCopyWidth, effectiveCopyHeight, 1 ), mtlDst, dstBaseLayer , dstMip, MTL::Origin (effectiveDstX, effectiveDstY, dstOffsetZ));
442
456
}
443
457
}
444
458
}
0 commit comments