Browse Source

metal: implement mesh cull modes

Alex Szpakowski 3 years ago
parent
commit
bcd64fe537
2 changed files with 24 additions and 5 deletions
  1. 1 0
      src/modules/graphics/metal/Graphics.h
  2. 23 5
      src/modules/graphics/metal/Graphics.mm

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

@@ -212,6 +212,7 @@ private:
 	MTLRenderPassDescriptor *passDesc;
 	MTLRenderPassDescriptor *passDesc;
 
 
 	uint32 dirtyRenderState;
 	uint32 dirtyRenderState;
+	CullMode lastCullMode;
 	VertexAttributes lastVertexAttributes;
 	VertexAttributes lastVertexAttributes;
 	bool windowHasStencil;
 	bool windowHasStencil;
 	int shaderSwitches;
 	int shaderSwitches;

+ 23 - 5
src/modules/graphics/metal/Graphics.mm

@@ -230,6 +230,7 @@ Graphics::Graphics()
 	, activeDrawable(nil)
 	, activeDrawable(nil)
 	, passDesc(nil)
 	, passDesc(nil)
 	, dirtyRenderState(STATEBIT_ALL)
 	, dirtyRenderState(STATEBIT_ALL)
+	, lastCullMode(CULL_MAX_ENUM)
 	, windowHasStencil(false)
 	, windowHasStencil(false)
 	, shaderSwitches(0)
 	, shaderSwitches(0)
 	, requestedBackbufferMSAA(0)
 	, requestedBackbufferMSAA(0)
@@ -576,6 +577,7 @@ id<MTLRenderCommandEncoder> Graphics::useRenderEncoder()
 		setBuffer(renderEncoder, renderBindings, SHADERSTAGE_VERTEX, DEFAULT_VERTEX_BUFFER_BINDING, defaultbuffer, 0);
 		setBuffer(renderEncoder, renderBindings, SHADERSTAGE_VERTEX, DEFAULT_VERTEX_BUFFER_BINDING, defaultbuffer, 0);
 
 
 		dirtyRenderState = STATEBIT_ALL;
 		dirtyRenderState = STATEBIT_ALL;
+		lastCullMode = CULL_MAX_ENUM;
 	}
 	}
 
 
 	return renderEncoder;
 	return renderEncoder;
@@ -795,7 +797,9 @@ void Graphics::applyRenderState(id<MTLRenderCommandEncoder> encoder, const Verte
 
 
 	if (dirtyState & STATEBIT_CULLMODE)
 	if (dirtyState & STATEBIT_CULLMODE)
 	{
 	{
-		// TODO
+		auto mode = lastCullMode == CULL_BACK ? MTLCullModeBack :
+			lastCullMode == CULL_FRONT ? MTLCullModeFront : MTLCullModeNone;
+		[encoder setCullMode:mode];
 	}
 	}
 
 
 	if ((dirtyState & pipelineStateBits) != 0 || !(attributes == lastVertexAttributes))
 	if ((dirtyState & pipelineStateBits) != 0 || !(attributes == lastVertexAttributes))
@@ -1000,11 +1004,15 @@ void Graphics::draw(const DrawCommand &cmd)
 { @autoreleasepool {
 { @autoreleasepool {
 	id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
 	id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
 
 
+	if (cmd.cullMode != lastCullMode)
+	{
+		lastCullMode = cmd.cullMode;
+		dirtyRenderState |= STATEBIT_CULLMODE;
+	}
+
 	applyRenderState(encoder, *cmd.attributes);
 	applyRenderState(encoder, *cmd.attributes);
 	applyShaderUniforms(encoder, Shader::current, cmd.texture);
 	applyShaderUniforms(encoder, Shader::current, cmd.texture);
 
 
-	[encoder setCullMode:MTLCullModeNone];
-
 	setVertexBuffers(encoder, cmd.buffers, renderBindings);
 	setVertexBuffers(encoder, cmd.buffers, renderBindings);
 
 
 	[encoder drawPrimitives:getMTLPrimitiveType(cmd.primitiveType)
 	[encoder drawPrimitives:getMTLPrimitiveType(cmd.primitiveType)
@@ -1019,6 +1027,12 @@ void Graphics::draw(const DrawIndexedCommand &cmd)
 { @autoreleasepool {
 { @autoreleasepool {
 	id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
 	id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
 
 
+	if (cmd.cullMode != lastCullMode)
+	{
+		lastCullMode = cmd.cullMode;
+		dirtyRenderState |= STATEBIT_CULLMODE;
+	}
+
 	applyRenderState(encoder, *cmd.attributes);
 	applyRenderState(encoder, *cmd.attributes);
 	applyShaderUniforms(encoder, Shader::current, cmd.texture);
 	applyShaderUniforms(encoder, Shader::current, cmd.texture);
 
 
@@ -1045,11 +1059,15 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes &attribute
 
 
 	id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
 	id<MTLRenderCommandEncoder> encoder = useRenderEncoder();
 
 
+	if (lastCullMode != CULL_NONE)
+	{
+		lastCullMode = CULL_NONE;
+		dirtyRenderState |= STATEBIT_CULLMODE;
+	}
+
 	applyRenderState(encoder, attributes);
 	applyRenderState(encoder, attributes);
 	applyShaderUniforms(encoder, Shader::current, texture);
 	applyShaderUniforms(encoder, Shader::current, texture);
 
 
-	[encoder setCullMode:MTLCullModeNone];
-
 	setVertexBuffers(encoder, &buffers, renderBindings);
 	setVertexBuffers(encoder, &buffers, renderBindings);
 
 
 	id<MTLBuffer> ib = getMTLBuffer(quadIndexBuffer);
 	id<MTLBuffer> ib = getMTLBuffer(quadIndexBuffer);