Commit bcb78908 by Ian Elliott Committed by Commit Bot

Implement eglSwapBuffersWithDamage on top of VK_KHR_incremental_present

Bug: angleproject:2510 Change-Id: I12b0877f787dbcb48e2890f54ba4bc8ebe8294b4 Reviewed-on: https://chromium-review.googlesource.com/c/1383373Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Reviewed-by: 's avatarYuly Novikov <ynovikov@chromium.org> Commit-Queue: Ian Elliott <ianelliott@google.com>
parent 96c11cc7
......@@ -53,6 +53,10 @@ struct FeaturesVk
// attributes and the vertex shader that reads from it is ineffective. Only known workaround is
// to perform a flush after the conversion. http://anglebug.com/3016
bool flushAfterVertexConversion = false;
// Whether the VkDevice supports the VK_KHR_incremental_present extension, on which the
// EGL_KHR_swap_buffers_with_damage extension can be layered.
bool supportsIncrementalPresent = false;
};
} // namespace angle
......
......@@ -171,7 +171,9 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
// backend can be tested in Chrome. http://anglebug.com/2722
outExtensions->robustResourceInitialization = true;
// Vulkan implementation will use regular swap for swapBuffersWithDamage.
// The Vulkan implementation will always say that EGL_KHR_swap_buffers_with_damage is supported.
// When the Vulkan driver supports VK_KHR_incremental_present, it will use it. Otherwise, it
// will ignore the hint and do a regular swap.
outExtensions->swapBuffersWithDamage = true;
}
......
......@@ -270,6 +270,19 @@ void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
// Initially dumping the command graphs is disabled.
constexpr bool kEnableCommandGraphDiagnostics = false;
bool ExtensionFound(const char *extensionName,
const std::vector<VkExtensionProperties> &extensionProps)
{
for (const auto &extensionProp : extensionProps)
{
if (strcmp(extensionProp.extensionName, extensionName) == 0)
{
return true;
}
}
return false;
}
} // anonymous namespace
// CommandBatch implementation.
......@@ -299,6 +312,7 @@ void RendererVk::CommandBatch::destroy(VkDevice device)
RendererVk::RendererVk()
: mDisplay(nullptr),
mCapsInitialized(false),
mFeaturesInitialized(false),
mInstance(VK_NULL_HANDLE),
mEnableValidationLayers(false),
mEnableMockICD(false),
......@@ -533,8 +547,6 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
ANGLE_VK_CHECK(displayVk, graphicsQueueFamilyCount > 0, VK_ERROR_INITIALIZATION_FAILED);
initFeatures();
// If only one queue family, go ahead and initialize the device. If there is more than one
// queue, we'll have to wait until we see a WindowSurface to know which supports present.
if (graphicsQueueFamilyCount == 1)
......@@ -589,11 +601,18 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
std::vector<const char *> enabledDeviceExtensions;
enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
initFeatures(deviceExtensionProps);
mFeaturesInitialized = true;
// Selectively enable KHR_MAINTENANCE1 to support viewport flipping.
if (getFeatures().flipViewportY)
{
enabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME);
}
if (getFeatures().supportsIncrementalPresent)
{
enabledDeviceExtensions.push_back(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME);
}
ANGLE_VK_TRY(displayVk, VerifyExtensionsPresent(deviceExtensionProps, enabledDeviceExtensions));
......@@ -766,7 +785,7 @@ gl::Version RendererVk::getMaxSupportedESVersion() const
return gl::Version(3, 0);
}
void RendererVk::initFeatures()
void RendererVk::initFeatures(const std::vector<VkExtensionProperties> &deviceExtensionProps)
{
// Use OpenGL line rasterization rules by default.
// TODO(jmadill): Fix Android support. http://anglebug.com/2830
......@@ -802,6 +821,11 @@ void RendererVk::initFeatures()
mFeatures.flushAfterVertexConversion =
IsNexus5X(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);
#endif
if (ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionProps))
{
mFeatures.supportsIncrementalPresent = true;
}
}
void RendererVk::initPipelineCacheVkKey()
......
......@@ -165,7 +165,11 @@ class RendererVk : angle::NonCopyable
angle::Result getFullScreenClearShaderProgram(vk::Context *context,
vk::ShaderProgramHelper **programOut);
DispatchUtilsVk &getDispatchUtils() { return mDispatchUtils; }
const angle::FeaturesVk &getFeatures() const { return mFeatures; }
const angle::FeaturesVk &getFeatures() const
{
ASSERT(mFeaturesInitialized);
return mFeatures;
}
angle::Result getTimestamp(vk::Context *context, uint64_t *timestampOut);
......@@ -212,7 +216,7 @@ class RendererVk : angle::NonCopyable
vk::CommandBuffer &&commandBuffer);
void freeAllInFlightResources();
angle::Result flushCommandGraph(vk::Context *context, vk::CommandBuffer *commandBatch);
void initFeatures();
void initFeatures(const std::vector<VkExtensionProperties> &deviceExtensionProps);
void initPipelineCacheVkKey();
angle::Result initPipelineCache(DisplayVk *display);
......@@ -234,6 +238,7 @@ class RendererVk : angle::NonCopyable
mutable gl::TextureCapsMap mNativeTextureCaps;
mutable gl::Extensions mNativeExtensions;
mutable gl::Limitations mNativeLimitations;
mutable bool mFeaturesInitialized;
mutable angle::FeaturesVk mFeatures;
VkInstance mInstance;
......
......@@ -539,22 +539,22 @@ FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::Context *co
}
egl::Error WindowSurfaceVk::swapWithDamage(const gl::Context *context,
EGLint * /*rects*/,
EGLint /*n_rects*/)
EGLint *rects,
EGLint n_rects)
{
DisplayVk *displayVk = vk::GetImpl(context->getCurrentDisplay());
angle::Result result = swapImpl(displayVk);
angle::Result result = swapImpl(displayVk, rects, n_rects);
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
}
egl::Error WindowSurfaceVk::swap(const gl::Context *context)
{
DisplayVk *displayVk = vk::GetImpl(context->getCurrentDisplay());
angle::Result result = swapImpl(displayVk);
angle::Result result = swapImpl(displayVk, nullptr, 0);
return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
}
angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk)
angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects)
{
RendererVk *renderer = displayVk->getRenderer();
......@@ -597,6 +597,31 @@ angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk)
presentInfo.pImageIndices = &mCurrentSwapchainImageIndex;
presentInfo.pResults = nullptr;
VkPresentRegionsKHR presentRegions = {};
if (renderer->getFeatures().supportsIncrementalPresent && (n_rects > 0))
{
VkPresentRegionKHR presentRegion = {};
std::vector<VkRectLayerKHR> vk_rects(n_rects);
EGLint *egl_rects = rects;
presentRegion.rectangleCount = n_rects;
for (EGLint rect = 0; rect < n_rects; rect++)
{
vk_rects[rect].offset.x = *egl_rects++;
vk_rects[rect].offset.y = *egl_rects++;
vk_rects[rect].extent.width = *egl_rects++;
vk_rects[rect].extent.height = *egl_rects++;
vk_rects[rect].layer = 0;
}
presentRegion.pRectangles = vk_rects.data();
presentRegions.sType = VK_STRUCTURE_TYPE_PRESENT_REGIONS_KHR;
presentRegions.pNext = nullptr;
presentRegions.swapchainCount = 1;
presentRegions.pRegions = &presentRegion;
presentInfo.pNext = &presentRegions;
}
ANGLE_VK_TRY(displayVk, vkQueuePresentKHR(renderer->getQueue(), &presentInfo));
{
......
......@@ -143,7 +143,7 @@ class WindowSurfaceVk : public SurfaceImpl
virtual angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut) = 0;
angle::Result initializeImpl(DisplayVk *displayVk);
angle::Result nextSwapchainImage(DisplayVk *displayVk);
angle::Result swapImpl(DisplayVk *displayVk);
angle::Result swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects);
VkSwapchainKHR mSwapchain;
VkPresentModeKHR mSwapchainPresentMode;
......
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