]
},
{"name" : "VK_KHR_incremental_present", "spec_version" : "1"}
+ {"name" : "VK_KHR_get_surface_capabilities2", "spec_version" : "1"},
+ {"name" : "VK_KHR_surface_protected_capabilities", "spec_version" : "1"},
+ {"name" : "VK_EXT_display_surface_counter", "spec_version" : "1"}
],
"disable_environment": {
"DISABLE_WSI_LAYER": "1"
GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilitiesKHR);
GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormatsKHR);
GET_PROC_ADDR(vkGetPhysicalDeviceSurfacePresentModesKHR);
+ GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilities2KHR);
+ GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceCapabilities2EXT);
+ GET_PROC_ADDR(vkGetPhysicalDeviceSurfaceFormats2KHR);
GET_PROC_ADDR(vkDestroySurfaceKHR);
}
REQUIRED(GetPhysicalDeviceImageFormatProperties) \
REQUIRED(EnumerateDeviceExtensionProperties) \
OPTIONAL(GetPhysicalDeviceSurfaceCapabilitiesKHR) \
+ OPTIONAL(GetPhysicalDeviceSurfaceCapabilities2KHR) \
+ OPTIONAL(GetPhysicalDeviceSurfaceCapabilities2EXT) \
OPTIONAL(GetPhysicalDeviceSurfaceFormatsKHR) \
+ OPTIONAL(GetPhysicalDeviceSurfaceFormats2KHR) \
OPTIONAL(GetPhysicalDeviceSurfacePresentModesKHR) \
OPTIONAL(GetPhysicalDeviceSurfaceSupportKHR) \
OPTIONAL(CreateHeadlessSurfaceEXT) \
instance_data.remove_surface(
surface, util::allocator{ instance_data.get_allocator(), VK_SYSTEM_ALLOCATION_SCOPE_OBJECT, pAllocator });
}
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR *pSurfaceCapabilities)
+{
+ auto &instance = layer::instance_private_data::get(physicalDevice);
+ if (instance.should_layer_handle_surface(physicalDevice, pSurfaceInfo->surface))
+ {
+ wsi::surface_properties *props = wsi::get_surface_properties(pSurfaceInfo->surface);
+ assert(props != nullptr);
+ const void *pNext = pSurfaceCapabilities->pNext;
+ while (pNext) {
+ VkSurfaceProtectedCapabilitiesKHR *pProctedCap =
+ const_cast<VkSurfaceProtectedCapabilitiesKHR *>(reinterpret_cast<const VkSurfaceProtectedCapabilitiesKHR *>(pNext));
+ if (pProctedCap->sType == VK_STRUCTURE_TYPE_SURFACE_PROTECTED_CAPABILITIES_KHR) {
+ pProctedCap->supportsProtected = VK_FALSE;
+ break;
+ }
+ pNext = pProctedCap->pNext;
+ }
+ return props->get_surface_capabilities(physicalDevice, pSurfaceInfo->surface, &pSurfaceCapabilities->surfaceCapabilities);
+ }
+
+ /* If the layer cannot handle this surface, then necessarily the surface must have been created by the ICDs (or a
+ * layer below us.) So it is safe to assume that the ICDs (or layers below us) support VK_KHR_surface and therefore
+ * it is safe to can call down. This holds for other entrypoints below.
+ */
+ return instance.disp.GetPhysicalDeviceSurfaceCapabilities2KHR(physicalDevice, pSurfaceInfo, pSurfaceCapabilities);
+}
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormat2KHR *pSurfaceFormats)
+{
+ auto &instance = layer::instance_private_data::get(physicalDevice);
+ if (instance.should_layer_handle_surface(physicalDevice, pSurfaceInfo->surface))
+ {
+ wsi::surface_properties *props = wsi::get_surface_properties(pSurfaceInfo->surface);
+ assert(props != nullptr);
+ return props->get_surface_formats_2(physicalDevice, pSurfaceInfo->surface, pSurfaceFormatCount, pSurfaceFormats);
+ }
+
+ return instance.disp.GetPhysicalDeviceSurfaceFormats2KHR(physicalDevice, pSurfaceInfo, pSurfaceFormatCount,
+ pSurfaceFormats);
+}
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface, uint32_t* pRectCount,
+ VkRect2D* pRects)
+{
+ auto &instance = layer::instance_private_data::get(physicalDevice);
+ if (instance.should_layer_handle_surface(physicalDevice, surface))
+ {
+ wsi::surface_properties *props = wsi::get_surface_properties(surface);
+ assert(props != nullptr);
+ return props->get_surface_present_rects(physicalDevice, surface, pRectCount, pRects);
+ }
+
+ return instance.disp.GetPhysicalDevicePresentRectanglesKHR(physicalDevice, surface, pRectCount, pRects);
+}
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT* pSurfaceCapabilities)
+{
+ auto &instance = layer::instance_private_data::get(physicalDevice);
+ if (instance.should_layer_handle_surface(physicalDevice, surface))
+ {
+ VkResult res = VK_SUCCESS;
+ wsi::surface_properties *props = wsi::get_surface_properties(surface);
+ assert(props != nullptr);
+
+ VkSurfaceCapabilitiesKHR surfaceCaps;
+ res = props->get_surface_capabilities(physicalDevice, surface, &surfaceCaps);
+ if (res != VK_SUCCESS)
+ return res;
+
+ pSurfaceCapabilities->minImageCount = surfaceCaps.minImageCount;
+ pSurfaceCapabilities->maxImageCount = surfaceCaps.maxImageCount;
+ pSurfaceCapabilities->currentExtent = surfaceCaps.currentExtent;
+ pSurfaceCapabilities->minImageExtent = surfaceCaps.minImageExtent;
+ pSurfaceCapabilities->maxImageExtent = surfaceCaps.maxImageExtent;
+ pSurfaceCapabilities->maxImageArrayLayers = surfaceCaps.maxImageArrayLayers;
+ pSurfaceCapabilities->supportedTransforms = surfaceCaps.supportedTransforms;
+ pSurfaceCapabilities->currentTransform = surfaceCaps.currentTransform;
+ pSurfaceCapabilities->supportedCompositeAlpha = surfaceCaps.supportedCompositeAlpha;
+ pSurfaceCapabilities->supportedUsageFlags = surfaceCaps.supportedUsageFlags;
+ pSurfaceCapabilities->supportedSurfaceCounters = 0;
+
+ return VK_SUCCESS;
+ }
+
+ /* If the layer cannot handle this surface, then necessarily the surface must have been created by the ICDs (or a
+ * layer below us.) So it is safe to assume that the ICDs (or layers below us) support VK_KHR_surface and therefore
+ * it is safe to can call down. This holds for other entrypoints below.
+ */
+ return instance.disp.GetPhysicalDeviceSurfaceCapabilities2EXT(physicalDevice, surface, pSurfaceCapabilities);
+
+}
#include <vulkan/vulkan.h>
#include "util/macros.hpp"
-VKAPI_ATTR VkResult wsi_layer_vkCreateWaylandSurfaceKHR(VkInstance instance, const VkWaylandSurfaceCreateInfoKHR* pCreateInfo,
- const VkAllocationCallbacks* pAllocator, VkSurfaceKHR* pSurface);
-
-VKAPI_ATTR void wsi_layer_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface, const VkAllocationCallbacks* pAllocator);
-
/**
* @brief Implements vkGetPhysicalDeviceSurfaceCapabilitiesKHR Vulkan entrypoint.
*/
VWL_VKAPI_CALL(void)
wsi_layer_vkDestroySurfaceKHR(VkInstance instance, VkSurfaceKHR surface,
const VkAllocationCallbacks *pAllocator) VWL_API_POST;
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ VkSurfaceCapabilities2KHR *pSurfaceCapabilities);
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDeviceSurfaceFormats2KHR(VkPhysicalDevice physicalDevice,
+ const VkPhysicalDeviceSurfaceInfo2KHR* pSurfaceInfo,
+ uint32_t *pSurfaceFormatCount,
+ VkSurfaceFormat2KHR *pSurfaceFormats);
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDevicePresentRectanglesKHR(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface, uint32_t* pRectCount,
+ VkRect2D* pRects);
+
+VWL_VKAPI_CALL(VkResult)
+wsi_layer_vkGetPhysicalDeviceSurfaceCapabilities2EXT(VkPhysicalDevice physicalDevice,
+ VkSurfaceKHR surface,
+ VkSurfaceCapabilities2EXT* pSurfaceCapabilities);
+
+}
wsi_layer_vkGetDeviceGroupPresentCapabilitiesKHR(
VkDevice device, VkDeviceGroupPresentCapabilitiesKHR *pDeviceGroupPresentCapabilities) VWL_API_POST;
+
VWL_VKAPI_CALL(VkResult)
wsi_layer_vkGetDeviceGroupSurfacePresentModesKHR(VkDevice device, VkSurfaceKHR surface,
VkDeviceGroupPresentModeFlagsKHR *pModes) VWL_API_POST;
--- /dev/null
+#pragma once
+
+#define LOG_TAG "WSI"
+#include <dlog/dlog.h>
+
+#define wsi_info(f, x...) LOGI(f, ##x)
+#define wsi_error(f, x...) LOGE(f, ##x)
+
virtual VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *surface_format_count, VkSurfaceFormatKHR *surface_formats) = 0;
+ virtual VkResult get_surface_formats_2(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ uint32_t *surface_format_count, VkSurfaceFormat2KHR *surface_formats) = 0;
+
/**
* @brief Implementation of vkGetPhysicalDeviceSurfacePresentModesKHR for the specific VkSurface type.
*/
virtual VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *present_mode_count, VkPresentModeKHR *present_modes) = 0;
+ virtual VkResult get_surface_present_rects(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ uint32_t* pRectCount, VkRect2D* pRects) = 0;
+
/**
* @brief Return the device extensions that this surface_properties implementation needs.
*/
#include <layer/private_data.hpp>
#include <util/timed_semaphore.hpp>
#include <util/custom_allocator.hpp>
-
-#define LOG_TAG "WSI"
-#include <dlog/dlog.h>
-
-#define wsi_info(f, x...) LOGI(f, ##x)
-#define wsi_error(f, x...) LOGE(f, ##x)
+#include <util/log_util.hpp>
namespace wsi
{
if (vk_surf == NULL || vk_surf->display == NULL || vk_surf->surface == NULL)
return VK_ERROR_SURFACE_LOST_KHR;
- tpl_display_t *tpl_display = tpl_display_get(reinterpret_cast<tpl_handle_t>(vk_surf->display));
- if (!tpl_display) {
- return VK_ERROR_SURFACE_LOST_KHR;
+ tpl_display_t *tpl_display = tpl_display_get_with_backend_type(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, reinterpret_cast<tpl_handle_t>(vk_surf->display));
+ if (tpl_display) {
+ tpl_object_reference(reinterpret_cast<tpl_object_t *>(tpl_display));
+ } else {
+ tpl_display = tpl_display_create(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, reinterpret_cast<tpl_handle_t>(vk_surf->display));
}
+ if (!tpl_display)
+ return VK_ERROR_SURFACE_LOST_KHR;
+
int cnt_min = 0, cnt_max = 0;
res = tpl_display_query_supported_buffer_count_from_native_window(tpl_display, vk_surf->display, &cnt_min, &cnt_max);
if (res != TPL_ERROR_NONE) {
return VK_ERROR_SURFACE_LOST_KHR;
}
+ tpl_object_unreference(reinterpret_cast<tpl_object_t *>(tpl_display));
+
/* Image count limits */
pSurfaceCapabilities->minImageCount = cnt_min;
pSurfaceCapabilities->maxImageCount = cnt_max;
return res;
}
+VkResult surface_properties::get_surface_formats_2(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ uint32_t *surfaceFormatCount, VkSurfaceFormat2KHR *surfaceFormats)
+{
+
+ VkResult res = VK_SUCCESS;
+ /* TODO: Hardcoding a list of sensible formats, may be query it from compositor later. */
+ static std::array<const VkFormat, 2> formats = { VK_FORMAT_R8G8B8A8_UNORM, VK_FORMAT_R8G8B8A8_SRGB };
+
+ assert(surfaceFormatCount != nullptr);
+ res = VK_SUCCESS;
+ if (nullptr == surfaceFormats)
+ {
+ *surfaceFormatCount = formats.size();
+ }
+ else
+ {
+ if (formats.size() > *surfaceFormatCount)
+ {
+ res = VK_INCOMPLETE;
+ }
+
+ *surfaceFormatCount = std::min(*surfaceFormatCount, static_cast<uint32_t>(formats.size()));
+ for (uint32_t i = 0; i < *surfaceFormatCount; ++i)
+ {
+ surfaceFormats[i].surfaceFormat.format = formats[i];
+ surfaceFormats[i].surfaceFormat.colorSpace = VK_COLORSPACE_SRGB_NONLINEAR_KHR;
+ }
+ }
+
+ return res;
+}
+
VkResult surface_properties::get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes)
{
if (vk_surf == NULL || vk_surf->display == NULL || vk_surf->surface == NULL)
return VK_ERROR_SURFACE_LOST_KHR;
- tpl_display_t *tpl_display = tpl_display_get(reinterpret_cast<tpl_handle_t>(vk_surf->display));
- if (!tpl_display) {
- return VK_ERROR_SURFACE_LOST_KHR;
+ tpl_display_t *tpl_display = tpl_display_get_with_backend_type(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, reinterpret_cast<tpl_handle_t>(vk_surf->display));
+ if (tpl_display) {
+ tpl_object_reference(reinterpret_cast<tpl_object_t *>(tpl_display));
+ } else {
+ tpl_display = tpl_display_create(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, reinterpret_cast<tpl_handle_t>(vk_surf->display));
}
+ if (!tpl_display)
+ return VK_ERROR_SURFACE_LOST_KHR;
+
int tplModes;
if (tpl_display_query_supported_present_modes_from_native_window(tpl_display, vk_surf->display, &tplModes) != TPL_ERROR_NONE) {
return VK_ERROR_SURFACE_LOST_KHR;
}
+ tpl_object_unreference(reinterpret_cast<tpl_object_t *>(tpl_display));
+
std::vector<VkPresentModeKHR> modes = {};
if (tplModes & TPL_DISPLAY_PRESENT_MODE_IMMEDIATE)
modes.push_back(VK_PRESENT_MODE_IMMEDIATE_KHR);
return res;
}
+VkResult surface_properties::get_surface_present_rects(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ uint32_t* pRectCount, VkRect2D* pRects)
+{
+ VkResult res = VK_SUCCESS;
+
+ if (nullptr == pRects)
+ {
+ *pRectCount = 1;
+ res = VK_SUCCESS;
+ }
+ else if (0 == *pRectCount)
+ {
+ res = VK_INCOMPLETE;
+ }
+ else
+ {
+ *pRectCount = 1;
+ pRects[0].offset.x = 0;
+ pRects[0].offset.y = 0;
+ pRects[0].extent = { 0xffffffff, 0xffffffff };
+
+ res = VK_SUCCESS;
+ }
+
+ return res;
+}
+
static const char *required_device_extensions[] = {
VK_EXT_IMAGE_DRM_FORMAT_MODIFIER_EXTENSION_NAME,
VK_KHR_BIND_MEMORY_2_EXTENSION_NAME,
VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) override;
VkResult get_surface_formats(VkPhysicalDevice physical_device, VkSurfaceKHR surface, uint32_t *surfaceFormatCount,
VkSurfaceFormatKHR *surfaceFormats) override;
+ VkResult get_surface_formats_2(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
+ uint32_t *surface_format_count, VkSurfaceFormat2KHR *surface_formats) override;
VkResult get_surface_present_modes(VkPhysicalDevice physical_device, VkSurfaceKHR surface,
uint32_t *pPresentModeCount, VkPresentModeKHR *pPresentModes) override;
+ VkResult get_surface_present_rects(VkPhysicalDevice physicalDevice, VkSurfaceKHR surface,
+ uint32_t* pRectCount, VkRect2D* pRects) override;
const util::extension_list &get_required_device_extensions() override;
swapchain::swapchain(layer::device_private_data &dev_data, const VkAllocationCallbacks *pAllocator)
: swapchain_base(dev_data, pAllocator)
+ , m_tpl_display(nullptr)
, m_tpl_surface(nullptr)
{
}
tpl_surface_destroy_swapchain(m_tpl_surface);
tpl_object_unreference((tpl_object_t *)m_tpl_surface);
}
+ if (m_tpl_display) {
+ tpl_object_unreference((tpl_object_t *)m_tpl_display);
+ }
}
#define TBM_FORMAT_0 0
int tpl_present_mode;
tpl_result_t res;
- tpl_display_t *tpl_display = tpl_display_get(reinterpret_cast<tpl_handle_t>(vk_surf->display));
- if (!tpl_display) {
- wsi_error("Get tpl display failed\n");
- return VK_ERROR_SURFACE_LOST_KHR;
+ m_tpl_display = tpl_display_get_with_backend_type(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, reinterpret_cast<tpl_handle_t>(vk_surf->display));
+ if (m_tpl_display) {
+ tpl_object_reference(reinterpret_cast<tpl_object_t *>(m_tpl_display));
+ } else {
+ m_tpl_display = tpl_display_create(TPL_BACKEND_WAYLAND_VULKAN_WSI_THREAD, reinterpret_cast<tpl_handle_t>(vk_surf->display));
}
- m_tpl_surface = tpl_surface_get(tpl_display, vk_surf->surface);
- wsi_info("Get tpl_surface[%p] from tpl_display[%p]", m_tpl_surface, tpl_display);
+ if (!m_tpl_display)
+ return VK_ERROR_SURFACE_LOST_KHR;
+
+ m_tpl_surface = tpl_surface_get(m_tpl_display, vk_surf->surface);
+ wsi_info("Get tpl_surface[%p] from tpl_display[%p]", m_tpl_surface, m_tpl_display);
if (m_tpl_surface == NULL) {
format = wsi_tizen_get_tbm_format(pSwapchainCreateInfo->imageFormat, pSwapchainCreateInfo->compositeAlpha);
- m_tpl_surface = tpl_surface_create(tpl_display, vk_surf->surface, TPL_SURFACE_TYPE_WINDOW, format);
+ m_tpl_surface = tpl_surface_create(m_tpl_display, vk_surf->surface, TPL_SURFACE_TYPE_WINDOW, format);
} else {
wsi_error("tpl_surface[%p] already in use", m_tpl_surface);
return VK_ERROR_INITIALIZATION_FAILED;
struct tizen_image_data;
VkResult allocate_image(const VkImageCreateInfo &image_create_info, tizen_image_data *image_data, VkImage *image);
- //tpl_display_t *m_tpl_display;
+ tpl_display_t *m_tpl_display;
tpl_surface_t *m_tpl_surface;
};