diff --git a/src/gfxstream/codegen/scripts/cereal/functable.py b/src/gfxstream/codegen/scripts/cereal/functable.py index 225193ad79c..0f42ff9ed23 100644 --- a/src/gfxstream/codegen/scripts/cereal/functable.py +++ b/src/gfxstream/codegen/scripts/cereal/functable.py @@ -95,6 +95,14 @@ RESOURCE_TRACKER_ENTRIES = [ "vkSetBufferCollectionImageConstraintsFUCHSIA", "vkSetBufferCollectionBufferConstraintsFUCHSIA", "vkGetBufferCollectionPropertiesFUCHSIA", + "vkSetPrivateData", + "vkSetPrivateDataKHR", + "vkGetPrivateData", + "vkGetPrivateDataKHR", + "vkCreatePrivateDataSlot", + "vkCreatePrivateDataSlotEXT", + "vkDestroyPrivateDataSlot", + "vkDestroyPrivateDataSlotEXT", ] SUCCESS_VAL = { diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp index 87986a1743a..6fdca3b64a0 100644 --- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp +++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.cpp @@ -1059,6 +1059,13 @@ void ResourceTracker::unregister_VkSampler(VkSampler sampler) { info_VkSampler.erase(sampler); } +void ResourceTracker::unregister_VkPrivateDataSlot(VkPrivateDataSlot privateSlot) { + if (!privateSlot) return; + + std::lock_guard lock(mLock); + info_VkPrivateDataSlot.erase(privateSlot); +} + void ResourceTracker::unregister_VkCommandBuffer(VkCommandBuffer commandBuffer) { resetCommandBufferStagingInfo(commandBuffer, true /* also reset primaries */, true /* also clear pending descriptor sets */); @@ -1566,9 +1573,15 @@ void ResourceTracker::deviceMemoryTransform_tohost(VkDeviceMemory* memory, uint3 for (uint32_t i = 0; i < memoryCount; ++i) { VkDeviceMemory mem = memory[i]; + if (!mem) { + return; + } auto it = info_VkDeviceMemory.find(mem); - if (it == info_VkDeviceMemory.end()) return; + if (it == info_VkDeviceMemory.end()) { + mesa_logw("%s cannot find memory %p!", __func__, mem); + return; + } const auto& info = it->second; @@ -1583,11 +1596,6 @@ void ResourceTracker::deviceMemoryTransform_tohost(VkDeviceMemory* memory, uint3 if (size && size[i] == VK_WHOLE_SIZE) { size[i] = info.allocationSize; } - - // TODO - (void)memory; - (void)offset; - (void)size; } } } @@ -4998,6 +5006,91 @@ VkResult ResourceTracker::on_vkWaitForFences(void* context, VkResult, VkDevice d #endif } +VkResult ResourceTracker::on_vkSetPrivateData(void* context, VkResult input_result, VkDevice device, + VkObjectType objectType, uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, uint64_t data) { + if (input_result != VK_SUCCESS) return input_result; + + VkPrivateDataSlot_Info::PrivateDataKey key = std::make_pair(objectHandle, objectType); + + std::lock_guard lock(mLock); + auto it = info_VkPrivateDataSlot.find(privateDataSlot); + + // Do not forward calls with invalid handles to host. + if (it == info_VkPrivateDataSlot.end()) { + return VK_ERROR_OUT_OF_HOST_MEMORY; + } + + auto& slotInfoTable = it->second.privateDataTable; + slotInfoTable[key] = data; + return VK_SUCCESS; +} + +VkResult ResourceTracker::on_vkSetPrivateDataEXT(void* context, VkResult input_result, + VkDevice device, VkObjectType objectType, + uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, uint64_t data) { + return on_vkSetPrivateData(context, input_result, device, objectType, objectHandle, + privateDataSlot, data); +} + +void ResourceTracker::on_vkGetPrivateData(void* context, VkDevice device, VkObjectType objectType, + uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, + uint64_t* pData) { + VkPrivateDataSlot_Info::PrivateDataKey key = std::make_pair(objectHandle, objectType); + + std::lock_guard lock(mLock); + auto it = info_VkPrivateDataSlot.find(privateDataSlot); + + // Do not forward calls with invalid handles to host. + if (it == info_VkPrivateDataSlot.end()) { + return; + } + + auto& slotInfoTable = it->second.privateDataTable; + *pData = slotInfoTable[key]; +} + +void ResourceTracker::on_vkGetPrivateDataEXT(void* context, VkDevice device, + VkObjectType objectType, uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, uint64_t* pData) { + return on_vkGetPrivateData(context, device, objectType, objectHandle, privateDataSlot, pData); +} + +VkResult ResourceTracker::on_vkCreatePrivateDataSlot(void* context, VkResult input_result, + VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot) { + if (input_result != VK_SUCCESS) { + return input_result; + } + VkEncoder* enc = (VkEncoder*)context; + return enc->vkCreatePrivateDataSlot(device, pCreateInfo, pAllocator, pPrivateDataSlot, + true /* do lock */); +} +VkResult ResourceTracker::on_vkCreatePrivateDataSlotEXT( + void* context, VkResult input_result, VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot) { + return on_vkCreatePrivateDataSlot(context, input_result, device, pCreateInfo, pAllocator, + pPrivateDataSlot); +} + +void ResourceTracker::on_vkDestroyPrivateDataSlot(void* context, VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator) { + if (!privateDataSlot) return; + + VkEncoder* enc = (VkEncoder*)context; + enc->vkDestroyPrivateDataSlot(device, privateDataSlot, pAllocator, true /* do lock */); +} +void ResourceTracker::on_vkDestroyPrivateDataSlotEXT(void* context, VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator) { + return on_vkDestroyPrivateDataSlot(context, device, privateDataSlot, pAllocator); +} + VkResult ResourceTracker::on_vkCreateDescriptorPool(void* context, VkResult, VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, diff --git a/src/gfxstream/guest/vulkan_enc/ResourceTracker.h b/src/gfxstream/guest/vulkan_enc/ResourceTracker.h index edec3f13b43..fc70fb5adc3 100644 --- a/src/gfxstream/guest/vulkan_enc/ResourceTracker.h +++ b/src/gfxstream/guest/vulkan_enc/ResourceTracker.h @@ -395,6 +395,35 @@ class ResourceTracker { uint32_t fenceCount, const VkFence* pFences, VkBool32 waitAll, uint64_t timeout); + VkResult on_vkSetPrivateData(void* context, VkResult input_result, VkDevice device, + VkObjectType objectType, uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, uint64_t data); + VkResult on_vkSetPrivateDataEXT(void* context, VkResult input_result, VkDevice device, + VkObjectType objectType, uint64_t objectHandle, + VkPrivateDataSlot privateDataSlot, uint64_t data); + + void on_vkGetPrivateData(void* context, VkDevice device, VkObjectType objectType, + uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, + uint64_t* pData); + void on_vkGetPrivateDataEXT(void* context, VkDevice device, VkObjectType objectType, + uint64_t objectHandle, VkPrivateDataSlot privateDataSlot, + uint64_t* pData); + + VkResult on_vkCreatePrivateDataSlot(void* context, VkResult input_result, VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + VkResult on_vkCreatePrivateDataSlotEXT(void* context, VkResult input_result, VkDevice device, + const VkPrivateDataSlotCreateInfo* pCreateInfo, + const VkAllocationCallbacks* pAllocator, + VkPrivateDataSlot* pPrivateDataSlot); + void on_vkDestroyPrivateDataSlot(void* context, VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + void on_vkDestroyPrivateDataSlotEXT(void* context, VkDevice device, + VkPrivateDataSlot privateDataSlot, + const VkAllocationCallbacks* pAllocator); + VkResult on_vkCreateDescriptorPool(void* context, VkResult input_result, VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo, const VkAllocationCallbacks* pAllocator, @@ -887,6 +916,28 @@ class ResourceTracker { uint32_t unused; }; + struct VkPrivateDataSlot_Info { + // We need special handling for device memory and swapchain object types for private data + // management. For memory, we can use a single handle on the host side, so setting a + // private data slot for guest handle can also set any other data set previously. + // For swapchains, we don't actually get create/destroy calls to keep track of object + // handles to be able to pass the call to the underlying host driver. Rather than handling + // the 2 cases separately, we handle all the private data management directly here with a + // single table, so vkSetPrivateData and vkGetPrivateData calls don't need to be encoded for + // the host. + typedef std::pair PrivateDataKey; + struct PrivateDataKeyHash { + template + std::size_t operator()(const std::pair& p) const { + std::size_t h1 = std::hash{}(p.first); + std::size_t h2 = std::hash{}(p.second); + return h1 ^ h2; + } + }; + + std::unordered_map privateDataTable; + }; + struct VkBufferCollectionFUCHSIA_Info { #ifdef VK_USE_PLATFORM_FUCHSIA std::optional constraints; diff --git a/src/gfxstream/guest/vulkan_enc/VulkanHandles.h b/src/gfxstream/guest/vulkan_enc/VulkanHandles.h index 1400b9c5092..248073fbd11 100644 --- a/src/gfxstream/guest/vulkan_enc/VulkanHandles.h +++ b/src/gfxstream/guest/vulkan_enc/VulkanHandles.h @@ -104,7 +104,6 @@ namespace vk { f(VkValidationCacheEXT) \ f(VkDebugReportCallbackEXT) \ f(VkDebugUtilsMessengerEXT) \ - f(VkPrivateDataSlot) \ f(VkMicromapEXT) \ __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_BINARY_IMPORT(f) \ __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_NVX_DEVICE_GENERATED_COMMANDS(f) \ @@ -124,6 +123,7 @@ namespace vk { f(VkDescriptorSetLayout) \ f(VkCommandPool) \ f(VkSampler) \ + f(VkPrivateDataSlot) \ __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \ GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f) @@ -150,6 +150,7 @@ namespace vk { f(VkDescriptorUpdateTemplate) \ f(VkCommandPool) \ f(VkSampler) \ + f(VkPrivateDataSlot) \ __GOLDFISH_VK_LIST_NON_DISPATCHABLE_HANDLE_TYPES_FUCHSIA(f) \ GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)