mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-21 03:55:32 +00:00
d3d12: Use ring buffer for textures too
It looks like the texture size calculation is wrong, it can lead to crash
This commit is contained in:
parent
6bb5dd2125
commit
9748007cd3
3 changed files with 35 additions and 30 deletions
|
@ -14,13 +14,13 @@ void SetGetD3DGSFrameCallback(GetGSFrameCb2 value)
|
|||
GetGSFrame = value;
|
||||
}
|
||||
|
||||
void DataHeap::Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type)
|
||||
void DataHeap::Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
|
||||
{
|
||||
m_size = heapSize;
|
||||
D3D12_HEAP_DESC heapDesc = {};
|
||||
heapDesc.SizeInBytes = m_size;
|
||||
heapDesc.Properties.Type = type;
|
||||
heapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
heapDesc.Flags = flags;
|
||||
check(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&m_heap)));
|
||||
m_putPos = 0;
|
||||
m_getPos = m_size - 1;
|
||||
|
@ -83,7 +83,6 @@ void D3D12GSRender::ResourceStorage::Reset()
|
|||
{
|
||||
m_constantsBufferIndex = 0;
|
||||
m_currentScaleOffsetBufferIndex = 0;
|
||||
m_currentStorageOffset = 0;
|
||||
m_currentTextureIndex = 0;
|
||||
|
||||
m_commandAllocator->Reset();
|
||||
|
@ -117,17 +116,6 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
|
|||
descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||
check(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_scaleOffsetDescriptorHeap)));
|
||||
|
||||
// Texture
|
||||
D3D12_HEAP_DESC heapDescription = {};
|
||||
heapDescription.SizeInBytes = 1024 * 1024 * 256;
|
||||
heapDescription.Properties.Type = D3D12_HEAP_TYPE_UPLOAD;
|
||||
heapDescription.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS;
|
||||
check(device->CreateHeap(&heapDescription, IID_PPV_ARGS(&m_uploadTextureHeap)));
|
||||
|
||||
heapDescription.Properties.Type = D3D12_HEAP_TYPE_DEFAULT;
|
||||
heapDescription.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES;
|
||||
check(device->CreateHeap(&heapDescription, IID_PPV_ARGS(&m_textureStorage)));
|
||||
|
||||
D3D12_DESCRIPTOR_HEAP_DESC textureDescriptorDesc = {};
|
||||
textureDescriptorDesc.NumDescriptors = 10000; // For safety
|
||||
textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
|
||||
|
@ -148,8 +136,6 @@ void D3D12GSRender::ResourceStorage::Release()
|
|||
for (auto tmp : m_inflightResources)
|
||||
tmp->Release();
|
||||
m_textureDescriptorsHeap->Release();
|
||||
m_textureStorage->Release();
|
||||
m_uploadTextureHeap->Release();
|
||||
m_samplerDescriptorHeap->Release();
|
||||
for (auto tmp : m_inflightCommandList)
|
||||
tmp->Release();
|
||||
|
@ -387,14 +373,18 @@ D3D12GSRender::D3D12GSRender()
|
|||
|
||||
m_rtts.Init(m_device);
|
||||
|
||||
m_constantsData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD);
|
||||
m_vertexIndexData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD);
|
||||
m_constantsData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
m_vertexIndexData.Init(m_device, 1024 * 1024 * 128, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
m_textureUploadData.Init(m_device, 1024 * 1024 * 256, D3D12_HEAP_TYPE_UPLOAD, D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS);
|
||||
m_textureData.Init(m_device, 1024 * 1024 * 256, D3D12_HEAP_TYPE_DEFAULT, D3D12_HEAP_FLAG_ALLOW_ONLY_NON_RT_DS_TEXTURES);
|
||||
}
|
||||
|
||||
D3D12GSRender::~D3D12GSRender()
|
||||
{
|
||||
m_constantsData.Release();
|
||||
m_vertexIndexData.Release();
|
||||
m_textureUploadData.Release();
|
||||
m_textureData.Release();
|
||||
m_UAVHeap.m_heap->Release();
|
||||
m_readbackResources.m_heap->Release();
|
||||
m_texturesRTTs.clear();
|
||||
|
@ -939,6 +929,18 @@ void D3D12GSRender::Flip()
|
|||
m_vertexIndexData.m_getPos = std::get<0>(tmp);
|
||||
}
|
||||
m_vertexIndexData.m_resourceStoredSinceLastSync.clear();
|
||||
for (auto tmp : m_textureUploadData.m_resourceStoredSinceLastSync)
|
||||
{
|
||||
std::get<2>(tmp)->Release();
|
||||
m_textureUploadData.m_getPos = std::get<0>(tmp);
|
||||
}
|
||||
m_textureUploadData.m_resourceStoredSinceLastSync.clear();
|
||||
for (auto tmp : m_textureData.m_resourceStoredSinceLastSync)
|
||||
{
|
||||
std::get<2>(tmp)->Release();
|
||||
m_textureData.m_getPos = std::get<0>(tmp);
|
||||
}
|
||||
m_textureData.m_resourceStoredSinceLastSync.clear();
|
||||
|
||||
m_frame->Flip(nullptr);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ struct DataHeap
|
|||
m_getPos; // End of free space
|
||||
std::vector<std::tuple<size_t, size_t, ID3D12Resource *> > m_resourceStoredSinceLastSync;
|
||||
|
||||
void Init(ID3D12Device *, size_t, D3D12_HEAP_TYPE);
|
||||
void Init(ID3D12Device *, size_t, D3D12_HEAP_TYPE, D3D12_HEAP_FLAGS);
|
||||
/**
|
||||
* Does alloc cross get position ?
|
||||
*/
|
||||
|
@ -94,8 +94,6 @@ private:
|
|||
|
||||
// Texture storage
|
||||
ID3D12CommandAllocator *m_textureUploadCommandAllocator;
|
||||
ID3D12Heap *m_uploadTextureHeap, *m_textureStorage;
|
||||
size_t m_currentStorageOffset;
|
||||
ID3D12DescriptorHeap *m_textureDescriptorsHeap;
|
||||
ID3D12DescriptorHeap *m_samplerDescriptorHeap;
|
||||
size_t m_currentTextureIndex;
|
||||
|
@ -111,6 +109,9 @@ private:
|
|||
DataHeap m_constantsData;
|
||||
// Vertex storage
|
||||
DataHeap m_vertexIndexData;
|
||||
// Texture storage
|
||||
DataHeap m_textureUploadData;
|
||||
DataHeap m_textureData;
|
||||
|
||||
struct UAVHeap
|
||||
{
|
||||
|
|
|
@ -196,15 +196,18 @@ size_t D3D12GSRender::UploadTextures()
|
|||
|
||||
ID3D12Resource *Texture;
|
||||
size_t textureSize = rowPitch * heightInBlocks;
|
||||
assert(m_textureUploadData.canAlloc(textureSize));
|
||||
size_t heapOffset = m_textureUploadData.alloc(textureSize);
|
||||
|
||||
check(m_device->CreatePlacedResource(
|
||||
m_perFrameStorage.m_uploadTextureHeap,
|
||||
m_perFrameStorage.m_currentStorageOffset,
|
||||
m_textureUploadData.m_heap,
|
||||
heapOffset,
|
||||
&getBufferResourceDesc(textureSize),
|
||||
D3D12_RESOURCE_STATE_GENERIC_READ,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&Texture)
|
||||
));
|
||||
m_textureUploadData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, textureSize, Texture));
|
||||
|
||||
auto pixels = vm::get_ptr<const u8>(texaddr);
|
||||
void *textureData;
|
||||
|
@ -247,19 +250,18 @@ size_t D3D12GSRender::UploadTextures()
|
|||
}
|
||||
Texture->Unmap(0, nullptr);
|
||||
|
||||
assert(m_textureData.canAlloc(textureSize));
|
||||
size_t heapOffset2 = m_textureData.alloc(textureSize);
|
||||
|
||||
check(m_device->CreatePlacedResource(
|
||||
m_perFrameStorage.m_textureStorage,
|
||||
m_perFrameStorage.m_currentStorageOffset,
|
||||
m_textureData.m_heap,
|
||||
heapOffset2,
|
||||
&getTexture2DResourceDesc(m_textures[i].GetWidth(), m_textures[i].GetHeight(), dxgiFormat),
|
||||
D3D12_RESOURCE_STATE_COPY_DEST,
|
||||
nullptr,
|
||||
IID_PPV_ARGS(&vramTexture)
|
||||
));
|
||||
|
||||
m_perFrameStorage.m_currentStorageOffset += textureSize;
|
||||
m_perFrameStorage.m_currentStorageOffset = (m_perFrameStorage.m_currentStorageOffset + 65536 - 1) & ~65535;
|
||||
m_perFrameStorage.m_inflightResources.push_back(Texture);
|
||||
m_perFrameStorage.m_inflightResources.push_back(vramTexture);
|
||||
m_textureData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset2, textureSize, vramTexture));
|
||||
|
||||
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
|
||||
dst.pResource = vramTexture;
|
||||
|
|
Loading…
Add table
Reference in a new issue