From 1b3bfda17b22745990d214526288dcf23019318b Mon Sep 17 00:00:00 2001 From: Zyko <13394516+Zyko0@users.noreply.github.com> Date: Wed, 10 Apr 2024 19:10:21 +0200 Subject: [PATCH] Fixed empty target for directx11 --- examples/mrt/main.go | 2 +- .../directx/graphics11_windows.go | 89 ++++++++++++++++--- .../graphicsdriver/directx/image11_windows.go | 63 ------------- 3 files changed, 78 insertions(+), 76 deletions(-) diff --git a/examples/mrt/main.go b/examples/mrt/main.go index 15c34d949..3435bcd71 100644 --- a/examples/mrt/main.go +++ b/examples/mrt/main.go @@ -127,7 +127,7 @@ func main() { ebiten.SetVsyncEnabled(false) ebiten.SetWindowTitle("MRT (Ebitengine Demo)") if err := ebiten.RunGameWithOptions(&Game{}, &ebiten.RunGameOptions{ - GraphicsLibrary: ebiten.GraphicsLibraryOpenGL, + GraphicsLibrary: ebiten.GraphicsLibraryDirectX, }); err != nil { log.Fatal(err) } diff --git a/internal/graphicsdriver/directx/graphics11_windows.go b/internal/graphicsdriver/directx/graphics11_windows.go index 56db26ac9..262de28e4 100644 --- a/internal/graphicsdriver/directx/graphics11_windows.go +++ b/internal/graphicsdriver/directx/graphics11_windows.go @@ -515,6 +515,69 @@ func (g *graphics11) removeShader(s *shader11) { delete(g.shaders, s.id) } +func (g *graphics11) setAsRenderTargets(dsts []*image11, useStencil bool) error { + var rtvs []*_ID3D11RenderTargetView + for _, i := range dsts { + // Ignore a nil image in case of MRT + if i == nil { + rtvs = append(rtvs, nil) + continue + } + if i.renderTargetView == nil { + rtv, err := g.device.CreateRenderTargetView(unsafe.Pointer(i.texture), nil) + if err != nil { + return err + } + i.renderTargetView = rtv + } + rtvs = append(rtvs, i.renderTargetView) + + if !useStencil { + continue + } + + if i.screen { + return fmt.Errorf("directx: a stencil buffer is not available for a screen image") + } + if i.stencilView == nil { + sv, err := g.device.CreateDepthStencilView(unsafe.Pointer(i.stencil), nil) + if err != nil { + return err + } + i.stencilView = sv + } + if i.stencil == nil { + w, h := i.internalSize() + s, err := g.device.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{ + Width: uint32(w), + Height: uint32(h), + MipLevels: 0, + ArraySize: 1, + Format: _DXGI_FORMAT_D24_UNORM_S8_UINT, + SampleDesc: _DXGI_SAMPLE_DESC{ + Count: 1, + Quality: 0, + }, + Usage: _D3D11_USAGE_DEFAULT, + BindFlags: uint32(_D3D11_BIND_DEPTH_STENCIL), + CPUAccessFlags: 0, + MiscFlags: 0, + }, nil) + if err != nil { + return err + } + i.stencil = s + } + } + + g.deviceContext.OMSetRenderTargets(rtvs, dsts[0].stencilView) + if useStencil { + g.deviceContext.ClearDepthStencilView(dsts[0].stencilView, uint8(_D3D11_CLEAR_STENCIL), 0, 0) + } + + return nil +} + func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphicsdriver.ImageID, srcIDs [graphics.ShaderSrcImageCount]graphicsdriver.ImageID, shaderID graphicsdriver.ShaderID, dstRegions []graphicsdriver.DstRegion, indexOffset int, blend graphicsdriver.Blend, uniforms []uint32, fillRule graphicsdriver.FillRule) error { // Remove bound textures first. This is needed to avoid warnings on the debugger. g.deviceContext.OMSetRenderTargets([]*_ID3D11RenderTargetView{nil}, nil) @@ -522,12 +585,24 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics g.deviceContext.PSSetShaderResources(0, srvs[:]) var dsts []*image11 + var viewports []_D3D11_VIEWPORT for _, id := range dstIDs { img := g.images[id] if img == nil { + dsts = append(dsts, nil) + viewports = append(viewports, _D3D11_VIEWPORT{}) continue } dsts = append(dsts, img) + w, h := img.internalSize() + viewports = append(viewports, _D3D11_VIEWPORT{ + TopLeftX: 0, + TopLeftY: 0, + Width: float32(w), + Height: float32(h), + MinDepth: 0, + MaxDepth: 1, + }) } var srcs [graphics.ShaderSrcImageCount]*image11 @@ -539,19 +614,9 @@ func (g *graphics11) DrawTriangles(dstIDs [graphics.ShaderDstImageCount]graphics srcs[i] = img } - w, h := dsts[0].internalSize() - g.deviceContext.RSSetViewports([]_D3D11_VIEWPORT{ - { - TopLeftX: 0, - TopLeftY: 0, - Width: float32(w), - Height: float32(h), - MinDepth: 0, - MaxDepth: 1, - }, - }) + g.deviceContext.RSSetViewports(viewports) - if err := setAsRenderTargets(dsts, fillRule != graphicsdriver.FillAll); err != nil { + if err := g.setAsRenderTargets(dsts, fillRule != graphicsdriver.FillAll); err != nil { return err } diff --git a/internal/graphicsdriver/directx/image11_windows.go b/internal/graphicsdriver/directx/image11_windows.go index b78f0b317..1b3adb150 100644 --- a/internal/graphicsdriver/directx/image11_windows.go +++ b/internal/graphicsdriver/directx/image11_windows.go @@ -204,69 +204,6 @@ func (i *image11) setAsRenderTarget(useStencil bool) error { return nil } -func setAsRenderTargets(dsts []*image11, useStencil bool) error { - for _, i := range dsts { - if i.renderTargetView == nil { - rtv, err := i.graphics.device.CreateRenderTargetView(unsafe.Pointer(i.texture), nil) - if err != nil { - return err - } - i.renderTargetView = rtv - } - - if !useStencil { - continue - } - - if i.screen { - return fmt.Errorf("directx: a stencil buffer is not available for a screen image") - } - if i.stencilView == nil { - sv, err := i.graphics.device.CreateDepthStencilView(unsafe.Pointer(i.stencil), nil) - if err != nil { - return err - } - i.stencilView = sv - } - if i.stencil == nil { - w, h := i.internalSize() - s, err := i.graphics.device.CreateTexture2D(&_D3D11_TEXTURE2D_DESC{ - Width: uint32(w), - Height: uint32(h), - MipLevels: 0, - ArraySize: 1, - Format: _DXGI_FORMAT_D24_UNORM_S8_UINT, - SampleDesc: _DXGI_SAMPLE_DESC{ - Count: 1, - Quality: 0, - }, - Usage: _D3D11_USAGE_DEFAULT, - BindFlags: uint32(_D3D11_BIND_DEPTH_STENCIL), - CPUAccessFlags: 0, - MiscFlags: 0, - }, nil) - if err != nil { - return err - } - i.stencil = s - } - } - - var rtvs []*_ID3D11RenderTargetView - var dsvs []*_ID3D11DepthStencilView - for _, i := range dsts { - rtvs = append(rtvs, i.renderTargetView) - dsvs = append(dsvs, i.stencilView) - } - - dsts[0].graphics.deviceContext.OMSetRenderTargets(rtvs, dsts[0].stencilView) - if useStencil { - dsts[0].graphics.deviceContext.ClearDepthStencilView(dsts[0].stencilView, uint8(_D3D11_CLEAR_STENCIL), 0, 0) - } - - return nil -} - func (i *image11) getShaderResourceView() (*_ID3D11ShaderResourceView, error) { if i.shaderResourceView == nil { srv, err := i.graphics.device.CreateShaderResourceView(unsafe.Pointer(i.texture), nil)