1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2025-01-31 14:52:11 +01:00

[d3d9] Remove additional swap chain context

This commit is contained in:
Philip Rebohle 2024-10-02 12:09:48 +02:00 committed by Philip Rebohle
parent 172d3450d1
commit 2af3fde5f2
4 changed files with 83 additions and 70 deletions

View File

@ -85,6 +85,8 @@ namespace dxvk {
ctx->setLogicOpState(loState); ctx->setLogicOpState(loState);
}); });
SynchronizeCsThread(DxvkCsThread::SynchronizeAll);
if (!(BehaviorFlags & D3DCREATE_FPU_PRESERVE)) if (!(BehaviorFlags & D3DCREATE_FPU_PRESERVE))
SetupFPU(); SetupFPU();
@ -5465,6 +5467,13 @@ namespace dxvk {
} }
void D3D9DeviceEx::InjectCsChunk(
DxvkCsChunkRef&& Chunk,
bool Synchronize) {
m_csThread.injectChunk(std::move(Chunk), Synchronize);
}
void D3D9DeviceEx::EmitCsChunk(DxvkCsChunkRef&& chunk) { void D3D9DeviceEx::EmitCsChunk(DxvkCsChunkRef&& chunk) {
m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk)); m_csSeqNum = m_csThread.dispatchChunk(std::move(chunk));
} }

View File

@ -1039,6 +1039,19 @@ namespace dxvk {
return m_swvpEmulator.GetShaderCount(); return m_swvpEmulator.GetShaderCount();
} }
void InjectCsChunk(
DxvkCsChunkRef&& Chunk,
bool Synchronize);
template<typename Fn>
void InjectCs(
Fn&& Command) {
auto chunk = AllocCsChunk();
chunk->push(std::move(Command));
InjectCsChunk(std::move(chunk), false);
}
private: private:
DxvkCsChunkRef AllocCsChunk() { DxvkCsChunkRef AllocCsChunk() {

View File

@ -26,7 +26,6 @@ namespace dxvk {
const D3DDISPLAYMODEEX* pFullscreenDisplayMode) const D3DDISPLAYMODEEX* pFullscreenDisplayMode)
: D3D9SwapChainExBase(pDevice) : D3D9SwapChainExBase(pDevice)
, m_device (pDevice->GetDXVKDevice()) , m_device (pDevice->GetDXVKDevice())
, m_context (m_device->createContext(DxvkContextType::Supplementary))
, m_frameLatencyCap (pDevice->GetOptions()->maxFrameLatency) , m_frameLatencyCap (pDevice->GetOptions()->maxFrameLatency)
, m_dialog (pDevice->GetOptions()->enableDialogMode) , m_dialog (pDevice->GetOptions()->enableDialogMode)
, m_swapchainExt (this) { , m_swapchainExt (this) {
@ -815,7 +814,7 @@ namespace dxvk {
// Presentation semaphores and WSI swap chain image // Presentation semaphores and WSI swap chain image
PresenterInfo info = m_wctx->presenter->info(); PresenterInfo info = m_wctx->presenter->info();
PresenterSync sync; PresenterSync sync = { };
uint32_t imageIndex = 0; uint32_t imageIndex = 0;
@ -836,9 +835,6 @@ namespace dxvk {
m_dirtyHdrMetadata = false; m_dirtyHdrMetadata = false;
} }
m_context->beginRecording(
m_device->createCommandList());
VkRect2D srcRect = { VkRect2D srcRect = {
{ int32_t(m_srcRect.left), int32_t(m_srcRect.top) }, { int32_t(m_srcRect.left), int32_t(m_srcRect.top) },
{ uint32_t(m_srcRect.right - m_srcRect.left), uint32_t(m_srcRect.bottom - m_srcRect.top) } }; { uint32_t(m_srcRect.right - m_srcRect.left), uint32_t(m_srcRect.bottom - m_srcRect.top) } };
@ -847,19 +843,57 @@ namespace dxvk {
{ int32_t(m_dstRect.left), int32_t(m_dstRect.top) }, { int32_t(m_dstRect.left), int32_t(m_dstRect.top) },
{ uint32_t(m_dstRect.right - m_dstRect.left), uint32_t(m_dstRect.bottom - m_dstRect.top) } }; { uint32_t(m_dstRect.right - m_dstRect.left), uint32_t(m_dstRect.bottom - m_dstRect.top) } };
m_blitter->beginPresent(m_context->beginExternalRendering(), // Bump frame ID
m_wctx->imageViews.at(imageIndex), m_colorspace, dstRect, if (!i)
swapImageView, m_colorspace, srcRect); m_wctx->frameId += 1;
if (m_hud) { // Present from CS thread so that we don't
m_hud->render(m_context->beginExternalRendering(), // have to synchronize with it first.
m_wctx->imageViews.at(imageIndex), m_colorspace); m_presentStatus.result = VK_NOT_READY;
m_parent->EmitCs([
cPresentStatus = &m_presentStatus,
cDevice = m_device,
cPresenter = m_wctx->presenter,
cBlitter = m_blitter,
cColorSpace = m_colorspace,
cSrcView = swapImageView,
cSrcRect = srcRect,
cDstView = m_wctx->imageViews.at(imageIndex),
cDstRect = dstRect,
cRepeat = i,
cSync = sync,
cHud = m_hud,
cFrameId = m_wctx->frameId
] (DxvkContext* ctx) {
// Blit back buffer onto Vulkan swap chain
auto contextObjects = ctx->beginExternalRendering();
cBlitter->beginPresent(contextObjects,
cDstView, cColorSpace, cDstRect,
cSrcView, cColorSpace, cSrcRect);
if (cHud) {
if (!cRepeat)
cHud->update();
cHud->render(contextObjects, cDstView, cColorSpace);
} }
m_blitter->endPresent(m_context->beginExternalRendering(), cBlitter->endPresent(contextObjects, cDstView);
m_wctx->imageViews.at(imageIndex));
SubmitPresent(sync, i); // Submit command list and present
ctx->synchronizeWsi(cSync);
ctx->flushCommandList(nullptr);
uint64_t frameId = cRepeat ? 0 : cFrameId;
cDevice->presentImage(cPresenter,
cPresenter->info().presentMode,
frameId, cPresentStatus);
});
m_parent->FlushCsChunk();
} }
SyncFrameLatency(); SyncFrameLatency();
@ -873,39 +907,6 @@ namespace dxvk {
} }
void D3D9SwapChainEx::SubmitPresent(const PresenterSync& Sync, uint32_t Repeat) {
// Bump frame ID
if (!Repeat)
m_wctx->frameId += 1;
// Present from CS thread so that we don't
// have to synchronize with it first.
m_presentStatus.result = VK_NOT_READY;
m_parent->EmitCs([this,
cRepeat = Repeat,
cSync = Sync,
cHud = m_hud,
cPresentMode = m_wctx->presenter->info().presentMode,
cFrameId = m_wctx->frameId,
cCommandList = m_context->endRecording()
] (DxvkContext* ctx) {
cCommandList->setWsiSemaphores(cSync);
m_device->submitCommandList(cCommandList, nullptr);
if (cHud != nullptr && !cRepeat)
cHud->update();
uint64_t frameId = cRepeat ? 0 : cFrameId;
m_device->presentImage(m_wctx->presenter,
cPresentMode, frameId, &m_presentStatus);
});
m_parent->FlushCsChunk();
}
void D3D9SwapChainEx::SynchronizePresent() { void D3D9SwapChainEx::SynchronizePresent() {
// Recreate swap chain if the previous present call failed // Recreate swap chain if the previous present call failed
VkResult status = m_device->waitForSubmission(&m_presentStatus); VkResult status = m_device->waitForSubmission(&m_presentStatus);
@ -1083,29 +1084,22 @@ namespace dxvk {
m_backBuffers.emplace_back(surface); m_backBuffers.emplace_back(surface);
} }
auto swapImage = m_backBuffers[0]->GetCommonTexture()->GetImage();
// Initialize the image so that we can use it. Clearing // Initialize the image so that we can use it. Clearing
// to black prevents garbled output for the first frame. // to black prevents garbled output for the first frame.
VkImageSubresourceRange subresources; small_vector<Rc<DxvkImage>, 4> images;
subresources.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
subresources.baseMipLevel = 0;
subresources.levelCount = 1;
subresources.baseArrayLayer = 0;
subresources.layerCount = 1;
m_context->beginRecording( for (size_t i = 0; i < m_backBuffers.size(); i++)
m_device->createCommandList()); images.push_back(m_backBuffers[i]->GetCommonTexture()->GetImage());
for (uint32_t i = 0; i < m_backBuffers.size(); i++) { m_parent->InjectCs([
m_context->initImage( cImages = std::move(images)
m_backBuffers[i]->GetCommonTexture()->GetImage(), ] (DxvkContext* ctx) {
subresources, VK_IMAGE_LAYOUT_UNDEFINED); for (size_t i = 0; i < cImages.size(); i++) {
ctx->initImage(cImages[i],
cImages[i]->getAvailableSubresources(),
VK_IMAGE_LAYOUT_UNDEFINED);
} }
});
m_device->submitCommandList(
m_context->endRecording(),
nullptr);
return D3D_OK; return D3D_OK;
} }

View File

@ -145,7 +145,6 @@ namespace dxvk {
D3DGAMMARAMP m_ramp; D3DGAMMARAMP m_ramp;
Rc<DxvkDevice> m_device; Rc<DxvkDevice> m_device;
Rc<DxvkContext> m_context;
Rc<DxvkSwapchainBlitter> m_blitter; Rc<DxvkSwapchainBlitter> m_blitter;
std::unordered_map< std::unordered_map<
@ -192,8 +191,6 @@ namespace dxvk {
void PresentImage(UINT PresentInterval); void PresentImage(UINT PresentInterval);
void SubmitPresent(const PresenterSync& Sync, uint32_t Repeat);
void SynchronizePresent(); void SynchronizePresent();
void RecreateSwapChain(); void RecreateSwapChain();