From 4d95676745e01919fc35345c6a7a1660f9fde4c7 Mon Sep 17 00:00:00 2001 From: crosire Date: Sun, 16 Jan 2022 00:29:42 +0100 Subject: [PATCH] Add "reshade_present" event and API to get window handle from swapchain --- include/reshade_api_device.hpp | 11 ++++++++++ include/reshade_events.hpp | 7 +++++++ .../d3d12/d3d12_command_queue_downlevel.cpp | 4 ++++ source/d3d9/d3d9_device.cpp | 6 ++++++ source/d3d9/d3d9_swapchain.cpp | 3 +++ source/dxgi/dxgi_swapchain.cpp | 9 +++++++++ source/input.hpp | 2 ++ source/opengl/opengl_hooks_wgl.cpp | 4 ++++ source/opengl/opengl_impl_device.cpp | 1 + source/openvr/openvr.cpp | 20 +++++++++++++++++++ source/runtime.hpp | 5 +++++ source/runtime_api.cpp | 5 +++++ source/vulkan/vulkan_hooks_device.cpp | 3 +++ source/vulkan/vulkan_impl_device.cpp | 2 ++ 14 files changed, 82 insertions(+) diff --git a/include/reshade_api_device.hpp b/include/reshade_api_device.hpp index 0623668057..ea251822e2 100644 --- a/include/reshade_api_device.hpp +++ b/include/reshade_api_device.hpp @@ -941,6 +941,7 @@ namespace reshade::api /// /// Index of the back buffer. This has to be between zero and the value returned by . virtual resource get_back_buffer(uint32_t index) = 0; + /// /// Gets the number of back buffer resources in this swap chain. /// @@ -954,5 +955,15 @@ namespace reshade::api /// Gets the index of the back buffer resource that can currently be rendered into. /// virtual uint32_t get_current_back_buffer_index() const = 0; + + /// + /// Gets the HWND of the window this swap chain was created with, or if none exists. + /// + virtual void *get_window_handle() const = 0; + + /// + /// Gets the description of the back buffer resources in this swap chain. + /// + inline resource_desc get_back_buffer_resource_desc() { return get_device()->get_resource_desc(get_current_back_buffer()); } }; } diff --git a/include/reshade_events.hpp b/include/reshade_events.hpp index 1e633d55a1..a13a59ab22 100644 --- a/include/reshade_events.hpp +++ b/include/reshade_events.hpp @@ -1390,6 +1390,12 @@ namespace reshade /// present, + /// + /// Called after ReShade has rendered its overlay. + /// Callback function signature: void (api::command_queue *queue, api::effect_runtime *runtime) + /// + reshade_present, + /// /// Called right before ReShade effects are rendered. /// Callback function signature: void (api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb) @@ -1540,6 +1546,7 @@ namespace reshade RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::present, void, api::command_queue *queue, api::swapchain *swapchain); + RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_present, void, api::command_queue *queue, api::effect_runtime *runtime); RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_begin_effects, void, api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb); RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_finish_effects, void, api::effect_runtime *runtime, api::command_list *cmd_list, api::resource_view rtv, api::resource_view rtv_srgb); RESHADE_DEFINE_ADDON_EVENT_TRAITS(addon_event::reshade_reloaded_effects, void, api::effect_runtime *runtime); diff --git a/source/d3d12/d3d12_command_queue_downlevel.cpp b/source/d3d12/d3d12_command_queue_downlevel.cpp index b71a8b2c3c..df1c6558be 100644 --- a/source/d3d12/d3d12_command_queue_downlevel.cpp +++ b/source/d3d12/d3d12_command_queue_downlevel.cpp @@ -51,6 +51,10 @@ HRESULT STDMETHODCALLTYPE D3D12CommandQueueDownlevel::Present(ID3D12GraphicsComm swapchain_impl::on_present(pSourceTex2D, hWindow); +#if RESHADE_ADDON + reshade::invoke_addon_event(_parent_queue, this); +#endif + _parent_queue->flush_immediate_command_list(); // Get original command list pointer from proxy object diff --git a/source/d3d9/d3d9_device.cpp b/source/d3d9/d3d9_device.cpp index 254e23250e..ac8b2be6c7 100644 --- a/source/d3d9/d3d9_device.cpp +++ b/source/d3d9/d3d9_device.cpp @@ -574,6 +574,9 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice9::Present(const RECT *pSourceRect, cons reshade::invoke_addon_event(this, _implicit_swapchain); #endif _implicit_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(this, _implicit_swapchain); +#endif } return _orig->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion); @@ -2186,6 +2189,9 @@ HRESULT STDMETHODCALLTYPE Direct3DDevice9::PresentEx(const RECT *pSourceRect, co reshade::invoke_addon_event(this, _implicit_swapchain); #endif _implicit_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(this, _implicit_swapchain); +#endif } assert(_extended_interface); diff --git a/source/d3d9/d3d9_swapchain.cpp b/source/d3d9/d3d9_swapchain.cpp index 59ca751c65..79ab5361be 100644 --- a/source/d3d9/d3d9_swapchain.cpp +++ b/source/d3d9/d3d9_swapchain.cpp @@ -116,6 +116,9 @@ HRESULT STDMETHODCALLTYPE Direct3DSwapChain9::Present(const RECT *pSourceRect, c reshade::invoke_addon_event(_device, this); #endif swapchain_impl::on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(_device, this); +#endif } return _orig->Present(pSourceRect, pDestRect, hDestWindowOverride, pDirtyRegion, dwFlags); diff --git a/source/dxgi/dxgi_swapchain.cpp b/source/dxgi/dxgi_swapchain.cpp index 06030c4475..3514c0c080 100644 --- a/source/dxgi/dxgi_swapchain.cpp +++ b/source/dxgi/dxgi_swapchain.cpp @@ -131,18 +131,27 @@ void DXGISwapChain::runtime_present(UINT flags) reshade::invoke_addon_event(static_cast(static_cast(_direct3d_device)), _impl); #endif static_cast(_impl)->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(static_cast(static_cast(_direct3d_device)), _impl); +#endif break; case 11: #if RESHADE_ADDON reshade::invoke_addon_event(static_cast(static_cast(_direct3d_device))->_immediate_context, _impl); #endif static_cast(_impl)->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(static_cast(static_cast(_direct3d_device))->_immediate_context, _impl); +#endif break; case 12: #if RESHADE_ADDON reshade::invoke_addon_event(static_cast(_direct3d_command_queue), _impl); #endif static_cast(_impl)->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(static_cast(_direct3d_command_queue), _impl); +#endif static_cast(_direct3d_command_queue)->flush_immediate_command_list(); break; } diff --git a/source/input.hpp b/source/input.hpp index 84ee713ce5..b04a04c811 100644 --- a/source/input.hpp +++ b/source/input.hpp @@ -35,6 +35,8 @@ namespace reshade /// A pointer to the input manager for the . static std::shared_ptr register_window(window_handle window); + window_handle get_window_handle() const { return _window; } + bool is_key_down(unsigned int keycode) const; bool is_key_pressed(unsigned int keycode) const; bool is_key_pressed(unsigned int keycode, bool ctrl, bool shift, bool alt, bool force_modifiers = false) const; diff --git a/source/opengl/opengl_hooks_wgl.cpp b/source/opengl/opengl_hooks_wgl.cpp index d3dba26bce..edbb6b14ea 100644 --- a/source/opengl/opengl_hooks_wgl.cpp +++ b/source/opengl/opengl_hooks_wgl.cpp @@ -885,6 +885,10 @@ HOOK_EXPORT BOOL WINAPI wglSwapBuffers(HDC hdc) // Assume that the correct OpenGL context is still current here runtime->on_present(); + +#if RESHADE_ADDON + reshade::invoke_addon_event(runtime, runtime); +#endif } return trampoline(hdc); diff --git a/source/opengl/opengl_impl_device.cpp b/source/opengl/opengl_impl_device.cpp index 5bff27daf6..990226a30d 100644 --- a/source/opengl/opengl_impl_device.cpp +++ b/source/opengl/opengl_impl_device.cpp @@ -1646,6 +1646,7 @@ static bool create_shader_module(GLenum type, const reshade::api::shader_desc &d else { assert(desc.code_size <= static_cast(std::numeric_limits::max())); + assert(desc.entry_point != nullptr); glShaderBinary(1, &shader_object, GL_SPIR_V_BINARY, desc.code, static_cast(desc.code_size)); glSpecializeShader(shader_object, desc.entry_point, desc.spec_constants, desc.spec_constant_ids, desc.spec_constant_values); diff --git a/source/openvr/openvr.cpp b/source/openvr/openvr.cpp index 64fb6f0391..ac3c10470e 100644 --- a/source/openvr/openvr.cpp +++ b/source/openvr/openvr.cpp @@ -74,6 +74,10 @@ static vr::EVRCompositorError on_vr_submit_d3d10(vr::IVRCompositor *compositor, s_vr_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(device_proxy, s_vr_swapchain); +#endif + const auto target_texture = reinterpret_cast(s_vr_swapchain->get_current_back_buffer().handle); // The left and right eye were copied side-by-side to a single texture in 'on_vr_submit', so set bounds accordingly @@ -130,6 +134,10 @@ static vr::EVRCompositorError on_vr_submit_d3d11(vr::IVRCompositor *compositor, s_vr_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(device_proxy->_immediate_context, s_vr_swapchain); +#endif + const auto target_texture = reinterpret_cast(s_vr_swapchain->get_current_back_buffer().handle); // The left and right eye were copied side-by-side to a single texture in 'on_vr_submit', so set bounds accordingly @@ -177,6 +185,10 @@ static vr::EVRCompositorError on_vr_submit_d3d12(vr::IVRCompositor *compositor, s_vr_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(command_queue_proxy.get(), s_vr_swapchain); +#endif + command_queue_proxy->flush_immediate_command_list(); lock.unlock(); @@ -228,6 +240,10 @@ static vr::EVRCompositorError on_vr_submit_opengl(vr::IVRCompositor *compositor, s_vr_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(g_current_context, s_vr_swapchain); +#endif + const GLuint target_rbo = s_vr_swapchain->get_current_back_buffer().handle & 0xFFFFFFFF; // Target object created in 'on_vr_submit' is a 2D texture @@ -286,6 +302,10 @@ static vr::EVRCompositorError on_vr_submit_vulkan(vr::IVRCompositor *compositor, s_vr_swapchain->on_present(); +#if RESHADE_ADDON + reshade::invoke_addon_event(queue, s_vr_swapchain); +#endif + queue->flush_immediate_command_list(); vr::VRVulkanTextureData_t target_texture = *texture; diff --git a/source/runtime.hpp b/source/runtime.hpp index 1e5dd1634e..a92b4b0788 100644 --- a/source/runtime.hpp +++ b/source/runtime.hpp @@ -44,6 +44,11 @@ namespace reshade /// api::command_queue *get_command_queue() final { return _graphics_queue; } + /// + /// Gets the handle of the window this swap chain was created with. + /// + virtual void *get_window_handle() const override; + /// /// Gets the path to the configuration file used by this effect runtime. /// diff --git a/source/runtime_api.cpp b/source/runtime_api.cpp index a36c9bf928..3223f197aa 100644 --- a/source/runtime_api.cpp +++ b/source/runtime_api.cpp @@ -8,6 +8,11 @@ #include "input.hpp" #include +reshade::input::window_handle reshade::runtime::get_window_handle() const +{ + return _input != nullptr ? _input->get_window_handle() : nullptr; +} + bool reshade::runtime::is_key_down(uint32_t keycode) const { return _input != nullptr && _input->is_key_down(keycode); diff --git a/source/vulkan/vulkan_hooks_device.cpp b/source/vulkan/vulkan_hooks_device.cpp index 74253049ac..2315981625 100644 --- a/source/vulkan/vulkan_hooks_device.cpp +++ b/source/vulkan/vulkan_hooks_device.cpp @@ -852,6 +852,9 @@ VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR *pPr reshade::invoke_addon_event(queue_impl, swapchain_impl); #endif swapchain_impl->on_present(queue, pPresentInfo->pImageIndices[i], wait_semaphores); +#if RESHADE_ADDON + reshade::invoke_addon_event(queue_impl, swapchain_impl); +#endif } } diff --git a/source/vulkan/vulkan_impl_device.cpp b/source/vulkan/vulkan_impl_device.cpp index 81bb232400..d64cb3a390 100644 --- a/source/vulkan/vulkan_impl_device.cpp +++ b/source/vulkan/vulkan_impl_device.cpp @@ -912,6 +912,8 @@ bool reshade::vulkan::device_impl::create_pipeline(const api::pipeline_desc &des } bool reshade::vulkan::device_impl::create_shader_module(VkShaderStageFlagBits stage, const api::shader_desc &desc, VkPipelineShaderStageCreateInfo &stage_info, VkSpecializationInfo &spec_info, std::vector &spec_map) { + assert(desc.entry_point != nullptr); + spec_map.reserve(desc.spec_constants); for (uint32_t i = 0; i < desc.spec_constants; ++i) spec_map.push_back(VkSpecializationMapEntry { desc.spec_constant_ids[i], i * 4, sizeof(uint32_t) });