aboutsummaryrefslogtreecommitdiff
path: root/render/vulkan/util.c
diff options
context:
space:
mode:
authornyorain <nyorain@gmail.com>2021-02-21 18:30:12 +0100
committerSimon Ser <contact@emersion.fr>2021-10-18 11:51:13 +0200
commit8e346922508aa3eaccd6e12f2917f6574f349843 (patch)
tree550742b8a086287b6d478db1ade14b2cc4a21294 /render/vulkan/util.c
parent2edf468aeb7d4703aa211cea3b58f04cbc73298c (diff)
render/vulkan: add Vulkan renderer
This new renderer is implemented with the existing wlr_renderer API (which is known to be sub-optimal for some operations). It's not used by default, but users can opt-in by setting WLR_RENDERER=vulkan. The renderer depends on VK_EXT_image_drm_format_modifier and VK_EXT_physical_device_drm. Co-authored-by: Simon Ser <contact@emersion.fr> Co-authored-by: Jan Beich <jbeich@FreeBSD.org>
Diffstat (limited to 'render/vulkan/util.c')
-rw-r--r--render/vulkan/util.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/render/vulkan/util.c b/render/vulkan/util.c
new file mode 100644
index 00000000..b15c57eb
--- /dev/null
+++ b/render/vulkan/util.c
@@ -0,0 +1,93 @@
+#include <vulkan/vulkan.h>
+#include <wlr/util/log.h>
+#include "render/vulkan.h"
+
+int vulkan_find_mem_type(struct wlr_vk_device *dev,
+ VkMemoryPropertyFlags flags, uint32_t req_bits) {
+
+ VkPhysicalDeviceMemoryProperties props;
+ vkGetPhysicalDeviceMemoryProperties(dev->phdev, &props);
+
+ for (unsigned i = 0u; i < props.memoryTypeCount; ++i) {
+ if (req_bits & (1 << i)) {
+ if ((props.memoryTypes[i].propertyFlags & flags) == flags) {
+ return i;
+ }
+ }
+ }
+
+ return -1;
+}
+
+const char *vulkan_strerror(VkResult err) {
+ #define ERR_STR(r) case VK_ ##r: return #r
+ switch (err) {
+ ERR_STR(SUCCESS);
+ ERR_STR(NOT_READY);
+ ERR_STR(TIMEOUT);
+ ERR_STR(EVENT_SET);
+ ERR_STR(EVENT_RESET);
+ ERR_STR(INCOMPLETE);
+ ERR_STR(SUBOPTIMAL_KHR);
+ ERR_STR(ERROR_OUT_OF_HOST_MEMORY);
+ ERR_STR(ERROR_OUT_OF_DEVICE_MEMORY);
+ ERR_STR(ERROR_INITIALIZATION_FAILED);
+ ERR_STR(ERROR_DEVICE_LOST);
+ ERR_STR(ERROR_MEMORY_MAP_FAILED);
+ ERR_STR(ERROR_LAYER_NOT_PRESENT);
+ ERR_STR(ERROR_EXTENSION_NOT_PRESENT);
+ ERR_STR(ERROR_FEATURE_NOT_PRESENT);
+ ERR_STR(ERROR_INCOMPATIBLE_DRIVER);
+ ERR_STR(ERROR_TOO_MANY_OBJECTS);
+ ERR_STR(ERROR_FORMAT_NOT_SUPPORTED);
+ ERR_STR(ERROR_SURFACE_LOST_KHR);
+ ERR_STR(ERROR_NATIVE_WINDOW_IN_USE_KHR);
+ ERR_STR(ERROR_OUT_OF_DATE_KHR);
+ ERR_STR(ERROR_FRAGMENTED_POOL);
+ ERR_STR(ERROR_INCOMPATIBLE_DISPLAY_KHR);
+ ERR_STR(ERROR_VALIDATION_FAILED_EXT);
+ ERR_STR(ERROR_INVALID_EXTERNAL_HANDLE);
+ ERR_STR(ERROR_OUT_OF_POOL_MEMORY);
+ ERR_STR(ERROR_INVALID_DRM_FORMAT_MODIFIER_PLANE_LAYOUT_EXT);
+ default:
+ return "<unknown>";
+ }
+ #undef ERR_STR
+}
+
+void vulkan_change_layout_queue(VkCommandBuffer cb, VkImage img,
+ VkImageLayout ol, VkPipelineStageFlags srcs, VkAccessFlags srca,
+ VkImageLayout nl, VkPipelineStageFlags dsts, VkAccessFlags dsta,
+ uint32_t src_family, uint32_t dst_family) {
+ VkImageMemoryBarrier barrier = {0};
+ barrier.sType = VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER;
+ barrier.oldLayout = ol;
+ barrier.newLayout = nl;
+ barrier.image = img;
+ barrier.subresourceRange.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
+ barrier.subresourceRange.layerCount = 1;
+ barrier.subresourceRange.levelCount = 1;
+ barrier.srcAccessMask = srca;
+ barrier.dstAccessMask = dsta;
+ barrier.srcQueueFamilyIndex = src_family;
+ barrier.dstQueueFamilyIndex = dst_family;
+
+ vkCmdPipelineBarrier(cb, srcs, dsts, 0, 0, NULL, 0, NULL, 1, &barrier);
+}
+
+void vulkan_change_layout(VkCommandBuffer cb, VkImage img,
+ VkImageLayout ol, VkPipelineStageFlags srcs, VkAccessFlags srca,
+ VkImageLayout nl, VkPipelineStageFlags dsts, VkAccessFlags dsta) {
+ vulkan_change_layout_queue(cb, img, ol, srcs, srca, nl, dsts, dsta,
+ VK_QUEUE_FAMILY_IGNORED, VK_QUEUE_FAMILY_IGNORED);
+}
+
+bool vulkan_has_extension(size_t count, const char **exts, const char *find) {
+ for (unsigned i = 0; i < count; ++i) {
+ if (strcmp(exts[i], find) == 0u) {
+ return true;
+ }
+ }
+
+ return false;
+}