mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-03-15 07:29:17 +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
|
// Optimization: If the number of draw and dispatch calls issued
|
||||||
// prior to the previous context flush is above a certain threshold,
|
// prior to the previous context flush is above a certain threshold,
|
||||||
// submit the current command buffer in order to keep the GPU busy.
|
// 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)
|
if (m_drawCount >= 500)
|
||||||
this->Flush();
|
this->Flush();
|
||||||
|
|
||||||
|
@ -1313,18 +1313,10 @@ namespace dxvk {
|
|||||||
|
|
||||||
|
|
||||||
void D3D11Device::FlushInitContext() {
|
void D3D11Device::FlushInitContext() {
|
||||||
auto lock = LockResourceInitContext();
|
LockResourceInitContext();
|
||||||
|
if (m_resourceInitCommands != 0)
|
||||||
if (m_resourceInitUsed) {
|
SubmitResourceInitCommands();
|
||||||
m_dxvkDevice->submitCommandList(
|
UnlockResourceInitContext(0);
|
||||||
m_resourceInitContext->endRecording(),
|
|
||||||
nullptr, nullptr);
|
|
||||||
|
|
||||||
m_resourceInitContext->beginRecording(
|
|
||||||
m_dxvkDevice->createCommandList());
|
|
||||||
|
|
||||||
m_resourceInitUsed = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1446,13 +1438,15 @@ namespace dxvk {
|
|||||||
= pBuffer->GetBufferSlice();
|
= pBuffer->GetBufferSlice();
|
||||||
|
|
||||||
if (pInitialData != nullptr) {
|
if (pInitialData != nullptr) {
|
||||||
auto lock = LockResourceInitContext();
|
LockResourceInitContext();
|
||||||
|
|
||||||
m_resourceInitContext->updateBuffer(
|
m_resourceInitContext->updateBuffer(
|
||||||
bufferSlice.buffer(),
|
bufferSlice.buffer(),
|
||||||
bufferSlice.offset(),
|
bufferSlice.offset(),
|
||||||
bufferSlice.length(),
|
bufferSlice.length(),
|
||||||
pInitialData->pSysMem);
|
pInitialData->pSysMem);
|
||||||
|
|
||||||
|
UnlockResourceInitContext(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1460,11 +1454,11 @@ namespace dxvk {
|
|||||||
void D3D11Device::InitTexture(
|
void D3D11Device::InitTexture(
|
||||||
const Rc<DxvkImage>& image,
|
const Rc<DxvkImage>& image,
|
||||||
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
const D3D11_SUBRESOURCE_DATA* pInitialData) {
|
||||||
auto lock = LockResourceInitContext();
|
|
||||||
|
|
||||||
const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format);
|
const DxvkFormatInfo* formatInfo = imageFormatInfo(image->info().format);
|
||||||
|
|
||||||
if (pInitialData != nullptr) {
|
if (pInitialData != nullptr) {
|
||||||
|
LockResourceInitContext();
|
||||||
|
|
||||||
// pInitialData is an array that stores an entry for
|
// pInitialData is an array that stores an entry for
|
||||||
// every single subresource. Since we will define all
|
// every single subresource. Since we will define all
|
||||||
// subresources, this counts as initialization.
|
// subresources, this counts as initialization.
|
||||||
@ -1491,7 +1485,13 @@ namespace dxvk {
|
|||||||
pInitialData[id].SysMemSlicePitch);
|
pInitialData[id].SysMemSlicePitch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const uint32_t subresourceCount =
|
||||||
|
image->info().numLayers * image->info().mipLevels;
|
||||||
|
UnlockResourceInitContext(subresourceCount);
|
||||||
} else {
|
} else {
|
||||||
|
LockResourceInitContext();
|
||||||
|
|
||||||
// While the Microsoft docs state that resource contents
|
// While the Microsoft docs state that resource contents
|
||||||
// are undefined if no initial data is provided, some
|
// are undefined if no initial data is provided, some
|
||||||
// applications expect a resource to be pre-cleared.
|
// applications expect a resource to be pre-cleared.
|
||||||
@ -1516,6 +1516,8 @@ namespace dxvk {
|
|||||||
m_resourceInitContext->clearDepthStencilImage(
|
m_resourceInitContext->clearDepthStencilImage(
|
||||||
image, value, subresources);
|
image, value, subresources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UnlockResourceInitContext(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1822,4 +1824,31 @@ namespace dxvk {
|
|||||||
m_counterSlices[i] = MaxCounterStructs - i - 1;
|
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 D3D11Texture3D;
|
||||||
|
|
||||||
class D3D11Device : public ComObject<ID3D11Device> {
|
class D3D11Device : public ComObject<ID3D11Device> {
|
||||||
|
/// Maximum number of resource init commands per command buffer
|
||||||
|
constexpr static uint64_t InitCommandThreshold = 50;
|
||||||
public:
|
public:
|
||||||
|
|
||||||
D3D11Device(
|
D3D11Device(
|
||||||
@ -276,7 +277,7 @@ namespace dxvk {
|
|||||||
|
|
||||||
std::mutex m_resourceInitMutex;
|
std::mutex m_resourceInitMutex;
|
||||||
Rc<DxvkContext> m_resourceInitContext;
|
Rc<DxvkContext> m_resourceInitContext;
|
||||||
bool m_resourceInitUsed = false;
|
uint64_t m_resourceInitCommands = 0;
|
||||||
|
|
||||||
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
D3D11StateObjectSet<D3D11BlendState> m_bsStateObjects;
|
||||||
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
D3D11StateObjectSet<D3D11DepthStencilState> m_dsStateObjects;
|
||||||
@ -319,11 +320,9 @@ namespace dxvk {
|
|||||||
|
|
||||||
void CreateCounterBuffer();
|
void CreateCounterBuffer();
|
||||||
|
|
||||||
std::unique_lock<std::mutex> LockResourceInitContext() {
|
void LockResourceInitContext();
|
||||||
auto lock = std::unique_lock<std::mutex>(m_resourceInitMutex);
|
void UnlockResourceInitContext(uint64_t CommandCount);
|
||||||
m_resourceInitUsed = true;
|
void SubmitResourceInitCommands();
|
||||||
return lock;
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user