#include "vkNullDriver.hpp"
#include "vkPlatform.hpp"
+#include "vkImageUtil.hpp"
#include "tcuFunctionLibrary.hpp"
#include "deMemory.h"
#include <stdexcept>
+#include <algorithm>
namespace vk
{
namespace
{
+using std::vector;
+
#define VK_NULL_RETURN(STMT) \
do { \
try { \
NAME (VkDevice, const Vk##NAME##CreateInfo*) {} \
}
+VK_NULL_DEFINE_DEVICE_OBJ(Fence);
+VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
+VK_NULL_DEFINE_DEVICE_OBJ(Event);
+VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
+VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
+VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
+VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
+VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
+VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
+VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
+VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
+VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
+VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
+VK_NULL_DEFINE_DEVICE_OBJ(CommandPool);
+
class Instance
{
public:
const tcu::StaticFunctionLibrary m_functions;
};
-class DescriptorSet
-{
-public:
- DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
-};
-
class Pipeline
{
public:
Pipeline (VkDevice, const VkComputePipelineCreateInfo*) {}
};
+void* allocateHeap (const VkMemoryAllocateInfo* pAllocInfo)
+{
+ // \todo [2015-12-03 pyry] Alignment requirements?
+ // \todo [2015-12-03 pyry] Empty allocations okay?
+ if (pAllocInfo->allocationSize > 0)
+ {
+ void* const heapPtr = deMalloc((size_t)pAllocInfo->allocationSize);
+ if (!heapPtr)
+ throw std::bad_alloc();
+ return heapPtr;
+ }
+ else
+ return DE_NULL;
+}
+
+void freeHeap (void* ptr)
+{
+ deFree(ptr);
+}
+
class DeviceMemory
{
public:
DeviceMemory (VkDevice, const VkMemoryAllocateInfo* pAllocInfo)
- : m_memory(deMalloc((size_t)pAllocInfo->allocationSize))
+ : m_memory(allocateHeap(pAllocInfo))
{
- if (!m_memory)
- throw std::bad_alloc();
}
~DeviceMemory (void)
{
- deFree(m_memory);
+ freeHeap(m_memory);
}
void* getPtr (void) const { return m_memory; }
const VkDeviceSize m_size;
};
+class Image
+{
+public:
+ Image (VkDevice, const VkImageCreateInfo* pCreateInfo)
+ : m_imageType (pCreateInfo->imageType)
+ , m_format (pCreateInfo->format)
+ , m_extent (pCreateInfo->extent)
+ , m_samples (pCreateInfo->samples)
+ {}
+
+ VkImageType getImageType (void) const { return m_imageType; }
+ VkFormat getFormat (void) const { return m_format; }
+ VkExtent3D getExtent (void) const { return m_extent; }
+ VkSampleCountFlagBits getSamples (void) const { return m_samples; }
+
+private:
+ const VkImageType m_imageType;
+ const VkFormat m_format;
+ const VkExtent3D m_extent;
+ const VkSampleCountFlagBits m_samples;
+};
+
class CommandBuffer
{
public:
{}
};
-VK_NULL_DEFINE_DEVICE_OBJ(Fence);
-VK_NULL_DEFINE_DEVICE_OBJ(Image);
-VK_NULL_DEFINE_DEVICE_OBJ(Semaphore);
-VK_NULL_DEFINE_DEVICE_OBJ(Event);
-VK_NULL_DEFINE_DEVICE_OBJ(QueryPool);
-VK_NULL_DEFINE_DEVICE_OBJ(BufferView);
-VK_NULL_DEFINE_DEVICE_OBJ(ImageView);
-VK_NULL_DEFINE_DEVICE_OBJ(ShaderModule);
-VK_NULL_DEFINE_DEVICE_OBJ(PipelineCache);
-VK_NULL_DEFINE_DEVICE_OBJ(PipelineLayout);
-VK_NULL_DEFINE_DEVICE_OBJ(RenderPass);
-VK_NULL_DEFINE_DEVICE_OBJ(DescriptorSetLayout);
-VK_NULL_DEFINE_DEVICE_OBJ(Sampler);
-VK_NULL_DEFINE_DEVICE_OBJ(Framebuffer);
-VK_NULL_DEFINE_DEVICE_OBJ(CommandPool);
-VK_NULL_DEFINE_DEVICE_OBJ(DescriptorPool);
+class DescriptorSet
+{
+public:
+ DescriptorSet (VkDevice, VkDescriptorPool, VkDescriptorSetLayout) {}
+};
+
+class DescriptorPool
+{
+public:
+ DescriptorPool (VkDevice device, const VkDescriptorPoolCreateInfo* pCreateInfo)
+ : m_device (device)
+ , m_flags (pCreateInfo->flags)
+ {}
+ ~DescriptorPool (void)
+ {
+ reset();
+ }
+
+ VkDescriptorSet allocate (VkDescriptorSetLayout setLayout);
+ void free (VkDescriptorSet set);
+
+ void reset (void);
+
+private:
+ const VkDevice m_device;
+ const VkDescriptorPoolCreateFlags m_flags;
+
+ vector<DescriptorSet*> m_managedSets;
+};
+
+VkDescriptorSet DescriptorPool::allocate (VkDescriptorSetLayout setLayout)
+{
+ DescriptorSet* const impl = new DescriptorSet(m_device, VkDescriptorPool(reinterpret_cast<deUintptr>(this)), setLayout);
+
+ try
+ {
+ m_managedSets.push_back(impl);
+ }
+ catch (...)
+ {
+ delete impl;
+ throw;
+ }
+
+ return VkDescriptorSet(reinterpret_cast<deUintptr>(impl));
+}
+
+void DescriptorPool::free (VkDescriptorSet set)
+{
+ DescriptorSet* const impl = reinterpret_cast<DescriptorSet*>((deUintptr)set.getInternal());
+
+ DE_ASSERT(m_flags & VK_DESCRIPTOR_POOL_CREATE_FREE_DESCRIPTOR_SET_BIT);
+
+ delete impl;
+
+ for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
+ {
+ if (m_managedSets[ndx] == impl)
+ {
+ std::swap(m_managedSets[ndx], m_managedSets.back());
+ m_managedSets.pop_back();
+ return;
+ }
+ }
+
+ DE_FATAL("VkDescriptorSet not owned by VkDescriptorPool");
+}
+
+void DescriptorPool::reset (void)
+{
+ for (size_t ndx = 0; ndx < m_managedSets.size(); ++ndx)
+ delete m_managedSets[ndx];
+ m_managedSets.clear();
+}
extern "C"
{
return VK_SUCCESS;
}
-VkResult getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
+void getPhysicalDeviceProperties (VkPhysicalDevice, VkPhysicalDeviceProperties* props)
{
deMemset(props, 0, sizeof(VkPhysicalDeviceProperties));
deMemcpy(props->deviceName, "null", 5);
// \todo [2015-09-25 pyry] Fill in reasonable limits
-
- return VK_SUCCESS;
+ props->limits.maxTexelBufferElements = 8096;
}
-VkResult getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
+void getPhysicalDeviceQueueFamilyProperties (VkPhysicalDevice, deUint32* count, VkQueueFamilyProperties* props)
{
if (props && *count >= 1u)
{
}
*count = 1u;
-
- return VK_SUCCESS;
}
-VkResult getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
+void getPhysicalDeviceMemoryProperties (VkPhysicalDevice, VkPhysicalDeviceMemoryProperties* props)
{
deMemset(props, 0, sizeof(VkPhysicalDeviceMemoryProperties));
props->memoryHeapCount = 1u;
props->memoryHeaps[0].size = 1ull << 31;
props->memoryHeaps[0].flags = 0u;
-
- return VK_SUCCESS;
}
-VkResult getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
+void getPhysicalDeviceFormatProperties (VkPhysicalDevice, VkFormat, VkFormatProperties* pFormatProperties)
{
const VkFormatFeatureFlags allFeatures = VK_FORMAT_FEATURE_SAMPLED_IMAGE_BIT
| VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT
pFormatProperties->linearTilingFeatures = allFeatures;
pFormatProperties->optimalTilingFeatures = allFeatures;
pFormatProperties->bufferFeatures = allFeatures;
-
- return VK_SUCCESS;
}
-VkResult getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
+void getBufferMemoryRequirements (VkDevice, VkBuffer bufferHandle, VkMemoryRequirements* requirements)
{
- const Buffer* buffer = reinterpret_cast<Buffer*>(bufferHandle.getInternal());
+ const Buffer* buffer = reinterpret_cast<const Buffer*>(bufferHandle.getInternal());
requirements->memoryTypeBits = 1u;
requirements->size = buffer->getSize();
requirements->alignment = (VkDeviceSize)1u;
+}
- return VK_SUCCESS;
+VkDeviceSize getPackedImageDataSize (VkFormat format, VkExtent3D extent, VkSampleCountFlagBits samples)
+{
+ return (VkDeviceSize)getPixelSize(mapVkFormat(format))
+ * (VkDeviceSize)extent.width
+ * (VkDeviceSize)extent.height
+ * (VkDeviceSize)extent.depth
+ * (VkDeviceSize)samples;
}
-VkResult getImageMemoryRequirements (VkDevice, VkImage, VkMemoryRequirements* requirements)
+void getImageMemoryRequirements (VkDevice, VkImage imageHandle, VkMemoryRequirements* requirements)
{
+ const Image* image = reinterpret_cast<const Image*>(imageHandle.getInternal());
+
requirements->memoryTypeBits = 1u;
- requirements->size = 4u;
requirements->alignment = 4u;
-
- return VK_SUCCESS;
+ requirements->size = getPackedImageDataSize(image->getFormat(), image->getExtent(), image->getSamples());
}
VkResult mapMemory (VkDevice, VkDeviceMemory memHandle, VkDeviceSize offset, VkDeviceSize size, VkMemoryMapFlags flags, void** ppData)
return VK_SUCCESS;
}
-VkResult allocateDescriptorSets (VkDevice device, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
+VkResult allocateDescriptorSets (VkDevice, const VkDescriptorSetAllocateInfo* pAllocateInfo, VkDescriptorSet* pDescriptorSets)
{
+ DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)pAllocateInfo->descriptorPool.getInternal());
+
for (deUint32 ndx = 0; ndx < pAllocateInfo->setLayoutCount; ++ndx)
{
try
{
- pDescriptorSets[ndx] = VkDescriptorSet((deUint64)(deUintptr)new DescriptorSet(device, pAllocateInfo->descriptorPool, pAllocateInfo->pSetLayouts[ndx]));
+ pDescriptorSets[ndx] = poolImpl->allocate(pAllocateInfo->pSetLayouts[ndx]);
}
catch (const std::bad_alloc&)
{
return VK_SUCCESS;
}
-void freeDescriptorSets (VkDevice, VkDescriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
+void freeDescriptorSets (VkDevice, VkDescriptorPool descriptorPool, deUint32 count, const VkDescriptorSet* pDescriptorSets)
{
+ DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
+
for (deUint32 ndx = 0; ndx < count; ++ndx)
- {
- // \note: delete cannot fail
- delete reinterpret_cast<DescriptorSet*>((deUintptr)pDescriptorSets[ndx].getInternal());
- }
+ poolImpl->free(pDescriptorSets[ndx]);
+}
+
+VkResult resetDescriptorPool (VkDevice, VkDescriptorPool descriptorPool, VkDescriptorPoolResetFlags)
+{
+ DescriptorPool* const poolImpl = reinterpret_cast<DescriptorPool*>((deUintptr)descriptorPool.getInternal());
+
+ poolImpl->reset();
+
+ return VK_SUCCESS;
}
VkResult allocateCommandBuffers (VkDevice device, const VkCommandBufferAllocateInfo* pAllocateInfo, VkCommandBuffer* pCommandBuffers)
class NullDriverLibrary : public Library
{
public:
- NullDriverLibrary (void)
- : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
- , m_driver (m_library)
- {}
+ NullDriverLibrary (void)
+ : m_library (s_platformFunctions, DE_LENGTH_OF_ARRAY(s_platformFunctions))
+ , m_driver (m_library)
+ {}
- const PlatformInterface& getPlatformInterface (void) const { return m_driver; }
+ const PlatformInterface& getPlatformInterface (void) const { return m_driver; }
private:
const tcu::StaticFunctionLibrary m_library;