mirror of
https://github.com/doitsujin/dxvk.git
synced 2025-01-19 05:52:11 +01:00
[d3d9] Remove initializer context
This commit is contained in:
parent
48c57c11e9
commit
5ff365b9f1
@ -71,7 +71,7 @@ namespace dxvk {
|
||||
if (m_dxvkDevice->instance()->extensions().extDebugUtils)
|
||||
m_annotation = new D3D9UserDefinedAnnotation(this);
|
||||
|
||||
m_initializer = new D3D9Initializer(m_dxvkDevice);
|
||||
m_initializer = new D3D9Initializer(this);
|
||||
m_converter = new D3D9FormatHelper(m_dxvkDevice);
|
||||
|
||||
EmitCs([
|
||||
@ -5512,6 +5512,10 @@ namespace dxvk {
|
||||
|
||||
|
||||
void D3D9DeviceEx::EmitCsChunk(DxvkCsChunkRef&& chunk) {
|
||||
// Flush init commands so that the CS thread
|
||||
// can processe them before the first use.
|
||||
m_initializer->FlushCsChunk();
|
||||
|
||||
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
|
||||
}
|
||||
|
||||
@ -5881,7 +5885,6 @@ namespace dxvk {
|
||||
if constexpr (Synchronize9On12)
|
||||
m_submitStatus.result = VK_NOT_READY;
|
||||
|
||||
m_initializer->Flush();
|
||||
m_converter->Flush();
|
||||
|
||||
EmitStagingBufferMarker();
|
||||
@ -5908,6 +5911,10 @@ namespace dxvk {
|
||||
// Vulkan queue submission is performed.
|
||||
if constexpr (Synchronize9On12)
|
||||
m_dxvkDevice->waitForSubmission(&m_submitStatus);
|
||||
|
||||
// Notify the device that the context has been flushed,
|
||||
// this resets some resource initialization heuristics.
|
||||
m_initializer->NotifyContextFlush();
|
||||
}
|
||||
|
||||
|
||||
|
@ -1052,13 +1052,13 @@ namespace dxvk {
|
||||
InjectCsChunk(std::move(chunk), false);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
DxvkCsChunkRef AllocCsChunk() {
|
||||
DxvkCsChunk* chunk = m_csChunkPool.allocChunk(DxvkCsChunkFlag::SingleUse);
|
||||
return DxvkCsChunkRef(chunk, &m_csChunkPool);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
template<bool AllowFlush = true, typename Cmd>
|
||||
void EmitCs(Cmd&& command) {
|
||||
if (unlikely(!m_csChunk->push(command))) {
|
||||
|
@ -1,27 +1,27 @@
|
||||
#include <cstring>
|
||||
|
||||
#include "d3d9_initializer.h"
|
||||
#include "d3d9_device.h"
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
D3D9Initializer::D3D9Initializer(
|
||||
const Rc<DxvkDevice>& Device)
|
||||
: m_device(Device), m_context(m_device->createContext(DxvkContextType::Supplementary)) {
|
||||
m_context->beginRecording(
|
||||
m_device->createCommandList());
|
||||
D3D9DeviceEx* pParent)
|
||||
: m_parent(pParent),
|
||||
m_device(pParent->GetDXVKDevice()),
|
||||
m_csChunk(m_parent->AllocCsChunk()) {
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
D3D9Initializer::~D3D9Initializer() {
|
||||
|
||||
}
|
||||
|
||||
|
||||
void D3D9Initializer::Flush() {
|
||||
void D3D9Initializer::NotifyContextFlush() {
|
||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
if (m_transferCommands != 0)
|
||||
FlushInternal();
|
||||
m_transferCommands = 0;
|
||||
}
|
||||
|
||||
|
||||
@ -36,7 +36,7 @@ namespace dxvk {
|
||||
if (pBuffer->GetMapMode() == D3D9_COMMON_BUFFER_MAP_MODE_BUFFER)
|
||||
InitHostVisibleBuffer(pBuffer->GetBufferSlice<D3D9_COMMON_BUFFER_TYPE_STAGING>());
|
||||
}
|
||||
|
||||
|
||||
|
||||
void D3D9Initializer::InitTexture(
|
||||
D3D9CommonTexture* pTexture,
|
||||
@ -59,6 +59,8 @@ namespace dxvk {
|
||||
InitHostVisibleTexture(pTexture, pInitialData, mapPtr);
|
||||
pTexture->UnmapData();
|
||||
}
|
||||
|
||||
SyncSharedTexture(pTexture);
|
||||
}
|
||||
|
||||
|
||||
@ -68,10 +70,14 @@ namespace dxvk {
|
||||
|
||||
m_transferCommands += 1;
|
||||
|
||||
m_context->initBuffer(
|
||||
Slice.buffer());
|
||||
EmitCs([
|
||||
cBuffer = Slice.buffer()
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->initBuffer(
|
||||
cBuffer);
|
||||
});
|
||||
|
||||
FlushImplicit();
|
||||
ThrottleAllocationLocked();
|
||||
}
|
||||
|
||||
|
||||
@ -90,30 +96,17 @@ namespace dxvk {
|
||||
D3D9CommonTexture* pTexture) {
|
||||
std::lock_guard<dxvk::mutex> lock(m_mutex);
|
||||
|
||||
auto InitImage = [&](Rc<DxvkImage> image) {
|
||||
if (image == nullptr)
|
||||
return;
|
||||
Rc<DxvkImage> image = pTexture->GetImage();
|
||||
|
||||
auto formatInfo = lookupFormatInfo(image->info().format);
|
||||
EmitCs([
|
||||
cImage = std::move(image)
|
||||
] (DxvkContext* ctx) {
|
||||
ctx->initImage(cImage,
|
||||
cImage->getAvailableSubresources(),
|
||||
VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
});
|
||||
|
||||
m_transferCommands += 1;
|
||||
|
||||
// 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.
|
||||
VkImageSubresourceRange subresources;
|
||||
subresources.aspectMask = formatInfo->aspectMask;
|
||||
subresources.baseMipLevel = 0;
|
||||
subresources.levelCount = image->info().mipLevels;
|
||||
subresources.baseArrayLayer = 0;
|
||||
subresources.layerCount = image->info().numLayers;
|
||||
|
||||
m_context->initImage(image, subresources, VK_IMAGE_LAYOUT_UNDEFINED);
|
||||
};
|
||||
|
||||
InitImage(pTexture->GetImage());
|
||||
|
||||
FlushImplicit();
|
||||
ThrottleAllocationLocked();
|
||||
}
|
||||
|
||||
|
||||
@ -154,18 +147,46 @@ namespace dxvk {
|
||||
}
|
||||
|
||||
|
||||
void D3D9Initializer::FlushImplicit() {
|
||||
if (m_transferCommands > MaxTransferCommands
|
||||
|| m_transferMemory > MaxTransferMemory)
|
||||
FlushInternal();
|
||||
void D3D9Initializer::ThrottleAllocationLocked() {
|
||||
if (m_transferCommands > MaxTransferCommands)
|
||||
ExecuteFlushLocked();
|
||||
}
|
||||
|
||||
|
||||
void D3D9Initializer::FlushInternal() {
|
||||
m_context->flushCommandList(nullptr);
|
||||
|
||||
void D3D9Initializer::ExecuteFlush() {
|
||||
std::lock_guard lock(m_mutex);
|
||||
|
||||
ExecuteFlushLocked();
|
||||
}
|
||||
|
||||
|
||||
void D3D9Initializer::ExecuteFlushLocked() {
|
||||
EmitCs([] (DxvkContext* ctx) {
|
||||
ctx->flushCommandList(nullptr);
|
||||
});
|
||||
|
||||
FlushCsChunk();
|
||||
|
||||
m_transferCommands = 0;
|
||||
m_transferMemory = 0;
|
||||
}
|
||||
|
||||
|
||||
void D3D9Initializer::SyncSharedTexture(D3D9CommonTexture* pResource) {
|
||||
if (pResource->GetImage() == nullptr || pResource->GetImage()->info().sharing.mode == DxvkSharedHandleMode::None)
|
||||
return;
|
||||
|
||||
// Ensure that initialization commands are submitted and waited on before
|
||||
// returning control to the application in order to avoid race conditions
|
||||
// in case the texture is used immediately on a secondary device.
|
||||
ExecuteFlush();
|
||||
|
||||
m_device->waitForResource(pResource->GetImage(), DxvkAccess::Write);
|
||||
}
|
||||
|
||||
|
||||
void D3D9Initializer::FlushCsChunkLocked() {
|
||||
m_parent->InjectCsChunk(std::move(m_csChunk), false);
|
||||
m_csChunk = m_parent->AllocCsChunk();
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
|
||||
namespace dxvk {
|
||||
|
||||
class D3D9DeviceEx;
|
||||
|
||||
/**
|
||||
* \brief Resource initialization context
|
||||
*
|
||||
@ -18,28 +20,37 @@ namespace dxvk {
|
||||
public:
|
||||
|
||||
D3D9Initializer(
|
||||
const Rc<DxvkDevice>& Device);
|
||||
|
||||
D3D9DeviceEx* pParent);
|
||||
|
||||
~D3D9Initializer();
|
||||
|
||||
void Flush();
|
||||
void FlushCsChunk() {
|
||||
std::lock_guard<dxvk::mutex> lock(m_csMutex);
|
||||
|
||||
if (!m_csChunk->empty())
|
||||
FlushCsChunkLocked();
|
||||
}
|
||||
|
||||
void NotifyContextFlush();
|
||||
|
||||
void InitBuffer(
|
||||
D3D9CommonBuffer* pBuffer);
|
||||
|
||||
|
||||
void InitTexture(
|
||||
D3D9CommonTexture* pTexture,
|
||||
void* pInitialData = nullptr);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
dxvk::mutex m_mutex;
|
||||
|
||||
D3D9DeviceEx* m_parent;
|
||||
Rc<DxvkDevice> m_device;
|
||||
Rc<DxvkContext> m_context;
|
||||
|
||||
size_t m_transferCommands = 0;
|
||||
size_t m_transferMemory = 0;
|
||||
|
||||
dxvk::mutex m_csMutex;
|
||||
DxvkCsChunkRef m_csChunk;
|
||||
|
||||
void InitDeviceLocalBuffer(
|
||||
DxvkBufferSlice Slice);
|
||||
@ -54,9 +65,30 @@ namespace dxvk {
|
||||
D3D9CommonTexture* pTexture,
|
||||
void* pInitialData,
|
||||
void* mapPtr);
|
||||
|
||||
void FlushImplicit();
|
||||
void FlushInternal();
|
||||
|
||||
void ThrottleAllocationLocked();
|
||||
|
||||
void ExecuteFlush();
|
||||
|
||||
void ExecuteFlushLocked();
|
||||
|
||||
void SyncSharedTexture(
|
||||
D3D9CommonTexture* pResource);
|
||||
|
||||
void FlushCsChunkLocked();
|
||||
|
||||
void NotifyContextFlushLocked();
|
||||
|
||||
template<typename Cmd>
|
||||
void EmitCs(Cmd&& command) {
|
||||
std::lock_guard<dxvk::mutex> lock(m_csMutex);
|
||||
|
||||
if (unlikely(!m_csChunk->push(command))) {
|
||||
FlushCsChunkLocked();
|
||||
|
||||
m_csChunk->push(command);
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user