vkAcquireNextImageKHR and vkQueuePresentKHR
The following changes will allow to present
to the screen. However, do not adjust the
size of the window.
Bug: b/124265819
Change-Id: Iaa42f458af9555e91d47238397112324ec080a67
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26008
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
Tested-by: Hernan Liatis <hliatis@google.com>
diff --git a/src/Vulkan/VkGetProcAddress.cpp b/src/Vulkan/VkGetProcAddress.cpp
index ea7eb7b..40b8f7e 100644
--- a/src/Vulkan/VkGetProcAddress.cpp
+++ b/src/Vulkan/VkGetProcAddress.cpp
@@ -251,6 +251,8 @@
MAKE_VULKAN_DEVICE_ENTRY(vkCreateSwapchainKHR),
MAKE_VULKAN_DEVICE_ENTRY(vkDestroySwapchainKHR),
MAKE_VULKAN_DEVICE_ENTRY(vkGetSwapchainImagesKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkAcquireNextImageKHR),
+ MAKE_VULKAN_DEVICE_ENTRY(vkQueuePresentKHR),
};
#undef MAKE_VULKAN_DEVICE_ENTRY
diff --git a/src/Vulkan/VkQueue.cpp b/src/Vulkan/VkQueue.cpp
index 1a7f0fc..339eeed 100644
--- a/src/Vulkan/VkQueue.cpp
+++ b/src/Vulkan/VkQueue.cpp
@@ -17,6 +17,7 @@
#include "VkQueue.hpp"
#include "VkSemaphore.hpp"
#include "Device/Renderer.hpp"
+#include "WSI/VkSwapchainKHR.hpp"
namespace vk
{
@@ -65,12 +66,20 @@
}
}
-void Queue::waitIdle()
-{
- // equivalent to submitting a fence to a queue and waiting
- // with an infinite timeout for that fence to signal
-
- // FIXME (b/117835459): implement once we have working fences
+void Queue::waitIdle()
+{
+ // equivalent to submitting a fence to a queue and waiting
+ // with an infinite timeout for that fence to signal
+
+ // FIXME (b/117835459): implement once we have working fences
+}
+
+void Queue::present(const VkPresentInfoKHR* presentInfo)
+{
+ for(uint32_t i = 0; i < presentInfo->swapchainCount; i++)
+ {
+ vk::Cast(presentInfo->pSwapchains[i])->present(presentInfo->pImageIndices[i]);
+ }
}
} // namespace vk
\ No newline at end of file
diff --git a/src/Vulkan/VkQueue.hpp b/src/Vulkan/VkQueue.hpp
index d38e3a0..5716fa8 100644
--- a/src/Vulkan/VkQueue.hpp
+++ b/src/Vulkan/VkQueue.hpp
@@ -43,6 +43,7 @@
void destroy();
void submit(uint32_t submitCount, const VkSubmitInfo* pSubmits, VkFence fence);
void waitIdle();
+ void present(const VkPresentInfoKHR* presentInfo);
private:
sw::Context* context = nullptr;
diff --git a/src/Vulkan/libVulkan.cpp b/src/Vulkan/libVulkan.cpp
index a22a3ef..3896b53 100644
--- a/src/Vulkan/libVulkan.cpp
+++ b/src/Vulkan/libVulkan.cpp
@@ -2212,4 +2212,22 @@
return vk::Cast(swapchain)->getImages(pSwapchainImageCount, pSwapchainImages);
}
+VKAPI_ATTR VkResult VKAPI_CALL vkAcquireNextImageKHR(VkDevice device, VkSwapchainKHR swapchain, uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex)
+{
+ TRACE("(VkDevice device = 0x%X, VkSwapchainKHR swapchain = 0x%X, uint64_t timeout = 0x%X, VkSemaphore semaphore = 0x%X, VkFence fence = 0x%X, uint32_t* pImageIndex = 0x%X)",
+ device, swapchain, timeout, semaphore, fence, pImageIndex);
+
+ return vk::Cast(swapchain)->getNextImage(timeout, semaphore, fence, pImageIndex);
+}
+
+VKAPI_ATTR VkResult VKAPI_CALL vkQueuePresentKHR(VkQueue queue, const VkPresentInfoKHR* pPresentInfo)
+{
+ TRACE("(VkQueue queue = 0x%X, const VkPresentInfoKHR* pPresentInfo = 0x%X)",
+ queue, pPresentInfo);
+
+ vk::Cast(queue)->present(pPresentInfo);
+
+ return VK_SUCCESS;
+}
+
}
diff --git a/src/WSI/VkSurfaceKHR.cpp b/src/WSI/VkSurfaceKHR.cpp
index 0fd3468..2877f8a 100644
--- a/src/WSI/VkSurfaceKHR.cpp
+++ b/src/WSI/VkSurfaceKHR.cpp
@@ -83,6 +83,4 @@
return VK_SUCCESS;
}
-
-
}
\ No newline at end of file
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
index 4734097..0d2c2e2 100644
--- a/src/WSI/VkSurfaceKHR.hpp
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -45,6 +45,8 @@
uint32_t getPresentModeCount() const;
VkResult getPresentModes(uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes) const;
+ virtual void present(VkImage image, VkDeviceMemory imageData) = 0;
+
private:
const std::vector<VkSurfaceFormatKHR> surfaceFormats =
{
diff --git a/src/WSI/VkSwapchainKHR.cpp b/src/WSI/VkSwapchainKHR.cpp
index c825f72..50487f1 100644
--- a/src/WSI/VkSwapchainKHR.cpp
+++ b/src/WSI/VkSwapchainKHR.cpp
@@ -146,4 +146,39 @@
return VK_SUCCESS;
}
+VkResult SwapchainKHR::getNextImage(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t *pImageIndex)
+{
+ for(uint32_t i = 0; i < getImageCount(); i++)
+ {
+ PresentImage& currentImage = images[i];
+ if(currentImage.imageStatus == AVAILABLE)
+ {
+ currentImage.imageStatus = DRAWING;
+ *pImageIndex = i;
+
+ if(semaphore)
+ {
+ vk::Cast(semaphore)->signal();
+ }
+
+ if(fence)
+ {
+ vk::Cast(fence)->signal();
+ }
+
+ return VK_SUCCESS;
+ }
+ }
+
+ return VK_NOT_READY;
+}
+
+void SwapchainKHR::present(uint32_t index)
+{
+ auto & image = images[index];
+ image.imageStatus = PRESENTING;
+ vk::Cast(createInfo.surface)->present(image.image, image.imageMemory);
+ image.imageStatus = AVAILABLE;
+}
+
}
\ No newline at end of file
diff --git a/src/WSI/VkSwapchainKHR.hpp b/src/WSI/VkSwapchainKHR.hpp
index 5be2584..4c9a926 100644
--- a/src/WSI/VkSwapchainKHR.hpp
+++ b/src/WSI/VkSwapchainKHR.hpp
@@ -54,6 +54,10 @@
uint32_t getImageCount() const;
VkResult getImages(uint32_t *pSwapchainImageCount, VkImage *pSwapchainImages) const;
+ VkResult getNextImage(uint64_t timeout, VkSemaphore semaphore, VkFence fence, uint32_t* pImageIndex);
+
+ void present(uint32_t index);
+
private:
VkSwapchainCreateInfoKHR createInfo;
std::vector<PresentImage> images;
diff --git a/src/WSI/XlibSurfaceKHR.cpp b/src/WSI/XlibSurfaceKHR.cpp
index 9dd7575..18b10ce 100644
--- a/src/WSI/XlibSurfaceKHR.cpp
+++ b/src/WSI/XlibSurfaceKHR.cpp
@@ -11,23 +11,49 @@
#include "XlibSurfaceKHR.hpp"
+#include "Vulkan/VkDeviceMemory.hpp"
+
+#include <string.h>
+
namespace vk {
XlibSurfaceKHR::XlibSurfaceKHR(const VkXlibSurfaceCreateInfoKHR *pCreateInfo, void *mem) :
pDisplay(pCreateInfo->dpy),
- window(pCreateInfo->window) {
+ window(pCreateInfo->window)
+{
+ int screen = DefaultScreen(pDisplay);
+ gc = libX11->XDefaultGC(pDisplay, screen);
+
+ XVisualInfo xVisual;
+ Status status = libX11->XMatchVisualInfo(pDisplay, screen, 32, TrueColor, &xVisual);
+ bool match = (status != 0 && xVisual.blue_mask ==0xFF);
+ Visual *visual = match ? xVisual.visual : libX11->XDefaultVisual(pDisplay, screen);
+
+ XWindowAttributes attr;
+ libX11->XGetWindowAttributes(pDisplay, window, &attr);
+
+ int bytes_per_line = attr.width * 4;
+ int bytes_per_image = attr.height * bytes_per_line;
+
+ xImage = libX11->XCreateImage(pDisplay, visual, attr.depth, ZPixmap, 0, nullptr, attr.width, attr.height, 32, bytes_per_line);
}
-void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator) {
-
+void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
+{
+ if(xImage)
+ {
+ XDestroyImage(xImage);
+ }
}
-size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo) {
+size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo)
+{
return 0;
}
-void XlibSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const {
+void XlibSurfaceKHR::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const
+{
SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
XWindowAttributes attr;
@@ -39,4 +65,16 @@
pSurfaceCapabilities->maxImageExtent = extent;
}
+void XlibSurfaceKHR::present(VkImage image, VkDeviceMemory imageData)
+{
+ xImage->data = static_cast<char*>(vk::Cast(imageData)->getOffsetPointer(0));
+
+ XWindowAttributes attr;
+ libX11->XGetWindowAttributes(pDisplay, window, &attr);
+
+ libX11->XPutImage(pDisplay, window, gc, xImage, 0, 0, 0, 0, attr.width, attr.height);
+
+ xImage->data = nullptr;
+}
+
}
\ No newline at end of file
diff --git a/src/WSI/XlibSurfaceKHR.hpp b/src/WSI/XlibSurfaceKHR.hpp
index 56540fe..1f49e1e 100644
--- a/src/WSI/XlibSurfaceKHR.hpp
+++ b/src/WSI/XlibSurfaceKHR.hpp
@@ -33,10 +33,13 @@
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
+ void present(VkImage image, VkDeviceMemory imageData) override;
+
private:
Display *pDisplay;
Window window;
-
+ GC gc;
+ XImage *xImage = nullptr;
};
}