vulkan: validate inheritance info
Bug: 186021150
Test: dEQP-VK.api.command_buffer.bad_inheritance_info*
Change-Id: I4720f15c8ed554b9bb7bcde41f97c90b69238bc8
diff --git a/system/vulkan_enc/ResourceTracker.cpp b/system/vulkan_enc/ResourceTracker.cpp
index c160259..814a8dc 100644
--- a/system/vulkan_enc/ResourceTracker.cpp
+++ b/system/vulkan_enc/ResourceTracker.cpp
@@ -6440,6 +6440,14 @@
struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(commandBuffer);
cb->flags = pBeginInfo->flags;
+ VkCommandBufferBeginInfo modifiedBeginInfo;
+
+ if (pBeginInfo->pInheritanceInfo && !cb->isSecondary) {
+ modifiedBeginInfo = *pBeginInfo;
+ modifiedBeginInfo.pInheritanceInfo = nullptr;
+ pBeginInfo = &modifiedBeginInfo;
+ }
+
if (!supportsDeferredCommands()) {
return enc->vkBeginCommandBuffer(commandBuffer, pBeginInfo, true /* do lock */);
}
@@ -6601,6 +6609,27 @@
decDescriptorSetLayoutRef(context, device, descriptorSetLayout, pAllocator);
}
+ VkResult on_vkAllocateCommandBuffers(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers) {
+
+ (void)input_result;
+
+ VkEncoder* enc = (VkEncoder*)context;
+ VkResult res = enc->vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, true /* do lock */);
+ if (VK_SUCCESS != res) return res;
+
+ for (uint32_t i = 0; i < pAllocateInfo->commandBufferCount; ++i) {
+ struct goldfish_VkCommandBuffer* cb = as_goldfish_VkCommandBuffer(pCommandBuffers[i]);
+ cb->isSecondary = pAllocateInfo->level == VK_COMMAND_BUFFER_LEVEL_SECONDARY;
+ }
+
+ return res;
+ }
+
uint32_t getApiVersionFromInstance(VkInstance instance) const {
AutoLock lock(mLock);
uint32_t api = kDefaultApiVersion;
@@ -7717,6 +7746,15 @@
mImpl->on_vkDestroyDescriptorSetLayout(context, device, descriptorSetLayout, pAllocator);
}
+VkResult ResourceTracker::on_vkAllocateCommandBuffers(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers) {
+ return mImpl->on_vkAllocateCommandBuffers(context, input_result, device, pAllocateInfo, pCommandBuffers);
+}
+
void ResourceTracker::deviceMemoryTransform_tohost(
VkDeviceMemory* memory, uint32_t memoryCount,
VkDeviceSize* offset, uint32_t offsetCount,
diff --git a/system/vulkan_enc/ResourceTracker.h b/system/vulkan_enc/ResourceTracker.h
index cd5aa13..13d0560 100644
--- a/system/vulkan_enc/ResourceTracker.h
+++ b/system/vulkan_enc/ResourceTracker.h
@@ -559,6 +559,13 @@
VkDescriptorSetLayout descriptorSetLayout,
const VkAllocationCallbacks* pAllocator);
+ VkResult on_vkAllocateCommandBuffers(
+ void* context,
+ VkResult input_result,
+ VkDevice device,
+ const VkCommandBufferAllocateInfo* pAllocateInfo,
+ VkCommandBuffer* pCommandBuffers);
+
bool isMemoryTypeHostVisible(VkDevice device, uint32_t typeIndex) const;
uint8_t* getMappedPointer(VkDeviceMemory memory);
VkDeviceSize getMappedSize(VkDeviceMemory memory);
diff --git a/system/vulkan_enc/Resources.h b/system/vulkan_enc/Resources.h
index 74f41ee..67c498e 100644
--- a/system/vulkan_enc/Resources.h
+++ b/system/vulkan_enc/Resources.h
@@ -83,7 +83,7 @@
#define GOLDFISH_VK_GET_HOST_U64_DECL(type) \
uint64_t get_host_u64_##type(type);
-GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT)
+GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_DEFINE_DISPATCHABLE_HANDLE_STRUCT)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_NEW_FROM_HOST_DECL)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_AS_GOLDFISH_DECL)
GOLDFISH_VK_LIST_DISPATCHABLE_HANDLE_TYPES(GOLDFISH_VK_GET_HOST_DECL)
@@ -116,6 +116,21 @@
goldfish_vk::DescriptorSetLayoutInfo* layoutInfo;
};
+struct goldfish_VkCommandBuffer {
+ hwvulkan_dispatch_t dispatch;
+ uint64_t underlying;
+ goldfish_vk::VkEncoder* lastUsedEncoder;
+ uint32_t sequenceNumber;
+ goldfish_vk::VkEncoder* privateEncoder;
+ IOStream* privateStream;
+ uint32_t flags;
+ struct goldfish_vk_object_list* poolObjects;
+ struct goldfish_vk_object_list* subObjects;
+ struct goldfish_vk_object_list* superObjects;
+ void* userPtr;
+ bool isSecondary;
+};
+
} // extern "C"
namespace goldfish_vk {
diff --git a/system/vulkan_enc/VulkanHandles.h b/system/vulkan_enc/VulkanHandles.h
index a233408..f12a753 100644
--- a/system/vulkan_enc/VulkanHandles.h
+++ b/system/vulkan_enc/VulkanHandles.h
@@ -129,6 +129,12 @@
GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f) \
GOLDFISH_VK_LIST_TRIVIAL_NON_DISPATCHABLE_HANDLE_TYPES(f)
+#define GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_DISPATCHABLE_HANDLE_TYPES(f) \
+ f(VkInstance) \
+ f(VkDevice) \
+ f(VkQueue) \
+ GOLDFISH_VK_LIST_TRIVIAL_DISPATCHABLE_HANDLE_TYPES(f)
+
#define GOLDFISH_VK_LIST_AUTODEFINED_STRUCT_NON_DISPATCHABLE_HANDLE_TYPES(f) \
f(VkDeviceMemory) \
f(VkBuffer) \
diff --git a/system/vulkan_enc/func_table.cpp b/system/vulkan_enc/func_table.cpp
index b1b11b5..dc3f66d 100644
--- a/system/vulkan_enc/func_table.cpp
+++ b/system/vulkan_enc/func_table.cpp
@@ -1025,7 +1025,8 @@
AEMU_SCOPED_TRACE("vkAllocateCommandBuffers");
auto vkEnc = ResourceTracker::getThreadLocalEncoder();
VkResult vkAllocateCommandBuffers_VkResult_return = (VkResult)0;
- vkAllocateCommandBuffers_VkResult_return = vkEnc->vkAllocateCommandBuffers(device, pAllocateInfo, pCommandBuffers, true /* do lock */);
+ auto resources = ResourceTracker::get();
+ vkAllocateCommandBuffers_VkResult_return = resources->on_vkAllocateCommandBuffers(vkEnc, VK_SUCCESS, device, pAllocateInfo, pCommandBuffers);
if (vkAllocateCommandBuffers_VkResult_return == VK_SUCCESS) {
ResourceTracker::get()->addToCommandPool(pAllocateInfo->commandPool, pAllocateInfo->commandBufferCount, pCommandBuffers);
}