vknulldrv: Implement creation of no-op object types
Change-Id: If093f4c0775415608851b9c0ce356d4916e16ee8
(cherry picked from commit d1a9e4154cdacdba0f84054688f3b2c8d530e073)
diff --git a/vulkan/nulldrv/null_driver.cpp b/vulkan/nulldrv/null_driver.cpp
index 69e2c0f..281873d 100644
--- a/vulkan/nulldrv/null_driver.cpp
+++ b/vulkan/nulldrv/null_driver.cpp
@@ -1,5 +1,6 @@
#include <hardware/hwvulkan.h>
+#include <array>
#include <string.h>
#include <algorithm>
@@ -29,10 +30,60 @@
hwvulkan_dispatch_t dispatch;
};
+namespace {
+// Handles for non-dispatchable objects are either pointers, or arbitrary
+// 64-bit non-zero values. We only use pointers when we need to keep state for
+// the object even in a null driver. For the rest, we form a handle as:
+// [63:63] = 1 to distinguish from pointer handles*
+// [62:56] = non-zero handle type enum value
+// [55: 0] = per-handle-type incrementing counter
+// * This works because virtual addresses with the high bit set are reserved
+// for kernel data in all ABIs we run on.
+//
+// We never reclaim handles on vkDestroy*. It's not even necessary for us to
+// have distinct handles for live objects, and practically speaking we won't
+// ever create 2^56 objects of the same type from a single VkDevice in a null
+// driver.
+//
+// Using a namespace here instead of 'enum class' since we want scoped
+// constants but also want implicit conversions to integral types.
+namespace HandleType {
+ enum Enum {
+ kAttachmentView,
+ kBufferView,
+ kCmdPool,
+ kDescriptorPool,
+ kDescriptorSet,
+ kDescriptorSetLayout,
+ kDynamicColorBlendState,
+ kDynamicDepthStencilState,
+ kDynamicRasterState,
+ kDynamicViewportState,
+ kEvent,
+ kFence,
+ kFramebuffer,
+ kImageView,
+ kPipeline,
+ kPipelineCache,
+ kPipelineLayout,
+ kQueryPool,
+ kRenderPass,
+ kSampler,
+ kSemaphore,
+ kShader,
+ kShaderModule,
+
+ kNumTypes
+ };
+} // namespace HandleType
+uint64_t AllocHandle(VkDevice device, HandleType::Enum type);
+} // anonymous namespace
+
struct VkDevice_T {
hwvulkan_dispatch_t dispatch;
VkInstance_T* instance;
VkQueue_T queue;
+ std::array<uint64_t, HandleType::kNumTypes> next_handle;
};
// -----------------------------------------------------------------------------
@@ -115,6 +166,15 @@
offsetof(VkInstance_T, physical_device));
}
+uint64_t AllocHandle(VkDevice device, HandleType::Enum type) {
+ const uint64_t kHandleMask = (UINT64_C(1) << 56) - 1;
+ ALOGE_IF(device->next_handle[type] == kHandleMask,
+ "non-dispatchable handles of type=%u are about to overflow",
+ type);
+ return (UINT64_C(1) << 63) | ((uint64_t(type) & 0x7) << 56) |
+ (device->next_handle[type]++ & kHandleMask);
+}
+
} // namespace
namespace null_driver {
@@ -218,6 +278,8 @@
device->dispatch.magic = HWVULKAN_DISPATCH_MAGIC;
device->instance = instance;
device->queue.dispatch.magic = HWVULKAN_DISPATCH_MAGIC;
+ std::fill(device->next_handle.begin(), device->next_handle.end(),
+ UINT64_C(0));
*out_device = device;
return VK_SUCCESS;
@@ -329,6 +391,192 @@
}
// -----------------------------------------------------------------------------
+// No-op types
+
+VkResult CreateAttachmentView(VkDevice device,
+ const VkAttachmentViewCreateInfo*,
+ VkAttachmentView* view) {
+ *view = AllocHandle(device, HandleType::kAttachmentView);
+ return VK_SUCCESS;
+}
+
+VkResult CreateBufferView(VkDevice device,
+ const VkBufferViewCreateInfo*,
+ VkBufferView* view) {
+ *view = AllocHandle(device, HandleType::kBufferView);
+ return VK_SUCCESS;
+}
+
+VkResult CreateCommandPool(VkDevice device,
+ const VkCmdPoolCreateInfo*,
+ VkCmdPool* pool) {
+ *pool = AllocHandle(device, HandleType::kCmdPool);
+ return VK_SUCCESS;
+}
+
+VkResult CreateDescriptorPool(VkDevice device,
+ VkDescriptorPoolUsage,
+ uint32_t,
+ const VkDescriptorPoolCreateInfo*,
+ VkDescriptorPool* pool) {
+ *pool = AllocHandle(device, HandleType::kDescriptorPool);
+ return VK_SUCCESS;
+}
+
+VkResult AllocDescriptorSets(VkDevice device,
+ VkDescriptorPool,
+ VkDescriptorSetUsage,
+ uint32_t count,
+ const VkDescriptorSetLayout*,
+ VkDescriptorSet* sets,
+ uint32_t* out_count) {
+ for (uint32_t i = 0; i < count; i++)
+ sets[i] = AllocHandle(device, HandleType::kDescriptorSet);
+ *out_count = count;
+ return VK_SUCCESS;
+}
+
+VkResult CreateDescriptorSetLayout(VkDevice device,
+ const VkDescriptorSetLayoutCreateInfo*,
+ VkDescriptorSetLayout* layout) {
+ *layout = AllocHandle(device, HandleType::kDescriptorSetLayout);
+ return VK_SUCCESS;
+}
+
+VkResult CreateDynamicColorBlendState(VkDevice device,
+ const VkDynamicColorBlendStateCreateInfo*,
+ VkDynamicColorBlendState* state) {
+ *state = AllocHandle(device, HandleType::kDynamicColorBlendState);
+ return VK_SUCCESS;
+}
+
+VkResult CreateDynamicDepthStencilState(
+ VkDevice device,
+ const VkDynamicDepthStencilStateCreateInfo*,
+ VkDynamicDepthStencilState* state) {
+ *state = AllocHandle(device, HandleType::kDynamicDepthStencilState);
+ return VK_SUCCESS;
+}
+
+VkResult CreateDynamicRasterState(VkDevice device,
+ const VkDynamicRasterStateCreateInfo*,
+ VkDynamicRasterState* state) {
+ *state = AllocHandle(device, HandleType::kDynamicRasterState);
+ return VK_SUCCESS;
+}
+
+VkResult CreateDynamicViewportState(VkDevice device,
+ const VkDynamicViewportStateCreateInfo*,
+ VkDynamicViewportState* state) {
+ *state = AllocHandle(device, HandleType::kDynamicViewportState);
+ return VK_SUCCESS;
+}
+
+VkResult CreateEvent(VkDevice device,
+ const VkEventCreateInfo*,
+ VkEvent* event) {
+ *event = AllocHandle(device, HandleType::kEvent);
+ return VK_SUCCESS;
+}
+
+VkResult CreateFence(VkDevice device,
+ const VkFenceCreateInfo*,
+ VkFence* fence) {
+ *fence = AllocHandle(device, HandleType::kFence);
+ return VK_SUCCESS;
+}
+
+VkResult CreateFramebuffer(VkDevice device,
+ const VkFramebufferCreateInfo*,
+ VkFramebuffer* framebuffer) {
+ *framebuffer = AllocHandle(device, HandleType::kFramebuffer);
+ return VK_SUCCESS;
+}
+
+VkResult CreateImageView(VkDevice device,
+ const VkImageViewCreateInfo*,
+ VkImageView* view) {
+ *view = AllocHandle(device, HandleType::kImageView);
+ return VK_SUCCESS;
+}
+
+VkResult CreateGraphicsPipelines(VkDevice device,
+ VkPipelineCache,
+ uint32_t count,
+ const VkGraphicsPipelineCreateInfo*,
+ VkPipeline* pipelines) {
+ for (uint32_t i = 0; i < count; i++)
+ pipelines[i] = AllocHandle(device, HandleType::kPipeline);
+ return VK_SUCCESS;
+}
+
+VkResult CreateComputePipelines(VkDevice device,
+ VkPipelineCache,
+ uint32_t count,
+ const VkComputePipelineCreateInfo*,
+ VkPipeline* pipelines) {
+ for (uint32_t i = 0; i < count; i++)
+ pipelines[i] = AllocHandle(device, HandleType::kPipeline);
+ return VK_SUCCESS;
+}
+
+VkResult CreatePipelineCache(VkDevice device,
+ const VkPipelineCacheCreateInfo*,
+ VkPipelineCache* cache) {
+ *cache = AllocHandle(device, HandleType::kPipelineCache);
+ return VK_SUCCESS;
+}
+
+VkResult CreatePipelineLayout(VkDevice device,
+ const VkPipelineLayoutCreateInfo*,
+ VkPipelineLayout* layout) {
+ *layout = AllocHandle(device, HandleType::kPipelineLayout);
+ return VK_SUCCESS;
+}
+
+VkResult CreateQueryPool(VkDevice device,
+ const VkQueryPoolCreateInfo*,
+ VkQueryPool* pool) {
+ *pool = AllocHandle(device, HandleType::kQueryPool);
+ return VK_SUCCESS;
+}
+
+VkResult CreateRenderPass(VkDevice device,
+ const VkRenderPassCreateInfo*,
+ VkRenderPass* renderpass) {
+ *renderpass = AllocHandle(device, HandleType::kRenderPass);
+ return VK_SUCCESS;
+}
+
+VkResult CreateSampler(VkDevice device,
+ const VkSamplerCreateInfo*,
+ VkSampler* sampler) {
+ *sampler = AllocHandle(device, HandleType::kSampler);
+ return VK_SUCCESS;
+}
+
+VkResult CreateSemaphore(VkDevice device,
+ const VkSemaphoreCreateInfo*,
+ VkSemaphore* semaphore) {
+ *semaphore = AllocHandle(device, HandleType::kSemaphore);
+ return VK_SUCCESS;
+}
+
+VkResult CreateShader(VkDevice device,
+ const VkShaderCreateInfo*,
+ VkShader* shader) {
+ *shader = AllocHandle(device, HandleType::kShader);
+ return VK_SUCCESS;
+}
+
+VkResult CreateShaderModule(VkDevice device,
+ const VkShaderModuleCreateInfo*,
+ VkShaderModule* module) {
+ *module = AllocHandle(device, HandleType::kShaderModule);
+ return VK_SUCCESS;
+}
+
+// -----------------------------------------------------------------------------
// No-op entrypoints
// clang-format off
@@ -453,13 +701,7 @@
return VK_SUCCESS;
}
-VkResult CreateFence(VkDevice device, const VkFenceCreateInfo* pCreateInfo, VkFence* pFence) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyFence(VkDevice device, VkFence fence) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -478,13 +720,7 @@
return VK_SUCCESS;
}
-VkResult CreateSemaphore(VkDevice device, const VkSemaphoreCreateInfo* pCreateInfo, VkSemaphore* pSemaphore) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroySemaphore(VkDevice device, VkSemaphore semaphore) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -498,13 +734,7 @@
return VK_SUCCESS;
}
-VkResult CreateEvent(VkDevice device, const VkEventCreateInfo* pCreateInfo, VkEvent* pEvent) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyEvent(VkDevice device, VkEvent event) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -523,13 +753,7 @@
return VK_SUCCESS;
}
-VkResult CreateQueryPool(VkDevice device, const VkQueryPoolCreateInfo* pCreateInfo, VkQueryPool* pQueryPool) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyQueryPool(VkDevice device, VkQueryPool queryPool) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -538,13 +762,7 @@
return VK_SUCCESS;
}
-VkResult CreateBufferView(VkDevice device, const VkBufferViewCreateInfo* pCreateInfo, VkBufferView* pView) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyBufferView(VkDevice device, VkBufferView bufferView) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -563,53 +781,23 @@
return VK_SUCCESS;
}
-VkResult CreateImageView(VkDevice device, const VkImageViewCreateInfo* pCreateInfo, VkImageView* pView) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyImageView(VkDevice device, VkImageView imageView) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateAttachmentView(VkDevice device, const VkAttachmentViewCreateInfo* pCreateInfo, VkAttachmentView* pView) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyAttachmentView(VkDevice device, VkAttachmentView attachmentView) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateShaderModule(VkDevice device, const VkShaderModuleCreateInfo* pCreateInfo, VkShaderModule* pShaderModule) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyShaderModule(VkDevice device, VkShaderModule shaderModule) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateShader(VkDevice device, const VkShaderCreateInfo* pCreateInfo, VkShader* pShader) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyShader(VkDevice device, VkShader shader) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreatePipelineCache(VkDevice device, const VkPipelineCacheCreateInfo* pCreateInfo, VkPipelineCache* pPipelineCache) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyPipelineCache(VkDevice device, VkPipelineCache pipelineCache) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -628,58 +816,23 @@
return VK_SUCCESS;
}
-VkResult CreateGraphicsPipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkGraphicsPipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateComputePipelines(VkDevice device, VkPipelineCache pipelineCache, uint32_t count, const VkComputePipelineCreateInfo* pCreateInfos, VkPipeline* pPipelines) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyPipeline(VkDevice device, VkPipeline pipeline) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreatePipelineLayout(VkDevice device, const VkPipelineLayoutCreateInfo* pCreateInfo, VkPipelineLayout* pPipelineLayout) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyPipelineLayout(VkDevice device, VkPipelineLayout pipelineLayout) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateSampler(VkDevice device, const VkSamplerCreateInfo* pCreateInfo, VkSampler* pSampler) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroySampler(VkDevice device, VkSampler sampler) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateDescriptorSetLayout(VkDevice device, const VkDescriptorSetLayoutCreateInfo* pCreateInfo, VkDescriptorSetLayout* pSetLayout) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyDescriptorSetLayout(VkDevice device, VkDescriptorSetLayout descriptorSetLayout) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateDescriptorPool(VkDevice device, VkDescriptorPoolUsage poolUsage, uint32_t maxSets, const VkDescriptorPoolCreateInfo* pCreateInfo, VkDescriptorPool* pDescriptorPool) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyDescriptorPool(VkDevice device, VkDescriptorPool descriptorPool) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -688,11 +841,6 @@
return VK_SUCCESS;
}
-VkResult AllocDescriptorSets(VkDevice device, VkDescriptorPool descriptorPool, VkDescriptorSetUsage setUsage, uint32_t count, const VkDescriptorSetLayout* pSetLayouts, VkDescriptorSet* pDescriptorSets, uint32_t* pCount) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult UpdateDescriptorSets(VkDevice device, uint32_t writeCount, const VkWriteDescriptorSet* pDescriptorWrites, uint32_t copyCount, const VkCopyDescriptorSet* pDescriptorCopies) {
ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
@@ -703,63 +851,27 @@
return VK_SUCCESS;
}
-VkResult CreateDynamicViewportState(VkDevice device, const VkDynamicViewportStateCreateInfo* pCreateInfo, VkDynamicViewportState* pState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyDynamicViewportState(VkDevice device, VkDynamicViewportState dynamicViewportState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateDynamicRasterState(VkDevice device, const VkDynamicRasterStateCreateInfo* pCreateInfo, VkDynamicRasterState* pState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyDynamicRasterState(VkDevice device, VkDynamicRasterState dynamicRasterState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateDynamicColorBlendState(VkDevice device, const VkDynamicColorBlendStateCreateInfo* pCreateInfo, VkDynamicColorBlendState* pState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyDynamicColorBlendState(VkDevice device, VkDynamicColorBlendState dynamicColorBlendState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateDynamicDepthStencilState(VkDevice device, const VkDynamicDepthStencilStateCreateInfo* pCreateInfo, VkDynamicDepthStencilState* pState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyDynamicDepthStencilState(VkDevice device, VkDynamicDepthStencilState dynamicDepthStencilState) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateFramebuffer(VkDevice device, const VkFramebufferCreateInfo* pCreateInfo, VkFramebuffer* pFramebuffer) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyFramebuffer(VkDevice device, VkFramebuffer framebuffer) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
-VkResult CreateRenderPass(VkDevice device, const VkRenderPassCreateInfo* pCreateInfo, VkRenderPass* pRenderPass) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
VkResult DestroyRenderPass(VkDevice device, VkRenderPass renderPass) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}
@@ -768,13 +880,7 @@
return VK_SUCCESS;
}
-VkResult CreateCommandPool(VkDevice device, const VkCmdPoolCreateInfo* pCreateInfo, VkCmdPool* pCmdPool) {
- ALOGV("TODO: vk%s", __FUNCTION__);
- return VK_SUCCESS;
-}
-
VkResult DestroyCommandPool(VkDevice device, VkCmdPool cmdPool) {
- ALOGV("TODO: vk%s", __FUNCTION__);
return VK_SUCCESS;
}