From b05f3f8e12c8d9075fc621328b426e2ec330acd2 Mon Sep 17 00:00:00 2001 From: Gurchetan Singh Date: Fri, 12 Jul 2024 11:31:59 -0700 Subject: [PATCH] gfxstream: guest: vk_CmdBeginTransformFeedbackEXT fix pCounterBuffers can be NULL, which crashes on the autogen path: "For each element of pCounterBuffers that is VK_NULL_HANDLE, transform feedback will start capturing vertex data to byte zero in the corresponding bound transform feedback buffer." Need to special case. Intel Reviewed-by: Aaron Ruby Acked-by: Yonggang Luo Acked-by: Adam Jackson Part-of: --- .../codegen/scripts/cereal/functable.py | 2 ++ .../guest/vulkan/gfxstream_vk_cmd.cpp | 22 +++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/src/gfxstream/codegen/scripts/cereal/functable.py b/src/gfxstream/codegen/scripts/cereal/functable.py index a718babede8..e5f2ce75dc7 100644 --- a/src/gfxstream/codegen/scripts/cereal/functable.py +++ b/src/gfxstream/codegen/scripts/cereal/functable.py @@ -122,6 +122,8 @@ HANDWRITTEN_ENTRY_POINTS = [ "vkResetCommandPool", "vkFreeCommandBuffers", "vkResetCommandPool", + # Transform feedback + "vkCmdBeginTransformFeedbackEXT", # Special cases to handle struct translations in the pNext chain # TODO: Make a codegen module (use deepcopy as reference) to make this more robust "vkAllocateMemory", diff --git a/src/gfxstream/guest/vulkan/gfxstream_vk_cmd.cpp b/src/gfxstream/guest/vulkan/gfxstream_vk_cmd.cpp index b3d6fce6d3c..721d343c540 100644 --- a/src/gfxstream/guest/vulkan/gfxstream_vk_cmd.cpp +++ b/src/gfxstream/guest/vulkan/gfxstream_vk_cmd.cpp @@ -186,3 +186,25 @@ void gfxstream_vk_FreeCommandBuffers(VkDevice device, VkCommandPool commandPool, vk_command_buffer_destroyOp(&gfxstream_commandBuffer->vk); } } + +void gfxstream_vk_CmdBeginTransformFeedbackEXT(VkCommandBuffer commandBuffer, + uint32_t firstCounterBuffer, + uint32_t counterBufferCount, + const VkBuffer* pCounterBuffers, + const VkDeviceSize* pCounterBufferOffsets) { + AEMU_SCOPED_TRACE("vkCmdBeginTransformFeedbackEXT"); + VK_FROM_HANDLE(gfxstream_vk_command_buffer, gfxstream_commandBuffer, commandBuffer); + auto vkEnc = gfxstream::vk::ResourceTracker::getCommandBufferEncoder( + gfxstream_commandBuffer->internal_object); + std::vector internal_pCounterBuffers(counterBufferCount); + for (uint32_t i = 0; i < counterBufferCount; ++i) { + if (pCounterBuffers && pCounterBuffers[i]) { + VK_FROM_HANDLE(gfxstream_vk_buffer, gfxstream_pCounterBuffers, pCounterBuffers[i]); + internal_pCounterBuffers[i] = gfxstream_pCounterBuffers->internal_object; + } + } + vkEnc->vkCmdBeginTransformFeedbackEXT(gfxstream_commandBuffer->internal_object, + firstCounterBuffer, counterBufferCount, + pCounterBuffers ? internal_pCounterBuffers.data() : NULL, + pCounterBufferOffsets, true /* do lock */); +}