Skip to content

Commit 6ef9f20

Browse files
committed
Add MSAA support (copy pasta from ReShade runtime.cpp) + fix some mistakes
1 parent 8f80b1c commit 6ef9f20

File tree

1 file changed

+176
-57
lines changed

1 file changed

+176
-57
lines changed

src/main.cpp

Lines changed: 176 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,29 @@
88
#include <map>
99
#include <set>
1010

11+
HMODULE g_hReShadeModule = nullptr;
12+
#define IDR_COPY_PS 101
13+
#define IDR_FULLSCREEN_VS 102
14+
15+
struct data_resource
16+
{
17+
size_t data_size;
18+
const void* data;
19+
};
20+
21+
data_resource load_data_resource(HMODULE module_handke, unsigned short id)
22+
{
23+
const HRSRC info = FindResource(module_handke, MAKEINTRESOURCE(id), RT_RCDATA);
24+
assert(info != nullptr);
25+
const HGLOBAL handle = LoadResource(module_handke, info);
26+
27+
data_resource result;
28+
result.data = LockResource(handle);
29+
result.data_size = SizeofResource(module_handke, info);
30+
31+
return result;
32+
}
33+
1134
using namespace reshade::api;
1235

1336
void update_dependent_effect_runtime(effect_runtime* runtime, resource depth_buffer_resource, resource_view rsv);
@@ -53,12 +76,21 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
5376
format _back_buffer_format;
5477
uint16_t _back_buffer_samples;
5578
resource _back_buffer_resolved = { 0 };
79+
resource_view _back_buffer_resolved_srv = {};
5680
std::vector<resource_view> _back_buffer_targets;
81+
std::vector<resource_view> _back_buffer_revoled_targets;
5782

5883
void free_buffer_resources(device* device) {
5984
if (_hasBackBuffer) {
85+
for (const auto view : _back_buffer_revoled_targets)
86+
device->destroy_resource_view(view);
87+
_back_buffer_revoled_targets.clear();
88+
89+
6090
device->destroy_resource(_back_buffer_resolved);
6191
_back_buffer_resolved = {};
92+
device->destroy_resource_view(_back_buffer_resolved_srv);
93+
_back_buffer_resolved_srv = {};
6294

6395
for (const auto view : _back_buffer_targets)
6496
device->destroy_resource_view(view);
@@ -113,41 +145,60 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
113145
break;
114146
}
115147

148+
const bool need_copy_pipeline =
149+
device->get_api() == device_api::d3d10 ||
150+
device->get_api() == device_api::d3d11 ||
151+
device->get_api() == device_api::d3d12;
152+
153+
resource_usage usage = resource_usage::render_target | resource_usage::copy_dest | resource_usage::resolve_dest;
154+
if (need_copy_pipeline)
155+
usage |= resource_usage::shader_resource;
156+
else
157+
usage |= resource_usage::copy_source;
158+
116159
if (!device->create_resource(
117-
resource_desc(_width, _height, 1, 1, format_to_typeless(_back_buffer_format), 1, memory_heap::gpu_only, resource_usage::shader_resource | resource_usage::render_target),
118-
nullptr, resource_usage::shader_resource | resource_usage::render_target, &_back_buffer_resolved) ||
160+
resource_desc(_width, _height, 1, 1, format_to_typeless(_back_buffer_format), 1, memory_heap::gpu_only, usage),
161+
nullptr, back_buffer_desc.texture.samples == 1 ? resource_usage::copy_dest : resource_usage::resolve_dest, &_back_buffer_resolved) ||
119162
!device->create_resource_view(
120163
_back_buffer_resolved,
121164
resource_usage::render_target,
122-
resource_view_desc(
123-
resource_view_type::texture_2d,
124-
format_to_default_typed(_back_buffer_format, 0), 0, 1, 0, 1),
125-
&_back_buffer_targets.emplace_back()) ||
165+
resource_view_desc(format_to_default_typed(_back_buffer_format, 0)),
166+
&_back_buffer_revoled_targets.emplace_back()) ||
126167
!device->create_resource_view(
127168
_back_buffer_resolved,
128169
resource_usage::render_target,
129-
resource_view_desc(
130-
resource_view_type::texture_2d,
131-
format_to_default_typed(_back_buffer_format, 1), 0, 1, 0, 1),
132-
&_back_buffer_targets.emplace_back()))
133-
{
170+
resource_view_desc(format_to_default_typed(_back_buffer_format, 1)),
171+
&_back_buffer_revoled_targets.emplace_back())) {
134172
free_buffer_resources(device);
135173
return false;
136174
}
175+
176+
if (need_copy_pipeline)
177+
{
178+
if (!device->create_resource_view(
179+
_back_buffer_resolved,
180+
resource_usage::shader_resource,
181+
resource_view_desc(_back_buffer_format),
182+
&_back_buffer_resolved_srv))
183+
{
184+
free_buffer_resources(device);
185+
return false;
186+
}
187+
}
137188
}
138189
// Create render targets for the back buffer resources
139-
else if (!device->create_resource_view(
190+
if (!device->create_resource_view(
140191
back_buffer_resource,
141192
resource_usage::render_target,
142193
resource_view_desc(
143-
resource_view_type::texture_2d,
194+
back_buffer_desc.texture.samples > 1 ? resource_view_type::texture_2d_multisample : resource_view_type::texture_2d,
144195
format_to_default_typed(back_buffer_desc.texture.format, 0), 0, 1, 0, 1),
145196
&_back_buffer_targets.emplace_back()) ||
146197
!device->create_resource_view(
147198
back_buffer_resource,
148199
resource_usage::render_target,
149200
resource_view_desc(
150-
resource_view_type::texture_2d,
201+
back_buffer_desc.texture.samples > 1 ? resource_view_type::texture_2d_multisample : resource_view_type::texture_2d,
151202
format_to_default_typed(back_buffer_desc.texture.format, 1), 0, 1, 0, 1),
152203
&_back_buffer_targets.emplace_back()))
153204
{
@@ -221,7 +272,6 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
221272
std::map<resource, depth_texture_data_s, cmp_resource> _depth_buffers;
222273
std::set<effect_runtime*> _effect_runtimes;
223274

224-
225275
void free_depth_resources(device* device, resource depth_texture_resource) {
226276
auto it = _depth_buffers.find(depth_texture_resource);
227277
if (it != _depth_buffers.end()) {
@@ -247,6 +297,48 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
247297
}
248298
}
249299

300+
pipeline _copy_pipeline = {};
301+
pipeline_layout _copy_pipeline_layout = {};
302+
sampler _copy_sampler_state = {};
303+
304+
void on_init_device(device* device) {
305+
sampler_desc sampler_desc = {};
306+
sampler_desc.filter = filter_mode::min_mag_mip_point;
307+
sampler_desc.address_u = texture_address_mode::clamp;
308+
sampler_desc.address_v = texture_address_mode::clamp;
309+
sampler_desc.address_w = texture_address_mode::clamp;
310+
311+
pipeline_layout_param layout_params[2];
312+
layout_params[0] = descriptor_range{ 0, 0, 0, 1, shader_stage::all, 1, descriptor_type::sampler };
313+
layout_params[1] = descriptor_range{ 0, 0, 0, 1, shader_stage::all, 1, descriptor_type::shader_resource_view };
314+
315+
const data_resource vs = load_data_resource(g_hReShadeModule,IDR_FULLSCREEN_VS);
316+
const data_resource ps = load_data_resource(g_hReShadeModule,IDR_COPY_PS);
317+
318+
shader_desc vs_desc = { vs.data, vs.data_size };
319+
shader_desc ps_desc = { ps.data, ps.data_size };
320+
321+
std::vector<pipeline_subobject> subobjects;
322+
subobjects.push_back({ pipeline_subobject_type::vertex_shader, 1, &vs_desc });
323+
subobjects.push_back({ pipeline_subobject_type::pixel_shader, 1, &ps_desc });
324+
325+
if (!device->create_pipeline_layout(2, layout_params, &_copy_pipeline_layout) ||
326+
!device->create_pipeline(_copy_pipeline_layout, static_cast<uint32_t>(subobjects.size()), subobjects.data(), &_copy_pipeline) ||
327+
!device->create_sampler(sampler_desc, &_copy_sampler_state))
328+
{
329+
330+
}
331+
}
332+
333+
void on_destroy_device(device* device) {
334+
device->destroy_pipeline(_copy_pipeline);
335+
_copy_pipeline = {};
336+
device->destroy_pipeline_layout(_copy_pipeline_layout);
337+
_copy_pipeline_layout = {};
338+
device->destroy_sampler(_copy_sampler_state);
339+
_copy_sampler_state = {};
340+
}
341+
250342
bool render_effects(device* device, effect_runtime* runtime, resource back_buffer_resource, resource depth_buffer_resource) {
251343
auto& back_buffer_data = _back_buffers.emplace(std::piecewise_construct, std::forward_as_tuple(back_buffer_resource), std::forward_as_tuple()).first->second;
252344
auto& depth_buffer_data = _depth_buffers.emplace(std::piecewise_construct, std::forward_as_tuple(depth_buffer_resource), std::forward_as_tuple()).first->second;
@@ -265,26 +357,15 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
265357
{
266358
if (back_buffer_data._back_buffer_samples == 1)
267359
{
268-
const resource resources[2] = { back_buffer_resource, back_buffer_data._back_buffer_resolved };
269-
const resource_usage state_old[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
270-
const resource_usage state_new[2] = { resource_usage::copy_source, resource_usage::copy_dest };
271-
const resource_usage state_final[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
272-
273-
command_list->barrier(2, resources, state_old, state_new);
360+
command_list->barrier(back_buffer_resource, resource_usage::present, resource_usage::copy_source);
274361
command_list->copy_texture_region(back_buffer_resource, 0, nullptr, back_buffer_data._back_buffer_resolved, 0, nullptr);
275-
command_list->barrier(2, resources, state_new, state_final);
276-
362+
command_list->barrier(back_buffer_data._back_buffer_resolved, resource_usage::copy_dest, resource_usage::render_target);
277363
}
278364
else
279365
{
280-
const resource resources[2] = { back_buffer_resource, back_buffer_data._back_buffer_resolved };
281-
const resource_usage state_old[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
282-
const resource_usage state_new[2] = { resource_usage::resolve_source, resource_usage::resolve_dest };
283-
const resource_usage state_final[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
284-
285-
command_list->barrier(2, resources, state_old, state_new);
366+
command_list->barrier(back_buffer_resource, resource_usage::present, resource_usage::resolve_source);
286367
command_list->resolve_texture_region(back_buffer_resource, 0, nullptr, back_buffer_data._back_buffer_resolved, 0, 0, 0, 0, back_buffer_data._back_buffer_format);
287-
command_list->barrier(2, resources, state_new, state_final);
368+
command_list->barrier(back_buffer_data._back_buffer_resolved, resource_usage::resolve_dest, resource_usage::render_target);
288369
}
289370
}
290371

@@ -293,23 +374,14 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
293374
update_dependent_effect_runtime(runtime, depth_buffer_resource, depth_buffer_data._depth_texture_view);
294375
}
295376

296-
auto old_depth_buffer_resource_usage = device->get_resource_desc(depth_buffer_resource).usage;
297-
298-
const resource resources[2] = { depth_buffer_resource, depth_buffer_data._depth_texture };
299-
const resource_usage state_old[2] = { old_depth_buffer_resource_usage, resource_usage::shader_resource };
300-
const resource_usage state_new[2] = { resource_usage::copy_source, resource_usage::copy_dest };
301-
const resource_usage state_final[2] = { old_depth_buffer_resource_usage, resource_usage::shader_resource };
302-
303-
command_list->barrier(2, resources, state_old, state_new);
304-
305-
command_list->copy_resource(depth_buffer_resource, depth_buffer_data._depth_texture);
306-
307-
command_list->barrier(2, resources, state_new, state_final);
377+
command_list->barrier(depth_buffer_resource, resource_usage::depth_stencil, resource_usage::copy_source);
378+
command_list->copy_texture_region(depth_buffer_resource, 0, nullptr, depth_buffer_data._depth_texture, 0, nullptr);
379+
command_list->barrier(depth_buffer_data._depth_texture, resource_usage::copy_dest, resource_usage::shader_resource);
308380
}
309381

310382
if (back_buffer_data._back_buffer_resolved != 0)
311383
{
312-
runtime->render_effects(command_list, back_buffer_data._back_buffer_targets[0], back_buffer_data._back_buffer_targets[1]);
384+
runtime->render_effects(command_list, back_buffer_data._back_buffer_revoled_targets[0], back_buffer_data._back_buffer_revoled_targets[1]);
313385
}
314386
else
315387
{
@@ -321,29 +393,41 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
321393
// Stretch main render target back into MSAA back buffer if MSAA is active or copy when format conversion is required
322394
if (back_buffer_data._back_buffer_resolved != 0)
323395
{
324-
if (back_buffer_data._back_buffer_samples == 1)
396+
const resource resources[2] = { back_buffer_resource, back_buffer_data._back_buffer_resolved };
397+
const resource_usage state_old[2] = { resource_usage::copy_source | resource_usage::resolve_source, resource_usage::render_target };
398+
const resource_usage state_final[2] = { resource_usage::present, resource_usage::resolve_dest };
399+
400+
if (device->get_api() == device_api::d3d10 ||
401+
device->get_api() == device_api::d3d11 ||
402+
device->get_api() == device_api::d3d12)
325403
{
326-
const resource resources[2] = { back_buffer_resource, back_buffer_data._back_buffer_resolved };
327-
const resource_usage state_old[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
328-
const resource_usage state_new[2] = { resource_usage::copy_dest, resource_usage::copy_source };
329-
const resource_usage state_final[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
404+
const resource_usage state_new[2] = { resource_usage::render_target, resource_usage::shader_resource };
330405

331406
command_list->barrier(2, resources, state_old, state_new);
332-
command_list->copy_texture_region(back_buffer_data._back_buffer_resolved, 0, nullptr, back_buffer_resource, 0, nullptr);
407+
408+
command_list->bind_pipeline(pipeline_stage::all_graphics, _copy_pipeline);
409+
410+
command_list->push_descriptors(shader_stage::pixel, _copy_pipeline_layout, 0, descriptor_table_update{ {}, 0, 0, 1, descriptor_type::sampler, &_copy_sampler_state });
411+
command_list->push_descriptors(shader_stage::pixel, _copy_pipeline_layout, 1, descriptor_table_update{ {}, 0, 0, 1, descriptor_type::shader_resource_view, &back_buffer_data._back_buffer_resolved_srv });
412+
413+
const viewport viewport = { 0.0f, 0.0f, static_cast<float>(back_buffer_data._width), static_cast<float>(back_buffer_data._height), 0.0f, 1.0f };
414+
command_list->bind_viewports(0, 1, &viewport);
415+
const rect scissor_rect = { 0, 0, static_cast<int32_t>(back_buffer_data._width), static_cast<int32_t>(back_buffer_data._height) };
416+
command_list->bind_scissor_rects(0, 1, &scissor_rect);
417+
418+
const bool srgb_write_enable = (back_buffer_data._back_buffer_format == format::r8g8b8a8_unorm_srgb || back_buffer_data._back_buffer_format == format::b8g8r8a8_unorm_srgb);
419+
command_list->bind_render_targets_and_depth_stencil(1, &back_buffer_data._back_buffer_targets[srgb_write_enable?1:0]);
420+
421+
command_list->draw(3, 1, 0, 0);
422+
333423
command_list->barrier(2, resources, state_new, state_final);
334424
}
335425
else
336426
{
337-
const resource resources[2] = { back_buffer_resource, back_buffer_data._back_buffer_resolved };
338-
const resource_usage state_old[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
339-
const resource_usage state_new[2] = { resource_usage::resolve_dest, resource_usage::resolve_dest };
340-
const resource_usage state_final[2] = { old_back_buffer_resource_usage, resource_usage::shader_resource | resource_usage::render_target };
341-
342-
float color[4] = { 1.0f,1.0f,0.0f,1.0f };
343-
command_list->clear_render_target_view(back_buffer_data._back_buffer_targets[0], color);
427+
const resource_usage state_new[2] = { resource_usage::copy_dest, resource_usage::copy_source };
344428

345429
command_list->barrier(2, resources, state_old, state_new);
346-
command_list->resolve_texture_region(back_buffer_data._back_buffer_resolved, 0, nullptr, back_buffer_resource, 0, 0, 0, 0, back_buffer_data._back_buffer_desc.texture.format);
430+
command_list->copy_texture_region(back_buffer_data._back_buffer_resolved, 0, nullptr, back_buffer_resource, 0, nullptr);
347431
command_list->barrier(2, resources, state_new, state_final);
348432
}
349433
}
@@ -398,9 +482,15 @@ extern "C" bool __declspec(dllexport) AdvancedfxRenderEffects(void* pRenderTarge
398482

399483
static void on_init_device(device* device) {
400484
device->create_private_data<device_data_s>();
485+
486+
auto device_data = device->get_private_data<device_data_s>();
487+
device_data->on_init_device(device);
401488
}
402489

403490
static void on_destroy_device(device* device) {
491+
auto device_data = device->get_private_data<device_data_s>();
492+
device_data->on_destroy_device(device);
493+
404494
device->destroy_private_data<device_data_s>();
405495
}
406496

@@ -466,11 +556,39 @@ static void on_reshade_present(effect_runtime* runtime) {
466556
if (nullptr == g_MainRuntime) g_MainRuntime = runtime;
467557
}
468558

559+
560+
HMODULE get_reshade_module_handle(HMODULE initial_handle = nullptr)
561+
{
562+
static HMODULE handle = initial_handle;
563+
if (handle == nullptr)
564+
{
565+
HMODULE modules[1024]; DWORD num = 0;
566+
if (K32EnumProcessModules(GetCurrentProcess(), modules, sizeof(modules), &num))
567+
{
568+
if (num > sizeof(modules))
569+
num = sizeof(modules);
570+
571+
for (DWORD i = 0; i < num / sizeof(HMODULE); ++i)
572+
{
573+
if (GetProcAddress(modules[i], "ReShadeRegisterAddon") &&
574+
GetProcAddress(modules[i], "ReShadeUnregisterAddon"))
575+
{
576+
handle = modules[i];
577+
break;
578+
}
579+
}
580+
}
581+
}
582+
return handle;
583+
}
584+
469585
BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID)
470586
{
471587
switch (fdwReason)
472588
{
473589
case DLL_PROCESS_ATTACH:
590+
g_hReShadeModule = get_reshade_module_handle();
591+
474592
if (!reshade::register_addon(hModule))
475593
return FALSE;
476594

@@ -489,6 +607,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID)
489607
break;
490608
case DLL_PROCESS_DETACH:
491609
reshade::unregister_addon(hModule);
610+
g_hReShadeModule = nullptr;
492611
break;
493612
}
494613

0 commit comments

Comments
 (0)