app/internal/d3d11: only use passed in ID3D11Device in NewBackend

We're about to enable drawing into foreign Direct3D contexts. In
preparation, NewBackend should only need a device handle.

Signed-off-by: Elias Naur <mail@eliasnaur.com>
This commit is contained in:
Elias Naur
2021-03-04 19:51:05 +01:00
parent 932465d891
commit c3dde562df
2 changed files with 49 additions and 32 deletions
+37 -32
View File
@@ -23,6 +23,8 @@ type Device struct {
} }
type Backend struct { type Backend struct {
ctx *_ID3D11DeviceContext
// Temporary storage to avoid garbage. // Temporary storage to avoid garbage.
clearColor [4]float32 clearColor [4]float32
viewport _D3D11_VIEWPORT viewport _D3D11_VIEWPORT
@@ -82,7 +84,8 @@ type Program struct {
} }
type Framebuffer struct { type Framebuffer struct {
dev *Device dev *_ID3D11Device
ctx *_ID3D11DeviceContext
format uint32 format uint32
resource *_ID3D11Resource resource *_ID3D11Resource
renderTarget *_ID3D11RenderTargetView renderTarget *_ID3D11RenderTargetView
@@ -209,15 +212,15 @@ func (s *SwapChain) Framebuffer(d *Device) (*Framebuffer, error) {
} }
s.fbo.renderTarget = renderTarget s.fbo.renderTarget = renderTarget
s.fbo.depthView = depthView s.fbo.depthView = depthView
s.fbo.dev = d s.fbo.dev = d.dev
s.fbo.ctx = d.ctx
return s.fbo, nil return s.fbo, nil
} }
func (d *Device) Release() { func (d *Device) Release() {
_IUnknownRelease(unsafe.Pointer(d.ctx), d.ctx.vtbl.Release) _IUnknownRelease(unsafe.Pointer(d.ctx), d.ctx.vtbl.Release)
_IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release) _IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release)
d.ctx = nil *d = Device{}
d.dev = nil
} }
func (s *SwapChain) Resize() error { func (s *SwapChain) Resize() error {
@@ -238,6 +241,7 @@ func (s *SwapChain) Present() error {
func NewBackend(d *Device) (*Backend, error) { func NewBackend(d *Device) (*Backend, error) {
b := &Backend{ b := &Backend{
dev: d, dev: d,
ctx: d.dev.GetImmediateContext(),
caps: backend.Caps{ caps: backend.Caps{
MaxTextureSize: 2048, // 9.1 maximum MaxTextureSize: 2048, // 9.1 maximum
}, },
@@ -247,7 +251,7 @@ func NewBackend(d *Device) (*Backend, error) {
featLvl := d.dev.GetFeatureLevel() featLvl := d.dev.GetFeatureLevel()
if featLvl < _D3D_FEATURE_LEVEL_9_1 { if featLvl < _D3D_FEATURE_LEVEL_9_1 {
_IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release) _IUnknownRelease(unsafe.Pointer(d.dev), d.dev.vtbl.Release)
_IUnknownRelease(unsafe.Pointer(d.ctx), d.ctx.vtbl.Release) _IUnknownRelease(unsafe.Pointer(b.ctx), b.ctx.vtbl.Release)
return nil, fmt.Errorf("d3d11: feature level too low: %d", featLvl) return nil, fmt.Errorf("d3d11: feature level too low: %d", featLvl)
} }
switch { switch {
@@ -272,12 +276,12 @@ func NewBackend(d *Device) (*Backend, error) {
return nil, err return nil, err
} }
defer _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release) defer _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release)
b.dev.ctx.RSSetState(state) b.ctx.RSSetState(state)
return b, nil return b, nil
} }
func (b *Backend) BeginFrame() backend.Framebuffer { func (b *Backend) BeginFrame() backend.Framebuffer {
renderTarget, depthView := b.dev.ctx.OMGetRenderTargets() renderTarget, depthView := b.ctx.OMGetRenderTargets()
// Assume someone else is holding on to the render targets. // Assume someone else is holding on to the render targets.
if renderTarget != nil { if renderTarget != nil {
_IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release) _IUnknownRelease(unsafe.Pointer(renderTarget), renderTarget.vtbl.Release)
@@ -285,7 +289,7 @@ func (b *Backend) BeginFrame() backend.Framebuffer {
if depthView != nil { if depthView != nil {
_IUnknownRelease(unsafe.Pointer(depthView), depthView.vtbl.Release) _IUnknownRelease(unsafe.Pointer(depthView), depthView.vtbl.Release)
} }
return &Framebuffer{dev: b.dev, renderTarget: renderTarget, depthView: depthView, foreign: true} return &Framebuffer{ctx: b.ctx, dev: b.dev.dev, renderTarget: renderTarget, depthView: depthView, foreign: true}
} }
func (b *Backend) EndFrame() { func (b *Backend) EndFrame() {
@@ -310,6 +314,7 @@ func (b *Backend) Release() {
for _, state := range b.blendStates { for _, state := range b.blendStates {
_IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release) _IUnknownRelease(unsafe.Pointer(state), state.vtbl.Release)
} }
_IUnknownRelease(unsafe.Pointer(b.ctx), b.ctx.vtbl.Release)
*b = Backend{} *b = Backend{}
} }
@@ -399,7 +404,7 @@ func (b *Backend) NewFramebuffer(tex backend.Texture, depthBits int) (backend.Fr
if err != nil { if err != nil {
return nil, err return nil, err
} }
fbo := &Framebuffer{dev: b.dev, format: d3dtex.format, resource: resource, renderTarget: renderTarget} fbo := &Framebuffer{ctx: b.ctx, dev: b.dev.dev, format: d3dtex.format, resource: resource, renderTarget: renderTarget}
if depthBits > 0 { if depthBits > 0 {
depthView, err := createDepthView(b.dev.dev, d3dtex.width, d3dtex.height, depthBits) depthView, err := createDepthView(b.dev.dev, d3dtex.width, d3dtex.height, depthBits)
if err != nil { if err != nil {
@@ -552,12 +557,12 @@ func (b *Backend) NewProgram(vertexShader, fragmentShader backend.ShaderSources)
func (b *Backend) Clear(colr, colg, colb, cola float32) { func (b *Backend) Clear(colr, colg, colb, cola float32) {
b.clearColor = [4]float32{colr, colg, colb, cola} b.clearColor = [4]float32{colr, colg, colb, cola}
b.dev.ctx.ClearRenderTargetView(b.fbo.renderTarget, &b.clearColor) b.ctx.ClearRenderTargetView(b.fbo.renderTarget, &b.clearColor)
} }
func (b *Backend) ClearDepth(depth float32) { func (b *Backend) ClearDepth(depth float32) {
if b.fbo.depthView != nil { if b.fbo.depthView != nil {
b.dev.ctx.ClearDepthStencilView(b.fbo.depthView, _D3D11_CLEAR_DEPTH|_D3D11_CLEAR_STENCIL, depth, 0) b.ctx.ClearDepthStencilView(b.fbo.depthView, _D3D11_CLEAR_DEPTH|_D3D11_CLEAR_STENCIL, depth, 0)
} }
} }
@@ -570,28 +575,28 @@ func (b *Backend) Viewport(x, y, width, height int) {
MinDepth: 0.0, MinDepth: 0.0,
MaxDepth: 1.0, MaxDepth: 1.0,
} }
b.dev.ctx.RSSetViewports(&b.viewport) b.ctx.RSSetViewports(&b.viewport)
} }
func (b *Backend) DrawArrays(mode backend.DrawMode, off, count int) { func (b *Backend) DrawArrays(mode backend.DrawMode, off, count int) {
b.prepareDraw(mode) b.prepareDraw(mode)
b.dev.ctx.Draw(uint32(count), uint32(off)) b.ctx.Draw(uint32(count), uint32(off))
} }
func (b *Backend) DrawElements(mode backend.DrawMode, off, count int) { func (b *Backend) DrawElements(mode backend.DrawMode, off, count int) {
b.prepareDraw(mode) b.prepareDraw(mode)
b.dev.ctx.DrawIndexed(uint32(count), uint32(off), 0) b.ctx.DrawIndexed(uint32(count), uint32(off), 0)
} }
func (b *Backend) prepareDraw(mode backend.DrawMode) { func (b *Backend) prepareDraw(mode backend.DrawMode) {
if p := b.prog; p != nil { if p := b.prog; p != nil {
b.dev.ctx.VSSetShader(p.vert.shader) b.ctx.VSSetShader(p.vert.shader)
b.dev.ctx.PSSetShader(p.frag.shader) b.ctx.PSSetShader(p.frag.shader)
if buf := p.vert.uniforms; buf != nil { if buf := p.vert.uniforms; buf != nil {
b.dev.ctx.VSSetConstantBuffers(buf.buf) b.ctx.VSSetConstantBuffers(buf.buf)
} }
if buf := p.frag.uniforms; buf != nil { if buf := p.frag.uniforms; buf != nil {
b.dev.ctx.PSSetConstantBuffers(buf.buf) b.ctx.PSSetConstantBuffers(buf.buf)
} }
} }
var topology uint32 var topology uint32
@@ -603,7 +608,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
default: default:
panic("unsupported draw mode") panic("unsupported draw mode")
} }
b.dev.ctx.IASetPrimitiveTopology(topology) b.ctx.IASetPrimitiveTopology(topology)
depthState, ok := b.depthStates[b.depthState] depthState, ok := b.depthStates[b.depthState]
if !ok { if !ok {
@@ -629,7 +634,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
} }
b.depthStates[b.depthState] = depthState b.depthStates[b.depthState] = depthState
} }
b.dev.ctx.OMSetDepthStencilState(depthState, 0) b.ctx.OMSetDepthStencilState(depthState, 0)
blendState, ok := b.blendStates[b.blendState] blendState, ok := b.blendStates[b.blendState]
if !ok { if !ok {
@@ -654,7 +659,7 @@ func (b *Backend) prepareDraw(mode backend.DrawMode) {
} }
b.blendStates[b.blendState] = blendState b.blendStates[b.blendState] = blendState
} }
b.dev.ctx.OMSetBlendState(blendState, nil, 0xffffffff) b.ctx.OMSetBlendState(blendState, nil, 0xffffffff)
} }
func (b *Backend) DepthFunc(f backend.DepthFunc) { func (b *Backend) DepthFunc(f backend.DepthFunc) {
@@ -701,7 +706,7 @@ func (t *Texture) Upload(offset, size image.Point, pixels []byte) {
back: 1, back: 1,
} }
res := (*_ID3D11Resource)(unsafe.Pointer(t.tex)) res := (*_ID3D11Resource)(unsafe.Pointer(t.tex))
t.backend.dev.ctx.UpdateSubresource(res, dst, uint32(stride), uint32(len(pixels)), pixels) t.backend.ctx.UpdateSubresource(res, dst, uint32(stride), uint32(len(pixels)), pixels)
} }
func (t *Texture) Release() { func (t *Texture) Release() {
@@ -719,8 +724,8 @@ func (t *Texture) Release() {
func (b *Backend) BindTexture(unit int, tex backend.Texture) { func (b *Backend) BindTexture(unit int, tex backend.Texture) {
t := tex.(*Texture) t := tex.(*Texture)
b.dev.ctx.PSSetSamplers(uint32(unit), t.sampler) b.ctx.PSSetSamplers(uint32(unit), t.sampler)
b.dev.ctx.PSSetShaderResources(uint32(unit), t.resView) b.ctx.PSSetShaderResources(uint32(unit), t.resView)
} }
func (b *Backend) BindProgram(prog backend.Program) { func (b *Backend) BindProgram(prog backend.Program) {
@@ -747,11 +752,11 @@ func (p *Program) SetFragmentUniforms(buf backend.Buffer) {
} }
func (b *Backend) BindVertexBuffer(buf backend.Buffer, stride, offset int) { func (b *Backend) BindVertexBuffer(buf backend.Buffer, stride, offset int) {
b.dev.ctx.IASetVertexBuffers(buf.(*Buffer).buf, uint32(stride), uint32(offset)) b.ctx.IASetVertexBuffers(buf.(*Buffer).buf, uint32(stride), uint32(offset))
} }
func (b *Backend) BindIndexBuffer(buf backend.Buffer) { func (b *Backend) BindIndexBuffer(buf backend.Buffer) {
b.dev.ctx.IASetIndexBuffer(buf.(*Buffer).buf, _DXGI_FORMAT_R16_UINT, 0) b.ctx.IASetIndexBuffer(buf.(*Buffer).buf, _DXGI_FORMAT_R16_UINT, 0)
} }
func (b *Buffer) Download(data []byte) error { func (b *Buffer) Download(data []byte) error {
@@ -759,7 +764,7 @@ func (b *Buffer) Download(data []byte) error {
} }
func (b *Buffer) Upload(data []byte) { func (b *Buffer) Upload(data []byte) {
b.backend.dev.ctx.UpdateSubresource((*_ID3D11Resource)(unsafe.Pointer(b.buf)), nil, 0, 0, data) b.backend.ctx.UpdateSubresource((*_ID3D11Resource)(unsafe.Pointer(b.buf)), nil, 0, 0, data)
} }
func (b *Buffer) Release() { func (b *Buffer) Release() {
@@ -772,7 +777,7 @@ func (f *Framebuffer) ReadPixels(src image.Rectangle, pixels []byte) error {
return errors.New("framebuffer does not support ReadPixels") return errors.New("framebuffer does not support ReadPixels")
} }
w, h := src.Dx(), src.Dy() w, h := src.Dx(), src.Dy()
tex, err := f.dev.dev.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{ tex, err := f.dev.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{
Width: uint32(w), Width: uint32(w),
Height: uint32(h), Height: uint32(h),
MipLevels: 1, MipLevels: 1,
@@ -790,7 +795,7 @@ func (f *Framebuffer) ReadPixels(src image.Rectangle, pixels []byte) error {
} }
defer _IUnknownRelease(unsafe.Pointer(tex), tex.vtbl.Release) defer _IUnknownRelease(unsafe.Pointer(tex), tex.vtbl.Release)
res := (*_ID3D11Resource)(unsafe.Pointer(tex)) res := (*_ID3D11Resource)(unsafe.Pointer(tex))
f.dev.ctx.CopySubresourceRegion( f.ctx.CopySubresourceRegion(
res, res,
0, // Destination subresource. 0, // Destination subresource.
0, 0, 0, // Destination coordinates (x, y, z). 0, 0, 0, // Destination coordinates (x, y, z).
@@ -805,11 +810,11 @@ func (f *Framebuffer) ReadPixels(src image.Rectangle, pixels []byte) error {
back: 1, back: 1,
}, },
) )
resMap, err := f.dev.ctx.Map(res, 0, _D3D11_MAP_READ, 0) resMap, err := f.ctx.Map(res, 0, _D3D11_MAP_READ, 0)
if err != nil { if err != nil {
return fmt.Errorf("ReadPixels: %v", err) return fmt.Errorf("ReadPixels: %v", err)
} }
defer f.dev.ctx.Unmap(res, 0) defer f.ctx.Unmap(res, 0)
srcPitch := w * 4 srcPitch := w * 4
dstPitch := int(resMap.RowPitch) dstPitch := int(resMap.RowPitch)
mapSize := dstPitch * h mapSize := dstPitch * h
@@ -845,7 +850,7 @@ func (f *Framebuffer) Release() {
} }
func (b *Backend) BindInputLayout(layout backend.InputLayout) { func (b *Backend) BindInputLayout(layout backend.InputLayout) {
b.dev.ctx.IASetInputLayout(layout.(*InputLayout).layout) b.ctx.IASetInputLayout(layout.(*InputLayout).layout)
} }
func (l *InputLayout) Release() { func (l *InputLayout) Release() {
+12
View File
@@ -924,6 +924,18 @@ func (d *_ID3D11Device) GetFeatureLevel() int {
return int(lvl) return int(lvl)
} }
func (d *_ID3D11Device) GetImmediateContext() *_ID3D11DeviceContext {
var ctx *_ID3D11DeviceContext
syscall.Syscall(
d.vtbl.GetImmediateContext,
2,
uintptr(unsafe.Pointer(d)),
uintptr(unsafe.Pointer(&ctx)),
0,
)
return ctx
}
func (s *_IDXGISwapChain) GetDesc() (_DXGI_SWAP_CHAIN_DESC, error) { func (s *_IDXGISwapChain) GetDesc() (_DXGI_SWAP_CHAIN_DESC, error) {
var desc _DXGI_SWAP_CHAIN_DESC var desc _DXGI_SWAP_CHAIN_DESC
r, _, _ := syscall.Syscall( r, _, _ := syscall.Syscall(