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; }; }