internal/graphicsdriver/directx: bug fix: too many constant buffers could be allocated

Closes #2204
This commit is contained in:
Hajime Hoshi 2022-07-15 03:40:22 +09:00
parent e3d025bf4f
commit b48c2aa103
2 changed files with 56 additions and 8 deletions

View File

@ -3376,3 +3376,47 @@ func TestImageSetOverSet(t *testing.T) {
t.Errorf("got: %v, want: %v", got, want) 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)
}
}

View File

@ -1160,6 +1160,18 @@ func (g *Graphics) DrawTriangles(dstID graphicsdriver.ImageID, srcs [graphics.Sh
return err 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] dst := g.images[dstID]
var resourceBarriers []_D3D12_RESOURCE_BARRIER_Transition var resourceBarriers []_D3D12_RESOURCE_BARRIER_Transition
if rb, ok := dst.transiteState(_D3D12_RESOURCE_STATE_RENDER_TARGET); ok { 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 return nil
} }