The open source OpenXR runtime
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

aux/vk: handle extFormatResolve in create_image

Part-of: <https://gitlab.freedesktop.org/monado/monado/-/merge_requests/2316>

+76 -39
+41 -23
src/xrt/auxiliary/vk/vk_helpers.c
··· 804 804 XRT_CHECK_RESULT VkResult 805 805 vk_alloc_and_bind_image_memory(struct vk_bundle *vk, 806 806 VkImage image, 807 - size_t max_size, 807 + const VkMemoryRequirements *requirements, 808 808 const void *pNext_for_allocate, 809 809 const char *caller_name, 810 - VkDeviceMemory *out_mem, 811 - VkDeviceSize *out_size) 810 + VkDeviceMemory *out_mem) 812 811 { 813 - VkMemoryRequirements memory_requirements; 814 - vk->vkGetImageMemoryRequirements(vk->device, image, &memory_requirements); 815 - 816 - if (max_size > 0 && memory_requirements.size > max_size) { 817 - VK_ERROR(vk, "(%s) vkGetImageMemoryRequirements: Requested more memory (%u) then given (%u)\n", 818 - caller_name, (uint32_t)memory_requirements.size, (uint32_t)max_size); 819 - return VK_ERROR_OUT_OF_DEVICE_MEMORY; 820 - } 821 - if (out_size != NULL) { 822 - *out_size = memory_requirements.size; 823 - } 824 - 825 812 uint32_t memory_type_index = UINT32_MAX; 826 813 bool bret = vk_get_memory_type( // 827 814 vk, // vk_bundle 828 - memory_requirements.memoryTypeBits, // type_bits 815 + requirements->memoryTypeBits, // type_bits 829 816 VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, // memory_props 830 817 &memory_type_index); // out_type_id 831 818 if (!bret) { ··· 836 823 VkMemoryAllocateInfo alloc_info = { 837 824 .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO, 838 825 .pNext = pNext_for_allocate, 839 - .allocationSize = memory_requirements.size, 826 + .allocationSize = requirements->size, 840 827 .memoryTypeIndex = memory_type_index, 841 828 }; 842 829 ··· 901 888 return ret; 902 889 } 903 890 891 + VkMemoryRequirements requirements = {0}; 892 + vk->vkGetImageMemoryRequirements(vk->device, image, &requirements); 893 + 904 894 ret = vk_alloc_and_bind_image_memory( // 905 895 vk, // vk_bundle 906 896 image, // image 907 - SIZE_MAX, // max_size 897 + &requirements, // max_size 908 898 NULL, // pNext_for_allocate 909 899 __func__, // caller_name 910 - out_mem, // out_mem 911 - NULL); // out_size 900 + out_mem); // out_mem 912 901 if (ret != VK_SUCCESS) { 913 902 // Clean up image 914 903 vk->vkDestroyImage(vk->device, image, NULL); ··· 1154 1143 // Nothing to cleanup 1155 1144 return ret; 1156 1145 } 1146 + 1147 + VkMemoryRequirements requirements = {0}; 1148 + vk->vkGetImageMemoryRequirements(vk->device, image, &requirements); 1149 + 1157 1150 #if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_FD) 1158 1151 VkImportMemoryFdInfoKHR import_memory_info = { 1159 1152 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_FD_INFO_KHR, 1160 1153 .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT_KHR, 1161 1154 .fd = image_native->handle, 1162 1155 }; 1156 + 1157 + // TODO memoryTypeBits from VkMemoryFdPropertiesKHR 1163 1158 #elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) 1164 1159 VkImportAndroidHardwareBufferInfoANDROID import_memory_info = { 1165 1160 .sType = VK_STRUCTURE_TYPE_IMPORT_ANDROID_HARDWARE_BUFFER_INFO_ANDROID, 1166 1161 .pNext = NULL, 1167 1162 .buffer = image_native->handle, 1168 1163 }; 1164 + 1165 + VkAndroidHardwareBufferPropertiesANDROID ahb_props = { 1166 + .sType = VK_STRUCTURE_TYPE_ANDROID_HARDWARE_BUFFER_PROPERTIES_ANDROID, 1167 + }; 1168 + 1169 + ret = vk->vkGetAndroidHardwareBufferPropertiesANDROID(vk->device, image_native->handle, &ahb_props); 1170 + if (ret != VK_SUCCESS) { 1171 + VK_ERROR(vk, "vkGetAndroidHardwareBufferPropertiesANDROID: %s", vk_result_string(ret)); 1172 + return ret; 1173 + } 1174 + 1175 + requirements.size = ahb_props.allocationSize; 1176 + requirements.memoryTypeBits = ahb_props.memoryTypeBits; 1169 1177 #elif defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_WIN32_HANDLE) 1170 1178 VkImportMemoryWin32HandleInfoKHR import_memory_info = { 1171 1179 .sType = VK_STRUCTURE_TYPE_IMPORT_MEMORY_WIN32_HANDLE_INFO_KHR, ··· 1173 1181 .handleType = handle_type, 1174 1182 .handle = image_native->handle, 1175 1183 }; 1184 + 1185 + // TODO memoryTypeBits from VkMemoryWin32HandlePropertiesKHR 1176 1186 #else 1177 1187 #error "need port" 1178 1188 #endif 1189 + if (requirements.size > image_native->size) { 1190 + VK_ERROR(vk, "size mismatch, exported %" PRIu64 " but requires %" PRIu64, image_native->size, 1191 + requirements.size); 1192 + return VK_ERROR_OUT_OF_DEVICE_MEMORY; 1193 + } else if (requirements.size < image_native->size) { 1194 + VK_WARN(vk, "size mismatch, exported %" PRIu64 " but requires %" PRIu64, image_native->size, 1195 + requirements.size); 1196 + } 1197 + 1179 1198 VkMemoryDedicatedAllocateInfoKHR dedicated_memory_info = { 1180 1199 .sType = VK_STRUCTURE_TYPE_MEMORY_DEDICATED_ALLOCATE_INFO_KHR, 1181 1200 .pNext = &import_memory_info, ··· 1186 1205 ret = vk_alloc_and_bind_image_memory( // 1187 1206 vk, // vk_bundle 1188 1207 image, // image 1189 - image_native->size, // max_size 1208 + &requirements, // requirements 1190 1209 &dedicated_memory_info, // pNext_for_allocate 1191 1210 __func__, // caller_name 1192 - out_mem, // out_mem 1193 - NULL); // out_size 1211 + out_mem); // out_mem 1194 1212 1195 1213 #if defined(XRT_GRAPHICS_BUFFER_HANDLE_CONSUMED_BY_VULKAN_IMPORT) 1196 1214 // We have consumed this fd now, make sure it's not freed again.
+4 -9
src/xrt/auxiliary/vk/vk_helpers.h
··· 1082 1082 * 1083 1083 * @param vk Vulkan bundle 1084 1084 * @param image The VkImage to allocate for and bind. 1085 - * @param max_size The maximum value you'll allow for 1086 - * VkMemoryRequirements::size. Pass SIZE_MAX if you will accept any size 1087 - * that works. 1085 + * @param requirements Memory requirements used for finding the memory type and the size. 1088 1086 * @param pNext_for_allocate (Optional) a pointer to use in the pNext chain of 1089 1087 * VkMemoryAllocateInfo. 1090 1088 * @param caller_name Used for error printing, this function is called from ··· 1104 1102 XRT_CHECK_RESULT VkResult 1105 1103 vk_alloc_and_bind_image_memory(struct vk_bundle *vk, 1106 1104 VkImage image, 1107 - size_t max_size, 1105 + const VkMemoryRequirements *requirements, 1108 1106 const void *pNext_for_allocate, 1109 1107 const char *caller_name, 1110 - VkDeviceMemory *out_mem, 1111 - VkDeviceSize *out_size); 1108 + VkDeviceMemory *out_mem); 1112 1109 1113 1110 /*! 1114 1111 * ··· 1564 1561 * CSCI = Compositor SwapChain Images. 1565 1562 */ 1566 1563 bool 1567 - vk_csci_is_format_supported(struct vk_bundle *vk, 1568 - VkFormat format, 1569 - enum xrt_swapchain_usage_bits xbits); 1564 + vk_csci_is_format_supported(struct vk_bundle *vk, VkFormat format, enum xrt_swapchain_usage_bits xbits); 1570 1565 1571 1566 /* 1572 1567 *
+31 -7
src/xrt/auxiliary/vk/vk_image_allocator.c
··· 108 108 VkDeviceMemory device_memory = VK_NULL_HANDLE; 109 109 VkImage image = VK_NULL_HANDLE; 110 110 VkResult ret = VK_SUCCESS; 111 - VkDeviceSize size; 112 111 113 112 #if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) 114 113 /* ··· 187 186 }; 188 187 CHAIN(format_android); 189 188 190 - // Android can't allocate native sRGB. 191 - // Use UNORM and correct gamma later. 192 189 if (image_format == VK_FORMAT_R8G8B8A8_SRGB) { 190 + // Some versions of Android can't allocate native sRGB, use UNORM and correct gamma later. 193 191 image_format = VK_FORMAT_R8G8B8A8_UNORM; 194 192 195 193 // https://www.khronos.org/registry/vulkan/specs/1.0/html/vkspec.html#VUID-VkImageViewCreateInfo-image-01019 ··· 203 201 add_format_non_dup(&flh, VK_FORMAT_R8G8B8A8_UNORM); 204 202 add_format_non_dup(&flh, VK_FORMAT_R8G8B8A8_SRGB); 205 203 } 204 + 205 + if (vk_csci_is_format_supported(vk, image_format, info->bits)) { 206 + // Format is supported, no need for VkExternalFormatANDROID 207 + format_android.externalFormat = 0; 208 + assert(a_buffer_format_props.format != VK_FORMAT_UNDEFINED); // Make sure there is a Vulkan format. 209 + } else if (image_usage != VK_IMAGE_USAGE_SAMPLED_BIT && !vk->has_ANDROID_external_format_resolve) { 210 + // VUID-VkImageCreateInfo-pNext-09457 211 + VK_ERROR( 212 + vk, "VK_ANDROID_external_format_resolve not supported, only VK_IMAGE_USAGE_SAMPLED_BIT is allowed"); 213 + return VK_ERROR_FORMAT_NOT_SUPPORTED; 214 + } else { 215 + VK_ERROR(vk, "Format not supported"); 216 + return VK_ERROR_FORMAT_NOT_SUPPORTED; 217 + } 206 218 #endif 207 219 208 220 #ifdef VK_KHR_image_format_list ··· 270 282 .pNext = &memory_dedicated_requirements, 271 283 }; 272 284 285 + VkMemoryRequirements *requirements; 286 + #if defined(XRT_GRAPHICS_BUFFER_HANDLE_IS_AHARDWAREBUFFER) 287 + // VUID-VkImageMemoryRequirementsInfo2-image-01897 288 + // VUID-VkMemoryAllocateInfo-pNext-01874 289 + // Use the requirements from the VkAndroidHardwareBufferPropertiesANDROID instead of querying them 290 + VkMemoryRequirements android_memory_requirements = { 291 + .size = a_buffer_props.allocationSize, 292 + .memoryTypeBits = a_buffer_props.memoryTypeBits, 293 + }; 294 + requirements = &android_memory_requirements; 295 + #else 273 296 vk->vkGetImageMemoryRequirements2(vk->device, &memory_requirements_info, &memory_requirements); 297 + requirements = &memory_requirements.memoryRequirements; 298 + #endif 274 299 275 300 /* 276 301 * On tegra we must not use dedicated allocation when it is only preferred to avoid black textures and driver ··· 312 337 ret = vk_alloc_and_bind_image_memory( // 313 338 vk, // vk_bundle 314 339 image, // image 315 - SIZE_MAX, // max_size 340 + requirements, // requirements 316 341 &export_alloc_info, // pNext_for_allocate 317 342 "vk_image_allocator::create_image", // caller_name 318 - &device_memory, // out_mem 319 - &size); // out_size 343 + &device_memory); // out_mem 320 344 if (ret != VK_SUCCESS) { 321 345 vk->vkDestroyImage(vk->device, image, NULL); 322 346 return ret; ··· 324 348 325 349 out_image->handle = image; 326 350 out_image->memory = device_memory; 327 - out_image->size = size; 351 + out_image->size = memory_requirements.memoryRequirements.size; 328 352 out_image->use_dedicated_allocation = use_dedicated_allocation; 329 353 330 354 return ret;