diff --git a/app/internal/d3d11/backend_windows.go b/app/internal/d3d11/backend_windows.go index c0d820b8..8d2b7183 100644 --- a/app/internal/d3d11/backend_windows.go +++ b/app/internal/d3d11/backend_windows.go @@ -22,8 +22,6 @@ type Device struct { ctx *_ID3D11DeviceContext featLvl uint32 floatFormat uint32 - depthStates map[depthState]*_ID3D11DepthStencilState - blendStates map[blendState]*_ID3D11BlendState } type Backend struct { @@ -32,13 +30,19 @@ type Backend struct { viewport _D3D11_VIEWPORT depthState depthState blendState blendState - prog *Program + + // Current program. + prog *Program dev *Device caps backend.Caps // fbo is the currently bound fbo. fbo *Framebuffer + + // cached state objects. + depthStates map[depthState]*_ID3D11DepthStencilState + blendStates map[blendState]*_ID3D11BlendState } type blendState struct { @@ -123,8 +127,6 @@ func NewDevice() (*Device, error) { } floatFormat, _ := detectFloatFormat(d3ddev) dev.floatFormat = floatFormat - dev.depthStates = make(map[depthState]*_ID3D11DepthStencilState) - dev.blendStates = make(map[blendState]*_ID3D11BlendState) return dev, nil } @@ -223,14 +225,6 @@ func (d *Device) Release() { _IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release) d.ctx = nil d.dev = nil - for _, state := range d.depthStates { - _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release) - } - d.depthStates = nil - for _, state := range d.blendStates { - _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release) - } - d.blendStates = nil } func (s *SwapChain) Resize() error { @@ -261,7 +255,11 @@ func NewBackend(d *Device) (*Backend, error) { case d.featLvl >= _D3D_FEATURE_LEVEL_9_3: caps.MaxTextureSize = 4096 } - b := &Backend{dev: d, caps: caps} + b := &Backend{ + dev: d, caps: caps, + depthStates: make(map[depthState]*_ID3D11DepthStencilState), + blendStates: make(map[blendState]*_ID3D11BlendState), + } // Enable depth mask to match OpenGL. b.depthState.mask = true // Disable backface culling to match OpenGL. @@ -305,6 +303,16 @@ func (b *Backend) IsTimeContinuous() bool { panic("timers not supported") } +func (b *Backend) Release() { + for _, state := range b.depthStates { + _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release) + } + for _, state := range b.blendStates { + _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release) + } + *b = Backend{} +} + func (b *Backend) NewTexture(format backend.TextureFormat, width, height int, minFilter, magFilter backend.TextureFilter, bindings backend.BufferBinding) (backend.Texture, error) { var d3dfmt uint32 switch format { @@ -597,7 +605,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) { } b.dev.ctx.IASetPrimitiveTopology(topology) - depthState, ok := b.dev.depthStates[b.depthState] + depthState, ok := b.depthStates[b.depthState] if !ok { var desc _D3D11_DEPTH_STENCIL_DESC if b.depthState.enable { @@ -619,11 +627,11 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) { if err != nil { panic(err) } - b.dev.depthStates[b.depthState] = depthState + b.depthStates[b.depthState] = depthState } b.dev.ctx.OMSetDepthStencilState(depthState, 0) - blendState, ok := b.dev.blendStates[b.blendState] + blendState, ok := b.blendStates[b.blendState] if !ok { var desc _D3D11_BLEND_DESC t0 := &desc.RenderTarget[0] @@ -644,7 +652,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) { if err != nil { panic(err) } - b.dev.blendStates[b.blendState] = blendState + b.blendStates[b.blendState] = blendState } b.dev.ctx.OMSetBlendState(blendState, nil, 0xffffffff) } diff --git a/gpu/backend/backend.go b/gpu/backend/backend.go index 34fc3b4b..b8b6de53 100644 --- a/gpu/backend/backend.go +++ b/gpu/backend/backend.go @@ -48,6 +48,8 @@ type Device interface { MemoryBarrier() DispatchCompute(x, y, z int) + + Release() } type ShaderSources struct { diff --git a/gpu/gl/backend.go b/gpu/gl/backend.go index 443e4693..37d6e4bd 100644 --- a/gpu/gl/backend.go +++ b/gpu/gl/backend.go @@ -310,6 +310,9 @@ func glErr(f *glimpl.Functions) error { return nil } +func (b *Backend) Release() { +} + func (b *Backend) MemoryBarrier() { b.funcs.MemoryBarrier(glimpl.ALL_BARRIER_BITS) } diff --git a/gpu/gpu.go b/gpu/gpu.go index 0c621de6..df61b737 100644 --- a/gpu/gpu.go +++ b/gpu/gpu.go @@ -422,6 +422,7 @@ func (g *gpu) Release() { if g.timers != nil { g.timers.release() } + g.ctx.Release() } func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) {