Skip to content

Commit eb08468

Browse files
committed
Rework Vulkan present queue synchronization
1 parent 8bbd608 commit eb08468

19 files changed

+88
-94
lines changed

source/addon.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -297,11 +297,9 @@ void ReShadeUpdateAndPresentEffectRuntime(reshade::api::effect_runtime *runtime)
297297
if (runtime == nullptr)
298298
return;
299299

300-
reshade::api::command_queue *const present_queue = runtime->get_command_queue();
300+
static_cast<reshade::runtime *>(runtime)->on_present();
301301

302-
static_cast<reshade::runtime *>(runtime)->on_present(present_queue);
303-
304-
present_queue->flush_immediate_command_list();
302+
runtime->get_command_queue()->flush_immediate_command_list();
305303
}
306304

307305
#if RESHADE_GUI

source/d3d12/d3d12_command_queue_downlevel.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ HRESULT STDMETHODCALLTYPE D3D12CommandQueueDownlevel::Present(ID3D12GraphicsComm
105105
reshade::invoke_addon_event<reshade::addon_event::present>(_parent_queue, this, nullptr, nullptr, 0, nullptr);
106106
#endif
107107

108-
reshade::present_effect_runtime(this, _parent_queue);
108+
reshade::present_effect_runtime(this);
109109

110110
_parent_queue->flush_immediate_command_list();
111111
}

source/d3d12/d3d12_impl_command_queue.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#pragma once
77

88
#include "d3d12_impl_command_list_immediate.hpp"
9-
#include <shared_mutex>
9+
#include <mutex>
1010

1111
namespace reshade::d3d12
1212
{

source/d3d9/d3d9_swapchain.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ void Direct3DSwapChain9::on_present(const RECT *source_rect, [[maybe_unused]] co
240240

241241
// Only call into the effect runtime if the entire surface is presented, to avoid partial updates messing up effects and the GUI
242242
if (is_presenting_entire_surface(source_rect, window_override))
243-
reshade::present_effect_runtime(this, _device);
243+
reshade::present_effect_runtime(this);
244244

245245
_hwnd = nullptr;
246246

source/dxgi/dxgi_swapchain.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -767,7 +767,7 @@ void DXGISwapChain::on_present(UINT flags, [[maybe_unused]] const DXGI_PRESENT_P
767767
params != nullptr ? params->DirtyRectsCount : 0,
768768
params != nullptr ? reinterpret_cast<const reshade::api::rect *>(params->pDirtyRects) : nullptr);
769769
#endif
770-
reshade::present_effect_runtime(_impl, static_cast<D3D10Device *>(static_cast<ID3D10Device *>(_direct3d_device)));
770+
reshade::present_effect_runtime(_impl);
771771
break;
772772
case 11:
773773
#if RESHADE_ADDON
@@ -783,7 +783,7 @@ void DXGISwapChain::on_present(UINT flags, [[maybe_unused]] const DXGI_PRESENT_P
783783
params != nullptr ? params->DirtyRectsCount : 0,
784784
params != nullptr ? reinterpret_cast<const reshade::api::rect *>(params->pDirtyRects) : nullptr);
785785
#endif
786-
reshade::present_effect_runtime(_impl, static_cast<D3D11Device *>(static_cast<ID3D11Device *>(_direct3d_device))->_immediate_context);
786+
reshade::present_effect_runtime(_impl);
787787
break;
788788
case 12:
789789
#if RESHADE_ADDON
@@ -795,7 +795,7 @@ void DXGISwapChain::on_present(UINT flags, [[maybe_unused]] const DXGI_PRESENT_P
795795
params != nullptr ? params->DirtyRectsCount : 0,
796796
params != nullptr ? reinterpret_cast<const reshade::api::rect *>(params->pDirtyRects) : nullptr);
797797
#endif
798-
reshade::present_effect_runtime(_impl, static_cast<D3D12CommandQueue *>(_direct3d_command_queue));
798+
reshade::present_effect_runtime(_impl);
799799
static_cast<D3D12CommandQueue *>(_direct3d_command_queue)->flush_immediate_command_list();
800800
break;
801801
}

source/opengl/opengl_hooks_wgl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ class wgl_swapchain : public reshade::opengl::swapchain_impl
337337
#endif
338338

339339
// Assume that the correct OpenGL context is still current here
340-
reshade::present_effect_runtime(this, context);
340+
reshade::present_effect_runtime(this);
341341

342342
#ifndef NDEBUG
343343
GLenum type = GL_NONE; char message[512] = "";

source/openvr/openvr_hooks.cpp

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,14 @@ static vr::EVRCompositorError on_vr_submit_d3d10(vr::IVRCompositor *compositor,
4646
{
4747
if (device_proxy == nullptr)
4848
return submit(eye, texture, bounds, layer, flags); // No proxy device found, so just submit normally
49-
else if (s_vr_swapchain == nullptr)
49+
50+
if (nullptr == s_vr_swapchain)
5051
s_vr_swapchain = new reshade::openvr::swapchain_impl(device_proxy, compositor);
5152
// It is not valid to switch the texture type once submitted for the first time
5253
else if (s_vr_swapchain->get_device() != device_proxy)
5354
return vr::VRCompositorError_InvalidTexture;
5455

55-
if (!s_vr_swapchain->on_vr_submit(device_proxy, eye, { reinterpret_cast<uintptr_t>(texture) }, color_space, bounds, eye))
56+
if (!s_vr_swapchain->on_vr_submit(eye, { reinterpret_cast<uintptr_t>(texture) }, color_space, bounds, eye))
5657
{
5758
// Failed to initialize effect runtime or copy the eye texture, so submit normally without applying effects
5859
#if RESHADE_VERBOSE_LOG
@@ -95,13 +96,14 @@ static vr::EVRCompositorError on_vr_submit_d3d11(vr::IVRCompositor *compositor,
9596
const auto device_proxy = get_private_pointer_d3dx<D3D11Device>(device.get());
9697
if (device_proxy == nullptr)
9798
return submit(eye, texture, bounds, layer, flags); // No proxy device found, so just submit normally
98-
else if (s_vr_swapchain == nullptr)
99+
100+
if (nullptr == s_vr_swapchain)
99101
s_vr_swapchain = new reshade::openvr::swapchain_impl(device_proxy, compositor);
100102
// It is not valid to switch the texture type once submitted for the first time
101103
else if (s_vr_swapchain->get_device() != device_proxy)
102104
return vr::VRCompositorError_InvalidTexture;
103105

104-
if (!s_vr_swapchain->on_vr_submit(device_proxy->_immediate_context, eye, { reinterpret_cast<uintptr_t>(texture) }, color_space, bounds, eye))
106+
if (!s_vr_swapchain->on_vr_submit(eye, { reinterpret_cast<uintptr_t>(texture) }, color_space, bounds, eye))
105107
{
106108
// Failed to initialize effect runtime or copy the eye texture, so submit normally without applying effects
107109
#if RESHADE_VERBOSE_LOG
@@ -128,16 +130,17 @@ static vr::EVRCompositorError on_vr_submit_d3d12(vr::IVRCompositor *compositor,
128130
com_ptr<D3D12CommandQueue> command_queue_proxy;
129131
if (FAILED(texture->m_pCommandQueue->QueryInterface(IID_PPV_ARGS(&command_queue_proxy))))
130132
return submit(eye, (void *)texture, bounds, layer, flags); // No proxy command queue found, so just submit normally
131-
else if (s_vr_swapchain == nullptr)
133+
134+
if (nullptr == s_vr_swapchain)
132135
s_vr_swapchain = new reshade::openvr::swapchain_impl(command_queue_proxy.get(), compositor);
133-
else if (s_vr_swapchain->get_device() != command_queue_proxy->get_device())
136+
else if (s_vr_swapchain->get_command_queue() != command_queue_proxy.get())
134137
return vr::VRCompositorError_InvalidTexture;
135138

136139
// Synchronize access to the command queue while events are invoked and the immediate command list may be accessed
137140
std::unique_lock<std::recursive_mutex> lock(command_queue_proxy->_mutex);
138141

139142
// Resource should be in D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE state at this point
140-
if (!s_vr_swapchain->on_vr_submit(command_queue_proxy.get(), eye, { reinterpret_cast<uintptr_t>(texture->m_pResource) }, color_space, bounds, layer))
143+
if (!s_vr_swapchain->on_vr_submit(eye, { reinterpret_cast<uintptr_t>(texture->m_pResource) }, color_space, bounds, layer))
141144
{
142145
// Failed to initialize effect runtime or copy the eye texture, so submit normally without applying effects
143146
#if RESHADE_VERBOSE_LOG
@@ -169,15 +172,16 @@ static vr::EVRCompositorError on_vr_submit_opengl(vr::IVRCompositor *compositor,
169172

170173
if (g_opengl_context == nullptr)
171174
return submit(eye, reinterpret_cast<void *>(static_cast<uintptr_t>(object)), bounds, layer, flags);
172-
else if (s_vr_swapchain == nullptr)
175+
176+
if (nullptr == s_vr_swapchain)
173177
s_vr_swapchain = new reshade::openvr::swapchain_impl(g_opengl_context->get_device(), g_opengl_context, compositor);
174-
else if (s_vr_swapchain->get_device() != g_opengl_context->get_device())
178+
else if (s_vr_swapchain->get_command_queue() != g_opengl_context)
175179
return vr::VRCompositorError_InvalidTexture;
176180

177181
const reshade::api::resource eye_texture = reshade::opengl::make_resource_handle(
178182
(flags & vr::Submit_GlRenderBuffer) != 0 ? GL_RENDERBUFFER : ((flags & vr::Submit_GlArrayTexture) != 0 ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D), object);
179183

180-
if (!s_vr_swapchain->on_vr_submit(g_opengl_context, eye, eye_texture, color_space, bounds, layer))
184+
if (!s_vr_swapchain->on_vr_submit(eye, eye_texture, color_space, bounds, layer))
181185
{
182186
// Failed to initialize effect runtime or copy the eye texture, so submit normally without applying effects
183187
#if RESHADE_VERBOSE_LOG
@@ -217,14 +221,14 @@ static vr::EVRCompositorError on_vr_submit_vulkan(vr::IVRCompositor *compositor,
217221
else
218222
return submit(eye, (void *)texture, bounds, layer, flags);
219223

220-
if (s_vr_swapchain == nullptr)
224+
if (nullptr == s_vr_swapchain)
221225
// OpenVR requires the passed in queue to be a graphics queue, so can safely use it
222226
s_vr_swapchain = new reshade::openvr::swapchain_impl(device, queue, compositor);
223-
else if (s_vr_swapchain->get_device() != device)
227+
else if (s_vr_swapchain->get_command_queue() != queue)
224228
return vr::VRCompositorError_InvalidTexture;
225229

226230
// Image should be in VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL layout at this point
227-
if (!s_vr_swapchain->on_vr_submit(queue, eye, { (uint64_t)(VkImage)texture->m_nImage }, color_space, bounds, (flags & vr::Submit_VulkanTextureWithArrayData) != 0 ? static_cast<const vr::VRVulkanTextureArrayData_t *>(texture)->m_unArrayIndex : layer))
231+
if (!s_vr_swapchain->on_vr_submit(eye, { (uint64_t)(VkImage)texture->m_nImage }, color_space, bounds, (flags & vr::Submit_VulkanTextureWithArrayData) != 0 ? static_cast<const vr::VRVulkanTextureArrayData_t *>(texture)->m_unArrayIndex : layer))
228232
{
229233
// Failed to initialize effect runtime or copy the eye texture, so submit normally without applying effects
230234
#if RESHADE_VERBOSE_LOG

source/openvr/openvr_impl_swapchain.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ reshade::openvr::swapchain_impl::swapchain_impl(D3D12CommandQueue *queue, vr::IV
4242

4343
reshade::openvr::swapchain_impl::swapchain_impl(api::device *device, api::command_queue *graphics_queue, vr::IVRCompositor *compositor) :
4444
api_object_impl(compositor),
45-
_device(device)
45+
_device(device),
46+
_graphics_queue(graphics_queue)
4647
{
4748
_is_opengl = device->get_api() == api::device_api::opengl;
4849

@@ -143,7 +144,7 @@ void reshade::openvr::swapchain_impl::on_reset()
143144
_side_by_side_texture = {};
144145
}
145146

146-
bool reshade::openvr::swapchain_impl::on_vr_submit(api::command_queue *queue, vr::EVREye eye, api::resource eye_texture, vr::EColorSpace color_space, const vr::VRTextureBounds_t *bounds, uint32_t layer)
147+
bool reshade::openvr::swapchain_impl::on_vr_submit(vr::EVREye eye, api::resource eye_texture, vr::EColorSpace color_space, const vr::VRTextureBounds_t *bounds, uint32_t layer)
147148
{
148149
assert(eye < 2 && eye_texture != 0);
149150

@@ -211,7 +212,7 @@ bool reshade::openvr::swapchain_impl::on_vr_submit(api::command_queue *queue, vr
211212
return false;
212213
}
213214

214-
api::command_list *const cmd_list = queue->get_immediate_command_list();
215+
api::command_list *const cmd_list = _graphics_queue->get_immediate_command_list();
215216

216217
// Copy region of the source texture (in case of an array texture, copy from the layer corresponding to the current eye)
217218
const api::subresource_box dest_box = get_eye_subresource_box(eye);
@@ -250,11 +251,11 @@ bool reshade::openvr::swapchain_impl::on_vr_submit(api::command_queue *queue, vr
250251

251252
#if RESHADE_ADDON
252253
const reshade::api::rect eye_rect = get_eye_rect(eye);
253-
invoke_addon_event<reshade::addon_event::present>(queue, this, &eye_rect, &eye_rect, 0, nullptr);
254+
invoke_addon_event<reshade::addon_event::present>(_graphics_queue, this, &eye_rect, &eye_rect, 0, nullptr);
254255
#endif
255256

256257
if (eye == vr::Eye_Right)
257-
reshade::present_effect_runtime(this, queue);
258+
reshade::present_effect_runtime(this);
258259

259260
return true;
260261
}

source/openvr/openvr_impl_swapchain.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ namespace reshade::openvr
2424
~swapchain_impl();
2525

2626
api::device *get_device() final;
27+
api::command_queue *get_command_queue() { return _graphics_queue; }
2728

2829
void *get_hwnd() const final { return nullptr; }
2930

@@ -43,10 +44,11 @@ namespace reshade::openvr
4344
bool on_init();
4445
void on_reset();
4546

46-
bool on_vr_submit(api::command_queue *queue, vr::EVREye eye, api::resource eye_texture, vr::EColorSpace color_space, const vr::VRTextureBounds_t *bounds, uint32_t layer);
47+
bool on_vr_submit(vr::EVREye eye, api::resource eye_texture, vr::EColorSpace color_space, const vr::VRTextureBounds_t *bounds, uint32_t layer);
4748

4849
private:
4950
api::device *const _device;
51+
api::command_queue *const _graphics_queue;
5052
api::resource _side_by_side_texture = {};
5153
void *_direct3d_device = nullptr;
5254
bool _is_opengl = false;

source/openxr/openxr_impl_swapchain.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ void reshade::openxr::swapchain_impl::on_present(uint32_t view_count, const api:
144144
invoke_addon_event<addon_event::present>(_graphics_queue, this, nullptr, nullptr, 0, nullptr);
145145
#endif
146146

147-
present_effect_runtime(this, _graphics_queue);
147+
present_effect_runtime(this);
148148

149149
cmd_list->barrier(view_textures[0], api::resource_usage::present, before_state);
150150
}
@@ -195,7 +195,7 @@ void reshade::openxr::swapchain_impl::on_present(uint32_t view_count, const api:
195195
invoke_addon_event<addon_event::present>(_graphics_queue, this, nullptr, nullptr, 0, nullptr);
196196
#endif
197197

198-
present_effect_runtime(this, _graphics_queue);
198+
present_effect_runtime(this);
199199

200200
cmd_list->barrier(_side_by_side_texture, api::resource_usage::present, api::resource_usage::copy_source);
201201

source/runtime.cpp

Lines changed: 1 addition & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -554,9 +554,6 @@ void reshade::runtime::on_reset()
554554
destroy_state_block(_device, _app_state);
555555
_app_state = {};
556556

557-
_device->destroy_fence(_queue_sync_fence);
558-
_queue_sync_fence = {};
559-
560557
_width = _height = 0;
561558
_back_buffer_format = api::format::unknown;
562559
_back_buffer_samples = 1;
@@ -575,32 +572,11 @@ void reshade::runtime::on_reset()
575572

576573
log::message(log::level::info, "Destroyed runtime environment on runtime %p ('%s').", this, _config_path.u8string().c_str());
577574
}
578-
void reshade::runtime::on_present(api::command_queue *present_queue)
575+
void reshade::runtime::on_present()
579576
{
580-
assert(present_queue != nullptr);
581-
582577
if (!_is_initialized)
583578
return;
584579

585-
// If the application is presenting with a different queue than rendering, synchronize these two queues first
586-
// This ensures that it has finished rendering before ReShade applies its own rendering
587-
if (present_queue != _graphics_queue)
588-
{
589-
if (_queue_sync_fence == 0 &&
590-
!_device->create_fence(_queue_sync_value, api::fence_flags::none, &_queue_sync_fence))
591-
{
592-
log::message(log::level::error, "Failed to create queue synchronization fence!");
593-
return;
594-
}
595-
596-
_queue_sync_value++;
597-
598-
// Signal from the queue the application is presenting with
599-
if (present_queue->signal(_queue_sync_fence, _queue_sync_value))
600-
// Wait on that before the immediate command list flush below
601-
_graphics_queue->wait(_queue_sync_fence, _queue_sync_value);
602-
}
603-
604580
#if RESHADE_ADDON
605581
_is_in_present_call = true;
606582
#endif
@@ -848,14 +824,6 @@ void reshade::runtime::on_present(api::command_queue *present_queue)
848824
// Apply previous state from application
849825
apply_state(cmd_list, _app_state);
850826

851-
if (present_queue != _graphics_queue)
852-
{
853-
_queue_sync_value++;
854-
855-
if (_graphics_queue->signal(_queue_sync_fence, _queue_sync_value))
856-
present_queue->wait(_queue_sync_fence, _queue_sync_value);
857-
}
858-
859827
// Update input status
860828
if (_input != nullptr)
861829
_input->next_frame();

source/runtime.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ namespace reshade
3535

3636
bool on_init();
3737
void on_reset();
38-
void on_present(api::command_queue *present_queue);
38+
void on_present();
3939

4040
uint64_t get_native() const final { return _swapchain->get_native(); }
4141

@@ -342,9 +342,6 @@ namespace reshade
342342
std::vector<api::resource_view> _back_buffer_targets;
343343

344344
api::state_block _app_state = {};
345-
346-
api::fence _queue_sync_fence = {};
347-
uint64_t _queue_sync_value = 0;
348345
#pragma endregion
349346

350347
#pragma region Screenshot

source/runtime_gui_vr.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -342,7 +342,7 @@ void reshade::runtime::draw_gui_vr()
342342
texture_data.vulkan.m_pPhysicalDevice = static_cast<vulkan::device_impl *>(_device)->_physical_device;
343343
texture_data.vulkan.m_pInstance = VK_NULL_HANDLE;
344344
texture_data.vulkan.m_pQueue = reinterpret_cast<VkQueue_T *>(_graphics_queue->get_native());
345-
texture_data.vulkan.m_nQueueFamilyIndex = static_cast<vulkan::device_impl *>(_device)->_graphics_queue_family_index;
345+
texture_data.vulkan.m_nQueueFamilyIndex = static_cast<vulkan::device_impl *>(_device)->_primary_graphics_queue_family_index;
346346
texture_data.vulkan.m_nWidth = OVERLAY_WIDTH;
347347
texture_data.vulkan.m_nHeight = OVERLAY_HEIGHT;
348348
texture_data.vulkan.m_nFormat = VK_FORMAT_R8G8B8A8_UNORM;

source/runtime_manager.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,8 @@ void reshade::reset_effect_runtime(api::swapchain *swapchain)
7272
if (const auto runtime = swapchain->get_private_data<reshade::runtime>())
7373
runtime->on_reset();
7474
}
75-
void reshade::present_effect_runtime(api::swapchain *swapchain, reshade::api::command_queue *present_queue)
75+
void reshade::present_effect_runtime(api::swapchain *swapchain)
7676
{
7777
if (const auto runtime = swapchain->get_private_data<reshade::runtime>())
78-
runtime->on_present(present_queue);
78+
runtime->on_present();
7979
}

source/runtime_manager.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,5 @@ namespace reshade
1414

1515
void init_effect_runtime(api::swapchain *swapchain);
1616
void reset_effect_runtime(api::swapchain *swapchain);
17-
void present_effect_runtime(api::swapchain *swapchain, api::command_queue *present_queue);
17+
void present_effect_runtime(api::swapchain *swapchain);
1818
}

0 commit comments

Comments
 (0)