Commit 198c92d2 authored by Antonio Caggiano's avatar Antonio Caggiano
Browse files

Vulkan: Fix present region rectangles



EGL rectangles are specified relative to the bottom-left of the surface,
while Vulkan framebuffer space puts the origin on the top-left corner.

Bug: angleproject:6933
Change-Id: Ia57eea8601ee724c0a82eb718d831de6b7566472
Reviewed-by: Constantine Shablya's avatarConstantine Shablya <constantine.shablya@collabora.com>
parent d1b1ef9a
......@@ -623,6 +623,14 @@ struct FeaturesVk : FeatureSetBase
// Whether dithering should be emulated.
Feature emulateDithering = {"emulateDithering", FeatureCategory::VulkanFeatures,
"Emulate OpenGL dithering", &members, "http://anglebug.com/6755"};
// Android bug workaround which assumes VkPresentRegionsKHR to have a bottom-left origin
// instead of top-left as specified by VK_KHR_incremental_present
Feature bottomLeftOriginPresentRegionRectangles = {
"bottomLeftOriginPresentRegionRectangles", FeatureCategory::VulkanWorkarounds,
"On some platforms present region rectangles are expected to have a bottom-left origin, "
"instead of top-left origin as from spec",
&members};
};
inline FeaturesVk::FeaturesVk() = default;
......
......@@ -3053,6 +3053,11 @@ void RendererVk::initFeatures(DisplayVk *displayVk,
// (which would require Chromium and Capture/Replay test expectations updates).
ANGLE_FEATURE_CONDITION(&mFeatures, emulateDithering, IsAndroid());
// http://anglebug.com/6933
// Android expects VkPresentRegionsKHR rectangles with a bottom-left origin, while spec
// states they should have a top-left origin.
ANGLE_FEATURE_CONDITION(&mFeatures, bottomLeftOriginPresentRegionRectangles, IsAndroid());
angle::PlatformMethods *platform = ANGLEPlatformCurrent();
platform->overrideFeaturesVk(platform, &mFeatures);
......
......@@ -342,6 +342,38 @@ angle::Result UnlockSurfaceImpl(DisplayVk *displayVk,
return angle::Result::Continue;
}
// Converts an EGL rectangle, which is relative to the bottom-left of the surface,
// to a VkRectLayerKHR, relative to Vulkan framebuffer-space, with top-left origin.
// No rotation is done to these damage rectangles per the Vulkan spec.
// The bottomLeftOrigin parameter is true on Android which assumes VkRectLayerKHR to
// have a bottom-left origin.
VkRectLayerKHR ToVkRectLayer(const EGLint *eglRect,
EGLint width,
EGLint height,
bool bottomLeftOrigin)
{
VkRectLayerKHR rect;
// Make sure the damage rects are within swapchain bounds.
rect.offset.x = gl::clamp(eglRect[0], 0, width);
if (bottomLeftOrigin)
{
// EGL rectangles are already specified with a bottom-left origin, therefore the conversion
// is trivial as we just get its Y coordinate as it is
rect.offset.y = gl::clamp(eglRect[1], 0, height);
}
else
{
rect.offset.y =
gl::clamp(height - gl::clamp(eglRect[1], 0, height) - gl::clamp(eglRect[3], 0, height),
0, height);
}
rect.extent.width = gl::clamp(eglRect[2], 0, width - rect.offset.x);
rect.extent.height = gl::clamp(eglRect[3], 0, height - rect.offset.y);
rect.layer = 0;
return rect;
}
} // namespace
#if defined(ANGLE_ENABLE_OVERLAY)
......@@ -1728,15 +1760,9 @@ angle::Result WindowSurfaceVk::present(ContextVk *contextVk,
vkRects.resize(n_rects);
for (EGLint i = 0; i < n_rects; i++)
{
VkRectLayerKHR &rect = vkRects[i];
// Make sure the damage rects are within swapchain bounds.
rect.offset.x = gl::clamp(*eglRects++, 0, width);
rect.offset.y = gl::clamp(*eglRects++, 0, height);
rect.extent.width = gl::clamp(*eglRects++, 0, width - rect.offset.x);
rect.extent.height = gl::clamp(*eglRects++, 0, height - rect.offset.y);
rect.layer = 0;
// No rotation is done to these damage rectangles per the Vulkan spec.
vkRects[i] = ToVkRectLayer(
eglRects + i * 4, width, height,
contextVk->getFeatures().bottomLeftOriginPresentRegionRectangles.enabled);
}
presentRegion.pRectangles = vkRects.data();
......
Supports Markdown
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