.travis.yml | 15 Makefile.am | 1 SConstruct | 8 VERSION | 2 bin/.cherry-ignore | 50 configure.ac | 13 debian/changelog | 29 debian/control | 3 debian/patches/i965-disable-l3-cache-alloc-for-ext-buffers.diff | 167 + debian/patches/series | 2 debian/patches/vulkan-mir.patch | 1099 ---------- debian/rules | 2 docs/relnotes/17.2.1.html | 3 docs/relnotes/17.2.2.html | 203 + docs/relnotes/17.2.3.html | 181 + docs/relnotes/17.2.4.html | 131 + include/EGL/eglmesaext.h | 1 scons/gallium.py | 22 scons/llvm.py | 37 src/SConscript | 2 src/amd/addrlib/core/addrobject.cpp | 8 src/amd/common/ac_llvm_build.c | 59 src/amd/common/ac_llvm_build.h | 14 src/amd/common/ac_nir_to_llvm.c | 23 src/amd/common/ac_surface.c | 11 src/amd/common/sid.h | 2 src/amd/vulkan/radv_cmd_buffer.c | 7 src/amd/vulkan/radv_formats.c | 6 src/amd/vulkan/radv_pipeline.c | 2 src/amd/vulkan/radv_private.h | 8 src/amd/vulkan/radv_query.c | 4 src/amd/vulkan/winsys/amdgpu/radv_amdgpu_bo.c | 2 src/compiler/glsl/blob.c | 11 src/compiler/glsl/blob.h | 6 src/compiler/glsl/glsl_to_nir.cpp | 2 src/compiler/glsl/linker.cpp | 23 src/compiler/glsl/lower_instructions.cpp | 167 - src/compiler/nir/nir_intrinsics.h | 8 src/compiler/nir/nir_opcodes.py | 2 src/compiler/spirv/spirv_to_nir.c | 1 src/compiler/spirv/vtn_cfg.c | 2 src/egl/drivers/dri2/egl_dri2.c | 12 src/egl/drivers/dri2/egl_dri2_fallbacks.h | 9 src/egl/drivers/dri2/platform_wayland.c | 68 src/egl/drivers/dri2/platform_x11.c | 1 src/egl/wayland/wayland-drm/wayland-drm.c | 10 src/gallium/auxiliary/gallivm/lp_bld_init.c | 2 src/gallium/auxiliary/gallivm/lp_bld_misc.cpp | 60 src/gallium/auxiliary/util/u_cpu_detect.c | 32 src/gallium/drivers/etnaviv/etnaviv_clear_blit.c | 2 src/gallium/drivers/freedreno/a5xx/fd5_emit.c | 3 src/gallium/drivers/freedreno/freedreno_resource.c | 6 src/gallium/drivers/llvmpipe/SConscript | 2 src/gallium/drivers/nouveau/codegen/nv50_ir_from_tgsi.cpp | 4 src/gallium/drivers/nouveau/nv50/nv50_push.c | 3 src/gallium/drivers/nouveau/nvc0/nvc0_vbo_translate.c | 9 src/gallium/drivers/radeon/r600_pipe_common.c | 11 src/gallium/drivers/radeon/r600_pipe_common.h | 2 src/gallium/drivers/radeon/r600_texture.c | 5 src/gallium/drivers/radeon/r600_viewport.c | 21 src/gallium/drivers/radeonsi/si_descriptors.c | 31 src/gallium/drivers/radeonsi/si_pipe.h | 2 src/gallium/drivers/radeonsi/si_shader.c | 20 src/gallium/drivers/radeonsi/si_shader_tgsi_mem.c | 161 + src/gallium/drivers/radeonsi/si_shader_tgsi_setup.c | 2 src/gallium/drivers/radeonsi/si_state.c | 127 - src/gallium/drivers/radeonsi/si_state_draw.c | 24 src/gallium/drivers/radeonsi/si_state_shaders.c | 16 src/gallium/drivers/svga/SConscript | 2 src/gallium/drivers/swr/SConscript | 6 src/gallium/drivers/swr/rasterizer/codegen/gen_llvm_ir_macros.py | 8 src/gallium/drivers/swr/rasterizer/core/utils.h | 3 src/gallium/drivers/vc4/vc4_bufmgr.c | 10 src/gallium/drivers/vc4/vc4_context.h | 7 src/gallium/drivers/vc4/vc4_draw.c | 65 src/gallium/drivers/vc4/vc4_job.c | 9 src/gallium/drivers/vc4/vc4_program.c | 21 src/gallium/drivers/vc4/vc4_qir_lower_uniforms.c | 2 src/gallium/drivers/vc4/vc4_resource.c | 15 src/gallium/drivers/vc4/vc4_resource.h | 14 src/gallium/drivers/vc4/vc4_state.c | 34 src/gallium/drivers/vc4/vc4_uniforms.c | 2 src/gallium/state_trackers/clover/llvm/codegen/common.cpp | 5 src/gallium/state_trackers/clover/llvm/compat.hpp | 12 src/gallium/state_trackers/dri/dri_drawable.c | 4 src/gallium/state_trackers/glx/xlib/xm_st.c | 4 src/gallium/state_trackers/hgl/hgl.c | 4 src/gallium/state_trackers/osmesa/osmesa.c | 2 src/gallium/state_trackers/va/buffer.c | 12 src/gallium/state_trackers/va/image.c | 10 src/gallium/state_trackers/va/postproc.c | 14 src/gallium/state_trackers/vdpau/surface.c | 2 src/gallium/state_trackers/wgl/stw_st.c | 4 src/gallium/targets/dri/SConscript | 2 src/intel/compiler/brw_eu_emit.c | 2 src/intel/compiler/brw_fs.cpp | 4 src/intel/compiler/brw_fs_cmod_propagation.cpp | 25 src/intel/compiler/brw_fs_generator.cpp | 1 src/intel/compiler/brw_vec4_cmod_propagation.cpp | 25 src/intel/compiler/brw_vec4_nir.cpp | 21 src/intel/compiler/brw_vec4_surface_builder.cpp | 13 src/intel/vulkan/anv_allocator.c | 2 src/intel/vulkan/anv_blorp.c | 4 src/intel/vulkan/anv_cmd_buffer.c | 61 src/intel/vulkan/anv_descriptor_set.c | 2 src/intel/vulkan/anv_pipeline.c | 3 src/intel/vulkan/anv_private.h | 3 src/intel/vulkan/gen8_cmd_buffer.c | 4 src/intel/vulkan/genX_cmd_buffer.c | 3 src/mesa/drivers/dri/i965/brw_blorp.c | 6 src/mesa/drivers/dri/i965/brw_state_upload.c | 24 src/mesa/drivers/dri/i965/intel_screen.c | 2 src/mesa/drivers/dri/nouveau/nouveau_gldefs.h | 19 src/mesa/drivers/dri/nouveau/nv20_state_tex.c | 16 src/mesa/main/context.c | 2 src/mesa/state_tracker/st_cb_eglimage.c | 96 src/mesa/state_tracker/st_format.c | 3 src/mesa/state_tracker/st_glsl_to_tgsi.cpp | 49 src/mesa/state_tracker/st_manager.c | 2 src/util/Makefile.am | 4 src/util/u_atomic.c | 14 src/util/u_queue.c | 13 src/vulkan/wsi/wsi_common_wayland.c | 249 +- src/vulkan/wsi/wsi_common_x11.c | 1 124 files changed, 2164 insertions(+), 1766 deletions(-)
New commits: commit 98c21694fbf47a84eb82dc6ef93e82dd3d252377 Author: Timo Aaltonen <tjaal...@debian.org> Date: Wed Nov 8 16:30:44 2017 +0200 release to bionic diff --git a/debian/changelog b/debian/changelog index 4a5b7bc..0ac3823 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,9 +1,10 @@ -mesa (17.2.4-0ubuntu2) UNRELEASED; urgency=medium +mesa (17.2.4-0ubuntu2) bionic; urgency=medium + * Import changes from 17.2.2-0ubuntu2 * Make mesa-va-drivers enhance libva2 rather than libva1. * vulkan-mir.patch: Dropped, breaks radeon vulkan driver. (LP: #1720890) - -- Timo Aaltonen <tjaal...@debian.org> Wed, 08 Nov 2017 16:22:08 +0200 + -- Timo Aaltonen <tjaal...@debian.org> Wed, 08 Nov 2017 16:29:58 +0200 mesa (17.2.4-0ubuntu1) bionic; urgency=medium commit bb7de675fab2ce1c67b508dbfad313a535e91dc8 Author: Timo Aaltonen <tjaal...@debian.org> Date: Wed Nov 8 16:24:59 2017 +0200 vulkan-mir.patch: Dropped, breaks radeon vulkan driver. (LP: #1720890) diff --git a/debian/changelog b/debian/changelog index 18f012d..4a5b7bc 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,6 +1,7 @@ mesa (17.2.4-0ubuntu2) UNRELEASED; urgency=medium * Make mesa-va-drivers enhance libva2 rather than libva1. + * vulkan-mir.patch: Dropped, breaks radeon vulkan driver. (LP: #1720890) -- Timo Aaltonen <tjaal...@debian.org> Wed, 08 Nov 2017 16:22:08 +0200 diff --git a/debian/patches/series b/debian/patches/series index 5f193c5..7f939ab 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -4,6 +4,5 @@ # Ubuntu patches. egl-platform-mir.patch egl-platform-rs.patch -vulkan-mir.patch khr_platform_mir.patch i965-disable-l3-cache-alloc-for-ext-buffers.diff diff --git a/debian/patches/vulkan-mir.patch b/debian/patches/vulkan-mir.patch deleted file mode 100644 index b218891..0000000 --- a/debian/patches/vulkan-mir.patch +++ /dev/null @@ -1,1099 +0,0 @@ ---- a/src/intel/vulkan/anv_device.c -+++ b/src/intel/vulkan/anv_device.c -@@ -419,6 +419,12 @@ static const VkExtensionProperties globa - .extensionName = VK_KHR_GET_SURFACE_CAPABILITIES_2_EXTENSION_NAME, - .specVersion = 1, - }, -+#ifdef VK_USE_PLATFORM_MIR_KHR -+ { -+ .extensionName = VK_KHR_MIR_SURFACE_EXTENSION_NAME, -+ .specVersion = 4, -+ }, -+#endif - { - .extensionName = VK_KHR_SURFACE_EXTENSION_NAME, - .specVersion = 25, -@@ -525,6 +531,67 @@ static const VkAllocationCallbacks defau - .pfnFree = default_free_func, - }; - -+static VkResult -+anv_bo_import_prime_fd(struct anv_bo *bo, struct anv_device *device, uint64_t size, int fd) -+{ -+ bo->gem_handle = anv_gem_fd_to_handle(device, fd); -+ if (!bo->gem_handle) -+ return vk_error(VK_ERROR_OUT_OF_DEVICE_MEMORY); -+ -+ bo->map = NULL; -+ bo->index = 0; -+ bo->offset = 0; -+ bo->size = size; -+ bo->flags = 0; -+ -+ return VK_SUCCESS; -+} -+ -+VkResult anv_ImportAllocatedMemory( -+ VkDevice _device, -+ int fd, -+ const VkMemoryAllocateInfo* pAllocateInfo, -+ const VkAllocationCallbacks* pAllocator, -+ VkDeviceMemory* pMem) -+{ -+ ANV_FROM_HANDLE(anv_device, device, _device); -+ struct anv_physical_device *pdevice = &device->instance->physicalDevice; -+ struct anv_device_memory *mem; -+ VkResult result; -+ -+ assert(pAllocateInfo->sType == VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO); -+ -+ if (pAllocateInfo->allocationSize == 0) { -+ /* Apparently, this is allowed */ -+ *pMem = VK_NULL_HANDLE; -+ return VK_SUCCESS; -+ } -+ -+ mem = vk_alloc2(&device->alloc, pAllocator, sizeof(*mem), 8, -+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); -+ if (mem == NULL) -+ return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY); -+ -+ /* The kernel is going to give us whole pages anyway */ -+ uint64_t alloc_size = align_u64(pAllocateInfo->allocationSize, 4096); -+ -+ result = anv_bo_import_prime_fd(&mem->bo, device, alloc_size, fd); -+ if (result != VK_SUCCESS) -+ goto fail; -+ -+ assert(pAllocateInfo->memoryTypeIndex < pdevice->memory.type_count); -+ mem->type = &pdevice->memory.types[pAllocateInfo->memoryTypeIndex]; -+ -+ *pMem = anv_device_memory_to_handle(mem); -+ -+ return VK_SUCCESS; -+ -+fail: -+ vk_free2(&device->alloc, pAllocator, mem); -+ -+ return result; -+} -+ - VkResult anv_CreateInstance( - const VkInstanceCreateInfo* pCreateInfo, - const VkAllocationCallbacks* pAllocator, ---- a/src/intel/vulkan/anv_private.h -+++ b/src/intel/vulkan/anv_private.h -@@ -74,6 +74,13 @@ struct gen_l3_config; - #include "common/gen_debug.h" - #include "wsi_common.h" - -+VkResult anv_ImportAllocatedMemory( -+ VkDevice _device, -+ int fd, -+ const VkMemoryAllocateInfo* pAllocateInfo, -+ const VkAllocationCallbacks* pAllocator, -+ VkDeviceMemory* pMem); -+ - /* Allowing different clear colors requires us to perform a depth resolve at - * the end of certain render passes. This is because while slow clears store - * the clear color in the HiZ buffer, fast clears (without a resolve) don't. ---- a/src/intel/vulkan/anv_wsi.c -+++ b/src/intel/vulkan/anv_wsi.c -@@ -57,12 +57,28 @@ anv_init_wsi(struct anv_physical_device - } - #endif - -+#ifdef VK_USE_PLATFORM_MIR_KHR -+ result = wsi_mir_init_wsi(&physical_device->wsi_device, &physical_device->instance->alloc); -+ if (result != VK_SUCCESS) { -+#ifdef VK_USE_PLATFORM_WAYLAND_KHR -+ wsi_wl_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc); -+#endif -+#ifdef VK_USE_PLATFORM_XCB_KHR -+ wsi_x11_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc); -+#endif -+ return result; -+ } -+#endif -+ - return VK_SUCCESS; - } - - void - anv_finish_wsi(struct anv_physical_device *physical_device) - { -+#ifdef VK_USE_PLATFORM_MIR_KHR -+ wsi_mir_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc); -+#endif - #ifdef VK_USE_PLATFORM_WAYLAND_KHR - wsi_wl_finish_wsi(&physical_device->wsi_device, &physical_device->instance->alloc); - #endif -@@ -174,6 +190,7 @@ anv_wsi_image_create(VkDevice device_h, - const VkAllocationCallbacks* pAllocator, - bool different_gpu, - bool linear, -+ bool import_fd, - VkImage *image_p, - VkDeviceMemory *memory_p, - uint32_t *size, -@@ -218,6 +235,18 @@ anv_wsi_image_create(VkDevice device_h, - - VkDeviceMemory memory_h; - struct anv_device_memory *memory; -+ if (import_fd) { -+ result = anv_ImportAllocatedMemory(anv_device_to_handle(device), -+ *fd_p, -+ &(VkMemoryAllocateInfo) { -+ .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, -+ .allocationSize = image->size, -+ .memoryTypeIndex = 0, -+ }, -+ pAllocator, -+ &memory_h); -+ } -+ else { - result = anv_AllocateMemory(anv_device_to_handle(device), - &(VkMemoryAllocateInfo) { - .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, -@@ -226,19 +255,27 @@ anv_wsi_image_create(VkDevice device_h, - }, - NULL /* XXX: pAllocator */, - &memory_h); -+ } - if (result != VK_SUCCESS) - goto fail_create_image; - - memory = anv_device_memory_from_handle(memory_h); - -- /* We need to set the WRITE flag on window system buffers so that GEM will -- * know we're writing to them and synchronize uses on other rings (eg if -- * the display server uses the blitter ring). -- */ -- memory->bo->flags &= ~EXEC_OBJECT_ASYNC; -- memory->bo->flags |= EXEC_OBJECT_WRITE; -+ if (import_fd) { -+ // Do we need to do more of what anv_BindImageMemory() does here? -+ image->bo = &memory->bo; -+ image->offset = 0; -+ } -+ else { -+ /* We need to set the WRITE flag on window system buffers so that GEM will -+ * know we're writing to them and synchronize uses on other rings (eg if -+ * the display server uses the blitter ring). -+ */ -+ memory->bo->flags &= ~EXEC_OBJECT_ASYNC; -+ memory->bo->flags |= EXEC_OBJECT_WRITE; - -- anv_BindImageMemory(device_h, image_h, memory_h, 0); -+ anv_BindImageMemory(device_h, image_h, memory_h, 0); -+ } - - struct anv_surface *surface = &image->color_surface; - assert(surface->isl.tiling == ISL_TILING_X); -@@ -253,13 +290,18 @@ anv_wsi_image_create(VkDevice device_h, - goto fail_alloc_memory; - } - -- int fd = anv_gem_handle_to_fd(device, memory->bo->gem_handle); -- if (fd == -1) { -- /* FINISHME: Choose a better error. */ -- result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, -- "handle_to_fd failed: %m"); -- goto fail_alloc_memory; -+ int fd; -+ if (!import_fd) { -+ fd = anv_gem_handle_to_fd(device, memory->bo->gem_handle); -+ if (fd == -1) { -+ /* FINISHME: Choose a better error. */ -+ result = vk_errorf(VK_ERROR_OUT_OF_DEVICE_MEMORY, -+ "handle_to_fd failed: %m"); -+ goto fail_alloc_memory; -+ } - } -+ else -+ fd = *fd_p; - - *image_p = image_h; - *memory_p = memory_h; -@@ -278,12 +320,14 @@ fail_create_image: - static void - anv_wsi_image_free(VkDevice device, - const VkAllocationCallbacks* pAllocator, -+ bool imported_fd, - VkImage image_h, - VkDeviceMemory memory_h) - { - anv_DestroyImage(device, image_h, pAllocator); - -- anv_FreeMemory(device, memory_h, pAllocator); -+ if (!imported_fd) -+ anv_FreeMemory(device, memory_h, pAllocator); - } - - static const struct wsi_image_fns anv_wsi_image_fns = { ---- /dev/null -+++ b/src/intel/vulkan/anv_wsi_mir.c -@@ -0,0 +1,53 @@ -+/* -+ * Copyright © 2017 Canonical Ltd. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#include "wsi_common_mir.h" -+#include "anv_private.h" -+ -+VkBool32 anv_GetPhysicalDeviceMirPresentationSupportKHR( -+ VkPhysicalDevice physicalDevice, -+ uint32_t queueFamilyIndex, -+ MirConnection* connection) -+{ -+ ANV_FROM_HANDLE(anv_physical_device, physical_device, physicalDevice); -+ -+ return wsi_get_mir_presentation_support(&physical_device->wsi_device, connection); -+} -+ -+VkResult anv_CreateMirSurfaceKHR( -+ VkInstance _instance, -+ const VkMirSurfaceCreateInfoKHR* pCreateInfo, -+ const VkAllocationCallbacks* pAllocator, -+ VkSurfaceKHR* pSurface) -+{ -+ ANV_FROM_HANDLE(anv_instance, instance, _instance); -+ const VkAllocationCallbacks *alloc; -+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_MIR_SURFACE_CREATE_INFO_KHR); -+ -+ if (pAllocator) -+ alloc = pAllocator; -+ else -+ alloc = &instance->alloc; -+ -+ return wsi_create_mir_surface(alloc, pCreateInfo, pSurface); -+} ---- a/src/vulkan/wsi/wsi_common.h -+++ b/src/vulkan/wsi/wsi_common.h -@@ -37,6 +37,7 @@ struct wsi_image_fns { - const VkAllocationCallbacks *pAllocator, - bool needs_linear_copy, - bool linear, -+ bool import_fd, - VkImage *image_p, - VkDeviceMemory *memory_p, - uint32_t *size_p, -@@ -45,6 +46,7 @@ struct wsi_image_fns { - int *fd_p); - void (*free_wsi_image)(VkDevice device, - const VkAllocationCallbacks *pAllocator, -+ bool imported_fd, - VkImage image_h, - VkDeviceMemory memory_h); - }; -@@ -169,6 +171,9 @@ VkResult wsi_wl_init_wsi(struct wsi_devi - const struct wsi_callbacks *cbs); - void wsi_wl_finish_wsi(struct wsi_device *wsi_device, - const VkAllocationCallbacks *alloc); -- -+VkResult wsi_mir_init_wsi(struct wsi_device *wsi_device, -+ const VkAllocationCallbacks *alloc); -+void wsi_mir_finish_wsi(struct wsi_device *wsi_device, -+ const VkAllocationCallbacks *alloc); - - #endif ---- /dev/null -+++ b/src/vulkan/wsi/wsi_common_mir.c -@@ -0,0 +1,585 @@ -+/* -+ * Copyright © 2017 Canonical Ltd. -+ * -+ * Permission is hereby granted, free of charge, to any person obtaining a -+ * copy of this software and associated documentation files (the "Software"), -+ * to deal in the Software without restriction, including without limitation -+ * the rights to use, copy, modify, merge, publish, distribute, sublicense, -+ * and/or sell copies of the Software, and to permit persons to whom the -+ * Software is furnished to do so, subject to the following conditions: -+ * -+ * The above copyright notice and this permission notice (including the next -+ * paragraph) shall be included in all copies or substantial portions of the -+ * Software. -+ * -+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL -+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -+ * IN THE SOFTWARE. -+ */ -+ -+#include <mir_toolkit/mir_client_library.h> -+#include <mir_toolkit/extensions/gbm_buffer.h> -+#include <gbm.h> -+#include <errno.h> -+ -+#include <util/hash_table.h> -+ -+#include "wsi_common_mir.h" -+ -+#define TRACE printf("%s()\n", __func__); -+ -+#define typed_memcpy(dest, src, count) ({ \ -+ STATIC_ASSERT(sizeof(*src) == sizeof(*dest)); \ -+ memcpy((dest), (src), (count) * sizeof(*(src))); \ -+}) -+ -+struct wsi_mir { -+ struct wsi_interface base; -+ -+// pthread_mutex_t mutex; -+ /* Hash table of MirConnection* -> wsi_mir_connection mappings */ -+// struct hash_table *connections; -+}; -+ -+static const VkSurfaceFormatKHR formats[] = { -+ { .format = VK_FORMAT_B8G8R8A8_UNORM, }, -+}; -+ -+static const VkPresentModeKHR present_modes[] = { -+ VK_PRESENT_MODE_FIFO_KHR, -+}; -+ -+struct wsi_mir_image { -+ VkImage image; -+ VkDeviceMemory memory; -+ MirBuffer* buffer; -+ bool busy; -+ pthread_mutex_t lock; -+ pthread_cond_t cv; -+}; -+ -+struct wsi_mir_swapchain { -+ struct wsi_swapchain base; -+ -+ MirConnection *connection; -+ MirRenderSurface *surface; -+ MirPresentationChain *presentation_chain; -+ -+ struct MirExtensionGbmBufferV1 const* gbm_buffer_ext; -+ -+ VkExtent2D extent; -+ VkFormat vk_format; -+ -+ VkPresentModeKHR present_mode; -+ bool fifo_ready; -+ pthread_mutex_t lock; -+ pthread_cond_t cv; -+ -+ uint32_t image_count; -+ uint32_t next_image_to_use; -+ struct wsi_mir_image images[0]; -+}; -+ -+static VkResult -+wsi_mir_surface_get_support(VkIcdSurfaceBase *surface, -+ struct wsi_device *wsi_device, -+ const VkAllocationCallbacks *alloc, -+ uint32_t queueFamilyIndex, -+ VkBool32* pSupported) -+{ -+ TRACE -+ -+ *pSupported = true; -+ -+ return VK_SUCCESS; -+} -+ -+static VkResult -+wsi_mir_surface_get_capabilities(VkIcdSurfaceBase *surface, -+ VkSurfaceCapabilitiesKHR *pSurfaceCapabilities) -+{ -+ TRACE -+ -+ pSurfaceCapabilities->minImageCount = 2; -+ pSurfaceCapabilities->maxImageCount = 0; // 0 to force to maximum supported -+ pSurfaceCapabilities->currentExtent = (VkExtent2D) { -1, -1 }; -+ pSurfaceCapabilities->minImageExtent = (VkExtent2D) { 1, 1 }; -+ pSurfaceCapabilities->maxImageExtent = (VkExtent2D) { INT16_MAX, INT16_MAX }; -+ pSurfaceCapabilities->supportedTransforms = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; -+ pSurfaceCapabilities->currentTransform = VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR; -+ pSurfaceCapabilities->maxImageArrayLayers = 1; -+ -+ pSurfaceCapabilities->supportedCompositeAlpha = -+ VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR /*| -+ VK_COMPOSITE_ALPHA_PRE_MULTIPLIED_BIT_KHR*/; -+ -+ pSurfaceCapabilities->supportedUsageFlags = -+/* VK_IMAGE_USAGE_TRANSFER_SRC_BIT | -+ VK_IMAGE_USAGE_SAMPLED_BIT |*/ -+ VK_IMAGE_USAGE_TRANSFER_DST_BIT | -+ VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT; -+ -+ return VK_SUCCESS; -+} -+ -+static VkResult -+wsi_mir_surface_get_formats(VkIcdSurfaceBase *surface, -+ struct wsi_device *wsi_device, -+ uint32_t* pSurfaceFormatCount, -+ VkSurfaceFormatKHR* pSurfaceFormats) -+{ -+ TRACE -+ -+ if (pSurfaceFormats == NULL) { -+ *pSurfaceFormatCount = ARRAY_SIZE(formats); -+ return VK_SUCCESS; -+ } -+ -+ *pSurfaceFormatCount = MIN2(*pSurfaceFormatCount, ARRAY_SIZE(formats)); -+ typed_memcpy(pSurfaceFormats, formats, *pSurfaceFormatCount); -+ -+ return *pSurfaceFormatCount < ARRAY_SIZE(formats) ? -+ VK_INCOMPLETE : VK_SUCCESS; -+} -+ -+static VkResult -+wsi_mir_surface_get_present_modes(VkIcdSurfaceBase *surface, -+ uint32_t* pPresentModeCount, -+ VkPresentModeKHR* pPresentModes) -+{ -+ TRACE -+ -+ if (pPresentModes == NULL) { -+ *pPresentModeCount = ARRAY_SIZE(present_modes); -+ return VK_SUCCESS; -+ } -+ -+ *pPresentModeCount = MIN2(*pPresentModeCount, ARRAY_SIZE(present_modes)); -+ typed_memcpy(pPresentModes, present_modes, *pPresentModeCount); -+ -+ return *pPresentModeCount < ARRAY_SIZE(present_modes) ? -+ VK_INCOMPLETE : VK_SUCCESS; -+} -+ -+static VkResult -+wsi_mir_swapchain_destroy(struct wsi_swapchain *swapchain, -+ const VkAllocationCallbacks *pAllocator) -+{ -+ TRACE -+ struct wsi_mir_swapchain *chain = (struct wsi_mir_swapchain *)swapchain; -+ -+ for (uint32_t i = 0; i < chain->image_count; i++) { -+ if (chain->images[i].buffer) -+ { -+ chain->base.image_fns->free_wsi_image(chain->base.device, -+ pAllocator, true, -+ chain->images[i].image, -+ chain->images[i].memory); -+ mir_buffer_release(chain->images[i].buffer); -+ } -+ } -+ -+ pthread_mutex_destroy(&chain->lock); -+ pthread_cond_destroy(&chain->cv); -+ -+ vk_free(pAllocator, chain); -+ -+ return VK_SUCCESS; -+} -+ -+static VkResult -+wsi_mir_swapchain_get_images(struct wsi_swapchain *swapchain, -+ uint32_t *pCount, VkImage *pSwapchainImages) -+{ -+ TRACE -+ -+ struct wsi_mir_swapchain *chain = (struct wsi_mir_swapchain *)swapchain; -+ uint32_t ret_count; -+ VkResult result; -+ -+ if (pSwapchainImages == NULL) { -+ *pCount = chain->image_count; -+ return VK_SUCCESS; -+ } -+ -+ result = VK_SUCCESS; -+ ret_count = chain->image_count; -+ if (chain->image_count > *pCount) { -+ ret_count = *pCount; -+ result = VK_INCOMPLETE; -+ } -+ -+ for (uint32_t i = 0; i < ret_count; i++) -+ pSwapchainImages[i] = chain->images[i].image; -+ -+ return result; -+} -+ -+static VkResult -+wsi_mir_swapchain_acquire_next_image(struct wsi_swapchain *swap_chain, -+ uint64_t timeout, -+ VkSemaphore semaphore, -+ uint32_t *image_index) -+{ -+// TRACE -+ assert(semaphore == VK_NULL_HANDLE); -+ assert(timeout == UINT64_MAX); -+/* -+ printf("\tsemaphore is %snull\n", -+ (semaphore != VK_NULL_HANDLE) ? "non-" : ""); -+ -+ switch (timeout) -+ { -+ case 0: -+ printf("\tWill not block\n"); -+ break; -+ case UINT64_MAX: -+ printf("\tWill block indefinitely\n"); -+ break; -+ default: -+ printf("\tWill block %lu nsecs\n", timeout); -+ break; -+ } -+*/ -+ -+ struct wsi_mir_swapchain *chain = (struct wsi_mir_swapchain *)swap_chain; -+ uint32_t wrap = (chain->next_image_to_use-1)%(chain->image_count); -+ bool found = false; -+ -+ do { -+ uint32_t const next_image = chain->next_image_to_use; -+ if (!chain->images[next_image].busy) { -+ found = true; -+ chain->images[next_image].busy = true; -+ *image_index = next_image; -+ } -+ else if (next_image == wrap) { -+ pthread_mutex_lock(&chain->lock); -+ pthread_cond_wait(&chain->cv, &chain->lock); -+ pthread_mutex_unlock(&chain->lock); -+ } -+ -+ chain->next_image_to_use = (next_image+1)%(chain->image_count); -+ } -+ while(!found); -+ -+ return VK_SUCCESS; -+} -+ -+static void -+buffer_submit_callback(MirBuffer* buffer, void* context) -+{ -+// TRACE -+ struct wsi_mir_swapchain* chain = (struct wsi_mir_swapchain*) context; -+ -+ for (uint32_t i = 0; i < chain->image_count; i++) -+ if (chain->images[i].buffer == buffer) { -+ pthread_mutex_lock(&chain->lock); -+ chain->images[i].busy = false; -+ pthread_mutex_unlock(&chain->lock); -+ pthread_cond_broadcast(&chain->cv); -+ return; -+ } -+} -+ -+static VkResult -+wsi_mir_swapchain_queue_present(struct wsi_swapchain *swap_chain, -+ uint32_t image_index) -+{ -+// TRACE -+ struct wsi_mir_swapchain *chain = (struct wsi_mir_swapchain *)swap_chain; -+ assert(chain->present_mode == VK_PRESENT_MODE_FIFO_KHR); -+ -+ mir_presentation_chain_submit_buffer(chain->presentation_chain, -+ chain->images[image_index].buffer, -+ buffer_submit_callback, -+ chain); -+ -+/* printf("\tBuffer %d queued to server\n", image_index);*/ -+ return VK_SUCCESS; -+} -+ -+ -+static void -+buffer_create_callback(MirBuffer* buffer, void* context) -+{ -+ struct wsi_mir_image* image = (struct wsi_mir_image*)context; -+ -+ printf("alloc'ed buffer\n"); -+ pthread_mutex_lock(&image->lock); -+ image->buffer = buffer; -+ pthread_cond_broadcast(&image->cv); -+ pthread_mutex_unlock(&image->lock); -+} -+ -+static VkResult -+wsi_mir_image_init(struct wsi_mir_swapchain *chain, -+ struct wsi_mir_image *mir_image, -+ const VkSwapchainCreateInfoKHR *pCreateInfo, -+ const VkAllocationCallbacks* pAllocator) -+{ -+ TRACE -+ -+ VkResult result; -+ -+ pthread_cond_init(&mir_image->cv, NULL); -+ pthread_mutex_init(&mir_image->lock, NULL); -+ -+ printf("to alloc buffer\n"); -+ chain->gbm_buffer_ext->allocate_buffer_gbm( -+ chain->connection, -+ chain->extent.width, -+ chain->extent.height, -+ GBM_FORMAT_ARGB8888, // TODO: map the actual vk format -+ GBM_BO_USE_SCANOUT | GBM_BO_USE_RENDERING, -+ buffer_create_callback, -+ mir_image); -+ -+ pthread_mutex_lock(&mir_image->lock); -+ while(!mir_image->buffer) -+ pthread_cond_wait(&mir_image->cv, &mir_image->lock); -+ pthread_mutex_unlock(&mir_image->lock); -+ -+ MirBufferPackage* mbp = mir_buffer_get_buffer_package(mir_image->buffer); -+/* DUMP_MirBufferPackage(mbp); -+*/ -+ uint32_t size; -+ uint32_t row_pitch; -+ uint32_t offset; -+ VkDevice vk_device = chain->base.device; -+ -+ printf("to wrap buffer\n"); -+ result = chain->base.image_fns->create_wsi_image(vk_device, -+ pCreateInfo, -+ pAllocator, -+ false, -+ false, -+ true, -+ &mir_image->image, -+ &mir_image->memory, -+ &size, -+ &offset, -+ &row_pitch, -+ &mbp->fd[0]); -+ -+ printf("wrapped buffer\n"); -+ return result; -+} -+ -+static VkResult -+wsi_mir_surface_create_swapchain(VkIcdSurfaceBase *surface, -+ VkDevice device, -+ struct wsi_device *wsi_device, -+ const VkSwapchainCreateInfoKHR* pCreateInfo, -+ const VkAllocationCallbacks* pAllocator, -+ const struct wsi_image_fns *image_fns, -+ struct wsi_swapchain **swapchain) -+{ -+ TRACE -+ -+ VkIcdSurfaceMir *mir_surface = (VkIcdSurfaceMir *)surface; -+ struct wsi_mir_swapchain *chain; -+ VkResult result; -+ -+ assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_SWAPCHAIN_CREATE_INFO_KHR); -+ -+ int num_images = pCreateInfo->minImageCount; -+ -+ size_t size = sizeof(*chain) + num_images * sizeof(chain->images[0]); -+ chain = vk_alloc(pAllocator, size, 8, -+ VK_SYSTEM_ALLOCATION_SCOPE_OBJECT); -+ if (chain == NULL) -+ return VK_ERROR_OUT_OF_HOST_MEMORY; -+ -+ chain->base.device = device; -+ chain->base.destroy = wsi_mir_swapchain_destroy; -+ chain->base.get_images = wsi_mir_swapchain_get_images; -+ chain->base.acquire_next_image = wsi_mir_swapchain_acquire_next_image; -+ chain->base.queue_present = wsi_mir_swapchain_queue_present; -+ chain->base.image_fns = image_fns; -+ chain->base.present_mode = pCreateInfo->presentMode; -+ chain->connection = mir_surface->connection; -+ chain->surface = mir_surface->mirSurface; -+ chain->extent = pCreateInfo->imageExtent; -+ chain->vk_format = pCreateInfo->imageFormat; -+ -+ chain->fifo_ready = true; -+ -+ chain->image_count = num_images; -+ chain->next_image_to_use = 0; -+ -+ /* Mark a bunch of stuff as NULL. This way we can just call -+ * destroy_swapchain for cleanup. -+ */ -+ for (uint32_t i = 0; i < chain->image_count; i++) -+ chain->images[i].buffer = NULL; -+ -+ int ret = pthread_mutex_init(&chain->lock, NULL); -+ if (ret != 0) { -+ if (ret == ENOMEM) { -+ result = VK_ERROR_OUT_OF_HOST_MEMORY; -+ } else { -+ /* FINISHME: Choose a better error. */ -+ result = VK_ERROR_OUT_OF_HOST_MEMORY; -+ } -+ -+ goto fail; -+ } -+ -+ ret = pthread_cond_init(&chain->cv, NULL); -+ if (ret != 0) { -+ if (ret == ENOMEM) { -+ result = VK_ERROR_OUT_OF_HOST_MEMORY; -+ } else { -+ /* FINISHME: Choose a better error. */ -+ result = VK_ERROR_OUT_OF_HOST_MEMORY; -+ } -+ -+ goto fail_cv; -+ } -+ -+ if (!mir_render_surface_is_valid(chain->surface)) -+ { -+ result = VK_ERROR_INITIALIZATION_FAILED; -+ goto fail_lock; -+ } -+ -+ chain->presentation_chain = mir_render_surface_get_presentation_chain(chain->surface); -+ if (!mir_presentation_chain_is_valid(chain->presentation_chain)) -+ { -+ result = VK_ERROR_INITIALIZATION_FAILED; -+ goto fail_lock; -+ } -+ -+ chain->gbm_buffer_ext = mir_extension_gbm_buffer_v1(chain->connection); -+ assert(chain->gbm_buffer_ext); -+ assert(chain->gbm_buffer_ext->allocate_buffer_gbm); -+ -+ for (uint32_t i = 0; i < chain->image_count; i++) { -+ result = wsi_mir_image_init(chain, &chain->images[i], -+ pCreateInfo, pAllocator); -+ if (result != VK_SUCCESS) -+ goto fail_lock; -+ chain->images[i].busy = false; -+ } -+ -+ *swapchain = &chain->base; -+ -+ return VK_SUCCESS; -+ -+fail_lock: -+ pthread_mutex_destroy(&chain->lock); -+fail_cv: -+ pthread_cond_destroy(&chain->cv); -+fail: -+ wsi_mir_swapchain_destroy(&chain->base, pAllocator); -+ -+ return result; -+} -+ -+VkBool32 -+wsi_get_mir_presentation_support(struct wsi_device *wsi_device, -+ MirConnection *connection) -+{ -+ TRACE -+ -+ return mir_connection_is_valid(connection); -+} -+ -+VkResult