Skip to content

Commit 73a3873

Browse files
committed
Add robustness vk extensions for debugging AMD issues
1 parent 9af2412 commit 73a3873

6 files changed

Lines changed: 174 additions & 94 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ While more integrated solutions are being found out, there's probably ways to se
7575
3. Open Cemu normally through the `Cemu.exe` (not the .bat file!).
7676
- Cemu's window title should state Cemu 2.6 or newer. Any older version isn't supported.
7777
- The game should say V208 inside the update column in Cemu's game list. Otherwise it's outdated/not updated, and won't work.
78-
- Go to `Options`->`General Settings`, and then under the `Graphics` tab make sure that you're using Vulkan and that the right GPU is selected.
78+
- Go to `Options`->`General Settings`, and then under the `Graphics` tab make sure that you're using Vulkan, that the right GPU is selected and that VSync is turned off.
7979

8080
If all that is true, continue to the next step by closing the settings window and then Cemu entirely. Otherwise, fix those issues before continuing.
8181

include/pch.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ using Microsoft::WRL::ComPtr;
7171
#include <glm/gtx/euler_angles.hpp>
7272
#undef GLM_ENABLE_EXPERIMENTAL
7373

74+
#define ENABLE_VK_ROBUSTNESS 0
75+
7476
inline glm::fvec2 ToGLM(const XrVector2f& vec) {
7577
return glm::make_vec2(&vec.x);
7678
}

src/hooking/framebuffer.cpp

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,8 +316,9 @@ inline bool IsTimeline(const VkSemaphore semaphore) {
316316
}
317317

318318
VkResult VkDeviceOverrides::QueueSubmit(const vkroots::VkDeviceDispatch* pDispatch, VkQueue queue, uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence) {
319+
VkResult result = VK_SUCCESS;
319320
if (s_activeCopyOperations.empty()) {
320-
return pDispatch->QueueSubmit(queue, submitCount, pSubmits, fence);
321+
result = pDispatch->QueueSubmit(queue, submitCount, pSubmits, fence);
321322
}
322323
else {
323324
Log::print<INTEROP>("QueueSubmit called with {} active copy operations", s_activeCopyOperations.size());
@@ -426,8 +427,42 @@ VkResult VkDeviceOverrides::QueueSubmit(const vkroots::VkDeviceDispatch* pDispat
426427
const_cast<VkSubmitInfo&>(submitInfo).signalSemaphoreCount = (uint32_t)modifiedSubmitInfo.signalSemaphores.size();
427428
const_cast<VkSubmitInfo&>(submitInfo).pSignalSemaphores = modifiedSubmitInfo.signalSemaphores.data();
428429
}
429-
return pDispatch->QueueSubmit(queue, submitCount, pSubmits, fence);
430+
result = pDispatch->QueueSubmit(queue, submitCount, pSubmits, fence);
430431
}
432+
433+
#if ENABLE_VK_ROBUSTNESS
434+
if (result == VK_ERROR_DEVICE_LOST) {
435+
auto vkGetDeviceFaultInfoEXT = (PFN_vkGetDeviceFaultInfoEXT)pDispatch->GetDeviceProcAddr(pDispatch->Device, "vkGetDeviceFaultInfoEXT");
436+
if (vkGetDeviceFaultInfoEXT) {
437+
VkDeviceFaultCountsEXT faultCounts = { VK_STRUCTURE_TYPE_DEVICE_FAULT_COUNTS_EXT };
438+
VkDeviceFaultInfoEXT faultInfo = { VK_STRUCTURE_TYPE_DEVICE_FAULT_INFO_EXT };
439+
440+
if (vkGetDeviceFaultInfoEXT(pDispatch->Device, &faultCounts, nullptr) == VK_SUCCESS) {
441+
Log::print<ERROR>("Device lost! Fault counts: Address info: {}, Vendor info: {}, Vendor binary: {}",
442+
faultCounts.addressInfoCount, faultCounts.vendorInfoCount, faultCounts.vendorBinarySize);
443+
444+
std::vector<VkDeviceFaultAddressInfoEXT> addressInfos(faultCounts.addressInfoCount);
445+
std::vector<VkDeviceFaultVendorInfoEXT> vendorInfos(faultCounts.vendorInfoCount);
446+
std::vector<uint8_t> vendorBinary(faultCounts.vendorBinarySize);
447+
448+
faultInfo.pAddressInfos = addressInfos.data();
449+
faultInfo.pVendorInfos = vendorInfos.data();
450+
faultInfo.pVendorBinaryData = vendorBinary.data();
451+
452+
if (vkGetDeviceFaultInfoEXT(pDispatch->Device, &faultCounts, &faultInfo) == VK_SUCCESS) {
453+
for (const auto& addrInfo : addressInfos) {
454+
Log::print<ERROR>("Fault Address: 0x{:X}, Precision: {}, Type: {}", addrInfo.reportedAddress, addrInfo.addressPrecision, (int)addrInfo.addressType);
455+
}
456+
for (const auto& vendorInfo : vendorInfos) {
457+
Log::print<ERROR>("Fault Vendor Info: Description: {}, Code: {}", vendorInfo.description, vendorInfo.vendorFaultCode);
458+
}
459+
}
460+
}
461+
}
462+
}
463+
#endif
464+
465+
return result;
431466
}
432467

433468
VkResult VkDeviceOverrides::QueuePresentKHR(const vkroots::VkDeviceDispatch* pDispatch, VkQueue queue, const VkPresentInfoKHR* pPresentInfo) {

src/hooking/layer.cpp

Lines changed: 43 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,11 @@ const std::vector<std::string> additionalDeviceExtensions = {
119119
VK_KHR_EXTERNAL_SEMAPHORE_EXTENSION_NAME,
120120
VK_KHR_EXTERNAL_SEMAPHORE_WIN32_EXTENSION_NAME,
121121
VK_KHR_SYNCHRONIZATION_2_EXTENSION_NAME,
122+
#if ENABLE_VK_ROBUSTNESS
123+
VK_EXT_DEVICE_FAULT_EXTENSION_NAME,
124+
VK_EXT_ROBUSTNESS_2_EXTENSION_NAME,
125+
VK_EXT_IMAGE_ROBUSTNESS_EXTENSION_NAME
126+
#endif
122127
};
123128

124129
VkResult VRLayer::VkInstanceOverrides::CreateDevice(const vkroots::VkInstanceDispatch* pDispatch, VkPhysicalDevice gpu, const VkDeviceCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, VkDevice* pDevice) {
@@ -135,21 +140,57 @@ VkResult VRLayer::VkInstanceOverrides::CreateDevice(const vkroots::VkInstanceDis
135140

136141
// Test if timeline semaphores are already enabled
137142
bool timelineSemaphoresEnabled = false;
143+
bool imageRobustnessEnabled = false;
144+
bool robustness2Enabled = false;
138145
const void* current_pNext = pCreateInfo->pNext;
139146
while (current_pNext) {
140147
const VkBaseInStructure* base = static_cast<const VkBaseInStructure*>(current_pNext);
141148
if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES) {
142149
timelineSemaphoresEnabled = true;
143150
}
151+
#if ENABLE_VK_ROBUSTNESS
152+
if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES) {
153+
imageRobustnessEnabled = true;
154+
}
155+
if (base->sType == VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT) {
156+
robustness2Enabled = true;
157+
}
158+
#endif
144159
current_pNext = base->pNext;
145160
}
146161

147162
VkPhysicalDeviceTimelineSemaphoreFeatures createSemaphoreFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_TIMELINE_SEMAPHORE_FEATURES };
148163
createSemaphoreFeatures.timelineSemaphore = true;
149-
createSemaphoreFeatures.pNext = const_cast<void*>(pCreateInfo->pNext);
164+
165+
VkPhysicalDeviceImageRobustnessFeatures createImageRobustnessFeatures = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_IMAGE_ROBUSTNESS_FEATURES };
166+
createImageRobustnessFeatures.robustImageAccess = true;
167+
168+
VkPhysicalDeviceRobustness2FeaturesEXT createRobustness2Features = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ROBUSTNESS_2_FEATURES_EXT };
169+
createRobustness2Features.robustBufferAccess2 = true;
170+
createRobustness2Features.robustImageAccess2 = true;
171+
createRobustness2Features.nullDescriptor = true;
172+
173+
void* nextChain = const_cast<void*>(pCreateInfo->pNext);
174+
175+
#if ENABLE_VK_ROBUSTNESS
176+
if (!robustness2Enabled) {
177+
createRobustness2Features.pNext = nextChain;
178+
nextChain = &createRobustness2Features;
179+
}
180+
181+
if (!imageRobustnessEnabled) {
182+
createImageRobustnessFeatures.pNext = nextChain;
183+
nextChain = &createImageRobustnessFeatures;
184+
}
185+
#endif
186+
187+
if (!timelineSemaphoresEnabled) {
188+
createSemaphoreFeatures.pNext = nextChain;
189+
nextChain = &createSemaphoreFeatures;
190+
}
150191

151192
VkDeviceCreateInfo modifiedCreateInfo = { VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO };
152-
modifiedCreateInfo.pNext = timelineSemaphoresEnabled ? pCreateInfo->pNext : &createSemaphoreFeatures;
193+
modifiedCreateInfo.pNext = nextChain;
153194
modifiedCreateInfo.flags = pCreateInfo->flags;
154195
modifiedCreateInfo.queueCreateInfoCount = pCreateInfo->queueCreateInfoCount;
155196
modifiedCreateInfo.pQueueCreateInfos = pCreateInfo->pQueueCreateInfos;

src/hooking/weapon.cpp

Lines changed: 89 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -17,95 +17,95 @@ std::array s_cameraPositions = {
1717
};
1818

1919
static bool isDroppable(std::string actorName) {
20-
static const std::string_view nonDroppableItems[] = {
21-
"AncientArrow",
22-
"Animal_Insect_A",
23-
"Animal_Insect_B",
24-
"Animal_Insect_F",
25-
"Animal_Insect_H",
26-
"Animal_Insect_M",
27-
"Animal_Insect_S",
28-
"Animal_Insect_X",
29-
"Armor_Default_Extra_00",
30-
"Armor_Default_Extra_01",
31-
"bj_SupportApp_Wind",
32-
"BombArrow_A",
33-
"BrightArrow",
34-
"BrightArrowTP",
35-
"CarryBox",
36-
"Dm_Npc_Gerudo_HeroSoul_Kago",
37-
"Dm_Npc_Goron_HeroSoul_Kago",
38-
"Dm_Npc_RevivalFairy",
39-
"Dm_Npc_Rito_HeroSoul_Kago",
40-
"Dm_Npc_Zora_HeroSoul_Kago",
41-
"ElectricArrow",
42-
"Explode",
43-
"FireArrow",
44-
"FireRodLv1Fire",
45-
"FireRodLv2Fire",
46-
"FireRodLv2FireChild",
47-
"GameRomHorseReins_01",
48-
"GameRomHorseReins_02",
49-
"GameRomHorseReins_03",
50-
"GameRomHorseReins_04",
51-
"GameRomHorseReins_05",
52-
"GameRomHorseReins_10",
53-
"GameRomHorseSaddle_01",
54-
"GameRomHorseSaddle_02",
55-
"GameRomHorseSaddle_03",
56-
"GameRomHorseSaddle_04",
57-
"GameRomHorseSaddle_05",
58-
"GameRomHorseSaddle_10",
59-
"GameROMPlayer",
60-
"Get_TwnObj_DLC_MemorialPicture_A_01",
61-
"IceArrow",
62-
"IceRodLv1Ice",
63-
"IceRodLv2Ice",
64-
"Item_Conductor",
65-
"Item_CookSet",
66-
"Item_Magnetglove",
67-
"Item_Material_01",
68-
"Item_Material_03",
69-
"Item_Material_07",
70-
"Item_Ore_F",
71-
"KeySmall",
72-
"NormalArrow",
73-
"Obj_Armor_115_Head",
74-
"Obj_DLC_HeroSeal_Gerudo",
75-
"Obj_DLC_HeroSeal_Goron",
76-
"Obj_DLC_HeroSeal_Rito",
77-
"Obj_DLC_HeroSeal_Zora",
78-
"Obj_DLC_HeroSoul_Gerudo",
79-
"Obj_DLC_HeroSoul_Goron",
80-
"Obj_DLC_HeroSoul_Rito",
81-
"Obj_DLC_HeroSoul_Zora",
82-
"Obj_DRStone_A_01",
83-
"Obj_DRStone_Get",
84-
"Obj_DungeonClearSeal",
85-
"Obj_HeartUtuwa_A_01",
86-
"Obj_HeroSoul_Gerudo",
87-
"Obj_HeroSoul_Goron",
88-
"Obj_HeroSoul_Rito",
89-
"Obj_HeroSoul_Zora",
90-
"Obj_IceMakerBlock",
91-
"Obj_KorokNuts",
92-
"Obj_Maracas",
93-
"Obj_ProofBook",
94-
"Obj_ProofGiantKiller",
95-
"Obj_ProofGolemKiller",
96-
"Obj_ProofKorok",
97-
"Obj_ProofSandwormKiller",
98-
"Obj_StaminaUtuwa_A_01",
99-
"Obj_WarpDLC",
100-
"PlayerStole2",
101-
"PlayerStole2_Vagrant",
102-
"Weapon_Bow_071",
103-
"Weapon_Sword_056",
104-
"Weapon_Sword_070",
105-
"Weapon_Sword_080",
106-
"Weapon_Sword_081",
107-
"Weapon_Sword_502"
108-
};
20+
static const std::string_view nonDroppableItems[] = {
21+
"AncientArrow",
22+
"Animal_Insect_A",
23+
"Animal_Insect_B",
24+
"Animal_Insect_F",
25+
"Animal_Insect_H",
26+
"Animal_Insect_M",
27+
"Animal_Insect_S",
28+
"Animal_Insect_X",
29+
"Armor_Default_Extra_00",
30+
"Armor_Default_Extra_01",
31+
"bj_SupportApp_Wind",
32+
"BombArrow_A",
33+
"BrightArrow",
34+
"BrightArrowTP",
35+
"CarryBox",
36+
"Dm_Npc_Gerudo_HeroSoul_Kago",
37+
"Dm_Npc_Goron_HeroSoul_Kago",
38+
"Dm_Npc_RevivalFairy",
39+
"Dm_Npc_Rito_HeroSoul_Kago",
40+
"Dm_Npc_Zora_HeroSoul_Kago",
41+
"ElectricArrow",
42+
"Explode",
43+
"FireArrow",
44+
"FireRodLv1Fire",
45+
"FireRodLv2Fire",
46+
"FireRodLv2FireChild",
47+
"GameRomHorseReins_01",
48+
"GameRomHorseReins_02",
49+
"GameRomHorseReins_03",
50+
"GameRomHorseReins_04",
51+
"GameRomHorseReins_05",
52+
"GameRomHorseReins_10",
53+
"GameRomHorseSaddle_01",
54+
"GameRomHorseSaddle_02",
55+
"GameRomHorseSaddle_03",
56+
"GameRomHorseSaddle_04",
57+
"GameRomHorseSaddle_05",
58+
"GameRomHorseSaddle_10",
59+
"GameROMPlayer",
60+
"Get_TwnObj_DLC_MemorialPicture_A_01",
61+
"IceArrow",
62+
"IceRodLv1Ice",
63+
"IceRodLv2Ice",
64+
"Item_Conductor",
65+
"Item_CookSet",
66+
"Item_Magnetglove",
67+
"Item_Material_01",
68+
"Item_Material_03",
69+
"Item_Material_07",
70+
"Item_Ore_F",
71+
"KeySmall",
72+
"NormalArrow",
73+
"Obj_Armor_115_Head",
74+
"Obj_DLC_HeroSeal_Gerudo",
75+
"Obj_DLC_HeroSeal_Goron",
76+
"Obj_DLC_HeroSeal_Rito",
77+
"Obj_DLC_HeroSeal_Zora",
78+
"Obj_DLC_HeroSoul_Gerudo",
79+
"Obj_DLC_HeroSoul_Goron",
80+
"Obj_DLC_HeroSoul_Rito",
81+
"Obj_DLC_HeroSoul_Zora",
82+
"Obj_DRStone_A_01",
83+
"Obj_DRStone_Get",
84+
"Obj_DungeonClearSeal",
85+
"Obj_HeartUtuwa_A_01",
86+
"Obj_HeroSoul_Gerudo",
87+
"Obj_HeroSoul_Goron",
88+
"Obj_HeroSoul_Rito",
89+
"Obj_HeroSoul_Zora",
90+
"Obj_IceMakerBlock",
91+
"Obj_KorokNuts",
92+
"Obj_Maracas",
93+
"Obj_ProofBook",
94+
"Obj_ProofGiantKiller",
95+
"Obj_ProofGolemKiller",
96+
"Obj_ProofKorok",
97+
"Obj_ProofSandwormKiller",
98+
"Obj_StaminaUtuwa_A_01",
99+
"Obj_WarpDLC",
100+
"PlayerStole2",
101+
"PlayerStole2_Vagrant",
102+
"Weapon_Bow_071",
103+
"Weapon_Sword_056",
104+
"Weapon_Sword_070",
105+
"Weapon_Sword_080",
106+
"Weapon_Sword_081",
107+
"Weapon_Sword_502"
108+
};
109109

110110
for (const auto& item : nonDroppableItems) {
111111
if (actorName == item) {

src/rendering/openxr.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,9 @@ OpenXR::OpenXR() {
4848
Log::print<WARNING>("OpenXR runtime doesn't support converting time from/to XrTime (XR_KHR_WIN32_CONVERT_PERFORMANCE_COUNTER_TIME). Not required, as of this version.");
4949
}
5050
if (!debugUtilsSupported) {
51+
#if defined(_DEBUG)
5152
Log::print<INFO>("OpenXR runtime doesn't support debug utils (XR_EXT_DEBUG_UTILS)! Errors/debug information will no longer be able to be shown!");
53+
#endif
5254
}
5355

5456
std::vector<const char*> enabledExtensions = { XR_KHR_D3D12_ENABLE_EXTENSION_NAME, XR_KHR_COMPOSITION_LAYER_DEPTH_EXTENSION_NAME, XR_KHR_WIN32_CONVERT_PERFORMANCE_COUNTER_TIME_EXTENSION_NAME };

0 commit comments

Comments
 (0)