It works with the Talos Principle and performs well, I'm seeing some artefacts in the grass which can be seen in https://imgur.com/a/3litB I'm not sure if that's caused by one of the LLVM bugs that have been mentioned
On Wed, 23 Nov 2016 at 11:13 Mike Lothian <m...@fireburn.co.uk> wrote: > I think it would be good to keep the DRI_PRIME switch to allow for > switching between anvil and radv, handy for testing / comparing / > benchmarking both > > It seems that Vulkan automatically uses the first card listed in > vulkaninfo (in my case it's the amdgpu card) with no way to select which is > used, hence why I've only been seeing garbage since the radv driver was > added into mesa > > If DRI_PRIME=0 is passed will this now automatically use anvil? > > Thanks > > Mike > > On Wed, 23 Nov 2016 at 10:47 Nicolai Hähnle <nhaeh...@gmail.com> wrote: > > On 23.11.2016 06:28, Dave Airlie wrote: > > From: Dave Airlie <airl...@redhat.com> > > > > This is kind of a gross hacks, but vulkan doesn't specify anything > > but it would be nice to let people with prime systems at least > > see some stuff rendering for now. > > > > This creates a linear shadow image in GART that gets blitted to at the > > image transition. > > > > Now ideally: > > this would use SDMA - but we want to use SDMA for transfer queues > > maybe we don't expose a transfer queue on prime cards who knows. > > Why is there a problem here? What stops you from just having multiple > SDMA queues? > > > > we wouldn't have to add two pointers to every image, but my other > > attempts at this were ugly. > > > > Is the image transition the proper place to hack this in? not > > really sure anywhere else is appropriate. > > So I'm not too deep into Vulkan, but isn't conceptually the blit to > shadow image a part of the present operation, not of the image > transition? I'd somehow expect the present part to have its own queue > (which could be SDMA) on which the blit happens. > > Cheers, > Nicolai > > > > > It also relies on DRI_PRIME=1 being set, I should be able > > to work this out somehow automatically I think, probably getting > > a DRI3 fd from the X server and doing drmGetDevice on it, and > > comparing where we end up. > > > > Signed-off-by: Dave Airlie <airl...@redhat.com> > > --- > > src/amd/vulkan/radv_cmd_buffer.c | 18 +++++++ > > src/amd/vulkan/radv_device.c | 3 ++ > > src/amd/vulkan/radv_meta.h | 2 + > > src/amd/vulkan/radv_meta_copy.c | 31 +++++++++++ > > src/amd/vulkan/radv_private.h | 4 ++ > > src/amd/vulkan/radv_wsi.c | 111 > ++++++++++++++++++++++++++++++--------- > > 6 files changed, 144 insertions(+), 25 deletions(-) > > > > diff --git a/src/amd/vulkan/radv_cmd_buffer.c > b/src/amd/vulkan/radv_cmd_buffer.c > > index a2d55833..4432afc 100644 > > --- a/src/amd/vulkan/radv_cmd_buffer.c > > +++ b/src/amd/vulkan/radv_cmd_buffer.c > > @@ -2296,6 +2296,20 @@ static void > radv_handle_dcc_image_transition(struct radv_cmd_buffer *cmd_buffer, > > } > > } > > > > +static void radv_handle_prime_image_transition(struct radv_cmd_buffer > *cmd_buffer, > > + struct radv_image *image, > > + VkImageLayout src_layout, > > + VkImageLayout dst_layout, > > + VkImageSubresourceRange > range, > > + VkImageAspectFlags > pending_clears) > > +{ > > + cmd_buffer->state.flush_bits |= RADV_CMD_FLUSH_AND_INV_FRAMEBUFFER; > > + si_emit_cache_flush(cmd_buffer); > > + radv_blit_to_prime_linear(cmd_buffer, image); > > + cmd_buffer->state.flush_bits |= RADV_CMD_FLUSH_AND_INV_FRAMEBUFFER; > > + si_emit_cache_flush(cmd_buffer); > > +} > > + > > static void radv_handle_image_transition(struct radv_cmd_buffer > *cmd_buffer, > > struct radv_image *image, > > VkImageLayout src_layout, > > @@ -2314,6 +2328,10 @@ static void radv_handle_image_transition(struct > radv_cmd_buffer *cmd_buffer, > > if (image->surface.dcc_size) > > radv_handle_dcc_image_transition(cmd_buffer, image, > src_layout, > > dst_layout, range, > pending_clears); > > + > > + if (image->prime_image && dst_layout == > VK_IMAGE_LAYOUT_PRESENT_SRC_KHR) > > + radv_handle_prime_image_transition(cmd_buffer, image, > src_layout, > > + dst_layout, range, > pending_clears); > > } > > > > void radv_CmdPipelineBarrier( > > diff --git a/src/amd/vulkan/radv_device.c b/src/amd/vulkan/radv_device.c > > index c639d53..b21447f 100644 > > --- a/src/amd/vulkan/radv_device.c > > +++ b/src/amd/vulkan/radv_device.c > > @@ -105,6 +105,9 @@ radv_physical_device_init(struct > radv_physical_device *device, > > } > > drmFreeVersion(version); > > > > + if (getenv("DRI_PRIME")) > > + device->is_different_gpu = true; > > + > > device->_loader_data.loaderMagic = ICD_LOADER_MAGIC; > > device->instance = instance; > > assert(strlen(path) < ARRAY_SIZE(device->path)); > > diff --git a/src/amd/vulkan/radv_meta.h b/src/amd/vulkan/radv_meta.h > > index 97d020c..e43a0e7 100644 > > --- a/src/amd/vulkan/radv_meta.h > > +++ b/src/amd/vulkan/radv_meta.h > > @@ -186,6 +186,8 @@ void radv_meta_resolve_compute_image(struct > radv_cmd_buffer *cmd_buffer, > > uint32_t region_count, > > const VkImageResolve *regions); > > > > +void radv_blit_to_prime_linear(struct radv_cmd_buffer *cmd_buffer, > > + struct radv_image *image); > > #ifdef __cplusplus > > } > > #endif > > diff --git a/src/amd/vulkan/radv_meta_copy.c > b/src/amd/vulkan/radv_meta_copy.c > > index 4c01eb7..3fd8d0c 100644 > > --- a/src/amd/vulkan/radv_meta_copy.c > > +++ b/src/amd/vulkan/radv_meta_copy.c > > @@ -397,3 +397,34 @@ void radv_CmdCopyImage( > > > > radv_meta_restore(&saved_state, cmd_buffer); > > } > > + > > +void radv_blit_to_prime_linear(struct radv_cmd_buffer *cmd_buffer, > > + struct radv_image *image) > > +{ > > + struct radv_meta_saved_state saved_state; > > + struct radv_meta_saved_pass_state saved_pass_state; > > + > > + radv_meta_save_pass(&saved_pass_state, cmd_buffer); > > + radv_meta_save_graphics_reset_vport_scissor(&saved_state, > cmd_buffer); > > + > > + struct radv_meta_blit2d_surf b_src = > > + blit_surf_for_image_level_layer(image, > > + VK_IMAGE_ASPECT_COLOR_BIT, > > + 0, > > + 0); > > + > > + struct radv_meta_blit2d_surf b_dst = > > + blit_surf_for_image_level_layer(image->prime_image, > > + VK_IMAGE_ASPECT_COLOR_BIT, > > + 0, > > + 0); > > + struct radv_meta_blit2d_rect rect = { > > + .width = image->extent.width, > > + .height = image->extent.height, > > + }; > > + > > + radv_meta_blit2d(cmd_buffer, &b_src, NULL, &b_dst, 1, &rect); > > + > > + radv_meta_restore(&saved_state, cmd_buffer); > > + radv_meta_restore_pass(&saved_pass_state, cmd_buffer); > > +} > > diff --git a/src/amd/vulkan/radv_private.h > b/src/amd/vulkan/radv_private.h > > index e1c24cb..5027431 100644 > > --- a/src/amd/vulkan/radv_private.h > > +++ b/src/amd/vulkan/radv_private.h > > @@ -261,6 +261,7 @@ struct radv_physical_device { > > uint8_t uuid[VK_UUID_SIZE]; > > > > struct wsi_device wsi_device; > > + bool is_different_gpu; > > }; > > > > struct radv_instance { > > @@ -987,6 +988,9 @@ struct radv_image { > > > > /* Depth buffer compression and fast clear. */ > > struct r600_htile_info htile; > > + > > + struct radv_image *prime_image; > > + struct radv_device_memory *prime_memory; > > }; > > > > bool radv_layout_has_htile(const struct radv_image *image, > > diff --git a/src/amd/vulkan/radv_wsi.c b/src/amd/vulkan/radv_wsi.c > > index 1f1ab1c..31aeb77 100644 > > --- a/src/amd/vulkan/radv_wsi.c > > +++ b/src/amd/vulkan/radv_wsi.c > > @@ -135,23 +135,27 @@ VkResult > radv_GetPhysicalDeviceSurfacePresentModesKHR( > > pPresentModes); > > } > > > > +static void > > +radv_wsi_image_destroy_single(VkDevice device_h, > > + const VkAllocationCallbacks* pAllocator, > > + VkImage image_h, > > + VkDeviceMemory memory_h) > > +{ > > + radv_DestroyImage(device_h, image_h, pAllocator); > > + radv_FreeMemory(device_h, memory_h, pAllocator); > > +} > > + > > static VkResult > > -radv_wsi_image_create(VkDevice device_h, > > - const VkSwapchainCreateInfoKHR *pCreateInfo, > > - const VkAllocationCallbacks* pAllocator, > > - VkImage *image_p, > > - VkDeviceMemory *memory_p, > > - uint32_t *size, > > - uint32_t *offset, > > - uint32_t *row_pitch, int *fd_p) > > +radv_wsi_image_create_single(VkDevice device_h, > > + const VkSwapchainCreateInfoKHR *pCreateInfo, > > + const VkAllocationCallbacks* pAllocator, > > + VkImage *image_p, > > + VkDeviceMemory *memory_p, > > + bool tiled) > > { > > - struct radv_device *device = radv_device_from_handle(device_h); > > - VkResult result = VK_SUCCESS; > > - struct radeon_surf *surface; > > + VkResult result; > > VkImage image_h; > > struct radv_image *image; > > - bool bret; > > - int fd; > > > > result = radv_image_create(device_h, > > &(struct radv_image_create_info) { > > @@ -169,7 +173,7 @@ radv_wsi_image_create(VkDevice device_h, > > .arrayLayers = 1, > > .samples = 1, > > /* FIXME: Need a way to > use X tiling to allow scanout */ > > - .tiling = > VK_IMAGE_TILING_OPTIMAL, > > + .tiling = tiled ? > VK_IMAGE_TILING_OPTIMAL : VK_IMAGE_TILING_LINEAR, > > .usage = > VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, > > .flags = 0, > > }, > > @@ -180,24 +184,74 @@ radv_wsi_image_create(VkDevice device_h, > > return result; > > > > image = radv_image_from_handle(image_h); > > - > > VkDeviceMemory memory_h; > > - struct radv_device_memory *memory; > > + > > result = radv_AllocateMemory(device_h, > > &(VkMemoryAllocateInfo) { > > .sType = > VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, > > .allocationSize = > image->size, > > - .memoryTypeIndex = 0, > > + .memoryTypeIndex = > tiled ? 0 : 1, > > }, > > NULL /* XXX: pAllocator */, > > &memory_h); > > if (result != VK_SUCCESS) > > goto fail_create_image; > > > > - memory = radv_device_memory_from_handle(memory_h); > > - > > radv_BindImageMemory(VK_NULL_HANDLE, image_h, memory_h, 0); > > > > + *image_p = image_h; > > + *memory_p = memory_h; > > + return VK_SUCCESS; > > +fail_create_image: > > + radv_DestroyImage(device_h, image_h, pAllocator); > > + return result; > > +} > > + > > +static VkResult > > +radv_wsi_image_create(VkDevice device_h, > > + const VkSwapchainCreateInfoKHR *pCreateInfo, > > + const VkAllocationCallbacks* pAllocator, > > + VkImage *image_p, > > + VkDeviceMemory *memory_p, > > + uint32_t *size, > > + uint32_t *offset, > > + uint32_t *row_pitch, int *fd_p) > > +{ > > + struct radv_device *device = radv_device_from_handle(device_h); > > + VkResult result = VK_SUCCESS; > > + struct radeon_surf *surface; > > + VkImage image_h, image_prime_h; > > + VkDeviceMemory memory_h, memory_prime_h; > > + struct radv_image *image; > > + struct radv_device_memory *memory; > > + bool bret; > > + int fd; > > + bool prime = device->instance->physicalDevice.is_different_gpu; > > + > > + result = radv_wsi_image_create_single(device_h, pCreateInfo, > > + pAllocator, &image_h, > &memory_h, > > + true); > > + if (result != VK_SUCCESS) > > + return result; > > + > > + image = radv_image_from_handle(image_h); > > + if (prime) { > > + result = radv_wsi_image_create_single(device_h, > pCreateInfo, > > + pAllocator, > &image_prime_h, > > + &memory_prime_h, > false); > > + > > + if (result != VK_SUCCESS) > > + goto fail_create_image; > > + > > + image->prime_image = radv_image_from_handle(image_prime_h); > > + image->prime_memory = > radv_device_memory_from_handle(memory_prime_h); > > + > > + memory = image->prime_memory; > > + image = image->prime_image; > > + } else { > > + memory = radv_device_memory_from_handle(memory_h); > > + } > > + > > bret = device->ws->buffer_get_fd(device->ws, > > memory->bo, &fd); > > if (bret == false) > > @@ -217,24 +271,31 @@ radv_wsi_image_create(VkDevice device_h, > > *offset = image->offset; > > *row_pitch = surface->level[0].pitch_bytes; > > return VK_SUCCESS; > > - fail_alloc_memory: > > - radv_FreeMemory(device_h, memory_h, pAllocator); > > + > > +fail_alloc_memory: > > + if (prime) > > + radv_wsi_image_destroy_single(device_h, pAllocator, > image_prime_h, memory_prime_h); > > > > fail_create_image: > > - radv_DestroyImage(device_h, image_h, pAllocator); > > + radv_wsi_image_destroy_single(device_h, pAllocator, image_h, > memory_h); > > > > return result; > > } > > > > static void > > -radv_wsi_image_free(VkDevice device, > > +radv_wsi_image_free(VkDevice device_h, > > const VkAllocationCallbacks* pAllocator, > > VkImage image_h, > > VkDeviceMemory memory_h) > > { > > - radv_DestroyImage(device, image_h, pAllocator); > > + RADV_FROM_HANDLE(radv_image, image, image_h); > > + > > + if (image->prime_image) > > + radv_wsi_image_destroy_single(device_h, pAllocator, > > + > radv_image_to_handle(image->prime_image), > > + > radv_device_memory_to_handle(image->prime_memory)); > > > > - radv_FreeMemory(device, memory_h, pAllocator); > > + radv_wsi_image_destroy_single(device_h, pAllocator, image_h, > memory_h); > > } > > > > static const struct wsi_image_fns radv_wsi_image_fns = { > > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev > >
_______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev