internal/graphicsdriver/directx: bug fix: wrong state transitions at screen images

This change fixes the following issues:
 * There should be two resource states for presenting targets, so an image
   for the screen must have two resource states, though it had only one
   in the current implementation.
 * At removeImage, the screen image was removed unexpectedly.

Updates #2081
Closes #2151
This commit is contained in:
Hajime Hoshi 2022-06-18 18:42:08 +09:00
parent 522660c1f9
commit b71a4975dd

View File

@ -632,8 +632,7 @@ func (g *Graphics) End(present bool) error {
return err
}
// The screen image can be nil when resizing the window (#2081).
if present && g.screenImage != nil {
if present {
g.screenImage.transiteState(g.drawCommandList, _D3D12_RESOURCE_STATE_PRESENT)
}
@ -884,7 +883,7 @@ func (g *Graphics) NewImage(width, height int) (graphicsdriver.Image, error) {
width: width,
height: height,
texture: t,
state: state,
states: [frameCount]_D3D12_RESOURCE_STATES{state},
layouts: layouts,
totalBytes: totalBytes,
}
@ -903,9 +902,10 @@ func (g *Graphics) NewScreenFramebufferImage(width, height int) (graphicsdriver.
width: width,
height: height,
screen: true,
state: _D3D12_RESOURCE_STATE_PRESENT,
states: [frameCount]_D3D12_RESOURCE_STATES{0, 0},
}
g.addImage(i)
g.screenImage = i
return i, nil
}
@ -917,17 +917,11 @@ func (g *Graphics) addImage(img *Image) {
panic(fmt.Sprintf("directx: image ID %d was already registered", img.id))
}
g.images[img.id] = img
if img.screen {
g.screenImage = img
}
}
func (g *Graphics) removeImage(img *Image) {
delete(g.images, img.id)
g.disposedImages[g.frameIndex] = append(g.disposedImages[g.frameIndex], img)
if img.screen {
g.screenImage = nil
}
}
func (g *Graphics) addShader(s *Shader) {
@ -1251,7 +1245,7 @@ type Image struct {
height int
screen bool
state _D3D12_RESOURCE_STATES
states [frameCount]_D3D12_RESOURCE_STATES
texture *_ID3D12Resource
stencil *_ID3D12Resource
layouts _D3D12_PLACED_SUBRESOURCE_FOOTPRINT
@ -1448,8 +1442,23 @@ func (i *Image) resource() *_ID3D12Resource {
return i.texture
}
func (i *Image) state() _D3D12_RESOURCE_STATES {
if i.screen {
return i.states[i.graphics.frameIndex]
}
return i.states[0]
}
func (i *Image) setState(newState _D3D12_RESOURCE_STATES) {
if i.screen {
i.states[i.graphics.frameIndex] = newState
return
}
i.states[0] = newState
}
func (i *Image) transiteState(commandList *_ID3D12GraphicsCommandList, newState _D3D12_RESOURCE_STATES) {
if i.state == newState {
if i.state() == newState {
return
}
@ -1460,12 +1469,12 @@ func (i *Image) transiteState(commandList *_ID3D12GraphicsCommandList, newState
Transition: _D3D12_RESOURCE_TRANSITION_BARRIER{
pResource: i.resource(),
Subresource: _D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES,
StateBefore: i.state,
StateBefore: i.state(),
StateAfter: newState,
},
},
})
i.state = newState
i.setState(newState)
}
func (i *Image) internalSize() (int, int) {