From 840b9ffa9b703a5945c4fe5c098c71f9c5513a89 Mon Sep 17 00:00:00 2001 From: Elias Naur Date: Thu, 4 Mar 2021 19:13:04 +0100 Subject: [PATCH] gpu/backend,gpu,app/internal/d3d11: move device state to backend We'd like to allow Gio to share a Direct3D context with an embedding program like the GLFW example does for OpenGL. To do that, d3d11.Device needs to carry only the minimal information needed (ID3D11Device). This change moves the caches of ID3D11DepthStencilState and ID3D11BlendState from from d3d11.Device to d3d11.Backend. It also adds a Release method for freeing them. Signed-off-by: Elias Naur --- app/internal/d3d11/backend_windows.go | 44 ++++++++++++++++----------- gpu/backend/backend.go | 2 ++ gpu/gl/backend.go | 3 ++ gpu/gpu.go | 1 + 4 files changed, 32 insertions(+), 18 deletions(-) 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) {