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:
parent
c7a9763f6d
commit
198c9389af
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user