diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp b/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp index fdf18ef5..2da259f3 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.cpp @@ -1,6 +1,7 @@ #include "Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h" #include "Common/precompiled.h" #include "Metal/MTLDepthStencil.hpp" +#include "Metal/MTLRenderCommandEncoder.hpp" #include "Metal/MTLSampler.hpp" std::map MTL_COLOR_FORMAT_TABLE = { @@ -247,22 +248,38 @@ TextureDecoder* GetMtlTextureDecoder(Latte::E_GX2SURFFMT format, bool isDepth) } } -MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode mode) +MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode primitiveMode) { - switch (mode) + switch (primitiveMode) { - case LattePrimitiveMode::POINTS: - return MTL::PrimitiveTypePoint; - case LattePrimitiveMode::LINES: - return MTL::PrimitiveTypeLine; - case LattePrimitiveMode::TRIANGLES: - return MTL::PrimitiveTypeTriangle; - case LattePrimitiveMode::TRIANGLE_STRIP: - return MTL::PrimitiveTypeTriangleStrip; - default: - // TODO: uncomment - //printf("unimplemented primitive type %u\n", (uint32)mode); - return MTL::PrimitiveTypeTriangle; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::POINTS: + return MTL::PrimitiveTypePoint; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::LINES: + return MTL::PrimitiveTypeLine; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::LINE_STRIP: + return MTL::PrimitiveTypeLineStrip; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::LINE_LOOP: + return MTL::PrimitiveTypeLineStrip; // line loops are emulated as line strips with an extra connecting strip at the end + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::LINE_STRIP_ADJACENT: // Tropical Freeze level 3-6 + debug_printf("Metal doesn't support line strip adjacent primitive, using line strip instead\n"); + return MTL::PrimitiveTypeLineStrip; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::TRIANGLES: + return MTL::PrimitiveTypeTriangle; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::TRIANGLE_FAN: + debug_printf("Metal doesn't support triangle fan primitive, using triangle strip instead\n"); + return MTL::PrimitiveTypeTriangleStrip; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::TRIANGLE_STRIP: + return MTL::PrimitiveTypeTriangleStrip; + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::QUADS: + return MTL::PrimitiveTypeTriangle; // quads are emulated as 2 triangles + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::QUAD_STRIP: + return MTL::PrimitiveTypeTriangle; // quad strips are emulated as (count-2)/2 triangles + case Latte::LATTE_VGT_PRIMITIVE_TYPE::E_PRIMITIVE_TYPE::RECTS: + return MTL::PrimitiveTypeTriangle; // rects are emulated as 2 triangles + default: + cemuLog_logDebug(LogType::Force, "Metal-Unsupported: Render pipeline with primitive mode {} created", primitiveMode); + cemu_assert_debug(false); + return MTL::PrimitiveTypeTriangle; } } diff --git a/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h b/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h index 7e75c35d..bd25ada5 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h +++ b/src/Cafe/HW/Latte/Renderer/Metal/LatteToMtl.h @@ -29,7 +29,7 @@ size_t GetMtlTextureBytesPerImage(Latte::E_GX2SURFFMT format, bool isDepth, uint TextureDecoder* GetMtlTextureDecoder(Latte::E_GX2SURFFMT format, bool isDepth); -MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode mode); +MTL::PrimitiveType GetMtlPrimitiveType(LattePrimitiveMode primitiveMode); MTL::VertexFormat GetMtlVertexFormat(uint8 format); diff --git a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp index d18f8bb9..5ced9e9f 100644 --- a/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp +++ b/src/Cafe/HW/Latte/Renderer/Metal/MetalPipelineCache.cpp @@ -60,6 +60,12 @@ MTL::RenderPipelineState* MetalPipelineCache::GetPipelineState(const LatteFetchS uint32 bufferBaseRegisterIndex = mmSQ_VTX_ATTRIBUTE_BLOCK_START + bufferIndex * 7; uint32 bufferStride = (LatteGPUState.contextNew.GetRawView()[bufferBaseRegisterIndex + 2] >> 11) & 0xFFFF; + uint32 strideRemainder = bufferStride % 4; + if (strideRemainder != 0) + { + debug_printf("vertex stride must be a multiple of 4, remainder: %u\n", strideRemainder); + } + auto layout = vertexDescriptor->layouts()->object(GET_MTL_VERTEX_BUFFER_INDEX(bufferIndex)); layout->setStride(bufferStride); if (!fetchType.has_value() || fetchType == LatteConst::VertexFetchType2::VERTEX_DATA)