Skip to content

Commit

Permalink
Fix add-on events being called when internal D3D9/11/12 resources are…
Browse files Browse the repository at this point in the history
… mapped or unmapped
  • Loading branch information
crosire committed Jun 17, 2022
1 parent b73baf5 commit 8da99e6
Show file tree
Hide file tree
Showing 9 changed files with 187 additions and 41 deletions.
3 changes: 3 additions & 0 deletions ReShade.vcxproj
Expand Up @@ -627,6 +627,7 @@
<ClInclude Include="source\d3d10\d3d10_impl_swapchain.hpp" />
<ClInclude Include="source\d3d10\d3d10_impl_type_convert.hpp" />
<ClInclude Include="source\d3d10\d3d10_resource.hpp" />
<ClInclude Include="source\d3d10\d3d10_resource_call_vtable.inl" />
<ClInclude Include="source\d3d11\d3d11on12_device.hpp" />
<ClInclude Include="source\d3d11\d3d11_command_list.hpp" />
<ClInclude Include="source\d3d11\d3d11_device.hpp" />
Expand All @@ -650,13 +651,15 @@
<ClInclude Include="source\d3d12\d3d12_impl_type_convert.hpp" />
<ClInclude Include="source\d3d12\d3d12_pipeline_library.hpp" />
<ClInclude Include="source\d3d12\d3d12_resource.hpp" />
<ClInclude Include="source\d3d12\d3d12_resource_call_vtable.inl" />
<ClInclude Include="source\d3d12\descriptor_heap.hpp" />
<ClInclude Include="source\d3d9\d3d9_device.hpp" />
<ClInclude Include="source\d3d9\d3d9_impl_device.hpp" />
<ClInclude Include="source\d3d9\d3d9_impl_state_block.hpp" />
<ClInclude Include="source\d3d9\d3d9_impl_swapchain.hpp" />
<ClInclude Include="source\d3d9\d3d9_impl_type_convert.hpp" />
<ClInclude Include="source\d3d9\d3d9_resource.hpp" />
<ClInclude Include="source\d3d9\d3d9_resource_call_vtable.inl" />
<ClInclude Include="source\d3d9\d3d9_swapchain.hpp" />
<ClInclude Include="source\dll_log.hpp" />
<ClInclude Include="source\dll_resources.hpp" />
Expand Down
9 changes: 9 additions & 0 deletions ReShade.vcxproj.filters
Expand Up @@ -452,6 +452,9 @@
<ClInclude Include="source\d3d9\d3d9_resource.hpp">
<Filter>hooks\d3d9</Filter>
</ClInclude>
<ClInclude Include="source\d3d9\d3d9_resource_call_vtable.inl">
<Filter>hooks\d3d9</Filter>
</ClInclude>
<ClInclude Include="source\d3d9\d3d9_swapchain.hpp">
<Filter>hooks\d3d9</Filter>
</ClInclude>
Expand All @@ -473,6 +476,9 @@
<ClInclude Include="source\d3d10\d3d10_resource.hpp">
<Filter>hooks\d3d10</Filter>
</ClInclude>
<ClInclude Include="source\d3d10\d3d10_resource_call_vtable.inl">
<Filter>hooks\d3d10</Filter>
</ClInclude>
<ClInclude Include="source\d3d11\d3d11_command_list.hpp">
<Filter>hooks\d3d11</Filter>
</ClInclude>
Expand Down Expand Up @@ -542,6 +548,9 @@
<ClInclude Include="source\d3d12\d3d12_resource.hpp">
<Filter>hooks\d3d12</Filter>
</ClInclude>
<ClInclude Include="source\d3d12\d3d12_resource_call_vtable.inl">
<Filter>hooks\d3d12</Filter>
</ClInclude>
<ClInclude Include="source\d3d12\descriptor_heap.hpp">
<Filter>hooks\d3d12</Filter>
</ClInclude>
Expand Down
5 changes: 3 additions & 2 deletions source/d3d10/d3d10_impl_command_list.cpp
Expand Up @@ -5,6 +5,7 @@

#include "d3d10_impl_device.hpp"
#include "d3d10_impl_type_convert.hpp"
#include "d3d10_resource_call_vtable.inl"
#include "dll_log.hpp"

void reshade::d3d10::pipeline_impl::apply(ID3D10Device *ctx, api::pipeline_stage stages) const
Expand Down Expand Up @@ -272,10 +273,10 @@ void reshade::d3d10::device_impl::push_constants(api::shader_stage stages, api::

// Discard the buffer to so driver can return a new memory region to avoid stalls
if (uint32_t *mapped_data;
SUCCEEDED(push_constants->Map(D3D10_MAP_WRITE_DISCARD, 0, reinterpret_cast<void **>(&mapped_data))))
SUCCEEDED(ID3D10Buffer_Map(push_constants, D3D10_MAP_WRITE_DISCARD, 0, reinterpret_cast<void **>(&mapped_data))))
{
std::memcpy(mapped_data + first, values, count * sizeof(uint32_t));
push_constants->Unmap();
ID3D10Buffer_Unmap(push_constants);
}

UINT push_constants_slot = 0;
Expand Down
17 changes: 9 additions & 8 deletions source/d3d10/d3d10_impl_device.cpp
Expand Up @@ -5,6 +5,7 @@

#include "d3d10_impl_device.hpp"
#include "d3d10_impl_type_convert.hpp"
#include "d3d10_resource_call_vtable.inl"
#include "dll_log.hpp"
#include <algorithm>

Expand Down Expand Up @@ -404,7 +405,7 @@ bool reshade::d3d10::device_impl::map_buffer_region(api::resource resource, uint

assert(resource.handle != 0);

if (SUCCEEDED(reinterpret_cast<ID3D10Buffer *>(resource.handle)->Map(convert_access_flags(access), 0, out_data)))
if (SUCCEEDED(ID3D10Buffer_Map(reinterpret_cast<ID3D10Buffer *>(resource.handle), convert_access_flags(access), 0, out_data)))
{
*out_data = static_cast<uint8_t *>(*out_data) + offset;
return true;
Expand All @@ -418,7 +419,7 @@ void reshade::d3d10::device_impl::unmap_buffer_region(api::resource resource)
{
assert(resource.handle != 0);

reinterpret_cast<ID3D10Buffer *>(resource.handle)->Unmap();
ID3D10Buffer_Unmap(reinterpret_cast<ID3D10Buffer *>(resource.handle));
}
bool reshade::d3d10::device_impl::map_texture_region(api::resource resource, uint32_t subresource, const api::subresource_box *box, api::map_access access, api::subresource_data *out_data)
{
Expand All @@ -442,15 +443,15 @@ bool reshade::d3d10::device_impl::map_texture_region(api::resource resource, uin
switch (dimension)
{
case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
return SUCCEEDED(static_cast<ID3D10Texture1D *>(object)->Map(
return SUCCEEDED(ID3D10Texture1D_Map(static_cast<ID3D10Texture1D *>(object),
subresource, convert_access_flags(access), 0, &out_data->data));
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
static_assert(sizeof(api::subresource_data) >= sizeof(D3D10_MAPPED_TEXTURE2D));
return SUCCEEDED(static_cast<ID3D10Texture2D *>(object)->Map(
return SUCCEEDED(ID3D10Texture2D_Map(static_cast<ID3D10Texture2D *>(object),
subresource, convert_access_flags(access), 0, reinterpret_cast<D3D10_MAPPED_TEXTURE2D *>(out_data)));
case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
static_assert(sizeof(api::subresource_data) == sizeof(D3D10_MAPPED_TEXTURE3D));
return SUCCEEDED(static_cast<ID3D10Texture3D *>(object)->Map(
return SUCCEEDED(ID3D10Texture3D_Map(static_cast<ID3D10Texture3D *>(object),
subresource, convert_access_flags(access), 0, reinterpret_cast<D3D10_MAPPED_TEXTURE3D *>(out_data)));
}

Expand All @@ -467,13 +468,13 @@ void reshade::d3d10::device_impl::unmap_texture_region(api::resource resource, u
switch (dimension)
{
case D3D10_RESOURCE_DIMENSION_TEXTURE1D:
static_cast<ID3D10Texture1D *>(object)->Unmap(subresource);
ID3D10Texture1D_Unmap(static_cast<ID3D10Texture1D *>(object), subresource);
break;
case D3D10_RESOURCE_DIMENSION_TEXTURE2D:
static_cast<ID3D10Texture2D *>(object)->Unmap(subresource);
ID3D10Texture2D_Unmap(static_cast<ID3D10Texture2D *>(object), subresource);
break;
case D3D10_RESOURCE_DIMENSION_TEXTURE3D:
static_cast<ID3D10Texture3D *>(object)->Unmap(subresource);
ID3D10Texture3D_Unmap(static_cast<ID3D10Texture3D *>(object), subresource);
break;
}
}
Expand Down
43 changes: 43 additions & 0 deletions source/d3d10/d3d10_resource_call_vtable.inl
@@ -0,0 +1,43 @@
/*
* Copyright (C) 2022 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause
*/

#if RESHADE_ADDON && !RESHADE_ADDON_LITE

#include "hook_manager.hpp"

template <size_t vtable_index, typename R, typename T, typename... Args>
static inline R call_vtable(T *object, Args... args)
{
const auto vtable_entry = vtable_from_instance(object) + vtable_index;
const auto func = reshade::hooks::is_hooked(vtable_entry) ?
reshade::hooks::call<R(STDMETHODCALLTYPE *)(T *, Args...)>(nullptr, vtable_entry) :
reinterpret_cast<R(STDMETHODCALLTYPE *)(T *, Args...)>(*vtable_entry);
return func(object, std::forward<Args>(args)...);
}

#define ID3D10Buffer_Map call_vtable<10, HRESULT, ID3D10Buffer, D3D10_MAP, UINT, void **>
#define ID3D10Buffer_Unmap call_vtable<11, HRESULT, ID3D10Buffer>

#define ID3D10Texture1D_Map call_vtable<10, HRESULT, ID3D10Texture1D, UINT, D3D10_MAP, UINT, void **>
#define ID3D10Texture1D_Unmap call_vtable<11, HRESULT, ID3D10Texture1D, UINT>

#define ID3D10Texture2D_Map call_vtable<10, HRESULT, ID3D10Texture2D, UINT, D3D10_MAP, UINT, D3D10_MAPPED_TEXTURE2D *>
#define ID3D10Texture2D_Unmap call_vtable<11, HRESULT, ID3D10Texture2D, UINT>

#define ID3D10Texture3D_Map call_vtable<10, HRESULT, ID3D10Texture3D, UINT, D3D10_MAP, UINT, D3D10_MAPPED_TEXTURE3D *>
#define ID3D10Texture3D_Unmap call_vtable<11, HRESULT, ID3D10Texture3D, UINT>

#else

#define ID3D10Buffer_Map(p, a, b, c) (p)->Map(a, b, c)
#define ID3D10Buffer_Unmap(p) (p)->Unmap()
#define ID3D10Texture1D_Map(p, a, b, c, d) (p)->Map(a, b, c, d)
#define ID3D10Texture1D_Unmap(p, a) (p)->Unmap(a)
#define ID3D10Texture2D_Map(p, a, b, c, d) (p)->Map(a, b, c, d)
#define ID3D10Texture2D_Unmap(p, a) (p)->Unmap(a)
#define ID3D10Texture3D_Map(p, a, b, c, d) (p)->Map(a, b, c, d)
#define ID3D10Texture3D_Unmap(p, a) (p)->Unmap(a)

#endif
21 changes: 11 additions & 10 deletions source/d3d12/d3d12_impl_device.cpp
Expand Up @@ -7,6 +7,7 @@
#include "d3d12_impl_command_queue.hpp"
#include "d3d12_impl_type_convert.hpp"
#include "d3d12_descriptor_heap.hpp"
#include "d3d12_resource_call_vtable.inl"
#include "dll_log.hpp"
#include "dll_resources.hpp"
#include <algorithm>
Expand Down Expand Up @@ -489,7 +490,7 @@ bool reshade::d3d12::device_impl::map_buffer_region(api::resource resource, uint

const D3D12_RANGE no_read = { 0, 0 };

if (SUCCEEDED(reinterpret_cast<ID3D12Resource *>(resource.handle)->Map(0, access == api::map_access::write_only || access == api::map_access::write_discard ? &no_read : nullptr, out_data)))
if (SUCCEEDED(ID3D12Resource_Map(reinterpret_cast<ID3D12Resource *>(resource.handle), 0, access == api::map_access::write_only || access == api::map_access::write_discard ? &no_read : nullptr, out_data)))
{
*out_data = static_cast<uint8_t *>(*out_data) + offset;
return true;
Expand All @@ -503,7 +504,7 @@ void reshade::d3d12::device_impl::unmap_buffer_region(api::resource resource)
{
assert(resource.handle != 0);

reinterpret_cast<ID3D12Resource *>(resource.handle)->Unmap(0, nullptr);
ID3D12Resource_Unmap(reinterpret_cast<ID3D12Resource *>(resource.handle), 0, nullptr);
}
bool reshade::d3d12::device_impl::map_texture_region(api::resource resource, uint32_t subresource, const api::subresource_box *box, api::map_access access, api::subresource_data *out_data)
{
Expand All @@ -528,14 +529,14 @@ bool reshade::d3d12::device_impl::map_texture_region(api::resource resource, uin
out_data->row_pitch = layout.Footprint.RowPitch;
out_data->slice_pitch *= layout.Footprint.RowPitch;

return SUCCEEDED(reinterpret_cast<ID3D12Resource *>(resource.handle)->Map(
return SUCCEEDED(ID3D12Resource_Map(reinterpret_cast<ID3D12Resource *>(resource.handle),
subresource, access == api::map_access::write_only || access == api::map_access::write_discard ? &no_read : nullptr, &out_data->data));
}
void reshade::d3d12::device_impl::unmap_texture_region(api::resource resource, uint32_t subresource)
{
assert(resource.handle != 0);

reinterpret_cast<ID3D12Resource *>(resource.handle)->Unmap(subresource, nullptr);
ID3D12Resource_Unmap(reinterpret_cast<ID3D12Resource *>(resource.handle), subresource, nullptr);
}

void reshade::d3d12::device_impl::update_buffer_region(const void *data, api::resource resource, uint64_t offset, uint64_t size)
Expand Down Expand Up @@ -564,12 +565,12 @@ void reshade::d3d12::device_impl::update_buffer_region(const void *data, api::re

// Fill upload buffer with pixel data
uint8_t *mapped_data;
if (FAILED(intermediate->Map(0, nullptr, reinterpret_cast<void **>(&mapped_data))))
if (FAILED(ID3D12Resource_Map(intermediate.get(), 0, nullptr, reinterpret_cast<void **>(&mapped_data))))
return;

std::memcpy(mapped_data, data, static_cast<size_t>(size));

intermediate->Unmap(0, nullptr);
ID3D12Resource_Unmap(intermediate.get(), 0, nullptr);

assert(!_queues.empty());

Expand Down Expand Up @@ -629,7 +630,7 @@ void reshade::d3d12::device_impl::update_texture_region(const api::subresource_d

// Fill upload buffer with pixel data
uint8_t *mapped_data;
if (FAILED(intermediate->Map(0, nullptr, reinterpret_cast<void **>(&mapped_data))))
if (FAILED(ID3D12Resource_Map(intermediate.get(), 0, nullptr, reinterpret_cast<void **>(&mapped_data))))
return;

for (size_t z = 0; z < num_slices; ++z)
Expand All @@ -647,7 +648,7 @@ void reshade::d3d12::device_impl::update_texture_region(const api::subresource_d
}
}

intermediate->Unmap(0, nullptr);
ID3D12Resource_Unmap(intermediate.get(), 0, nullptr);

assert(!_queues.empty());

Expand Down Expand Up @@ -1239,14 +1240,14 @@ bool reshade::d3d12::device_impl::get_query_pool_results(api::query_pool pool, u
const D3D12_RANGE write_range = { 0, 0 };

void *mapped_data = nullptr;
if (SUCCEEDED(readback_resource->Map(0, &read_range, &mapped_data)))
if (SUCCEEDED(ID3D12Resource_Map(readback_resource.get(), 0, &read_range, &mapped_data)))
{
for (size_t i = 0; i < count; ++i)
{
*reinterpret_cast<uint64_t *>(reinterpret_cast<uint8_t *>(results) + i * stride) = static_cast<uint64_t *>(mapped_data)[first + i];
}

readback_resource->Unmap(0, &write_range);
ID3D12Resource_Unmap(readback_resource.get(), 0, &write_range);

return true;
}
Expand Down
32 changes: 32 additions & 0 deletions source/d3d12/d3d12_resource_call_vtable.inl
@@ -0,0 +1,32 @@
/*
* Copyright (C) 2022 Patrick Mours
* SPDX-License-Identifier: BSD-3-Clause
*/

#if RESHADE_ADDON && !RESHADE_ADDON_LITE

#include "hook_manager.hpp"

template <size_t vtable_index, typename R, typename T, typename... Args>
static inline R call_vtable(T *object, Args... args)
{
const auto vtable_entry = vtable_from_instance(object) + vtable_index;
const auto func = reshade::hooks::is_hooked(vtable_entry) ?
reshade::hooks::call<R(STDMETHODCALLTYPE *)(T *, Args...)>(nullptr, vtable_entry) :
reinterpret_cast<R(STDMETHODCALLTYPE *)(T *, Args...)>(*vtable_entry);
return func(object, std::forward<Args>(args)...);
}

#define ID3D12Resource_GetDevice call_vtable<7, HRESULT, ID3D12Resource, REFIID, void **>

#define ID3D12Resource_Map call_vtable<8, HRESULT, ID3D12Resource, UINT, const D3D12_RANGE *, void **>
#define ID3D12Resource_Unmap call_vtable<9, void, ID3D12Resource, UINT, const D3D12_RANGE *>

#else

#define ID3D12Resource_GetDevice(p, a, b) (p)->GetDevice(a, b)

#define ID3D12Resource_Map(p, a, b, c) (p)->Map(a, b, c)
#define ID3D12Resource_Unmap(p, a, b) (p)->Unmap(a, b)

#endif

0 comments on commit 8da99e6

Please sign in to comment.