Add BindImageMemory2 support for swapchain images
This finishes our KHR_swapchain v70 implementation.
Test: dEQP-VK.wsi.*
Change-Id: I512e0c086db687ca7ffb8cd5e5375fa7a9d432cd
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/35929
Tested-by: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: Chris Forbes <chrisforbes@google.com>
Kokoro-Presubmit: kokoro <noreply+kokoro@google.com>
Reviewed-by: Ben Clayton <bclayton@google.com>
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index 189c684..aa4e68c 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -207,9 +207,15 @@
// Only 1.1 core version of this is supported. The extension has additional requirements
//{ VK_KHR_VARIABLE_POINTERS_EXTENSION_NAME, VK_KHR_VARIABLE_POINTERS_SPEC_VERSION },
#ifndef __ANDROID__
+ // We fully support the KHR_swapchain v70 additions, so just track the spec version.
{ VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_SPEC_VERSION },
#else
- { VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME, VK_ANDROID_NATIVE_BUFFER_SPEC_VERSION },
+ // We only support V7 of this extension. Missing functionality: in V8,
+ // it becomes possible to pass a VkNativeBufferANDROID structure to
+ // vkBindImageMemory2. Android's swapchain implementation does this in
+ // order to support passing VkBindImageMemorySwapchainInfoKHR
+ // (from KHR_swapchain v70) to vkBindImageMemory2.
+ { VK_ANDROID_NATIVE_BUFFER_EXTENSION_NAME, 7 },
#endif
};
@@ -1104,6 +1110,9 @@
}
break;
#endif
+ case VK_STRUCTURE_TYPE_IMAGE_SWAPCHAIN_CREATE_INFO_KHR:
+ /* Do nothing. We don't actually need the swapchain handle yet; we'll do all the work in vkBindImageMemory2. */
+ break;
default:
// "the [driver] must skip over, without processing (other than reading the sType and pNext members) any structures in the chain with sType values not defined by [supported extenions]"
UNIMPLEMENTED("extensionCreateInfo->sType"); // TODO(b/119321052): UNIMPLEMENTED() should be used only for features that must still be implemented. Use a more informational macro here.
@@ -2137,12 +2146,35 @@
for(uint32_t i = 0; i < bindInfoCount; i++)
{
- if(pBindInfos[i].pNext)
+ vk::DeviceMemory *memory = vk::Cast(pBindInfos[i].memory);
+ VkDeviceSize offset = pBindInfos[i].memoryOffset;
+
+ auto extInfo = reinterpret_cast<VkBaseInStructure const *>(pBindInfos[i].pNext);
+ while (extInfo)
{
- UNIMPLEMENTED("pBindInfos[%d].pNext", i);
+ switch (extInfo->sType)
+ {
+ case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_DEVICE_GROUP_INFO:
+ /* Do nothing */
+ break;
+
+#ifndef __ANDROID__
+ case VK_STRUCTURE_TYPE_BIND_IMAGE_MEMORY_SWAPCHAIN_INFO_KHR:
+ {
+ auto swapchainInfo = reinterpret_cast<VkBindImageMemorySwapchainInfoKHR const *>(extInfo);
+ memory = vk::Cast(swapchainInfo->swapchain)->getImage(swapchainInfo->imageIndex).getImageMemory();
+ offset = 0;
+ }
+ break;
+#endif
+
+ default:
+ break;
+ }
+ extInfo = extInfo->pNext;
}
- vk::Cast(pBindInfos[i].image)->bind(vk::Cast(pBindInfos[i].memory), pBindInfos[i].memoryOffset);
+ vk::Cast(pBindInfos[i].image)->bind(memory, offset);
}
return VK_SUCCESS;
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
index 48f25ce..0e833da 100644
--- a/src/WSI/VkSurfaceKHR.hpp
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -45,7 +45,7 @@
VkImage asVkImage() const;
const Image* getImage() const { return image; }
- const DeviceMemory* getImageMemory() const { return imageMemory; }
+ DeviceMemory* getImageMemory() const { return imageMemory; }
bool isAvailable() const { return (imageStatus == AVAILABLE); }
bool exists() const { return (imageStatus != NONEXISTENT); }
void setStatus(PresentImageStatus status) { imageStatus = status; }
diff --git a/src/WSI/VkSwapchainKHR.hpp b/src/WSI/VkSwapchainKHR.hpp
index 3e6bf33..7a77ebb 100644
--- a/src/WSI/VkSwapchainKHR.hpp
+++ b/src/WSI/VkSwapchainKHR.hpp
@@ -47,6 +47,7 @@
VkResult getNextImage(uint64_t timeout, Semaphore* semaphore, Fence* fence, uint32_t* pImageIndex);
void present(uint32_t index);
+ PresentImage const &getImage(uint32_t imageIndex) { return images[imageIndex]; }
private:
SurfaceKHR* surface = nullptr;