Fix resizing issues
In summary, this change associates a 1:1
correspondance between a VkImage and XImage.
This will fix resize issues as well as prepare
to implement createInfo->oldSwapchain.
Bug: b/124265819
Change-Id: I42e8e1e7b5c9a5b64820156603dca10e2ab828ca
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/26368
Reviewed-by: Alexis Hétu <sugoi@google.com>
Tested-by: Hernan Liatis <hliatis@google.com>
diff --git a/src/WSI/VkSurfaceKHR.hpp b/src/WSI/VkSurfaceKHR.hpp
index 0d2c2e2..f17cbbd 100644
--- a/src/WSI/VkSurfaceKHR.hpp
+++ b/src/WSI/VkSurfaceKHR.hpp
@@ -22,6 +22,21 @@
namespace vk
{
+enum PresentImageStatus
+{
+ NONEXISTENT, // Image wasn't made
+ AVAILABLE,
+ DRAWING,
+ PRESENTING,
+};
+
+struct PresentImage
+{
+ VkImage image;
+ VkDeviceMemory imageMemory;
+ PresentImageStatus imageStatus;
+};
+
class SurfaceKHR
{
public:
@@ -45,7 +60,9 @@
uint32_t getPresentModeCount() const;
VkResult getPresentModes(uint32_t* pPresentModeCount, VkPresentModeKHR* pPresentModes) const;
- virtual void present(VkImage image, VkDeviceMemory imageData) = 0;
+ virtual void attachImage(PresentImage* image) = 0;
+ virtual void detachImage(PresentImage* image) = 0;
+ virtual void present(PresentImage* image) = 0;
private:
const std::vector<VkSurfaceFormatKHR> surfaceFormats =
diff --git a/src/WSI/VkSwapchainKHR.cpp b/src/WSI/VkSwapchainKHR.cpp
index 50487f1..bd1672e 100644
--- a/src/WSI/VkSwapchainKHR.cpp
+++ b/src/WSI/VkSwapchainKHR.cpp
@@ -36,6 +36,7 @@
{
if (currentImage.imageStatus != NONEXISTENT)
{
+ vk::Cast(createInfo.surface)->detachImage(¤tImage);
vk::destroy(currentImage.imageMemory, pAllocator);
vk::destroy(currentImage.image, pAllocator);
@@ -116,6 +117,8 @@
vkBindImageMemory(device, currentImage.image, currentImage.imageMemory, 0);
currentImage.imageStatus = AVAILABLE;
+
+ vk::Cast(createInfo.surface)->attachImage(¤tImage);
}
return VK_SUCCESS;
@@ -177,7 +180,7 @@
{
auto & image = images[index];
image.imageStatus = PRESENTING;
- vk::Cast(createInfo.surface)->present(image.image, image.imageMemory);
+ vk::Cast(createInfo.surface)->present(&image);
image.imageStatus = AVAILABLE;
}
diff --git a/src/WSI/VkSwapchainKHR.hpp b/src/WSI/VkSwapchainKHR.hpp
index 4c9a926..7cd06d6 100644
--- a/src/WSI/VkSwapchainKHR.hpp
+++ b/src/WSI/VkSwapchainKHR.hpp
@@ -18,27 +18,13 @@
#include "Vulkan/VkObject.hpp"
#include "Vulkan/VkImage.hpp"
+#include "VkSurfaceKHR.hpp"
#include <vector>
namespace vk
{
-enum PresentImageStatus
-{
- NONEXISTENT, // Image wasn't made
- AVAILABLE,
- DRAWING,
- PRESENTING,
-};
-
-struct PresentImage
-{
- VkImage image;
- VkDeviceMemory imageMemory;
- PresentImageStatus imageStatus;
-};
-
class SwapchainKHR : public Object<SwapchainKHR, VkSwapchainKHR>
{
public:
diff --git a/src/WSI/XlibSurfaceKHR.cpp b/src/WSI/XlibSurfaceKHR.cpp
index 18b10ce..3bf3022 100644
--- a/src/WSI/XlibSurfaceKHR.cpp
+++ b/src/WSI/XlibSurfaceKHR.cpp
@@ -27,24 +27,12 @@
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);
-
+ visual = match ? xVisual.visual : libX11->XDefaultVisual(pDisplay, screen);
}
void XlibSurfaceKHR::destroySurface(const VkAllocationCallbacks *pAllocator)
{
- if(xImage)
- {
- XDestroyImage(xImage);
- }
+
}
size_t XlibSurfaceKHR::ComputeRequiredAllocationSize(const VkXlibSurfaceCreateInfoKHR *pCreateInfo)
@@ -65,16 +53,46 @@
pSurfaceCapabilities->maxImageExtent = extent;
}
-void XlibSurfaceKHR::present(VkImage image, VkDeviceMemory imageData)
+void XlibSurfaceKHR::attachImage(PresentImage* image)
{
- 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);
+ VkExtent3D extent = vk::Cast(image->image)->getMipLevelExtent(0);
- xImage->data = nullptr;
+ int bytes_per_line = vk::Cast(image->image)->rowPitchBytes(VK_IMAGE_ASPECT_COLOR_BIT, 0);
+ char* buffer = static_cast<char*>(vk::Cast(image->imageMemory)->getOffsetPointer(0));
+
+ XImage* xImage = libX11->XCreateImage(pDisplay, visual, attr.depth, ZPixmap, 0, buffer, extent.width, extent.height, 32, bytes_per_line);
+
+ imageMap[image] = xImage;
+}
+
+void XlibSurfaceKHR::detachImage(PresentImage* image)
+{
+ auto it = imageMap.find(image);
+ if(it != imageMap.end())
+ {
+ XImage* xImage = it->second;
+ xImage->data = nullptr; // the XImage does not actually own the buffer
+ XDestroyImage(xImage);
+ imageMap.erase(image);
+ }
+}
+
+void XlibSurfaceKHR::present(PresentImage* image)
+{
+ auto it = imageMap.find(image);
+ if(it != imageMap.end())
+ {
+ XImage* xImage = it->second;
+
+ if(xImage->data)
+ {
+ VkExtent3D extent = vk::Cast(image->image)->getMipLevelExtent(0);
+ libX11->XPutImage(pDisplay, window, gc, xImage, 0, 0, 0, 0, extent.width, extent.height);
+ }
+ }
}
}
\ No newline at end of file
diff --git a/src/WSI/XlibSurfaceKHR.hpp b/src/WSI/XlibSurfaceKHR.hpp
index 1f49e1e..bafd973 100644
--- a/src/WSI/XlibSurfaceKHR.hpp
+++ b/src/WSI/XlibSurfaceKHR.hpp
@@ -16,9 +16,12 @@
#define SWIFTSHADER_XLIBSURFACEKHR_HPP
#include "Vulkan/VkObject.hpp"
+#include "Vulkan/VkImage.hpp"
#include "libX11.hpp"
#include "VkSurfaceKHR.hpp"
+#include <map>
+
namespace vk {
class XlibSurfaceKHR : public SurfaceKHR, public ObjectBase<XlibSurfaceKHR, VkSurfaceKHR> {
@@ -33,13 +36,16 @@
void getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) const override;
- void present(VkImage image, VkDeviceMemory imageData) override;
+ virtual void attachImage(PresentImage* image) override;
+ virtual void detachImage(PresentImage* image) override;
+ void present(PresentImage* image) override;
private:
Display *pDisplay;
Window window;
GC gc;
- XImage *xImage = nullptr;
+ Visual *visual = nullptr;
+ std::map<PresentImage*, XImage*> imageMap;
};
}