From b48c2aa1038c1592a21e0b711d51911bb6c39066 Mon Sep 17 00:00:00 2001 From: Hajime Hoshi Date: Fri, 15 Jul 2022 03:40:22 +0900 Subject: [PATCH] internal/graphicsdriver/directx: bug fix: too many constant buffers could be allocated Closes #2204 --- image_test.go | 44 +++++++++++++++++++ .../directx/graphics_windows.go | 20 +++++---- 2 files changed, 56 insertions(+), 8 deletions(-) diff --git a/image_test.go b/image_test.go index 954dccae8..e3b3404ff 100644 --- a/image_test.go +++ b/image_test.go @@ -3376,3 +3376,47 @@ func TestImageSetOverSet(t *testing.T) { t.Errorf("got: %v, want: %v", got, want) } } + +// Issue #2204 +func TestImageTooManyConstantBuffersInDirectX(t *testing.T) { + src := ebiten.NewImage(3, 3) + src.Fill(color.White) + src = src.SubImage(image.Rect(1, 1, 2, 2)).(*ebiten.Image) + + vs := []ebiten.Vertex{ + { + DstX: 0, DstY: 0, SrcX: 1, SrcY: 1, + ColorR: 1, ColorG: 1, ColorB: 1, ColorA: 1, + }, + { + DstX: 16, DstY: 0, SrcX: 1, SrcY: 1, + ColorR: 1, ColorG: 1, ColorB: 1, ColorA: 1, + }, + { + DstX: 0, DstY: 16, SrcX: 1, SrcY: 1, + ColorR: 1, ColorG: 1, ColorB: 1, ColorA: 1, + }, + { + DstX: 16, DstY: 16, SrcX: 1, SrcY: 1, + ColorR: 1, ColorG: 1, ColorB: 1, ColorA: 1, + }, + } + is := []uint16{0, 1, 2, 1, 2, 3} + + dst0 := ebiten.NewImage(16, 16) + dst1 := ebiten.NewImage(16, 16) + op := &ebiten.DrawTrianglesOptions{ + FillRule: ebiten.EvenOdd, + } + for i := 0; i < 100; i++ { + dst0.DrawTriangles(vs, is, src, op) + dst1.DrawTriangles(vs, is, src, op) + } + + if got, want := dst0.At(0, 0), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want { + t.Errorf("got: %v, want: %v", got, want) + } + if got, want := dst1.At(0, 0), (color.RGBA{0xff, 0xff, 0xff, 0xff}); got != want { + t.Errorf("got: %v, want: %v", got, want) + } +} diff --git a/internal/graphicsdriver/directx/graphics_windows.go b/internal/graphicsdriver/directx/graphics_windows.go index 298cdf418..a7fe0b8ed 100644 --- a/internal/graphicsdriver/directx/graphics_windows.go +++ b/internal/graphicsdriver/directx/graphics_windows.go @@ -1160,6 +1160,18 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.Sh return err } + // Release constant buffers when too many ones were created. + numPipelines := 1 + if evenOdd { + numPipelines = 2 + } + if len(g.pipelineStates.constantBuffers[g.frameIndex])+numPipelines > numDescriptorsPerFrame { + if err := g.flushCommandList(g.drawCommandList); err != nil { + return err + } + g.pipelineStates.releaseConstantBuffers(g.frameIndex) + } + dst := g.images[dstID] var resourceBarriers []_D3D12_RESOURCE_BARRIER_Transition if rb, ok := dst.transiteState(_D3D12_RESOURCE_STATE_RENDER_TARGET); ok { @@ -1382,14 +1394,6 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.Sh } } - // Release constant buffers when too many ones were created. - if len(g.pipelineStates.constantBuffers[g.frameIndex]) >= numDescriptorsPerFrame { - if err := g.flushCommandList(g.drawCommandList); err != nil { - return err - } - g.pipelineStates.releaseConstantBuffers(g.frameIndex) - } - return nil }