mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-11-10 04:57:26 +01:00
internal/graphicsdriver/metal: Reuse DepthStencilState objects
In Metal, *State objects are not 'transient' and are expensive to create. Reuse them whenever possible. See also: https://developer.apple.com/library/archive/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/Cmd-Submiss/Cmd-Submiss.html
This commit is contained in:
parent
ab26312108
commit
3670b7dd62
@ -312,6 +312,7 @@ type Graphics struct {
|
|||||||
cq mtl.CommandQueue
|
cq mtl.CommandQueue
|
||||||
cb mtl.CommandBuffer
|
cb mtl.CommandBuffer
|
||||||
rce mtl.RenderCommandEncoder
|
rce mtl.RenderCommandEncoder
|
||||||
|
dsss map[stencilMode]mtl.DepthStencilState
|
||||||
|
|
||||||
screenDrawable ca.MetalDrawable
|
screenDrawable ca.MetalDrawable
|
||||||
|
|
||||||
@ -511,11 +512,21 @@ func (g *Graphics) Reset() error {
|
|||||||
g.cq = mtl.CommandQueue{}
|
g.cq = mtl.CommandQueue{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Creating *State objects are expensive and reuse them whenever possible.
|
||||||
|
// See https://developer.apple.com/library/archive/documentation/Miscellaneous/Conceptual/MetalProgrammingGuide/Cmd-Submiss/Cmd-Submiss.html
|
||||||
|
|
||||||
// TODO: Release existing rpss
|
// TODO: Release existing rpss
|
||||||
if g.rpss == nil {
|
if g.rpss == nil {
|
||||||
g.rpss = map[rpsKey]mtl.RenderPipelineState{}
|
g.rpss = map[rpsKey]mtl.RenderPipelineState{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for _, dss := range g.dsss {
|
||||||
|
dss.Release()
|
||||||
|
}
|
||||||
|
if g.dsss == nil {
|
||||||
|
g.dsss = map[stencilMode]mtl.DepthStencilState{}
|
||||||
|
}
|
||||||
|
|
||||||
if err := g.view.reset(); err != nil {
|
if err := g.view.reset(); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -635,6 +646,50 @@ func (g *Graphics) Reset() error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The stencil reference value is always 0 (default).
|
||||||
|
g.dsss[prepareStencil] = g.view.getMTLDevice().MakeDepthStencilState(mtl.DepthStencilDescriptor{
|
||||||
|
BackFaceStencil: mtl.StencilDescriptor{
|
||||||
|
StencilFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthStencilPassOperation: mtl.StencilOperationInvert,
|
||||||
|
StencilCompareFunction: mtl.CompareFunctionAlways,
|
||||||
|
},
|
||||||
|
FrontFaceStencil: mtl.StencilDescriptor{
|
||||||
|
StencilFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthStencilPassOperation: mtl.StencilOperationInvert,
|
||||||
|
StencilCompareFunction: mtl.CompareFunctionAlways,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
g.dsss[drawWithStencil] = g.view.getMTLDevice().MakeDepthStencilState(mtl.DepthStencilDescriptor{
|
||||||
|
BackFaceStencil: mtl.StencilDescriptor{
|
||||||
|
StencilFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
||||||
|
StencilCompareFunction: mtl.CompareFunctionNotEqual,
|
||||||
|
},
|
||||||
|
FrontFaceStencil: mtl.StencilDescriptor{
|
||||||
|
StencilFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
||||||
|
StencilCompareFunction: mtl.CompareFunctionNotEqual,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
g.dsss[noStencil] = g.view.getMTLDevice().MakeDepthStencilState(mtl.DepthStencilDescriptor{
|
||||||
|
BackFaceStencil: mtl.StencilDescriptor{
|
||||||
|
StencilFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
||||||
|
StencilCompareFunction: mtl.CompareFunctionAlways,
|
||||||
|
},
|
||||||
|
FrontFaceStencil: mtl.StencilDescriptor{
|
||||||
|
StencilFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthFailureOperation: mtl.StencilOperationKeep,
|
||||||
|
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
||||||
|
StencilCompareFunction: mtl.CompareFunctionAlways,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
g.cq = g.view.getMTLDevice().MakeCommandQueue()
|
g.cq = g.view.getMTLDevice().MakeCommandQueue()
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -727,63 +782,7 @@ func (g *Graphics) draw(rps mtl.RenderPipelineState, dst *Image, dstRegion drive
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The stencil reference value is always 0 (default).
|
g.rce.SetDepthStencilState(g.dsss[stencilMode])
|
||||||
switch stencilMode {
|
|
||||||
case prepareStencil:
|
|
||||||
desc := mtl.DepthStencilDescriptor{
|
|
||||||
BackFaceStencil: mtl.StencilDescriptor{
|
|
||||||
StencilFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthStencilPassOperation: mtl.StencilOperationInvert,
|
|
||||||
StencilCompareFunction: mtl.CompareFunctionAlways,
|
|
||||||
},
|
|
||||||
FrontFaceStencil: mtl.StencilDescriptor{
|
|
||||||
StencilFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthStencilPassOperation: mtl.StencilOperationInvert,
|
|
||||||
StencilCompareFunction: mtl.CompareFunctionAlways,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ss := g.view.getMTLDevice().MakeDepthStencilState(desc)
|
|
||||||
g.rce.SetDepthStencilState(ss)
|
|
||||||
ss.Release()
|
|
||||||
case drawWithStencil:
|
|
||||||
desc := mtl.DepthStencilDescriptor{
|
|
||||||
BackFaceStencil: mtl.StencilDescriptor{
|
|
||||||
StencilFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
|
||||||
StencilCompareFunction: mtl.CompareFunctionNotEqual,
|
|
||||||
},
|
|
||||||
FrontFaceStencil: mtl.StencilDescriptor{
|
|
||||||
StencilFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
|
||||||
StencilCompareFunction: mtl.CompareFunctionNotEqual,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ss := g.view.getMTLDevice().MakeDepthStencilState(desc)
|
|
||||||
g.rce.SetDepthStencilState(ss)
|
|
||||||
ss.Release()
|
|
||||||
case noStencil:
|
|
||||||
desc := mtl.DepthStencilDescriptor{
|
|
||||||
BackFaceStencil: mtl.StencilDescriptor{
|
|
||||||
StencilFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
|
||||||
StencilCompareFunction: mtl.CompareFunctionAlways,
|
|
||||||
},
|
|
||||||
FrontFaceStencil: mtl.StencilDescriptor{
|
|
||||||
StencilFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthFailureOperation: mtl.StencilOperationKeep,
|
|
||||||
DepthStencilPassOperation: mtl.StencilOperationKeep,
|
|
||||||
StencilCompareFunction: mtl.CompareFunctionAlways,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
ss := g.view.getMTLDevice().MakeDepthStencilState(desc)
|
|
||||||
g.rce.SetDepthStencilState(ss)
|
|
||||||
ss.Release()
|
|
||||||
}
|
|
||||||
|
|
||||||
g.rce.DrawIndexedPrimitives(mtl.PrimitiveTypeTriangle, indexLen, mtl.IndexTypeUInt16, g.ib, indexOffset*2)
|
g.rce.DrawIndexedPrimitives(mtl.PrimitiveTypeTriangle, indexLen, mtl.IndexTypeUInt16, g.ib, indexOffset*2)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user