<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">2016-11-23 6:28 GMT+01:00 Dave Airlie <span dir="ltr"><<a href="mailto:airlied@gmail.com" target="_blank">airlied@gmail.com</a>></span>:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">From: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
<br>
This is kind of a gross hacks, but vulkan doesn't specify anything<br>
but it would be nice to let people with prime systems at least<br>
see some stuff rendering for now.<br>
<br>
This creates a linear shadow image in GART that gets blitted to at the<br>
image transition.<br>
<br>
Now ideally:<br>
this would use SDMA - but we want to use SDMA for transfer queues<br>
maybe we don't expose a transfer queue on prime cards who knows.<br></blockquote><div><br></div><div>I might not be that much familiar with Vulkan, but I believe you can specify the transfer queue as a present queue and then the Vulkan applications would be required to perform the present operation on this queue. Wouldn't that be enough for the prime to work?</div><div><br></div><div>Regards,</div><div>Gustaw</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
we wouldn't have to add two pointers to every image, but my other<br>
attempts at this were ugly.<br>
<br>
Is the image transition the proper place to hack this in? not<br>
really sure anywhere else is appropriate.<br>
<br>
It also relies on DRI_PRIME=1 being set, I should be able<br>
to work this out somehow automatically I think, probably getting<br>
a DRI3 fd from the X server and doing drmGetDevice on it, and<br>
comparing where we end up.<br>
<br>
Signed-off-by: Dave Airlie <<a href="mailto:airlied@redhat.com">airlied@redhat.com</a>><br>
---<br>
 src/amd/vulkan/radv_cmd_<wbr>buffer.c |  18 +++++++<br>
 src/amd/vulkan/radv_device.c     |   3 ++<br>
 src/amd/vulkan/radv_meta.h       |   2 +<br>
 src/amd/vulkan/radv_meta_copy.<wbr>c  |  31 +++++++++++<br>
 src/amd/vulkan/radv_private.h    |   4 ++<br>
 src/amd/vulkan/radv_wsi.c        | 111 ++++++++++++++++++++++++++++++<wbr>---------<br>
 6 files changed, 144 insertions(+), 25 deletions(-)<br>
<br>
diff --git a/src/amd/vulkan/radv_cmd_<wbr>buffer.c b/src/amd/vulkan/radv_cmd_<wbr>buffer.c<br>
index a2d55833..4432afc 100644<br>
--- a/src/amd/vulkan/radv_cmd_<wbr>buffer.c<br>
+++ b/src/amd/vulkan/radv_cmd_<wbr>buffer.c<br>
@@ -2296,6 +2296,20 @@ static void radv_handle_dcc_image_<wbr>transition(struct radv_cmd_buffer *cmd_buffer,<br>
        }<br>
 }<br>
<br>
+static void radv_handle_prime_image_<wbr>transition(struct radv_cmd_buffer *cmd_buffer,<br>
+                                              struct radv_image *image,<br>
+                                              VkImageLayout src_layout,<br>
+                                              VkImageLayout dst_layout,<br>
+                                              VkImageSubresourceRange range,<br>
+                                              VkImageAspectFlags pending_clears)<br>
+{<br>
+       cmd_buffer->state.flush_bits |= RADV_CMD_FLUSH_AND_INV_<wbr>FRAMEBUFFER;<br>
+       si_emit_cache_flush(cmd_<wbr>buffer);<br>
+       radv_blit_to_prime_linear(cmd_<wbr>buffer, image);<br>
+       cmd_buffer->state.flush_bits |= RADV_CMD_FLUSH_AND_INV_<wbr>FRAMEBUFFER;<br>
+       si_emit_cache_flush(cmd_<wbr>buffer);<br>
+}<br>
+<br>
 static void radv_handle_image_transition(<wbr>struct radv_cmd_buffer *cmd_buffer,<br>
                                         struct radv_image *image,<br>
                                         VkImageLayout src_layout,<br>
@@ -2314,6 +2328,10 @@ static void radv_handle_image_transition(<wbr>struct radv_cmd_buffer *cmd_buffer,<br>
        if (image->surface.dcc_size)<br>
                radv_handle_dcc_image_<wbr>transition(cmd_buffer, image, src_layout,<br>
                                                 dst_layout, range, pending_clears);<br>
+<br>
+       if (image->prime_image && dst_layout == VK_IMAGE_LAYOUT_PRESENT_SRC_<wbr>KHR)<br>
+               radv_handle_prime_image_<wbr>transition(cmd_buffer, image, src_layout,<br>
+                                                  dst_layout, range, pending_clears);<br>
 }<br>
<br>
 void radv_CmdPipelineBarrier(<br>
diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c<br>
index c639d53..b21447f 100644<br>
--- a/src/amd/vulkan/radv_device.c<br>
+++ b/src/amd/vulkan/radv_device.c<br>
@@ -105,6 +105,9 @@ radv_physical_device_init(<wbr>struct radv_physical_device *device,<br>
        }<br>
        drmFreeVersion(version);<br>
<br>
+       if (getenv("DRI_PRIME"))<br>
+               device->is_different_gpu = true;<br>
+<br>
        device->_loader_data.<wbr>loaderMagic = ICD_LOADER_MAGIC;<br>
        device->instance = instance;<br>
        assert(strlen(path) < ARRAY_SIZE(device->path));<br>
diff --git a/src/amd/vulkan/radv_meta.h b/src/amd/vulkan/radv_meta.h<br>
index 97d020c..e43a0e7 100644<br>
--- a/src/amd/vulkan/radv_meta.h<br>
+++ b/src/amd/vulkan/radv_meta.h<br>
@@ -186,6 +186,8 @@ void radv_meta_resolve_compute_<wbr>image(struct radv_cmd_buffer *cmd_buffer,<br>
                                     uint32_t region_count,<br>
                                     const VkImageResolve *regions);<br>
<br>
+void radv_blit_to_prime_linear(<wbr>struct radv_cmd_buffer *cmd_buffer,<br>
+                              struct radv_image *image);<br>
 #ifdef __cplusplus<br>
 }<br>
 #endif<br>
diff --git a/src/amd/vulkan/radv_meta_<wbr>copy.c b/src/amd/vulkan/radv_meta_<wbr>copy.c<br>
index 4c01eb7..3fd8d0c 100644<br>
--- a/src/amd/vulkan/radv_meta_<wbr>copy.c<br>
+++ b/src/amd/vulkan/radv_meta_<wbr>copy.c<br>
@@ -397,3 +397,34 @@ void radv_CmdCopyImage(<br>
<br>
        radv_meta_restore(&saved_<wbr>state, cmd_buffer);<br>
 }<br>
+<br>
+void radv_blit_to_prime_linear(<wbr>struct radv_cmd_buffer *cmd_buffer,<br>
+                              struct radv_image *image)<br>
+{<br>
+       struct radv_meta_saved_state saved_state;<br>
+       struct radv_meta_saved_pass_state saved_pass_state;<br>
+<br>
+       radv_meta_save_pass(&saved_<wbr>pass_state, cmd_buffer);<br>
+       radv_meta_save_graphics_reset_<wbr>vport_scissor(&saved_state, cmd_buffer);<br>
+<br>
+       struct radv_meta_blit2d_surf b_src =<br>
+               blit_surf_for_image_level_<wbr>layer(image,<br>
+                                               VK_IMAGE_ASPECT_COLOR_BIT,<br>
+                                               0,<br>
+                                               0);<br>
+<br>
+       struct radv_meta_blit2d_surf b_dst =<br>
+               blit_surf_for_image_level_<wbr>layer(image->prime_image,<br>
+                                               VK_IMAGE_ASPECT_COLOR_BIT,<br>
+                                               0,<br>
+                                               0);<br>
+       struct radv_meta_blit2d_rect rect = {<br>
+               .width = image->extent.width,<br>
+               .height = image->extent.height,<br>
+       };<br>
+<br>
+       radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect);<br>
+<br>
+       radv_meta_restore(&saved_<wbr>state, cmd_buffer);<br>
+       radv_meta_restore_pass(&saved_<wbr>pass_state, cmd_buffer);<br>
+}<br>
diff --git a/src/amd/vulkan/radv_private.<wbr>h b/src/amd/vulkan/radv_private.<wbr>h<br>
index e1c24cb..5027431 100644<br>
--- a/src/amd/vulkan/radv_private.<wbr>h<br>
+++ b/src/amd/vulkan/radv_private.<wbr>h<br>
@@ -261,6 +261,7 @@ struct radv_physical_device {<br>
        uint8_t                                     uuid[VK_UUID_SIZE];<br>
<br>
        struct wsi_device                       wsi_device;<br>
+       bool is_different_gpu;<br>
 };<br>
<br>
 struct radv_instance {<br>
@@ -987,6 +988,9 @@ struct radv_image {<br>
<br>
        /* Depth buffer compression and fast clear. */<br>
        struct r600_htile_info htile;<br>
+<br>
+       struct radv_image *prime_image;<br>
+       struct radv_device_memory *prime_memory;<br>
 };<br>
<br>
 bool radv_layout_has_htile(const struct radv_image *image,<br>
diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c<br>
index 1f1ab1c..31aeb77 100644<br>
--- a/src/amd/vulkan/radv_wsi.c<br>
+++ b/src/amd/vulkan/radv_wsi.c<br>
@@ -135,23 +135,27 @@ VkResult radv_<wbr>GetPhysicalDeviceSurfacePresen<wbr>tModesKHR(<br>
                                        pPresentModes);<br>
 }<br>
<br>
+static void<br>
+radv_wsi_image_destroy_<wbr>single(VkDevice device_h,<br>
+                             const VkAllocationCallbacks* pAllocator,<br>
+                             VkImage image_h,<br>
+                             VkDeviceMemory memory_h)<br>
+{<br>
+       radv_DestroyImage(device_h, image_h, pAllocator);<br>
+       radv_FreeMemory(device_h, memory_h, pAllocator);<br>
+}<br>
+<br>
 static VkResult<br>
-radv_wsi_image_create(<wbr>VkDevice device_h,<br>
-                     const VkSwapchainCreateInfoKHR *pCreateInfo,<br>
-                     const VkAllocationCallbacks* pAllocator,<br>
-                     VkImage *image_p,<br>
-                     VkDeviceMemory *memory_p,<br>
-                     uint32_t *size,<br>
-                     uint32_t *offset,<br>
-                     uint32_t *row_pitch, int *fd_p)<br>
+radv_wsi_image_create_single(<wbr>VkDevice device_h,<br>
+                            const VkSwapchainCreateInfoKHR *pCreateInfo,<br>
+                            const VkAllocationCallbacks* pAllocator,<br>
+                            VkImage *image_p,<br>
+                            VkDeviceMemory *memory_p,<br>
+                            bool tiled)<br>
 {<br>
-       struct radv_device *device = radv_device_from_handle(<wbr>device_h);<br>
-       VkResult result = VK_SUCCESS;<br>
-       struct radeon_surf *surface;<br>
+       VkResult result;<br>
        VkImage image_h;<br>
        struct radv_image *image;<br>
-       bool bret;<br>
-       int fd;<br>
<br>
        result = radv_image_create(device_h,<br>
                                   &(struct radv_image_create_info) {<br>
@@ -169,7 +173,7 @@ radv_wsi_image_create(VkDevice device_h,<br>
                                                   .arrayLayers = 1,<br>
                                                   .samples = 1,<br>
                                                   /* FIXME: Need a way to use X tiling to allow scanout */<br>
-                                                  .tiling = VK_IMAGE_TILING_OPTIMAL,<br>
+                                                  .tiling = tiled ? VK_IMAGE_TILING_OPTIMAL : VK_IMAGE_TILING_LINEAR,<br>
                                                   .usage = VK_IMAGE_USAGE_COLOR_<wbr>ATTACHMENT_BIT,<br>
                                                   .flags = 0,<br>
                                           },<br>
@@ -180,24 +184,74 @@ radv_wsi_image_create(VkDevice device_h,<br>
                return result;<br>
<br>
        image = radv_image_from_handle(image_<wbr>h);<br>
-<br>
        VkDeviceMemory memory_h;<br>
-       struct radv_device_memory *memory;<br>
+<br>
        result = radv_AllocateMemory(device_h,<br>
                                     &(VkMemoryAllocateInfo) {<br>
                                             .sType = VK_STRUCTURE_TYPE_MEMORY_<wbr>ALLOCATE_INFO,<br>
                                                     .allocationSize = image->size,<br>
-                                                    .memoryTypeIndex = 0,<br>
+                                                    .memoryTypeIndex = tiled ? 0 : 1,<br>
                                                     },<br>
                                     NULL /* XXX: pAllocator */,<br>
                                     &memory_h);<br>
        if (result != VK_SUCCESS)<br>
                goto fail_create_image;<br>
<br>
-       memory = radv_device_memory_from_<wbr>handle(memory_h);<br>
-<br>
        radv_BindImageMemory(VK_NULL_<wbr>HANDLE, image_h, memory_h, 0);<br>
<br>
+       *image_p = image_h;<br>
+       *memory_p = memory_h;<br>
+       return VK_SUCCESS;<br>
+fail_create_image:<br>
+       radv_DestroyImage(device_h, image_h, pAllocator);<br>
+       return result;<br>
+}<br>
+<br>
+static VkResult<br>
+radv_wsi_image_create(<wbr>VkDevice device_h,<br>
+                     const VkSwapchainCreateInfoKHR *pCreateInfo,<br>
+                     const VkAllocationCallbacks* pAllocator,<br>
+                     VkImage *image_p,<br>
+                     VkDeviceMemory *memory_p,<br>
+                     uint32_t *size,<br>
+                     uint32_t *offset,<br>
+                     uint32_t *row_pitch, int *fd_p)<br>
+{<br>
+       struct radv_device *device = radv_device_from_handle(<wbr>device_h);<br>
+       VkResult result = VK_SUCCESS;<br>
+       struct radeon_surf *surface;<br>
+       VkImage image_h, image_prime_h;<br>
+       VkDeviceMemory memory_h, memory_prime_h;<br>
+       struct radv_image *image;<br>
+       struct radv_device_memory *memory;<br>
+       bool bret;<br>
+       int fd;<br>
+       bool prime = device->instance-><wbr>physicalDevice.is_different_<wbr>gpu;<br>
+<br>
+       result = radv_wsi_image_create_single(<wbr>device_h, pCreateInfo,<br>
+                                             pAllocator, &image_h, &memory_h,<br>
+                                             true);<br>
+       if (result != VK_SUCCESS)<br>
+               return result;<br>
+<br>
+       image = radv_image_from_handle(image_<wbr>h);<br>
+       if (prime) {<br>
+               result = radv_wsi_image_create_single(<wbr>device_h, pCreateInfo,<br>
+                                                     pAllocator, &image_prime_h,<br>
+                                                     &memory_prime_h, false);<br>
+<br>
+               if (result != VK_SUCCESS)<br>
+                       goto fail_create_image;<br>
+<br>
+               image->prime_image = radv_image_from_handle(image_<wbr>prime_h);<br>
+               image->prime_memory = radv_device_memory_from_<wbr>handle(memory_prime_h);<br>
+<br>
+               memory = image->prime_memory;<br>
+               image = image->prime_image;<br>
+       } else {<br>
+               memory = radv_device_memory_from_<wbr>handle(memory_h);<br>
+       }<br>
+<br>
        bret = device->ws->buffer_get_fd(<wbr>device->ws,<br>
                                         memory->bo, &fd);<br>
        if (bret == false)<br>
@@ -217,24 +271,31 @@ radv_wsi_image_create(VkDevice device_h,<br>
        *offset = image->offset;<br>
        *row_pitch = surface->level[0].pitch_bytes;<br>
        return VK_SUCCESS;<br>
- fail_alloc_memory:<br>
-       radv_FreeMemory(device_h, memory_h, pAllocator);<br>
+<br>
+fail_alloc_memory:<br>
+       if (prime)<br>
+               radv_wsi_image_destroy_single(<wbr>device_h, pAllocator, image_prime_h, memory_prime_h);<br>
<br>
 fail_create_image:<br>
-       radv_DestroyImage(device_h, image_h, pAllocator);<br>
+       radv_wsi_image_destroy_single(<wbr>device_h, pAllocator, image_h, memory_h);<br>
<br>
        return result;<br>
 }<br>
<br>
 static void<br>
-radv_wsi_image_free(VkDevice device,<br>
+radv_wsi_image_free(VkDevice device_h,<br>
                    const VkAllocationCallbacks* pAllocator,<br>
                    VkImage image_h,<br>
                    VkDeviceMemory memory_h)<br>
 {<br>
-       radv_DestroyImage(device, image_h, pAllocator);<br>
+       RADV_FROM_HANDLE(radv_image, image, image_h);<br>
+<br>
+       if (image->prime_image)<br>
+               radv_wsi_image_destroy_single(<wbr>device_h, pAllocator,<br>
+                                             radv_image_to_handle(image-><wbr>prime_image),<br>
+                                             radv_device_memory_to_handle(<wbr>image->prime_memory));<br>
<br>
-       radv_FreeMemory(device, memory_h, pAllocator);<br>
+       radv_wsi_image_destroy_single(<wbr>device_h, pAllocator, image_h, memory_h);<br>
 }<br>
<br>
 static const struct wsi_image_fns radv_wsi_image_fns = {<br>
<span class="HOEnZb"><font color="#888888">--<br>
2.9.3<br>
<br>
______________________________<wbr>_________________<br>
mesa-dev mailing list<br>
<a href="mailto:mesa-dev@lists.freedesktop.org">mesa-dev@lists.freedesktop.org</a><br>
<a href="https://lists.freedesktop.org/mailman/listinfo/mesa-dev" rel="noreferrer" target="_blank">https://lists.freedesktop.org/<wbr>mailman/listinfo/mesa-dev</a><br>
</font></span></blockquote></div><br></div></div>