d3d12: Rewrite per frame resource cleaning function.

This commit is contained in:
Vincent Lejeune 2015-08-16 00:20:08 +02:00 committed by Nekotekina
commit 63a54dd70d
4 changed files with 72 additions and 75 deletions

View file

@ -195,7 +195,7 @@ std::vector<VertexBufferFormat> FormatVertexData(const RSXVertexData *m_vertex_d
* Create a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap. * Create a new vertex buffer with attributes from vbf using vertexIndexHeap as storage heap.
*/ */
static static
ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, ID3D12Device *device, DataHeap<ID3D12Heap, 65536> &vertexIndexHeap) ComPtr<ID3D12Resource> createVertexBuffer(const VertexBufferFormat &vbf, const RSXVertexData *vertexData, ID3D12Device *device, DataHeap<ID3D12Heap, 65536> &vertexIndexHeap)
{ {
size_t subBufferSize = vbf.range.second - vbf.range.first + 1; size_t subBufferSize = vbf.range.second - vbf.range.first + 1;
// Make multiple of stride // Make multiple of stride
@ -204,14 +204,14 @@ ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVerte
assert(vertexIndexHeap.canAlloc(subBufferSize)); assert(vertexIndexHeap.canAlloc(subBufferSize));
size_t heapOffset = vertexIndexHeap.alloc(subBufferSize); size_t heapOffset = vertexIndexHeap.alloc(subBufferSize);
ID3D12Resource *vertexBuffer; ComPtr<ID3D12Resource> vertexBuffer;
ThrowIfFailed(device->CreatePlacedResource( ThrowIfFailed(device->CreatePlacedResource(
vertexIndexHeap.m_heap, vertexIndexHeap.m_heap,
heapOffset, heapOffset,
&getBufferResourceDesc(subBufferSize), &getBufferResourceDesc(subBufferSize),
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr, nullptr,
IID_PPV_ARGS(&vertexBuffer) IID_PPV_ARGS(vertexBuffer.GetAddressOf())
)); ));
void *bufferMap; void *bufferMap;
ThrowIfFailed(vertexBuffer->Map(0, nullptr, (void**)&bufferMap)); ThrowIfFailed(vertexBuffer->Map(0, nullptr, (void**)&bufferMap));
@ -260,7 +260,6 @@ ID3D12Resource *createVertexBuffer(const VertexBufferFormat &vbf, const RSXVerte
} }
vertexBuffer->Unmap(0, nullptr); vertexBuffer->Unmap(0, nullptr);
vertexIndexHeap.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, subBufferSize, vertexBuffer));
return vertexBuffer; return vertexBuffer;
} }
@ -302,8 +301,10 @@ std::vector<D3D12_VERTEX_BUFFER_VIEW> D3D12GSRender::UploadVertexBuffers(bool in
vertexBuffer = It->second; vertexBuffer = It->second;
else else
{ {
vertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_device.Get(), m_vertexIndexData); ComPtr<ID3D12Resource> newVertexBuffer = createVertexBuffer(vbf, m_vertex_data, m_device.Get(), m_vertexIndexData);
m_vertexCache[key] = vertexBuffer; vertexBuffer = newVertexBuffer.Get();
m_vertexCache[key] = newVertexBuffer.Get();
getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(newVertexBuffer);
} }
D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {}; D3D12_VERTEX_BUFFER_VIEW vertexBufferView = {};
@ -404,14 +405,14 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw)
assert(m_vertexIndexData.canAlloc(subBufferSize)); assert(m_vertexIndexData.canAlloc(subBufferSize));
size_t heapOffset = m_vertexIndexData.alloc(subBufferSize); size_t heapOffset = m_vertexIndexData.alloc(subBufferSize);
ID3D12Resource *indexBuffer; ComPtr<ID3D12Resource> indexBuffer;
ThrowIfFailed(m_device->CreatePlacedResource( ThrowIfFailed(m_device->CreatePlacedResource(
m_vertexIndexData.m_heap, m_vertexIndexData.m_heap,
heapOffset, heapOffset,
&getBufferResourceDesc(subBufferSize), &getBufferResourceDesc(subBufferSize),
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr, nullptr,
IID_PPV_ARGS(&indexBuffer) IID_PPV_ARGS(indexBuffer.GetAddressOf())
)); ));
void *bufferMap; void *bufferMap;
@ -461,7 +462,7 @@ D3D12_INDEX_BUFFER_VIEW D3D12GSRender::uploadIndexBuffers(bool indexed_draw)
} }
indexBuffer->Unmap(0, nullptr); indexBuffer->Unmap(0, nullptr);
m_vertexIndexData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, subBufferSize, indexBuffer)); getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(indexBuffer);
indexBufferView.SizeInBytes = (UINT)subBufferSize; indexBufferView.SizeInBytes = (UINT)subBufferSize;
indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress(); indexBufferView.BufferLocation = indexBuffer->GetGPUVirtualAddress();
@ -512,7 +513,6 @@ void D3D12GSRender::setScaleOffset()
D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_scaleOffsetDescriptorHeap->GetCPUDescriptorHandleForHeapStart(); D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_scaleOffsetDescriptorHeap->GetCPUDescriptorHandleForHeapStart();
Handle.ptr += getCurrentResourceStorage().m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); Handle.ptr += getCurrentResourceStorage().m_currentScaleOffsetBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, 256, nullptr));
} }
void D3D12GSRender::FillVertexShaderConstantsBuffer() void D3D12GSRender::FillVertexShaderConstantsBuffer()
@ -550,7 +550,6 @@ void D3D12GSRender::FillVertexShaderConstantsBuffer()
D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, bufferSize, nullptr));
} }
void D3D12GSRender::FillPixelShaderConstantsBuffer() void D3D12GSRender::FillPixelShaderConstantsBuffer()
@ -614,7 +613,6 @@ void D3D12GSRender::FillPixelShaderConstantsBuffer()
D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart(); D3D12_CPU_DESCRIPTOR_HANDLE Handle = getCurrentResourceStorage().m_constantsBufferDescriptorsHeap->GetCPUDescriptorHandleForHeapStart();
Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV); Handle.ptr += getCurrentResourceStorage().m_constantsBufferIndex * m_device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);
m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle); m_device->CreateConstantBufferView(&constantBufferViewDesc, Handle);
m_constantsData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, bufferSize, nullptr));
} }

View file

@ -104,6 +104,7 @@ void D3D12GSRender::ResourceStorage::Reset()
m_commandAllocator->Reset(); m_commandAllocator->Reset();
m_inflightCommandList.clear(); m_inflightCommandList.clear();
m_singleFrameLifetimeResources.clear();
} }
void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device) void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
@ -141,6 +142,19 @@ void D3D12GSRender::ResourceStorage::Init(ID3D12Device *device)
m_isUseable = true; m_isUseable = true;
} }
void D3D12GSRender::ResourceStorage::WaitAndClean(const std::vector<ID3D12Resource *> &dirtyTextures)
{
WaitForSingleObjectEx(m_frameFinishedHandle, INFINITE, FALSE);
Reset();
for (auto tmp : dirtyTextures)
tmp->Release();
m_RAMFramebuffer = nullptr;
m_isUseable.store(true, std::memory_order_release);
}
void D3D12GSRender::ResourceStorage::Release() void D3D12GSRender::ResourceStorage::Release()
{ {
// NOTE: Should be released only after gfx pipeline last command has been finished. // NOTE: Should be released only after gfx pipeline last command has been finished.
@ -763,7 +777,7 @@ void D3D12GSRender::Flip()
nullptr, nullptr,
IID_PPV_ARGS(&stagingTexture) IID_PPV_ARGS(&stagingTexture)
)); ));
m_textureUploadData.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, textureSize, stagingTexture)); getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(stagingTexture);
void *dstBuffer; void *dstBuffer;
ThrowIfFailed(stagingTexture->Map(0, nullptr, &dstBuffer)); ThrowIfFailed(stagingTexture->Map(0, nullptr, &dstBuffer));
@ -897,12 +911,15 @@ void D3D12GSRender::Flip()
m_vertexCache.clear(); m_vertexCache.clear();
m_vertexConstants.clear(); m_vertexConstants.clear();
std::vector<std::function<void()> > cleaningFunction =
{ // Get the put pos - 1. This way after cleaning we can set the get ptr to
m_constantsData.getCleaningFunction(), // this value, allowing heap to proceed even if we cleant before allocating
m_vertexIndexData.getCleaningFunction(), // a new value (that's the reason of the -1)
m_textureUploadData.getCleaningFunction(), size_t newGetPosConstantsHeap = m_constantsData.getCurrentPutPosMinusOne();
}; size_t newGetPosVertexIndexHeap = m_vertexIndexData.getCurrentPutPosMinusOne();
size_t newGetPosTextureUploadHeap = m_textureUploadData.getCurrentPutPosMinusOne();
size_t newGetPosReadbackHeap = m_readbackResources.getCurrentPutPosMinusOne();
size_t newGetPosUAVHeap = m_UAVHeap.getCurrentPutPosMinusOne();
std::lock_guard<std::mutex> lock(mut); std::lock_guard<std::mutex> lock(mut);
std::vector<ID3D12Resource *> textoclean = m_texToClean; std::vector<ID3D12Resource *> textoclean = m_texToClean;
@ -910,20 +927,20 @@ void D3D12GSRender::Flip()
storage.m_isUseable.store(false); storage.m_isUseable.store(false);
m_GC.pushWork([&, cleaningFunction, textoclean]() m_GC.pushWork([&,
textoclean,
newGetPosConstantsHeap,
newGetPosVertexIndexHeap,
newGetPosTextureUploadHeap,
newGetPosReadbackHeap,
newGetPosUAVHeap]()
{ {
WaitForSingleObjectEx(storage.m_frameFinishedHandle, INFINITE, FALSE); storage.WaitAndClean(textoclean);
m_constantsData.m_getPos.store(newGetPosConstantsHeap, std::memory_order_release);
for (auto &cleanFunc : cleaningFunction) m_vertexIndexData.m_getPos.store(newGetPosVertexIndexHeap, std::memory_order_release);
cleanFunc(); m_textureUploadData.m_getPos.store(newGetPosTextureUploadHeap, std::memory_order_release);
storage.Reset(); m_readbackResources.m_getPos.store(newGetPosReadbackHeap, std::memory_order_release);
m_UAVHeap.m_getPos.store(newGetPosUAVHeap, std::memory_order_release);
for (auto tmp : textoclean)
tmp->Release();
SAFE_RELEASE(storage.m_RAMFramebuffer);
storage.m_RAMFramebuffer = nullptr;
storage.m_isUseable.store(true, std::memory_order_release);
}); });
while (!getCurrentResourceStorage().m_isUseable.load(std::memory_order_acquire)) while (!getCurrentResourceStorage().m_isUseable.load(std::memory_order_acquire))
@ -990,7 +1007,7 @@ ID3D12Resource * D3D12GSRender::writeColorBuffer(ID3D12Resource * RTT, ID3D12Gra
IID_PPV_ARGS(&Result) IID_PPV_ARGS(&Result)
) )
); );
m_readbackResources.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, sizeInByte, Result)); getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(Result);
cmdlist->ResourceBarrier(1, &getResourceBarrierTransition(RTT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE)); cmdlist->ResourceBarrier(1, &getResourceBarrierTransition(RTT, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE));
@ -1040,7 +1057,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
HANDLE handle = CreateEvent(0, FALSE, FALSE, 0); HANDLE handle = CreateEvent(0, FALSE, FALSE, 0);
fence->SetEventOnCompletion(1, handle); fence->SetEventOnCompletion(1, handle);
ID3D12Resource *writeDest, *depthConverted; ComPtr<ID3D12Resource> writeDest, depthConverted;
ID3D12GraphicsCommandList *convertCommandList; ID3D12GraphicsCommandList *convertCommandList;
ID3D12DescriptorHeap *descriptorHeap; ID3D12DescriptorHeap *descriptorHeap;
size_t depthRowPitch = m_surface_clip_w; size_t depthRowPitch = m_surface_clip_w;
@ -1067,10 +1084,10 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
&resdesc, &resdesc,
D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_UNORDERED_ACCESS,
nullptr, nullptr,
IID_PPV_ARGS(&depthConverted) IID_PPV_ARGS(depthConverted.GetAddressOf())
) )
); );
m_UAVHeap.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, sizeInByte, depthConverted)); getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(depthConverted);
sizeInByte = depthRowPitch * m_surface_clip_h; sizeInByte = depthRowPitch * m_surface_clip_h;
assert(m_readbackResources.canAlloc(sizeInByte)); assert(m_readbackResources.canAlloc(sizeInByte));
@ -1084,10 +1101,10 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
&resdesc, &resdesc,
D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_COPY_DEST,
nullptr, nullptr,
IID_PPV_ARGS(&writeDest) IID_PPV_ARGS(writeDest.GetAddressOf())
) )
); );
m_readbackResources.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, sizeInByte, writeDest)); getCurrentResourceStorage().m_singleFrameLifetimeResources.push_back(writeDest);
ThrowIfFailed( ThrowIfFailed(
m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&convertCommandList)) m_device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, getCurrentResourceStorage().m_commandAllocator.Get(), nullptr, IID_PPV_ARGS(&convertCommandList))
@ -1124,7 +1141,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {}; D3D12_UNORDERED_ACCESS_VIEW_DESC uavDesc = {};
uavDesc.Format = DXGI_FORMAT_R8_UNORM; uavDesc.Format = DXGI_FORMAT_R8_UNORM;
uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D; uavDesc.ViewDimension = D3D12_UAV_DIMENSION_TEXTURE2D;
m_device->CreateUnorderedAccessView(depthConverted, nullptr, &uavDesc, Handle); m_device->CreateUnorderedAccessView(depthConverted.Get(), nullptr, &uavDesc, Handle);
// Convert // Convert
convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ)); convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(m_rtts.m_currentlyBoundDepthStencil, D3D12_RESOURCE_STATE_DEPTH_WRITE, D3D12_RESOURCE_STATE_GENERIC_READ));
@ -1138,7 +1155,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
// Flush UAV // Flush UAV
D3D12_RESOURCE_BARRIER uavbarrier = {}; D3D12_RESOURCE_BARRIER uavbarrier = {};
uavbarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV; uavbarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_UAV;
uavbarrier.UAV.pResource = depthConverted; uavbarrier.UAV.pResource = depthConverted.Get();
D3D12_RESOURCE_BARRIER barriers[] = D3D12_RESOURCE_BARRIER barriers[] =
{ {
@ -1146,7 +1163,7 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
uavbarrier, uavbarrier,
}; };
convertCommandList->ResourceBarrier(2, barriers); convertCommandList->ResourceBarrier(2, barriers);
convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(depthConverted, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE)); convertCommandList->ResourceBarrier(1, &getResourceBarrierTransition(depthConverted.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE));
ThrowIfFailed(convertCommandList->Close()); ThrowIfFailed(convertCommandList->Close());
m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&convertCommandList); m_commandQueueGraphic->ExecuteCommandLists(1, (ID3D12CommandList**)&convertCommandList);
@ -1165,9 +1182,9 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
// Copy // Copy
D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {}; D3D12_TEXTURE_COPY_LOCATION dst = {}, src = {};
src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; src.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src.pResource = depthConverted; src.pResource = depthConverted.Get();
dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; dst.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
dst.pResource = writeDest; dst.pResource = writeDest.Get();
dst.PlacedFootprint.Offset = 0; dst.PlacedFootprint.Offset = 0;
dst.PlacedFootprint.Footprint.Depth = 1; dst.PlacedFootprint.Footprint.Depth = 1;
dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8_UNORM; dst.PlacedFootprint.Footprint.Format = DXGI_FORMAT_R8_UNORM;
@ -1228,10 +1245,6 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
//Wait for result //Wait for result
m_commandQueueGraphic->Signal(fence, 1); m_commandQueueGraphic->Signal(fence, 1);
auto depthUAVCleaning = m_UAVHeap.getCleaningFunction();
auto readbackCleaning = m_readbackResources.getCleaningFunction();
m_GC.pushWork([=]() { m_GC.pushWork([=]() {
WaitForSingleObject(handle, INFINITE); WaitForSingleObject(handle, INFINITE);
CloseHandle(handle); CloseHandle(handle);
@ -1256,11 +1269,8 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
ptrAsChar[4 * (row * m_surface_clip_w + i) + 3] = c; ptrAsChar[4 * (row * m_surface_clip_w + i) + 3] = c;
} }
} }
writeDest->Release();
depthConverted->Release();
descriptorHeap->Release(); descriptorHeap->Release();
convertCommandList->Release(); convertCommandList->Release();
depthUAVCleaning();
} }
size_t srcPitch, dstPitch; size_t srcPitch, dstPitch;
@ -1345,7 +1355,6 @@ void D3D12GSRender::semaphorePGRAPHBackendRelease(u32 offset, u32 value)
if (needTransfer) if (needTransfer)
downloadCommandList->Release(); downloadCommandList->Release();
readbackCleaning();
vm::write32(m_label_addr + offset, value); vm::write32(m_label_addr + offset, value);
}); });

View file

@ -122,7 +122,6 @@ struct DataHeap
size_t m_size; size_t m_size;
size_t m_putPos; // Start of free space size_t m_putPos; // Start of free space
std::atomic<size_t> m_getPos; // End of free space std::atomic<size_t> m_getPos; // End of free space
std::vector<std::tuple<size_t, size_t, ID3D12Resource *> > m_resourceStoredSinceLastSync;
void Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags) void Init(ID3D12Device *device, size_t heapSize, D3D12_HEAP_TYPE type, D3D12_HEAP_FLAGS flags)
{ {
@ -182,28 +181,14 @@ struct DataHeap
void Release() void Release()
{ {
m_heap->Release(); m_heap->Release();
for (auto tmp : m_resourceStoredSinceLastSync)
{
SAFE_RELEASE(std::get<2>(tmp));
}
} }
/** /**
* Get a function that cleans heaps. * return current putpos - 1
* It's caller responsability to ensure data are not used when executed.
*/ */
std::function<void()> getCleaningFunction() size_t getCurrentPutPosMinusOne() const
{ {
std::atomic<size_t>& getPointer = m_getPos; return (m_putPos - 1 > 0) ? m_putPos - 1 : m_size - 1;
auto duplicatem_resourceStoredSinceLastSync = m_resourceStoredSinceLastSync;
m_resourceStoredSinceLastSync.clear();
return [=, &getPointer]() {
for (auto tmp : duplicatem_resourceStoredSinceLastSync)
{
SAFE_RELEASE(std::get<2>(tmp));
getPointer.exchange(std::get<0>(tmp));
}
};
} }
}; };
@ -337,8 +322,12 @@ private:
ComPtr<ID3D12Resource> m_RAMFramebuffer; ComPtr<ID3D12Resource> m_RAMFramebuffer;
// List of resources that can be freed after frame is flipped
std::vector<ComPtr<ID3D12Resource> > m_singleFrameLifetimeResources;
void Reset(); void Reset();
void Init(ID3D12Device *device); void Init(ID3D12Device *device);
void WaitAndClean(const std::vector<ID3D12Resource *> &dirtyTextures);
void Release(); void Release();
}; };

View file

@ -395,7 +395,8 @@ ID3D12Resource *uploadSingleTexture(
const RSXTexture &texture, const RSXTexture &texture,
ID3D12Device *device, ID3D12Device *device,
ID3D12GraphicsCommandList *commandList, ID3D12GraphicsCommandList *commandList,
DataHeap<ID3D12Heap, 65536> &textureBuffersHeap) DataHeap<ID3D12Heap, 65536> &textureBuffersHeap,
std::vector<ComPtr<ID3D12Resource> > &stagingRamTexture)
{ {
ID3D12Resource *vramTexture; ID3D12Resource *vramTexture;
size_t w = texture.GetWidth(), h = texture.GetHeight(); size_t w = texture.GetWidth(), h = texture.GetHeight();
@ -550,7 +551,7 @@ ID3D12Resource *uploadSingleTexture(
// Multiple of 256 // Multiple of 256
size_t rowPitch = align(blockSizeInByte * widthInBlocks, 256); size_t rowPitch = align(blockSizeInByte * widthInBlocks, 256);
ID3D12Resource *Texture; ComPtr<ID3D12Resource> Texture;
size_t textureSize = rowPitch * heightInBlocks * 2; // * 4 for mipmap levels size_t textureSize = rowPitch * heightInBlocks * 2; // * 4 for mipmap levels
assert(textureBuffersHeap.canAlloc(textureSize)); assert(textureBuffersHeap.canAlloc(textureSize));
size_t heapOffset = textureBuffersHeap.alloc(textureSize); size_t heapOffset = textureBuffersHeap.alloc(textureSize);
@ -561,9 +562,9 @@ ID3D12Resource *uploadSingleTexture(
&getBufferResourceDesc(textureSize), &getBufferResourceDesc(textureSize),
D3D12_RESOURCE_STATE_GENERIC_READ, D3D12_RESOURCE_STATE_GENERIC_READ,
nullptr, nullptr,
IID_PPV_ARGS(&Texture) IID_PPV_ARGS(Texture.GetAddressOf())
)); ));
textureBuffersHeap.m_resourceStoredSinceLastSync.push_back(std::make_tuple(heapOffset, textureSize, Texture)); stagingRamTexture.push_back(Texture);
auto pixels = vm::get_ptr<const u8>(texaddr); auto pixels = vm::get_ptr<const u8>(texaddr);
void *textureData; void *textureData;
@ -633,7 +634,7 @@ ID3D12Resource *uploadSingleTexture(
dst.SubresourceIndex = (UINT)miplevel; dst.SubresourceIndex = (UINT)miplevel;
dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX; dst.Type = D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX;
src.PlacedFootprint.Offset = mli.offset; src.PlacedFootprint.Offset = mli.offset;
src.pResource = Texture; src.pResource = Texture.Get();
src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT; src.Type = D3D12_TEXTURE_COPY_TYPE_PLACED_FOOTPRINT;
src.PlacedFootprint.Footprint.Depth = 1; src.PlacedFootprint.Footprint.Depth = 1;
src.PlacedFootprint.Footprint.Width = (UINT)mli.width; src.PlacedFootprint.Footprint.Width = (UINT)mli.width;
@ -758,7 +759,7 @@ size_t D3D12GSRender::UploadTextures(ID3D12GraphicsCommandList *cmdlist)
} }
else else
{ {
vramTexture = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData); vramTexture = uploadSingleTexture(m_textures[i], m_device.Get(), cmdlist, m_textureUploadData, getCurrentResourceStorage().m_singleFrameLifetimeResources);
m_texturesCache[texaddr] = vramTexture; m_texturesCache[texaddr] = vramTexture;
u32 s = (u32)align(getTextureSize(m_textures[i]), 4096); u32 s = (u32)align(getTextureSize(m_textures[i]), 4096);