Skip to content

Commit 4b7c01e

Browse files
committed
fix: 3D texture copies & fix: present filter
1 parent 3f52f3a commit 4b7c01e

File tree

6 files changed

+38
-18
lines changed

6 files changed

+38
-18
lines changed

src/Cafe/HW/Latte/Core/LatteIndices.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,7 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
699699
cemu_assert_debug(false);
700700
outputCount = count + 1;
701701
}
702+
/*
702703
else if (primitiveMode == LattePrimitiveMode::TRIANGLE_FAN && g_renderer->GetType() == RendererAPI::Metal)
703704
{
704705
if (indexType == LatteIndexType::AUTO)
@@ -722,6 +723,7 @@ void LatteIndices_decode(const void* indexData, LatteIndexType indexType, uint32
722723
cemu_assert_debug(false);
723724
outputCount = count;
724725
}
726+
*/
725727
else
726728
{
727729
if (indexType == LatteIndexType::U16_BE)

src/Cafe/HW/Latte/Core/LatteRenderTarget.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ void LatteRenderTarget_copyToBackbuffer(LatteTextureView* textureView, bool isPa
934934
{
935935
sint32 scaling_filter = downscaling ? GetConfig().downscale_filter : GetConfig().upscale_filter;
936936

937-
if (g_renderer->GetType() == RendererAPI::Vulkan)
937+
if (g_renderer->GetType() == RendererAPI::Vulkan || g_renderer->GetType() == RendererAPI::Metal)
938938
{
939939
// force linear or nearest neighbor filter
940940
if(scaling_filter != kLinearFilter && scaling_filter != kNearestNeighborFilter)

src/Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@
66
LatteTextureViewMtl::LatteTextureViewMtl(MetalRenderer* mtlRenderer, LatteTextureMtl* texture, Latte::E_DIM dim, Latte::E_GX2SURFFMT format, sint32 firstMip, sint32 mipCount, sint32 firstSlice, sint32 sliceCount)
77
: LatteTextureView(texture, firstMip, mipCount, firstSlice, sliceCount, dim, format), m_mtlr(mtlRenderer), m_baseTexture(texture)
88
{
9+
m_rgbaView = CreateSwizzledView(RGBA_SWIZZLE);
910
}
1011

1112
LatteTextureViewMtl::~LatteTextureViewMtl()
1213
{
14+
m_rgbaView->release();
1315
for (sint32 i = 0; i < std::size(m_viewCache); i++)
1416
{
1517
if (m_viewCache[i].key != INVALID_SWIZZLE)
@@ -30,7 +32,7 @@ MTL::Texture* LatteTextureViewMtl::GetSwizzledView(uint32 gpuSamplerSwizzle)
3032
// RGBA swizzle == no swizzle
3133
if (gpuSamplerSwizzle == RGBA_SWIZZLE)
3234
{
33-
return m_baseTexture->GetTexture();
35+
return m_rgbaView;
3436
}
3537

3638
// First, try to find a view in the cache

src/Cafe/HW/Latte/Renderer/Metal/LatteTextureViewMtl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ class LatteTextureViewMtl : public LatteTextureView
2626

2727
class LatteTextureMtl* m_baseTexture;
2828

29+
MTL::Texture* m_rgbaView;
2930
struct {
3031
uint32 key;
3132
MTL::Texture* texture;

src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.cpp

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
#include "Cafe/HW/Latte/Core/LatteIndices.h"
1717
#include "Cemu/Logging/CemuDebugLogging.h"
1818
#include "Common/precompiled.h"
19-
#include "Metal/MTLPixelFormat.hpp"
2019
#include "gui/guiWrapper.h"
2120

2221
#define COMMIT_TRESHOLD 256
@@ -32,6 +31,10 @@ MetalRenderer::MetalRenderer()
3231

3332
MTL::SamplerDescriptor* samplerDescriptor = MTL::SamplerDescriptor::alloc()->init();
3433
m_nearestSampler = m_device->newSamplerState(samplerDescriptor);
34+
35+
samplerDescriptor->setMinFilter(MTL::SamplerMinMagFilterLinear);
36+
samplerDescriptor->setMagFilter(MTL::SamplerMinMagFilterLinear);
37+
m_linearSampler = m_device->newSamplerState(samplerDescriptor);
3538
samplerDescriptor->release();
3639

3740
m_memoryManager = new MetalMemoryManager(this);
@@ -109,6 +112,7 @@ MetalRenderer::~MetalRenderer()
109112
delete m_memoryManager;
110113

111114
m_nearestSampler->release();
115+
m_linearSampler->release();
112116

113117
m_readbackBuffer->release();
114118

@@ -200,25 +204,26 @@ void MetalRenderer::DrawBackbufferQuad(LatteTextureView* texView, RendererOutput
200204
if (!AcquireNextDrawable(!padView))
201205
return;
202206

203-
if (clearBackground)
204-
ClearColorbuffer(padView);
205-
206207
MTL::Texture* presentTexture = static_cast<LatteTextureViewMtl*>(texView)->GetRGBAView();
207208

208209
// Create render pass
209210
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);
211216

212217
MTL::Texture* colorRenderTargets[8] = {nullptr};
213218
colorRenderTargets[0] = m_drawable->texture();
214219
// 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);
216221
renderPassDescriptor->release();
217222

218223
// Draw to Metal layer
219224
renderCommandEncoder->setRenderPipelineState(m_state.m_usesSRGB ? m_presentPipelineSRGB : m_presentPipelineLinear);
220225
renderCommandEncoder->setFragmentTexture(presentTexture, 0);
221-
renderCommandEncoder->setFragmentSamplerState(m_nearestSampler, 0);
226+
renderCommandEncoder->setFragmentSamplerState((useLinearTexFilter ? m_linearSampler : m_nearestSampler), 0);
222227

223228
renderCommandEncoder->drawPrimitives(MTL::PrimitiveTypeTriangle, NS::UInteger(0), NS::UInteger(3));
224229
}
@@ -314,11 +319,19 @@ void MetalRenderer::texture_clearSlice(LatteTexture* hostTexture, sint32 sliceIn
314319

315320
void MetalRenderer::texture_loadSlice(LatteTexture* hostTexture, sint32 width, sint32 height, sint32 depth, void* pixelData, sint32 sliceIndex, sint32 mipIndex, uint32 compressedImageSize)
316321
{
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+
}
318330

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);
322335
}
323336

324337
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
409422

410423
// If copying whole textures, we can do a more efficient copy
411424
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) &&
414428
srcLayerCount == dstLayerCount)
415429
{
416-
blitCommandEncoder->copyFromTexture(mtlSrc, srcSlice, srcMip, mtlDst, dstSlice, dstMip, srcLayerCount, 1);
430+
blitCommandEncoder->copyFromTexture(mtlSrc, srcBaseLayer, srcMip, mtlDst, dstBaseLayer, dstMip, srcLayerCount, 1);
417431
}
418432
else
419433
{
420434
if (srcLayerCount == dstLayerCount)
421435
{
422436
for (uint32 i = 0; i < srcLayerCount; i++)
423437
{
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));
425439
}
426440
}
427441
else
@@ -438,7 +452,7 @@ void MetalRenderer::texture_copyImageSubData(LatteTexture* src, sint32 srcMip, s
438452
else
439453
dstSlice++;
440454

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));
442456
}
443457
}
444458
}

src/Cafe/HW/Latte/Renderer/Metal/MetalRenderer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,7 @@ class MetalRenderer : public Renderer
288288

289289
// Basic
290290
MTL::SamplerState* m_nearestSampler;
291+
MTL::SamplerState* m_linearSampler;
291292

292293
// Texture readback
293294
MTL::Buffer* m_readbackBuffer;

0 commit comments

Comments
 (0)