mirror of
https://github.com/hajimehoshi/ebiten.git
synced 2024-12-25 03:08:54 +01:00
internal/graphicsdriver/directx: reduce memory usages when reading pixels
Updates #2294 Updates #2582
This commit is contained in:
parent
707a44e367
commit
264f0bad42
@ -26,7 +26,6 @@ import (
|
|||||||
"runtime"
|
"runtime"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/hajimehoshi/ebiten/v2"
|
"github.com/hajimehoshi/ebiten/v2"
|
||||||
"github.com/hajimehoshi/ebiten/v2/examples/resources/images"
|
"github.com/hajimehoshi/ebiten/v2/examples/resources/images"
|
||||||
@ -51,10 +50,6 @@ func skipTooSlowTests(t *testing.T) bool {
|
|||||||
t.Skip("too slow or fragile on Wasm")
|
t.Skip("too slow or fragile on Wasm")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if runtime.GOOS == "windows" && unsafe.Sizeof(uintptr(0)) == 4 {
|
|
||||||
t.Skip("out of memory often happens on 32bit Windows (#2332)")
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1335,7 +1335,6 @@ type Image struct {
|
|||||||
layouts _D3D12_PLACED_SUBRESOURCE_FOOTPRINT
|
layouts _D3D12_PLACED_SUBRESOURCE_FOOTPRINT
|
||||||
totalBytes uint64
|
totalBytes uint64
|
||||||
uploadingStagingBuffer *_ID3D12Resource
|
uploadingStagingBuffer *_ID3D12Resource
|
||||||
readingStagingBuffer *_ID3D12Resource
|
|
||||||
rtvDescriptorHeap *_ID3D12DescriptorHeap
|
rtvDescriptorHeap *_ID3D12DescriptorHeap
|
||||||
dsvDescriptorHeap *_ID3D12DescriptorHeap
|
dsvDescriptorHeap *_ID3D12DescriptorHeap
|
||||||
}
|
}
|
||||||
@ -1362,10 +1361,6 @@ func (i *Image) disposeImpl() {
|
|||||||
i.uploadingStagingBuffer.Release()
|
i.uploadingStagingBuffer.Release()
|
||||||
i.uploadingStagingBuffer = nil
|
i.uploadingStagingBuffer = nil
|
||||||
}
|
}
|
||||||
if i.readingStagingBuffer != nil {
|
|
||||||
i.readingStagingBuffer.Release()
|
|
||||||
i.readingStagingBuffer = nil
|
|
||||||
}
|
|
||||||
if i.stencil != nil {
|
if i.stencil != nil {
|
||||||
i.stencil.Release()
|
i.stencil.Release()
|
||||||
i.stencil = nil
|
i.stencil = nil
|
||||||
@ -1392,18 +1387,6 @@ func (i *Image) ensureUploadingStagingBuffer() error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Image) ensureReadingStagingBuffer() error {
|
|
||||||
if i.readingStagingBuffer != nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
var err error
|
|
||||||
i.readingStagingBuffer, err = createBuffer(i.graphics.device, i.totalBytes, _D3D12_HEAP_TYPE_READBACK)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (i *Image) ReadPixels(buf []byte, x, y, width, height int) error {
|
func (i *Image) ReadPixels(buf []byte, x, y, width, height int) error {
|
||||||
if i.screen {
|
if i.screen {
|
||||||
return errors.New("directx: Pixels cannot be called on the screen")
|
return errors.New("directx: Pixels cannot be called on the screen")
|
||||||
@ -1413,23 +1396,43 @@ func (i *Image) ReadPixels(buf []byte, x, y, width, height int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := i.ensureReadingStagingBuffer(); err != nil {
|
desc := _D3D12_RESOURCE_DESC{
|
||||||
|
Dimension: _D3D12_RESOURCE_DIMENSION_TEXTURE2D,
|
||||||
|
Alignment: 0,
|
||||||
|
Width: uint64(width),
|
||||||
|
Height: uint32(height),
|
||||||
|
DepthOrArraySize: 1,
|
||||||
|
MipLevels: 0,
|
||||||
|
Format: _DXGI_FORMAT_R8G8B8A8_UNORM,
|
||||||
|
SampleDesc: _DXGI_SAMPLE_DESC{
|
||||||
|
Count: 1,
|
||||||
|
Quality: 0,
|
||||||
|
},
|
||||||
|
Layout: _D3D12_TEXTURE_LAYOUT_UNKNOWN,
|
||||||
|
Flags: _D3D12_RESOURCE_FLAG_ALLOW_RENDER_TARGET,
|
||||||
|
}
|
||||||
|
layouts, _, _, totalBytes := i.graphics.device.GetCopyableFootprints(&desc, 0, 1, 0)
|
||||||
|
readingStagingBuffer, err := createBuffer(i.graphics.device, totalBytes, _D3D12_HEAP_TYPE_READBACK)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
defer func() {
|
||||||
|
readingStagingBuffer.Release()
|
||||||
|
}()
|
||||||
|
|
||||||
if rb, ok := i.transiteState(_D3D12_RESOURCE_STATE_COPY_SOURCE); ok {
|
if rb, ok := i.transiteState(_D3D12_RESOURCE_STATE_COPY_SOURCE); ok {
|
||||||
i.graphics.copyCommandList.ResourceBarrier([]_D3D12_RESOURCE_BARRIER_Transition{rb})
|
i.graphics.copyCommandList.ResourceBarrier([]_D3D12_RESOURCE_BARRIER_Transition{rb})
|
||||||
}
|
}
|
||||||
|
|
||||||
m, err := i.readingStagingBuffer.Map(0, &_D3D12_RANGE{0, 0})
|
m, err := readingStagingBuffer.Map(0, &_D3D12_RANGE{0, 0})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dst := _D3D12_TEXTURE_COPY_LOCATION_PlacedFootPrint{
|
dst := _D3D12_TEXTURE_COPY_LOCATION_PlacedFootPrint{
|
||||||
pResource: i.readingStagingBuffer,
|
pResource: readingStagingBuffer,
|
||||||
Type: _D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
Type: _D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT,
|
||||||
PlacedFootprint: i.layouts,
|
PlacedFootprint: layouts,
|
||||||
}
|
}
|
||||||
src := _D3D12_TEXTURE_COPY_LOCATION_SubresourceIndex{
|
src := _D3D12_TEXTURE_COPY_LOCATION_SubresourceIndex{
|
||||||
pResource: i.texture,
|
pResource: i.texture,
|
||||||
@ -1451,12 +1454,12 @@ func (i *Image) ReadPixels(buf []byte, x, y, width, height int) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
dstBytes := unsafe.Slice((*byte)(unsafe.Pointer(m)), i.totalBytes)
|
dstBytes := unsafe.Slice((*byte)(unsafe.Pointer(m)), totalBytes)
|
||||||
for j := 0; j < height; j++ {
|
for j := 0; j < height; j++ {
|
||||||
copy(buf[j*width*4:(j+1)*width*4], dstBytes[j*int(i.layouts.Footprint.RowPitch):])
|
copy(buf[j*width*4:(j+1)*width*4], dstBytes[j*int(layouts.Footprint.RowPitch):])
|
||||||
}
|
}
|
||||||
|
|
||||||
i.readingStagingBuffer.Unmap(0, nil)
|
readingStagingBuffer.Unmap(0, nil)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user