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
commit 9748007cd3
3 changed files with 35 additions and 30 deletions

View file

@ -14,13 +14,13 @@ void SetGetD3DGSFrameCallback(GetGSFrameCb2 value)
GetGSFrame = 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; m_size = heapSize;
D3D12_HEAP_DESC heapDesc = {}; D3D12_HEAP_DESC heapDesc = {};
heapDesc.SizeInBytes = m_size; heapDesc.SizeInBytes = m_size;
heapDesc.Properties.Type = type; heapDesc.Properties.Type = type;
heapDesc.Flags = D3D12_HEAP_FLAG_ALLOW_ONLY_BUFFERS; heapDesc.Flags = flags;
check(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&m_heap))); check(device->CreateHeap(&heapDesc, IID_PPV_ARGS(&m_heap)));
m_putPos = 0; m_putPos = 0;
m_getPos = m_size - 1; m_getPos = m_size - 1;
@ -83,7 +83,6 @@ void D3D12GSRender::ResourceStorage::Reset()
{ {
m_constantsBufferIndex = 0; m_constantsBufferIndex = 0;
m_currentScaleOffsetBufferIndex = 0; m_currentScaleOffsetBufferIndex = 0;
m_currentStorageOffset = 0;
m_currentTextureIndex = 0; m_currentTextureIndex = 0;
m_commandAllocator->Reset(); m_commandAllocator->Reset();
@ -117,17 +116,6 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; descriptorHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
check(device->CreateDescriptorHeap(&descriptorHeapDesc, IID_PPV_ARGS(&m_scaleOffsetDescriptorHeap))); 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 = {}; D3D12_DESCRIPTOR_HEAP_DESC textureDescriptorDesc = {};
textureDescriptorDesc.NumDescriptors = 10000; // For safety textureDescriptorDesc.NumDescriptors = 10000; // For safety
textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; textureDescriptorDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
@ -148,8 +136,6 @@ void D3D12GSRender::ResourceStorage::Release()
for (auto tmp : m_inflightResources) for (auto tmp : m_inflightResources)
tmp->Release(); tmp->Release();
m_textureDescriptorsHeap->Release(); m_textureDescriptorsHeap->Release();
m_textureStorage->Release();
m_uploadTextureHeap->Release();
m_samplerDescriptorHeap->Release(); m_samplerDescriptorHeap->Release();
for (auto tmp : m_inflightCommandList) for (auto tmp : m_inflightCommandList)
tmp->Release(); tmp->Release();
@ -387,14 +373,18 @@ D3D12GSRender::D3D12GSRender()
m_rtts.Init(m_device); m_rtts.Init(m_device);
m_constantsData.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); 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() D3D12GSRender::~D3D12GSRender()
{ {
m_constantsData.Release(); m_constantsData.Release();
m_vertexIndexData.Release(); m_vertexIndexData.Release();
m_textureUploadData.Release();
m_textureData.Release();
m_UAVHeap.m_heap->Release(); m_UAVHeap.m_heap->Release();
m_readbackResources.m_heap->Release(); m_readbackResources.m_heap->Release();
m_texturesRTTs.clear(); m_texturesRTTs.clear();
@ -939,6 +929,18 @@ void D3D12GSRender::Flip()
m_vertexIndexData.m_getPos = std::get<0>(tmp); m_vertexIndexData.m_getPos = std::get<0>(tmp);
} }
m_vertexIndexData.m_resourceStoredSinceLastSync.clear(); 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); m_frame->Flip(nullptr);
} }

View file

@ -52,7 +52,7 @@ struct DataHeap
m_getPos; // End of free space m_getPos; // End of free space
std::vector<std::tuple<size_t, size_t, ID3D12Resource *> > m_resourceStoredSinceLastSync; 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 ? * Does alloc cross get position ?
*/ */
@ -94,8 +94,6 @@ private:
// Texture storage // Texture storage
ID3D12CommandAllocator *m_textureUploadCommandAllocator; ID3D12CommandAllocator *m_textureUploadCommandAllocator;
ID3D12Heap *m_uploadTextureHeap, *m_textureStorage;
size_t m_currentStorageOffset;
ID3D12DescriptorHeap *m_textureDescriptorsHeap; ID3D12DescriptorHeap *m_textureDescriptorsHeap;
ID3D12DescriptorHeap *m_samplerDescriptorHeap; ID3D12DescriptorHeap *m_samplerDescriptorHeap;
size_t m_currentTextureIndex; size_t m_currentTextureIndex;
@ -111,6 +109,9 @@ private:
DataHeap m_constantsData; DataHeap m_constantsData;
// Vertex storage // Vertex storage
DataHeap m_vertexIndexData; DataHeap m_vertexIndexData;
// Texture storage
DataHeap m_textureUploadData;
DataHeap m_textureData;
struct UAVHeap struct UAVHeap
{ {

View file

@ -196,15 +196,18 @@ size_t D3D12GSRender::UploadTextures()
ID3D12Resource *Texture; ID3D12Resource *Texture;
size_t textureSize = rowPitch * heightInBlocks; size_t textureSize = rowPitch * heightInBlocks;
assert(m_textureUploadData.canAlloc(textureSize));
size_t heapOffset = m_textureUploadData.alloc(textureSize);
check(m_device->CreatePlacedResource( check(m_device->CreatePlacedResource(
m_perFrameStorage.m_uploadTextureHeap, m_textureUploadData.m_heap,
m_perFrameStorage.m_currentStorageOffset, heapOffset,
&getBufferResourceDesc(textureSize), &getBufferResourceDesc(textureSize),
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr, nullptr,
IID_PPV_ARGS(&Texture) IID_PPV_ARGS(&Texture)
)); ));
m_textureUploadData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, textureSize, Texture));
auto pixels = vm::get_ptr<const u8>(texaddr); auto pixels = vm::get_ptr<const u8>(texaddr);
void *textureData; void *textureData;
@ -247,19 +250,18 @@ size_t D3D12GSRender::UploadTextures()
} }
Texture->Unmap(0, nullptr); Texture->Unmap(0, nullptr);
assert(m_textureData.canAlloc(textureSize));
size_t heapOffset2 = m_textureData.alloc(textureSize);
check(m_device->CreatePlacedResource( check(m_device->CreatePlacedResource(
m_perFrameStorage.m_textureStorage, m_textureData.m_heap,
m_perFrameStorage.m_currentStorageOffset, heapOffset2,
&getTexture2DResourceDesc(m_textures[i].GetWidth(), m_textures[i].GetHeight(), dxgiFormat), &getTexture2DResourceDesc(m_textures[i].GetWidth(), m_textures[i].GetHeight(), dxgiFormat),
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, nullptr,
IID_PPV_ARGS(&vramTexture) IID_PPV_ARGS(&vramTexture)
)); ));
m_textureData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset2, textureSize, 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);
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {}; D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
dst.pResource = vramTexture; dst.pResource = vramTexture;