Browse Source

metal: fix depth24stencil8 fallback on macOS

Alex Szpakowski 3 years ago
parent
commit
759937a458

+ 9 - 7
src/modules/graphics/metal/Graphics.mm

@@ -837,7 +837,6 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder, const Verte
 	{
 		lastVertexAttributes = attributes;
 
-//		Shader *shader = (Shader *) state.shader.get();
 		Shader *shader = (Shader *) Shader::current;
 		id<MTLRenderPipelineState> pipeline = nil;
 
@@ -849,18 +848,21 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder, const Verte
 			key.blend = state.blend;
 			key.colorChannelMask = state.colorMask;
 
-			const auto &rts = state.renderTargets.colors;
-
-			for (size_t i = 0; i < rts.size(); i++)
-				key.colorRenderTargetFormats |= (rts[i].texture->getPixelFormat()) << (8 * i);
-
 			if (state.renderTargets.getFirstTarget().texture.get() == nullptr)
 			{
 				key.colorRenderTargetFormats = isGammaCorrect() ? PIXELFORMAT_BGRA8_UNORM_sRGB : PIXELFORMAT_BGRA8_UNORM;
 				key.depthStencilFormat = backbufferDepthStencil->getPixelFormat();
 			}
+			else
+			{
+				const auto &rts = state.renderTargets.colors;
+				for (size_t i = 0; i < rts.size(); i++)
+					key.colorRenderTargetFormats |= (rts[i].texture->getPixelFormat()) << (8 * i);
 
-			// TODO: depth/stencil
+				// TODO: automatic depth/stencil (state doesn't store it).
+				if (state.renderTargets.depthStencil.texture.get())
+					key.depthStencilFormat = state.renderTargets.depthStencil.texture->getPixelFormat();
+			}
 
 			pipeline = shader->getCachedRenderPipeline(key);
 		}

+ 1 - 1
src/modules/graphics/metal/Metal.h

@@ -44,7 +44,7 @@ public:
 	};
 
 	API_AVAILABLE(macos(10.15), ios(13.0))
-	static PixelFormatDesc convertPixelFormat(PixelFormat format, bool &isSRGB);
+	static PixelFormatDesc convertPixelFormat(id<MTLDevice> device, PixelFormat format, bool &isSRGB);
 
 }; // Metal
 

+ 5 - 2
src/modules/graphics/metal/Metal.mm

@@ -28,7 +28,7 @@ namespace graphics
 namespace metal
 {
 
-Metal::PixelFormatDesc Metal::convertPixelFormat(PixelFormat format, bool &isSRGB)
+Metal::PixelFormatDesc Metal::convertPixelFormat(id<MTLDevice> device, PixelFormat format, bool &isSRGB)
 {
 	MTLPixelFormat mtlformat = MTLPixelFormatInvalid;
 	PixelFormatDesc desc = {};
@@ -192,7 +192,10 @@ Metal::PixelFormatDesc Metal::convertPixelFormat(PixelFormat format, bool &isSRG
 #ifdef LOVE_IOS
 		mtlformat = MTLPixelFormatDepth32Float_Stencil8;
 #else
-		mtlformat = MTLPixelFormatDepth24Unorm_Stencil8;
+		if ([device isDepth24Stencil8PixelFormatSupported])
+			mtlformat = MTLPixelFormatDepth24Unorm_Stencil8;
+		else
+			mtlformat = MTLPixelFormatDepth32Float_Stencil8;
 #endif
 		break;
 	case PIXELFORMAT_DEPTH32_FLOAT_STENCIL8:

+ 2 - 2
src/modules/graphics/metal/Shader.mm

@@ -931,7 +931,7 @@ id<MTLRenderPipelineState> Shader::getCachedRenderPipeline(const RenderPipelineK
 			// We already don't really support metal on older systems, this just
 			// silences a compiler warning about it.
 			bool isSRGB = false;
-			auto formatdesc = Metal::convertPixelFormat(format, isSRGB);
+			auto formatdesc = Metal::convertPixelFormat(device, format, isSRGB);
 			attachment.pixelFormat = formatdesc.format;
 		}
 
@@ -969,7 +969,7 @@ id<MTLRenderPipelineState> Shader::getCachedRenderPipeline(const RenderPipelineK
 			// We already don't really support metal on older systems, this just
 			// silences a compiler warning about it.
 			bool isSRGB = false;
-			auto formatdesc = Metal::convertPixelFormat(dsformat, isSRGB);
+			auto formatdesc = Metal::convertPixelFormat(device, dsformat, isSRGB);
 			if (isPixelFormatDepth(dsformat))
 				desc.depthAttachmentPixelFormat = formatdesc.format;
 			if (isPixelFormatStencil(dsformat))

+ 1 - 1
src/modules/graphics/metal/Texture.mm

@@ -62,7 +62,7 @@ Texture::Texture(love::graphics::Graphics *gfx, id<MTLDevice> device, const Sett
 	{
 		// We already don't really support metal on older systems, this just
 		// silences a compiler warning about it.
-		auto formatdesc = Metal::convertPixelFormat(format, sRGB);
+		auto formatdesc = Metal::convertPixelFormat(device, format, sRGB);
 		desc.pixelFormat = formatdesc.format;
 		if (formatdesc.swizzled)
 			desc.swizzle = formatdesc.swizzle;