Browse Source

metal: initial (bad/slow) setShader tracking

Alex Szpakowski 4 years ago
parent
commit
aad0810e11

+ 3 - 0
src/modules/graphics/metal/Graphics.h

@@ -96,6 +96,8 @@ public:
 	bool usesGLSLES() const override;
 	RendererInfo getRendererInfo() const override;
 
+	void attachShader(love::graphics::Shader *shader);
+
 	id<MTLCommandBuffer> useCommandBuffer();
 	id<MTLCommandBuffer> getCommandBuffer() const { return commandBuffer; }
 	void submitCommandBuffer();
@@ -194,6 +196,7 @@ private:
 	MTLRenderPassDescriptor *passDesc;
 
 	uint32 dirtyRenderState;
+	VertexAttributes lastVertexAttributes;
 	bool windowHasStencil;
 
 	StreamBuffer *uniformBuffer;

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

@@ -381,6 +381,11 @@ void Graphics::setActive(bool enable)
 	active = enable;
 }
 
+void Graphics::attachShader(love::graphics::Shader *shader)
+{
+	dirtyRenderState |= STATE_SHADER;
+}
+
 id<MTLCommandBuffer> Graphics::useCommandBuffer()
 {
 	if (commandBuffer == nil)
@@ -620,9 +625,10 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder, const Verte
 		// TODO
 	}
 
-	// TODO: attributes
-	if ((dirtyState & pipelineStateBits) != 0 || true)
+	if ((dirtyState & pipelineStateBits) != 0 || !(attributes == lastVertexAttributes))
 	{
+		lastVertexAttributes = attributes;
+
 //		Shader *shader = (Shader *) state.shader.get();
 		Shader *shader = (Shader *) Shader::current;
 		id<MTLRenderPipelineState> pipeline = nil;
@@ -923,6 +929,7 @@ void Graphics::setRenderTargetsInternal(const RenderTargets &rts, int w, int h,
 
 	projectionMatrix = Matrix4::ortho(0.0, (float) w, (float) h, 0.0, -10.0f, 10.0f);
 	dirtyRenderState = STATEBIT_ALL;
+	lastVertexAttributes = VertexAttributes();
 }}
 
 void Graphics::endPass()

+ 3 - 1
src/modules/graphics/metal/Shader.mm

@@ -441,7 +441,9 @@ void Shader::attach()
 {
 	if (current != this)
 	{
-		Graphics::flushBatchedDrawsGlobal();
+		Graphics *gfx = Module::getInstance<Graphics>(Module::M_GRAPHICS);
+		gfx->flushBatchedDrawsGlobal();
+		gfx->attachShader(this);
 		current = this;
 	}
 }

+ 28 - 0
src/modules/graphics/vertex.cpp

@@ -322,6 +322,34 @@ void VertexAttributes::setCommonFormat(CommonFormat format, uint8 bufferindex)
 	}
 }
 
+bool VertexAttributes::operator == (const VertexAttributes &other) const
+{
+	if (enableBits != other.enableBits || instanceBits != other.instanceBits)
+		return false;
+
+	uint32 allbits = enableBits;
+	uint32 i = 0;
+
+	while (allbits)
+	{
+		if (isEnabled(i))
+		{
+			const auto &a = attribs[i];
+			const auto &b = other.attribs[i];
+			if (a.bufferIndex != b.bufferIndex || a.format != b.format || a.offsetFromVertex != b.offsetFromVertex)
+				return false;
+
+			if (bufferLayouts[a.bufferIndex].stride != other.bufferLayouts[a.bufferIndex].stride)
+				return false;
+		}
+
+		i++;
+		allbits >>= 1;
+	}
+
+	return true;
+}
+
 STRINGMAP_BEGIN(BuiltinVertexAttribute, ATTRIB_MAX_ENUM, attribName)
 {
 	{ "VertexPosition", ATTRIB_POS           },

+ 2 - 0
src/modules/graphics/vertex.h

@@ -371,6 +371,8 @@ struct VertexAttributes
 	}
 
 	void setCommonFormat(CommonFormat format, uint8 bufferindex);
+
+	bool operator == (const VertexAttributes &other) const;
 };
 
 size_t getFormatStride(CommonFormat format);