@@ -164,7 +164,7 @@ SL_API sl::Result Hooked_slInit(const sl::Preferences& pref, uint64_t sdkVersion
164164 return sl::Result::eOk;
165165 }
166166
167- #if defined(DEBUG_LEVEL_1 ) && !defined(NDEBUG)
167+ #if defined(DEBUG_LEVEL_3 ) && !defined(NDEBUG)
168168 const auto ret = Real_slInit (pref_copy, sdkVersion);
169169#else
170170 const auto ret = Real_slInit (pref, sdkVersion);
@@ -199,6 +199,10 @@ struct TrackedCommandQueueInfo {
199199using TrackedCommandQueueMap = utils::data::ParallelFlatHashMap<ID3D12CommandQueue*, TrackedCommandQueueInfo, std::shared_mutex>;
200200TrackedCommandQueueMap tracked_command_queues;
201201
202+ static constexpr bool SUPPORT_UNKNOWN_CREATE_DXGI_FACTORY2_FLAGS = false ;
203+ // Only zero and DXGI_CREATE_FACTORY_DEBUG are documented; bypass RenoDX/Streamline factory wrapping for anything else unless explicitly enabled above.
204+ static constexpr UINT CREATE_DXGI_FACTORY2_ALLOWED_FLAGS = DXGI_CREATE_FACTORY_DEBUG ;
205+
202206// Result slUpgradeInterface(void** baseInterface)
203207extern " C" decltype (&slUpgradeInterface) Real_slUpgradeInterface = nullptr ;
204208extern " C" sl::Result Hooked_slUpgradeInterface (void ** baseInterface) {
@@ -257,18 +261,21 @@ extern "C" sl::Result Hooked_slUpgradeInterface(void** baseInterface) {
257261
258262 IDXGIFactory7* dxgi_factory7{};
259263 if (SUCCEEDED (unknown->QueryInterface (&dxgi_factory7))) {
260- // dxgiFactory7->Release();
261-
262264 // Upgrade ReShade's internal factory to use the Streamline factory
263265 DXGIFactory* reshade_factory = nullptr ;
264266 UINT size = sizeof (reshade_factory);
265- dxgi_factory7->GetPrivateData (__uuidof (DXGIFactory), &size, &reshade_factory);
266- if (reshade_factory == nullptr ) {
267+ const HRESULT proxy_result = dxgi_factory7->GetPrivateData (__uuidof (DXGIFactory), &size, &reshade_factory);
268+ if (FAILED (proxy_result) || reshade_factory == nullptr ) {
267269 log::e (" utils::streamline_v2::slUpgradeInterface() - Failed to get DXGIFactory proxy from IDXGIFactory7" );
270+ return Real_slUpgradeInterface (baseInterface);
268271 }
269272 auto * Real_factory = (IDXGIFactory7*)reshade_factory->_orig ;
270273
271- Real_slUpgradeInterface ((void **)&Real_factory);
274+ auto ret = Real_slUpgradeInterface ((void **)&Real_factory);
275+ if (ret != sl::Result::eOk) {
276+ log::e (" utils::streamline_v2::slUpgradeInterface() - Failed to upgrade DXGIFactory interface" );
277+ return ret;
278+ }
272279
273280 reshade_factory->_orig = Real_factory;
274281
@@ -564,13 +571,58 @@ extern "C" HRESULT Hooked_D3D12CreateDevice(IUnknown* pAdapter, D3D_FEATURE_LEVE
564571 // assert(IsDebuggerPresent());
565572 renodx::utils::directx::Initialize ();
566573
574+ #ifdef DEBUG_LEVEL_0
575+ log::i (std::format (
576+ " utils::streamline_v2::D3D12CreateDevice(adapter: {:p}, feature_level: {:#x}, ppDevice: {:p})" ,
577+ (void *)pAdapter,
578+ static_cast <uint32_t >(MinimumFeatureLevel),
579+ (void *)ppDevice)
580+ .c_str ());
581+ #endif
582+
567583 assert (is_streamline_device == false );
568584 is_streamline_device = true ;
569585 auto hr = renodx::utils::directx::pD3D12CreateDevice != nullptr
570586 ? renodx::utils::directx::pD3D12CreateDevice (pAdapter, MinimumFeatureLevel, riid, ppDevice)
571587 : E_FAIL ;
572588 is_streamline_device = false ;
573589
590+ #ifdef DEBUG_LEVEL_0
591+ log::i (std::format (
592+ " utils::streamline_v2::D3D12CreateDevice -> hr: {:#010x}, device: {:p}" ,
593+ static_cast <uint32_t >(hr),
594+ ppDevice != nullptr ? *ppDevice : nullptr )
595+ .c_str ());
596+ #endif
597+
598+ return hr;
599+ }
600+
601+ extern " C" decltype (&D3D12GetInterface) Real_D3D12GetInterface = nullptr ;
602+ extern " C" HRESULT Hooked_D3D12GetInterface (REFCLSID rclsid, REFIID riid, void ** ppvDebug) {
603+ renodx::utils::directx::Initialize ();
604+
605+ #ifdef DEBUG_LEVEL_0
606+ log::i (std::format (
607+ " utils::streamline_v2::D3D12GetInterface(rclsid: {}, riid: {}, out: {:p})" ,
608+ rclsid.Data1 ,
609+ riid.Data1 ,
610+ (void *)ppvDebug)
611+ .c_str ());
612+ #endif
613+
614+ auto hr = renodx::utils::directx::pD3D12GetInterface != nullptr
615+ ? renodx::utils::directx::pD3D12GetInterface (rclsid, riid, ppvDebug)
616+ : E_NOINTERFACE ;
617+
618+ #ifdef DEBUG_LEVEL_0
619+ log::i (std::format (
620+ " utils::streamline_v2::D3D12GetInterface -> hr: {:#010x}, interface: {:p}" ,
621+ static_cast <uint32_t >(hr),
622+ ppvDebug != nullptr ? *ppvDebug : nullptr )
623+ .c_str ());
624+ #endif
625+
574626 return hr;
575627}
576628
@@ -582,33 +634,77 @@ extern "C" HRESULT Hooked_CreateDXGIFactory1(REFIID riid, void** ppFactory) {
582634static decltype (&CreateDXGIFactory2) Real_CreateDXGIFactory2 = nullptr;
583635SL_API HRESULT Hooked_CreateDXGIFactory2 (UINT flags, REFIID riid, void ** ppFactory) {
584636 renodx::utils::directx::Initialize ();
637+ #ifdef DEBUG_LEVEL_0
638+ log::i (std::format (
639+ " utils::streamline_v2::CreateDXGIFactory2(flags: {:#x}, ppFactory: {:p})" ,
640+ flags,
641+ (void *)ppFactory)
642+ .c_str ());
643+ #endif
644+
645+ if (!SUPPORT_UNKNOWN_CREATE_DXGI_FACTORY2_FLAGS && (flags & ~CREATE_DXGI_FACTORY2_ALLOWED_FLAGS ) != 0u ) {
646+ if (renodx::utils::directx::pCreateDXGIFactory2 != nullptr ) {
647+ return renodx::utils::directx::pCreateDXGIFactory2 (flags, riid, ppFactory);
648+ }
649+ if (Real_CreateDXGIFactory2 != nullptr ) {
650+ return Real_CreateDXGIFactory2 (flags, riid, ppFactory);
651+ }
652+ return E_NOINTERFACE ;
653+ }
654+
655+ if (ppFactory == nullptr ) {
656+ return E_POINTER ;
657+ }
658+
659+ if (renodx::utils::directx::pCreateDXGIFactory2 == nullptr ) {
660+ return E_NOINTERFACE ;
661+ }
662+
585663 // Make real ReShade Factory instead of Streamline factory
586664 IDXGIFactory2* unknown = nullptr ;
587665 auto ret = renodx::utils::directx::pCreateDXGIFactory2 (flags, riid, reinterpret_cast <void **>(&unknown));
588- if (ret != S_OK ) {
666+ #ifdef DEBUG_LEVEL_0
667+ log::i (std::format (
668+ " utils::streamline_v2::CreateDXGIFactory2 -> reshade hr: {:#010x}, unknown: {:p}" ,
669+ static_cast <uint32_t >(ret),
670+ (void *)unknown)
671+ .c_str ());
672+ #endif
673+ if (FAILED (ret) || unknown == nullptr ) {
589674 log::e (" utils::streamline_v2::CreateDXGIFactory2() - Failed to create DXGIFactory2" );
590675 return ret;
591676 }
592- IDXGIFactory7* dxgi_factory7{};
593- if (SUCCEEDED (unknown->QueryInterface (&dxgi_factory7))) {
594- dxgi_factory7->Release ();
595-
596- // Upgrade ReShade's internal factory to use the Streamline factory
597- DXGIFactory* reshade_factory = nullptr ;
598- UINT size = sizeof (reshade_factory);
599- dxgi_factory7->GetPrivateData (__uuidof (DXGIFactory), &size, &reshade_factory);
600- if (reshade_factory == nullptr ) {
601- log::e (" utils::streamline_v2::CreateDXGIFactory2() - Failed to get DXGIFactory proxy from IDXGIFactory7" );
602- }
603- auto * real_factory = (IDXGIFactory7*)reshade_factory->_orig ;
604677
605- Real_slUpgradeInterface (( void **)&real_factory); // Now Streamline factory
678+ *ppFactory = unknown;
606679
607- reshade_factory->_orig = real_factory;
680+ // Upgrade ReShade's internal factory to use the Streamline factory
681+ DXGIFactory* reshade_factory = nullptr ;
682+ UINT size = sizeof (reshade_factory);
683+ const HRESULT proxy_result = unknown->GetPrivateData (__uuidof (DXGIFactory), &size, &reshade_factory);
684+ if (FAILED (proxy_result) || reshade_factory == nullptr ) {
685+ log::e (" utils::streamline_v2::CreateDXGIFactory2() - Failed to get DXGIFactory proxy from IDXGIFactory7" );
686+ return ret;
687+ }
688+ auto * real_factory = (IDXGIFactory7*)reshade_factory->_orig ;
608689
609- *ppFactory = reshade_factory;
690+ auto upgrade_result = Real_slUpgradeInterface ((void **)&real_factory); // Now Streamline factory
691+ if (upgrade_result != sl::Result::eOk || real_factory == nullptr ) {
692+ log::e (" utils::streamline_v2::CreateDXGIFactory2() - Failed to upgrade DXGIFactory interface" );
693+ return ret;
610694 }
611695
696+ #ifdef DEBUG_LEVEL_0
697+ log::i (std::format (
698+ " utils::streamline_v2::CreateDXGIFactory2 -> upgraded factory: reshade {:p}, original {:p}" ,
699+ (void *)reshade_factory,
700+ (void *)real_factory)
701+ .c_str ());
702+ #endif
703+
704+ reshade_factory->_orig = real_factory;
705+
706+ *ppFactory = reshade_factory;
707+
612708 return ret;
613709}
614710
@@ -903,8 +999,17 @@ static sl::Result Hooked_slSetTag(const sl::ViewportHandle& viewport, const sl::
903999 }
9041000#endif
9051001
906- sl::ResourceTag* new_tags = nullptr ;
907- std::vector<sl::Resource> rewritten_resources = {};
1002+ static thread_local std::vector<sl::ResourceTag> rewritten_tags;
1003+ static thread_local std::vector<sl::Resource> rewritten_resources;
1004+ uint32_t rewritten_resource_count = 0u ;
1005+ uint32_t last_written_tag_index = 0u ;
1006+ auto copy_tags_until = [&](uint32_t end_index) {
1007+ if (rewritten_tags.size () < numTags) rewritten_tags.resize (numTags);
1008+ if (last_written_tag_index < end_index) {
1009+ memcpy (rewritten_tags.data () + last_written_tag_index, tags + last_written_tag_index, sizeof (sl::ResourceTag) * (end_index - last_written_tag_index));
1010+ last_written_tag_index = end_index;
1011+ }
1012+ };
9081013 for (auto i = 0u ; i < numTags; ++i) {
9091014 const auto & tag = tags[i];
9101015 // if (tag.type == sl::kBufferTypeBackbuffer) continue;
@@ -937,31 +1042,28 @@ static sl::Result Hooked_slSetTag(const sl::ViewportHandle& viewport, const sl::
9371042 }
9381043
9391044 if (redirected_native != tag.resource ->native ) {
940- if (new_tags == nullptr ) {
941- auto size = sizeof (sl::ResourceTag) * numTags;
942- new_tags = reinterpret_cast <sl::ResourceTag*>(malloc (sizeof (sl::ResourceTag) * numTags));
943- memcpy (new_tags, tags, sizeof (sl::ResourceTag) * numTags);
944- rewritten_resources.reserve (numTags);
1045+ if (rewritten_resource_count == 0u ) {
1046+ if (rewritten_resources.size () < numTags) rewritten_resources.resize (numTags);
9451047 }
1048+ copy_tags_until (i);
9461049
947- rewritten_resources.emplace_back (tag.resource ->type , redirected_native, tag.resource ->state );
948- auto new_sl_resource_tag = sl::ResourceTag (&rewritten_resources.back (), tag.type , tag.lifecycle , &tag.extent );
949- new_tags[i] = new_sl_resource_tag;
1050+ rewritten_resources[rewritten_resource_count] = sl::Resource (tag.resource ->type , redirected_native, tag.resource ->state );
1051+ auto new_sl_resource_tag = sl::ResourceTag (&rewritten_resources[rewritten_resource_count++], tag.type , tag.lifecycle , &tag.extent );
1052+ rewritten_tags[i] = new_sl_resource_tag;
1053+ last_written_tag_index = i + 1u ;
9501054 }
951- // }
9521055 }
9531056
9541057 const bool unwrapped = utils::directx::NativeFromReShadeProxy (&cmdBuffer);
9551058 assert ((unwrapped || cmdBuffer == nullptr ) && " slSetTag expected a ReShade proxy command buffer." );
9561059
9571060 // return sl::Result::eOk;
958- if (new_tags == nullptr ) {
1061+ if (rewritten_resource_count == 0u ) {
9591062 return Real_slSetTag (viewport, tags, numTags, cmdBuffer);
9601063 }
1064+ copy_tags_until (numTags);
9611065
962- sl::Result result = Real_slSetTag (viewport, new_tags, numTags, cmdBuffer);
963- free (new_tags);
964- new_tags = nullptr ;
1066+ sl::Result result = Real_slSetTag (viewport, rewritten_tags.data (), numTags, cmdBuffer);
9651067 return result;
9661068}
9671069
@@ -1102,8 +1204,17 @@ static sl::Result Hooked_slSetTagForFrame(const sl::FrameToken& frame, const sl:
11021204 }
11031205#endif
11041206
1105- sl::ResourceTag* new_tags = nullptr ;
1106- std::vector<sl::Resource> rewritten_resources = {};
1207+ static thread_local std::vector<sl::ResourceTag> rewritten_tags;
1208+ static thread_local std::vector<sl::Resource> rewritten_resources;
1209+ uint32_t rewritten_resource_count = 0u ;
1210+ uint32_t last_written_tag_index = 0u ;
1211+ auto copy_tags_until = [&](uint32_t end_index) {
1212+ if (rewritten_tags.size () < numTags) rewritten_tags.resize (numTags);
1213+ if (last_written_tag_index < end_index) {
1214+ memcpy (rewritten_tags.data () + last_written_tag_index, tags + last_written_tag_index, sizeof (sl::ResourceTag) * (end_index - last_written_tag_index));
1215+ last_written_tag_index = end_index;
1216+ }
1217+ };
11071218 for (auto i = 0u ; i < numTags; ++i) {
11081219 const auto & tag = tags[i];
11091220 if (tag.type == sl::kBufferTypeBackbuffer ) continue ;
@@ -1123,29 +1234,27 @@ static sl::Result Hooked_slSetTagForFrame(const sl::FrameToken& frame, const sl:
11231234 }
11241235
11251236 if (redirected_native != tag.resource ->native ) {
1126- if (new_tags == nullptr ) {
1127- auto size = sizeof (sl::ResourceTag) * numTags;
1128- new_tags = reinterpret_cast <sl::ResourceTag*>(malloc (sizeof (sl::ResourceTag) * numTags));
1129- memcpy (new_tags, tags, sizeof (sl::ResourceTag) * numTags);
1130- rewritten_resources.reserve (numTags);
1237+ if (rewritten_resource_count == 0u ) {
1238+ if (rewritten_resources.size () < numTags) rewritten_resources.resize (numTags);
11311239 }
1240+ copy_tags_until (i);
11321241
1133- rewritten_resources.emplace_back (tag.resource ->type , redirected_native, tag.resource ->state );
1134- auto new_sl_resource_tag = sl::ResourceTag (&rewritten_resources.back (), tag.type , tag.lifecycle , &tag.extent );
1135- new_tags[i] = new_sl_resource_tag;
1242+ rewritten_resources[rewritten_resource_count] = sl::Resource (tag.resource ->type , redirected_native, tag.resource ->state );
1243+ auto new_sl_resource_tag = sl::ResourceTag (&rewritten_resources[rewritten_resource_count++], tag.type , tag.lifecycle , &tag.extent );
1244+ rewritten_tags[i] = new_sl_resource_tag;
1245+ last_written_tag_index = i + 1u ;
11361246 }
11371247 }
11381248
11391249 const bool unwrapped = utils::directx::NativeFromReShadeProxy (&cmdBuffer);
11401250 assert ((unwrapped || cmdBuffer == nullptr ) && " slSetTagForFrame expected a ReShade proxy command buffer." );
11411251
1142- if (new_tags == nullptr ) {
1252+ if (rewritten_resource_count == 0u ) {
11431253 return Real_slSetTagForFrame (frame, viewport, tags, numTags, cmdBuffer);
11441254 }
1255+ copy_tags_until (numTags);
11451256
1146- sl::Result result = Real_slSetTagForFrame (frame, viewport, new_tags, numTags, cmdBuffer);
1147- free (new_tags);
1148- new_tags = nullptr ;
1257+ sl::Result result = Real_slSetTagForFrame (frame, viewport, rewritten_tags.data (), numTags, cmdBuffer);
11491258 return result;
11501259}
11511260
@@ -1162,6 +1271,7 @@ static const std::vector<std::tuple<const char*, void**, void*>> INTERPOSER_HOOK
11621271 {" CreateDXGIFactory1" , (void **)&Real_CreateDXGIFactory1, &Hooked_CreateDXGIFactory1},
11631272 {" CreateDXGIFactory2" , (void **)&Real_CreateDXGIFactory2, &Hooked_CreateDXGIFactory2},
11641273 {" D3D12CreateDevice" , (void **)&Real_D3D12CreateDevice, &Hooked_D3D12CreateDevice},
1274+ {" D3D12GetInterface" , (void **)&Real_D3D12GetInterface, &Hooked_D3D12GetInterface},
11651275};
11661276
11671277} // namespace renodx::utils::streamline::v2
0 commit comments