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:
vlj 2015-06-02 00:11:59 +02:00 committed by Vincent Lejeune
parent 6bb5dd2125
commit 9748007cd3
3 changed files with 35 additions and 30 deletions

View file

@ -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);
}

View file

@ -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
{

View file

@ -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;