Commit a23231ea by Corentin Wallez Committed by Alexis Hétu

MetalSurface: correctly handle the window resizing.

In metal the size of the drawable (the texture use to render to the window) is decoupled from the window's size: - When the first drawable is created, its size is given by layer.bounds.size * layer.contentsScale. - Once set the drawableSize never changes without the user setting the layer.drawableSize explicitly. This means that the code checking for OUT_OF_DATE_KHR needs to be updated to check the texture size against the drawable's size (and not the current scaled window size). Also Swiftshader needs to set the drawableSize to the correct value when the window is resized. The best moment to do this is when querying the capabilities as that's done when a new swapchain is created (which happens when the application is handling the window's resize). Bug: dawn:269 Change-Id: Icf1c3df63d42e0fa9211893f6b89d8709dfd942e Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/49328Tested-by: 's avatarCorentin Wallez <cwallez@google.com> Reviewed-by: 's avatarAlexis Hétu <sugoi@google.com>
parent 04bd4d8e
......@@ -78,7 +78,9 @@ public:
}
}
VkExtent2D getExtent() const API_AVAILABLE(macosx(10.11))
// Synchronizes the drawableSize to layer.bounds.size * layer.contentsScale and returns the new value of
// drawableSize.
VkExtent2D syncExtent() const API_AVAILABLE(macosx(10.11))
{
if(layer)
{
......@@ -86,6 +88,9 @@ public:
CGFloat scaleFactor = layer.contentsScale;
drawSize.width = trunc(drawSize.width * scaleFactor);
drawSize.height = trunc(drawSize.height * scaleFactor);
[layer setDrawableSize: drawSize];
return { static_cast<uint32_t>(drawSize.width), static_cast<uint32_t>(drawSize.height) };
}
else
......@@ -104,6 +109,16 @@ public:
return nil;
}
VkExtent2D getDrawableSize() const API_AVAILABLE(macosx(10.11)) {
if (layer) {
return {
static_cast<uint32_t>([layer drawableSize].width),
static_cast<uint32_t>([layer drawableSize].height),
};
}
return {0, 0};
}
private:
NSView* view;
CAMetalLayer* layer API_AVAILABLE(macosx(10.11));
......@@ -133,7 +148,11 @@ void MetalSurface::getSurfaceCapabilities(VkSurfaceCapabilitiesKHR *pSurfaceCapa
{
SurfaceKHR::getSurfaceCapabilities(pSurfaceCapabilities);
VkExtent2D extent = metalLayer->getExtent();
// The value of drawableSize in CAMetalLayer is set the first time a drawable is queried but after that it is the
// (Metal) application's responsibility to resize the drawable when the window is resized. The best time for Swiftshader
// to resize the drawable is when querying the capabilities of the swapchain as that's done when the Vulkan application
// is trying to handle a window resize.
VkExtent2D extent = metalLayer->syncExtent();
pSurfaceCapabilities->currentExtent = extent;
pSurfaceCapabilities->minImageExtent = extent;
pSurfaceCapabilities->maxImageExtent = extent;
......@@ -146,10 +165,10 @@ VkResult MetalSurface::present(PresentImage* image) API_AVAILABLE(macosx(10.11))
auto drawable = metalLayer->getNextDrawable();
if(drawable)
{
VkExtent2D windowExtent = metalLayer->getExtent();
const VkExtent3D &extent = image->getImage()->getExtent();
VkExtent2D drawableExtent = metalLayer->getDrawableSize();
if(windowExtent.width != extent.width || windowExtent.height != extent.height)
if(drawableExtent.width != extent.width || drawableExtent.height != extent.height)
{
return VK_ERROR_OUT_OF_DATE_KHR;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment