diff --git a/src/modules/graphics/metal/Graphics.h b/src/modules/graphics/metal/Graphics.h index 65af5357d..e1c356d02 100644 --- a/src/modules/graphics/metal/Graphics.h +++ b/src/modules/graphics/metal/Graphics.h @@ -212,6 +212,7 @@ private: MTLRenderPassDescriptor *passDesc; uint32 dirtyRenderState; + CullMode lastCullMode; VertexAttributes lastVertexAttributes; bool windowHasStencil; int shaderSwitches; diff --git a/src/modules/graphics/metal/Graphics.mm b/src/modules/graphics/metal/Graphics.mm index ba6191d2b..e17534b7d 100644 --- a/src/modules/graphics/metal/Graphics.mm +++ b/src/modules/graphics/metal/Graphics.mm @@ -230,6 +230,7 @@ Graphics::Graphics() , activeDrawable(nil) , passDesc(nil) , dirtyRenderState(STATEBIT_ALL) + , lastCullMode(CULL_MAX_ENUM) , windowHasStencil(false) , shaderSwitches(0) , requestedBackbufferMSAA(0) @@ -576,6 +577,7 @@ id Graphics::useRenderEncoder() setBuffer(renderEncoder, renderBindings, SHADERSTAGE_VERTEX, DEFAULT_VERTEX_BUFFER_BINDING, defaultbuffer, 0); dirtyRenderState = STATEBIT_ALL; + lastCullMode = CULL_MAX_ENUM; } return renderEncoder; @@ -795,7 +797,9 @@ void Graphics::applyRenderState(id encoder, const Verte 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)) @@ -1000,11 +1004,15 @@ void Graphics::draw(const DrawCommand &cmd) { @autoreleasepool { id encoder = useRenderEncoder(); + if (cmd.cullMode != lastCullMode) + { + lastCullMode = cmd.cullMode; + dirtyRenderState |= STATEBIT_CULLMODE; + } + applyRenderState(encoder, *cmd.attributes); applyShaderUniforms(encoder, Shader::current, cmd.texture); - [encoder setCullMode:MTLCullModeNone]; - setVertexBuffers(encoder, cmd.buffers, renderBindings); [encoder drawPrimitives:getMTLPrimitiveType(cmd.primitiveType) @@ -1019,6 +1027,12 @@ void Graphics::draw(const DrawIndexedCommand &cmd) { @autoreleasepool { id encoder = useRenderEncoder(); + if (cmd.cullMode != lastCullMode) + { + lastCullMode = cmd.cullMode; + dirtyRenderState |= STATEBIT_CULLMODE; + } + applyRenderState(encoder, *cmd.attributes); applyShaderUniforms(encoder, Shader::current, cmd.texture); @@ -1045,11 +1059,15 @@ void Graphics::drawQuads(int start, int count, const VertexAttributes &attribute id encoder = useRenderEncoder(); + if (lastCullMode != CULL_NONE) + { + lastCullMode = CULL_NONE; + dirtyRenderState |= STATEBIT_CULLMODE; + } + applyRenderState(encoder, attributes); applyShaderUniforms(encoder, Shader::current, texture); - [encoder setCullMode:MTLCullModeNone]; - setVertexBuffers(encoder, &buffers, renderBindings); id ib = getMTLBuffer(quadIndexBuffer);