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 ...@@ -53,6 +53,10 @@ struct FeaturesVk
// attributes and the vertex shader that reads from it is ineffective. Only known workaround is // 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 // to perform a flush after the conversion. http://anglebug.com/3016
bool flushAfterVertexConversion = false; 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 } // namespace angle
......
...@@ -171,7 +171,9 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const ...@@ -171,7 +171,9 @@ void DisplayVk::generateExtensions(egl::DisplayExtensions *outExtensions) const
// backend can be tested in Chrome. http://anglebug.com/2722 // backend can be tested in Chrome. http://anglebug.com/2722
outExtensions->robustResourceInitialization = true; 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; outExtensions->swapBuffersWithDamage = true;
} }
......
...@@ -270,6 +270,19 @@ void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices, ...@@ -270,6 +270,19 @@ void ChoosePhysicalDevice(const std::vector<VkPhysicalDevice> &physicalDevices,
// Initially dumping the command graphs is disabled. // Initially dumping the command graphs is disabled.
constexpr bool kEnableCommandGraphDiagnostics = false; 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 } // anonymous namespace
// CommandBatch implementation. // CommandBatch implementation.
...@@ -299,6 +312,7 @@ void RendererVk::CommandBatch::destroy(VkDevice device) ...@@ -299,6 +312,7 @@ void RendererVk::CommandBatch::destroy(VkDevice device)
RendererVk::RendererVk() RendererVk::RendererVk()
: mDisplay(nullptr), : mDisplay(nullptr),
mCapsInitialized(false), mCapsInitialized(false),
mFeaturesInitialized(false),
mInstance(VK_NULL_HANDLE), mInstance(VK_NULL_HANDLE),
mEnableValidationLayers(false), mEnableValidationLayers(false),
mEnableMockICD(false), mEnableMockICD(false),
...@@ -533,8 +547,6 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk, ...@@ -533,8 +547,6 @@ angle::Result RendererVk::initialize(DisplayVk *displayVk,
ANGLE_VK_CHECK(displayVk, graphicsQueueFamilyCount > 0, VK_ERROR_INITIALIZATION_FAILED); 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 // 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. // queue, we'll have to wait until we see a WindowSurface to know which supports present.
if (graphicsQueueFamilyCount == 1) if (graphicsQueueFamilyCount == 1)
...@@ -589,11 +601,18 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF ...@@ -589,11 +601,18 @@ angle::Result RendererVk::initializeDevice(DisplayVk *displayVk, uint32_t queueF
std::vector<const char *> enabledDeviceExtensions; std::vector<const char *> enabledDeviceExtensions;
enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME); enabledDeviceExtensions.push_back(VK_KHR_SWAPCHAIN_EXTENSION_NAME);
initFeatures(deviceExtensionProps);
mFeaturesInitialized = true;
// Selectively enable KHR_MAINTENANCE1 to support viewport flipping. // Selectively enable KHR_MAINTENANCE1 to support viewport flipping.
if (getFeatures().flipViewportY) if (getFeatures().flipViewportY)
{ {
enabledDeviceExtensions.push_back(VK_KHR_MAINTENANCE1_EXTENSION_NAME); 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)); ANGLE_VK_TRY(displayVk, VerifyExtensionsPresent(deviceExtensionProps, enabledDeviceExtensions));
...@@ -766,7 +785,7 @@ gl::Version RendererVk::getMaxSupportedESVersion() const ...@@ -766,7 +785,7 @@ gl::Version RendererVk::getMaxSupportedESVersion() const
return gl::Version(3, 0); return gl::Version(3, 0);
} }
void RendererVk::initFeatures() void RendererVk::initFeatures(const std::vector<VkExtensionProperties> &deviceExtensionProps)
{ {
// Use OpenGL line rasterization rules by default. // Use OpenGL line rasterization rules by default.
// TODO(jmadill): Fix Android support. http://anglebug.com/2830 // TODO(jmadill): Fix Android support. http://anglebug.com/2830
...@@ -802,6 +821,11 @@ void RendererVk::initFeatures() ...@@ -802,6 +821,11 @@ void RendererVk::initFeatures()
mFeatures.flushAfterVertexConversion = mFeatures.flushAfterVertexConversion =
IsNexus5X(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID); IsNexus5X(mPhysicalDeviceProperties.vendorID, mPhysicalDeviceProperties.deviceID);
#endif #endif
if (ExtensionFound(VK_KHR_INCREMENTAL_PRESENT_EXTENSION_NAME, deviceExtensionProps))
{
mFeatures.supportsIncrementalPresent = true;
}
} }
void RendererVk::initPipelineCacheVkKey() void RendererVk::initPipelineCacheVkKey()
......
...@@ -165,7 +165,11 @@ class RendererVk : angle::NonCopyable ...@@ -165,7 +165,11 @@ class RendererVk : angle::NonCopyable
angle::Result getFullScreenClearShaderProgram(vk::Context *context, angle::Result getFullScreenClearShaderProgram(vk::Context *context,
vk::ShaderProgramHelper **programOut); vk::ShaderProgramHelper **programOut);
DispatchUtilsVk &getDispatchUtils() { return mDispatchUtils; } 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); angle::Result getTimestamp(vk::Context *context, uint64_t *timestampOut);
...@@ -212,7 +216,7 @@ class RendererVk : angle::NonCopyable ...@@ -212,7 +216,7 @@ class RendererVk : angle::NonCopyable
vk::CommandBuffer &&commandBuffer); vk::CommandBuffer &&commandBuffer);
void freeAllInFlightResources(); void freeAllInFlightResources();
angle::Result flushCommandGraph(vk::Context *context, vk::CommandBuffer *commandBatch); angle::Result flushCommandGraph(vk::Context *context, vk::CommandBuffer *commandBatch);
void initFeatures(); void initFeatures(const std::vector<VkExtensionProperties> &deviceExtensionProps);
void initPipelineCacheVkKey(); void initPipelineCacheVkKey();
angle::Result initPipelineCache(DisplayVk *display); angle::Result initPipelineCache(DisplayVk *display);
...@@ -234,6 +238,7 @@ class RendererVk : angle::NonCopyable ...@@ -234,6 +238,7 @@ class RendererVk : angle::NonCopyable
mutable gl::TextureCapsMap mNativeTextureCaps; mutable gl::TextureCapsMap mNativeTextureCaps;
mutable gl::Extensions mNativeExtensions; mutable gl::Extensions mNativeExtensions;
mutable gl::Limitations mNativeLimitations; mutable gl::Limitations mNativeLimitations;
mutable bool mFeaturesInitialized;
mutable angle::FeaturesVk mFeatures; mutable angle::FeaturesVk mFeatures;
VkInstance mInstance; VkInstance mInstance;
......
...@@ -539,22 +539,22 @@ FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::Context *co ...@@ -539,22 +539,22 @@ FramebufferImpl *WindowSurfaceVk::createDefaultFramebuffer(const gl::Context *co
} }
egl::Error WindowSurfaceVk::swapWithDamage(const gl::Context *context, egl::Error WindowSurfaceVk::swapWithDamage(const gl::Context *context,
EGLint * /*rects*/, EGLint *rects,
EGLint /*n_rects*/) EGLint n_rects)
{ {
DisplayVk *displayVk = vk::GetImpl(context->getCurrentDisplay()); 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); return angle::ToEGL(result, displayVk, EGL_BAD_SURFACE);
} }
egl::Error WindowSurfaceVk::swap(const gl::Context *context) egl::Error WindowSurfaceVk::swap(const gl::Context *context)
{ {
DisplayVk *displayVk = vk::GetImpl(context->getCurrentDisplay()); 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); 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(); RendererVk *renderer = displayVk->getRenderer();
...@@ -597,6 +597,31 @@ angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk) ...@@ -597,6 +597,31 @@ angle::Result WindowSurfaceVk::swapImpl(DisplayVk *displayVk)
presentInfo.pImageIndices = &mCurrentSwapchainImageIndex; presentInfo.pImageIndices = &mCurrentSwapchainImageIndex;
presentInfo.pResults = nullptr; 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)); ANGLE_VK_TRY(displayVk, vkQueuePresentKHR(renderer->getQueue(), &presentInfo));
{ {
......
...@@ -143,7 +143,7 @@ class WindowSurfaceVk : public SurfaceImpl ...@@ -143,7 +143,7 @@ class WindowSurfaceVk : public SurfaceImpl
virtual angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut) = 0; virtual angle::Result createSurfaceVk(vk::Context *context, gl::Extents *extentsOut) = 0;
angle::Result initializeImpl(DisplayVk *displayVk); angle::Result initializeImpl(DisplayVk *displayVk);
angle::Result nextSwapchainImage(DisplayVk *displayVk); angle::Result nextSwapchainImage(DisplayVk *displayVk);
angle::Result swapImpl(DisplayVk *displayVk); angle::Result swapImpl(DisplayVk *displayVk, EGLint *rects, EGLint n_rects);
VkSwapchainKHR mSwapchain; VkSwapchainKHR mSwapchain;
VkPresentModeKHR mSwapchainPresentMode; 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