diff --git a/docs/features.txt b/docs/features.txt index ec70bd47bd8..b8eb5202a15 100644 --- a/docs/features.txt +++ b/docs/features.txt @@ -601,6 +601,7 @@ Khronos extensions that are not part of any Vulkan version: VK_EXT_global_priority_query DONE (anv, hasvk, radv, tu) VK_EXT_graphics_pipeline_library DONE (anv, lvp, nvk, panvk, radv, tu, vn) VK_EXT_headless_surface DONE (anv, dzn, hasvk, lvp, nvk, panvk, pvr, radv, tu, v3dv, vn) + VK_EXT_host_image_copy DONE (nvk/Turing+) VK_EXT_image_2d_view_of_3d DONE (anv, hasvk, lvp, nvk, radv, tu, vn) VK_EXT_image_compression_control DONE (radv) VK_EXT_image_drm_format_modifier DONE (anv, hasvk, nvk, radv/gfx9+, tu, v3dv, vn) diff --git a/docs/relnotes/new_features.txt b/docs/relnotes/new_features.txt index f93d947319f..26f2d9bc63c 100644 --- a/docs/relnotes/new_features.txt +++ b/docs/relnotes/new_features.txt @@ -18,3 +18,4 @@ GL_OVR_multiview and GL_OVR_multiview2 on zink VK_KHR_shader_float_controls2 on radv VK_KHR_shader_float_controls2 on nvk VK_EXT_device_generated_commands on nvk +VK_EXT_host_image_copy on nvk/Turing+ diff --git a/src/nouveau/vulkan/nvk_image.c b/src/nouveau/vulkan/nvk_image.c index 9f2f9b7a3a0..e3ff600a9fc 100644 --- a/src/nouveau/vulkan/nvk_image.c +++ b/src/nouveau/vulkan/nvk_image.c @@ -88,6 +88,8 @@ nvk_get_image_plane_format_features(struct nvk_physical_device *pdev, if (features != 0) { features |= VK_FORMAT_FEATURE_2_TRANSFER_SRC_BIT; features |= VK_FORMAT_FEATURE_2_TRANSFER_DST_BIT; + if (!vk_format_is_depth_or_stencil(vk_format)) + features |= VK_FORMAT_FEATURE_2_HOST_IMAGE_TRANSFER_BIT_EXT; } return features; @@ -557,6 +559,10 @@ nvk_GetPhysicalDeviceImageFormatProperties2( (pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT))) return VK_ERROR_FORMAT_NOT_SUPPORTED; + if ((pImageFormatInfo->flags & VK_IMAGE_CREATE_SPARSE_BINDING_BIT) && + (pImageFormatInfo->usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT)) + return VK_ERROR_FORMAT_NOT_SUPPORTED; + pImageFormatProperties->imageFormatProperties = (VkImageFormatProperties) { .maxExtent = maxExtent, .maxMipLevels = maxMipLevels, @@ -587,6 +593,12 @@ nvk_GetPhysicalDeviceImageFormatProperties2( ycbcr_props->combinedImageSamplerDescriptorCount = plane_count; break; } + case VK_STRUCTURE_TYPE_HOST_IMAGE_COPY_DEVICE_PERFORMANCE_QUERY_EXT: { + VkHostImageCopyDevicePerformanceQueryEXT *host_props = (void *) s; + host_props->optimalDeviceAccess = true; + host_props->identicalMemoryLayout = true; + break; + } default: vk_debug_ignored_stype(s->sType); break; @@ -1042,6 +1054,18 @@ nvk_get_image_memory_requirements(struct nvk_device *dev, struct nvk_physical_device *pdev = nvk_device_physical(dev); uint32_t memory_types = (1 << pdev->mem_type_count) - 1; + /* Remove non host visible heaps from the types for host image copy in case + * of potential issues. This should be removed when we get ReBAR. + */ + if (image->vk.usage & VK_IMAGE_USAGE_HOST_TRANSFER_BIT_EXT) { + struct nvk_physical_device *pdev = nvk_device_physical(dev); + for (uint32_t i = 0; i < pdev->mem_type_count; i++) { + if (!(pdev->mem_types[i].propertyFlags & + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT)) + memory_types &= ~BITFIELD_BIT(i); + } + } + // TODO hope for the best? uint64_t size_B = 0; @@ -1254,6 +1278,14 @@ nvk_get_image_subresource_layout(struct nvk_device *dev, offset_B += nil_image_level_layer_offset_B(&plane->nil, isr->mipLevel, isr->arrayLayer); + VkSubresourceHostMemcpySizeEXT *host_memcpy_size = + vk_find_struct(pLayout->pNext, SUBRESOURCE_HOST_MEMCPY_SIZE_EXT); + if (host_memcpy_size) { + host_memcpy_size->size = + nil_image_level_layer_size_B(&plane->nil, isr->mipLevel) * + plane->nil.extent_px.array_len; + } + pLayout->subresourceLayout = (VkSubresourceLayout) { .offset = offset_B, .size = nil_image_level_size_B(&plane->nil, isr->mipLevel), diff --git a/src/nouveau/vulkan/nvk_physical_device.c b/src/nouveau/vulkan/nvk_physical_device.c index 4dd2ce3f285..455f9eb1688 100644 --- a/src/nouveau/vulkan/nvk_physical_device.c +++ b/src/nouveau/vulkan/nvk_physical_device.c @@ -204,6 +204,7 @@ nvk_get_device_extensions(const struct nvk_instance *instance, .EXT_external_memory_dma_buf = true, .EXT_graphics_pipeline_library = true, .EXT_host_query_reset = true, + .EXT_host_image_copy = info->cls_eng3d >= TURING_A, .EXT_image_2d_view_of_3d = true, .EXT_image_robustness = true, .EXT_image_sliced_view_of_3d = true, @@ -568,6 +569,9 @@ nvk_get_device_features(const struct nv_device_info *info, /* VK_EXT_graphics_pipeline_library */ .graphicsPipelineLibrary = true, + /* VK_EXT_host_image_copy */ + .hostImageCopy = info->cls_eng3d >= TURING_A, + /* VK_EXT_image_2d_view_of_3d */ .image2DViewOf3D = true, .sampler2DViewOf3D = true, @@ -1102,6 +1106,43 @@ nvk_get_device_properties(const struct nvk_instance *instance, "%s (NVK %s)", info->device_name, info->chipset_name); } + /* VK_EXT_host_image_copy */ + + /* Not sure if there are layout specific things, so for now just reporting + * all layouts from extensions. + */ + static const VkImageLayout supported_layouts[] = { + VK_IMAGE_LAYOUT_GENERAL, /* this one is required by spec */ + VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, + VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, + VK_IMAGE_LAYOUT_PREINITIALIZED, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_DEPTH_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_STENCIL_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_READ_ONLY_OPTIMAL, + VK_IMAGE_LAYOUT_ATTACHMENT_OPTIMAL, + VK_IMAGE_LAYOUT_FRAGMENT_DENSITY_MAP_OPTIMAL_EXT, + VK_IMAGE_LAYOUT_ATTACHMENT_FEEDBACK_LOOP_OPTIMAL_EXT, + }; + + properties->pCopySrcLayouts = (VkImageLayout *)supported_layouts; + properties->copySrcLayoutCount = ARRAY_SIZE(supported_layouts); + properties->pCopyDstLayouts = (VkImageLayout *)supported_layouts; + properties->copyDstLayoutCount = ARRAY_SIZE(supported_layouts); + + STATIC_ASSERT(sizeof(instance->driver_build_sha) >= VK_UUID_SIZE); + memcpy(properties->optimalTilingLayoutUUID, + instance->driver_build_sha, VK_UUID_SIZE); + + properties->identicalMemoryTypeRequirements = false; + /* VK_EXT_shader_module_identifier */ STATIC_ASSERT(sizeof(vk_shaderModuleIdentifierAlgorithmUUID) == sizeof(properties->shaderModuleIdentifierAlgorithmUUID));