8
8
#include < map>
9
9
#include < set>
10
10
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
+
11
34
using namespace reshade ::api;
12
35
13
36
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
53
76
format _back_buffer_format;
54
77
uint16_t _back_buffer_samples;
55
78
resource _back_buffer_resolved = { 0 };
79
+ resource_view _back_buffer_resolved_srv = {};
56
80
std::vector<resource_view> _back_buffer_targets;
81
+ std::vector<resource_view> _back_buffer_revoled_targets;
57
82
58
83
void free_buffer_resources (device* device) {
59
84
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
+
60
90
device->destroy_resource (_back_buffer_resolved);
61
91
_back_buffer_resolved = {};
92
+ device->destroy_resource_view (_back_buffer_resolved_srv);
93
+ _back_buffer_resolved_srv = {};
62
94
63
95
for (const auto view : _back_buffer_targets)
64
96
device->destroy_resource_view (view);
@@ -113,41 +145,60 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
113
145
break ;
114
146
}
115
147
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
+
116
159
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) ||
119
162
!device->create_resource_view (
120
163
_back_buffer_resolved,
121
164
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 ()) ||
126
167
!device->create_resource_view (
127
168
_back_buffer_resolved,
128
169
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 ())) {
134
172
free_buffer_resources (device);
135
173
return false ;
136
174
}
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
+ }
137
188
}
138
189
// Create render targets for the back buffer resources
139
- else if (!device->create_resource_view (
190
+ if (!device->create_resource_view (
140
191
back_buffer_resource,
141
192
resource_usage::render_target,
142
193
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,
144
195
format_to_default_typed (back_buffer_desc.texture .format , 0 ), 0 , 1 , 0 , 1 ),
145
196
&_back_buffer_targets.emplace_back ()) ||
146
197
!device->create_resource_view (
147
198
back_buffer_resource,
148
199
resource_usage::render_target,
149
200
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,
151
202
format_to_default_typed (back_buffer_desc.texture .format , 1 ), 0 , 1 , 0 , 1 ),
152
203
&_back_buffer_targets.emplace_back ()))
153
204
{
@@ -221,7 +272,6 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
221
272
std::map<resource, depth_texture_data_s, cmp_resource> _depth_buffers;
222
273
std::set<effect_runtime*> _effect_runtimes;
223
274
224
-
225
275
void free_depth_resources (device* device, resource depth_texture_resource) {
226
276
auto it = _depth_buffers.find (depth_texture_resource);
227
277
if (it != _depth_buffers.end ()) {
@@ -247,6 +297,48 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
247
297
}
248
298
}
249
299
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
+
250
342
bool render_effects (device* device, effect_runtime* runtime, resource back_buffer_resource, resource depth_buffer_resource) {
251
343
auto & back_buffer_data = _back_buffers.emplace (std::piecewise_construct, std::forward_as_tuple (back_buffer_resource), std::forward_as_tuple ()).first ->second ;
252
344
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
265
357
{
266
358
if (back_buffer_data._back_buffer_samples == 1 )
267
359
{
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);
274
361
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);
277
363
}
278
364
else
279
365
{
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);
286
367
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 );
288
369
}
289
370
}
290
371
@@ -293,23 +374,14 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
293
374
update_dependent_effect_runtime (runtime, depth_buffer_resource, depth_buffer_data._depth_texture_view );
294
375
}
295
376
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);
308
380
}
309
381
310
382
if (back_buffer_data._back_buffer_resolved != 0 )
311
383
{
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 ]);
313
385
}
314
386
else
315
387
{
@@ -321,29 +393,41 @@ struct __declspec(uuid("4F2FCBC8-D459-4325-A4D8-4EE63F5C4571")) device_data_s
321
393
// Stretch main render target back into MSAA back buffer if MSAA is active or copy when format conversion is required
322
394
if (back_buffer_data._back_buffer_resolved != 0 )
323
395
{
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)
325
403
{
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 };
330
405
331
406
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
+
333
423
command_list->barrier (2 , resources, state_new, state_final);
334
424
}
335
425
else
336
426
{
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 };
344
428
345
429
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 );
347
431
command_list->barrier (2 , resources, state_new, state_final);
348
432
}
349
433
}
@@ -398,9 +482,15 @@ extern "C" bool __declspec(dllexport) AdvancedfxRenderEffects(void* pRenderTarge
398
482
399
483
static void on_init_device (device* device) {
400
484
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);
401
488
}
402
489
403
490
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
+
404
494
device->destroy_private_data <device_data_s>();
405
495
}
406
496
@@ -466,11 +556,39 @@ static void on_reshade_present(effect_runtime* runtime) {
466
556
if (nullptr == g_MainRuntime) g_MainRuntime = runtime;
467
557
}
468
558
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
+
469
585
BOOL APIENTRY DllMain (HMODULE hModule, DWORD fdwReason, LPVOID)
470
586
{
471
587
switch (fdwReason)
472
588
{
473
589
case DLL_PROCESS_ATTACH:
590
+ g_hReShadeModule = get_reshade_module_handle ();
591
+
474
592
if (!reshade::register_addon (hModule))
475
593
return FALSE ;
476
594
@@ -489,6 +607,7 @@ BOOL APIENTRY DllMain(HMODULE hModule, DWORD fdwReason, LPVOID)
489
607
break ;
490
608
case DLL_PROCESS_DETACH:
491
609
reshade::unregister_addon (hModule);
610
+ g_hReShadeModule = nullptr ;
492
611
break ;
493
612
}
494
613
0 commit comments