Browse Source

metal: fix automatic depth/stencil with setCanvas.

Alex Szpakowski 3 years ago
parent
commit
87592513a2

+ 3 - 3
src/modules/graphics/Graphics.cpp

@@ -891,10 +891,10 @@ void Graphics::setRenderTargets(const RenderTargets &rts)
 		realRTs.depthStencil.texture = getTemporaryTexture(dsformat, pixelw, pixelh, reqmsaa);
 		realRTs.depthStencil.slice = 0;
 
-		setRenderTargetsInternal(realRTs, w, h, pixelw, pixelh, hasSRGBtexture);
+		setRenderTargetsInternal(realRTs, pixelw, pixelh, hasSRGBtexture);
 	}
 	else
-		setRenderTargetsInternal(rts, w, h, pixelw, pixelh, hasSRGBtexture);
+		setRenderTargetsInternal(rts, pixelw, pixelh, hasSRGBtexture);
 
 	RenderTargetsStrongRef refs;
 	refs.colors.reserve(rts.colors.size());
@@ -920,7 +920,7 @@ void Graphics::setRenderTarget()
 		return;
 
 	flushBatchedDraws();
-	setRenderTargetsInternal(RenderTargets(), width, height, pixelWidth, pixelHeight, isGammaCorrect());
+	setRenderTargetsInternal(RenderTargets(), pixelWidth, pixelHeight, isGammaCorrect());
 
 	state.renderTargets = RenderTargetsStrongRef();
 	renderTargetSwitchCount++;

+ 1 - 1
src/modules/graphics/Graphics.h

@@ -982,7 +982,7 @@ protected:
 
 	virtual bool dispatch(int x, int y, int z) = 0;
 
-	virtual void setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBtexture) = 0;
+	virtual void setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture) = 0;
 
 	virtual void initCapabilities() = 0;
 	virtual void getAPIStats(int &shaderswitches) const = 0;

+ 2 - 1
src/modules/graphics/metal/Graphics.h

@@ -201,7 +201,7 @@ private:
 	love::graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
 	love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
 	love::graphics::StreamBuffer *newStreamBuffer(BufferUsage usage, size_t size) override;
-	void setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBcanvas) override;
+	void setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBcanvas) override;
 	void initCapabilities() override;
 	void getAPIStats(int &shaderswitches) const override;
 
@@ -226,6 +226,7 @@ private:
 	uint32 dirtyRenderState;
 	CullMode lastCullMode;
 	VertexAttributes lastVertexAttributes;
+	PixelFormat activeDepthStencilFormat;
 	bool windowHasStencil;
 	int shaderSwitches;
 

+ 10 - 6
src/modules/graphics/metal/Graphics.mm

@@ -270,6 +270,7 @@ Graphics::Graphics()
 	, passDesc(nil)
 	, dirtyRenderState(STATEBIT_ALL)
 	, lastCullMode(CULL_MAX_ENUM)
+	, activeDepthStencilFormat(PIXELFORMAT_UNKNOWN)
 	, windowHasStencil(false)
 	, shaderSwitches(0)
 	, requestedBackbufferMSAA(0)
@@ -920,9 +921,9 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder, const Verte
 				for (size_t i = 0; i < rts.size(); i++)
 					key.colorRenderTargetFormats |= (rts[i].texture->getPixelFormat()) << (8 * i);
 
-				// TODO: automatic depth/stencil (state doesn't store it).
-				if (state.renderTargets.depthStencil.texture.get())
-					key.depthStencilFormat = state.renderTargets.depthStencil.texture->getPixelFormat();
+				// Don't query the current RTs because they don't include
+				// automatic depth/stencil.
+				key.depthStencilFormat = activeDepthStencilFormat;
 
 				key.msaa = (uint8) firsttarget.texture->getMSAA();
 			}
@@ -1321,7 +1322,7 @@ bool Graphics::dispatch(int x, int y, int z)
 	return true;
 }}
 
-void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int /*w*/, int /*h*/, int /*pixelw*/, int /*pixelh*/, bool /*hasSRGBtexture*/)
+void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int /*pixelw*/, int /*pixelh*/, bool /*hasSRGBtexture*/)
 { @autoreleasepool {
 	endPass();
 
@@ -1346,18 +1347,21 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int /*w*/, int
 	if (isbackbuffer && ds == nullptr)
 		ds = backbufferDepthStencil;
 
+	PixelFormat dsformat = PIXELFORMAT_UNKNOWN;
 	if (ds != nullptr)
 	{
 		RenderTarget rt = rts.depthStencil;
 		rt.texture = ds;
+		dsformat = ds->getPixelFormat();
 
-		if (isPixelFormatDepth(ds->getPixelFormat()))
+		if (isPixelFormatDepth(dsformat))
 			setAttachment(rt, passDesc.depthAttachment, attachmentStoreActions.depth);
 
-		if (isPixelFormatStencil(ds->getPixelFormat()))
+		if (isPixelFormatStencil(dsformat))
 			setAttachment(rt, passDesc.stencilAttachment, attachmentStoreActions.stencil);
 	}
 
+	activeDepthStencilFormat = dsformat;
 	dirtyRenderState = STATEBIT_ALL;
 	lastVertexAttributes = VertexAttributes();
 }}

+ 1 - 1
src/modules/graphics/opengl/Graphics.cpp

@@ -742,7 +742,7 @@ void Graphics::setDebug(bool enable)
 	::printf("OpenGL debug output enabled (LOVE_GRAPHICS_DEBUG=1)\n");
 }
 
-void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int /*w*/, int /*h*/, int pixelw, int pixelh, bool hasSRGBtexture)
+void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture)
 {
 	const DisplayState &state = states.back();
 

+ 1 - 1
src/modules/graphics/opengl/Graphics.h

@@ -144,7 +144,7 @@ private:
 	love::graphics::ShaderStage *newShaderStageInternal(ShaderStageType stage, const std::string &cachekey, const std::string &source, bool gles) override;
 	love::graphics::Shader *newShaderInternal(StrongRef<love::graphics::ShaderStage> stages[SHADERSTAGE_MAX_ENUM]) override;
 	love::graphics::StreamBuffer *newStreamBuffer(BufferUsage type, size_t size) override;
-	void setRenderTargetsInternal(const RenderTargets &rts, int w, int h, int pixelw, int pixelh, bool hasSRGBtexture) override;
+	void setRenderTargetsInternal(const RenderTargets &rts, int pixelw, int pixelh, bool hasSRGBtexture) override;
 	void initCapabilities() override;
 	void getAPIStats(int &shaderswitches) const override;