├── .editorconfig
├── .github
└── workflows
│ └── build.yml
├── .gitignore
├── .gitmodules
├── Common.props
├── Doxyfile
├── FUNDING.yml
├── LICENSE.md
├── README.md
├── REFERENCE.md
├── ReShade.sln
├── ReShade.vcxproj
├── ReShade.vcxproj.filters
├── ReShadeFX.vcxproj
├── ReShadeFX.vcxproj.filters
├── ReShadeFXC.vcxproj
├── ReShadeFXC.vcxproj.filters
├── ReShadeInject.vcxproj
├── cpp.hint
├── deps
├── D3D12On7.props
├── ImGui.patch
├── ImGui.props
├── ImGui.vcxproj
├── MinHook.props
├── MinHook.vcxproj
├── MinHook.vcxproj.filters
├── OpenVR.props
├── OpenXR.props
├── SPIRV.props
├── Vulkan.props
├── Windows.props
├── d3d12on7
│ ├── LICENSE.txt
│ └── include
│ │ └── D3D12Downlevel.h
├── d3d911on12
│ ├── LICENSE.txt
│ └── include
│ │ ├── d3d11on12.h
│ │ └── d3d9on12.h
├── fpng.props
├── fpng.vcxproj
├── gl3w.props
├── gl3w.vcxproj
├── imgui_config.cpp
├── imgui_config.hpp
├── openvr
│ ├── LICENSE
│ ├── headers
│ │ └── openvr.h
│ └── src
│ │ └── ivrclientcore.h
├── sk_hdr_png.props
├── sk_hdr_png
│ └── include
│ │ └── sk_hdr_png.hpp
├── stb.props
├── stb.vcxproj
├── stb_image_dds
│ └── stb_image_dds.h
├── stb_impl.c
├── utfcpp.props
└── vulkan_layer
│ └── vk_layer_dispatch_table.h
├── examples
├── 01-fps_limit
│ ├── fps_limit.vcxproj
│ └── fps_limit_addon.cpp
├── 02-freepie
│ ├── freepie.vcxproj
│ └── freepie_addon.cpp
├── 03-history_window
│ ├── history_window.vcxproj
│ └── history_window_addon.cpp
├── 04-api_trace
│ ├── api_trace.vcxproj
│ └── api_trace_addon.cpp
├── 05-shader_dump
│ ├── shader_dump_addon.cpp
│ └── shader_dump_addon.vcxproj
├── 06-shader_replace
│ ├── shader_replace_addon.cpp
│ └── shader_replace_addon.vcxproj
├── 07-texture_dump
│ ├── texture_dump_addon.cpp
│ └── texture_dump_addon.vcxproj
├── 08-texture_replace
│ ├── texture_replace_addon.cpp
│ └── texture_replace_addon.vcxproj
├── 09-depth
│ ├── generic_depth.vcxproj
│ └── generic_depth_addon.cpp
├── 10-texture_overlay
│ ├── texture_overlay_addon.cpp
│ └── texture_overlay_addon.vcxproj
├── 11-obs_capture
│ ├── LICENSE.txt
│ ├── obs_capture.cpp
│ ├── obs_capture.vcxproj
│ ├── obs_hook_info.cpp
│ └── obs_hook_info.hpp
├── 12-video_capture
│ ├── video_capture.cpp
│ └── video_capture.vcxproj
├── 13-effects_during_frame
│ ├── effects_during_frame.vcxproj
│ └── effects_during_frame_addon.cpp
├── 14-ray_tracing
│ ├── ray_tracing.vcxproj
│ ├── ray_tracing.vcxproj.filters
│ ├── ray_tracing_addon.cpp
│ └── ray_tracing_shaders.hlsl
├── 15-effect_runtime_sync
│ ├── runtime_sync.vcxproj
│ └── runtime_sync_addon.cpp
├── 16-swapchain_override
│ ├── swapchain_override.vcxproj
│ └── swapchain_override_addon.cpp
├── 17-screenshot_to_clipboard
│ ├── screenshot_to_clipboard.vcxproj
│ └── screenshot_to_clipboard_addon.cpp
├── Examples.sln
├── README.md
└── utils
│ ├── config.hpp
│ ├── crc32_hash.hpp
│ ├── descriptor_tracking.cpp
│ ├── descriptor_tracking.hpp
│ ├── load_texture_image.cpp
│ ├── save_texture_image.cpp
│ ├── state_tracking.cpp
│ └── state_tracking.hpp
├── include
├── reshade.hpp
├── reshade_api.hpp
├── reshade_api_device.hpp
├── reshade_api_format.hpp
├── reshade_api_pipeline.hpp
├── reshade_api_resource.hpp
├── reshade_events.hpp
└── reshade_overlay.hpp
├── res
├── exports.def
├── fonts
│ ├── forkawesome.h
│ ├── forkawesome.ifs
│ ├── forkawesome.inl
│ └── glyph_ranges.hpp
├── lang_bg-BG.rc2
├── lang_de-DE.rc2
├── lang_en-US.rc2
├── lang_es-ES.rc2
├── lang_fr-FR.rc2
├── lang_ja-JP.rc2
├── lang_ko-KR.rc2
├── lang_ru-RU.rc2
├── lang_zh-CN.rc2
├── main_icon.ico
├── main_icon.svg
├── main_icon_small.png
├── main_icon_small.svg
├── resource.h
├── resource.rc
├── shaders
│ ├── copy_ps.hlsl
│ ├── fullscreen_vs.hlsl
│ ├── imgui_hdr.hlsl
│ ├── imgui_ps_3_0.hlsl
│ ├── imgui_ps_430.glsl
│ ├── imgui_ps_450.glsl
│ ├── imgui_ps_450.spv
│ ├── imgui_ps_450_hdr.spv
│ ├── imgui_ps_4_0.hlsl
│ ├── imgui_vs_3_0.hlsl
│ ├── imgui_vs_430.glsl
│ ├── imgui_vs_450.glsl
│ ├── imgui_vs_450.spv
│ ├── imgui_vs_4_0.hlsl
│ ├── mipmap_cs_430.glsl
│ └── mipmap_cs_5_0.hlsl
└── version.rc2
├── setup
├── MainWindow.xaml
├── MainWindow.xaml.cs
├── Pages
│ ├── Resources
│ │ ├── DirectX.png
│ │ ├── OpenGL.png
│ │ ├── OpenXR.png
│ │ └── Vulkan.png
│ ├── SelectAddonsPage.xaml
│ ├── SelectAddonsPage.xaml.cs
│ ├── SelectApiPage.xaml
│ ├── SelectApiPage.xaml.cs
│ ├── SelectAppPage.xaml
│ ├── SelectAppPage.xaml.cs
│ ├── SelectEffectsPage.xaml
│ ├── SelectEffectsPage.xaml.cs
│ ├── SelectOperationPage.xaml
│ ├── SelectOperationPage.xaml.cs
│ ├── StatusPage.xaml
│ └── StatusPage.xaml.cs
├── Properties
│ ├── App.config
│ ├── App.xaml
│ ├── App.xaml.cs
│ ├── Assembly.manifest
│ └── AssemblyInfo.cs.in
├── ReShade Setup.csproj
├── ReShade32.json
├── ReShade32_XR.json
├── ReShade64.json
├── ReShade64_XR.json
└── Utilities
│ ├── AeroGlass.cs
│ ├── FileOpenDialog.cs
│ ├── IniFile.cs
│ └── PEInfo.cs
├── source
├── addon.cpp
├── addon.hpp
├── addon_manager.cpp
├── addon_manager.hpp
├── com_ptr.hpp
├── com_utils.hpp
├── d2d1
│ └── d2d1.cpp
├── d3d10
│ ├── d3d10.cpp
│ ├── d3d10_device.cpp
│ ├── d3d10_device.hpp
│ ├── d3d10_impl_command_list.cpp
│ ├── d3d10_impl_command_queue.cpp
│ ├── d3d10_impl_device.cpp
│ ├── d3d10_impl_device.hpp
│ ├── d3d10_impl_state_block.cpp
│ ├── d3d10_impl_state_block.hpp
│ ├── d3d10_impl_swapchain.cpp
│ ├── d3d10_impl_swapchain.hpp
│ ├── d3d10_impl_type_convert.cpp
│ ├── d3d10_impl_type_convert.hpp
│ ├── d3d10_resource.cpp
│ ├── d3d10_resource.hpp
│ └── d3d10_resource_call_vtable.inl
├── d3d11
│ ├── d3d11.cpp
│ ├── d3d11_command_list.cpp
│ ├── d3d11_command_list.hpp
│ ├── d3d11_device.cpp
│ ├── d3d11_device.hpp
│ ├── d3d11_device_context.cpp
│ ├── d3d11_device_context.hpp
│ ├── d3d11_impl_command_list.cpp
│ ├── d3d11_impl_command_queue.cpp
│ ├── d3d11_impl_device.cpp
│ ├── d3d11_impl_device.hpp
│ ├── d3d11_impl_device_context.hpp
│ ├── d3d11_impl_state_block.cpp
│ ├── d3d11_impl_state_block.hpp
│ ├── d3d11_impl_swapchain.cpp
│ ├── d3d11_impl_swapchain.hpp
│ ├── d3d11_impl_type_convert.cpp
│ ├── d3d11_impl_type_convert.hpp
│ ├── d3d11_resource.cpp
│ ├── d3d11_resource.hpp
│ ├── d3d11_resource_call_vtable.inl
│ ├── d3d11on12.cpp
│ ├── d3d11on12_device.cpp
│ └── d3d11on12_device.hpp
├── d3d12
│ ├── d3d12.cpp
│ ├── d3d12_command_list.cpp
│ ├── d3d12_command_list.hpp
│ ├── d3d12_command_queue.cpp
│ ├── d3d12_command_queue.hpp
│ ├── d3d12_command_queue_downlevel.cpp
│ ├── d3d12_command_queue_downlevel.hpp
│ ├── d3d12_descriptor_heap.cpp
│ ├── d3d12_descriptor_heap.hpp
│ ├── d3d12_device.cpp
│ ├── d3d12_device.hpp
│ ├── d3d12_device_downlevel.cpp
│ ├── d3d12_device_downlevel.hpp
│ ├── d3d12_impl_command_list.cpp
│ ├── d3d12_impl_command_list.hpp
│ ├── d3d12_impl_command_list_immediate.cpp
│ ├── d3d12_impl_command_list_immediate.hpp
│ ├── d3d12_impl_command_queue.cpp
│ ├── d3d12_impl_command_queue.hpp
│ ├── d3d12_impl_device.cpp
│ ├── d3d12_impl_device.hpp
│ ├── d3d12_impl_swapchain.cpp
│ ├── d3d12_impl_swapchain.hpp
│ ├── d3d12_impl_type_convert.cpp
│ ├── d3d12_impl_type_convert.hpp
│ ├── d3d12_pipeline_library.cpp
│ ├── d3d12_pipeline_library.hpp
│ ├── d3d12_pix.cpp
│ ├── d3d12_resource.cpp
│ ├── d3d12_resource.hpp
│ ├── d3d12_resource_call_vtable.inl
│ └── descriptor_heap.hpp
├── d3d9
│ ├── d3d9.cpp
│ ├── d3d9_device.cpp
│ ├── d3d9_device.hpp
│ ├── d3d9_impl_command_list.cpp
│ ├── d3d9_impl_command_queue.cpp
│ ├── d3d9_impl_device.cpp
│ ├── d3d9_impl_device.hpp
│ ├── d3d9_impl_state_block.cpp
│ ├── d3d9_impl_state_block.hpp
│ ├── d3d9_impl_swapchain.cpp
│ ├── d3d9_impl_swapchain.hpp
│ ├── d3d9_impl_type_convert.cpp
│ ├── d3d9_impl_type_convert.hpp
│ ├── d3d9_internal.cpp
│ ├── d3d9_pix.cpp
│ ├── d3d9_resource.cpp
│ ├── d3d9_resource.hpp
│ ├── d3d9_resource_call_vtable.inl
│ ├── d3d9_swapchain.cpp
│ ├── d3d9_swapchain.hpp
│ ├── d3d9on12.cpp
│ ├── d3d9on12_device.cpp
│ └── d3d9on12_device.hpp
├── ddraw
│ └── ddraw.cpp
├── dll_log.cpp
├── dll_log.hpp
├── dll_main.cpp
├── dll_main_test_app.cpp
├── dll_resources.cpp
├── dll_resources.hpp
├── dxgi
│ ├── dxgi.cpp
│ ├── dxgi_d3d10.cpp
│ ├── dxgi_device.cpp
│ ├── dxgi_device.hpp
│ ├── dxgi_swapchain.cpp
│ └── dxgi_swapchain.hpp
├── effect_codegen.hpp
├── effect_codegen_glsl.cpp
├── effect_codegen_hlsl.cpp
├── effect_codegen_spirv.cpp
├── effect_expression.cpp
├── effect_expression.hpp
├── effect_lexer.cpp
├── effect_lexer.hpp
├── effect_module.hpp
├── effect_parser.hpp
├── effect_parser_exp.cpp
├── effect_parser_stmt.cpp
├── effect_preprocessor.cpp
├── effect_preprocessor.hpp
├── effect_symbol_table.cpp
├── effect_symbol_table.hpp
├── effect_symbol_table_intrinsics.inl
├── effect_token.hpp
├── hook.cpp
├── hook.hpp
├── hook_manager.cpp
├── hook_manager.hpp
├── imgui_code_editor.cpp
├── imgui_code_editor.hpp
├── imgui_function_table.cpp
├── imgui_function_table_18600.cpp
├── imgui_function_table_18600.hpp
├── imgui_function_table_18971.cpp
├── imgui_function_table_18971.hpp
├── imgui_function_table_19000.cpp
├── imgui_function_table_19000.hpp
├── imgui_function_table_19040.cpp
├── imgui_function_table_19040.hpp
├── imgui_function_table_19180.cpp
├── imgui_function_table_19180.hpp
├── imgui_function_table_19191.cpp
├── imgui_function_table_19191.hpp
├── imgui_widgets.cpp
├── imgui_widgets.hpp
├── ini_file.cpp
├── ini_file.hpp
├── input.cpp
├── input.hpp
├── input_gamepad.cpp
├── input_gamepad.hpp
├── localization.hpp
├── lockfree_linear_map.hpp
├── moving_average.hpp
├── opengl
│ ├── opengl_hooks.cpp
│ ├── opengl_hooks.hpp
│ ├── opengl_hooks_ffp.cpp
│ ├── opengl_hooks_wgl.cpp
│ ├── opengl_impl_command_list.cpp
│ ├── opengl_impl_command_queue.cpp
│ ├── opengl_impl_device.cpp
│ ├── opengl_impl_device.hpp
│ ├── opengl_impl_device_context.hpp
│ ├── opengl_impl_state_block.cpp
│ ├── opengl_impl_state_block.hpp
│ ├── opengl_impl_swapchain.cpp
│ ├── opengl_impl_swapchain.hpp
│ ├── opengl_impl_type_convert.cpp
│ └── opengl_impl_type_convert.hpp
├── openvr
│ ├── openvr_hooks.cpp
│ ├── openvr_impl_swapchain.cpp
│ └── openvr_impl_swapchain.hpp
├── openxr
│ ├── openxr_hooks.cpp
│ ├── openxr_hooks.hpp
│ ├── openxr_hooks_instance.cpp
│ ├── openxr_hooks_session.cpp
│ ├── openxr_impl_swapchain.cpp
│ └── openxr_impl_swapchain.hpp
├── platform_utils.cpp
├── platform_utils.hpp
├── reshade_api_object_impl.hpp
├── runtime.cpp
├── runtime.hpp
├── runtime_api.cpp
├── runtime_gui.cpp
├── runtime_gui_vr.cpp
├── runtime_internal.hpp
├── runtime_manager.cpp
├── runtime_manager.hpp
├── runtime_update_check.cpp
├── state_block.cpp
├── state_block.hpp
├── vulkan
│ ├── vulkan_hooks.cpp
│ ├── vulkan_hooks.hpp
│ ├── vulkan_hooks_cmd.cpp
│ ├── vulkan_hooks_device.cpp
│ ├── vulkan_hooks_instance.cpp
│ ├── vulkan_impl_command_list.cpp
│ ├── vulkan_impl_command_list.hpp
│ ├── vulkan_impl_command_list_immediate.cpp
│ ├── vulkan_impl_command_list_immediate.hpp
│ ├── vulkan_impl_command_queue.cpp
│ ├── vulkan_impl_command_queue.hpp
│ ├── vulkan_impl_device.cpp
│ ├── vulkan_impl_device.hpp
│ ├── vulkan_impl_swapchain.cpp
│ ├── vulkan_impl_swapchain.hpp
│ ├── vulkan_impl_type_convert.cpp
│ └── vulkan_impl_type_convert.hpp
└── windows
│ ├── dinput.cpp
│ ├── dinput8.cpp
│ ├── user32.cpp
│ └── ws2_32.cpp
└── tools
├── 7za.exe
├── create_language_template.ps1
├── fxc.cpp
├── injector.cpp
├── update_all_languages.ps1
├── update_imgui_function_table.ps1
└── update_version.ps1
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | spelling_languages = en-us
5 |
6 | [*.{c,cpp,h,hpp,inl,cs,glsl,hlsl}]
7 | indent_size = 4
8 | indent_style = tab
9 | insert_final_newline = true
10 | trim_trailing_whitespace = true
11 |
12 | [*.{xml,xaml,manifest}]
13 | indent_size = 2
14 | indent_style = space
15 | insert_final_newline = false
16 | trim_trailing_whitespace = true
17 |
18 | [*.{c,cpp,h,hpp,inl}]
19 | cpp_generate_documentation_comments = xml
20 | cpp_indent_braces = false
21 | cpp_indent_multi_line_relative_to = statement_begin
22 | cpp_indent_within_parentheses = indent
23 | cpp_indent_preserve_within_parentheses = true
24 | cpp_indent_case_contents = true
25 | cpp_indent_case_labels = false
26 | cpp_indent_case_contents_when_block = false
27 | cpp_indent_lambda_braces_when_parameter = true
28 | cpp_indent_goto_labels = one_left
29 | cpp_indent_preprocessor = leftmost_column
30 | cpp_indent_access_specifiers = false
31 | cpp_indent_namespace_contents = true
32 | cpp_indent_preserve_comments = false
33 | cpp_new_line_before_open_brace_namespace = ignore
34 | cpp_new_line_before_open_brace_type = ignore
35 | cpp_new_line_before_open_brace_function = ignore
36 | cpp_new_line_before_open_brace_block = ignore
37 | cpp_new_line_before_open_brace_lambda = ignore
38 | cpp_new_line_scope_braces_on_separate_lines = false
39 | cpp_new_line_close_brace_same_line_empty_type = false
40 | cpp_new_line_close_brace_same_line_empty_function = false
41 | cpp_new_line_before_catch = true
42 | cpp_new_line_before_else = true
43 | cpp_new_line_before_while_in_do_while = false
44 | cpp_space_before_function_open_parenthesis = remove
45 | cpp_space_within_parameter_list_parentheses = false
46 | cpp_space_between_empty_parameter_list_parentheses = false
47 | cpp_space_after_keywords_in_control_flow_statements = true
48 | cpp_space_within_control_flow_statement_parentheses = false
49 | cpp_space_before_lambda_open_parenthesis = false
50 | cpp_space_within_cast_parentheses = false
51 | cpp_space_after_cast_close_parenthesis = false
52 | cpp_space_within_expression_parentheses = false
53 | cpp_space_before_block_open_brace = true
54 | cpp_space_between_empty_braces = false
55 | cpp_space_before_initializer_list_open_brace = true
56 | cpp_space_within_initializer_list_braces = true
57 | cpp_space_preserve_in_initializer_list = true
58 | cpp_space_before_open_square_bracket = false
59 | cpp_space_within_square_brackets = false
60 | cpp_space_before_empty_square_brackets = false
61 | cpp_space_between_empty_square_brackets = false
62 | cpp_space_group_square_brackets = true
63 | cpp_space_within_lambda_brackets = false
64 | cpp_space_between_empty_lambda_brackets = false
65 | cpp_space_before_comma = false
66 | cpp_space_after_comma = true
67 | cpp_space_remove_around_member_operators = true
68 | cpp_space_before_inheritance_colon = true
69 | cpp_space_before_constructor_colon = true
70 | cpp_space_remove_before_semicolon = true
71 | cpp_space_after_semicolon = true
72 | cpp_space_remove_around_unary_operator = true
73 | cpp_space_around_binary_operator = insert
74 | cpp_space_around_assignment_operator = insert
75 | cpp_space_pointer_reference_alignment = right
76 | cpp_space_around_ternary_operator = insert
77 | cpp_wrap_preserve_blocks = one_liners
78 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: build
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 | branches:
9 | - main
10 |
11 | jobs:
12 | build:
13 | runs-on: windows-latest
14 |
15 | steps:
16 | - name: Checkout
17 | uses: actions/checkout@v4
18 | with:
19 | fetch-depth: 0
20 | submodules: true
21 |
22 | - name: Set up Python
23 | uses: actions/setup-python@v5
24 | with:
25 | python-version: '3.x'
26 |
27 | - name: Set up MSBuild
28 | uses: microsoft/setup-msbuild@v2
29 |
30 | - name: Build ReShade (32-bit)
31 | run: |
32 | msbuild ReShade.sln /p:Configuration=Release /p:Platform=32-bit
33 |
34 | - name: Build ReShade (64-bit)
35 | run: |
36 | msbuild ReShade.sln /p:Configuration=Release /p:Platform=64-bit
37 |
38 | - name: Build ReShade Setup
39 | run: |
40 | msbuild ReShade.sln /p:Configuration="Release Setup"
41 |
42 | - name: Upload ReShade (32-bit)
43 | uses: actions/upload-artifact@v4
44 | with:
45 | name: ReShade (32-bit)
46 | path: './bin/Win32/Release/ReShade32.dll'
47 |
48 | - name: Upload ReShade (64-bit)
49 | uses: actions/upload-artifact@v4
50 | with:
51 | name: ReShade (64-bit)
52 | path: './bin/x64/Release/ReShade64.dll'
53 |
54 | - name: Upload ReShade Setup
55 | uses: actions/upload-artifact@v4
56 | with:
57 | name: ReShade Setup
58 | path: './bin/AnyCPU/Release/ReShade Setup.exe'
59 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Build results
2 | [Bb]in/
3 | [Oo]bj/
4 | [Ii]ntermediate/
5 | [Bb]uild/
6 | [Dd]ebug/
7 | [Rr]elease/
8 | *.obj
9 | *.cso
10 |
11 | # Visual Studio cache files
12 | .vs/
13 | ipch/
14 | packages/
15 | *.aps
16 | *.VC.db
17 | *.VC.opendb
18 |
19 | # Visual Studio user config files
20 | *.sdf
21 | *.opensdf
22 | *.suo
23 | *.vcxproj.user
24 | *.Args.json
25 | *.ArgsCfg.json
26 |
27 | # Visual Studio performance profiling
28 | *.vsp
29 | *.psess
30 |
31 | # Visual Studio Code
32 | .vscode/
33 |
34 | # Code signing
35 | *.pfx
36 | *.pvk
37 |
38 | # Temporary OS files
39 | .DS_Store
40 | Thumbs.db
41 |
42 | # Versioning and setup files
43 | /res/[Vv]ersion.h
44 | /setup/*.ini
45 | /setup/Properties/AssemblyInfo.cs
46 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "imgui"]
2 | path = deps/imgui
3 | url = https://github.com/ocornut/imgui.git
4 | [submodule "minhook"]
5 | path = deps/minhook
6 | url = https://github.com/TsudaKageyu/minhook.git
7 | [submodule "stb"]
8 | path = deps/stb
9 | url = https://github.com/nothings/stb.git
10 | [submodule "gl3w"]
11 | path = deps/gl3w
12 | url = https://github.com/skaslev/gl3w.git
13 | [submodule "utfcpp"]
14 | path = deps/utfcpp
15 | url = https://github.com/nemtrif/utfcpp.git
16 | fetchRecurseSubmodules = false
17 | [submodule "spirv"]
18 | path = deps/spirv
19 | url = https://github.com/KhronosGroup/SPIRV-Headers.git
20 | [submodule "vma"]
21 | path = deps/vma
22 | url = https://github.com/GPUOpen-LibrariesAndSDKs/VulkanMemoryAllocator
23 | [submodule "vulkan"]
24 | path = deps/vulkan
25 | url = https://github.com/KhronosGroup/Vulkan-Headers.git
26 | [submodule "fpng"]
27 | path = deps/fpng
28 | url = https://github.com/richgel999/fpng
29 | [submodule "d3d12"]
30 | path = deps/d3d12
31 | url = https://github.com/microsoft/DirectX-Headers.git
32 | [submodule "openxr"]
33 | path = deps/openxr
34 | url = https://github.com/KhronosGroup/OpenXR-SDK.git
35 |
--------------------------------------------------------------------------------
/Common.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(SolutionDir)bin\$(Platform)\$(Configuration)\
6 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Doxyfile:
--------------------------------------------------------------------------------
1 | PROJECT_NAME = "ReShade"
2 | PROJECT_BRIEF = "A generic post-processing injector for games and video software."
3 | PROJECT_LOGO = ./res/main_icon_small.png
4 |
5 | INPUT = ./include ./REFERENCE.md
6 | EXCLUDE = ./include/imgui.h ./include/reshade_overlay.hpp
7 | FILE_PATTERNS = *.c *.cpp *.h *.hpp *.inl
8 | EXCLUDE_SYMBOLS = addon_event_traits
9 | USE_MDFILE_AS_MAINPAGE = ./REFERENCE.md
10 |
11 | OUTPUT_DIRECTORY = ./build
12 |
13 | GENERATE_XML = YES
14 | GENERATE_HTML = YES
15 | GENERATE_LATEX = NO
16 |
17 | SHOW_USED_FILES = YES
18 | SHOW_FILES = YES
19 | SHOW_NAMESPACES = YES
20 | MAX_INITIALIZER_LINES = 0
21 |
22 | # Parser configuration
23 |
24 | EXTRACT_ALL = YES
25 | EXTRACT_STATIC = YES
26 |
27 | # Preprocessor configuration
28 |
29 | ENABLE_PREPROCESSING = YES
30 | MACRO_EXPANSION = YES
31 | PREDEFINED = __declspec(x)=
32 | SKIP_FUNCTION_MACROS = YES
33 |
--------------------------------------------------------------------------------
/FUNDING.yml:
--------------------------------------------------------------------------------
1 | patreon: crosire
2 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2014 Patrick Mours. All rights reserved.
2 |
3 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4 |
5 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
7 | * Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
8 |
9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
10 |
--------------------------------------------------------------------------------
/ReShadeFX.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/ReShadeFXC.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/cpp.hint:
--------------------------------------------------------------------------------
1 | // ReShade.vcxproj
2 |
3 | #define VR_Interface_Impl(type, method_name, vtable_index, interface_version, impl, return_type, ...) static return_type type##_##method_name##_##interface_version(vr::type *pThis, ##__VA_ARGS__) {}
4 |
5 | // ReShadeFX.vcxproj
6 |
7 | #define DEFINE_INTRINSIC(name, i, ret_type, ...)
8 | #define IMPLEMENT_INTRINSIC_GLSL(name, i, code)
9 | #define IMPLEMENT_INTRINSIC_HLSL(name, i, code)
10 | #define IMPLEMENT_INTRINSIC_SPIRV(name, i, code)
11 |
--------------------------------------------------------------------------------
/deps/D3D12On7.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(SolutionDir)deps\bin\$(Configuration);$(ExecutablePath)
6 |
7 |
8 |
9 | $(SolutionDir)deps\d3d12on7\include;%(AdditionalIncludeDirectories)
10 |
11 |
12 |
--------------------------------------------------------------------------------
/deps/ImGui.patch:
--------------------------------------------------------------------------------
1 | diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp
2 | --- a/imgui_widgets.cpp
3 | +++ b/imgui_widgets.cpp
4 | @@ -7110,8 +7110,6 @@ int ImGui::PlotEx(ImGuiPlotType plot_type, const char* label, float (*values_get
5 | }
6 | else if (plot_type == ImGuiPlotType_Histogram)
7 | {
8 | - if (pos1.x >= pos0.x + 2.0f)
9 | - pos1.x -= 1.0f;
10 | window->DrawList->AddRectFilled(pos0, pos1, idx_hovered == v1_idx ? col_hovered : col_base);
11 | }
12 |
13 | diff --git a/imgui.cpp b/imgui.cpp
14 | --- a/imgui.cpp
15 | +++ b/imgui.cpp
16 | @@ -4490,14 +4490,15 @@ void ImGui::StartMouseMovingWindowOrNode(ImGuiWindow* window, ImGuiDockNode* nod
17 | {
18 | ImGuiContext& g = *GImGui;
19 | bool can_undock_node = false;
20 | - if (undock && node != NULL && node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove) == 0 && (node->MergedFlags & ImGuiDockNodeFlags_NoUndocking) == 0)
21 | + if (node != NULL && node->VisibleWindow && (node->VisibleWindow->Flags & ImGuiWindowFlags_NoMove) == 0 && (node->MergedFlags & ImGuiDockNodeFlags_NoUndocking) == 0)
22 | {
23 | // Can undock if:
24 | // - part of a hierarchy with more than one visible node (if only one is visible, we'll just move the root window)
25 | // - part of a dockspace node hierarchy: so we can undock the last single visible node too (trivia: undocking from a fixed/central node will create a new node and copy windows)
26 | ImGuiDockNode* root_node = DockNodeGetRootNode(node);
27 | if (root_node->OnlyNodeWithWindows != node || root_node->CentralNode != NULL) // -V1051 PVS-Studio thinks node should be root_node and is wrong about that.
28 | - can_undock_node = true;
29 | + if (undock || root_node->IsDockSpace())
30 | + can_undock_node = true;
31 | }
32 |
33 | const bool clicked = IsMouseClicked(0);
34 | @@ -13233,6 +13234,8 @@ static ImGuiWindow* FindWindowNavFocusable(int i_start, int i_stop, int dir) //
35 |
36 | static void NavUpdateWindowingHighlightWindow(int focus_change_dir)
37 | {
38 | + focus_change_dir *= -1;
39 | +
40 | ImGuiContext& g = *GImGui;
41 | IM_ASSERT(g.NavWindowingTarget);
42 | if (g.NavWindowingTarget->Flags & ImGuiWindowFlags_Modal)
43 | @@ -13484,7 +13487,7 @@ void ImGui::NavUpdateWindowingOverlay()
44 | SetNextWindowPos(viewport->GetCenter(), ImGuiCond_Always, ImVec2(0.5f, 0.5f));
45 | PushStyleVar(ImGuiStyleVar_WindowPadding, g.Style.WindowPadding * 2.0f);
46 | Begin("###NavWindowingList", NULL, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoMove | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings);
47 | - for (int n = g.WindowsFocusOrder.Size - 1; n >= 0; n--)
48 | + for (int n = 0; n < g.WindowsFocusOrder.Size; n++)
49 | {
50 | ImGuiWindow* window = g.WindowsFocusOrder[n];
51 | IM_ASSERT(window != NULL); // Fix static analyzers
52 |
--------------------------------------------------------------------------------
/deps/ImGui.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\imgui;%(AdditionalIncludeDirectories)
7 | ImTextureID=ImU64;IMGUI_USER_CONFIG="..\imgui_config.hpp";IMGUI_DEFINE_MATH_OPERATORS;IMGUI_DISABLE_OBSOLETE_FUNCTIONS;IMGUI_DISABLE_FILE_FUNCTIONS;IMGUI_DISABLE_WIN32_DEFAULT_IME_FUNCTIONS;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/MinHook.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\minhook\include;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/MinHook.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {4f094667-e67f-4105-b94d-5ffd7bc80831}
6 |
7 |
8 | {6d8d397a-3296-469c-bfc1-0138956f951d}
9 |
10 |
11 |
12 |
13 | HDE
14 |
15 |
16 | HDE
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | HDE
25 |
26 |
27 | HDE
28 |
29 |
30 | HDE
31 |
32 |
33 | HDE
34 |
35 |
36 | HDE
37 |
38 |
39 | API
40 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/deps/OpenVR.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\openvr\headers;$(SolutionDir)deps\openvr\src;%(AdditionalIncludeDirectories)
7 | OPENVR_BUILD_STATIC;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/OpenXR.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\openxr\include;$(SolutionDir)deps\openxr\src;%(AdditionalIncludeDirectories)
7 | XR_USE_PLATFORM_WIN32;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/SPIRV.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\spirv\include\spirv\unified1;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/Vulkan.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(VK_SDK_PATH)\Bin;$(ExecutablePath)
6 |
7 |
8 |
9 | $(SolutionDir)deps\vulkan\include;$(SolutionDir)deps\vulkan_layer;$(SolutionDir)deps\vma\include;%(AdditionalIncludeDirectories)
10 | VK_USE_PLATFORM_WIN32_KHR;VMA_STATIC_VULKAN_FUNCTIONS=0;VMA_DYNAMIC_VULKAN_FUNCTIONS=0;VMA_STATS_STRING_ENABLED=0;%(PreprocessorDefinitions)
11 |
12 |
13 |
--------------------------------------------------------------------------------
/deps/Windows.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\d3d12\include\directx;$(SolutionDir)deps\d3d911on12\include;%(AdditionalIncludeDirectories)
7 | WIN32_LEAN_AND_MEAN;NOGDICAPMASKS;NOMENUS;NOICONS;NOKEYSTATES;NOSYSCOMMANDS;NORASTEROPS;NOATOM;NOCOLOR;NODRAWTEXT;NOMEMMGR;NOMETAFILE;NOMINMAX;NOOPENFILE;NOSCROLL;NOSERVICE;NOSOUND;NOTEXTMETRIC;NOCOMM;NOKANJI;NOHELP;NOPROFILER;NODEFERWINDOWPOS;NOMCX;%(PreprocessorDefinitions)
8 |
9 |
10 | Dwmapi.lib;dxguid.lib;ShLwApi.lib;WinInet.lib;WS2_32.lib;Version.lib;winmm.lib;%(AdditionalDependencies)
11 |
12 |
13 |
--------------------------------------------------------------------------------
/deps/d3d12on7/LICENSE.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/deps/d3d12on7/LICENSE.txt
--------------------------------------------------------------------------------
/deps/d3d911on12/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) Microsoft Corporation.
2 |
3 | MIT License
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/deps/fpng.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\fpng\src;%(AdditionalIncludeDirectories)
7 | FPNG_NO_STDIO;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/gl3w.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\gl3w\include;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/imgui_config.cpp:
--------------------------------------------------------------------------------
1 | #include "imgui_config.hpp"
2 |
3 | thread_local ImGuiContext *GImGuiThreadLocal = nullptr;
4 |
--------------------------------------------------------------------------------
/deps/imgui_config.hpp:
--------------------------------------------------------------------------------
1 | struct ImGuiContext;
2 | extern thread_local ImGuiContext *GImGuiThreadLocal;
3 |
4 | #define GImGui GImGuiThreadLocal
5 |
--------------------------------------------------------------------------------
/deps/openvr/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015, Valve Corporation
2 | All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation and/or
12 | other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder nor the names of its contributors
15 | may be used to endorse or promote products derived from this software without
16 | specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
22 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
25 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
27 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/deps/openvr/src/ivrclientcore.h:
--------------------------------------------------------------------------------
1 | //========= Copyright Valve Corporation ============//
2 | #pragma once
3 |
4 | namespace vr
5 | {
6 |
7 | class IVRClientCore
8 | {
9 | public:
10 | /** Initializes the system */
11 | virtual EVRInitError Init( vr::EVRApplicationType eApplicationType, const char *pStartupInfo ) = 0;
12 |
13 | /** cleans up everything in vrclient.dll and prepares the DLL to be unloaded */
14 | virtual void Cleanup() = 0;
15 |
16 | /** checks to see if the specified interface/version is supported in this vrclient.dll */
17 | virtual EVRInitError IsInterfaceVersionValid( const char *pchInterfaceVersion ) = 0;
18 |
19 | /** Retrieves any interface from vrclient.dll */
20 | virtual void *GetGenericInterface( const char *pchNameAndVersion, EVRInitError *peError ) = 0;
21 |
22 | /** Returns true if any driver has an HMD attached. Can be called outside of Init/Cleanup */
23 | virtual bool BIsHmdPresent() = 0;
24 |
25 | /** Returns an English error string from inside vrclient.dll which might be newer than the API DLL */
26 | virtual const char *GetEnglishStringForHmdError( vr::EVRInitError eError ) = 0;
27 |
28 | /** Returns an error symbol from inside vrclient.dll which might be newer than the API DLL */
29 | virtual const char *GetIDForVRInitError( vr::EVRInitError eError ) = 0;
30 | };
31 |
32 | static const char * const IVRClientCore_Version = "IVRClientCore_003";
33 |
34 |
35 | }
36 |
--------------------------------------------------------------------------------
/deps/sk_hdr_png.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\sk_hdr_png\include;%(AdditionalIncludeDirectories)
7 | SK_HDR_PNG_RESHADE;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/stb.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\stb;$(SolutionDir)deps\stb_image_dds;%(AdditionalIncludeDirectories)
7 | STBI_NO_STDIO;STBI_WRITE_NO_STDIO;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/stb_impl.c:
--------------------------------------------------------------------------------
1 | #define STB_IMAGE_IMPLEMENTATION
2 | #define STB_IMAGE_DDS_IMPLEMENTATION
3 | #define STB_IMAGE_WRITE_IMPLEMENTATION
4 | #define STB_IMAGE_RESIZE_IMPLEMENTATION
5 |
6 | #include "stb_image.h"
7 | #include "stb_image_dds.h"
8 | #include "stb_image_write.h"
9 | #include "stb_image_resize2.h"
10 |
--------------------------------------------------------------------------------
/deps/utfcpp.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\utfcpp\source;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/01-fps_limit/fps_limit_addon.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | static int s_fps_limit = 0;
12 | static std::chrono::high_resolution_clock::time_point s_last_time_point;
13 |
14 | static void on_present(reshade::api::command_queue *, reshade::api::swapchain *, const reshade::api::rect *, const reshade::api::rect *, uint32_t, const reshade::api::rect *)
15 | {
16 | if (s_fps_limit <= 0)
17 | return;
18 |
19 | const auto time_per_frame = std::chrono::high_resolution_clock::duration(std::chrono::seconds(1)) / s_fps_limit;
20 | const auto next_time_point = s_last_time_point + time_per_frame;
21 |
22 | while (next_time_point > std::chrono::high_resolution_clock::now())
23 | std::this_thread::sleep_for(std::chrono::high_resolution_clock::duration(std::chrono::milliseconds(1)));
24 |
25 | s_last_time_point = next_time_point;
26 | }
27 |
28 | static void draw_settings(reshade::api::effect_runtime *)
29 | {
30 | if (ImGui::DragInt("Target FPS", &s_fps_limit, 1, 0, 200))
31 | s_last_time_point = std::chrono::high_resolution_clock::now();
32 |
33 | ImGui::SetItemTooltip("Set to zero to disable the FPS limit.");
34 | }
35 |
36 | extern "C" __declspec(dllexport) const char *NAME = "FPS Limiter";
37 | extern "C" __declspec(dllexport) const char *DESCRIPTION = "Example add-on that limits the frame rate of an application to a specified FPS value.";
38 |
39 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID)
40 | {
41 | switch (fdwReason)
42 | {
43 | case DLL_PROCESS_ATTACH:
44 | if (!reshade::register_addon(hModule))
45 | return FALSE;
46 | reshade::register_event(on_present);
47 | reshade::register_overlay(nullptr, draw_settings);
48 | break;
49 | case DLL_PROCESS_DETACH:
50 | reshade::unregister_addon(hModule);
51 | break;
52 | }
53 |
54 | return TRUE;
55 | }
56 |
--------------------------------------------------------------------------------
/examples/11-obs_capture/obs_hook_info.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Hugh Bailey
3 | * Copyright (C) 2022 Patrick Mours
4 | * SPDX-License-Identifier: GPL-2.0-or-later
5 | *
6 | * Adapted from https://github.com/obsproject/obs-studio/blob/master/plugins/win-capture/graphics-hook/graphics-hook.h
7 | */
8 |
9 | #pragma once
10 |
11 | #include
12 |
13 | #define HOOK_VER_MAJOR 1
14 | #define HOOK_VER_MINOR 7
15 | #define HOOK_VER_PATCH 1
16 |
17 | #define NUM_BUFFERS 3
18 |
19 | #define EVENT_CAPTURE_RESTART L"CaptureHook_Restart"
20 | #define EVENT_CAPTURE_STOP L"CaptureHook_Stop"
21 |
22 | #define EVENT_HOOK_READY L"CaptureHook_HookReady"
23 | #define EVENT_HOOK_EXIT L"CaptureHook_Exit"
24 |
25 | #define EVENT_HOOK_INIT L"CaptureHook_Initialize"
26 |
27 | #define WINDOW_HOOK_KEEPALIVE L"CaptureHook_KeepAlive"
28 |
29 | #define MUTEX_TEXTURE1 L"CaptureHook_TextureMutex1"
30 | #define MUTEX_TEXTURE2 L"CaptureHook_TextureMutex2"
31 |
32 | #define SHMEM_HOOK_INFO L"CaptureHook_HookInfo"
33 | #define SHMEM_TEXTURE L"CaptureHook_Texture"
34 |
35 | enum capture_type
36 | {
37 | CAPTURE_TYPE_MEMORY,
38 | CAPTURE_TYPE_TEXTURE,
39 | };
40 |
41 | #pragma pack(push, 8)
42 |
43 | struct hook_info
44 | {
45 | /* hook version */
46 | uint32_t hook_ver_major;
47 | uint32_t hook_ver_minor;
48 |
49 | /* capture info */
50 | capture_type type;
51 | uint32_t window;
52 | uint32_t format;
53 | uint32_t cx;
54 | uint32_t cy;
55 | uint32_t UNUSED_base_cx;
56 | uint32_t UNUSED_base_cy;
57 | uint32_t pitch;
58 | uint32_t map_id;
59 | uint32_t map_size;
60 | bool flip;
61 |
62 | /* additional options */
63 | uint64_t frame_interval;
64 | bool UNUSED_use_scale;
65 | bool force_shmem;
66 | bool capture_overlay;
67 | bool allow_srgb_alias;
68 |
69 | uint8_t reserved[574];
70 | };
71 | static_assert(sizeof(hook_info) == 648);
72 |
73 | struct shmem_data
74 | {
75 | volatile int last_tex;
76 | uint32_t tex1_offset;
77 | uint32_t tex2_offset;
78 | };
79 |
80 | struct shtex_data
81 | {
82 | uint32_t tex_handle;
83 | };
84 |
85 | #pragma pack(pop)
86 |
87 | extern hook_info *global_hook_info;
88 |
89 | extern void shmem_copy_data(size_t idx, void *volatile data);
90 | extern bool shmem_texture_data_lock(int idx);
91 | extern void shmem_texture_data_unlock(int idx);
92 |
93 | bool hook_init();
94 | void hook_free();
95 |
96 | bool capture_init_shtex(shtex_data *&data, void *window, uint32_t cx, uint32_t cy, uint32_t format, bool flip, uintptr_t handle);
97 | bool capture_init_shmem(shmem_data *&data, void *window, uint32_t cx, uint32_t cy, uint32_t pitch, uint32_t format, bool flip);
98 | void capture_free();
99 |
100 | bool capture_ready();
101 | bool capture_alive();
102 | bool capture_active();
103 | bool capture_stopped();
104 | bool capture_restarted();
105 |
106 | bool capture_signal_ready();
107 | bool capture_signal_restart();
108 |
109 | inline bool capture_should_stop()
110 | {
111 | return capture_active() && capture_stopped() && !capture_alive();
112 | }
113 | inline bool capture_should_init()
114 | {
115 | return !capture_active() && capture_restarted() && capture_alive();
116 | }
117 |
--------------------------------------------------------------------------------
/examples/14-ray_tracing/ray_tracing.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/examples/14-ray_tracing/ray_tracing_shaders.hlsl:
--------------------------------------------------------------------------------
1 | [[vk::binding(0)]]
2 | RaytracingAccelerationStructure as : register(t0);
3 | [[vk::binding(1)]]
4 | RWTexture2D image : register(u0);
5 |
6 | struct Payload
7 | {
8 | float3 color;
9 | };
10 |
11 | [shader("raygeneration")]
12 | void main_raygen()
13 | {
14 | const float2 uv = (float2(DispatchRaysIndex().xy) + float2(0.5, 0.5)) / float2(DispatchRaysDimensions().xy);
15 |
16 | float3 origin = float3(0.0, 0.0, 0.0);
17 | float3 direction = normalize(float3(uv * 2.0 - 1.0, 1.0));
18 |
19 | RayDesc ray = { origin, 0.1, direction, 1000.0 };
20 | Payload payload = { float3(0.0, 0.0, 0.0) };
21 |
22 | TraceRay(as, 0, 0xFF, 0, 0, 0, ray, payload);
23 |
24 | image[DispatchRaysIndex().xy] = float4(payload.color, 0.0);
25 | }
26 |
27 | [shader("miss")]
28 | void main_miss(inout Payload payload)
29 | {
30 | payload.color = float3(0.0, 0.0, 0.0);
31 | }
32 |
33 | [shader("closesthit")]
34 | void main_closest_hit(inout Payload payload, in BuiltInTriangleIntersectionAttributes attribs)
35 | {
36 | const float3 barycentrics = float3(1.0 - attribs.barycentrics.x - attribs.barycentrics.y, attribs.barycentrics.x, attribs.barycentrics.y);
37 | payload.color = barycentrics;
38 | }
39 |
--------------------------------------------------------------------------------
/examples/17-screenshot_to_clipboard/screenshot_to_clipboard_addon.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2025 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include
7 | #include
8 | #include
9 | #include
10 |
11 | static void on_screenshot(reshade::api::effect_runtime *, const char *path_string)
12 | {
13 | if (!OpenClipboard(nullptr))
14 | return;
15 |
16 | const std::wstring path = std::filesystem::u8path(path_string).wstring();
17 |
18 | const HDROP drop_handle = static_cast(GlobalAlloc(GHND, sizeof(DROPFILES) + (path.size() + 1 + 1) * sizeof(WCHAR))); // Terminated with two zero characters
19 | if (drop_handle != nullptr)
20 | {
21 | const LPDROPFILES drop_data = static_cast(GlobalLock(drop_handle));
22 | if (drop_data != nullptr)
23 | {
24 | drop_data->pFiles = sizeof(DROPFILES);
25 | drop_data->fWide = TRUE;
26 |
27 | std::memcpy(reinterpret_cast(drop_data) + drop_data->pFiles, path.c_str(), path.size() * sizeof(WCHAR));
28 |
29 | GlobalUnlock(drop_handle);
30 |
31 | EmptyClipboard();
32 | if (SetClipboardData(CF_HDROP, drop_handle) == nullptr)
33 | GlobalFree(drop_handle);
34 | }
35 | else
36 | {
37 | GlobalFree(drop_handle);
38 | }
39 | }
40 |
41 | CloseClipboard();
42 | }
43 |
44 | extern "C" __declspec(dllexport) const char *NAME = "Copy screenshot to clipboard";
45 |
46 | BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID)
47 | {
48 | switch (fdwReason)
49 | {
50 | case DLL_PROCESS_ATTACH:
51 | if (!reshade::register_addon(hModule))
52 | return FALSE;
53 | reshade::register_event(on_screenshot);
54 | break;
55 | case DLL_PROCESS_DETACH:
56 | reshade::unregister_addon(hModule);
57 | break;
58 | }
59 |
60 | return TRUE;
61 | }
62 |
--------------------------------------------------------------------------------
/examples/utils/config.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2024 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | // The subdirectory to save shader binaries to
7 | #define RESHADE_ADDON_SHADER_SAVE_DIR ".\\shaderdump"
8 |
9 | // The subdirectory to load shader binaries from
10 | #define RESHADE_ADDON_SHADER_LOAD_DIR ".\\shaderreplace"
11 |
12 | // The subdirectory to save textures to
13 | #define RESHADE_ADDON_TEXTURE_SAVE_DIR ".\\texdump"
14 | #define RESHADE_ADDON_TEXTURE_SAVE_FORMAT ".png"
15 | #define RESHADE_ADDON_TEXTURE_SAVE_HASH_TEXMOD 1
16 | // Skip any textures that were already dumped this session, to reduce lag at the cost of increased memory usage
17 | #define RESHADE_ADDON_TEXTURE_SAVE_ENABLE_HASH_SET 1
18 |
19 | // The subdirectory to load textures from
20 | #define RESHADE_ADDON_TEXTURE_LOAD_DIR ".\\texreplace"
21 | #define RESHADE_ADDON_TEXTURE_LOAD_FORMAT ".png"
22 | #define RESHADE_ADDON_TEXTURE_LOAD_HASH_TEXMOD 1
23 |
--------------------------------------------------------------------------------
/examples/utils/state_tracking.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 |
11 | ///
12 | /// A state block capturing current state of a command list.
13 | ///
14 | struct state_block
15 | {
16 | ///
17 | /// Binds all state captured by this state block on the specified command list.
18 | ///
19 | /// Target command list to bind the state on.
20 | void apply(reshade::api::command_list *cmd_list) const;
21 |
22 | ///
23 | /// Removes all state in this state block.
24 | ///
25 | void clear();
26 |
27 | std::vector render_targets;
28 | reshade::api::resource_view depth_stencil = { 0 };
29 | std::unordered_map pipelines;
30 | reshade::api::primitive_topology primitive_topology = reshade::api::primitive_topology::undefined;
31 | uint32_t blend_constant = 0;
32 | uint32_t sample_mask = 0xFFFFFFFF;
33 | uint32_t front_stencil_reference_value = 0;
34 | uint32_t back_stencil_reference_value = 0;
35 | std::vector viewports;
36 | std::vector scissor_rects;
37 | std::unordered_map>> descriptor_tables;
38 | };
39 |
40 | ///
41 | /// An instance of this is automatically created for all command lists and can be queried with cmd_list->get_private_data<state_tracking>() (assuming state tracking was registered via ).
42 | ///
43 | class __declspec(uuid("c9abddf0-f9c2-4a7b-af49-89d8d470e207")) state_tracking : public state_block
44 | {
45 | public:
46 | ///
47 | /// Registers all the necessary add-on events for state tracking to work.
48 | ///
49 | static void register_events();
50 | ///
51 | /// Unregisters all the necessary add-on events for state tracking to work.
52 | ///
53 | static void unregister_events();
54 | };
55 |
--------------------------------------------------------------------------------
/res/fonts/forkawesome.h:
--------------------------------------------------------------------------------
1 | //Header Generated with https://github.com/aiekick/ImGuiFontStudio
2 | //Based on https://github.com/juliettef/IconFontCppHeaders
3 |
4 | #pragma once
5 |
6 | #define FONT_ICON_BUFFER_NAME_FK FK_compressed_data_base85
7 | #define FONT_ICON_BUFFER_SIZE_FK 0xc26
8 |
9 | #define ICON_MIN_FK 0xf002
10 | #define ICON_MAX_FK 0xf1c9
11 |
12 | #define ICON_FK_CANCEL u8"\uf00d"
13 | #define ICON_FK_FILE u8"\uf016"
14 | #define ICON_FK_FILE_CODE u8"\uf1c9"
15 | #define ICON_FK_FILE_IMAGE u8"\uf1c5"
16 | #define ICON_FK_FLOPPY u8"\uf0c7"
17 | #define ICON_FK_FOLDER u8"\uf114"
18 | #define ICON_FK_FOLDER_OPEN u8"\uf115"
19 | #define ICON_FK_MINUS u8"\uf068"
20 | #define ICON_FK_OK u8"\uf00c"
21 | #define ICON_FK_PENCIL u8"\uf040"
22 | #define ICON_FK_PLUS u8"\uf067"
23 | #define ICON_FK_REFRESH u8"\uf021"
24 | #define ICON_FK_SEARCH u8"\uf002"
25 | #define ICON_FK_UNDO u8"\uf0e2"
26 | #define ICON_FK_WARNING u8"\uf071"
27 |
--------------------------------------------------------------------------------
/res/fonts/forkawesome.ifs:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | FK
22 | forkawesome-webfont.ttf
23 | 1
24 | 32
25 |
26 |
27 | 20
28 |
29 | true
30 | true
31 | true
32 | 1
33 | false
34 | 5
35 | 653
36 | forkawesome-webfont.ttf
37 |
38 |
39 |
--------------------------------------------------------------------------------
/res/fonts/forkawesome.inl:
--------------------------------------------------------------------------------
1 | #include "forkawesome.h"
2 |
3 | static const char FONT_ICON_BUFFER_NAME_FK[3110+1] =
4 | "7])#######l4F<6'/###[),##+Sl##Q6>##w#S+HcY..Xm1NP&&A'o/dJ[^Ii4j)%afG<-dwhP/-2JuBXhc/(,xkA##B^01:_[FH<:p3#L,>>#:qEn/Bd@UCAuOi$hhG<-87T;-QF%U."
5 | "4tw<6rhG<-]vhP/Q-0%JU)*Im0YK_#:7KwA--4S>-Mr*J-2%KgL`Kss'k,e'&(_.R3dFrZu2/FI%[CP)M*f(HMP;7A-A_@U.Blu##[brX-rLmHHsn&W74xD_&4oP]O"
6 | ":*L/L7q+N'w[a`WCT8U)$bj-$D)+Z$CFt-$N;>uu`0YR*OWe;%s9]jL3MG8.'5>##SFpG##WPj%r0hLgVV8&jIdK'<;/q-X,-9dS=N'*ABppd#),##i@H0'L0:/DNAhJ)"
7 | "Fs.O=/MbA#99uD+rSXL#=1GcMgJGi8Lw-Sr[fLrrH##.GY##2Sl##6`($#ePgc.>xL$#1ZqV%p[%/1,60MTqWLA+%O5SeGDfY,os.Gik/f`E-PQ/1?kR/9hu>#fl?Q#(./J36qiYLMOP?uuYg8e$UNc##K(m<-?qD#MbPMG)@f)T/^b%T%S2`^#J:8Y.pV*i("
9 | "T=)?#h-[guT#9iu&](?#A]wG;[Dm]uB*07QK(]qFV=fV$H[`V$#kUK#$8^fLmw@8%P92^uJ98=/+@u2OHI.o`5BOojOps+/QlRfL*xFt$=bx5#G%KgLmb]s$wkH>#iE(E#VA@r%Mep$-"
10 | "T1G$,G2J1,mQOhuvne.Mv?75/Huiw'6`?$=VC]&,EH*7M:9s%,:7QVQNcb-?GlguuWN3L#Y@%%#+.>15XAic)rkh8.mNv)4')'J3Ne_F*-vY8/NmVE-*tbU%.qFX$]f.'5/^@+0j.8$$H33-,+VxA&W@1,'#(kZoAKkP9MTC(T7"
12 | "t#;(,b_mL,v?qr&4uG##%J/GV;leJj:SU*%S6[0#9%T*#?3B:%isAv-&O]s$^jtJ)iMTG.KG>c4[lZ#6*@G.)Kfhd3WH5<.*M4gL;ngo0TAOZ6W.PV-RVx_4QmuX$KOj`ub>(6RTcZUL"
13 | "bR39/oBfU+-p9x9SP>bnQ5&X%pbO-)&-g[us_.u-=^7>N8$EG'i_7MTv+qM#ReBtLg@RxktpqbrUv?rC*+8C8i&X1)e61nLx-$O*%@h-Ml=DX-xv@=(`()?#B8WeFeN4kL4Sq'#'&>uu"
14 | "D@]p$?HY##Pe[%#jMOV-H,Jd)K?_`3qh)?#0SEF3oc@A4voXV-HNpdmrZ*G4S)ZA#V8HC@BO?h#l7=9%8>>#XIVS%Ae8e$rLbMYWI))CuM(jAqB#]p*P(uAOZ6m('J3k#fF4Rq@.*G7K,3L1O058b4-5mS4'5841'5%J/GV/1:B#'at%$q^DIMiYV6MdS6##,>3/L"
16 | "dbb(NRdimM-a4o7qPa>$cMDX:c)L'5&8YuuCmxE%jxIfLNdP&sgo.5>PjLcgp>,&'ihLoGb%$kLu/MdB]s$8uaX(g?T:%-<3jLV*<9/r4)mL`ZH##gFYF'rh%T%kE,7-xh&`]3I)"
17 | "bRX-)Vi08.bC/#.&_H#6*,`#$b9bS9#Yhb'0R:-MA<6GMXfU9%NB5N'q(73'4(NSt?fxD,os3;7]OQ--#E^>e&@,gL7R=g*P(Bis9))%x[-"
18 | ",CS@#_t1kbE'7eM=WqP8[`_s-D7H>#Ot]=u'bKd33_+/(R4U8.b(<9/%&AA4LU%],sq-x64=S_#vBo8%FLHm8=N#B=[5ZA#83E.3C4Z##PIpUm6MU7eK2[S%+.`0(k3VNI%(Y4=%]uY`n9.0O7DEhTr2a52Ca79XIMbevebt2o7^Bf,jl2r"
23 | "(2M'#J.#I9mU7C#mc4c4br9s-;va.3DY[OVk1k3Gpv,W.O-F%beUU@-$eQX.4^(##2tff.P=#+#g_7-@XA#R4r?#fgGj'x%MT/ObE]-QtfM'-Wgf1Q<258MnP,*"
24 | "?ulW-tYqw0`EmS/si+C#[<;S&mInS%FAov#Fu[E+*L'O'GWuN'+)U40`a5k'sA;)*RIRF%Tw/Z--1=e?5;1X:;vPk&CdNjL*(KJ1/,TV-G(^S*v14gL#8,,M*YPgLaII@b*]IK37Ah1T"
25 | "GkI9(&;cY#,VC;$0o$s$9bJM'rCdS%8I<5&B1#?LFdo>kEBbT%JpO]:Co4;hFwf1eG0Y5W-lKx?0aeKh5"
26 | "WTw0FZd^$&p)fUC2ve:C3n8AtjXI)g";
27 |
28 |
--------------------------------------------------------------------------------
/res/main_icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/res/main_icon.ico
--------------------------------------------------------------------------------
/res/main_icon_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/res/main_icon_small.png
--------------------------------------------------------------------------------
/res/main_icon_small.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
69 |
--------------------------------------------------------------------------------
/res/resource.h:
--------------------------------------------------------------------------------
1 | //{{NO_DEPENDENCIES}}
2 | // Microsoft Visual C++ generated include file.
3 | // Used by resource.rc
4 | //
5 | #define IDR_COPY_PS 101
6 | #define IDR_FULLSCREEN_VS 102
7 | #define IDR_IMGUI_PS_3_0 103
8 | #define IDR_IMGUI_PS_4_0 104
9 | #define IDR_IMGUI_PS_GLSL 105
10 | #define IDR_IMGUI_PS_SPIRV 106
11 | #define IDR_IMGUI_VS_3_0 107
12 | #define IDR_IMGUI_VS_4_0 108
13 | #define IDR_IMGUI_VS_GLSL 109
14 | #define IDR_IMGUI_VS_SPIRV 110
15 | #define IDR_MIPMAP_CS 111
16 | #define IDR_MIPMAP_CS_GLSL 112
17 | #define IDB_MAIN_ICON 600
18 | #define IDR_LICENSE_GL3W 701
19 | #define IDR_LICENSE_IMGUI 702
20 | #define IDR_LICENSE_MINHOOK 703
21 | #define IDR_LICENSE_OPENVR 704
22 | #define IDR_LICENSE_OPENXR 705
23 | #define IDR_LICENSE_RESHADE 706
24 | #define IDR_LICENSE_SPIRV 707
25 | #define IDR_LICENSE_STB 708
26 | #define IDR_LICENSE_UTFCPP 709
27 | #define IDR_LICENSE_VMA 710
28 | #define IDR_LICENSE_VULKAN 711
29 |
30 | // Next default values for new objects
31 | //
32 | #ifdef APSTUDIO_INVOKED
33 | #ifndef APSTUDIO_READONLY_SYMBOLS
34 | #define _APS_NEXT_RESOURCE_VALUE 115
35 | #define _APS_NEXT_COMMAND_VALUE 40001
36 | #define _APS_NEXT_CONTROL_VALUE 1001
37 | #define _APS_NEXT_SYMED_VALUE 115
38 | #endif
39 | #endif
40 |
--------------------------------------------------------------------------------
/res/shaders/copy_ps.hlsl:
--------------------------------------------------------------------------------
1 | Texture2D t0 : register(t0);
2 | SamplerState s0 : register(s0);
3 |
4 | void main(float4 vpos : SV_POSITION, float2 uv : TEXCOORD0, out float4 col : SV_TARGET)
5 | {
6 | col = t0.Sample(s0, uv);
7 | col.a = 1.0; // Clear alpha channel
8 | }
9 |
--------------------------------------------------------------------------------
/res/shaders/fullscreen_vs.hlsl:
--------------------------------------------------------------------------------
1 | // Vertex shader generating a triangle covering the entire screen
2 | void main(uint id : SV_VERTEXID, out float4 pos : SV_POSITION, out float2 uv : TEXCOORD0)
3 | {
4 | uv.x = (id == 1) ? 2.0 : 0.0;
5 | uv.y = (id == 2) ? 2.0 : 0.0;
6 | pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
7 | }
8 |
--------------------------------------------------------------------------------
/res/shaders/imgui_hdr.hlsl:
--------------------------------------------------------------------------------
1 | #ifdef float3x3
2 | #define mul(a, b) (a) * (b)
3 | #endif
4 |
5 | #define COLOR_SPACE_SRGB 1
6 | #define COLOR_SPACE_HDR10 3
7 | #define COLOR_SPACE_HLG 4
8 | #define COLOR_SPACE_SCRGB 2
9 |
10 | float3 bt709_to_bt2020(float3 col)
11 | {
12 | const float3x3 bt709_to_bt2020 = float3x3(
13 | 0.627403914928436279296875, 0.3292830288410186767578125, 0.0433130674064159393310546875,
14 | 0.069097287952899932861328125, 0.9195404052734375, 0.011362315155565738677978515625,
15 | 0.01639143936336040496826171875, 0.08801330626010894775390625, 0.895595252513885498046875);
16 |
17 | return mul(bt709_to_bt2020, col);
18 | }
19 |
20 | float3 pq_inverse_eotf(float3 col) // 1.0 = 10000 nits here
21 | {
22 | // PQ constants as per Rec. ITU-R BT.2100-2 Table 4
23 | const float PQ_m1 = 0.1593017578125;
24 | const float PQ_m2 = 78.84375;
25 | const float PQ_c1 = 0.8359375;
26 | const float PQ_c2 = 18.8515625;
27 | const float PQ_c3 = 18.6875;
28 |
29 | float3 col_pow_m1 = pow(col, PQ_m1.xxx);
30 |
31 | return pow((PQ_c1 + PQ_c2 * col_pow_m1) / (1.f + PQ_c3 * col_pow_m1), PQ_m2.xxx);
32 | }
33 |
34 | float hlg_inverse_eotf(float col) // 1.0 = 1000 nits here
35 | {
36 | // HLG constants as per Rec. ITU-R BT.2100-2 Table 5
37 | const float HLG_a = 0.17883277;
38 | const float HLG_b = 0.28466892; // 1 - 4 * HLG_a
39 | const float HLG_c = 0.559910714626312255859375; // 0.5 - HLG_a * ln(4 * HLG_a)
40 |
41 | if (col <= (1.0 / 12.0))
42 | {
43 | return sqrt(3.0 * col);
44 | }
45 | else
46 | {
47 | return HLG_a * log(12.0 * col - HLG_b) + HLG_c;
48 | }
49 | }
50 | float3 hlg_inverse_eotf(float3 col)
51 | {
52 | return float3(hlg_inverse_eotf(col.r), hlg_inverse_eotf(col.g), hlg_inverse_eotf(col.b));
53 | }
54 |
55 | // HDR10 (PQ transfer function + BT.2020 primaries)
56 | float3 to_pq(float3 col)
57 | {
58 | col = pow(col, 2.2.xxx);
59 | col = bt709_to_bt2020(col);
60 | col = col * hdr_overlay_brightness / 10000.0;
61 | col = pq_inverse_eotf(col);
62 |
63 | return col;
64 | }
65 |
66 | // HLG (HLG transfer function + BT.2020 primaries)
67 | float3 to_hlg(float3 col)
68 | {
69 | col = pow(col, 2.2.xxx);
70 | col = bt709_to_bt2020(col);
71 | col = col * hdr_overlay_brightness / 1000.0;
72 | col = hlg_inverse_eotf(col);
73 |
74 | return col;
75 | }
76 |
77 | // scRGB (linear + BT.709/sRGB primaries)
78 | float3 to_scrgb(float3 col) // 1.0 = 80 nits in scRGB
79 | {
80 | col = pow(col, 2.2.xxx);
81 | col = col * hdr_overlay_brightness / 80.0;
82 |
83 | return col;
84 | }
85 |
--------------------------------------------------------------------------------
/res/shaders/imgui_ps_3_0.hlsl:
--------------------------------------------------------------------------------
1 | sampler2D s0 : register(s0);
2 |
3 | void main(float4 vpos : VPOS, float4 vcol : COLOR0, float2 uv : TEXCOORD0, out float4 col : COLOR)
4 | {
5 | col = tex2D(s0, uv);
6 | col *= vcol; // Blend vertex color and texture
7 | }
8 |
--------------------------------------------------------------------------------
/res/shaders/imgui_ps_430.glsl:
--------------------------------------------------------------------------------
1 | #version 430
2 |
3 | layout(binding = 0) uniform sampler2D s0;
4 |
5 | in vec4 frag_col;
6 | in vec2 frag_tex;
7 |
8 | out vec4 col;
9 |
10 | void main()
11 | {
12 | col = texture(s0, frag_tex);
13 | col *= frag_col; // Blend vertex color and texture
14 | }
15 |
--------------------------------------------------------------------------------
/res/shaders/imgui_ps_450.glsl:
--------------------------------------------------------------------------------
1 | #version 450 core
2 | #extension GL_ARB_shading_language_include : require
3 |
4 | layout(set = 0, binding = 0) uniform sampler2D s0;
5 |
6 | layout(location = 0) in struct { vec4 col; vec2 tex; } i;
7 | vec4 vcol = i.col;
8 | layout(location = 0) out vec4 col;
9 |
10 | layout(push_constant) uniform PushConstants
11 | {
12 | // Offset from the orthographic projection matrix used in the vertex shader
13 | layout(offset = 64) uint color_space;
14 | layout(offset = 68) float hdr_overlay_brightness;
15 | };
16 |
17 | #include "imgui_hdr.hlsl"
18 |
19 | void main()
20 | {
21 | if (color_space == COLOR_SPACE_HDR10)
22 | {
23 | vcol.rgb = to_pq(vcol.rgb);
24 | }
25 | else if (color_space == COLOR_SPACE_HLG)
26 | {
27 | vcol.rgb = to_hlg(vcol.rgb);
28 | }
29 | else if (color_space == COLOR_SPACE_SCRGB)
30 | {
31 | vcol.rgb = to_scrgb(vcol.rgb);
32 | }
33 |
34 | col = texture(s0, i.tex);
35 | col *= vcol; // Blend vertex color and texture
36 | }
37 |
--------------------------------------------------------------------------------
/res/shaders/imgui_ps_450.spv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/res/shaders/imgui_ps_450.spv
--------------------------------------------------------------------------------
/res/shaders/imgui_ps_450_hdr.spv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/res/shaders/imgui_ps_450_hdr.spv
--------------------------------------------------------------------------------
/res/shaders/imgui_ps_4_0.hlsl:
--------------------------------------------------------------------------------
1 | Texture2D t0 : register(t0);
2 | SamplerState s0 : register(s0);
3 |
4 | cbuffer PushConstants : register(b0)
5 | {
6 | // Offset from the orthographic projection matrix used in the vertex shader
7 | uint color_space : packoffset(c4.x);
8 | float hdr_overlay_brightness : packoffset(c4.y);
9 | };
10 |
11 | #include "imgui_hdr.hlsl"
12 |
13 | void main(float4 vpos : SV_POSITION, float4 vcol : COLOR0, float2 uv : TEXCOORD0, out float4 col : SV_TARGET)
14 | {
15 | if (color_space == COLOR_SPACE_HDR10)
16 | {
17 | vcol.rgb = to_pq(vcol.rgb);
18 | }
19 | else if (color_space == COLOR_SPACE_HLG)
20 | {
21 | vcol.rgb = to_hlg(vcol.rgb);
22 | }
23 | else if (color_space == COLOR_SPACE_SCRGB)
24 | {
25 | vcol.rgb = to_scrgb(vcol.rgb);
26 | }
27 |
28 | col = t0.Sample(s0, uv);
29 | col *= vcol; // Blend vertex color and texture
30 | }
31 |
--------------------------------------------------------------------------------
/res/shaders/imgui_vs_3_0.hlsl:
--------------------------------------------------------------------------------
1 | struct VS_INPUT
2 | {
3 | float2 pos : POSITION;
4 | float4 col : COLOR0;
5 | float2 tex : TEXCOORD0;
6 | };
7 | struct PS_INPUT
8 | {
9 | float4 pos : POSITION;
10 | float4 col : COLOR0;
11 | float2 tex : TEXCOORD0;
12 | };
13 |
14 | uniform float4x4 ortho_projection;
15 |
16 | void main(VS_INPUT input, out PS_INPUT output)
17 | {
18 | output.pos = mul(ortho_projection, float4(input.pos.xy, 0.0, 1.0));
19 | output.col = input.col;
20 | output.tex = input.tex;
21 | }
22 |
--------------------------------------------------------------------------------
/res/shaders/imgui_vs_430.glsl:
--------------------------------------------------------------------------------
1 | #version 430
2 |
3 | layout(location = 0) in vec2 pos;
4 | layout(location = 1) in vec2 tex;
5 | layout(location = 2) in vec4 col;
6 |
7 | out vec4 frag_col;
8 | out vec2 frag_tex;
9 |
10 | layout(binding = 0) uniform PushConstants
11 | {
12 | mat4 ortho_projection;
13 | };
14 |
15 | void main()
16 | {
17 | frag_col = col;
18 | frag_tex = tex;
19 | gl_Position = ortho_projection * vec4(pos.xy, 0, 1);
20 | }
21 |
--------------------------------------------------------------------------------
/res/shaders/imgui_vs_450.glsl:
--------------------------------------------------------------------------------
1 | #version 450 core
2 |
3 | layout(location = 0) in vec2 pos;
4 | layout(location = 1) in vec2 tex;
5 | layout(location = 2) in vec4 col;
6 | layout(location = 0) out struct { vec4 col; vec2 tex; } o;
7 |
8 | layout(push_constant) uniform PushConstants
9 | {
10 | mat4 ortho_projection;
11 | };
12 |
13 | void main()
14 | {
15 | o.col = col;
16 | o.tex = tex;
17 | gl_Position = ortho_projection * vec4(pos, 0, 1);
18 | }
19 |
--------------------------------------------------------------------------------
/res/shaders/imgui_vs_450.spv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/res/shaders/imgui_vs_450.spv
--------------------------------------------------------------------------------
/res/shaders/imgui_vs_4_0.hlsl:
--------------------------------------------------------------------------------
1 | struct VS_INPUT
2 | {
3 | float2 pos : POSITION;
4 | float4 col : COLOR0;
5 | float2 tex : TEXCOORD0;
6 | };
7 | struct PS_INPUT
8 | {
9 | float4 pos : SV_POSITION;
10 | float4 col : COLOR0;
11 | float2 tex : TEXCOORD0;
12 | };
13 |
14 | cbuffer PushConstants : register(b0)
15 | {
16 | float4x4 ortho_projection;
17 | };
18 |
19 | void main(VS_INPUT input, out PS_INPUT output)
20 | {
21 | output.pos = mul(ortho_projection, float4(input.pos.xy, 0.0, 1.0));
22 | output.col = input.col;
23 | output.tex = input.tex;
24 | }
25 |
--------------------------------------------------------------------------------
/res/shaders/mipmap_cs_430.glsl:
--------------------------------------------------------------------------------
1 | #version 430
2 |
3 | layout(binding = 0) uniform sampler2D src;
4 | layout(binding = 1) uniform writeonly image2D dest;
5 |
6 | layout(location = 0) uniform int src_level;
7 |
8 | layout(local_size_x = 8, local_size_y = 8) in;
9 |
10 | vec4 reduce(ivec2 location)
11 | {
12 | vec4 v0 = texelFetch(src, location + ivec2(0, 0), src_level);
13 | vec4 v1 = texelFetch(src, location + ivec2(0, 1), src_level);
14 | vec4 v2 = texelFetch(src, location + ivec2(1, 0), src_level);
15 | vec4 v3 = texelFetch(src, location + ivec2(1, 1), src_level);
16 | return (v0 + v1 + v2 + v3) * 0.25;
17 | }
18 |
19 | void main()
20 | {
21 | vec4 v = reduce(ivec2(gl_GlobalInvocationID.xy * 2));
22 | imageStore(dest, ivec2(gl_GlobalInvocationID.xy), v);
23 | }
24 |
--------------------------------------------------------------------------------
/res/version.rc2:
--------------------------------------------------------------------------------
1 | #include "version.h"
2 |
3 | /////////////////////////////////////////////////////////////////////////////
4 | //
5 | // Version
6 | //
7 |
8 | VS_VERSION_INFO VERSIONINFO
9 | FILEVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILD
10 | PRODUCTVERSION VERSION_MAJOR,VERSION_MINOR,VERSION_REVISION,VERSION_BUILD
11 | FILEFLAGSMASK VS_FFI_FILEFLAGSMASK
12 | #ifdef _DEBUG
13 | FILEFLAGS (VS_FF_PRERELEASE | VS_FF_DEBUG)
14 | #else
15 | FILEFLAGS 0x0L
16 | #endif
17 | FILEOS VOS_NT_WINDOWS32
18 | FILETYPE VFT_DLL
19 | FILESUBTYPE VFT2_UNKNOWN
20 | BEGIN
21 | BLOCK "StringFileInfo"
22 | BEGIN
23 | BLOCK "040004b0"
24 | BEGIN
25 | VALUE "CompanyName", "crosire"
26 | VALUE "FileVersion", VERSION_STRING_FILE
27 | VALUE "ProductName", "ReShade"
28 | VALUE "ProductVersion", VERSION_STRING_PRODUCT
29 | VALUE "LegalCopyright", "Copyright © 2014. All rights reserved."
30 | #ifdef RESHADE_FXC
31 | VALUE "FileDescription", "ReShade FX compiler"
32 | #else
33 | #ifndef _WIN64
34 | VALUE "FileDescription", "crosire's ReShade post-processing injector for 32-bit"
35 | VALUE "OriginalFilename", "ReShade32.dll"
36 | #else
37 | VALUE "FileDescription", "crosire's ReShade post-processing injector for 64-bit"
38 | VALUE "OriginalFilename", "ReShade64.dll"
39 | #endif
40 | #endif
41 | END
42 | END
43 | BLOCK "VarFileInfo"
44 | BEGIN
45 | VALUE "Translation", 0x400, 0x4b0
46 | END
47 | END
48 |
--------------------------------------------------------------------------------
/setup/MainWindow.xaml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/setup/Pages/Resources/DirectX.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/setup/Pages/Resources/DirectX.png
--------------------------------------------------------------------------------
/setup/Pages/Resources/OpenGL.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/setup/Pages/Resources/OpenGL.png
--------------------------------------------------------------------------------
/setup/Pages/Resources/OpenXR.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/setup/Pages/Resources/OpenXR.png
--------------------------------------------------------------------------------
/setup/Pages/Resources/Vulkan.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/setup/Pages/Resources/Vulkan.png
--------------------------------------------------------------------------------
/setup/Pages/SelectApiPage.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | using System.Diagnostics;
7 | using System.Windows.Controls;
8 | using System.Windows.Navigation;
9 |
10 | namespace ReShade.Setup.Pages
11 | {
12 | public enum Api
13 | {
14 | Unknown,
15 | D3D9,
16 | D3D10,
17 | D3D11,
18 | D3D12,
19 | DXGI,
20 | DDraw,
21 | OpenGL,
22 | Vulkan
23 | }
24 |
25 | public partial class SelectApiPage : Page
26 | {
27 | public SelectApiPage(string appName)
28 | {
29 | InitializeComponent();
30 |
31 | AppName.Text = appName;
32 | }
33 |
34 | public Api SelectedApi
35 | {
36 | get
37 | {
38 | if (ApiD3D9.IsChecked == true)
39 | {
40 | return Api.D3D9;
41 | }
42 | if (ApiDXGI.IsChecked == true)
43 | {
44 | return Api.DXGI;
45 | }
46 | if (ApiOpenGL.IsChecked == true)
47 | {
48 | return Api.OpenGL;
49 | }
50 | if (ApiVulkan.IsChecked == true)
51 | {
52 | return Api.Vulkan;
53 | }
54 |
55 | return Api.Unknown;
56 | }
57 | set
58 | {
59 | ApiD3D9.IsChecked = value == Api.D3D9;
60 | ApiDXGI.IsChecked = value == Api.D3D10 || value == Api.D3D11 || value == Api.D3D12 || value == Api.DXGI;
61 | ApiOpenGL.IsChecked = value == Api.OpenGL;
62 | ApiVulkan.IsChecked = value == Api.Vulkan;
63 | }
64 | }
65 | public bool SelectedOpenXR
66 | {
67 | get => ApiOpenXR.IsChecked == true;
68 | set => ApiOpenXR.IsChecked = value;
69 | }
70 |
71 | private void OnHyperlinkNavigate(object sender, RequestNavigateEventArgs e)
72 | {
73 | Process.Start(e.Uri.ToString());
74 | e.Handled = true;
75 | }
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/setup/Pages/SelectAppPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 | Recently Used
15 | A to Z
16 | Z to A
17 |
18 |
19 |
20 |
21 | Browse and select a game to manage its ReShade installation.
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/setup/Pages/SelectOperationPage.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 | An existing ReShade installation was found for the target game. Choose how to proceed with this installation.
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 | Update ReShade to this version, but keep existing preset and effect files unchanged.
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | Update ReShade to this version and also download effect files again.
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 | Remove ReShade, related configuration, logs and all installed effect files from the target game.
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/setup/Pages/SelectOperationPage.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | using System.Windows.Controls;
7 |
8 | namespace ReShade.Setup.Pages
9 | {
10 | public enum InstallOperation
11 | {
12 | Install,
13 | Update,
14 | UpdateWithEffects,
15 | Uninstall,
16 | Finished
17 | }
18 |
19 | public partial class SelectOperationPage : Page
20 | {
21 | public SelectOperationPage()
22 | {
23 | InitializeComponent();
24 | }
25 |
26 | public InstallOperation SelectedOperation
27 | {
28 | get
29 | {
30 | if (UpdateButton.IsChecked == true)
31 | {
32 | return InstallOperation.Update;
33 | }
34 | if (ModifyButton.IsChecked == true)
35 | {
36 | return InstallOperation.UpdateWithEffects;
37 | }
38 | if (UninstallButton.IsChecked == true)
39 | {
40 | return InstallOperation.Uninstall;
41 | }
42 |
43 | return InstallOperation.Install;
44 | }
45 | set
46 | {
47 | UpdateButton.IsChecked = value == InstallOperation.Update;
48 | ModifyButton.IsChecked = value == InstallOperation.UpdateWithEffects;
49 | UninstallButton.IsChecked = value == InstallOperation.Uninstall;
50 | }
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/setup/Pages/StatusPage.xaml.cs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | using System.Diagnostics;
7 | using System.Windows;
8 | using System.Windows.Controls;
9 |
10 | namespace ReShade.Setup.Pages
11 | {
12 | public partial class StatusPage : Page
13 | {
14 | public StatusPage()
15 | {
16 | InitializeComponent();
17 | }
18 |
19 | public void UpdateStatus(string message, bool? status = null)
20 | {
21 | if (status is null)
22 | {
23 | StatusSpin.Visibility = Visibility.Visible;
24 | StatusSuccess.Visibility = Visibility.Collapsed;
25 | StatusFailure.Visibility = Visibility.Collapsed;
26 | PatreonButton.Visibility = Visibility.Collapsed;
27 | }
28 | else
29 | {
30 | StatusSpin.Visibility = Visibility.Collapsed;
31 | StatusSuccess.Visibility = status == true ? Visibility.Visible : Visibility.Collapsed;
32 | StatusFailure.Visibility = status == true ? Visibility.Collapsed : Visibility.Visible;
33 | PatreonButton.Visibility = status == true ? Visibility.Visible : Visibility.Collapsed;
34 | }
35 |
36 | ProgressText.Text = message;
37 | }
38 |
39 | private void OnPatreonButtonClick(object sender, RoutedEventArgs e)
40 | {
41 | Process.Start("https://patreon.com/crosire");
42 | }
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/setup/Properties/App.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/setup/Properties/App.xaml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
18 |
19 |
--------------------------------------------------------------------------------
/setup/Properties/App.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Runtime.InteropServices;
3 |
4 | namespace ReShade.Setup
5 | {
6 | public partial class App
7 | {
8 | [DllImport("kernel32.dll", SetLastError = true)]
9 | [return: MarshalAs(UnmanagedType.Bool)]
10 | static extern bool SetDefaultDllDirectories(uint directoryFlags);
11 |
12 | public App()
13 | {
14 | if (Type.GetType("Mono.Runtime") == null)
15 | {
16 | // The 'DefaultDllImportSearchPaths' assembly attribute does not cover DLLs loaded by the WPF runtime, so force it to load from the system directory via native call
17 | SetDefaultDllDirectories(0x00000800 /* LOAD_LIBRARY_SEARCH_SYSTEM32 */);
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/setup/Properties/Assembly.manifest:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/setup/Properties/AssemblyInfo.cs.in:
--------------------------------------------------------------------------------
1 | #include "version.h"
2 |
3 | #define STRINGIZE(value) #value
4 | #define EXPAND_AND_STRINGIZE(value) STRINGIZE(value)
5 |
6 | #define BUILD_VERSION(major, minor, revision) \
7 | EXPAND_AND_STRINGIZE(major.minor.revision)
8 |
9 | using System.Reflection;
10 | using System.Runtime.InteropServices;
11 |
12 | [assembly: AssemblyTitle("ReShade Setup")]
13 | [assembly: AssemblyVersion(BUILD_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_REVISION))]
14 | [assembly: AssemblyInformationalVersion(VERSION_STRING_PRODUCT)]
15 | [assembly: AssemblyDescription("")]
16 | [assembly: AssemblyCompany("crosire")]
17 | [assembly: AssemblyProduct("ReShade")]
18 | [assembly: AssemblyCopyright("Copyright © 2014. All rights reserved.")]
19 |
20 | #ifdef BUILD_CONFIGURATION
21 | [assembly: AssemblyConfiguration(EXPAND_AND_STRINGIZE(BUILD_CONFIGURATION))]
22 | #endif
23 |
24 | [assembly: DefaultDllImportSearchPaths(DllImportSearchPath.System32)]
25 |
--------------------------------------------------------------------------------
/setup/ReShade32.json:
--------------------------------------------------------------------------------
1 | {
2 | "file_format_version": "1.0.0",
3 | "layer": {
4 | "name": "VK_LAYER_reshade",
5 | "type": "GLOBAL",
6 | "library_path": ".\\ReShade32.dll",
7 | "api_version": "1.3.268",
8 | "implementation_version": "1",
9 | "description": "crosire's ReShade post-processing injector for 32-bit",
10 | "device_extensions": [
11 | {
12 | "name": "VK_EXT_tooling_info",
13 | "spec_version": "1",
14 | "entrypoints": [ "vkGetPhysicalDeviceToolPropertiesEXT" ]
15 | }
16 | ],
17 | "disable_environment": {
18 | "DISABLE_VK_LAYER_reshade_1": "1"
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/setup/ReShade32_XR.json:
--------------------------------------------------------------------------------
1 | {
2 | "file_format_version": "1.0.0",
3 | "api_layer": {
4 | "name": "XR_APILAYER_reshade",
5 | "library_path": ".\\ReShade32.dll",
6 | "api_version": "1.0",
7 | "implementation_version": "2",
8 | "description": "crosire's ReShade post-processing injector for 32-bit",
9 | "disable_environment": "DISABLE_XR_APILAYER_reshade_1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/setup/ReShade64.json:
--------------------------------------------------------------------------------
1 | {
2 | "file_format_version": "1.0.0",
3 | "layer": {
4 | "name": "VK_LAYER_reshade",
5 | "type": "GLOBAL",
6 | "library_path": ".\\ReShade64.dll",
7 | "api_version": "1.3.268",
8 | "implementation_version": "1",
9 | "description": "crosire's ReShade post-processing injector for 64-bit",
10 | "device_extensions": [
11 | {
12 | "name": "VK_EXT_tooling_info",
13 | "spec_version": "1",
14 | "entrypoints": [ "vkGetPhysicalDeviceToolPropertiesEXT" ]
15 | }
16 | ],
17 | "disable_environment": {
18 | "DISABLE_VK_LAYER_reshade_1": "1"
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/setup/ReShade64_XR.json:
--------------------------------------------------------------------------------
1 | {
2 | "file_format_version": "1.0.0",
3 | "api_layer": {
4 | "name": "XR_APILAYER_reshade",
5 | "library_path": ".\\ReShade64.dll",
6 | "api_version": "1.0",
7 | "implementation_version": "2",
8 | "description": "crosire's ReShade post-processing injector for 64-bit",
9 | "disable_environment": "DISABLE_XR_APILAYER_reshade_1"
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/source/addon.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "reshade_api.hpp"
9 | #include
10 | #include
11 |
12 | #if RESHADE_ADDON
13 |
14 | namespace reshade
15 | {
16 | struct addon_info
17 | {
18 | struct overlay_callback
19 | {
20 | std::string title;
21 | void(*callback)(api::effect_runtime *) = nullptr;
22 | };
23 |
24 | void *handle = nullptr;
25 | std::string name;
26 | std::string description;
27 | std::string file;
28 | std::string author;
29 | std::string website_url;
30 | std::string issues_url;
31 | union version
32 | {
33 | struct number
34 | {
35 | uint16_t major;
36 | uint16_t minor;
37 | uint16_t build;
38 | uint16_t revision;
39 | } number;
40 | uint64_t value;
41 | } version = {};
42 | bool external = true;
43 |
44 | std::vector> event_callbacks;
45 | #if RESHADE_GUI
46 | void(*settings_overlay_callback)(api::effect_runtime *) = nullptr;
47 | std::vector overlay_callbacks;
48 | #endif
49 | };
50 | }
51 |
52 | #endif
53 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_impl_command_queue.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d10_impl_device.hpp"
7 |
8 | void reshade::d3d10::device_impl::wait_idle() const
9 | {
10 | #if 0
11 | D3D10_QUERY_DESC temp_query_desc;
12 | temp_query_desc.Query = D3D10_QUERY_EVENT;
13 | temp_query_desc.MiscFlags = 0;
14 |
15 | com_ptr temp_query;
16 | if (SUCCEEDED(_orig->CreateQuery(&temp_query_desc, &temp_query)))
17 | {
18 | temp_query->End();
19 | while (temp_query->GetData(nullptr, 0, 0) == S_FALSE)
20 | Sleep(0);
21 | }
22 | #endif
23 | }
24 |
25 | void reshade::d3d10::device_impl::flush_immediate_command_list() const
26 | {
27 | _orig->Flush();
28 | }
29 |
30 | uint64_t reshade::d3d10::device_impl::get_timestamp_frequency() const
31 | {
32 | D3D10_QUERY_DESC temp_query_desc;
33 | temp_query_desc.Query = D3D10_QUERY_TIMESTAMP_DISJOINT;
34 | temp_query_desc.MiscFlags = 0;
35 |
36 | com_ptr temp_query;
37 | if (SUCCEEDED(_orig->CreateQuery(&temp_query_desc, &temp_query)))
38 | {
39 | temp_query->Begin();
40 | temp_query->End();
41 |
42 | D3D10_QUERY_DATA_TIMESTAMP_DISJOINT temp_query_data = {};
43 | while (temp_query->GetData(&temp_query_data, sizeof(temp_query_data), 0) == S_FALSE)
44 | Sleep(1);
45 |
46 | return temp_query_data.Frequency;
47 | }
48 |
49 | return 0;
50 | }
51 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_impl_state_block.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "com_ptr.hpp"
10 |
11 | namespace reshade::d3d10
12 | {
13 | class state_block
14 | {
15 | public:
16 | explicit state_block(com_ptr device);
17 | ~state_block();
18 |
19 | void capture();
20 | void apply_and_release();
21 |
22 | private:
23 | com_ptr _device;
24 | com_ptr _ia_input_layout;
25 | D3D10_PRIMITIVE_TOPOLOGY _ia_primitive_topology = D3D10_PRIMITIVE_TOPOLOGY_UNDEFINED;
26 | com_ptr _ia_vertex_buffers[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
27 | UINT _ia_vertex_strides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {};
28 | UINT _ia_vertex_offsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT] = {};
29 | com_ptr _ia_index_buffer;
30 | DXGI_FORMAT _ia_index_format = DXGI_FORMAT_UNKNOWN;
31 | UINT _ia_index_offset = 0;
32 | com_ptr _vs;
33 | com_ptr _vs_constant_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
34 | com_ptr _vs_sampler_states[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
35 | com_ptr _vs_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
36 | com_ptr _gs;
37 | com_ptr _gs_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
38 | com_ptr _rs_state;
39 | UINT _rs_num_viewports = 0;
40 | D3D10_VIEWPORT _rs_viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = {};
41 | UINT _rs_num_scissor_rects = 0;
42 | D3D10_RECT _rs_scissor_rects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE] = {};
43 | com_ptr _ps;
44 | com_ptr _ps_constant_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
45 | com_ptr _ps_sampler_states[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
46 | com_ptr _ps_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
47 | com_ptr _om_blend_state;
48 | FLOAT _om_blend_factor[4] = { D3D10_DEFAULT_BLEND_FACTOR_RED, D3D10_DEFAULT_BLEND_FACTOR_BLUE, D3D10_DEFAULT_BLEND_FACTOR_GREEN, D3D10_DEFAULT_BLEND_FACTOR_ALPHA };
49 | UINT _om_sample_mask = D3D10_DEFAULT_SAMPLE_MASK;
50 | com_ptr _om_depth_stencil_state;
51 | UINT _om_stencil_ref = D3D10_DEFAULT_STENCIL_REFERENCE;
52 | com_ptr _om_render_targets[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
53 | com_ptr _om_depth_stencil;
54 | };
55 | }
56 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_impl_swapchain.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d10_impl_device.hpp"
7 | #include "d3d10_impl_swapchain.hpp"
8 | #include "d3d10_impl_type_convert.hpp"
9 |
10 | reshade::d3d10::swapchain_impl::swapchain_impl(device_impl *device, IDXGISwapChain *swapchain) :
11 | api_object_impl(swapchain),
12 | _device_impl(device)
13 | {
14 | #ifndef NDEBUG
15 | DXGI_SWAP_CHAIN_DESC swap_desc = {};
16 | _orig->GetDesc(&swap_desc);
17 |
18 | assert(swap_desc.BufferUsage & DXGI_USAGE_RENDER_TARGET_OUTPUT);
19 | #endif
20 | }
21 |
22 | reshade::api::device *reshade::d3d10::swapchain_impl::get_device()
23 | {
24 | return _device_impl;
25 | }
26 |
27 | void *reshade::d3d10::swapchain_impl::get_hwnd() const
28 | {
29 | DXGI_SWAP_CHAIN_DESC swap_desc = {};
30 | _orig->GetDesc(&swap_desc);
31 |
32 | return swap_desc.OutputWindow;
33 | }
34 |
35 | reshade::api::resource reshade::d3d10::swapchain_impl::get_back_buffer(uint32_t index)
36 | {
37 | assert(index == 0);
38 |
39 | com_ptr back_buffer;
40 | _orig->GetBuffer(0, IID_PPV_ARGS(&back_buffer));
41 | assert(back_buffer != nullptr);
42 |
43 | return to_handle(back_buffer.get());
44 | }
45 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade::d3d10
9 | {
10 | class device_impl;
11 |
12 | class swapchain_impl : public api::api_object_impl
13 | {
14 | public:
15 | swapchain_impl(device_impl *device, IDXGISwapChain *swapchain);
16 |
17 | api::device *get_device() final;
18 |
19 | void *get_hwnd() const final;
20 |
21 | api::resource get_back_buffer(uint32_t index = 0) final;
22 |
23 | uint32_t get_back_buffer_count() const final { return 1; }
24 | uint32_t get_current_back_buffer_index() const final { return 0; }
25 |
26 | bool check_color_space_support(api::color_space color_space) const final { return color_space == api::color_space::srgb_nonlinear || color_space == api::color_space::extended_srgb_linear; }
27 |
28 | api::color_space get_color_space() const final { return api::color_space::unknown; }
29 |
30 | private:
31 | device_impl *const _device_impl;
32 | };
33 | }
34 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_resource.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | void STDMETHODCALLTYPE ID3D10Resource_GetDevice(ID3D10Resource *pResource, ID3D10Device **ppDevice);
9 |
10 | #if RESHADE_ADDON >= 2
11 |
12 | HRESULT STDMETHODCALLTYPE ID3D10Buffer_Map(ID3D10Buffer *pResource, D3D10_MAP MapType, UINT MapFlags, void **ppData);
13 | HRESULT STDMETHODCALLTYPE ID3D10Buffer_Unmap(ID3D10Buffer *pResource);
14 |
15 | HRESULT STDMETHODCALLTYPE ID3D10Texture1D_Map(ID3D10Texture1D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, void **ppData);
16 | HRESULT STDMETHODCALLTYPE ID3D10Texture1D_Unmap(ID3D10Texture1D *pResource, UINT Subresource);
17 |
18 | HRESULT STDMETHODCALLTYPE ID3D10Texture2D_Map(ID3D10Texture2D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, D3D10_MAPPED_TEXTURE2D *pMappedTex2D);
19 | HRESULT STDMETHODCALLTYPE ID3D10Texture2D_Unmap(ID3D10Texture2D *pResource, UINT Subresource);
20 |
21 | HRESULT STDMETHODCALLTYPE ID3D10Texture3D_Map(ID3D10Texture3D *pResource, UINT Subresource, D3D10_MAP MapType, UINT MapFlags, D3D10_MAPPED_TEXTURE3D *pMappedTex3D);
22 | HRESULT STDMETHODCALLTYPE ID3D10Texture3D_Unmap(ID3D10Texture3D *pResource, UINT Subresource);
23 |
24 | #endif
25 |
--------------------------------------------------------------------------------
/source/d3d10/d3d10_resource_call_vtable.inl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "hook_manager.hpp"
7 |
8 | #define ID3D10Resource_GetDevice reshade::hooks::call_vtable<3, HRESULT, ID3D10Resource, ID3D10Device **>
9 |
10 | #if RESHADE_ADDON >= 2
11 |
12 | #define ID3D10Buffer_Map reshade::hooks::call_vtable<10, HRESULT, ID3D10Buffer, D3D10_MAP, UINT, void **>
13 | #define ID3D10Buffer_Unmap reshade::hooks::call_vtable<11, HRESULT, ID3D10Buffer>
14 |
15 | #define ID3D10Texture1D_Map reshade::hooks::call_vtable<10, HRESULT, ID3D10Texture1D, UINT, D3D10_MAP, UINT, void **>
16 | #define ID3D10Texture1D_Unmap reshade::hooks::call_vtable<11, HRESULT, ID3D10Texture1D, UINT>
17 |
18 | #define ID3D10Texture2D_Map reshade::hooks::call_vtable<10, HRESULT, ID3D10Texture2D, UINT, D3D10_MAP, UINT, D3D10_MAPPED_TEXTURE2D *>
19 | #define ID3D10Texture2D_Unmap reshade::hooks::call_vtable<11, HRESULT, ID3D10Texture2D, UINT>
20 |
21 | #define ID3D10Texture3D_Map reshade::hooks::call_vtable<10, HRESULT, ID3D10Texture3D, UINT, D3D10_MAP, UINT, D3D10_MAPPED_TEXTURE3D *>
22 | #define ID3D10Texture3D_Unmap reshade::hooks::call_vtable<11, HRESULT, ID3D10Texture3D, UINT>
23 |
24 | #else
25 |
26 | #define ID3D10Buffer_Map(p, a, b, c) (p)->Map(a, b, c)
27 | #define ID3D10Buffer_Unmap(p) (p)->Unmap()
28 |
29 | #define ID3D10Texture1D_Map(p, a, b, c, d) (p)->Map(a, b, c, d)
30 | #define ID3D10Texture1D_Unmap(p, a) (p)->Unmap(a)
31 |
32 | #define ID3D10Texture2D_Map(p, a, b, c, d) (p)->Map(a, b, c, d)
33 | #define ID3D10Texture2D_Unmap(p, a) (p)->Unmap(a)
34 |
35 | #define ID3D10Texture3D_Map(p, a, b, c, d) (p)->Map(a, b, c, d)
36 | #define ID3D10Texture3D_Unmap(p, a) (p)->Unmap(a)
37 |
38 | #endif
39 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_command_list.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "d3d11_device.hpp"
7 | #include "d3d11_command_list.hpp"
8 | #include "dll_log.hpp"
9 | #include "addon_manager.hpp"
10 |
11 | D3D11CommandList::D3D11CommandList(D3D11Device *device, ID3D11CommandList *original) :
12 | command_list_impl(device, original),
13 | _device(device)
14 | {
15 | assert(_orig != nullptr && _device != nullptr);
16 |
17 | #if RESHADE_ADDON
18 | reshade::invoke_addon_event(this);
19 | #endif
20 | }
21 | D3D11CommandList::~D3D11CommandList()
22 | {
23 | #if RESHADE_ADDON
24 | reshade::invoke_addon_event(this);
25 | #endif
26 | }
27 |
28 | bool D3D11CommandList::check_and_upgrade_interface(REFIID riid)
29 | {
30 | if (riid == __uuidof(this) ||
31 | riid == __uuidof(IUnknown) ||
32 | riid == __uuidof(ID3D11DeviceChild) ||
33 | riid == __uuidof(ID3D11CommandList))
34 | return true;
35 |
36 | return false;
37 | }
38 |
39 | HRESULT STDMETHODCALLTYPE D3D11CommandList::QueryInterface(REFIID riid, void **ppvObj)
40 | {
41 | if (ppvObj == nullptr)
42 | return E_POINTER;
43 |
44 | if (check_and_upgrade_interface(riid))
45 | {
46 | AddRef();
47 | *ppvObj = this;
48 | return S_OK;
49 | }
50 |
51 | return _orig->QueryInterface(riid, ppvObj);
52 | }
53 | ULONG STDMETHODCALLTYPE D3D11CommandList::AddRef()
54 | {
55 | _orig->AddRef();
56 | return InterlockedIncrement(&_ref);
57 | }
58 | ULONG STDMETHODCALLTYPE D3D11CommandList::Release()
59 | {
60 | const ULONG ref = InterlockedDecrement(&_ref);
61 | if (ref != 0)
62 | {
63 | _orig->Release();
64 | return ref;
65 | }
66 |
67 | const auto orig = _orig;
68 | #if 0
69 | reshade::log::message(reshade::log::level::debug, "Destroying ID3D11CommandList object %p (%p).", this, orig);
70 | #endif
71 | delete this;
72 |
73 | const ULONG ref_orig = orig->Release();
74 | if (ref_orig != 0) // Verify internal reference count
75 | reshade::log::message(reshade::log::level::warning, "Reference count for ID3D11CommandList object %p (%p) is inconsistent (%lu).", this, orig, ref_orig);
76 | return 0;
77 | }
78 |
79 | void STDMETHODCALLTYPE D3D11CommandList::GetDevice(ID3D11Device **ppDevice)
80 | {
81 | _device->AddRef();
82 | *ppDevice = _device;
83 | }
84 | HRESULT STDMETHODCALLTYPE D3D11CommandList::GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData)
85 | {
86 | return _orig->GetPrivateData(guid, pDataSize, pData);
87 | }
88 | HRESULT STDMETHODCALLTYPE D3D11CommandList::SetPrivateData(REFGUID guid, UINT DataSize, const void *pData)
89 | {
90 | return _orig->SetPrivateData(guid, DataSize, pData);
91 | }
92 | HRESULT STDMETHODCALLTYPE D3D11CommandList::SetPrivateDataInterface(REFGUID guid, const IUnknown *pData)
93 | {
94 | return _orig->SetPrivateDataInterface(guid, pData);
95 | }
96 |
97 | UINT STDMETHODCALLTYPE D3D11CommandList::GetContextFlags()
98 | {
99 | return _orig->GetContextFlags();
100 | }
101 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_command_list.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d11_impl_device_context.hpp"
9 |
10 | struct D3D11Device;
11 |
12 | struct DECLSPEC_UUID("592F5E83-A17B-4EEB-A2BF-7568DA2A3728") D3D11CommandList final : ID3D11CommandList, public reshade::d3d11::command_list_impl
13 | {
14 | D3D11CommandList(D3D11Device *device, ID3D11CommandList *original);
15 | ~D3D11CommandList();
16 |
17 | #pragma region IUnknown
18 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
19 | ULONG STDMETHODCALLTYPE AddRef() override;
20 | ULONG STDMETHODCALLTYPE Release() override;
21 | #pragma endregion
22 | #pragma region ID3D11DeviceChild
23 | void STDMETHODCALLTYPE GetDevice(ID3D11Device **ppDevice) override;
24 | HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData) override;
25 | HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void *pData) override;
26 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown *pData) override;
27 | #pragma endregion
28 | #pragma region ID3D11CommandList
29 | UINT STDMETHODCALLTYPE GetContextFlags() override;
30 | #pragma endregion
31 |
32 | bool check_and_upgrade_interface(REFIID riid);
33 |
34 | ULONG _ref = 1;
35 | D3D11Device *const _device;
36 | };
37 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_impl_swapchain.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d11_impl_device.hpp"
7 | #include "d3d11_impl_swapchain.hpp"
8 | #include "d3d11_impl_type_convert.hpp"
9 |
10 | reshade::d3d11::swapchain_impl::swapchain_impl(device_impl *device, IDXGISwapChain *swapchain) :
11 | api_object_impl(swapchain),
12 | _device_impl(device)
13 | {
14 | }
15 |
16 | reshade::api::device *reshade::d3d11::swapchain_impl::get_device()
17 | {
18 | return _device_impl;
19 | }
20 |
21 | void *reshade::d3d11::swapchain_impl::get_hwnd() const
22 | {
23 | DXGI_SWAP_CHAIN_DESC swap_desc = {};
24 | _orig->GetDesc(&swap_desc);
25 |
26 | return swap_desc.OutputWindow;
27 | }
28 |
29 | reshade::api::resource reshade::d3d11::swapchain_impl::get_back_buffer(uint32_t index)
30 | {
31 | assert(index == 0);
32 |
33 | com_ptr back_buffer;
34 | _orig->GetBuffer(0, IID_PPV_ARGS(&back_buffer));
35 | assert(back_buffer != nullptr);
36 | // Reference is immediately released to make Unreal Engine 4 happy (https://github.com/EpicGames/UnrealEngine/blob/4.7/Engine/Source/Runtime/Windows/D3D11RHI/Private/D3D11Viewport.cpp#L195)
37 |
38 | return to_handle(back_buffer.get());
39 | }
40 |
41 | bool reshade::d3d11::swapchain_impl::check_color_space_support(api::color_space color_space) const
42 | {
43 | if (color_space == api::color_space::unknown)
44 | return false;
45 |
46 | com_ptr swapchain3;
47 | if (FAILED(_orig->QueryInterface(&swapchain3)))
48 | return color_space == api::color_space::srgb_nonlinear;
49 |
50 | UINT support;
51 | return SUCCEEDED(swapchain3->CheckColorSpaceSupport(convert_color_space(color_space), &support)) && (support & DXGI_SWAP_CHAIN_COLOR_SPACE_SUPPORT_FLAG_PRESENT) != 0;
52 | }
53 |
54 | inline constexpr GUID SKID_SwapChainColorSpace = { 0x18b57e4, 0x1493, 0x4953, { 0xad, 0xf2, 0xde, 0x6d, 0x99, 0xcc, 0x5, 0xe5 } };
55 |
56 | reshade::api::color_space reshade::d3d11::swapchain_impl::get_color_space() const
57 | {
58 | DXGI_COLOR_SPACE_TYPE color_space = DXGI_COLOR_SPACE_RGB_FULL_G22_NONE_P709;
59 | UINT color_space_size = sizeof(color_space);
60 | if (FAILED(_orig->GetPrivateData(SKID_SwapChainColorSpace, &color_space_size, &color_space)))
61 | {
62 | DXGI_SWAP_CHAIN_DESC swap_desc = {};
63 | _orig->GetDesc(&swap_desc);
64 |
65 | if (swap_desc.BufferDesc.Format == DXGI_FORMAT_R16G16B16A16_FLOAT)
66 | color_space = DXGI_COLOR_SPACE_RGB_FULL_G10_NONE_P709;
67 | }
68 |
69 | if (color_space == DXGI_COLOR_SPACE_CUSTOM)
70 | return api::color_space::unknown;
71 |
72 | return convert_color_space(color_space);
73 | }
74 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade::d3d11
9 | {
10 | class device_impl;
11 |
12 | class swapchain_impl : public api::api_object_impl
13 | {
14 | public:
15 | swapchain_impl(device_impl *device, IDXGISwapChain *swapchain);
16 |
17 | api::device *get_device() final;
18 |
19 | void *get_hwnd() const final;
20 |
21 | api::resource get_back_buffer(uint32_t index = 0) final;
22 |
23 | uint32_t get_back_buffer_count() const final { return 1; }
24 | uint32_t get_current_back_buffer_index() const final { return 0; }
25 |
26 | bool check_color_space_support(api::color_space color_space) const final;
27 |
28 | api::color_space get_color_space() const final;
29 |
30 | private:
31 | device_impl *const _device_impl;
32 | };
33 | }
34 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_resource.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d11_device.hpp"
7 | #include "d3d11_resource.hpp"
8 | #include "com_utils.hpp"
9 | #include "hook_manager.hpp"
10 |
11 | // Chromium ANGLE checks the device pointer queried from textures, which fails if that is not pointing to the proxy device, causing content to not show up
12 | // See https://chromium.googlesource.com/angle/angle/+/refs/heads/main/src/libANGLE/renderer/d3d/d3d11/Renderer11.cpp#1567
13 | void STDMETHODCALLTYPE ID3D11Resource_GetDevice(ID3D11Resource *pResource, ID3D11Device **ppDevice)
14 | {
15 | reshade::hooks::call(ID3D11Resource_GetDevice, reshade::hooks::vtable_from_instance(pResource) + 3)(pResource, ppDevice);
16 |
17 | const auto device = *ppDevice;
18 | assert(device != nullptr);
19 |
20 | // Do not return proxy device when video support is enabled due to checks performed by the Microsoft Media Foundation library (see also comment in 'D3D11Device::QueryInterface')
21 | if (device->GetCreationFlags() & D3D11_CREATE_DEVICE_VIDEO_SUPPORT)
22 | return;
23 |
24 | const auto device_proxy = get_private_pointer_d3dx(device);
25 | if (device_proxy != nullptr)
26 | {
27 | assert(device != device_proxy);
28 |
29 | *ppDevice = device_proxy;
30 | InterlockedIncrement(&device_proxy->_ref);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_resource.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | void STDMETHODCALLTYPE ID3D11Resource_GetDevice(ID3D11Resource *pResource, ID3D11Device **ppDevice);
9 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11_resource_call_vtable.inl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "hook_manager.hpp"
7 |
8 | #define ID3D11Resource_GetDevice reshade::hooks::call_vtable<3, HRESULT, ID3D11Resource, ID3D11Device **>
9 |
--------------------------------------------------------------------------------
/source/d3d11/d3d11on12_device.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct D3D11Device;
11 | struct D3D12Device;
12 |
13 | struct DECLSPEC_UUID("6BE8CF18-2108-4506-AAA0-AD5A29812A31") D3D11On12Device final : ID3D11On12Device2
14 | {
15 | D3D11On12Device(D3D11Device *device_11, D3D12Device *device_12, ID3D11On12Device *original);
16 | ~D3D11On12Device();
17 |
18 | D3D11On12Device(const D3D11On12Device &) = delete;
19 | D3D11On12Device &operator=(const D3D11On12Device &) = delete;
20 |
21 | #pragma region IUnknown
22 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
23 | ULONG STDMETHODCALLTYPE AddRef() override;
24 | ULONG STDMETHODCALLTYPE Release() override;
25 | #pragma endregion
26 | #pragma region ID3D11On12Device
27 | HRESULT STDMETHODCALLTYPE CreateWrappedResource(IUnknown *pResource12, const D3D11_RESOURCE_FLAGS *pFlags11, D3D12_RESOURCE_STATES InState, D3D12_RESOURCE_STATES OutState, REFIID riid, void **ppResource11) override;
28 | void STDMETHODCALLTYPE ReleaseWrappedResources(ID3D11Resource *const *ppResources, UINT NumResources) override;
29 | void STDMETHODCALLTYPE AcquireWrappedResources(ID3D11Resource *const *ppResources, UINT NumResources) override;
30 | #pragma endregion
31 | #pragma region ID3D11On12Device1
32 | HRESULT STDMETHODCALLTYPE GetD3D12Device(REFIID riid, void **ppvDevice) override;
33 | #pragma endregion
34 | #pragma region ID3D11On12Device2
35 | HRESULT STDMETHODCALLTYPE UnwrapUnderlyingResource(ID3D11Resource *pResource11, ID3D12CommandQueue *pCommandQueue, REFIID riid, void **ppvResource12) override;
36 | HRESULT STDMETHODCALLTYPE ReturnUnderlyingResource(ID3D11Resource *pResource11, UINT NumSync, UINT64 *pSignalValues, ID3D12Fence **ppFences) override;
37 | #pragma endregion
38 |
39 | bool check_and_upgrade_interface(REFIID riid);
40 |
41 | ID3D11On12Device *_orig;
42 | unsigned short _interface_version;
43 |
44 | D3D11Device *const _parent_device_11;
45 | D3D12Device *const _parent_device_12;
46 | };
47 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_command_queue.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d12_impl_command_queue.hpp"
9 |
10 | struct D3D12Device;
11 | struct D3D12CommandQueueDownlevel;
12 |
13 | struct DECLSPEC_UUID("2C576D2A-0C1C-4D1D-AD7C-BC4FAEC15ABC") D3D12CommandQueue final : ID3D12CommandQueue, public reshade::d3d12::command_queue_impl
14 | {
15 | D3D12CommandQueue(D3D12Device *device, ID3D12CommandQueue *original);
16 | ~D3D12CommandQueue();
17 |
18 | #pragma region IUnknown
19 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
20 | ULONG STDMETHODCALLTYPE AddRef() override;
21 | ULONG STDMETHODCALLTYPE Release() override;
22 | #pragma endregion
23 | #pragma region ID3D12Object
24 | HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData) override;
25 | HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void *pData) override;
26 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown *pData) override;
27 | HRESULT STDMETHODCALLTYPE SetName(LPCWSTR Name) override;
28 | #pragma endregion
29 | #pragma region ID3D12DeviceChild
30 | HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppvDevice) override;
31 | #pragma endregion
32 | #pragma region ID3D12CommandQueue
33 | void STDMETHODCALLTYPE UpdateTileMappings(ID3D12Resource *pResource, UINT NumResourceRegions, const D3D12_TILED_RESOURCE_COORDINATE *pResourceRegionStartCoordinates, const D3D12_TILE_REGION_SIZE *pResourceRegionSizes, ID3D12Heap *pHeap, UINT NumRanges, const D3D12_TILE_RANGE_FLAGS *pRangeFlags, const UINT *pHeapRangeStartOffsets, const UINT *pRangeTileCounts, D3D12_TILE_MAPPING_FLAGS Flags) override;
34 | void STDMETHODCALLTYPE CopyTileMappings(ID3D12Resource *pDstResource, const D3D12_TILED_RESOURCE_COORDINATE *pDstRegionStartCoordinate, ID3D12Resource *pSrcResource, const D3D12_TILED_RESOURCE_COORDINATE *pSrcRegionStartCoordinate, const D3D12_TILE_REGION_SIZE *pRegionSize, D3D12_TILE_MAPPING_FLAGS Flags) override;
35 | void STDMETHODCALLTYPE ExecuteCommandLists(UINT NumCommandLists, ID3D12CommandList *const *ppCommandLists) override;
36 | void STDMETHODCALLTYPE SetMarker(UINT Metadata, const void *pData, UINT Size) override;
37 | void STDMETHODCALLTYPE BeginEvent(UINT Metadata, const void *pData, UINT Size) override;
38 | void STDMETHODCALLTYPE EndEvent() override;
39 | HRESULT STDMETHODCALLTYPE Signal(ID3D12Fence *pFence, UINT64 Value) override;
40 | HRESULT STDMETHODCALLTYPE Wait(ID3D12Fence *pFence, UINT64 Value) override;
41 | HRESULT STDMETHODCALLTYPE GetTimestampFrequency(UINT64 *pFrequency) override;
42 | HRESULT STDMETHODCALLTYPE GetClockCalibration(UINT64 *pGpuTimestamp, UINT64 *pCpuTimestamp) override;
43 | D3D12_COMMAND_QUEUE_DESC STDMETHODCALLTYPE GetDesc() override;
44 | #pragma endregion
45 |
46 | bool check_and_upgrade_interface(REFIID riid);
47 |
48 | ULONG _ref = 1;
49 | unsigned short _interface_version = 0;
50 | D3D12Device *const _device;
51 | D3D12CommandQueueDownlevel *_downlevel = nullptr;
52 | };
53 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_command_queue_downlevel.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "d3d12_impl_swapchain.hpp"
10 |
11 | struct D3D12CommandQueue;
12 |
13 | struct DECLSPEC_UUID("98CF28C0-F383-487E-A61E-3A638FEE29BD") D3D12CommandQueueDownlevel final : ID3D12CommandQueueDownlevel, public reshade::d3d12::swapchain_d3d12on7_impl
14 | {
15 | D3D12CommandQueueDownlevel(D3D12CommandQueue *queue, ID3D12CommandQueueDownlevel *original);
16 | ~D3D12CommandQueueDownlevel();
17 |
18 | D3D12CommandQueueDownlevel(const D3D12CommandQueueDownlevel &) = delete;
19 | D3D12CommandQueueDownlevel &operator=(const D3D12CommandQueueDownlevel &) = delete;
20 |
21 | #pragma region IUnknown
22 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
23 | ULONG STDMETHODCALLTYPE AddRef() override;
24 | ULONG STDMETHODCALLTYPE Release() override;
25 | #pragma endregion
26 | #pragma region ID3D12CommandQueueDownlevel
27 | HRESULT STDMETHODCALLTYPE Present(ID3D12GraphicsCommandList *pOpenCommandList, ID3D12Resource *pSourceTex2D, HWND hWindow, D3D12_DOWNLEVEL_PRESENT_FLAGS Flags) override;
28 | #pragma endregion
29 |
30 | D3D12CommandQueue *const _parent_queue;
31 | };
32 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_descriptor_heap.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #if RESHADE_ADDON >= 2
7 |
8 | #include "d3d12_device.hpp"
9 | #include "d3d12_descriptor_heap.hpp"
10 | #include "dll_log.hpp"
11 |
12 | D3D12DescriptorHeap::D3D12DescriptorHeap(ID3D12Device *device, ID3D12DescriptorHeap *original) :
13 | _orig(original),
14 | _device(device)
15 | {
16 | assert(_orig != nullptr && _device != nullptr);
17 | }
18 |
19 | bool D3D12DescriptorHeap::check_and_upgrade_interface(REFIID riid)
20 | {
21 | if (riid == __uuidof(this) ||
22 | riid == __uuidof(IUnknown) || // This is the IID_IUnknown identity object
23 | riid == __uuidof(ID3D12Object) ||
24 | riid == __uuidof(ID3D12DeviceChild) ||
25 | riid == __uuidof(ID3D12Pageable) ||
26 | riid == __uuidof(ID3D12DescriptorHeap))
27 | return true;
28 |
29 | return false;
30 | }
31 |
32 | HRESULT STDMETHODCALLTYPE D3D12DescriptorHeap::QueryInterface(REFIID riid, void **ppvObj)
33 | {
34 | if (ppvObj == nullptr)
35 | return E_POINTER;
36 |
37 | if (check_and_upgrade_interface(riid))
38 | {
39 | AddRef();
40 | *ppvObj = this;
41 | return S_OK;
42 | }
43 |
44 | return _orig->QueryInterface(riid, ppvObj);
45 | }
46 | ULONG STDMETHODCALLTYPE D3D12DescriptorHeap::AddRef()
47 | {
48 | _orig->AddRef();
49 | return InterlockedIncrement(&_ref);
50 | }
51 | ULONG STDMETHODCALLTYPE D3D12DescriptorHeap::Release()
52 | {
53 | const ULONG ref = InterlockedDecrement(&_ref);
54 | if (ref != 0)
55 | {
56 | _orig->Release();
57 | return ref;
58 | }
59 |
60 | const auto orig = _orig;
61 | #if 0
62 | reshade::log::message(reshade::log::level::debug, "Destroying ID3D12DescriptorHeap object %p (%p).", this, orig);
63 | #endif
64 | delete this;
65 |
66 | const ULONG ref_orig = orig->Release();
67 | if (ref_orig != 0) // Verify internal reference count
68 | reshade::log::message(reshade::log::level::warning, "Reference count for ID3D12DescriptorHeap object %p (%p) is inconsistent (%lu).", this, orig, ref_orig);
69 | return 0;
70 | }
71 |
72 | HRESULT STDMETHODCALLTYPE D3D12DescriptorHeap::GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData)
73 | {
74 | return _orig->GetPrivateData(guid, pDataSize, pData);
75 | }
76 | HRESULT STDMETHODCALLTYPE D3D12DescriptorHeap::SetPrivateData(REFGUID guid, UINT DataSize, const void *pData)
77 | {
78 | return _orig->SetPrivateData(guid, DataSize, pData);
79 | }
80 | HRESULT STDMETHODCALLTYPE D3D12DescriptorHeap::SetPrivateDataInterface(REFGUID guid, const IUnknown *pData)
81 | {
82 | return _orig->SetPrivateDataInterface(guid, pData);
83 | }
84 | HRESULT STDMETHODCALLTYPE D3D12DescriptorHeap::SetName(LPCWSTR Name)
85 | {
86 | return _orig->SetName(Name);
87 | }
88 |
89 | HRESULT STDMETHODCALLTYPE D3D12DescriptorHeap::GetDevice(REFIID riid, void **ppvDevice)
90 | {
91 | return _device->QueryInterface(riid, ppvDevice);
92 | }
93 |
94 | D3D12_DESCRIPTOR_HEAP_DESC STDMETHODCALLTYPE D3D12DescriptorHeap::GetDesc()
95 | {
96 | return _orig->GetDesc();
97 | }
98 | D3D12_CPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE D3D12DescriptorHeap::GetCPUDescriptorHandleForHeapStart()
99 | {
100 | assert(_internal_base_cpu_handle.ptr != 0);
101 | return _internal_base_cpu_handle;
102 | }
103 | D3D12_GPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE D3D12DescriptorHeap::GetGPUDescriptorHandleForHeapStart()
104 | {
105 | return _orig->GetGPUDescriptorHandleForHeapStart();
106 | }
107 |
108 | #endif
109 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_descriptor_heap.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #if RESHADE_ADDON >= 2
9 |
10 | struct D3D12Device;
11 |
12 | struct DECLSPEC_UUID("8628AD68-6047-4D27-9D87-3E5F386E0231") D3D12DescriptorHeap final : ID3D12DescriptorHeap
13 | {
14 | D3D12DescriptorHeap(ID3D12Device *device, ID3D12DescriptorHeap *original);
15 |
16 | #pragma region IUnknown
17 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
18 | ULONG STDMETHODCALLTYPE AddRef() override;
19 | ULONG STDMETHODCALLTYPE Release() override;
20 | #pragma endregion
21 | #pragma region ID3D12Object
22 | HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID guid, UINT *pDataSize, void *pData) override;
23 | HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID guid, UINT DataSize, const void *pData) override;
24 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID guid, const IUnknown *pData) override;
25 | HRESULT STDMETHODCALLTYPE SetName(LPCWSTR Name) override;
26 | #pragma endregion
27 | #pragma region ID3D12DeviceChild
28 | HRESULT STDMETHODCALLTYPE GetDevice(REFIID riid, void **ppvDevice) override;
29 | #pragma endregion
30 | #pragma region ID3D12DescriptorHeap
31 | D3D12_DESCRIPTOR_HEAP_DESC STDMETHODCALLTYPE GetDesc() override;
32 | D3D12_CPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE GetCPUDescriptorHandleForHeapStart() override;
33 | D3D12_GPU_DESCRIPTOR_HANDLE STDMETHODCALLTYPE GetGPUDescriptorHandleForHeapStart() override;
34 | #pragma endregion
35 |
36 | bool check_and_upgrade_interface(REFIID riid);
37 |
38 | void initialize_descriptor_base_handle(size_t heap_index);
39 |
40 | ID3D12DescriptorHeap *const _orig;
41 | ULONG _ref = 1;
42 | ID3D12Device *const _device;
43 |
44 | D3D12_CPU_DESCRIPTOR_HANDLE _orig_base_cpu_handle = { 0 };
45 | D3D12_GPU_DESCRIPTOR_HANDLE _orig_base_gpu_handle = { 0 };
46 | D3D12_CPU_DESCRIPTOR_HANDLE _internal_base_cpu_handle = { 0 };
47 | };
48 |
49 | #endif
50 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_device_downlevel.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "d3d12_device.hpp"
7 | #include "d3d12_device_downlevel.hpp"
8 |
9 | D3D12DeviceDownlevel::D3D12DeviceDownlevel(D3D12Device *device, ID3D12DeviceDownlevel *original) :
10 | _orig(original),
11 | _parent_device(device)
12 | {
13 | assert(_orig != nullptr && _parent_device != nullptr);
14 | }
15 |
16 | HRESULT STDMETHODCALLTYPE D3D12DeviceDownlevel::QueryInterface(REFIID riid, void **ppvObj)
17 | {
18 | if (ppvObj == nullptr)
19 | return E_POINTER;
20 |
21 | // IUnknown is handled by D3D12Device
22 | if (riid == __uuidof(this) ||
23 | riid == __uuidof(ID3D12DeviceDownlevel))
24 | {
25 | AddRef();
26 | *ppvObj = this;
27 | return S_OK;
28 | }
29 |
30 | return _parent_device->QueryInterface(riid, ppvObj);
31 | }
32 | ULONG STDMETHODCALLTYPE D3D12DeviceDownlevel::AddRef()
33 | {
34 | return _parent_device->AddRef();
35 | }
36 | ULONG STDMETHODCALLTYPE D3D12DeviceDownlevel::Release()
37 | {
38 | return _parent_device->Release();
39 | }
40 |
41 | HRESULT STDMETHODCALLTYPE D3D12DeviceDownlevel::QueryVideoMemoryInfo(UINT NodeIndex, DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup, DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo)
42 | {
43 | return _orig->QueryVideoMemoryInfo(NodeIndex, MemorySegmentGroup, pVideoMemoryInfo);
44 | }
45 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_device_downlevel.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct D3D12Device;
11 |
12 | struct DECLSPEC_UUID("918B5021-E085-430C-BA85-D9C0EFE6FAA0") D3D12DeviceDownlevel final : ID3D12DeviceDownlevel
13 | {
14 | D3D12DeviceDownlevel(D3D12Device *device, ID3D12DeviceDownlevel *original);
15 |
16 | D3D12DeviceDownlevel(const D3D12DeviceDownlevel &) = delete;
17 | D3D12DeviceDownlevel &operator=(const D3D12DeviceDownlevel &) = delete;
18 |
19 | #pragma region IUnknown
20 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
21 | ULONG STDMETHODCALLTYPE AddRef() override;
22 | ULONG STDMETHODCALLTYPE Release() override;
23 | #pragma endregion
24 | #pragma region ID3D12DeviceDownlevel
25 | HRESULT STDMETHODCALLTYPE QueryVideoMemoryInfo(UINT NodeIndex, DXGI_MEMORY_SEGMENT_GROUP MemorySegmentGroup, DXGI_QUERY_VIDEO_MEMORY_INFO *pVideoMemoryInfo) override;
26 | #pragma endregion
27 |
28 | ID3D12DeviceDownlevel *const _orig;
29 | D3D12Device *const _parent_device;
30 | };
31 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_impl_command_list_immediate.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d12_impl_command_list.hpp"
9 |
10 | namespace reshade::d3d12
11 | {
12 | class command_list_immediate_impl : public command_list_impl
13 | {
14 | static constexpr uint32_t NUM_COMMAND_FRAMES = 4; // Use power of two so that modulo can be replaced with bitwise operation
15 |
16 | public:
17 | static thread_local command_list_immediate_impl *s_last_immediate_command_list;
18 |
19 | command_list_immediate_impl(device_impl *device, ID3D12CommandQueue *queue);
20 | ~command_list_immediate_impl();
21 |
22 | void end_query(api::query_heap heap, api::query_type type, uint32_t index) final;
23 | void query_acceleration_structures(uint32_t count, const api::resource_view *acceleration_structures, api::query_heap heap, api::query_type type, uint32_t first) final;
24 |
25 | bool flush();
26 | bool flush_and_wait();
27 |
28 | private:
29 | ID3D12CommandQueue *const _parent_queue;
30 | UINT32 _cmd_index = 0;
31 | HANDLE _fence_event = nullptr;
32 | UINT64 _fence_value[NUM_COMMAND_FRAMES] = {};
33 | com_ptr _fence[NUM_COMMAND_FRAMES];
34 | com_ptr _cmd_alloc[NUM_COMMAND_FRAMES];
35 |
36 | // List of query fences scheduled for signaling during next flush
37 | std::vector> _current_query_fences;
38 | };
39 | }
40 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_impl_command_queue.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d12_impl_command_list_immediate.hpp"
9 | #include
10 |
11 | namespace reshade::d3d12
12 | {
13 | class command_queue_impl : public api::api_object_impl
14 | {
15 | public:
16 | command_queue_impl(device_impl *device, ID3D12CommandQueue *queue);
17 | ~command_queue_impl();
18 |
19 | api::device *get_device() final;
20 |
21 | api::command_queue_type get_type() const final;
22 |
23 | void wait_idle() const final;
24 |
25 | void flush_immediate_command_list() const final;
26 |
27 | api::command_list *get_immediate_command_list() final { return _immediate_cmd_list; }
28 |
29 | void begin_debug_event(const char *label, const float color[4]) final;
30 | void end_debug_event() final;
31 | void insert_debug_marker(const char *label, const float color[4]) final;
32 |
33 | bool wait(api::fence fence, uint64_t value) final;
34 | bool signal(api::fence fence, uint64_t value) final;
35 |
36 | uint64_t get_timestamp_frequency() const final;
37 |
38 | // 'ID3D12CommandQueue' is thread-safe, so need to lock when accessed from multiple threads
39 | std::recursive_mutex _mutex;
40 |
41 | private:
42 | device_impl *const _device_impl;
43 | command_list_immediate_impl *_immediate_cmd_list = nullptr;
44 |
45 | HANDLE _wait_idle_fence_event = nullptr;
46 | mutable UINT64 _wait_idle_fence_value = 0;
47 | com_ptr _wait_idle_fence;
48 | };
49 | }
50 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct ID3D12CommandQueueDownlevel;
11 |
12 | namespace reshade::d3d12
13 | {
14 | class device_impl;
15 |
16 | class swapchain_impl : public api::api_object_impl
17 | {
18 | public:
19 | swapchain_impl(device_impl *device, IDXGISwapChain3 *swapchain);
20 |
21 | api::device *get_device() final;
22 |
23 | void *get_hwnd() const final;
24 |
25 | api::resource get_back_buffer(uint32_t index) final;
26 |
27 | uint32_t get_back_buffer_count() const final;
28 | uint32_t get_current_back_buffer_index() const final;
29 |
30 | bool check_color_space_support(api::color_space color_space) const final;
31 |
32 | api::color_space get_color_space() const final;
33 |
34 | private:
35 | device_impl *const _device_impl;
36 | };
37 |
38 | class swapchain_d3d12on7_impl : public api::api_object_impl
39 | {
40 | public:
41 | swapchain_d3d12on7_impl(device_impl *device, ID3D12CommandQueueDownlevel *command_queue_downlevel);
42 |
43 | api::device *get_device() final;
44 |
45 | void *get_hwnd() const final;
46 |
47 | api::resource get_back_buffer(uint32_t index) final;
48 |
49 | uint32_t get_back_buffer_count() const final;
50 | uint32_t get_current_back_buffer_index() const final;
51 |
52 | bool check_color_space_support(api::color_space color_space) const final { return color_space == api::color_space::srgb_nonlinear || color_space == api::color_space::extended_srgb_linear; }
53 |
54 | api::color_space get_color_space() const final { return api::color_space::unknown; }
55 |
56 | private:
57 | device_impl *const _device_impl;
58 |
59 | protected:
60 | std::vector> _back_buffers;
61 | HWND _hwnd = nullptr;
62 | UINT _swap_index = 0;
63 | };
64 | }
65 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_pipeline_library.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #if RESHADE_ADDON >= 2
9 |
10 | extern thread_local bool g_in_d3d12_pipeline_creation;
11 |
12 | HRESULT STDMETHODCALLTYPE ID3D12PipelineLibrary_LoadGraphicsPipeline(ID3D12PipelineLibrary *pPipelineLibrary, LPCWSTR pName, const D3D12_GRAPHICS_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState);
13 | HRESULT STDMETHODCALLTYPE ID3D12PipelineLibrary_LoadComputePipeline(ID3D12PipelineLibrary *pPipelineLibrary, LPCWSTR pName, const D3D12_COMPUTE_PIPELINE_STATE_DESC *pDesc, REFIID riid, void **ppPipelineState);
14 |
15 | HRESULT STDMETHODCALLTYPE ID3D12PipelineLibrary1_LoadPipeline(ID3D12PipelineLibrary1 *pPipelineLibrary, LPCWSTR pName, const D3D12_PIPELINE_STATE_STREAM_DESC *pDesc, REFIID riid, void **ppPipelineState);
16 |
17 | #endif
18 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_pix.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "hook_manager.hpp"
7 | #include
8 | #include
9 |
10 | // The following hooks can only be called when installed as d3d12.dll, since they are skipped otherwise (see hook_manager.cpp)
11 | // Therefore can assume that the export module handle points toward the system d3d12.dll
12 | extern HMODULE g_export_module_handle;
13 |
14 | extern "C" UINT64 WINAPI D3D12PIXEventsReplaceBlock(UINT64 *pUnknown1, UINT64 Unknown2)
15 | {
16 | reshade::hooks::ensure_export_module_loaded();
17 | assert(g_export_module_handle != nullptr);
18 |
19 | const FARPROC proc = GetProcAddress(g_export_module_handle, "D3D12PIXEventsReplaceBlock");
20 | if (proc != nullptr)
21 | return reinterpret_cast(proc)(pUnknown1, Unknown2);
22 | else
23 | return 0;
24 | }
25 |
26 | extern "C" LPVOID WINAPI D3D12PIXGetThreadInfo(UINT64 Unknown1, UINT64 Unknown2)
27 | {
28 | reshade::hooks::ensure_export_module_loaded();
29 | assert(g_export_module_handle != nullptr);
30 |
31 | const FARPROC proc = GetProcAddress(g_export_module_handle, "D3D12PIXGetThreadInfo");
32 | if (proc != nullptr)
33 | return reinterpret_cast(proc)(Unknown1, Unknown2);
34 | else
35 | return nullptr;
36 | }
37 |
38 | extern "C" void WINAPI D3D12PIXNotifyWakeFromFenceSignal(UINT64 Unknown1, UINT64 Unknown2)
39 | {
40 | reshade::hooks::ensure_export_module_loaded();
41 | assert(g_export_module_handle != nullptr);
42 |
43 | const FARPROC proc = GetProcAddress(g_export_module_handle, "D3D12PIXNotifyWakeFromFenceSignal");
44 | if (proc != nullptr)
45 | reinterpret_cast(proc)(Unknown1, Unknown2);
46 | }
47 |
48 | extern "C" void WINAPI D3D12PIXReportCounter(UINT64 Unknown1, UINT64 Unknown2, LPCWSTR Unknown3, UINT64 Unknown4, UINT64 Unknown5)
49 | {
50 | reshade::hooks::ensure_export_module_loaded();
51 | assert(g_export_module_handle != nullptr);
52 |
53 | const FARPROC proc = GetProcAddress(g_export_module_handle, "D3D12PIXReportCounter");
54 | if (proc != nullptr)
55 | reinterpret_cast(proc)(Unknown1, Unknown2, Unknown3, Unknown4, Unknown5);
56 | }
57 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_resource.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | HRESULT STDMETHODCALLTYPE ID3D12Resource_GetDevice(ID3D12Resource *pResource, REFIID riid, void **ppvDevice);
9 |
10 | #if RESHADE_ADDON >= 2
11 |
12 | HRESULT STDMETHODCALLTYPE ID3D12Resource_Map(ID3D12Resource *pResource, UINT Subresource, const D3D12_RANGE *pReadRange, void **ppData);
13 | HRESULT STDMETHODCALLTYPE ID3D12Resource_Unmap(ID3D12Resource *pResource, UINT Subresource, const D3D12_RANGE *pWrittenRange);
14 |
15 | #endif
16 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_resource_call_vtable.inl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "hook_manager.hpp"
7 |
8 | #define ID3D12Resource_GetDevice reshade::hooks::call_vtable<7, HRESULT, ID3D12Resource, REFIID, void **>
9 |
10 | #if RESHADE_ADDON >= 2
11 |
12 | #define ID3D12Resource_Map reshade::hooks::call_vtable<8, HRESULT, ID3D12Resource, UINT, const D3D12_RANGE *, void **>
13 | #define ID3D12Resource_Unmap reshade::hooks::call_vtable<9, void, ID3D12Resource, UINT, const D3D12_RANGE *>
14 |
15 | #else
16 |
17 | #define ID3D12Resource_Map(p, a, b, c) (p)->Map(a, b, c)
18 | #define ID3D12Resource_Unmap(p, a, b) (p)->Unmap(a, b)
19 |
20 | #endif
21 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_impl_command_queue.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d9_impl_device.hpp"
7 |
8 | void reshade::d3d9::device_impl::wait_idle() const
9 | {
10 | com_ptr temp_query;
11 | if (SUCCEEDED(_orig->CreateQuery(D3DQUERYTYPE_EVENT, &temp_query)))
12 | {
13 | temp_query->Issue(D3DISSUE_END);
14 | while (temp_query->GetData(nullptr, 0, D3DGETDATA_FLUSH) == S_FALSE)
15 | Sleep(0);
16 | }
17 | }
18 |
19 | void reshade::d3d9::device_impl::flush_immediate_command_list() const
20 | {
21 | com_ptr temp_query;
22 | if (SUCCEEDED(_orig->CreateQuery(D3DQUERYTYPE_EVENT, &temp_query)))
23 | {
24 | temp_query->Issue(D3DISSUE_END);
25 | temp_query->GetData(nullptr, 0, D3DGETDATA_FLUSH);
26 | }
27 | }
28 |
29 | uint64_t reshade::d3d9::device_impl::get_timestamp_frequency() const
30 | {
31 | com_ptr temp_query;
32 | if (SUCCEEDED(_orig->CreateQuery(D3DQUERYTYPE_TIMESTAMPFREQ, &temp_query)))
33 | {
34 | temp_query->Issue(D3DISSUE_END);
35 |
36 | UINT64 frequency = 0;
37 | while (temp_query->GetData(&frequency, sizeof(frequency), D3DGETDATA_FLUSH) == S_FALSE)
38 | Sleep(1);
39 |
40 | return frequency;
41 | }
42 |
43 | return 0;
44 | }
45 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_impl_state_block.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d9_impl_state_block.hpp"
7 |
8 | reshade::d3d9::state_block::state_block(IDirect3DDevice9 *device) :
9 | _device(device)
10 | {
11 | #ifdef RESHADE_TEST_APPLICATION
12 | // Avoid errors from the D3D9 debug runtime because the other slots return D3DERR_NOTFOUND with the test application
13 | _num_simultaneous_rts = 1;
14 | #else
15 | D3DCAPS9 caps;
16 | _device->GetDeviceCaps(&caps);
17 | _num_simultaneous_rts = caps.NumSimultaneousRTs;
18 | if (_num_simultaneous_rts > ARRAYSIZE(_render_targets))
19 | _num_simultaneous_rts = ARRAYSIZE(_render_targets);
20 | #endif
21 |
22 | D3DDEVICE_CREATION_PARAMETERS cp = {};
23 | device->GetCreationParameters(&cp);
24 | _vertex_processing = cp.BehaviorFlags & (D3DCREATE_SOFTWARE_VERTEXPROCESSING | D3DCREATE_HARDWARE_VERTEXPROCESSING | D3DCREATE_MIXED_VERTEXPROCESSING);
25 | }
26 | reshade::d3d9::state_block::~state_block()
27 | {
28 | }
29 |
30 | void reshade::d3d9::state_block::capture()
31 | {
32 | assert(_state_block == nullptr);
33 |
34 | if (SUCCEEDED(_device->CreateStateBlock(D3DSBT_ALL, &_state_block)))
35 | _state_block->Capture();
36 | else
37 | assert(false);
38 |
39 | _device->GetViewport(&_viewport);
40 |
41 | for (DWORD target = 0; target < _num_simultaneous_rts; target++)
42 | _device->GetRenderTarget(target, &_render_targets[target]);
43 | _device->GetDepthStencilSurface(&_depth_stencil);
44 |
45 | _device->GetRenderState(D3DRS_SRGBWRITEENABLE, &_srgb_write);
46 | _device->GetSamplerState(0, D3DSAMP_SRGBTEXTURE, &_srgb_texture);
47 |
48 | if (0 != (_vertex_processing & D3DCREATE_MIXED_VERTEXPROCESSING))
49 | {
50 | _vertex_processing |= _device->GetSoftwareVertexProcessing();
51 | _device->SetSoftwareVertexProcessing(FALSE); // Disable software vertex processing since it is incompatible with programmable shaders
52 | }
53 | }
54 | void reshade::d3d9::state_block::apply_and_release()
55 | {
56 | if (_state_block != nullptr)
57 | _state_block->Apply();
58 |
59 | // Release state block every time, so that all references to captured vertex and index buffers, textures, etc. are released again
60 | _state_block.reset();
61 |
62 | if (0 != (_vertex_processing & D3DCREATE_MIXED_VERTEXPROCESSING))
63 | {
64 | _device->SetSoftwareVertexProcessing(_vertex_processing & (TRUE | FALSE));
65 | _vertex_processing &= ~(TRUE | FALSE);
66 | }
67 |
68 | // This should technically be captured and applied by the state block already ...
69 | // But Steam overlay messes it up somehow and this is neceesary to fix the screen darkening in Portal when the Steam overlay is showing a notification popup and the ReShade overlay is open at the same time
70 | _device->SetRenderState(D3DRS_SRGBWRITEENABLE, _srgb_write);
71 | _device->SetSamplerState(0, D3DSAMP_SRGBTEXTURE, _srgb_texture);
72 |
73 | for (DWORD i = 0; i < _num_simultaneous_rts; i++)
74 | _device->SetRenderTarget(i, _render_targets[i].get());
75 | _device->SetDepthStencilSurface(_depth_stencil.get());
76 |
77 | // Set viewport after render targets have been set, since 'SetRenderTarget' causes the viewport to be set to the full size of the render target
78 | _device->SetViewport(&_viewport);
79 |
80 | for (auto &render_target : _render_targets)
81 | render_target.reset();
82 | _depth_stencil.reset();
83 | }
84 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_impl_state_block.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "com_ptr.hpp"
10 |
11 | namespace reshade::d3d9
12 | {
13 | class state_block
14 | {
15 | public:
16 | explicit state_block(IDirect3DDevice9 *device);
17 | ~state_block();
18 |
19 | void capture();
20 | void apply_and_release();
21 |
22 | private:
23 | com_ptr _device;
24 | com_ptr _state_block;
25 | UINT _num_simultaneous_rts;
26 | D3DVIEWPORT9 _viewport = {};
27 | com_ptr _render_targets[8];
28 | com_ptr _depth_stencil;
29 | DWORD _srgb_write = FALSE;
30 | DWORD _srgb_texture = FALSE;
31 | DWORD _vertex_processing = 0;
32 | };
33 | }
34 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_impl_swapchain.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "d3d9_impl_device.hpp"
7 | #include "d3d9_impl_swapchain.hpp"
8 | #include "d3d9_impl_type_convert.hpp"
9 |
10 | reshade::d3d9::swapchain_impl::swapchain_impl(device_impl *device, IDirect3DSwapChain9 *swapchain) :
11 | api_object_impl(swapchain),
12 | _device_impl(device)
13 | {
14 | }
15 |
16 | reshade::api::device *reshade::d3d9::swapchain_impl::get_device()
17 | {
18 | return _device_impl;
19 | }
20 |
21 | void *reshade::d3d9::swapchain_impl::get_hwnd() const
22 | {
23 | // Destination window may be temporarily overriden by 'hDestWindowOverride' parameter during present call
24 | if (_hwnd != nullptr)
25 | return _hwnd;
26 |
27 | // Always retrieve present parameters from device, since the application may have set 'hDeviceWindow' to zero and instead used 'hFocusWindow' (e.g. Resident Evil 4)
28 | // Retrieving them from the device ensures that 'hDeviceWindow' is always set (with either the original value from 'hDeviceWindow' or 'hFocusWindow')
29 | D3DPRESENT_PARAMETERS pp = {};
30 | _orig->GetPresentParameters(&pp);
31 | assert(pp.hDeviceWindow != nullptr);
32 |
33 | return pp.hDeviceWindow;
34 | }
35 |
36 | reshade::api::resource reshade::d3d9::swapchain_impl::get_back_buffer(uint32_t index)
37 | {
38 | assert(index == 0);
39 |
40 | if (_back_buffer == nullptr)
41 | _orig->GetBackBuffer(0, D3DBACKBUFFER_TYPE_MONO, &_back_buffer);
42 | assert(_back_buffer != nullptr);
43 |
44 | return to_handle(static_cast(_back_buffer.get()));
45 | }
46 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade::d3d9
9 | {
10 | class device_impl;
11 |
12 | class swapchain_impl : public api::api_object_impl
13 | {
14 | public:
15 | swapchain_impl(device_impl *device, IDirect3DSwapChain9 *swapchain);
16 |
17 | api::device *get_device() final;
18 |
19 | void *get_hwnd() const final;
20 |
21 | api::resource get_back_buffer(uint32_t index = 0) final;
22 |
23 | uint32_t get_back_buffer_count() const final { return 1; }
24 | uint32_t get_current_back_buffer_index() const final { return 0; }
25 |
26 | bool check_color_space_support(api::color_space color_space) const final { return color_space == api::color_space::srgb_nonlinear || color_space == api::color_space::extended_srgb_linear; }
27 |
28 | api::color_space get_color_space() const final { return api::color_space::unknown; }
29 |
30 | private:
31 | device_impl *const _device_impl;
32 |
33 | protected:
34 | com_ptr _back_buffer;
35 | HWND _hwnd = nullptr;
36 | };
37 | }
38 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_pix.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "hook_manager.hpp"
7 | #include
8 | #include
9 |
10 | extern "C" int WINAPI D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName)
11 | {
12 | #ifndef NDEBUG
13 | static const auto trampoline = reshade::hooks::call(D3DPERF_BeginEvent);
14 | if (trampoline == nullptr)
15 | return 0;
16 | return trampoline(col, wszName);
17 | #else
18 | UNREFERENCED_PARAMETER(col);
19 | UNREFERENCED_PARAMETER(wszName);
20 |
21 | return 0;
22 | #endif
23 | }
24 | extern "C" int WINAPI D3DPERF_EndEvent()
25 | {
26 | #ifndef NDEBUG
27 | static const auto trampoline = reshade::hooks::call(D3DPERF_EndEvent);
28 | if (trampoline == nullptr)
29 | return 0;
30 | return trampoline();
31 | #else
32 | return 0;
33 | #endif
34 | }
35 |
36 | extern "C" void WINAPI D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName)
37 | {
38 | #ifndef NDEBUG
39 | static const auto trampoline = reshade::hooks::call(D3DPERF_SetMarker);
40 | if (trampoline == nullptr)
41 | return;
42 | trampoline(col, wszName);
43 | #else
44 | UNREFERENCED_PARAMETER(col);
45 | UNREFERENCED_PARAMETER(wszName);
46 | #endif
47 | }
48 | extern "C" void WINAPI D3DPERF_SetRegion(D3DCOLOR col, LPCWSTR wszName)
49 | {
50 | UNREFERENCED_PARAMETER(col);
51 | UNREFERENCED_PARAMETER(wszName);
52 | }
53 | extern "C" void WINAPI D3DPERF_SetOptions(DWORD dwOptions)
54 | {
55 | UNREFERENCED_PARAMETER(dwOptions);
56 |
57 | #ifndef NDEBUG // Enable PIX in debug builds (calling 'D3DPERF_SetOptions(1)' disables profiling/analysis tools, so revert that)
58 | reshade::hooks::call(D3DPERF_SetOptions)(0);
59 | #endif
60 | }
61 |
62 | extern "C" BOOL WINAPI D3DPERF_QueryRepeatFrame()
63 | {
64 | return FALSE;
65 | }
66 |
67 | extern "C" DWORD WINAPI D3DPERF_GetStatus()
68 | {
69 | #ifndef NDEBUG
70 | return reshade::hooks::call(D3DPERF_GetStatus)();
71 | #else
72 | return 0;
73 | #endif
74 | }
75 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_resource_call_vtable.inl:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "hook_manager.hpp"
7 |
8 | #if RESHADE_ADDON >= 2
9 |
10 | #undef IDirect3DSurface9_LockRect
11 | #define IDirect3DSurface9_LockRect reshade::hooks::call_vtable<13, HRESULT, IDirect3DSurface9, D3DLOCKED_RECT *, const RECT *, DWORD>
12 | #undef IDirect3DSurface9_UnlockRect
13 | #define IDirect3DSurface9_UnlockRect reshade::hooks::call_vtable<14, HRESULT, IDirect3DSurface9>
14 |
15 | #undef IDirect3DVolume9_LockBox
16 | #define IDirect3DVolume9_LockBox reshade::hooks::call_vtable<9, HRESULT, IDirect3DVolume9, D3DLOCKED_BOX *, const D3DBOX *, DWORD>
17 | #undef IDirect3DVolume9_UnlockBox
18 | #define IDirect3DVolume9_UnlockBox reshade::hooks::call_vtable<10, HRESULT, IDirect3DVolume9>
19 |
20 | #undef IDirect3DTexture9_LockRect
21 | #define IDirect3DTexture9_LockRect reshade::hooks::call_vtable<19, HRESULT, IDirect3DTexture9, UINT, D3DLOCKED_RECT *, const RECT *, DWORD>
22 | #undef IDirect3DTexture9_UnlockRect
23 | #define IDirect3DTexture9_UnlockRect reshade::hooks::call_vtable<20, HRESULT, IDirect3DTexture9, UINT>
24 |
25 | #undef IDirect3DVolumeTexture9_LockBox
26 | #define IDirect3DVolumeTexture9_LockBox reshade::hooks::call_vtable<19, HRESULT, IDirect3DVolumeTexture9, UINT, D3DLOCKED_BOX *, const D3DBOX *, DWORD>
27 | #undef IDirect3DVolumeTexture9_UnlockBox
28 | #define IDirect3DVolumeTexture9_UnlockBox reshade::hooks::call_vtable<20, HRESULT, IDirect3DVolumeTexture9, UINT>
29 |
30 | #undef IDirect3DCubeTexture9_LockRect
31 | #define IDirect3DCubeTexture9_LockRect reshade::hooks::call_vtable<19, HRESULT, IDirect3DCubeTexture9, D3DCUBEMAP_FACES, UINT, D3DLOCKED_RECT *, const RECT *, DWORD>
32 | #undef IDirect3DCubeTexture9_UnlockRect
33 | #define IDirect3DCubeTexture9_UnlockRect reshade::hooks::call_vtable<20, HRESULT, IDirect3DCubeTexture9, D3DCUBEMAP_FACES, UINT>
34 |
35 | #undef IDirect3DVertexBuffer9_Lock
36 | #define IDirect3DVertexBuffer9_Lock reshade::hooks::call_vtable<11, HRESULT, IDirect3DVertexBuffer9, UINT, UINT, void **, DWORD>
37 | #undef IDirect3DVertexBuffer9_Unlock
38 | #define IDirect3DVertexBuffer9_Unlock reshade::hooks::call_vtable<12, HRESULT, IDirect3DVertexBuffer9>
39 |
40 | #undef IDirect3DIndexBuffer9_Lock
41 | #define IDirect3DIndexBuffer9_Lock reshade::hooks::call_vtable<11, HRESULT, IDirect3DIndexBuffer9, UINT, UINT, void **, DWORD>
42 | #undef IDirect3DIndexBuffer9_Unlock
43 | #define IDirect3DIndexBuffer9_Unlock reshade::hooks::call_vtable<12, HRESULT, IDirect3DIndexBuffer9>
44 |
45 | #endif
46 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include "d3d9_impl_swapchain.hpp"
9 |
10 | struct Direct3DDevice9;
11 |
12 | struct DECLSPEC_UUID("BC52FCE4-1EAC-40C8-84CF-863600BBAA01") Direct3DSwapChain9 final : IDirect3DSwapChain9Ex, public reshade::d3d9::swapchain_impl
13 | {
14 | Direct3DSwapChain9(Direct3DDevice9 *device, IDirect3DSwapChain9 *original);
15 | Direct3DSwapChain9(Direct3DDevice9 *device, IDirect3DSwapChain9Ex *original);
16 | ~Direct3DSwapChain9();
17 |
18 | #pragma region IUnknown
19 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
20 | ULONG STDMETHODCALLTYPE AddRef() override;
21 | ULONG STDMETHODCALLTYPE Release() override;
22 | #pragma endregion
23 | #pragma region IDirect3DSwapChain9
24 | HRESULT STDMETHODCALLTYPE Present(const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion, DWORD dwFlags) override;
25 | HRESULT STDMETHODCALLTYPE GetFrontBufferData(IDirect3DSurface9 *pDestSurface) override;
26 | HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer) override;
27 | HRESULT STDMETHODCALLTYPE GetRasterStatus(D3DRASTER_STATUS *pRasterStatus) override;
28 | HRESULT STDMETHODCALLTYPE GetDisplayMode(D3DDISPLAYMODE *pMode) override;
29 | HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9 **ppDevice) override;
30 | HRESULT STDMETHODCALLTYPE GetPresentParameters(D3DPRESENT_PARAMETERS *pPresentationParameters) override;
31 | #pragma endregion
32 | #pragma region IDirect3DSwapChain9Ex
33 | HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount) override;
34 | HRESULT STDMETHODCALLTYPE GetPresentStats(D3DPRESENTSTATS *pPresentationStatistics) override;
35 | HRESULT STDMETHODCALLTYPE GetDisplayModeEx(D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) override;
36 | #pragma endregion
37 |
38 | static bool is_presenting_entire_surface(const RECT *source_rect, HWND hwnd);
39 |
40 | void on_init(bool resize);
41 | void on_reset(bool resize);
42 | void on_present(const RECT *source_rect, [[maybe_unused]] const RECT *dest_rect, HWND window_override, [[maybe_unused]] const RGNDATA *dirty_region);
43 | void handle_device_loss(HRESULT hr);
44 |
45 | bool check_and_upgrade_interface(REFIID riid);
46 |
47 | LONG _ref = 1;
48 | bool _extended_interface;
49 | Direct3DDevice9 *const _device;
50 | bool _is_initialized = false;
51 | bool _was_still_drawing_last_frame = false;
52 | };
53 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9on12_device.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "d3d9_device.hpp"
7 | #include "d3d9on12_device.hpp"
8 | #include "d3d12/d3d12_device.hpp"
9 | #include "d3d12/d3d12_command_queue.hpp"
10 |
11 | Direct3DDevice9On12::Direct3DDevice9On12(Direct3DDevice9 *device_9, D3D12Device *device_12, IDirect3DDevice9On12 *original) :
12 | _orig(original),
13 | _parent_device_9(device_9),
14 | _parent_device_12(device_12)
15 | {
16 | assert(_orig != nullptr && _parent_device_9 != nullptr && _parent_device_12 != nullptr);
17 |
18 | _parent_device_12->AddRef();
19 | }
20 | Direct3DDevice9On12::~Direct3DDevice9On12()
21 | {
22 | _parent_device_12->Release();
23 | }
24 |
25 | bool Direct3DDevice9On12::check_and_upgrade_interface(REFIID riid)
26 | {
27 | if (riid == __uuidof(this) ||
28 | riid == __uuidof(IDirect3DDevice9On12))
29 | return true;
30 |
31 | return false;
32 | }
33 |
34 | HRESULT STDMETHODCALLTYPE Direct3DDevice9On12::QueryInterface(REFIID riid, void **ppvObj)
35 | {
36 | if (ppvObj == nullptr)
37 | return E_POINTER;
38 |
39 | // IUnknown is handled by Direct3DDevice9
40 | if (check_and_upgrade_interface(riid))
41 | {
42 | AddRef();
43 | *ppvObj = this;
44 | return S_OK;
45 | }
46 |
47 | return _parent_device_9->QueryInterface(riid, ppvObj);
48 | }
49 | ULONG STDMETHODCALLTYPE Direct3DDevice9On12::AddRef()
50 | {
51 | return _parent_device_9->AddRef();
52 | }
53 | ULONG STDMETHODCALLTYPE Direct3DDevice9On12::Release()
54 | {
55 | return _parent_device_9->Release();
56 | }
57 |
58 | HRESULT STDMETHODCALLTYPE Direct3DDevice9On12::GetD3D12Device(REFIID riid, void **ppvDevice)
59 | {
60 | return _parent_device_12->QueryInterface(riid, ppvDevice);
61 | }
62 |
63 | HRESULT STDMETHODCALLTYPE Direct3DDevice9On12::UnwrapUnderlyingResource(IDirect3DResource9 *pResource, ID3D12CommandQueue *pCommandQueue, REFIID riid, void **ppvResource12)
64 | {
65 | if (com_ptr command_queue_proxy;
66 | SUCCEEDED(pCommandQueue->QueryInterface(&command_queue_proxy)))
67 | pCommandQueue = command_queue_proxy->_orig;
68 |
69 | return _orig->UnwrapUnderlyingResource(pResource, pCommandQueue, riid, ppvResource12);
70 | }
71 | HRESULT STDMETHODCALLTYPE Direct3DDevice9On12::ReturnUnderlyingResource(IDirect3DResource9 *pResource, UINT NumSync, UINT64 *pSignalValues, ID3D12Fence **ppFences)
72 | {
73 | return _orig->ReturnUnderlyingResource(pResource, NumSync, pSignalValues, ppFences);
74 | }
75 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9on12_device.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct Direct3DDevice9;
11 | struct D3D12Device;
12 |
13 | struct DECLSPEC_UUID("C09BBC5E-FC80-4D9A-A46E-F67542343008") Direct3DDevice9On12 final : IDirect3DDevice9On12
14 | {
15 | Direct3DDevice9On12(Direct3DDevice9 *device_9, D3D12Device *device_12, IDirect3DDevice9On12 *original);
16 | ~Direct3DDevice9On12();
17 |
18 | Direct3DDevice9On12(const Direct3DDevice9On12 &) = delete;
19 | Direct3DDevice9On12 &operator=(const Direct3DDevice9On12 &) = delete;
20 |
21 | #pragma region IUnknown
22 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
23 | ULONG STDMETHODCALLTYPE AddRef() override;
24 | ULONG STDMETHODCALLTYPE Release() override;
25 | #pragma endregion
26 | #pragma region IDirect3DDevice9On12
27 | HRESULT STDMETHODCALLTYPE GetD3D12Device(REFIID riid, void **ppvDevice) override;
28 | HRESULT STDMETHODCALLTYPE UnwrapUnderlyingResource(IDirect3DResource9 *pResource, ID3D12CommandQueue *pCommandQueue, REFIID riid, void **ppvResource12) override;
29 | HRESULT STDMETHODCALLTYPE ReturnUnderlyingResource(IDirect3DResource9 *pResource, UINT NumSync, UINT64 *pSignalValues, ID3D12Fence **ppFences) override;
30 | #pragma endregion
31 |
32 | bool check_and_upgrade_interface(REFIID riid);
33 |
34 | IDirect3DDevice9On12 *_orig;
35 |
36 | Direct3DDevice9 *const _parent_device_9;
37 | D3D12Device *const _parent_device_12;
38 | };
39 |
--------------------------------------------------------------------------------
/source/ddraw/ddraw.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include
7 | #include "hook_manager.hpp"
8 |
9 | extern "C" HRESULT WINAPI DirectDrawCreate(GUID *lpGUID, LPDIRECTDRAW *lplpDD, IUnknown *pUnkOuter)
10 | {
11 | return reshade::hooks::call(DirectDrawCreate)(lpGUID, lplpDD, pUnkOuter);
12 | }
13 |
14 | extern "C" HRESULT WINAPI DirectDrawCreateEx(GUID *lpGUID, LPVOID *lplpDD, REFIID iid, IUnknown *pUnkOuter)
15 | {
16 | return reshade::hooks::call(DirectDrawCreateEx)(lpGUID, lplpDD, iid, pUnkOuter);
17 | }
18 |
--------------------------------------------------------------------------------
/source/dll_log.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 |
13 | namespace reshade::log
14 | {
15 | ///
16 | /// Severity levels for logging.
17 | ///
18 | enum class level
19 | {
20 | ///
21 | /// | ERROR | ...
22 | ///
23 | error = 1,
24 | ///
25 | /// | WARN | ...
26 | ///
27 | warning = 2,
28 | ///
29 | /// | INFO | ...
30 | ///
31 | info = 3,
32 | ///
33 | /// | DEBUG | ...
34 | ///
35 | debug = 4,
36 | };
37 |
38 | ///
39 | /// Opens a log file for writing.
40 | ///
41 | /// Path to the log file.
42 | /// Error code that is set on failure.
43 | bool open_log_file(const std::filesystem::path &path, std::error_code &ec);
44 |
45 | ///
46 | /// Constructs a single log message including current time and level and writes it to the open log file.
47 | ///
48 | void message(level level, const char *format, ...);
49 |
50 | #if defined(_HRESULT_DEFINED)
51 | inline std::string hr_to_string(HRESULT hr)
52 | {
53 | switch (hr)
54 | {
55 | case E_NOTIMPL:
56 | return "E_NOTIMPL";
57 | case E_OUTOFMEMORY:
58 | return "E_OUTOFMEMORY";
59 | case E_INVALIDARG:
60 | return "E_INVALIDARG";
61 | case E_NOINTERFACE:
62 | return "E_NOINTERFACE";
63 | case E_FAIL:
64 | return "E_FAIL";
65 | case 0x8876017C:
66 | return "D3DERR_OUTOFVIDEOMEMORY";
67 | case 0x88760868:
68 | return "D3DERR_DEVICELOST";
69 | case 0x8876086A:
70 | return "D3DERR_NOTAVAILABLE";
71 | case 0x8876086C:
72 | return "D3DERR_INVALIDCALL";
73 | case 0x88760870:
74 | return "D3DERR_DEVICEREMOVED";
75 | case 0x88760874:
76 | return "D3DERR_DEVICEHUNG";
77 | case DXGI_ERROR_INVALID_CALL:
78 | return "DXGI_ERROR_INVALID_CALL";
79 | case DXGI_ERROR_UNSUPPORTED:
80 | return "DXGI_ERROR_UNSUPPORTED";
81 | case DXGI_ERROR_DEVICE_REMOVED:
82 | return "DXGI_ERROR_DEVICE_REMOVED";
83 | case DXGI_ERROR_DEVICE_HUNG:
84 | return "DXGI_ERROR_DEVICE_HUNG";
85 | case DXGI_ERROR_DEVICE_RESET:
86 | return "DXGI_ERROR_DEVICE_RESET";
87 | case DXGI_ERROR_DRIVER_INTERNAL_ERROR:
88 | return "DXGI_ERROR_DRIVER_INTERNAL_ERROR";
89 | default:
90 | char temp_string[11];
91 | return std::string(temp_string, std::snprintf(temp_string, std::size(temp_string), "%#lx", static_cast(hr)));
92 | }
93 | }
94 | #endif
95 |
96 | #if defined(_REFIID_DEFINED) && defined(_COMBASEAPI_H_)
97 | inline std::string iid_to_string(REFIID riid)
98 | {
99 | OLECHAR riid_string[40];
100 | const int len = StringFromGUID2(riid, riid_string, static_cast(std::size(riid_string)));
101 | if (len != 0)
102 | {
103 | char temp_string[40];
104 | assert(len < static_cast(std::size(temp_string)));
105 | for (int i = 0; i < len; ++i)
106 | // The GUID string contains only ANSI characters, so can just mask off the first few bits to convert
107 | temp_string[i] = riid_string[i] & 0xFF;
108 | return std::string(temp_string, len);
109 | }
110 | return "{...}";
111 | }
112 | #endif
113 | }
114 |
--------------------------------------------------------------------------------
/source/dll_resources.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include "resource.h"
9 | #include
10 | #include
11 |
12 | namespace reshade::resources
13 | {
14 | struct data_resource
15 | {
16 | size_t data_size;
17 | const void *data;
18 | };
19 |
20 | ///
21 | /// Loads the raw data associated with the specified from the DLL resources.
22 | ///
23 | /// Resource identifier of the raw data resource.
24 | data_resource load_data_resource(unsigned short id);
25 |
26 | ///
27 | /// Loads the localized string associated with the specified from the DLL resources.
28 | ///
29 | /// Resource identifier of the string resource.
30 | std::string load_string(unsigned short id);
31 | template
32 | inline std::string load_string() { return load_string(id); }
33 |
34 | #if RESHADE_LOCALIZATION
35 | ///
36 | /// Gets the preferred UI language used to look up resources for the current thread.
37 | ///
38 | std::string get_current_language();
39 | ///
40 | /// Changes the language used to look up resources for the current thread.
41 | ///
42 | /// Language name of the new language to set.
43 | /// Language name of the language that was set before the change.
44 | std::string set_current_language(const std::string &language);
45 |
46 | ///
47 | /// Returns a list of languages for which a string table is embeded in the DLL resources.
48 | ///
49 | std::vector get_languages();
50 | #endif
51 | }
52 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi_device.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct DECLSPEC_UUID("CB285C3B-3677-4332-98C7-D6339B9782B1") DXGIDevice : IDXGIDevice4
11 | {
12 | DXGIDevice(IDXGIDevice1 *original);
13 |
14 | DXGIDevice(const DXGIDevice &) = delete;
15 | DXGIDevice &operator=(const DXGIDevice &) = delete;
16 |
17 | #pragma region IDXGIObject
18 | HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent) override;
19 | #pragma endregion
20 | #pragma region IDXGIDevice
21 | HRESULT STDMETHODCALLTYPE GetAdapter(IDXGIAdapter **pAdapter) override;
22 | HRESULT STDMETHODCALLTYPE CreateSurface(const DXGI_SURFACE_DESC *pDesc, UINT NumSurfaces, DXGI_USAGE Usage, const DXGI_SHARED_RESOURCE *pSharedResource, IDXGISurface **ppSurface) override;
23 | HRESULT STDMETHODCALLTYPE QueryResourceResidency(IUnknown *const *ppResources, DXGI_RESIDENCY *pResidencyStatus, UINT NumResources) override;
24 | HRESULT STDMETHODCALLTYPE SetGPUThreadPriority(INT Priority) override;
25 | HRESULT STDMETHODCALLTYPE GetGPUThreadPriority(INT *pPriority) override;
26 | #pragma endregion
27 | #pragma region IDXGIDevice1
28 | HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(UINT MaxLatency) override;
29 | HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency(UINT *pMaxLatency) override;
30 | #pragma endregion
31 | #pragma region IDXGIDevice2
32 | HRESULT STDMETHODCALLTYPE OfferResources(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority) override;
33 | HRESULT STDMETHODCALLTYPE ReclaimResources(UINT NumResources, IDXGIResource *const *ppResources, BOOL *pDiscarded) override;
34 | HRESULT STDMETHODCALLTYPE EnqueueSetEvent(HANDLE hEvent) override;
35 | #pragma endregion
36 | #pragma region IDXGIDevice3
37 | void STDMETHODCALLTYPE Trim() override;
38 | #pragma endregion
39 | #pragma region IDXGIDevice4
40 | HRESULT STDMETHODCALLTYPE OfferResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority, UINT Flags) override;
41 | HRESULT STDMETHODCALLTYPE ReclaimResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_RECLAIM_RESOURCE_RESULTS *pResults) override;
42 | #pragma endregion
43 |
44 | bool check_and_upgrade_interface(REFIID riid);
45 |
46 | IDXGIDevice1 *_orig;
47 | unsigned short _interface_version;
48 | };
49 |
--------------------------------------------------------------------------------
/source/effect_parser.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_symbol_table.hpp"
9 | #include // std::unique_ptr
10 |
11 | namespace reshadefx
12 | {
13 | ///
14 | /// A parser for the ReShade FX shader language.
15 | ///
16 | class parser : symbol_table
17 | {
18 | public:
19 | // Define constructor explicitly because lexer class is not included here
20 | parser();
21 | ~parser();
22 |
23 | ///
24 | /// Parses the provided input string.
25 | ///
26 | /// String to analyze.
27 | /// Code generation implementation to use.
28 | /// if parsing was successfull, otherwise.
29 | bool parse(std::string source, class codegen *backend);
30 |
31 | ///
32 | /// Gets the list of error messages.
33 | ///
34 | const std::string &errors() const { return _errors; }
35 |
36 | private:
37 | void error(const location &location, unsigned int code, const std::string &message);
38 | void warning(const location &location, unsigned int code, const std::string &message);
39 |
40 | void backup();
41 | void restore();
42 |
43 | bool peek(char tok) const { return _token_next.id == static_cast(tok); }
44 | bool peek(tokenid tokid) const { return _token_next.id == tokid; }
45 | void consume();
46 | void consume_until(char tok) { return consume_until(static_cast(tok)); }
47 | void consume_until(tokenid tokid);
48 | bool accept(char tok) { return accept(static_cast(tok)); }
49 | bool accept(tokenid tokid);
50 | bool expect(char tok) { return expect(static_cast(tok)); }
51 | bool expect(tokenid tokid);
52 |
53 | bool accept_symbol(std::string &identifier, scoped_symbol &symbol);
54 | bool accept_type_class(type &type);
55 | bool accept_type_qualifiers(type &type);
56 | bool accept_unary_op();
57 | bool accept_postfix_op();
58 | bool peek_multary_op(unsigned int &precedence) const;
59 | bool accept_assignment_op();
60 |
61 | bool parse_top(bool &parse_success);
62 | bool parse_struct();
63 | bool parse_function(type type, std::string name, shader_type stype, int num_threads[3]);
64 | bool parse_variable(type type, std::string name, bool global = false);
65 | bool parse_technique();
66 | bool parse_technique_pass(pass &info);
67 | bool parse_type(type &type);
68 | bool parse_array_length(type &type);
69 | bool parse_expression(expression &expression);
70 | bool parse_expression_unary(expression &expression);
71 | bool parse_expression_multary(expression &expression, unsigned int precedence = 0);
72 | bool parse_expression_assignment(expression &expression);
73 | bool parse_annotations(std::vector &annotations);
74 | bool parse_statement(bool scoped);
75 | bool parse_statement_block(bool scoped);
76 |
77 | std::string _errors;
78 |
79 | std::unique_ptr _lexer;
80 | class codegen *_codegen = nullptr;
81 |
82 | token _token;
83 | token _token_next;
84 | token _token_backup;
85 |
86 | std::vector _loop_break_target_stack;
87 | std::vector _loop_continue_target_stack;
88 | };
89 | }
90 |
--------------------------------------------------------------------------------
/source/effect_symbol_table.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_module.hpp"
9 | #include // Used for symbol lookup table
10 |
11 | namespace reshadefx
12 | {
13 | ///
14 | /// A scope encapsulating symbols.
15 | ///
16 | struct scope
17 | {
18 | std::string name;
19 | uint32_t level, namespace_level;
20 | };
21 |
22 | ///
23 | /// Enumeration of all possible symbol types.
24 | ///
25 | enum class symbol_type
26 | {
27 | invalid,
28 | variable,
29 | constant,
30 | function,
31 | intrinsic,
32 | structure,
33 | };
34 |
35 | ///
36 | /// A single symbol in the symbol table.
37 | ///
38 | struct symbol
39 | {
40 | symbol_type op = symbol_type::invalid;
41 | uint32_t id = 0;
42 | reshadefx::type type = {};
43 | reshadefx::constant constant = {};
44 | const reshadefx::function *function = nullptr;
45 | };
46 | struct scoped_symbol : symbol
47 | {
48 | struct scope scope; // Store scope together with symbol data
49 | };
50 |
51 | ///
52 | /// A symbol table managing a list of scopes and symbols.
53 | ///
54 | class symbol_table
55 | {
56 | public:
57 | symbol_table();
58 |
59 | ///
60 | /// Enters a new scope as child of the current one.
61 | ///
62 | void enter_scope();
63 | ///
64 | /// Enters a new namespace as child of the current one.
65 | ///
66 | void enter_namespace(const std::string &name);
67 | ///
68 | /// Leaves the current scope and enter the parent one.
69 | ///
70 | void leave_scope();
71 | ///
72 | /// Leaves the current namespace and enter the parent one.
73 | ///
74 | void leave_namespace();
75 |
76 | ///
77 | /// Gets the current scope the symbol table operates in.
78 | ///
79 | const scope ¤t_scope() const { return _current_scope; }
80 |
81 | ///
82 | /// Inserts an new symbol in the symbol table.
83 | /// Returns if a symbol by that name and type already exists.
84 | ///
85 | bool insert_symbol(const std::string &name, const symbol &symbol, bool global = false);
86 |
87 | ///
88 | /// Looks for an existing symbol with the specified .
89 | ///
90 | scoped_symbol find_symbol(const std::string &name) const;
91 | scoped_symbol find_symbol(const std::string &name, const scope &scope, bool exclusive) const;
92 |
93 | ///
94 | /// Searches for the best function or intrinsic overload matching the argument list.
95 | ///
96 | bool resolve_function_call(const std::string &name, const std::vector &args, const scope &scope, symbol &data, bool &ambiguous) const;
97 |
98 | private:
99 | scope _current_scope;
100 | // Lookup table from name to matching symbols
101 | std::unordered_map> _symbol_stack;
102 | };
103 | }
104 |
--------------------------------------------------------------------------------
/source/hook.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "hook.hpp"
7 | #include
8 | #include
9 |
10 | // Verify status codes match the ones from MinHook
11 | static_assert(static_cast(reshade::hook::status::unknown) == MH_UNKNOWN);
12 | static_assert(static_cast(reshade::hook::status::success) == MH_OK);
13 | static_assert(static_cast(reshade::hook::status::not_executable) == MH_ERROR_NOT_EXECUTABLE);
14 | static_assert(static_cast(reshade::hook::status::unsupported_function) == MH_ERROR_UNSUPPORTED_FUNCTION);
15 | static_assert(static_cast(reshade::hook::status::allocation_failure) == MH_ERROR_MEMORY_ALLOC);
16 | static_assert(static_cast(reshade::hook::status::memory_protection_failure) == MH_ERROR_MEMORY_PROTECT);
17 |
18 | static unsigned long s_reference_count = 0;
19 |
20 | void reshade::hook::enable() const
21 | {
22 | MH_QueueEnableHook(target);
23 | }
24 | void reshade::hook::disable() const
25 | {
26 | MH_QueueDisableHook(target);
27 | }
28 |
29 | reshade::hook::status reshade::hook::install()
30 | {
31 | if (!valid())
32 | return hook::status::unsupported_function;
33 |
34 | // Only leave MinHook active as long as any hooks exist
35 | if (InterlockedIncrement(&s_reference_count) == 1)
36 | MH_Initialize();
37 |
38 | const MH_STATUS status_code = MH_CreateHook(target, replacement, &trampoline);
39 | if (status_code == MH_OK || status_code == MH_ERROR_ALREADY_CREATED)
40 | {
41 | // Installation was successful, so enable the hook and return
42 | enable();
43 |
44 | return hook::status::success;
45 | }
46 |
47 | if (InterlockedDecrement(&s_reference_count) == 0)
48 | MH_Uninitialize();
49 |
50 | return static_cast(status_code);
51 | }
52 | reshade::hook::status reshade::hook::uninstall()
53 | {
54 | if (!valid())
55 | return hook::status::unsupported_function;
56 |
57 | const MH_STATUS status_code = MH_RemoveHook(target);
58 | if (status_code == MH_ERROR_NOT_CREATED)
59 | return hook::status::success; // If the hook was never created, then uninstallation is implicitly successful
60 | else if (status_code != MH_OK)
61 | return static_cast(status_code);
62 |
63 | trampoline = nullptr;
64 |
65 | // MinHook can be uninitialized after all hooks were uninstalled
66 | if (InterlockedDecrement(&s_reference_count) == 0)
67 | MH_Uninitialize();
68 |
69 | return hook::status::success;
70 | }
71 |
72 | reshade::hook::address reshade::hook::call() const
73 | {
74 | assert(installed());
75 |
76 | return trampoline;
77 | }
78 |
79 | bool reshade::hook::apply_queued_actions()
80 | {
81 | return MH_ApplyQueued() == MH_OK;
82 | }
83 |
--------------------------------------------------------------------------------
/source/hook.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade
9 | {
10 | struct hook
11 | {
12 | ///
13 | /// Type which holds the address of a function.
14 | ///
15 | using address = void *;
16 |
17 | ///
18 | /// Enumeration of status codes returned by the hook installation functions.
19 | /// These match the values of the enumeration.
20 | ///
21 | enum class status
22 | {
23 | unknown = -1,
24 | success,
25 | not_executable = 7,
26 | unsupported_function,
27 | allocation_failure,
28 | memory_protection_failure,
29 | };
30 |
31 | ///
32 | /// Actually enables or disables any queued up hooks.
33 | ///
34 | static bool apply_queued_actions();
35 |
36 | ///
37 | /// Returns whether this hook is valid.
38 | ///
39 | bool valid() const { return target != nullptr && replacement != nullptr && target != replacement; }
40 | ///
41 | /// Returns whether this hook is currently installed.
42 | ///
43 | bool installed() const { return trampoline != nullptr; }
44 | ///
45 | /// Returns whether this hook is not currently installed.
46 | ///
47 | bool uninstalled() const { return trampoline == nullptr; }
48 |
49 | ///
50 | /// Enables this hook. This queues the action for later execution in .
51 | ///
52 | void enable() const;
53 | ///
54 | /// Disables this hook. This queues the action for later execution in .
55 | ///
56 | void disable() const;
57 | ///
58 | /// Installs this hook.
59 | ///
60 | hook::status install();
61 | ///
62 | /// Uninstalls this hook.
63 | ///
64 | hook::status uninstall();
65 |
66 | ///
67 | /// Returns the trampoline function address of the hook.
68 | ///
69 | address call() const;
70 | template
71 | T call() const { return reinterpret_cast(call()); }
72 |
73 | address target = nullptr;
74 | address trampoline = nullptr;
75 | address replacement = nullptr;
76 | };
77 | }
78 |
--------------------------------------------------------------------------------
/source/imgui_function_table.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2024 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #if defined(RESHADE_API_LIBRARY_EXPORT) && RESHADE_ADDON && RESHADE_GUI
7 |
8 | #include "dll_log.hpp"
9 | #include "imgui_function_table_19191.hpp"
10 | #include "imgui_function_table_19180.hpp"
11 | #include "imgui_function_table_19040.hpp"
12 | #include "imgui_function_table_19000.hpp"
13 | #include "imgui_function_table_18971.hpp"
14 | #include "imgui_function_table_18600.hpp"
15 |
16 | extern const imgui_function_table_19191 init_imgui_function_table_19191();
17 | extern const imgui_function_table_19180 init_imgui_function_table_19180();
18 | extern const imgui_function_table_19040 init_imgui_function_table_19040();
19 | extern const imgui_function_table_19000 init_imgui_function_table_19000();
20 | extern const imgui_function_table_18971 init_imgui_function_table_18971();
21 | extern const imgui_function_table_18600 init_imgui_function_table_18600();
22 |
23 | // Force initialization order (has to happen in a single translation unit to be well defined by declaration order) from newest to oldest, so that older function tables can reference newer ones
24 | const imgui_function_table_19191 g_imgui_function_table_19191 = init_imgui_function_table_19191();
25 | const imgui_function_table_19180 g_imgui_function_table_19180 = init_imgui_function_table_19180();
26 | const imgui_function_table_19040 g_imgui_function_table_19040 = init_imgui_function_table_19040();
27 | const imgui_function_table_19000 g_imgui_function_table_19000 = init_imgui_function_table_19000();
28 | const imgui_function_table_18971 g_imgui_function_table_18971 = init_imgui_function_table_18971();
29 | const imgui_function_table_18600 g_imgui_function_table_18600 = init_imgui_function_table_18600();
30 |
31 | extern "C" __declspec(dllexport) const void *ReShadeGetImGuiFunctionTable(uint32_t version)
32 | {
33 | if (version == 19190 || version == 19191)
34 | return &g_imgui_function_table_19191;
35 | if (version == 19180)
36 | return &g_imgui_function_table_19180;
37 | if (version == 19040)
38 | return &g_imgui_function_table_19040;
39 | if (version >= 19000 && version < 19040)
40 | return &g_imgui_function_table_19000;
41 | if (version == 18971)
42 | return &g_imgui_function_table_18971;
43 | if (version == 18600)
44 | return &g_imgui_function_table_18600;
45 |
46 | reshade::log::message(reshade::log::level::error, "Failed to retrieve ImGui function table, because the requested ImGui version (%u) is not supported.", version);
47 | return nullptr;
48 | }
49 |
50 | #endif
51 |
--------------------------------------------------------------------------------
/source/input_gamepad.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | namespace reshade
11 | {
12 | class input_gamepad
13 | {
14 | public:
15 | enum button
16 | {
17 | button_a = 0x1000,
18 | button_b = 0x2000,
19 | button_x = 0x4000,
20 | button_y = 0x8000,
21 | button_dpad_up = 0x0001,
22 | button_dpad_down = 0x0002,
23 | button_dpad_left = 0x0004,
24 | button_dpad_right = 0x0008,
25 | button_back = 0x0020,
26 | button_start = 0x0010,
27 | button_left_thumb = 0x0040,
28 | button_right_thumb = 0x0080,
29 | button_left_shoulder = 0x0100,
30 | button_right_shoulder = 0x0200,
31 | };
32 |
33 | explicit input_gamepad(void *xinput_module);
34 | ~input_gamepad();
35 |
36 | ///
37 | /// Loads XInput and creates or gets the gamepad input manager singleton.
38 | ///
39 | /// Pointer to the input manager.
40 | static std::shared_ptr load();
41 |
42 | ///
43 | /// Gets the connection status of the gamepad.
44 | ///
45 | bool is_connected() const { return _last_packet_num != 0; }
46 |
47 | bool is_button_down(unsigned int button) const;
48 | bool is_button_pressed(unsigned int button) const;
49 | bool is_button_released(unsigned int button) const;
50 |
51 | auto left_thumb_axis_x() const { return _left_thumb_axis_x; }
52 | auto left_thumb_axis_y() const { return _left_thumb_axis_y; }
53 | auto right_thumb_axis_x() const { return _right_thumb_axis_x; }
54 | auto right_thumb_axis_y() const { return _right_thumb_axis_y; }
55 |
56 | auto left_trigger_position() const { return _left_trigger; }
57 | auto right_trigger_position() const { return _right_trigger; }
58 |
59 | ///
60 | /// Notifies the gamepad input manager to advance a frame.
61 | ///
62 | void next_frame();
63 |
64 | private:
65 | void *_xinput_module = nullptr;
66 | void *_xinput_get_state = nullptr;
67 |
68 | uint16_t _buttons = 0;
69 | uint16_t _last_buttons = 0;
70 | float _left_trigger = 0.0f;
71 | float _right_trigger = 0.0f;
72 | float _left_thumb_axis_x = 0.0f;
73 | float _left_thumb_axis_y = 0.0f;
74 | float _right_thumb_axis_x = 0.0f;
75 | float _right_thumb_axis_y = 0.0f;
76 | uint32_t _last_packet_num = 0;
77 | };
78 | }
79 |
--------------------------------------------------------------------------------
/source/localization.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade::resources
9 | {
10 | struct localized_string
11 | {
12 | std::string data;
13 |
14 | explicit localized_string(std::string &&data) : data(std::move(data)) {}
15 |
16 | operator const char *() const
17 | {
18 | return data.c_str();
19 | }
20 | operator std::string &&()
21 | {
22 | return std::move(data);
23 | }
24 |
25 | friend localized_string operator+(const char *prefix, localized_string &&string)
26 | {
27 | string.data = prefix + string.data;
28 | return string;
29 | }
30 | friend localized_string operator+(localized_string &&string, const char *postfix)
31 | {
32 | string.data += postfix;
33 | return string;
34 | }
35 | };
36 | }
37 |
38 | #if RESHADE_LOCALIZATION
39 |
40 | #include "dll_resources.hpp"
41 |
42 | constexpr uint16_t compute_crc16(const char *data, size_t size)
43 | {
44 | uint16_t crc = 0;
45 | while (size--)
46 | {
47 | crc ^= *data++;
48 | for (int k = 0; k < 8; k++)
49 | crc = crc & 1 ? (crc >> 1) ^ 0xa001 : crc >> 1;
50 | }
51 | return crc;
52 | }
53 |
54 | #define _(message) reshade::resources::localized_string(reshade::resources::load_string())
55 |
56 | #else
57 |
58 | #define _(message) reshade::resources::localized_string(message)
59 |
60 | #endif
61 |
--------------------------------------------------------------------------------
/source/moving_average.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | template
9 | class moving_average
10 | {
11 | public:
12 | moving_average() : _index(0), _average(0), _tick_sum(0), _tick_list() {}
13 |
14 | operator T() const { return _average; }
15 |
16 | void clear()
17 | {
18 | _index = 0;
19 | _average = 0;
20 | _tick_sum = 0;
21 |
22 | for (size_t i = 0; i < SAMPLES; i++)
23 | _tick_list[i] = 0;
24 | }
25 | void append(T value)
26 | {
27 | _tick_sum -= _tick_list[_index];
28 | _tick_sum += _tick_list[_index] = value;
29 | _index = ++_index % SAMPLES;
30 | _average = _tick_sum / SAMPLES;
31 | }
32 |
33 | private:
34 | size_t _index;
35 | T _average, _tick_sum, _tick_list[SAMPLES];
36 | };
37 |
--------------------------------------------------------------------------------
/source/opengl/opengl_impl_command_queue.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "opengl_impl_device.hpp"
7 | #include "opengl_impl_device_context.hpp"
8 | #include "opengl_impl_type_convert.hpp"
9 |
10 | #define gl gl3wProcs.gl
11 |
12 | reshade::opengl::device_context_impl::device_context_impl(device_impl *device, HGLRC hglrc) :
13 | api_object_impl(hglrc),
14 | _device_impl(device),
15 | _default_fbo_width(device->_default_fbo_desc.texture.width),
16 | _default_fbo_height(device->_default_fbo_desc.texture.height)
17 | {
18 | }
19 | reshade::opengl::device_context_impl::~device_context_impl()
20 | {
21 | // Destroy framebuffers
22 | for (const auto &fbo_data : _fbo_lookup)
23 | gl.DeleteFramebuffers(1, &fbo_data.second);
24 |
25 | // Destroy vertex array objects
26 | for (const auto &vao_data : _vao_lookup)
27 | gl.DeleteVertexArrays(1, &vao_data.second);
28 |
29 | // Destroy push constants buffers
30 | gl.DeleteBuffers(static_cast(_push_constants.size()), _push_constants.data());
31 | }
32 |
33 | reshade::api::device *reshade::opengl::device_context_impl::get_device()
34 | {
35 | return _device_impl;
36 | }
37 |
38 | void reshade::opengl::device_context_impl::flush_immediate_command_list() const
39 | {
40 | gl.Flush();
41 | }
42 |
43 | void reshade::opengl::device_context_impl::wait_idle() const
44 | {
45 | gl.Finish();
46 | }
47 |
48 | bool reshade::opengl::device_context_impl::wait(api::fence fence, uint64_t value)
49 | {
50 | if ((fence.handle >> 40) == 0xFFFFFFFF)
51 | {
52 | #if 0
53 | const GLuint object = fence.handle & 0xFFFFFFFF;
54 | glSemaphoreParameterui64vEXT(object, GL_D3D12_FENCE_VALUE_EXT, &value);
55 | glWaitSemaphoreEXT(object, 0, nullptr, 0, nullptr, nullptr);
56 | return true;
57 | #else
58 | return false;
59 | #endif
60 | }
61 |
62 | const auto impl = reinterpret_cast(fence.handle);
63 | if (value > impl->current_value)
64 | return false;
65 |
66 | const GLsync &sync_object = impl->sync_objects[value % std::size(impl->sync_objects)];
67 | if (sync_object != 0)
68 | {
69 | gl.WaitSync(sync_object, 0, GL_TIMEOUT_IGNORED);
70 | return true;
71 | }
72 | else
73 | {
74 | return false;
75 | }
76 | }
77 | bool reshade::opengl::device_context_impl::signal(api::fence fence, uint64_t value)
78 | {
79 | if ((fence.handle >> 40) == 0xFFFFFFFF)
80 | {
81 | #if 0
82 | const GLuint object = fence.handle & 0xFFFFFFFF;
83 | glSemaphoreParameterui64vEXT(object, GL_D3D12_FENCE_VALUE_EXT, &value);
84 | glSignalSemaphoreEXT(object, 0, nullptr, 0, nullptr, nullptr);
85 | return true;
86 | #else
87 | return false;
88 | #endif
89 | }
90 |
91 | const auto impl = reinterpret_cast(fence.handle);
92 | if (value < impl->current_value)
93 | return false;
94 | impl->current_value = value;
95 |
96 | GLsync &sync_object = impl->sync_objects[value % std::size(impl->sync_objects)];
97 | gl.DeleteSync(sync_object);
98 |
99 | sync_object = gl.FenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
100 | return sync_object != 0;
101 | }
102 |
--------------------------------------------------------------------------------
/source/opengl/opengl_impl_state_block.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | namespace reshade::opengl
11 | {
12 | class state_block
13 | {
14 | public:
15 | state_block();
16 |
17 | void capture(bool compatibility);
18 | void apply(bool compatibility) const;
19 |
20 | private:
21 | GLint _copy_read = 0;
22 | GLint _copy_write = 0;
23 |
24 | GLint _vao = 0;
25 | GLint _vbo = 0;
26 | GLint _ibo = 0;
27 | GLint _ubo[4] = {};
28 | GLintptr _ubo_offsets[4] = {};
29 | GLsizeiptr _ubo_sizes[4] = {};
30 | GLint _active_ubo = 0;
31 | GLint _program = 0;
32 | GLint _textures2d[32] = {}, _samplers[32] = {};
33 | GLint _active_texture = 0;
34 |
35 | GLint _read_fbo = 0;
36 | GLint _draw_fbo = 0;
37 | GLint _viewport[4] = {};
38 | GLint _read_buffer = 0;
39 | GLint _draw_buffers[8] = {};
40 |
41 | GLboolean _srgb_enable = GL_FALSE;
42 | GLboolean _alpha_test = GL_FALSE;
43 |
44 | GLboolean _sample_alpha_to_coverage = GL_FALSE;
45 | GLboolean _blend_enable = GL_FALSE;
46 | GLboolean _logic_op_enable = GL_FALSE;
47 | GLint _blend_src = GL_NONE;
48 | GLint _blend_dst = GL_NONE;
49 | GLint _blend_src_alpha = GL_NONE;
50 | GLint _blend_dst_alpha = GL_NONE;
51 | GLint _blend_eq = GL_NONE;
52 | GLint _blend_eq_alpha = GL_NONE;
53 | GLint _logic_op = GL_NONE;
54 | GLfloat _blend_constant[4] = {};
55 | GLboolean _color_write_mask[4] = {};
56 |
57 | GLint _polygon_mode = GL_NONE;
58 | GLboolean _cull_enable = GL_FALSE;
59 | GLint _cull_mode = GL_NONE;
60 | GLint _front_face = GL_NONE;
61 | GLboolean _depth_clamp = GL_FALSE;
62 | GLboolean _scissor_test = GL_FALSE;
63 | GLint _scissor_rect[4] = {};
64 | GLboolean _multisample_enable = GL_FALSE;
65 | GLboolean _line_smooth_enable = GL_FALSE;
66 |
67 | GLboolean _depth_test = GL_FALSE;
68 | GLboolean _depth_mask = GL_FALSE;
69 | GLint _depth_func = GL_NONE;
70 | GLboolean _stencil_test = GL_FALSE;
71 | GLint _stencil_func = GL_NONE;
72 | GLint _stencil_read_mask = GL_NONE;
73 | GLint _stencil_write_mask = GL_NONE;
74 | GLint _stencil_reference_value = GL_NONE;
75 | GLint _stencil_op_fail = GL_NONE;
76 | GLint _stencil_op_depth_fail = GL_NONE;
77 | GLint _stencil_op_depth_pass = GL_NONE;
78 |
79 | GLint _clip_origin = GL_NONE;
80 | GLint _clip_depthmode = GL_NONE;
81 | };
82 | }
83 |
--------------------------------------------------------------------------------
/source/opengl/opengl_impl_swapchain.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "opengl_impl_device.hpp"
7 | #include "opengl_impl_swapchain.hpp"
8 | #include "opengl_impl_type_convert.hpp"
9 |
10 | reshade::opengl::swapchain_impl::swapchain_impl(device_impl *device, HDC hdc) :
11 | api_object_impl(hdc),
12 | _device_impl(device)
13 | {
14 | }
15 |
16 | reshade::api::device *reshade::opengl::swapchain_impl::get_device()
17 | {
18 | return _device_impl;
19 | }
20 |
21 | void *reshade::opengl::swapchain_impl::get_hwnd() const
22 | {
23 | return WindowFromDC(_orig);
24 | }
25 |
26 | reshade::api::resource reshade::opengl::swapchain_impl::get_back_buffer(uint32_t index)
27 | {
28 | assert(index == 0);
29 |
30 | return make_resource_handle(GL_FRAMEBUFFER_DEFAULT, GL_BACK);
31 | }
32 |
--------------------------------------------------------------------------------
/source/opengl/opengl_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include "reshade_api_object_impl.hpp"
10 |
11 | namespace reshade::opengl
12 | {
13 | class device_impl;
14 |
15 | class swapchain_impl : public api::api_object_impl
16 | {
17 | public:
18 | swapchain_impl(device_impl *device, HDC hdc);
19 |
20 | api::device *get_device() final;
21 |
22 | void *get_hwnd() const final;
23 |
24 | api::resource get_back_buffer(uint32_t index = 0) final;
25 |
26 | uint32_t get_back_buffer_count() const final { return 1; }
27 | uint32_t get_current_back_buffer_index() const final { return 0; }
28 |
29 | bool check_color_space_support(api::color_space color_space) const final { return color_space == api::color_space::srgb_nonlinear || color_space == api::color_space::extended_srgb_linear; }
30 |
31 | api::color_space get_color_space() const final { return api::color_space::unknown; }
32 |
33 | private:
34 | device_impl *const _device_impl;
35 | };
36 | }
37 |
--------------------------------------------------------------------------------
/source/openvr/openvr_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "reshade_api_object_impl.hpp"
9 | #include
10 |
11 | struct D3D10Device;
12 | struct D3D11Device;
13 | struct D3D12CommandQueue;
14 |
15 | namespace reshade::openvr
16 | {
17 | class swapchain_impl : public api::api_object_impl
18 | {
19 | public:
20 | swapchain_impl(D3D10Device *device, vr::IVRCompositor *compositor);
21 | swapchain_impl(D3D11Device *device, vr::IVRCompositor *compositor);
22 | swapchain_impl(D3D12CommandQueue *queue, vr::IVRCompositor *compositor);
23 | swapchain_impl(api::device *device, api::command_queue *graphics_queue, vr::IVRCompositor *compositor);
24 | ~swapchain_impl();
25 |
26 | api::device *get_device() final;
27 | api::command_queue *get_command_queue() { return _graphics_queue; }
28 |
29 | void *get_hwnd() const final { return nullptr; }
30 |
31 | api::resource get_back_buffer(uint32_t index = 0) final;
32 |
33 | uint32_t get_back_buffer_count() const final { return 1; }
34 | uint32_t get_current_back_buffer_index() const final { return 0; }
35 |
36 | bool check_color_space_support(api::color_space color_space) const final { return color_space == api::color_space::srgb_nonlinear || color_space == api::color_space::extended_srgb_linear; }
37 |
38 | api::color_space get_color_space() const final { return _back_buffer_color_space; }
39 | void set_color_space(vr::EColorSpace color_space);
40 |
41 | api::rect get_eye_rect(vr::EVREye eye) const;
42 | api::subresource_box get_eye_subresource_box(vr::EVREye eye) const;
43 |
44 | void on_init();
45 | void on_reset();
46 |
47 | bool on_vr_submit(vr::EVREye eye, api::resource eye_texture, vr::EColorSpace color_space, const vr::VRTextureBounds_t *bounds, uint32_t layer);
48 |
49 | private:
50 | api::device *const _device;
51 | api::command_queue *const _graphics_queue;
52 | api::resource _side_by_side_texture = {};
53 | void *_direct3d_device = nullptr;
54 | api::color_space _back_buffer_color_space = api::color_space::unknown;
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/source/openxr/openxr_hooks.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #include "openxr_hooks.hpp"
7 | #include "lockfree_linear_map.hpp"
8 | #include // std::strcmp
9 |
10 | extern lockfree_linear_map g_openxr_instances;
11 |
12 | #define HOOK_PROC(name) \
13 | if (0 == std::strcmp(pName, "xr" #name)) { \
14 | *pFunction = reinterpret_cast(xr##name); \
15 | return XR_SUCCESS; \
16 | }
17 |
18 | XrResult XRAPI_CALL xrGetInstanceProcAddr(XrInstance instance, const char *pName, PFN_xrVoidFunction *pFunction)
19 | {
20 | // Core 1_0
21 | HOOK_PROC(DestroyInstance);
22 | HOOK_PROC(CreateSession);
23 | HOOK_PROC(DestroySession);
24 | HOOK_PROC(CreateSwapchain);
25 | HOOK_PROC(DestroySwapchain);
26 | HOOK_PROC(AcquireSwapchainImage);
27 | HOOK_PROC(ReleaseSwapchainImage);
28 | HOOK_PROC(EndFrame);
29 |
30 | if (instance == XR_NULL_HANDLE)
31 | return XR_ERROR_HANDLE_INVALID;
32 |
33 | const auto trampoline = g_openxr_instances.at(instance).GetInstanceProcAddr;
34 | return trampoline(instance, pName, pFunction);
35 | }
36 |
--------------------------------------------------------------------------------
/source/openxr/openxr_hooks.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct openxr_dispatch_table : public XrGeneratedDispatchTable
11 | {
12 | XrInstance instance;
13 | };
14 |
15 | template
16 | static const T *find_in_structure_chain(const void *structure_chain, XrStructureType type)
17 | {
18 | const T *next = reinterpret_cast(structure_chain);
19 | while (next != nullptr && next->type != type)
20 | next = reinterpret_cast(next->next);
21 | return next;
22 | }
23 |
--------------------------------------------------------------------------------
/source/openxr/openxr_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "reshade_api_object_impl.hpp"
9 | #include
10 | #include
11 |
12 | namespace reshade::openxr
13 | {
14 | class swapchain_impl : public api::api_object_impl
15 | {
16 | public:
17 | swapchain_impl(api::device *device, api::command_queue *graphics_queue, XrSession session);
18 | ~swapchain_impl();
19 |
20 | api::device *get_device() final;
21 |
22 | void *get_hwnd() const final { return nullptr; }
23 |
24 | api::resource get_back_buffer(uint32_t index = 0) final;
25 |
26 | uint32_t get_back_buffer_count() const final;
27 | uint32_t get_current_back_buffer_index() const final;
28 |
29 | bool check_color_space_support(api::color_space color_space) const final { return color_space == api::color_space::srgb_nonlinear || color_space == api::color_space::extended_srgb_linear; }
30 |
31 | api::color_space get_color_space() const final { return api::color_space::unknown; }
32 |
33 | api::rect get_view_rect(uint32_t index, uint32_t view_count) const;
34 | api::subresource_box get_view_subresource_box(uint32_t index, uint32_t view_count) const;
35 |
36 | void on_init();
37 | void on_reset();
38 |
39 | void on_present(uint32_t view_count, const api::resource *view_textures, const api::subresource_box *view_boxes, const uint32_t *view_layers, const std::vector *swapchain_images, uint32_t swap_index);
40 |
41 | private:
42 | api::device *const _device;
43 | api::command_queue *const _graphics_queue;
44 | api::resource _side_by_side_texture = {};
45 | const std::vector *_swapchain_images = nullptr;
46 | uint32_t _swap_index = 0;
47 | };
48 | }
49 |
--------------------------------------------------------------------------------
/source/platform_utils.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2022 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | namespace reshade::utils
11 | {
12 | ///
13 | /// Opens a Windows explorer window with the specified file selected.
14 | ///
15 | bool open_explorer(const std::filesystem::path &path);
16 |
17 | ///
18 | /// Executes the specified command as a new process, with basic (not elevated) user privileges.
19 | ///
20 | bool execute_command(const std::string &command_line, const std::filesystem::path &working_directory = L".", bool hide_window = false);
21 |
22 | ///
23 | /// Plays the specified audio file asynchronously.
24 | ///
25 | void play_sound_async(const std::filesystem::path &audio_file);
26 |
27 | ///
28 | /// Changes the window background to be transparent or opaque.
29 | /// Alpha values in the swap chain are only respected when the window is transparent.
30 | ///
31 | void set_window_transparency(void *window, bool enabled);
32 | }
33 |
--------------------------------------------------------------------------------
/source/reshade_api_object_impl.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "reshade_api_device.hpp"
9 | #include
10 | #include
11 |
12 | namespace reshade::api
13 | {
14 | template
15 | class api_object_impl : public api_object_base...
16 | {
17 | static_assert(sizeof(T) <= sizeof(uint64_t));
18 |
19 | struct guid_t
20 | {
21 | struct hash
22 | {
23 | auto operator()(const guid_t &key) const -> size_t
24 | {
25 | #ifndef _WIN64
26 | return key.a ^ key.b ^ ((key.c & 0xFF00) | (key.d & 0xFF));
27 | #else
28 | return key.a ^ (key.b << 1);
29 | #endif
30 | }
31 | };
32 | struct equal
33 | {
34 | bool operator()(const guid_t &lhs, const guid_t &rhs) const
35 | {
36 | #ifndef _WIN64
37 | return lhs.a == rhs.a && lhs.b == rhs.b && lhs.c == rhs.c && lhs.d == rhs.d;
38 | #else
39 | return lhs.a == rhs.a && lhs.b == rhs.b;
40 | #endif
41 | }
42 | };
43 |
44 | #ifndef _WIN64
45 | uint32_t a, b, c, d;
46 | #else
47 | uint64_t a, b;
48 | #endif
49 | };
50 |
51 | public:
52 | api_object_impl(const api_object_impl &) = delete;
53 | api_object_impl &operator=(const api_object_impl &) = delete;
54 |
55 | void get_private_data(const uint8_t guid[16], uint64_t *data) const final
56 | {
57 | assert(data != nullptr);
58 |
59 | if (_private_data.empty()) // Early-out to avoid crash when this is called after the object was destroyed
60 | {
61 | *data = 0;
62 | return;
63 | }
64 |
65 | if (const auto it = _private_data.find(*reinterpret_cast(guid));
66 | it != _private_data.end())
67 | *data = it->second;
68 | else
69 | *data = 0;
70 | }
71 | void set_private_data(const uint8_t guid[16], const uint64_t data) final
72 | {
73 | if (data != 0)
74 | _private_data[*reinterpret_cast(guid)] = data;
75 | else
76 | _private_data.erase(*reinterpret_cast(guid));
77 | }
78 |
79 | uint64_t get_native() const final { return (uint64_t)_orig; }
80 |
81 | T _orig;
82 |
83 | protected:
84 | template
85 | explicit api_object_impl(T orig, Args... args) : api_object_base(std::forward(args)...)..., _orig(orig) {}
86 | ~api_object_impl()
87 | {
88 | // All user data should ideally have been removed before destruction, to avoid leaks
89 | assert(_private_data.empty());
90 | }
91 |
92 | private:
93 | std::unordered_map _private_data;
94 | };
95 | }
96 |
97 | template
98 | struct temp_mem
99 | {
100 | explicit temp_mem(size_t elements = STACK_ELEMENTS) : p(stack)
101 | {
102 | if (elements > STACK_ELEMENTS)
103 | p = new T[elements];
104 | }
105 | temp_mem(const temp_mem &) = delete;
106 | temp_mem(temp_mem &&) = delete;
107 | ~temp_mem()
108 | {
109 | if (p != stack)
110 | delete[] p;
111 | }
112 |
113 | temp_mem &operator=(const temp_mem &) = delete;
114 | temp_mem &operator=(temp_mem &&other_mem) = delete;
115 |
116 | T &operator[](size_t element)
117 | {
118 | assert(element < STACK_ELEMENTS || p != stack);
119 |
120 | return p[element];
121 | }
122 |
123 | T *p, stack[STACK_ELEMENTS];
124 | };
125 |
--------------------------------------------------------------------------------
/source/runtime_manager.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2024 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "runtime.hpp"
7 | #include "runtime_manager.hpp"
8 | #include "ini_file.hpp"
9 | #include
10 | #include
11 | #include
12 |
13 | static std::shared_mutex s_runtime_config_names_mutex;
14 | static std::unordered_set s_runtime_config_names;
15 |
16 | void reshade::create_effect_runtime(api::swapchain *swapchain, api::command_queue *graphics_queue, bool vr)
17 | {
18 | if (graphics_queue == nullptr || swapchain->get_private_data() != nullptr)
19 | return;
20 |
21 | assert((graphics_queue->get_type() & api::command_queue_type::graphics) != 0);
22 |
23 | // Try to find a unique configuration name for this effect runtime instance
24 | std::string config_name = "ReShade";
25 | if (vr)
26 | config_name += "VR";
27 | {
28 | const std::string config_name_base = config_name;
29 |
30 | const std::unique_lock lock(s_runtime_config_names_mutex);
31 |
32 | if (size_t max_runtimes = std::numeric_limits::max();
33 | global_config().get("INSTALL", "MaxEffectRuntimes", max_runtimes) &&
34 | s_runtime_config_names.size() >= max_runtimes)
35 | return;
36 |
37 | for (int attempt = 1; attempt < 100 && s_runtime_config_names.find(config_name) != s_runtime_config_names.end(); ++attempt)
38 | config_name = config_name_base + std::to_string(attempt + 1);
39 |
40 | assert(s_runtime_config_names.find(config_name) == s_runtime_config_names.end());
41 | s_runtime_config_names.insert(config_name);
42 | }
43 |
44 | const ini_file &config = ini_file::load_cache(g_reshade_base_path / std::filesystem::u8path(config_name + ".ini"));
45 | if (config.get("GENERAL", "Disable"))
46 | return;
47 |
48 | swapchain->create_private_data(swapchain, graphics_queue, config.path(), vr);
49 | }
50 | void reshade::destroy_effect_runtime(api::swapchain *swapchain)
51 | {
52 | if (const auto runtime = swapchain->get_private_data())
53 | {
54 | const std::string config_name = runtime->get_config_path().stem().u8string();
55 |
56 | // Free up the configuration name of this effect runtime instance for reuse
57 | const std::unique_lock lock(s_runtime_config_names_mutex);
58 |
59 | s_runtime_config_names.erase(config_name);
60 | }
61 |
62 | swapchain->destroy_private_data();
63 | }
64 |
65 | void reshade::init_effect_runtime(api::swapchain *swapchain)
66 | {
67 | if (const auto runtime = swapchain->get_private_data())
68 | runtime->on_init();
69 | }
70 | void reshade::reset_effect_runtime(api::swapchain *swapchain)
71 | {
72 | if (const auto runtime = swapchain->get_private_data())
73 | runtime->on_reset();
74 | }
75 | void reshade::present_effect_runtime(api::swapchain *swapchain)
76 | {
77 | if (const auto runtime = swapchain->get_private_data())
78 | runtime->on_present();
79 | }
80 |
--------------------------------------------------------------------------------
/source/runtime_manager.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2024 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "reshade_api_device.hpp"
9 |
10 | namespace reshade
11 | {
12 | void create_effect_runtime(api::swapchain *swapchain, api::command_queue *graphics_queue, bool vr = false);
13 | void destroy_effect_runtime(api::swapchain *swapchain);
14 |
15 | void init_effect_runtime(api::swapchain *swapchain);
16 | void reset_effect_runtime(api::swapchain *swapchain);
17 | void present_effect_runtime(api::swapchain *swapchain);
18 | }
19 |
--------------------------------------------------------------------------------
/source/runtime_update_check.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "runtime.hpp"
7 | #include
8 | #include
9 |
10 | struct scoped_internet_handle
11 | {
12 | scoped_internet_handle(HINTERNET handle) : handle(handle) {}
13 | ~scoped_internet_handle() { InternetCloseHandle(handle); }
14 |
15 | operator HINTERNET() const { return handle; }
16 |
17 | private:
18 | HINTERNET handle;
19 | };
20 |
21 | unsigned int reshade::runtime::s_latest_version[3] = {};
22 |
23 | void reshade::runtime::check_for_update()
24 | {
25 | #if defined(NDEBUG) && !defined(RESHADE_TEST_APPLICATION)
26 | if (s_latest_version[0] != 0)
27 | return;
28 |
29 | const scoped_internet_handle handle = InternetOpen(TEXT("reshade"), INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
30 | if (handle == nullptr)
31 | return;
32 |
33 | constexpr auto api_url = TEXT("https://api.github.com/repos/crosire/reshade/tags");
34 |
35 | const scoped_internet_handle request = InternetOpenUrl(handle, api_url, nullptr, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, 0);
36 | if (request == nullptr)
37 | return;
38 |
39 | // Set some timeouts to avoid stalling startup because of a broken Internet connection
40 | DWORD timeout = 2000; // 2 seconds
41 | InternetSetOption(request, INTERNET_OPTION_CONNECT_TIMEOUT, &timeout, sizeof(timeout));
42 | InternetSetOption(request, INTERNET_OPTION_RECEIVE_TIMEOUT, &timeout, sizeof(timeout));
43 |
44 | char response_data[32];
45 | if (DWORD len = 0; InternetReadFile(request, response_data, sizeof(response_data) - 1, &len) && len > 0)
46 | {
47 | response_data[len] = '\0';
48 |
49 | const char *version_major_offset = std::strchr(response_data, 'v');
50 | if (version_major_offset == nullptr) return; else version_major_offset++;
51 | const char *version_minor_offset = std::strchr(version_major_offset, '.');
52 | if (version_minor_offset == nullptr) return; else version_minor_offset++;
53 | const char *version_revision_offset = std::strchr(version_minor_offset, '.');
54 | if (version_revision_offset == nullptr) return; else version_revision_offset++;
55 |
56 | s_latest_version[0] = static_cast(std::strtoul(version_major_offset, nullptr, 10));
57 | s_latest_version[1] = static_cast(std::strtoul(version_minor_offset, nullptr, 10));
58 | s_latest_version[2] = static_cast(std::strtoul(version_revision_offset, nullptr, 10));
59 | }
60 | #endif
61 | }
62 |
--------------------------------------------------------------------------------
/source/state_block.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "state_block.hpp"
7 | #include "d3d9/d3d9_impl_state_block.hpp"
8 | #include "d3d10/d3d10_impl_state_block.hpp"
9 | #include "d3d11/d3d11_impl_state_block.hpp"
10 | #include "opengl/opengl_impl_device.hpp"
11 | #include "opengl/opengl_impl_state_block.hpp"
12 |
13 | void reshade::api::create_state_block(api::device *device, state_block *out_state_block)
14 | {
15 | switch (device->get_api())
16 | {
17 | case api::device_api::d3d9:
18 | *out_state_block = { reinterpret_cast(new d3d9::state_block(reinterpret_cast(device->get_native()))) };
19 | break;
20 | case api::device_api::d3d10:
21 | *out_state_block = { reinterpret_cast(new d3d10::state_block(reinterpret_cast(device->get_native()))) };
22 | break;
23 | case api::device_api::d3d11:
24 | *out_state_block = { reinterpret_cast(new d3d11::state_block(reinterpret_cast(device->get_native()))) };
25 | break;
26 | case api::device_api::opengl:
27 | *out_state_block = { reinterpret_cast(new opengl::state_block()) };
28 | break;
29 | default:
30 | *out_state_block = { 0 };
31 | }
32 | }
33 | void reshade::api::destroy_state_block(api::device *device, state_block state_block)
34 | {
35 | switch (device->get_api())
36 | {
37 | case api::device_api::d3d9:
38 | delete reinterpret_cast(state_block.handle);
39 | break;
40 | case api::device_api::d3d10:
41 | delete reinterpret_cast(state_block.handle);
42 | break;
43 | case api::device_api::d3d11:
44 | delete reinterpret_cast(state_block.handle);
45 | break;
46 | case api::device_api::opengl:
47 | delete reinterpret_cast(state_block.handle);
48 | break;
49 | }
50 | }
51 |
52 | void reshade::api::apply_state(api::command_list *cmd_list, state_block state_block)
53 | {
54 | api::device *const device = cmd_list->get_device();
55 |
56 | switch (device->get_api())
57 | {
58 | case api::device_api::d3d9:
59 | reinterpret_cast(state_block.handle)->apply_and_release();
60 | break;
61 | case api::device_api::d3d10:
62 | reinterpret_cast(state_block.handle)->apply_and_release();
63 | break;
64 | case api::device_api::d3d11:
65 | reinterpret_cast(state_block.handle)->apply_and_release();
66 | break;
67 | case api::device_api::opengl:
68 | reinterpret_cast(state_block.handle)->apply(static_cast(device)->get_compatibility_context());
69 | break;
70 | }
71 | }
72 | void reshade::api::capture_state(api::command_list *cmd_list, state_block state_block)
73 | {
74 | api::device *const device = cmd_list->get_device();
75 |
76 | switch (device->get_api())
77 | {
78 | case api::device_api::d3d9:
79 | reinterpret_cast(state_block.handle)->capture();
80 | break;
81 | case api::device_api::d3d10:
82 | reinterpret_cast(state_block.handle)->capture();
83 | break;
84 | case api::device_api::d3d11:
85 | reinterpret_cast(state_block.handle)->capture(reinterpret_cast(cmd_list->get_native()));
86 | break;
87 | case api::device_api::opengl:
88 | reinterpret_cast(state_block.handle)->capture(static_cast(device)->get_compatibility_context());
89 | break;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/source/state_block.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "reshade_api_device.hpp"
9 |
10 | namespace reshade::api
11 | {
12 | RESHADE_DEFINE_HANDLE(state_block);
13 |
14 | void create_state_block(api::device *device, state_block *out_state_block);
15 | void destroy_state_block(api::device *device, state_block state_block);
16 |
17 | void apply_state(api::command_list *cmd_list, state_block state_block);
18 | void capture_state(api::command_list *cmd_list, state_block state_block);
19 | }
20 |
--------------------------------------------------------------------------------
/source/vulkan/vulkan_hooks.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause OR MIT
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | // Windows SDK headers define these, which breaks the dispatch table
13 | #undef CreateEvent
14 | #undef CreateSemaphore
15 |
16 | #include
17 |
18 | struct instance_dispatch_table : public VkLayerInstanceDispatchTable
19 | {
20 | VkInstance instance;
21 | uint32_t api_version;
22 | };
23 |
24 | template
25 | inline T *find_layer_info(const void *structure_chain, VkStructureType type, VkLayerFunction function)
26 | {
27 | T *next = reinterpret_cast(const_cast(structure_chain));
28 | while (next != nullptr && !(next->sType == type && next->function == function))
29 | next = reinterpret_cast(const_cast(next->pNext));
30 | return next;
31 | }
32 | template
33 | inline const T *find_in_structure_chain(const void *structure_chain, VkStructureType type)
34 | {
35 | const T *next = reinterpret_cast(structure_chain);
36 | while (next != nullptr && next->sType != type)
37 | next = reinterpret_cast(next->pNext);
38 | return next;
39 | }
40 |
41 | inline void *const dispatch_key_from_handle(const void *dispatch_handle)
42 | {
43 | assert(dispatch_handle != nullptr);
44 |
45 | // The Vulkan loader writes the dispatch table pointer right to the start of the object, so use that as a key for lookup
46 | // This ensures that all objects of a specific level (device or instance) will use the same dispatch table
47 | return *(void **)dispatch_handle;
48 | }
49 |
--------------------------------------------------------------------------------
/source/vulkan/vulkan_impl_command_list_immediate.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "vulkan_impl_command_list.hpp"
9 |
10 | namespace reshade::vulkan
11 | {
12 | class command_list_immediate_impl : public command_list_impl
13 | {
14 | static constexpr uint32_t NUM_COMMAND_FRAMES = 4; // Use power of two so that modulo can be replaced with bitwise operation
15 |
16 | public:
17 | static thread_local command_list_immediate_impl *s_last_immediate_command_list;
18 |
19 | command_list_immediate_impl(device_impl *device, uint32_t queue_family_index, VkQueue queue);
20 | ~command_list_immediate_impl();
21 |
22 | bool flush(VkSubmitInfo &semaphore_info);
23 | bool flush_and_wait();
24 |
25 | private:
26 | const VkQueue _parent_queue;
27 | uint32_t _cmd_index = 0;
28 | VkCommandPool _cmd_pool = VK_NULL_HANDLE;
29 | VkFence _cmd_fences[NUM_COMMAND_FRAMES] = {};
30 | VkSemaphore _cmd_semaphores[NUM_COMMAND_FRAMES] = {};
31 | VkCommandBuffer _cmd_buffers[NUM_COMMAND_FRAMES] = {};
32 | };
33 | }
34 |
--------------------------------------------------------------------------------
/source/vulkan/vulkan_impl_command_queue.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2021 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | #include "vulkan_impl_command_list_immediate.hpp"
9 | #include
10 |
11 | namespace reshade::vulkan
12 | {
13 | class command_queue_impl : public api::api_object_impl
14 | {
15 | public:
16 | command_queue_impl(device_impl *device, uint32_t queue_family_index, const VkQueueFamilyProperties &queue_family, VkQueue queue);
17 | ~command_queue_impl();
18 |
19 | api::device *get_device() final;
20 |
21 | api::command_queue_type get_type() const final;
22 |
23 | void wait_idle() const final;
24 |
25 | void flush_immediate_command_list() const final;
26 | void flush_immediate_command_list(VkSubmitInfo &semaphore_info) const;
27 |
28 | api::command_list *get_immediate_command_list() final { return _immediate_cmd_list; }
29 |
30 | void begin_debug_event(const char *label, const float color[4]) final;
31 | void end_debug_event() final;
32 | void insert_debug_marker(const char *label, const float color[4]) final;
33 |
34 | bool wait(api::fence fence, uint64_t value) final;
35 | bool signal(api::fence fence, uint64_t value) final;
36 |
37 | uint64_t get_timestamp_frequency() const final;
38 |
39 | mutable std::recursive_mutex _mutex;
40 |
41 | private:
42 | device_impl *const _device_impl;
43 | command_list_immediate_impl *_immediate_cmd_list = nullptr;
44 | VkQueueFamilyProperties _queue_family_props = {};
45 | };
46 |
47 | template <>
48 | struct object_data : public command_queue_impl
49 | {
50 | using Handle = VkQueue;
51 |
52 | object_data(device_impl *device, uint32_t queue_family_index, const VkQueueFamilyProperties &queue_family, VkQueue queue) :
53 | command_queue_impl(device, queue_family_index, queue_family, queue) {}
54 | };
55 | }
56 |
--------------------------------------------------------------------------------
/source/vulkan/vulkan_impl_swapchain.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #include "vulkan_impl_device.hpp"
7 | #include "vulkan_impl_swapchain.hpp"
8 | #include "vulkan_impl_type_convert.hpp"
9 |
10 | #define vk _device_impl->_dispatch_table
11 |
12 | reshade::vulkan::swapchain_impl::swapchain_impl(device_impl *device, VkSwapchainKHR swapchain, const VkSwapchainCreateInfoKHR &create_info, HWND hwnd) :
13 | api_object_impl(swapchain),
14 | _device_impl(device),
15 | _create_info(create_info),
16 | _hwnd(hwnd)
17 | {
18 | _create_info.pNext = nullptr;
19 |
20 | assert(create_info.imageUsage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
21 | }
22 |
23 | reshade::api::device *reshade::vulkan::swapchain_impl::get_device()
24 | {
25 | return _device_impl;
26 | }
27 |
28 | void *reshade::vulkan::swapchain_impl::get_hwnd() const
29 | {
30 | return _hwnd;
31 | }
32 |
33 | reshade::api::resource reshade::vulkan::swapchain_impl::get_back_buffer(uint32_t index)
34 | {
35 | uint32_t num_images = index + 1;
36 | temp_mem swapchain_images(num_images);
37 | return vk.GetSwapchainImagesKHR(_device_impl->_orig, _orig, &num_images, swapchain_images.p) >= VK_SUCCESS ? api::resource { (uint64_t)swapchain_images[index] } : api::resource {};
38 | }
39 |
40 | uint32_t reshade::vulkan::swapchain_impl::get_back_buffer_count() const
41 | {
42 | uint32_t num_images = 0;
43 | return vk.GetSwapchainImagesKHR(_device_impl->_orig, _orig, &num_images, nullptr) == VK_SUCCESS ? num_images : 0;
44 | }
45 |
46 | uint32_t reshade::vulkan::swapchain_impl::get_current_back_buffer_index() const
47 | {
48 | return _swap_index;
49 | }
50 |
51 | bool reshade::vulkan::swapchain_impl::check_color_space_support(api::color_space color_space) const
52 | {
53 | uint32_t num_formats = 0;
54 | _device_impl->_instance_dispatch_table.GetPhysicalDeviceSurfaceFormatsKHR(_device_impl->_physical_device, _create_info.surface, &num_formats, nullptr);
55 | temp_mem formats(num_formats);
56 | _device_impl->_instance_dispatch_table.GetPhysicalDeviceSurfaceFormatsKHR(_device_impl->_physical_device, _create_info.surface, &num_formats, formats.p);
57 |
58 | for (uint32_t i = 0; i < num_formats; ++i)
59 | if (formats[i].format == _create_info.imageFormat && formats[i].colorSpace == convert_color_space(color_space))
60 | return true;
61 |
62 | return false;
63 | }
64 |
65 | reshade::api::color_space reshade::vulkan::swapchain_impl::get_color_space() const
66 | {
67 | return convert_color_space(_create_info.imageColorSpace);
68 | }
69 |
--------------------------------------------------------------------------------
/source/vulkan/vulkan_impl_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 Patrick Mours
3 | * SPDX-License-Identifier: BSD-3-Clause
4 | */
5 |
6 | #pragma once
7 |
8 | namespace reshade::vulkan
9 | {
10 | class device_impl;
11 |
12 | class swapchain_impl : public api::api_object_impl
13 | {
14 | public:
15 | swapchain_impl(device_impl *device, VkSwapchainKHR swapchain, const VkSwapchainCreateInfoKHR &create_info, HWND hwnd);
16 |
17 | api::device *get_device() final;
18 |
19 | void *get_hwnd() const final;
20 |
21 | api::resource get_back_buffer(uint32_t index) final;
22 |
23 | uint32_t get_back_buffer_count() const final;
24 | uint32_t get_current_back_buffer_index() const final;
25 |
26 | bool check_color_space_support(api::color_space color_space) const final;
27 |
28 | api::color_space get_color_space() const final;
29 |
30 | private:
31 | device_impl *const _device_impl;
32 |
33 | protected:
34 | VkSwapchainCreateInfoKHR _create_info = { VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR };
35 | HWND _hwnd = nullptr;
36 | uint32_t _swap_index = 0;
37 | };
38 |
39 | template <>
40 | struct object_data : public swapchain_impl
41 | {
42 | using Handle = VkSwapchainKHR;
43 |
44 | object_data(device_impl *device, VkSwapchainKHR swapchain, const VkSwapchainCreateInfoKHR &create_info, HWND hwnd) :
45 | swapchain_impl(device, swapchain, create_info, hwnd) {}
46 |
47 | using swapchain_impl::_create_info;
48 | using swapchain_impl::_hwnd;
49 | using swapchain_impl::_swap_index;
50 |
51 | HMONITOR hmonitor = nullptr;
52 | };
53 | }
54 |
--------------------------------------------------------------------------------
/tools/7za.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/crosire/reshade/5ebeb52d965015cc492d6b892945d683ac3f45e2/tools/7za.exe
--------------------------------------------------------------------------------
/tools/create_language_template.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [string]
3 | $locale = "en-US"
4 | )
5 |
6 | # This hash function has to match the one used in localization.hpp
7 | function compute_crc16 {
8 | Param($data)
9 |
10 | $size = $data.Length
11 | $i = 0
12 | $crc = 0
13 | while ($size--)
14 | {
15 | $crc = $crc -bxor $data[$i++]
16 | for ($k = 0; $k -lt 8; $k++) {
17 | $crc = if ($crc -band 1) { ($crc -shr 1) -bxor 0xa001 } else { $crc -shr 1 }
18 | }
19 | }
20 | return $crc
21 | }
22 |
23 | $strings = ""
24 | $lang_file = Get-Item -Path "..\res\lang_$locale.rc2"
25 |
26 | if ($lang_file.Exists)
27 | {
28 | $lang_messages = @{}
29 | foreach ($line in Get-Content $lang_file -Encoding UTF8) {
30 | if ($line -match "([0-9]+) ([^\r\n]+)") {
31 | $lang_messages[[int]$matches[1]] = $matches[2]
32 | }
33 | }
34 | }
35 |
36 | if (Get-Command "xgettext.exe" -ErrorAction SilentlyContinue)
37 | {
38 | $message = ""
39 | $is_inside_message = $false
40 |
41 | xgettext.exe --c++ --keyword=_ --omit-header --indent --no-wrap --output=- ..\source\runtime_gui.cpp ..\source\runtime_gui_vr.cpp ..\source\imgui_widgets.cpp | ForEach-Object {
42 | if ($_.StartsWith("#") -or $_.Length -eq 0) {
43 | return # Ignore comments
44 | }
45 |
46 | if ($_.StartsWith("msgid")) {
47 | $is_inside_message = $true
48 | }
49 | if ($_.StartsWith("msgstr")) {
50 | $hash = compute_crc16([System.Text.Encoding]::UTF8.GetBytes($message.Trim('"').Replace("\`"", "`"").Replace("\\", "\").Replace("\n", "`n")))
51 |
52 | # Check if there is an existing message in the language file for this hash, which should be preserved
53 | if ($lang_messages.Keys -contains $hash) {
54 | $message = $lang_messages.$hash
55 | }
56 |
57 | $message = $message.Replace("\`"", "`"`"")
58 | $strings += "$hash $message`r`n"
59 |
60 | $message = ""
61 | $is_inside_message = $false
62 | return
63 | }
64 |
65 | if ($is_inside_message) {
66 | if ($message.Length -ne 0) {
67 | $message = $message.Remove($message.Length - 1) + $_.Substring($_.IndexOf('"') + 1)
68 | } else {
69 | $message += $_.Substring($_.IndexOf('"'))
70 | }
71 | }
72 | }
73 | }
74 |
75 | $ci = New-Object -TypeName System.Globalization.CultureInfo -ArgumentList $locale
76 | $locale = $ci.Name
77 | $locale_name = $ci.EnglishName
78 | $locale_short = $ci.ThreeLetterWindowsLanguageName
79 | $locale_lang_id = $ci.LCID -band 0x3FF
80 | $locale_sublang_id = ($ci.LCID -band 0xFC00) -shr 10
81 |
82 | @"
83 | /////////////////////////////////////////////////////////////////////////////
84 | // $locale_name resources
85 |
86 | #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_$locale_short)
87 | LANGUAGE $locale_lang_id, $locale_sublang_id
88 |
89 | /////////////////////////////////////////////////////////////////////////////
90 | //
91 | // String Table
92 | //
93 |
94 | STRINGTABLE
95 | BEGIN
96 |
97 | $strings
98 | END
99 |
100 | #endif // $locale_name resources
101 | /////////////////////////////////////////////////////////////////////////////
102 | "@ | Out-String | Set-Variable lang_data
103 | # Cannot use 'Out-File' directly, since it does not support in UTF8 without BOM in older Powershell versions
104 | [System.IO.File]::WriteAllText($lang_file, $lang_data, [System.Text.UTF8Encoding]::new($false))
105 |
--------------------------------------------------------------------------------
/tools/update_all_languages.ps1:
--------------------------------------------------------------------------------
1 | if ((Get-Command "xgettext.exe" -ErrorAction SilentlyContinue) -eq $null)
2 | {
3 | Write-Host "Unable to find xgettext.exe. Please download https://gnuwin32.sourceforge.net/packages/gettext.htm."
4 | return
5 | }
6 |
7 | .\create_language_template.ps1 bg-BG
8 | .\create_language_template.ps1 de-DE
9 | .\create_language_template.ps1 en-US
10 | .\create_language_template.ps1 es-ES
11 | .\create_language_template.ps1 fr-FR
12 | .\create_language_template.ps1 ja-JP
13 | .\create_language_template.ps1 ko-KR
14 | .\create_language_template.ps1 ru-RU
15 | .\create_language_template.ps1 zh-CN
16 |
--------------------------------------------------------------------------------
/tools/update_version.ps1:
--------------------------------------------------------------------------------
1 | Param(
2 | [Parameter(Mandatory = $true)][string]
3 | $path,
4 | [string]
5 | $config = "Release",
6 | [string]
7 | $platform = "x64"
8 | )
9 |
10 | $exists = Test-Path $path
11 | $version = 0,0,0,0
12 |
13 | # Get version from existing file
14 | if ($exists -and $(Get-Content $path | Out-String) -match "VERSION_FULL (\d+).(\d+).(\d+).(\d+)") {
15 | $version = [int]::Parse($matches[1]), [int]::Parse($matches[2]), [int]::Parse($matches[3]), [int]::Parse($matches[4])
16 | }
17 | elseif ($(git describe --tags) -match "v(\d+)\.(\d+)\.(\d+)(-\d+-\w+)?") {
18 | $version = [int]::Parse($matches[1]), [int]::Parse($matches[2]), [int]::Parse($matches[3]), 0
19 | }
20 |
21 | # Increment build version for release builds
22 | if (($config -eq "Release") -or
23 | ($config -eq "Release Signed")) {
24 | $version[3] += 1
25 | "Updating version to $([string]::Join('.', $version)) ..."
26 | }
27 | elseif ($exists) {
28 | return
29 | }
30 |
31 | $official = Test-Path ($path + "\..\sign.pfx")
32 |
33 | # Update version file with the new version information
34 | @"
35 | #pragma once
36 |
37 | #define VERSION_FULL $([string]::Join('.', $version))
38 | #define VERSION_MAJOR $($version[0])
39 | #define VERSION_MINOR $($version[1])
40 | #define VERSION_REVISION $($version[2])
41 | #define VERSION_BUILD $($version[3])
42 |
43 | #define VERSION_STRING_FILE "$([string]::Join('.', $version))"
44 | #define VERSION_STRING_PRODUCT "$($version[0]).$($version[1]).$($version[2])$(if (-not $official) { " UNOFFICIAL" })"
45 | "@ | Out-File -FilePath $path -Encoding ASCII
46 |
--------------------------------------------------------------------------------