fix: preserve OpenVR shared image layouts

This commit is contained in:
XxJSONDeruloxX committed 2026-10-15 19:16:11 -04:00
1 parent 46335b7871
commit 21742403a4
3 files changed
+10 -5

No files matched your search

+3 -2
View File
@@ -136,8 +136,9 @@ immersive scenes. SUPERHOT's Windows OpenXR build initially showed shared-image
corruption: DXVK supplied a restricted mutable-image format list while SteamVR
created its corresponding opaque shared images without one. Turnip can select
different memory layouts for those descriptions. On the Quest bridge, the layer
normalizes the known opaque-FD creation chains to SteamVR's unrestricted list,
without changing DMA-BUF/modifier images or other targets. A headset capture then
normalizes the known opaque-FD stereo-array creation chains to SteamVR's unrestricted list,
without changing application-owned single-layer OpenVR images, DMA-BUF/modifier
images or other targets. A headset capture then
showed clean SUPERHOT scene geometry; interactive gameplay remains unverified.
A subsequent 60-second shared-buffer dashboard run delivered about
43 new stereo images per second. Reusing Android pixel buffers raised the next
+4 -3
View File
@@ -980,8 +980,9 @@ static VkResult VKAPI_CALL CreateImage(VkDevice d, const VkImageCreateInfo *ci,
VkImageCreateInfo compatible = *ci;
VkExternalMemoryImageCreateInfo shared;
const VkBaseInStructure *first = ci->pNext;
// SteamVR omits a format list, but DXVK adds one; Turnip can choose a different shared-memory layout.
if (dev_for(d)->quest_images && (ci->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && ci->tiling == VK_IMAGE_TILING_OPTIMAL
// SteamVR's OpenXR stereo arrays omit a format list, while DXVK adds one on import.
// Leave single-layer OpenVR images alone: the application owns their export layout.
if (dev_for(d)->quest_images && ci->arrayLayers > 1 && (ci->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && ci->tiling == VK_IMAGE_TILING_OPTIMAL
&& first && first->sType == VK_STRUCTURE_TYPE_IMAGE_FORMAT_LIST_CREATE_INFO) {
const VkBaseInStructure *second = first->pNext;
if (second && second->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO
@@ -990,7 +991,7 @@ static VkResult VKAPI_CALL CreateImage(VkDevice d, const VkImageCreateInfo *ci,
say("%s", "matching opaque shared image layout to SteamVR's unrestricted format list");
}
}
if (dev_for(d)->quest_images && (ci->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && ci->tiling == VK_IMAGE_TILING_OPTIMAL
if (dev_for(d)->quest_images && ci->arrayLayers > 1 && (ci->flags & VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT) && ci->tiling == VK_IMAGE_TILING_OPTIMAL
&& first && first->sType == VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_IMAGE_CREATE_INFO) {
const VkExternalMemoryImageCreateInfo *external = (const void *)first;
const VkBaseInStructure *second = external->pNext;
+3
View File
@@ -42,6 +42,9 @@ static void check_shared_images(VkDevice device) {
expected_image_chain = &list;
assert(CreateImage(device, &image, NULL, &output) == VK_ERROR_FORMAT_NOT_SUPPORTED);
g_dev[0].quest_images = 1;
image.arrayLayers = 1;
assert(CreateImage(device, &image, NULL, &output) == VK_ERROR_FORMAT_NOT_SUPPORTED);
image.arrayLayers = 2;
image.flags = 0;
assert(CreateImage(device, &image, NULL, &output) == VK_ERROR_FORMAT_NOT_SUPPORTED);
image.flags = VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;