├── res
├── resource.h
├── resource.rc
├── resource.rc2
├── shader_copy_ps.hlsl
├── shader_fullscreen_vs.hlsl
├── shader_imgui_ps.hlsl
├── shader_mipmap_cs.hlsl
└── shader_imgui_vs.hlsl
├── tools
├── 7za.exe
├── verbuild.exe
└── fxc.cpp
├── source
├── input.cpp
├── resource_loading.hpp
├── d3d9
│ ├── state_block.hpp
│ ├── d3d9_profiling.cpp
│ ├── state_block.cpp
│ ├── d3d9_swapchain.hpp
│ ├── runtime_d3d9.hpp
│ └── d3d9_swapchain.cpp
├── moving_average.hpp
├── resource_loading.cpp
├── opengl
│ ├── state_block.hpp
│ ├── runtime_opengl.hpp
│ └── state_block.cpp
├── gui_widgets.hpp
├── dxgi
│ ├── dxgi_d3d10.cpp
│ ├── dxgi_device.hpp
│ ├── format_utils.hpp
│ ├── dxgi_swapchain.hpp
│ └── dxgi_device.cpp
├── hook.cpp
├── log.cpp
├── hook.hpp
├── d3d10
│ ├── state_block.hpp
│ ├── draw_call_tracker.hpp
│ ├── runtime_d3d10.hpp
│ ├── state_block.cpp
│ └── d3d10.cpp
├── update_check.cpp
├── log.hpp
├── d3d11
│ ├── state_block.hpp
│ ├── draw_call_tracker.hpp
│ ├── runtime_d3d11.hpp
│ └── d3d11.cpp
├── input.hpp
├── windows
│ ├── user32.cpp
│ └── ws2_32.cpp
├── d3d12
│ ├── d3d12_command_queue.hpp
│ ├── runtime_d3d12.hpp
│ ├── d3d12.cpp
│ └── d3d12_command_queue.cpp
├── effect_symbol_table.hpp
├── hook_manager.hpp
├── effect_parser.hpp
├── ini_file.cpp
├── com_ptr.hpp
├── effect_preprocessor.hpp
├── runtime_objects.hpp
├── gui_code_editor.hpp
└── ini_file.hpp
├── setup
├── Properties
│ ├── Icon.ico
│ ├── App.xaml
│ ├── AssemblyInfo.cs
│ └── Assembly.manifest
├── FodyWeavers.xml
├── Packages.config
├── IniFile.cs
├── Select.xaml
├── Select.xaml.cs
├── Wizard.xaml
├── Settings.xaml
├── Glass.cs
├── PEInfo.cs
└── Settings.xaml.cs
├── .editorconfig
├── deps
├── stb_impl.c
├── Windows.props
├── gl3w.props
├── utfcpp.props
├── MinHook.props
├── SPIRV.props
├── stb.props
├── ImGui.props
├── MinHook.vcxproj.filters
├── stb.vcxproj
├── MinHook.vcxproj
├── ImGui.vcxproj
└── gl3w.vcxproj
├── ReShadeFXC.vcxproj.filters
├── Common.props
├── .gitignore
├── .gitmodules
├── ReShadeFX.vcxproj.filters
├── LICENSE.md
└── README.md
/res/resource.h:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/res/resource.h
--------------------------------------------------------------------------------
/res/resource.rc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/res/resource.rc
--------------------------------------------------------------------------------
/tools/7za.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/tools/7za.exe
--------------------------------------------------------------------------------
/res/resource.rc2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/res/resource.rc2
--------------------------------------------------------------------------------
/source/input.cpp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/source/input.cpp
--------------------------------------------------------------------------------
/tools/verbuild.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/tools/verbuild.exe
--------------------------------------------------------------------------------
/setup/Properties/Icon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/0101011/reshade/master/setup/Properties/Icon.ico
--------------------------------------------------------------------------------
/setup/FodyWeavers.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | indent_size = 4
5 | indent_style = tab
6 | insert_final_newline = true
7 | trim_trailing_whitespace = true
8 |
--------------------------------------------------------------------------------
/setup/Properties/App.xaml:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/res/shader_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/shader_fullscreen_vs.hlsl:
--------------------------------------------------------------------------------
1 | void main(uint id : SV_VERTEXID, out float4 pos : SV_POSITION, out float2 uv : TEXCOORD0)
2 | {
3 | uv.x = (id == 2) ? 2.0 : 0.0;
4 | uv.y = (id == 1) ? 2.0 : 0.0;
5 | pos = float4(uv * float2(2.0, -2.0) + float2(-1.0, 1.0), 0.0, 1.0);
6 | }
7 |
--------------------------------------------------------------------------------
/res/shader_imgui_ps.hlsl:
--------------------------------------------------------------------------------
1 | Texture2D t0 : register(t0);
2 | SamplerState s0 : register(s0);
3 |
4 | void main(float4 vpos : SV_POSITION, float4 vcol : COLOR0, float2 uv : TEXCOORD0, out float4 col : SV_TARGET)
5 | {
6 | col = t0.Sample(s0, uv);
7 | col *= vcol; // Blend vertex color and texture
8 | }
9 |
--------------------------------------------------------------------------------
/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_resize.h"
10 |
--------------------------------------------------------------------------------
/ReShadeFXC.vcxproj.filters:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/setup/Packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
--------------------------------------------------------------------------------
/deps/Windows.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Shlwapi.lib;WinInet.lib;%(AdditionalDependencies)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/setup/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 |
3 | [assembly: AssemblyTitle("ReShade Setup")]
4 | [assembly: AssemblyVersion("2.0.0.0")]
5 | [assembly: AssemblyDescription("")]
6 | [assembly: AssemblyConfiguration("")]
7 | [assembly: AssemblyCompany("crosire")]
8 | [assembly: AssemblyProduct("ReShade")]
9 | [assembly: AssemblyCopyright("Copyright © 2014. All rights reserved.")]
10 |
--------------------------------------------------------------------------------
/Common.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | $(SolutionDir)bin\$(Platform)\$(Configuration)\
6 | $(SolutionDir)intermediate\$(ProjectName)\$(Platform)\$(Configuration)\
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/gl3w.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\gl3w\include;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/utfcpp.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\utfcpp\source;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/MinHook.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\minhook\include;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/deps/SPIRV.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\spirv\include\spirv\unified1;%(AdditionalIncludeDirectories)
7 |
8 |
9 |
--------------------------------------------------------------------------------
/res/shader_mipmap_cs.hlsl:
--------------------------------------------------------------------------------
1 | SamplerState s0 : register(s0);
2 | Texture2D t0 : register(t0);
3 | RWTexture2D dest : register(u0);
4 |
5 | cbuffer cb0 : register(b0)
6 | {
7 | float2 texel; // 1.0 / dimension
8 | }
9 |
10 | [numthreads(8, 8, 1)]
11 | void main(uint3 tid : SV_DispatchThreadID)
12 | {
13 | float2 uv = texel * (tid.xy + 0.5);
14 |
15 | // Sample input texture and write result to the destination mipmap level
16 | dest[tid.xy] = t0.SampleLevel(s0, uv, 0);
17 | }
18 |
--------------------------------------------------------------------------------
/.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 | *.sdf
19 | *.opensdf
20 | *.suo
21 | *.vcxproj.user
22 |
23 | # Visual Studio performance profiling
24 | *.vsp
25 | *.psess
26 |
27 | # Code signing
28 | *.pfx
29 | *.pvk
30 |
31 | # Temporary OS files
32 | .DS_Store
33 | Thumbs.db
34 |
35 | # Versioning
36 | /res/Version.h
37 |
--------------------------------------------------------------------------------
/res/shader_imgui_vs.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 cb0 : register(b0)
15 | {
16 | float4x4 ProjectionMatrix;
17 | };
18 |
19 | void main(VS_INPUT input, out PS_INPUT output)
20 | {
21 | output.pos = mul(ProjectionMatrix, float4(input.pos.xy, 0.0, 1.0));
22 | output.col = input.col;
23 | output.tex = input.tex;
24 | }
25 |
--------------------------------------------------------------------------------
/deps/stb.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\stb;$(SolutionDir)deps\stb_image_dds;%(AdditionalIncludeDirectories)
7 | _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/deps/ImGui.props:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | $(SolutionDir)deps\imgui;%(AdditionalIncludeDirectories)
7 | IMGUI_DEFINE_MATH_OPERATORS;IMGUI_DISABLE_OBSOLETE_FUNCTIONS;%(PreprocessorDefinitions)
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.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
16 | [submodule "spirv"]
17 | path = deps/spirv
18 | url = https://github.com/KhronosGroup/SPIRV-Headers/
19 |
--------------------------------------------------------------------------------
/source/resource_loading.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "resource.h"
9 |
10 | namespace reshade::resources
11 | {
12 | struct data_resource
13 | {
14 | size_t data_size;
15 | const void *data;
16 | };
17 | struct image_resource : public data_resource
18 | {
19 | unsigned int width, height, bits_per_pixel;
20 | };
21 |
22 | data_resource load_data_resource(unsigned int id);
23 | image_resource load_image_resource(unsigned int id);
24 | }
25 |
--------------------------------------------------------------------------------
/source/d3d9/state_block.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "com_ptr.hpp"
9 | #include
10 |
11 | namespace reshade::d3d9
12 | {
13 | class state_block
14 | {
15 | public:
16 | explicit state_block(IDirect3DDevice9 *device);
17 | ~state_block();
18 |
19 | bool init_state_block();
20 | void release_state_block();
21 |
22 | void capture();
23 | void apply_and_release();
24 |
25 | private:
26 | void release_all_device_objects();
27 |
28 | com_ptr _device;
29 | com_ptr _state_block;
30 | UINT _num_simultaneous_rendertargets;
31 | D3DVIEWPORT9 _viewport;
32 | com_ptr _depth_stencil;
33 | com_ptr _render_targets[8];
34 | };
35 | }
36 |
--------------------------------------------------------------------------------
/source/moving_average.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
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 | inline 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 | {
24 | _tick_list[i] = 0;
25 | }
26 | }
27 | void append(T value)
28 | {
29 | _tick_sum -= _tick_list[_index];
30 | _tick_sum += _tick_list[_index] = value;
31 | _index = ++_index % SAMPLES;
32 | _average = _tick_sum / SAMPLES;
33 | }
34 |
35 | private:
36 | size_t _index;
37 | T _average, _tick_sum, _tick_list[SAMPLES];
38 | };
39 |
--------------------------------------------------------------------------------
/setup/IniFile.cs:
--------------------------------------------------------------------------------
1 | using System.Text;
2 | using System.Runtime.InteropServices;
3 |
4 | public static class IniFile
5 | {
6 | [DllImport("kernel32", CharSet = CharSet.Unicode)]
7 | private static extern int GetPrivateProfileString(string section, string key, string defaultValue, StringBuilder value, int size, string filePath);
8 | [DllImport("kernel32", CharSet = CharSet.Unicode, SetLastError = true)]
9 | [return: MarshalAs(UnmanagedType.Bool)]
10 | private static extern bool WritePrivateProfileString(string section, string key, string value, string filePath);
11 |
12 | public static string ReadValue(string file, string section, string key, string defaultValue = "")
13 | {
14 | var value = new StringBuilder(512);
15 | GetPrivateProfileString(section, key, defaultValue, value, value.Capacity, file);
16 | return value.ToString();
17 | }
18 | public static bool WriteValue(string file, string section, string key, string value)
19 | {
20 | return WritePrivateProfileString(section, key, value, file);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/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 |
23 |
24 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/source/resource_loading.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "resource_loading.hpp"
7 | #include
8 |
9 | extern HMODULE g_module_handle;
10 |
11 | reshade::resources::data_resource reshade::resources::load_data_resource(unsigned int id)
12 | {
13 | const HRSRC info = FindResource(g_module_handle, MAKEINTRESOURCE(id), RT_RCDATA);
14 | const HGLOBAL handle = LoadResource(g_module_handle, info);
15 |
16 | data_resource result;
17 | result.data = LockResource(handle);
18 | result.data_size = SizeofResource(g_module_handle, info);
19 |
20 | return result;
21 | }
22 | reshade::resources::image_resource reshade::resources::load_image_resource(unsigned int id)
23 | {
24 | DIBSECTION dib = {};
25 | const HANDLE handle = LoadImage(g_module_handle, MAKEINTRESOURCE(id), IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION);
26 | GetObject(handle, sizeof(dib), &dib);
27 |
28 | image_resource result;
29 | result.width = dib.dsBm.bmWidth;
30 | result.height = dib.dsBm.bmHeight;
31 | result.bits_per_pixel = dib.dsBm.bmBitsPixel;
32 | result.data = dib.dsBm.bmBits;
33 | result.data_size = dib.dsBmih.biSizeImage;
34 |
35 | return result;
36 | }
37 |
--------------------------------------------------------------------------------
/setup/Select.xaml:
--------------------------------------------------------------------------------
1 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_profiling.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "hook_manager.hpp"
7 | #include
8 |
9 | HOOK_EXPORT int WINAPI D3DPERF_BeginEvent(D3DCOLOR col, LPCWSTR wszName)
10 | {
11 | UNREFERENCED_PARAMETER(col);
12 | UNREFERENCED_PARAMETER(wszName);
13 |
14 | return 0;
15 | }
16 | HOOK_EXPORT int WINAPI D3DPERF_EndEvent()
17 | {
18 | return 0;
19 | }
20 |
21 | HOOK_EXPORT void WINAPI D3DPERF_SetMarker(D3DCOLOR col, LPCWSTR wszName)
22 | {
23 | UNREFERENCED_PARAMETER(col);
24 | UNREFERENCED_PARAMETER(wszName);
25 | }
26 | HOOK_EXPORT void WINAPI D3DPERF_SetRegion(D3DCOLOR col, LPCWSTR wszName)
27 | {
28 | UNREFERENCED_PARAMETER(col);
29 | UNREFERENCED_PARAMETER(wszName);
30 | }
31 | HOOK_EXPORT void WINAPI D3DPERF_SetOptions(DWORD dwOptions)
32 | {
33 | UNREFERENCED_PARAMETER(dwOptions);
34 |
35 | #ifdef _DEBUG // Enable PIX in debug builds (calling 'D3DPERF_SetOptions(1)' disables profiling/analysis tools, so revert that)
36 | reshade::hooks::call(D3DPERF_SetOptions)(0);
37 | #endif
38 | }
39 |
40 | HOOK_EXPORT BOOL WINAPI D3DPERF_QueryRepeatFrame()
41 | {
42 | return FALSE;
43 | }
44 |
45 | HOOK_EXPORT DWORD WINAPI D3DPERF_GetStatus()
46 | {
47 | return 0;
48 | }
49 |
--------------------------------------------------------------------------------
/source/opengl/state_block.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "opengl.hpp"
9 |
10 | namespace reshade::opengl
11 | {
12 | class state_block
13 | {
14 | public:
15 | state_block();
16 |
17 | void capture();
18 | void apply() const;
19 |
20 | #ifndef NDEBUG
21 | mutable bool has_state = false;
22 | #endif
23 |
24 | private:
25 | GLint _vao;
26 | GLint _vbo;
27 | GLint _ubo;
28 | GLint _program;
29 | GLint _textures2d[32], _samplers[32];
30 | GLint _active_texture;
31 | GLint _viewport[4];
32 | GLint _scissor_rect[4];
33 | GLint _scissor_test;
34 | GLint _blend;
35 | GLint _blend_src, _blend_dest;
36 | GLint _blend_eq_color, _blend_eq_alpha;
37 | GLint _depth_test;
38 | GLboolean _depth_mask;
39 | GLint _depth_func;
40 | GLint _stencil_test;
41 | GLint _stencil_ref;
42 | GLint _stencil_func;
43 | GLint _stencil_op_fail, _stencil_op_zfail, _stencil_op_zpass;
44 | GLint _stencil_read_mask, _stencil_mask;
45 | GLint _polygon_mode, _frontface;
46 | GLint _cullface, _cullface_mode;
47 | GLint _fbo;
48 | GLint _srgb;
49 | GLint clip_origin;
50 | GLint clip_depthmode;
51 | GLboolean _color_mask[4];
52 | GLenum _drawbuffers[8];
53 | };
54 | }
55 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ReShade
2 | =======
3 |
4 | This is a generic post-processing injector for games and video software. It exposes an automated way to access both frame color and depth information and a custom shader language called ReShade FX to write effects like ambient occlusion, depth of field, color correction and more which work everywhere.
5 |
6 | ## Building
7 |
8 | You'll need both Git and Visual Studio 2017 or higher to build ReShade. Latter is required since the project makes use of several C++14 and C++17 features. Additionally a Python 2.7.9 or later (Python 3 is supported as well) installation is necessary for the `gl3w` dependency to build.
9 |
10 | 1. Clone this repository including all Git submodules
11 | 2. Open the Visual Studio solution
12 | 3. Select either the "32-bit" or "64-bit" target platform and build the solution (this will build ReShade and all dependencies).
13 |
14 | After the first build, a `version.h` file will show up in the [res](/res) directory. Change the `VERSION_FULL` definition inside to something matching the current release version and rebuild so that shaders from the official repository at https://github.com/crosire/reshade-shaders won't cause a version mismatch error during compilation.
15 |
16 | ## Contributing
17 |
18 | Any contributions to the project are welcomed, it's recommended to use GitHub [pull requests](https://help.github.com/articles/using-pull-requests/).
19 |
20 | ## License
21 |
22 | All source code in this repository is licensed under a [BSD 3-clause license](LICENSE.md).
23 |
--------------------------------------------------------------------------------
/source/gui_widgets.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 |
11 | bool imgui_key_input(const char *name, unsigned int key_data[4], const reshade::input &input);
12 |
13 | bool imgui_font_select(const char *name, std::filesystem::path &path, int &size);
14 |
15 | bool imgui_directory_dialog(const char *name, std::filesystem::path &path);
16 |
17 | bool imgui_directory_input_box(const char *name, std::filesystem::path &path, std::filesystem::path &dialog_path);
18 |
19 | bool imgui_path_list(const char *label, std::vector &paths, std::filesystem::path &dialog_path, const std::filesystem::path &default_path = std::filesystem::path());
20 |
21 | bool imgui_popup_button(const char *label, float width = 0.0f, ImGuiWindowFlags flags = 0);
22 |
23 | bool imgui_list_with_buttons(const char *label, const std::string_view ui_items, int &v);
24 |
25 | bool imgui_drag_with_buttons(const char *label, ImGuiDataType data_type, void *v, int components, const void *v_speed, const void *v_min, const void *v_max, const char *format = nullptr);
26 |
27 | bool imgui_slider_with_buttons(const char *label, ImGuiDataType data_type, void *v, int components, const void *v_speed, const void *v_min, const void *v_max, const char *format = nullptr);
28 |
29 | bool imgui_slider_for_alpha(const char *label, float *v);
30 |
31 | void imgui_image_with_checkerboard_background(ImTextureID user_texture_id, const ImVec2 &size);
32 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi_d3d10.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "hook_manager.hpp"
7 | #include
8 | #include
9 |
10 | // These are filtered out during hook installation (see hook_manager.cpp)
11 | HOOK_EXPORT HRESULT WINAPI DXGIDumpJournal()
12 | {
13 | assert(false);
14 | return E_NOTIMPL;
15 | }
16 | HOOK_EXPORT HRESULT WINAPI DXGIReportAdapterConfiguration()
17 | {
18 | assert(false);
19 | return E_NOTIMPL;
20 | }
21 |
22 | // These are actually called internally by the Direct3D driver on some versions of Windows, so just pass them through
23 | HOOK_EXPORT HRESULT WINAPI DXGID3D10CreateDevice(HMODULE hModule, IDXGIFactory *pFactory, IDXGIAdapter *pAdapter, UINT Flags, void *pUnknown, void **ppDevice)
24 | {
25 | return reshade::hooks::call(DXGID3D10CreateDevice)(hModule, pFactory, pAdapter, Flags, pUnknown, ppDevice);
26 | }
27 | HOOK_EXPORT HRESULT WINAPI DXGID3D10CreateLayeredDevice(void *pUnknown1, void *pUnknown2, void *pUnknown3, void *pUnknown4, void *pUnknown5)
28 | {
29 | return reshade::hooks::call(DXGID3D10CreateLayeredDevice)(pUnknown1, pUnknown2, pUnknown3, pUnknown4, pUnknown5);
30 | }
31 | HOOK_EXPORT SIZE_T WINAPI DXGID3D10GetLayeredDeviceSize(const void *pLayers, UINT NumLayers)
32 | {
33 | return reshade::hooks::call(DXGID3D10GetLayeredDeviceSize)(pLayers, NumLayers);
34 | }
35 | HOOK_EXPORT HRESULT WINAPI DXGID3D10RegisterLayers(const void *pLayers, UINT NumLayers)
36 | {
37 | return reshade::hooks::call(DXGID3D10RegisterLayers)(pLayers, NumLayers);
38 | }
39 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/setup/Select.xaml.cs:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | using System.Collections.Generic;
7 | using System.ComponentModel;
8 | using System.IO;
9 | using System.Linq;
10 | using System.Windows;
11 | using System.Windows.Controls;
12 |
13 | namespace ReShade.Setup
14 | {
15 | public partial class SelectWindow : Window
16 | {
17 | public class EffectItem : INotifyPropertyChanged
18 | {
19 | public string Name { get; set; }
20 | public string Path { get; set; }
21 |
22 | public bool IsChecked
23 | {
24 | get
25 | {
26 | return _isChecked;
27 | }
28 | set
29 | {
30 | _isChecked = value;
31 | PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("IsChecked"));
32 | }
33 | }
34 |
35 | private bool _isChecked = true;
36 | public event PropertyChangedEventHandler PropertyChanged;
37 | }
38 |
39 | public SelectWindow(IEnumerable effectFiles)
40 | {
41 | InitializeComponent();
42 |
43 | EffectList.ItemsSource =
44 | effectFiles
45 | .Where(it => Path.GetExtension(it) == ".fx")
46 | .Select(it => new EffectItem {
47 | Name = Path.GetFileName(it),
48 | Path = it
49 | });
50 | }
51 |
52 | public IEnumerable GetSelection()
53 | {
54 | return EffectList.Items.Cast();
55 | }
56 |
57 | private void ChangeChecked(object sender, RoutedEventArgs e)
58 | {
59 | var button = (Button)sender;
60 | bool check = (string)button.Content == "Check All";
61 | button.Content = check ? "Uncheck All" : "Check All";
62 |
63 | foreach (EffectItem item in EffectList.Items)
64 | {
65 | item.IsChecked = check;
66 | }
67 | }
68 | private void ConfirmSelection(object sender, RoutedEventArgs e)
69 | {
70 | Close();
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/source/d3d9/state_block.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "state_block.hpp"
7 | #include
8 |
9 | reshade::d3d9::state_block::state_block(IDirect3DDevice9 *device)
10 | {
11 | ZeroMemory(this, sizeof(*this));
12 |
13 | _device = device;
14 |
15 | D3DCAPS9 caps;
16 | device->GetDeviceCaps(&caps);
17 | _num_simultaneous_rendertargets = std::min(caps.NumSimultaneousRTs, DWORD(8));
18 | }
19 | reshade::d3d9::state_block::~state_block()
20 | {
21 | release_all_device_objects();
22 | }
23 |
24 | void reshade::d3d9::state_block::capture()
25 | {
26 | _state_block->Capture();
27 |
28 | _device->GetViewport(&_viewport);
29 |
30 | for (DWORD target = 0; target < _num_simultaneous_rendertargets; target++)
31 | _device->GetRenderTarget(target, &_render_targets[target]);
32 | _device->GetDepthStencilSurface(&_depth_stencil);
33 | }
34 | void reshade::d3d9::state_block::apply_and_release()
35 | {
36 | _state_block->Apply();
37 |
38 | for (DWORD target = 0; target < _num_simultaneous_rendertargets; target++)
39 | _device->SetRenderTarget(target, _render_targets[target].get());
40 | _device->SetDepthStencilSurface(_depth_stencil.get());
41 |
42 | // Set viewport after render targets have been set, since 'SetRenderTarget' causes the viewport to be set to the full size of the render target
43 | _device->SetViewport(&_viewport);
44 |
45 | release_all_device_objects();
46 | }
47 |
48 | bool reshade::d3d9::state_block::init_state_block()
49 | {
50 | return SUCCEEDED(_device->CreateStateBlock(D3DSBT_ALL, &_state_block));
51 | }
52 | void reshade::d3d9::state_block::release_state_block()
53 | {
54 | _state_block.reset();
55 | }
56 | void reshade::d3d9::state_block::release_all_device_objects()
57 | {
58 | _depth_stencil.reset();
59 | for (auto &render_target : _render_targets)
60 | render_target.reset();
61 | }
62 |
--------------------------------------------------------------------------------
/source/hook.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "hook.hpp"
7 | #include
8 | #include
9 |
10 | static unsigned long s_reference_count = 0;
11 |
12 | void reshade::hook::enable(bool enable) const
13 | {
14 | if (enable)
15 | MH_QueueEnableHook(target);
16 | else
17 | MH_QueueDisableHook(target);
18 | }
19 |
20 | reshade::hook::status reshade::hook::install()
21 | {
22 | if (!valid())
23 | return hook::status::unsupported_function;
24 |
25 | // Only leave MinHook active as long as any hooks exist
26 | if (s_reference_count++ == 0)
27 | MH_Initialize();
28 |
29 | const MH_STATUS statuscode = MH_CreateHook(target, replacement, &trampoline);
30 |
31 | if (statuscode == MH_OK || statuscode == MH_ERROR_ALREADY_CREATED)
32 | {
33 | // Installation was successful, so enable the hook and return
34 | enable(true);
35 |
36 | return hook::status::success;
37 | }
38 |
39 | if (--s_reference_count == 0)
40 | MH_Uninitialize();
41 |
42 | return static_cast(statuscode);
43 | }
44 | reshade::hook::status reshade::hook::uninstall()
45 | {
46 | if (!valid())
47 | return hook::status::unsupported_function;
48 |
49 | const MH_STATUS statuscode = MH_RemoveHook(target);
50 |
51 | if (statuscode == MH_ERROR_NOT_CREATED)
52 | return hook::status::success; // If the hook was never created, then uninstallation is implicitly successful
53 | else if (statuscode != MH_OK)
54 | return static_cast(statuscode);
55 |
56 | trampoline = nullptr;
57 |
58 | if (--s_reference_count == 0)
59 | MH_Uninitialize(); // If this was the last active hook, MinHook can now be uninialized, since no more are active
60 |
61 | return hook::status::success;
62 | }
63 |
64 | reshade::hook::address reshade::hook::call() const
65 | {
66 | assert(installed());
67 |
68 | return trampoline;
69 | }
70 |
71 | bool reshade::hook::apply_queued_actions()
72 | {
73 | return MH_ApplyQueued() == MH_OK;
74 | }
75 |
--------------------------------------------------------------------------------
/source/log.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include
8 | #include
9 | #include
10 |
11 | std::ofstream reshade::log::stream;
12 | std::ostringstream reshade::log::linestream;
13 | std::vector reshade::log::lines;
14 | static std::mutex s_mutex;
15 |
16 | reshade::log::message::message(level level)
17 | {
18 | SYSTEMTIME time;
19 | GetLocalTime(&time);
20 |
21 | const char level_names[][6] = { "ERROR", "WARN ", "INFO ", "DEBUG" };
22 | assert(static_cast(level) - 1 < _countof(level_names));
23 |
24 | // Lock the stream until the message is complete
25 | s_mutex.lock();
26 |
27 | // Start a new line
28 | linestream.str("");
29 | linestream.clear();
30 |
31 | stream << std::right << std::setfill('0')
32 | #if RESHADE_VERBOSE_LOG
33 | << std::setw(4) << time.wYear << '-'
34 | << std::setw(2) << time.wMonth << '-'
35 | << std::setw(2) << time.wDay << 'T'
36 | #endif
37 | << std::setw(2) << time.wHour << ':'
38 | << std::setw(2) << time.wMinute << ':'
39 | << std::setw(2) << time.wSecond << ':'
40 | << std::setw(3) << time.wMilliseconds << ' '
41 | << '[' << std::setw(5) << GetCurrentThreadId() << ']' << std::setfill(' ') << " | "
42 | << level_names[static_cast(level) - 1] << " | " << std::left;
43 | linestream
44 | << level_names[static_cast(level) - 1] << " | ";
45 | }
46 | reshade::log::message::~message()
47 | {
48 | // Finish the line
49 | stream << std::endl;
50 | linestream << std::endl;
51 |
52 | lines.push_back(linestream.str());
53 |
54 | // The message is finished, we can unlock the stream
55 | s_mutex.unlock();
56 | }
57 |
58 | bool reshade::log::open(const std::filesystem::path &path)
59 | {
60 | stream.open(path, std::ios::out | std::ios::trunc);
61 |
62 | if (!stream.is_open())
63 | return false;
64 |
65 | stream.setf(std::ios::left);
66 | stream.setf(std::ios::showbase);
67 | stream.flush();
68 |
69 | linestream.setf(std::ios::left);
70 | linestream.setf(std::ios::showbase);
71 |
72 | return true;
73 | }
74 |
--------------------------------------------------------------------------------
/source/hook.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
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 | ///
20 | enum class status
21 | {
22 | unknown = -1,
23 | success,
24 | not_executable = 7,
25 | unsupported_function,
26 | allocation_failure,
27 | memory_protection_failure,
28 | };
29 |
30 | ///
31 | /// Actually enable or disable any queued hooks.
32 | ///
33 | static bool apply_queued_actions();
34 |
35 | ///
36 | /// Returns whether this hook is valid.
37 | ///
38 | bool valid() const { return target != nullptr && replacement != nullptr && target != replacement; }
39 | ///
40 | /// Returns whether this hook is currently installed.
41 | ///
42 | bool installed() const { return trampoline != nullptr; }
43 | ///
44 | /// Returns whether this hook is not currently installed.
45 | ///
46 | bool uninstalled() const { return trampoline == nullptr; }
47 |
48 | ///
49 | /// Enable or disable this hook. This queues the action for later execution in .
50 | ///
51 | /// Boolean indicating if hook should be enabled or disabled.
52 | void enable(bool enable) const;
53 | ///
54 | /// Install this hook.
55 | ///
56 | hook::status install();
57 | ///
58 | /// Uninstall this hook.
59 | ///
60 | hook::status uninstall();
61 |
62 | ///
63 | /// Returns the trampoline function address of the hook.
64 | ///
65 | address call() const;
66 | template
67 | T call() const { return reinterpret_cast(call()); }
68 |
69 | address target = nullptr;
70 | address trampoline = nullptr;
71 | address replacement = nullptr;
72 | };
73 | }
74 |
--------------------------------------------------------------------------------
/source/d3d10/state_block.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "com_ptr.hpp"
9 | #include
10 |
11 | namespace reshade::d3d10
12 | {
13 | class state_block
14 | {
15 | public:
16 | explicit state_block(ID3D10Device *device);
17 | ~state_block();
18 |
19 | void capture();
20 | void apply_and_release();
21 |
22 | private:
23 | void release_all_device_objects();
24 |
25 | com_ptr _device;
26 | ID3D10InputLayout *_ia_input_layout;
27 | D3D10_PRIMITIVE_TOPOLOGY _ia_primitive_topology;
28 | ID3D10Buffer *_ia_vertex_buffers[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
29 | UINT _ia_vertex_strides[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
30 | UINT _ia_vertex_offsets[D3D10_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
31 | ID3D10Buffer *_ia_index_buffer;
32 | DXGI_FORMAT _ia_index_format;
33 | UINT _ia_index_offset;
34 | ID3D10VertexShader *_vs;
35 | ID3D10Buffer *_vs_constant_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
36 | ID3D10SamplerState *_vs_sampler_states[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
37 | ID3D10ShaderResourceView *_vs_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
38 | ID3D10GeometryShader *_gs;
39 | ID3D10RasterizerState *_rs_state;
40 | UINT _rs_num_viewports;
41 | D3D10_VIEWPORT _rs_viewports[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
42 | UINT _rs_num_scissor_rects;
43 | D3D10_RECT _rs_scissor_rects[D3D10_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
44 | ID3D10PixelShader *_ps;
45 | ID3D10Buffer *_ps_constant_buffers[D3D10_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
46 | ID3D10SamplerState *_ps_sampler_states[D3D10_COMMONSHADER_SAMPLER_SLOT_COUNT];
47 | ID3D10ShaderResourceView *_ps_shader_resources[D3D10_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
48 | ID3D10BlendState *_om_blend_state;
49 | FLOAT _om_blend_factor[4];
50 | UINT _om_sample_mask;
51 | ID3D10DepthStencilState *_om_depth_stencil_state;
52 | UINT _om_stencil_ref;
53 | ID3D10RenderTargetView *_om_render_targets[D3D10_SIMULTANEOUS_RENDER_TARGET_COUNT];
54 | ID3D10DepthStencilView *_om_depth_stencil;
55 | };
56 | }
57 |
--------------------------------------------------------------------------------
/source/update_check.cpp:
--------------------------------------------------------------------------------
1 | #include "version.h"
2 | #include "runtime.hpp"
3 | #include
4 | #include
5 |
6 | struct scoped_handle
7 | {
8 | scoped_handle(HINTERNET handle) : handle(handle) {}
9 | ~scoped_handle() { InternetCloseHandle(handle); }
10 |
11 | inline operator HINTERNET() const { return handle; }
12 |
13 | private:
14 | HINTERNET handle;
15 | };
16 |
17 | bool reshade::runtime::check_for_update(unsigned long latest_version[3])
18 | {
19 | memset(latest_version, 0, 3 * sizeof(unsigned long));
20 |
21 | #if !defined(_DEBUG)
22 | const scoped_handle handle = InternetOpen(L"reshade", INTERNET_OPEN_TYPE_PRECONFIG, nullptr, nullptr, 0);
23 |
24 | if (handle == nullptr)
25 | return false;
26 |
27 | constexpr auto api_url = TEXT("https://api.github.com/repos/crosire/reshade/tags");
28 |
29 | const scoped_handle request = InternetOpenUrl(handle, api_url, nullptr, 0, INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE | INTERNET_FLAG_NO_CACHE_WRITE, 0);
30 |
31 | if (request == nullptr)
32 | return false;
33 |
34 | CHAR response_data[32];
35 | DWORD response_length = 0;
36 |
37 | if (InternetReadFile(request, response_data, sizeof(response_data) - 1, &response_length) && response_length > 0)
38 | {
39 | response_data[response_length] = '\0';
40 |
41 | const char *version_major_offset = std::strchr(response_data, 'v');
42 | if (version_major_offset == nullptr) return false; else version_major_offset++;
43 | const char *version_minor_offset = std::strchr(version_major_offset, '.');
44 | if (version_minor_offset == nullptr) return false; else version_minor_offset++;
45 | const char *version_revision_offset = std::strchr(version_minor_offset, '.');
46 | if (version_revision_offset == nullptr) return false; else version_revision_offset++;
47 |
48 | latest_version[0] = std::strtoul(version_major_offset, nullptr, 10);
49 | latest_version[1] = std::strtoul(version_minor_offset, nullptr, 10);
50 | latest_version[2] = std::strtoul(version_revision_offset, nullptr, 10);
51 |
52 | return (latest_version[0] > VERSION_MAJOR) ||
53 | (latest_version[0] == VERSION_MAJOR && latest_version[1] > VERSION_MINOR) ||
54 | (latest_version[0] == VERSION_MAJOR && latest_version[1] == VERSION_MINOR && latest_version[2] > VERSION_REVISION);
55 | }
56 | #endif
57 |
58 | return false;
59 | }
60 |
--------------------------------------------------------------------------------
/source/d3d9/d3d9_swapchain.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 |
11 | struct Direct3DDevice9;
12 | namespace reshade::d3d9 { class runtime_d3d9; }
13 |
14 | struct __declspec(uuid("BC52FCE4-1EAC-40C8-84CF-863600BBAA01")) Direct3DSwapChain9 : IDirect3DSwapChain9Ex
15 | {
16 | Direct3DSwapChain9(Direct3DDevice9 *device, IDirect3DSwapChain9 *original, const std::shared_ptr &runtime);
17 | Direct3DSwapChain9(Direct3DDevice9 *device, IDirect3DSwapChain9Ex *original, const std::shared_ptr &runtime);
18 |
19 | Direct3DSwapChain9(const Direct3DSwapChain9 &) = delete;
20 | Direct3DSwapChain9 &operator=(const Direct3DSwapChain9 &) = delete;
21 |
22 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
23 | ULONG STDMETHODCALLTYPE AddRef() override;
24 | ULONG STDMETHODCALLTYPE Release() override;
25 |
26 | #pragma region IDirect3DSwapChain9
27 | HRESULT STDMETHODCALLTYPE Present(const RECT *pSourceRect, const RECT *pDestRect, HWND hDestWindowOverride, const RGNDATA *pDirtyRegion, DWORD dwFlags) override;
28 | HRESULT STDMETHODCALLTYPE GetFrontBufferData(IDirect3DSurface9 *pDestSurface) override;
29 | HRESULT STDMETHODCALLTYPE GetBackBuffer(UINT iBackBuffer, D3DBACKBUFFER_TYPE Type, IDirect3DSurface9 **ppBackBuffer) override;
30 | HRESULT STDMETHODCALLTYPE GetRasterStatus(D3DRASTER_STATUS *pRasterStatus) override;
31 | HRESULT STDMETHODCALLTYPE GetDisplayMode(D3DDISPLAYMODE *pMode) override;
32 | HRESULT STDMETHODCALLTYPE GetDevice(IDirect3DDevice9 **ppDevice) override;
33 | HRESULT STDMETHODCALLTYPE GetPresentParameters(D3DPRESENT_PARAMETERS *pPresentationParameters) override;
34 | #pragma endregion
35 | #pragma region IDirect3DSwapChain9Ex
36 | HRESULT STDMETHODCALLTYPE GetLastPresentCount(UINT *pLastPresentCount) override;
37 | HRESULT STDMETHODCALLTYPE GetPresentStats(D3DPRESENTSTATS *pPresentationStatistics) override;
38 | HRESULT STDMETHODCALLTYPE GetDisplayModeEx(D3DDISPLAYMODEEX *pMode, D3DDISPLAYROTATION *pRotation) override;
39 | #pragma endregion
40 |
41 | bool check_and_upgrade_interface(REFIID riid);
42 |
43 | LONG _ref = 1;
44 | IDirect3DSwapChain9 *_orig;
45 | bool _extended_interface;
46 | Direct3DDevice9 *const _device;
47 | std::shared_ptr _runtime;
48 | };
49 |
--------------------------------------------------------------------------------
/source/log.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 | #include
12 | #include
13 |
14 | #define LOG(LEVEL) LOG_##LEVEL()
15 | #define LOG_INFO() reshade::log::message(reshade::log::level::info)
16 | #define LOG_ERROR() reshade::log::message(reshade::log::level::error)
17 | #define LOG_WARN() reshade::log::message(reshade::log::level::warning)
18 | #define LOG_DEBUG() reshade::log::message(reshade::log::level::debug)
19 |
20 | namespace reshade::log
21 | {
22 | enum class level
23 | {
24 | info = 3,
25 | error = 1,
26 | warning = 2,
27 | debug = 4,
28 | };
29 |
30 | extern std::ofstream stream;
31 | extern std::ostringstream linestream;
32 | extern std::vector lines;
33 |
34 | struct message
35 | {
36 | message(level level);
37 | ~message();
38 |
39 | template
40 | inline message &operator<<(const T &value)
41 | {
42 | stream << value;
43 | linestream << value;
44 | return *this;
45 | }
46 |
47 | template <>
48 | inline message &operator<<(const std::wstring &message)
49 | {
50 | static_assert(sizeof(std::wstring::value_type) == sizeof(uint16_t), "expected 'std::wstring' to use UTF-16 encoding");
51 | std::string utf8_message;
52 | utf8_message.reserve(message.size());
53 | utf8::unchecked::utf16to8(message.begin(), message.end(), std::back_inserter(utf8_message));
54 | return operator<<(utf8_message);
55 | }
56 | template <>
57 | inline message &operator<<(const std::filesystem::path &path)
58 | {
59 | return operator<<('"' + path.u8string() + '"');
60 | }
61 |
62 | inline message &operator<<(const char *message)
63 | {
64 | stream << message;
65 | linestream << message;
66 | return *this;
67 | }
68 | inline message &operator<<(const wchar_t *message)
69 | {
70 | static_assert(sizeof(wchar_t) == sizeof(uint16_t), "expected 'wchar_t' to use UTF-16 encoding");
71 | std::string utf8_message;
72 | utf8::unchecked::utf16to8(message, message + wcslen(message), std::back_inserter(utf8_message));
73 | return operator<<(utf8_message);
74 | }
75 | };
76 |
77 | ///
78 | /// Open a log file for writing.
79 | ///
80 | /// The path to the log file.
81 | bool open(const std::filesystem::path &path);
82 | }
83 |
--------------------------------------------------------------------------------
/setup/Wizard.xaml:
--------------------------------------------------------------------------------
1 |
13 |
15 |
25 |
28 |
35 |
42 |
49 |
50 |
51 |
86 |
87 |
88 |
--------------------------------------------------------------------------------
/source/d3d11/state_block.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "com_ptr.hpp"
9 | #include
10 |
11 | namespace reshade::d3d11
12 | {
13 | class state_block
14 | {
15 | public:
16 | explicit state_block(ID3D11Device *device);
17 | ~state_block();
18 |
19 | void capture(ID3D11DeviceContext *devicecontext);
20 | void apply_and_release();
21 |
22 | private:
23 | void release_all_device_objects();
24 |
25 | D3D_FEATURE_LEVEL _device_feature_level;
26 | com_ptr _device;
27 | com_ptr _device_context;
28 | ID3D11InputLayout *_ia_input_layout;
29 | D3D11_PRIMITIVE_TOPOLOGY _ia_primitive_topology;
30 | ID3D11Buffer *_ia_vertex_buffers[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
31 | UINT _ia_vertex_strides[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
32 | UINT _ia_vertex_offsets[D3D11_IA_VERTEX_INPUT_RESOURCE_SLOT_COUNT];
33 | ID3D11Buffer *_ia_index_buffer;
34 | DXGI_FORMAT _ia_index_format;
35 | UINT _ia_index_offset;
36 | ID3D11VertexShader *_vs;
37 | UINT _vs_num_class_instances;
38 | ID3D11ClassInstance *_vs_class_instances[256];
39 | ID3D11Buffer *_vs_constant_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
40 | ID3D11SamplerState *_vs_sampler_states[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
41 | ID3D11ShaderResourceView *_vs_shader_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
42 | ID3D11HullShader *_hs;
43 | UINT _hs_num_class_instances;
44 | ID3D11ClassInstance *_hs_class_instances[256];
45 | ID3D11DomainShader *_ds;
46 | UINT _ds_num_class_instances;
47 | ID3D11ClassInstance *_ds_class_instances[256];
48 | ID3D11GeometryShader *_gs;
49 | UINT _gs_num_class_instances;
50 | ID3D11ClassInstance *_gs_class_instances[256];
51 | ID3D11RasterizerState *_rs_state;
52 | UINT _rs_num_viewports;
53 | D3D11_VIEWPORT _rs_viewports[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
54 | UINT _rs_num_scissor_rects;
55 | D3D11_RECT _rs_scissor_rects[D3D11_VIEWPORT_AND_SCISSORRECT_OBJECT_COUNT_PER_PIPELINE];
56 | ID3D11PixelShader *_ps;
57 | UINT _ps_num_class_instances;
58 | ID3D11ClassInstance *_ps_class_instances[256];
59 | ID3D11Buffer *_ps_constant_buffers[D3D11_COMMONSHADER_CONSTANT_BUFFER_API_SLOT_COUNT];
60 | ID3D11SamplerState *_ps_sampler_states[D3D11_COMMONSHADER_SAMPLER_SLOT_COUNT];
61 | ID3D11ShaderResourceView *_ps_shader_resources[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT];
62 | ID3D11BlendState *_om_blend_state;
63 | FLOAT _om_blend_factor[4];
64 | UINT _om_sample_mask;
65 | ID3D11DepthStencilState *_om_depth_stencil_state;
66 | UINT _om_stencil_ref;
67 | ID3D11RenderTargetView *_om_render_targets[D3D11_SIMULTANEOUS_RENDER_TARGET_COUNT];
68 | ID3D11DepthStencilView *_om_depth_stencil;
69 | };
70 | }
71 |
--------------------------------------------------------------------------------
/source/input.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 | #include
10 | #include
11 |
12 | namespace reshade
13 | {
14 | class input
15 | {
16 | public:
17 | using window_handle = void *;
18 |
19 | explicit input(window_handle window);
20 |
21 | static void register_window_with_raw_input(window_handle window, bool no_legacy_keyboard, bool no_legacy_mouse);
22 | static std::shared_ptr register_window(window_handle window);
23 |
24 | bool is_key_down(unsigned int keycode) const;
25 | bool is_key_pressed(unsigned int keycode) const;
26 | bool is_key_pressed(unsigned int keycode, bool ctrl, bool shift, bool alt) const;
27 | bool is_key_pressed(const unsigned int key[4]) const { return is_key_pressed(key[0], key[1] != 0, key[2] != 0, key[3] != 0); }
28 | bool is_key_released(unsigned int keycode) const;
29 | bool is_any_key_down() const;
30 | bool is_any_key_pressed() const;
31 | bool is_any_key_released() const;
32 | unsigned int last_key_pressed() const;
33 | unsigned int last_key_released() const;
34 | bool is_mouse_button_down(unsigned int button) const;
35 | bool is_mouse_button_pressed(unsigned int button) const;
36 | bool is_mouse_button_released(unsigned int button) const;
37 | bool is_any_mouse_button_down() const;
38 | bool is_any_mouse_button_pressed() const;
39 | bool is_any_mouse_button_released() const;
40 | short mouse_wheel_delta() const { return _mouse_wheel_delta; }
41 | int mouse_movement_delta_x() const { return _mouse_position[0] - _last_mouse_position[0]; }
42 | int mouse_movement_delta_y() const { return _mouse_position[1] - _last_mouse_position[1]; }
43 | unsigned int mouse_position_x() const { return _mouse_position[0]; }
44 | unsigned int mouse_position_y() const { return _mouse_position[1]; }
45 | const std::wstring &text_input() const { return _text_input; }
46 |
47 | void block_mouse_input(bool enable);
48 | void block_keyboard_input(bool enable);
49 |
50 | bool is_blocking_mouse_input() const { return _block_mouse; }
51 | bool is_blocking_keyboard_input() const { return _block_keyboard; }
52 |
53 | auto lock() { return std::lock_guard(_mutex); }
54 | void next_frame();
55 |
56 | static std::string key_name(unsigned int keycode);
57 | static std::string key_name(const unsigned int key[4]);
58 |
59 | static bool handle_window_message(const void *message_data);
60 |
61 | private:
62 | std::mutex _mutex;
63 | window_handle _window;
64 | bool _block_mouse = false, _block_keyboard = false;
65 | uint8_t _keys[256] = {}, _mouse_buttons[5] = {};
66 | short _mouse_wheel_delta = 0;
67 | unsigned int _mouse_position[2] = {};
68 | unsigned int _last_mouse_position[2] = {};
69 | uint64_t _frame_count = 0;
70 | std::wstring _text_input;
71 | };
72 | }
73 |
--------------------------------------------------------------------------------
/setup/Settings.xaml:
--------------------------------------------------------------------------------
1 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
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 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/source/windows/user32.cpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #include "log.hpp"
7 | #include "hook_manager.hpp"
8 | #include "input.hpp"
9 | #include
10 | #include
11 |
12 | HOOK_EXPORT ATOM WINAPI HookRegisterClassA(const WNDCLASSA *lpWndClass)
13 | {
14 | assert(lpWndClass != nullptr);
15 |
16 | auto wndclass = *lpWndClass;
17 |
18 | if (wndclass.hInstance == GetModuleHandle(nullptr))
19 | {
20 | LOG(INFO) << "Redirecting RegisterClassA" << '(' << lpWndClass << " { " << wndclass.lpszClassName << " }" << ')' << " ...";
21 |
22 | if ((wndclass.style & CS_OWNDC) == 0)
23 | {
24 | LOG(INFO) << "> Adding 'CS_OWNDC' window class style flag to '" << wndclass.lpszClassName << "'.";
25 |
26 | wndclass.style |= CS_OWNDC;
27 | }
28 | }
29 |
30 | return reshade::hooks::call(HookRegisterClassA)(&wndclass);
31 | }
32 | HOOK_EXPORT ATOM WINAPI HookRegisterClassW(const WNDCLASSW *lpWndClass)
33 | {
34 | assert(lpWndClass != nullptr);
35 |
36 | auto wndclass = *lpWndClass;
37 |
38 | if (wndclass.hInstance == GetModuleHandle(nullptr))
39 | {
40 | LOG(INFO) << "Redirecting RegisterClassW" << '(' << lpWndClass << " { " << wndclass.lpszClassName << " }" << ')' << " ...";
41 |
42 | if ((wndclass.style & CS_OWNDC) == 0)
43 | {
44 | LOG(INFO) << "> Adding 'CS_OWNDC' window class style flag to '" << wndclass.lpszClassName << "'.";
45 |
46 | wndclass.style |= CS_OWNDC;
47 | }
48 | }
49 |
50 | return reshade::hooks::call(HookRegisterClassW)(&wndclass);
51 | }
52 | HOOK_EXPORT ATOM WINAPI HookRegisterClassExA(const WNDCLASSEXA *lpWndClassEx)
53 | {
54 | assert(lpWndClassEx != nullptr);
55 |
56 | auto wndclass = *lpWndClassEx;
57 |
58 | if (wndclass.hInstance == GetModuleHandle(nullptr))
59 | {
60 | LOG(INFO) << "Redirecting RegisterClassExA" << '(' << lpWndClassEx << " { " << wndclass.lpszClassName << " }" << ')' << " ...";
61 |
62 | if ((wndclass.style & CS_OWNDC) == 0)
63 | {
64 | LOG(INFO) << "> Adding 'CS_OWNDC' window class style flag to '" << wndclass.lpszClassName << "'.";
65 |
66 | wndclass.style |= CS_OWNDC;
67 | }
68 | }
69 |
70 | return reshade::hooks::call(HookRegisterClassExA)(&wndclass);
71 | }
72 | HOOK_EXPORT ATOM WINAPI HookRegisterClassExW(const WNDCLASSEXW *lpWndClassEx)
73 | {
74 | assert(lpWndClassEx != nullptr);
75 |
76 | auto wndclass = *lpWndClassEx;
77 |
78 | if (wndclass.hInstance == GetModuleHandle(nullptr))
79 | {
80 | LOG(INFO) << "Redirecting RegisterClassExW" << '(' << lpWndClassEx << " { " << wndclass.lpszClassName << " }" << ')' << " ...";
81 |
82 | if ((wndclass.style & CS_OWNDC) == 0)
83 | {
84 | LOG(INFO) << "> Adding 'CS_OWNDC' window class style flag to '" << wndclass.lpszClassName << "'.";
85 |
86 | wndclass.style |= CS_OWNDC;
87 | }
88 | }
89 |
90 | return reshade::hooks::call(HookRegisterClassExW)(&wndclass);
91 | }
92 |
--------------------------------------------------------------------------------
/source/d3d12/d3d12_command_queue.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include
9 |
10 | struct __declspec(uuid("2C576D2A-0C1C-4D1D-AD7C-BC4FAEC15ABC")) D3D12CommandQueue : ID3D12CommandQueue
11 | {
12 | D3D12CommandQueue(D3D12Device *device, ID3D12CommandQueue *original);
13 |
14 | D3D12CommandQueue(const D3D12CommandQueue &) = delete;
15 | D3D12CommandQueue &operator=(const D3D12CommandQueue &) = delete;
16 |
17 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
18 | ULONG STDMETHODCALLTYPE AddRef() override;
19 | ULONG STDMETHODCALLTYPE Release() override;
20 |
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 ID3D12CommandQueue
31 | 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;
32 | 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;
33 | void STDMETHODCALLTYPE ExecuteCommandLists(UINT NumCommandLists, ID3D12CommandList *const *ppCommandLists) override;
34 | void STDMETHODCALLTYPE SetMarker(UINT Metadata, const void *pData, UINT Size) override;
35 | void STDMETHODCALLTYPE BeginEvent(UINT Metadata, const void *pData, UINT Size) override;
36 | void STDMETHODCALLTYPE EndEvent() override;
37 | HRESULT STDMETHODCALLTYPE Signal(ID3D12Fence *pFence, UINT64 Value) override;
38 | HRESULT STDMETHODCALLTYPE Wait(ID3D12Fence *pFence, UINT64 Value) override;
39 | HRESULT STDMETHODCALLTYPE GetTimestampFrequency(UINT64 *pFrequency) override;
40 | HRESULT STDMETHODCALLTYPE GetClockCalibration(UINT64 *pGpuTimestamp, UINT64 *pCpuTimestamp) override;
41 | D3D12_COMMAND_QUEUE_DESC STDMETHODCALLTYPE GetDesc() override;
42 | #pragma endregion
43 |
44 | ULONG _ref = 1;
45 | ID3D12CommandQueue *const _orig;
46 | D3D12Device *const _device;
47 | };
48 |
--------------------------------------------------------------------------------
/source/dxgi/dxgi_device.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
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, IUnknown *direct3d_device);
13 |
14 | DXGIDevice(const DXGIDevice &) = delete;
15 | DXGIDevice &operator=(const DXGIDevice &) = delete;
16 |
17 | HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppvObj) override;
18 | ULONG STDMETHODCALLTYPE AddRef() override;
19 | ULONG STDMETHODCALLTYPE Release() override;
20 |
21 | #pragma region IDXGIObject
22 | HRESULT STDMETHODCALLTYPE SetPrivateData(REFGUID Name, UINT DataSize, const void *pData) override;
23 | HRESULT STDMETHODCALLTYPE SetPrivateDataInterface(REFGUID Name, const IUnknown *pUnknown) override;
24 | HRESULT STDMETHODCALLTYPE GetPrivateData(REFGUID Name, UINT *pDataSize, void *pData) override;
25 | HRESULT STDMETHODCALLTYPE GetParent(REFIID riid, void **ppParent) override;
26 | #pragma endregion
27 | #pragma region IDXGIDevice
28 | HRESULT STDMETHODCALLTYPE GetAdapter(IDXGIAdapter **pAdapter) override;
29 | HRESULT STDMETHODCALLTYPE CreateSurface(const DXGI_SURFACE_DESC *pDesc, UINT NumSurfaces, DXGI_USAGE Usage, const DXGI_SHARED_RESOURCE *pSharedResource, IDXGISurface **ppSurface) override;
30 | HRESULT STDMETHODCALLTYPE QueryResourceResidency(IUnknown *const *ppResources, DXGI_RESIDENCY *pResidencyStatus, UINT NumResources) override;
31 | HRESULT STDMETHODCALLTYPE SetGPUThreadPriority(INT Priority) override;
32 | HRESULT STDMETHODCALLTYPE GetGPUThreadPriority(INT *pPriority) override;
33 | #pragma endregion
34 | #pragma region IDXGIDevice1
35 | HRESULT STDMETHODCALLTYPE SetMaximumFrameLatency(UINT MaxLatency) override;
36 | HRESULT STDMETHODCALLTYPE GetMaximumFrameLatency(UINT *pMaxLatency) override;
37 | #pragma endregion
38 | #pragma region IDXGIDevice2
39 | HRESULT STDMETHODCALLTYPE OfferResources(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority) override;
40 | HRESULT STDMETHODCALLTYPE ReclaimResources(UINT NumResources, IDXGIResource *const *ppResources, BOOL *pDiscarded) override;
41 | HRESULT STDMETHODCALLTYPE EnqueueSetEvent(HANDLE hEvent) override;
42 | #pragma endregion
43 | #pragma region IDXGIDevice3
44 | void STDMETHODCALLTYPE Trim() override;
45 | #pragma endregion
46 | #pragma region IDXGIDevice4
47 | HRESULT STDMETHODCALLTYPE OfferResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_OFFER_RESOURCE_PRIORITY Priority, UINT Flags) override;
48 | HRESULT STDMETHODCALLTYPE ReclaimResources1(UINT NumResources, IDXGIResource *const *ppResources, DXGI_RECLAIM_RESOURCE_RESULTS *pResults) override;
49 | #pragma endregion
50 |
51 | bool check_and_upgrade_interface(REFIID riid);
52 |
53 | LONG _ref = 1;
54 | IDXGIDevice1 *_orig;
55 | unsigned int _interface_version;
56 | IUnknown *const _direct3d_device;
57 | };
58 |
--------------------------------------------------------------------------------
/source/effect_symbol_table.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_expression.hpp"
9 |
10 | namespace reshadefx
11 | {
12 | ///
13 | /// A scope encapsulating symbols
14 | ///
15 | struct scope
16 | {
17 | std::string name;
18 | unsigned int level, namespace_level;
19 | };
20 |
21 | ///
22 | /// Enumeration of all possible symbol types
23 | ///
24 | enum class symbol_type
25 | {
26 | invalid,
27 | variable,
28 | constant,
29 | function,
30 | intrinsic,
31 | structure,
32 | };
33 |
34 | ///
35 | /// A single symbol in the symbol table
36 | ///
37 | struct symbol
38 | {
39 | symbol_type op = symbol_type::invalid;
40 | uint32_t id = 0;
41 | type type = {};
42 | constant constant = {};
43 | const function_info *function = nullptr;
44 | };
45 |
46 | ///
47 | /// A symbol table managing a list of scopes and symbols
48 | ///
49 | class symbol_table
50 | {
51 | public:
52 | symbol_table();
53 |
54 | ///
55 | /// Enter a new scope as child of the current one.
56 | ///
57 | void enter_scope();
58 | ///
59 | /// Enter a new namespace as child of the current one.
60 | ///
61 | void enter_namespace(const std::string &name);
62 | ///
63 | /// Leave the current scope and enter the parent one.
64 | ///
65 | void leave_scope();
66 | ///
67 | /// Leave the current namespace and enter the parent one.
68 | ///
69 | void leave_namespace();
70 |
71 | ///
72 | /// Get the current scope the symbol table operates in.
73 | ///
74 | ///
75 | const scope ¤t_scope() const { return _current_scope; }
76 |
77 | ///
78 | /// Insert an new symbol in the symbol table. Returns false if a symbol by that name and type already exists.
79 | ///
80 | bool insert_symbol(const std::string &name, const symbol &symbol, bool global = false);
81 |
82 | ///
83 | /// Look for an existing symbol with the specified .
84 | ///
85 | symbol find_symbol(const std::string &name) const;
86 | symbol find_symbol(const std::string &name, const scope &scope, bool exclusive) const;
87 |
88 | ///
89 | /// Search for the best function or intrinsic overload matching the argument list.
90 | ///
91 | bool resolve_function_call(const std::string &name, const std::vector &args, const scope &scope, symbol &data, bool &ambiguous) const;
92 |
93 | private:
94 | struct scoped_symbol : symbol {
95 | scope scope; // Store scope with symbol data
96 | };
97 |
98 | scope _current_scope;
99 | std::unordered_map> _symbol_stack;
101 | };
102 | }
103 |
--------------------------------------------------------------------------------
/source/hook_manager.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "hook.hpp"
9 | #include
10 |
11 | #define HOOK_EXPORT extern "C"
12 |
13 | template
14 | inline reshade::hook::address *vtable_from_instance(T *instance)
15 | {
16 | static_assert(std::is_polymorphic::value, "can only get virtual function table from polymorphic types");
17 |
18 | return *reinterpret_cast(instance);
19 | }
20 |
21 | namespace reshade::hooks
22 | {
23 | ///
24 | /// Install hook for the specified target function.
25 | ///
26 | /// The function name. This is used for debugging only.
27 | /// The address of the target function.
28 | /// The address of the hook function.
29 | /// Set this to true to queue the enable action instead of immediately executing it.
30 | /// The status of the hook installation.
31 | bool install(const char *name, hook::address target, hook::address replacement, bool queue_enable = false);
32 | ///
33 | /// Install hook for the specified virtual function table entry.
34 | ///
35 | /// The function name. This is used for debugging only.
36 | /// The virtual function table pointer of the object to targeted object.
37 | /// The index of the target function in the virtual function table.
38 | /// The address of the hook function.
39 | /// The status of the hook installation.
40 | bool install(const char *name, hook::address vtable[], unsigned int offset, hook::address replacement);
41 | ///
42 | /// Uninstall all previously installed hooks.
43 | /// Only call this function as long as the loader-lock is active, since it is not thread-safe.
44 | ///
45 | void uninstall();
46 |
47 | ///
48 | /// Register the matching exports in the specified module and install or delay their hooking.
49 | /// Only call this function as long as the loader-lock is active, since it is not thread-safe.
50 | ///
51 | /// The file path to the target module.
52 | void register_module(const std::filesystem::path &path);
53 |
54 | ///
55 | /// Call the original/trampoline function for the specified hook.
56 | ///
57 | /// The original target address the hook was installed to (optional).
58 | /// The address of the hook function which was previously used to install a hook.
59 | /// The address of original/trampoline function.
60 | hook::address call(hook::address target, hook::address replacement);
61 | template
62 | inline T call(T replacement, hook::address target = nullptr)
63 | {
64 | return reinterpret_cast(call(target, reinterpret_cast(replacement)));
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/source/effect_parser.hpp:
--------------------------------------------------------------------------------
1 | /**
2 | * Copyright (C) 2014 Patrick Mours. All rights reserved.
3 | * License: https://github.com/crosire/reshade#license
4 | */
5 |
6 | #pragma once
7 |
8 | #include "effect_lexer.hpp"
9 | #include "effect_symbol_table.hpp"
10 | #include
11 |
12 | namespace reshadefx
13 | {
14 | ///
15 | /// A parser for the ReShade FX shader language.
16 | ///
17 | class parser : symbol_table
18 | {
19 | public:
20 | ///
21 | /// Parse the provided input string.
22 | ///
23 | /// The string to analyze.
24 | /// The code generation implementation to use.
25 | /// A boolean value indicating whether parsing was successful or not.
26 | bool parse(std::string source, class codegen *backend);
27 |
28 | ///
29 | /// Get the list of error messages.
30 | ///
31 | std::string &errors() { return _errors; }
32 | const std::string &errors() const { return _errors; }
33 |
34 | private:
35 | void error(const location &location, unsigned int code, const std::string &message);
36 | void warning(const location &location, unsigned int code, const std::string &message);
37 |
38 | void backup();
39 | void restore();
40 |
41 | bool peek(char tok) const { return _token_next.id == static_cast(tok); }
42 | bool peek(tokenid tokid) const { return _token_next.id == tokid; }
43 | void consume();
44 | void consume_until(char tok) { return consume_until(static_cast(tok)); }
45 | void consume_until(tokenid tokid);
46 | bool accept(char tok) { return accept(static_cast(tok)); }
47 | bool accept(tokenid tokid);
48 | bool expect(char tok) { return expect(static_cast(tok)); }
49 | bool expect(tokenid tokid);
50 |
51 | bool accept_type_class(type &type);
52 | bool accept_type_qualifiers(type &type);
53 |
54 | bool parse_type(type &type);
55 |
56 | bool parse_array_size(type &type);
57 |
58 | bool accept_unary_op();
59 | bool accept_postfix_op();
60 | bool peek_multary_op(unsigned int &precedence) const;
61 | bool accept_assignment_op();
62 |
63 | bool parse_expression(expression &expression);
64 | bool parse_expression_unary(expression &expression);
65 | bool parse_expression_multary(expression &expression, unsigned int precedence = 0);
66 | bool parse_expression_assignment(expression &expression);
67 |
68 | bool parse_annotations(std::unordered_map> &annotations);
69 |
70 | bool parse_statement(bool scoped);
71 | bool parse_statement_block(bool scoped);
72 |
73 | bool parse_top();
74 | bool parse_struct();
75 | bool parse_function(type type, std::string name);
76 | bool parse_variable(type type, std::string name, bool global = false);
77 | bool parse_technique();
78 | bool parse_technique_pass(pass_info &info);
79 |
80 | std::string _errors;
81 | token _token, _token_next, _token_backup;
82 | std::unique_ptr _lexer, _lexer_backup;
83 | codegen *_codegen = nullptr;
84 |
85 | std::vector _loop_break_target_stack;
86 | std::vector _loop_continue_target_stack;
87 | type _current_return_type;
88 | };
89 | }
90 |
--------------------------------------------------------------------------------
/source/d3d10/draw_call_tracker.hpp:
--------------------------------------------------------------------------------
1 | #pragma once
2 |
3 | #include