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 <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-03-04 19:13:04 +01:00
parent 44991f355c
commit 840b9ffa9b
4 changed files with 32 additions and 18 deletions
+26 -18
View File
@@ -22,8 +22,6 @@ type Device struct {
ctx *_ID3D11DeviceContext ctx *_ID3D11DeviceContext
featLvl uint32 featLvl uint32
floatFormat uint32 floatFormat uint32
depthStates map[depthState]*_ID3D11DepthStencilState
blendStates map[blendState]*_ID3D11BlendState
} }
type Backend struct { type Backend struct {
@@ -32,13 +30,19 @@ type Backend struct {
viewport _D3D11_VIEWPORT viewport _D3D11_VIEWPORT
depthState depthState depthState depthState
blendState blendState blendState blendState
prog *Program
// Current program.
prog *Program
dev *Device dev *Device
caps backend.Caps caps backend.Caps
// fbo is the currently bound fbo. // fbo is the currently bound fbo.
fbo *Framebuffer fbo *Framebuffer
// cached state objects.
depthStates map[depthState]*_ID3D11DepthStencilState
blendStates map[blendState]*_ID3D11BlendState
} }
type blendState struct { type blendState struct {
@@ -123,8 +127,6 @@ func NewDevice() (*Device, error) {
} }
floatFormat, _ := detectFloatFormat(d3ddev) floatFormat, _ := detectFloatFormat(d3ddev)
dev.floatFormat = floatFormat dev.floatFormat = floatFormat
dev.depthStates = make(map[depthState]*_ID3D11DepthStencilState)
dev.blendStates = make(map[blendState]*_ID3D11BlendState)
return dev, nil return dev, nil
} }
@@ -223,14 +225,6 @@ func (d *Device) Release() {
_IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release) _IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release)
d.ctx = nil d.ctx = nil
d.dev = 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 { func (s *SwapChain) Resize() error {
@@ -261,7 +255,11 @@ func NewBackend(d *Device) (*Backend, error) {
case d.featLvl >= _D3D_FEATURE_LEVEL_9_3: case d.featLvl >= _D3D_FEATURE_LEVEL_9_3:
caps.MaxTextureSize = 4096 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. // Enable depth mask to match OpenGL.
b.depthState.mask = true b.depthState.mask = true
// Disable backface culling to match OpenGL. // Disable backface culling to match OpenGL.
@@ -305,6 +303,16 @@ func (b *Backend) IsTimeContinuous() bool {
panic("timers not supported") 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) { func (b *Backend) NewTexture(format backend.TextureFormat, width, height int, minFilter, magFilter backend.TextureFilter, bindings backend.BufferBinding) (backend.Texture, error) {
var d3dfmt uint32 var d3dfmt uint32
switch format { switch format {
@@ -597,7 +605,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
} }
b.dev.ctx.IASetPrimitiveTopology(topology) b.dev.ctx.IASetPrimitiveTopology(topology)
depthState, ok := b.dev.depthStates[b.depthState] depthState, ok := b.depthStates[b.depthState]
if !ok { if !ok {
var desc _D3D11_DEPTH_STENCIL_DESC var desc _D3D11_DEPTH_STENCIL_DESC
if b.depthState.enable { if b.depthState.enable {
@@ -619,11 +627,11 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
b.dev.depthStates[b.depthState] = depthState b.depthStates[b.depthState] = depthState
} }
b.dev.ctx.OMSetDepthStencilState(depthState, 0) b.dev.ctx.OMSetDepthStencilState(depthState, 0)
blendState, ok := b.dev.blendStates[b.blendState] blendState, ok := b.blendStates[b.blendState]
if !ok { if !ok {
var desc _D3D11_BLEND_DESC var desc _D3D11_BLEND_DESC
t0 := &desc.RenderTarget[0] t0 := &desc.RenderTarget[0]
@@ -644,7 +652,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
if err != nil { if err != nil {
panic(err) panic(err)
} }
b.dev.blendStates[b.blendState] = blendState b.blendStates[b.blendState] = blendState
} }
b.dev.ctx.OMSetBlendState(blendState, nil, 0xffffffff) b.dev.ctx.OMSetBlendState(blendState, nil, 0xffffffff)
} }
+2
View File
@@ -48,6 +48,8 @@ type Device interface {
MemoryBarrier() MemoryBarrier()
DispatchCompute(x, y, z int) DispatchCompute(x, y, z int)
Release()
} }
type ShaderSources struct { type ShaderSources struct {
+3
View File
@@ -310,6 +310,9 @@ func glErr(f *glimpl.Functions) error {
return nil return nil
} }
func (b *Backend) Release() {
}
func (b *Backend) MemoryBarrier() { func (b *Backend) MemoryBarrier() {
b.funcs.MemoryBarrier(glimpl.ALL_BARRIER_BITS) b.funcs.MemoryBarrier(glimpl.ALL_BARRIER_BITS)
} }
+1
View File
@@ -422,6 +422,7 @@ func (g *gpu) Release() {
if g.timers != nil { if g.timers != nil {
g.timers.release() g.timers.release()
} }
g.ctx.Release()
} }
func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) { func (g *gpu) Collect(viewport image.Point, frameOps *op.Ops) {