internal/graphicsdriver/directx: batch ExecuteCommandList

Updates #2188
This commit is contained in:
Hajime Hoshi 2022-07-15 00:33:48 +09:00
parent 82d31c5fb7
commit f92107c2ee

View File

@ -632,15 +632,12 @@ func (g *Graphics) initSwapChainXbox(width, height int) (ferr error) {
} }
func (g *Graphics) resizeSwapChainDesktop(width, height int) error { func (g *Graphics) resizeSwapChainDesktop(width, height int) error {
if err := g.flushCommandList(g.copyCommandList); err != nil { if err := g.flushCommandList(g.copyCommandList, g.drawCommandList); err != nil {
return err return err
} }
if err := g.copyCommandList.Close(); err != nil { if err := g.copyCommandList.Close(); err != nil {
return err return err
} }
if err := g.flushCommandList(g.drawCommandList); err != nil {
return err
}
if err := g.drawCommandList.Close(); err != nil { if err := g.drawCommandList.Close(); err != nil {
return err return err
} }
@ -749,22 +746,18 @@ func (g *Graphics) Begin() error {
func (g *Graphics) End(present bool) error { func (g *Graphics) End(present bool) error {
// The swap chain might still be nil when Begin-End is invoked not by a frame (e.g., Image.At). // The swap chain might still be nil when Begin-End is invoked not by a frame (e.g., Image.At).
// As copyCommandList and drawCommandList are exclusive, the order should not matter here. if present {
if err := g.flushCommandList(g.copyCommandList); err != nil { g.screenImage.transiteState(g.drawCommandList, _D3D12_RESOURCE_STATE_PRESENT)
}
if err := g.flushCommandList(g.copyCommandList, g.drawCommandList); err != nil {
return err return err
} }
if err := g.copyCommandList.Close(); err != nil { if err := g.copyCommandList.Close(); err != nil {
return err return err
} }
if present {
g.screenImage.transiteState(g.drawCommandList, _D3D12_RESOURCE_STATE_PRESENT)
}
if err := g.drawCommandList.Close(); err != nil { if err := g.drawCommandList.Close(); err != nil {
return err return err
} }
g.commandQueue.ExecuteCommandLists([]*_ID3D12GraphicsCommandList{g.drawCommandList})
// Release vertices and indices buffers when too many ones were created. // Release vertices and indices buffers when too many ones were created.
// This is needed espciallly for testings, where present is always false. // This is needed espciallly for testings, where present is always false.
@ -885,44 +878,56 @@ func (g *Graphics) releaseVerticesAndIndices(frameIndex int) {
// flushCommandList executes commands in the command list and waits for its completion. // flushCommandList executes commands in the command list and waits for its completion.
// //
// TODO: This is not efficient. Is it possible to make two command lists work in parallel? // TODO: This is not efficient. Is it possible to make two command lists work in parallel?
func (g *Graphics) flushCommandList(commandList *_ID3D12GraphicsCommandList) error { func (g *Graphics) flushCommandList(commandLists ...*_ID3D12GraphicsCommandList) error {
switch commandList { var flushingCommandLists []*_ID3D12GraphicsCommandList
case g.drawCommandList: for _, commandList := range commandLists {
if !g.needFlushDrawCommandList { switch commandList {
return nil case g.drawCommandList:
if !g.needFlushDrawCommandList {
continue
}
g.needFlushDrawCommandList = false
flushingCommandLists = append(flushingCommandLists, commandList)
case g.copyCommandList:
if !g.needFlushCopyCommandList {
continue
}
g.needFlushCopyCommandList = false
flushingCommandLists = append(flushingCommandLists, commandList)
} }
g.needFlushDrawCommandList = false
case g.copyCommandList:
if !g.needFlushCopyCommandList {
return nil
}
g.needFlushCopyCommandList = false
} }
if err := commandList.Close(); err != nil { if len(flushingCommandLists) == 0 {
return err return nil
} }
g.commandQueue.ExecuteCommandLists([]*_ID3D12GraphicsCommandList{commandList}) for _, commandList := range flushingCommandLists {
if err := commandList.Close(); err != nil {
return err
}
}
g.commandQueue.ExecuteCommandLists(flushingCommandLists)
if err := g.waitForCommandQueue(); err != nil { if err := g.waitForCommandQueue(); err != nil {
return err return err
} }
switch commandList { for _, commandList := range flushingCommandLists {
case g.drawCommandList: switch commandList {
if err := g.drawCommandAllocators[g.frameIndex].Reset(); err != nil { case g.drawCommandList:
return err if err := g.drawCommandAllocators[g.frameIndex].Reset(); err != nil {
} return err
if err := commandList.Reset(g.drawCommandAllocators[g.frameIndex], nil); err != nil { }
return err if err := commandList.Reset(g.drawCommandAllocators[g.frameIndex], nil); err != nil {
} return err
case g.copyCommandList: }
if err := g.copyCommandAllocators[g.frameIndex].Reset(); err != nil { case g.copyCommandList:
return err if err := g.copyCommandAllocators[g.frameIndex].Reset(); err != nil {
} return err
if err := commandList.Reset(g.copyCommandAllocators[g.frameIndex], nil); err != nil { }
return err if err := commandList.Reset(g.copyCommandAllocators[g.frameIndex], nil); err != nil {
return err
}
} }
} }