1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-03-14 04:29:15 +01:00

[d3d11] Flush resource init commands

Like regular command buffers, the command buffers used for resource
initialization should not be able to grow indefinitely.
This commit is contained in:
Philip Rebohle 2018-01-13 23:40:17 +01:00
parent c7a9763f6d
commit 198c9389af
3 changed files with 51 additions and 22 deletions

View File

@ -1553,6 +1553,7 @@ namespace dxvk {
// Optimization: If the number of draw and dispatch calls issued
// prior to the previous context flush is above a certain threshold,
// submit the current command buffer in order to keep the GPU busy.
// This also helps keep the command buffers at a reasonable size.
if (m_drawCount >= 500)
this->Flush();

View File

@ -1313,18 +1313,10 @@ namespace dxvk {
void D3D11Device::FlushInitContext() {
auto lock = LockResourceInitContext();
if (m_resourceInitUsed) {
m_dxvkDevice->submitCommandList(
m_resourceInitContext->endRecording(),
nullptr, nullptr);
m_resourceInitContext->beginRecording(
m_dxvkDevice->createCommandList());
m_resourceInitUsed = false;
}
LockResourceInitContext();
if (m_resourceInitCommands != 0)
SubmitResourceInitCommands();
UnlockResourceInitContext(0);
}
@ -1446,13 +1438,15 @@ namespace dxvk {
= pBuffer->GetBufferSlice();
if (pInitialData != nullptr) {
auto lock = LockResourceInitContext();
LockResourceInitContext();
m_resourceInitContext->updateBuffer(
bufferSlice.buffer(),
bufferSlice.offset(),
bufferSlice.length(),
pInitialData->pSysMem);
UnlockResourceInitContext(1);
}
}
@ -1460,11 +1454,11 @@ namespace dxvk {
void D3D11Device::InitTexture(
const Rc<DxvkImage>& image,
const D3D11_SUBRESOURCE_DATA* pInitialData) {
auto lock = LockResourceInitContext();
const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format);
if (pInitialData != nullptr) {
LockResourceInitContext();
// pInitialData is an array that stores an entry for
// every single subresource. Since we will define all
// subresources, this counts as initialization.
@ -1491,7 +1485,13 @@ namespace dxvk {
pInitialData[id].SysMemSlicePitch);
}
}
const uint32_t subresourceCount =
image->info().numLayers * image->info().mipLevels;
UnlockResourceInitContext(subresourceCount);
} else {
LockResourceInitContext();
// While the Microsoft docs state that resource contents
// are undefined if no initial data is provided, some
// applications expect a resource to be pre-cleared.
@ -1516,6 +1516,8 @@ namespace dxvk {
m_resourceInitContext->clearDepthStencilImage(
image, value, subresources);
}
UnlockResourceInitContext(1);
}
}
@ -1822,4 +1824,31 @@ namespace dxvk {
m_counterSlices[i] = MaxCounterStructs - i - 1;
}
void D3D11Device::LockResourceInitContext() {
m_resourceInitMutex.lock();
}
void D3D11Device::UnlockResourceInitContext(uint64_t CommandCount) {
m_resourceInitCommands += CommandCount;
if (m_resourceInitCommands >= InitCommandThreshold)
SubmitResourceInitCommands();
m_resourceInitMutex.unlock();
}
void D3D11Device::SubmitResourceInitCommands() {
m_dxvkDevice->submitCommandList(
m_resourceInitContext->endRecording(),
nullptr, nullptr);
m_resourceInitContext->beginRecording(
m_dxvkDevice->createCommandList());
m_resourceInitCommands = 0;
}
}

View File

@ -28,7 +28,8 @@ namespace dxvk {
class D3D11Texture3D;
class D3D11Device : public ComObject<ID3D11Device> {
/// Maximum number of resource init commands per command buffer
constexpr static uint64_t InitCommandThreshold = 50;
public:
D3D11Device(
@ -276,7 +277,7 @@ namespace dxvk {
std::mutex m_resourceInitMutex;
Rc<DxvkContext> m_resourceInitContext;
bool m_resourceInitUsed = false;
uint64_t m_resourceInitCommands = 0;
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
@ -319,11 +320,9 @@ namespace dxvk {
void CreateCounterBuffer();
std::unique_lock<std::mutex> LockResourceInitContext() {
auto lock = std::unique_lock<std::mutex>(m_resourceInitMutex);
m_resourceInitUsed = true;
return lock;
}
void LockResourceInitContext();
void UnlockResourceInitContext(uint64_t CommandCount);
void SubmitResourceInitCommands();
};