auto extension = parse_extension_name(create_info.ppEnabledExtensionNames[i]);
if(extension == Supported_extension::Not_supported)
return VK_ERROR_EXTENSION_NOT_PRESENT;
+ if(get_extension_scope(extension) != Extension_scope::Instance)
+ {
+ std::cerr << "Error: device extension passed to vkCreateInstance: "
+ << create_info.ppEnabledExtensionNames[i] << std::endl;
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
if(!std::get<1>(extensions.insert(extension)))
{
std::cerr << "Warning: duplicate extension passed to vkCreateInstance: "
if(extensions.count(dependency) == 0)
{
std::cerr << "Error: vkCreateInstance: enabled extension "
- << get_extension_name(extension) << " depends on extension "
- << get_extension_name(dependency) << ", however "
- << get_extension_name(dependency) << " is not enabled" << std::endl;
+ << get_extension_properties(extension).extensionName
+ << " depends on extension "
+ << get_extension_properties(dependency).extensionName << ", however "
+ << get_extension_properties(dependency).extensionName << " is not enabled"
+ << std::endl;
return VK_ERROR_INITIALIZATION_FAILED;
}
}
}
return std::make_unique<Vulkan_instance>(std::move(*app_info), std::move(extensions));
}
+
+util::variant<std::unique_ptr<Vulkan_device>, VkResult> Vulkan_device::create(
+ Vulkan_physical_device &physical_device, const VkDeviceCreateInfo &create_info)
+{
+ assert(create_info.sType == VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO);
+ Supported_extensions extensions;
+ Supported_extensions all_extensions = physical_device.instance.extensions;
+ for(std::size_t i = 0; i < create_info.enabledExtensionCount; i++)
+ {
+ auto extension = parse_extension_name(create_info.ppEnabledExtensionNames[i]);
+ if(extension == Supported_extension::Not_supported)
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ if(get_extension_scope(extension) != Extension_scope::Device)
+ {
+ std::cerr << "Error: instance extension passed to vkCreateDevice: "
+ << create_info.ppEnabledExtensionNames[i] << std::endl;
+ return VK_ERROR_EXTENSION_NOT_PRESENT;
+ }
+ if(!std::get<1>(extensions.insert(extension)))
+ {
+ std::cerr << "Warning: duplicate extension passed to vkCreateDevice: "
+ << create_info.ppEnabledExtensionNames[i] << std::endl;
+ }
+ all_extensions.insert(extension);
+ }
+ for(auto extension : extensions)
+ {
+ for(auto dependency : get_extension_dependencies(extension))
+ {
+ if(all_extensions.count(dependency) == 0)
+ {
+ std::cerr << "Error: vkCreateDevice: enabled extension "
+ << get_extension_properties(extension).extensionName
+ << " depends on extension "
+ << get_extension_properties(dependency).extensionName << ", however "
+ << get_extension_properties(dependency).extensionName << " is not enabled"
+ << std::endl;
+ return VK_ERROR_INITIALIZATION_FAILED;
+ }
+ }
+ }
+ VkPhysicalDeviceFeatures enabled_features = {};
+ if(create_info.pEnabledFeatures)
+ enabled_features = *create_info.pEnabledFeatures;
+ struct Feature_descriptor
+ {
+ VkBool32 VkPhysicalDeviceFeatures::*member;
+ const char *name;
+ };
+ static constexpr std::initializer_list<Feature_descriptor> features = {
+ {
+ .member = &VkPhysicalDeviceFeatures::robustBufferAccess, .name = "robustBufferAccess",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::fullDrawIndexUint32, .name = "fullDrawIndexUint32",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::imageCubeArray, .name = "imageCubeArray",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::independentBlend, .name = "independentBlend",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::geometryShader, .name = "geometryShader",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::tessellationShader, .name = "tessellationShader",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sampleRateShading, .name = "sampleRateShading",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::dualSrcBlend, .name = "dualSrcBlend",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::logicOp, .name = "logicOp",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::multiDrawIndirect, .name = "multiDrawIndirect",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::drawIndirectFirstInstance,
+ .name = "drawIndirectFirstInstance",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::depthClamp, .name = "depthClamp",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::depthBiasClamp, .name = "depthBiasClamp",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::fillModeNonSolid, .name = "fillModeNonSolid",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::depthBounds, .name = "depthBounds",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::wideLines, .name = "wideLines",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::largePoints, .name = "largePoints",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::alphaToOne, .name = "alphaToOne",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::multiViewport, .name = "multiViewport",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::samplerAnisotropy, .name = "samplerAnisotropy",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::textureCompressionETC2,
+ .name = "textureCompressionETC2",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::textureCompressionASTC_LDR,
+ .name = "textureCompressionASTC_LDR",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::textureCompressionBC,
+ .name = "textureCompressionBC",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::occlusionQueryPrecise,
+ .name = "occlusionQueryPrecise",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::pipelineStatisticsQuery,
+ .name = "pipelineStatisticsQuery",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::vertexPipelineStoresAndAtomics,
+ .name = "vertexPipelineStoresAndAtomics",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::fragmentStoresAndAtomics,
+ .name = "fragmentStoresAndAtomics",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderTessellationAndGeometryPointSize,
+ .name = "shaderTessellationAndGeometryPointSize",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderImageGatherExtended,
+ .name = "shaderImageGatherExtended",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderStorageImageExtendedFormats,
+ .name = "shaderStorageImageExtendedFormats",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderStorageImageMultisample,
+ .name = "shaderStorageImageMultisample",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderStorageImageReadWithoutFormat,
+ .name = "shaderStorageImageReadWithoutFormat",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderStorageImageWriteWithoutFormat,
+ .name = "shaderStorageImageWriteWithoutFormat",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderUniformBufferArrayDynamicIndexing,
+ .name = "shaderUniformBufferArrayDynamicIndexing",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderSampledImageArrayDynamicIndexing,
+ .name = "shaderSampledImageArrayDynamicIndexing",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderStorageBufferArrayDynamicIndexing,
+ .name = "shaderStorageBufferArrayDynamicIndexing",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderStorageImageArrayDynamicIndexing,
+ .name = "shaderStorageImageArrayDynamicIndexing",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderClipDistance, .name = "shaderClipDistance",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderCullDistance, .name = "shaderCullDistance",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderFloat64, .name = "shaderFloat64",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderInt64, .name = "shaderInt64",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderInt16, .name = "shaderInt16",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderResourceResidency,
+ .name = "shaderResourceResidency",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::shaderResourceMinLod,
+ .name = "shaderResourceMinLod",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseBinding, .name = "sparseBinding",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidencyBuffer,
+ .name = "sparseResidencyBuffer",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidencyImage2D,
+ .name = "sparseResidencyImage2D",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidencyImage3D,
+ .name = "sparseResidencyImage3D",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidency2Samples,
+ .name = "sparseResidency2Samples",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidency4Samples,
+ .name = "sparseResidency4Samples",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidency8Samples,
+ .name = "sparseResidency8Samples",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidency16Samples,
+ .name = "sparseResidency16Samples",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::sparseResidencyAliased,
+ .name = "sparseResidencyAliased",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::variableMultisampleRate,
+ .name = "variableMultisampleRate",
+ },
+ {
+ .member = &VkPhysicalDeviceFeatures::inheritedQueries, .name = "inheritedQueries",
+ },
+ };
+ for(auto &feature : features)
+ {
+ if(enabled_features.*feature.member && !(physical_device.features.*feature.member))
+ {
+ std::cerr << "Error: vkCreateDevice: feature not supported: " << feature.name
+ << std::endl;
+ return VK_ERROR_FEATURE_NOT_PRESENT;
+ }
+ }
+ assert(create_info.queueCreateInfoCount == 1);
+ assert(create_info.pQueueCreateInfos);
+ assert(create_info.pQueueCreateInfos[0].sType == VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO);
+ assert(create_info.pQueueCreateInfos[0].queueFamilyIndex == 0);
+ assert(create_info.pQueueCreateInfos[0].queueCount == 1);
+ return std::make_unique<Vulkan_device>(physical_device, enabled_features);
+}
}
}
#include "util/enum.h"
#include "util/string_view.h"
#include "util/variant.h"
+#include "util/system_memory_info.h"
+#include "util/constexpr_array.h"
#include <memory>
#include <cassert>
#include <chrono>
+#include <limits>
namespace kazan
{
return Extension_scope::Not_supported;
}
-constexpr util::string_view get_extension_name(Supported_extension extension) noexcept
+constexpr VkExtensionProperties get_extension_properties(Supported_extension extension) noexcept
{
- using namespace util::string_view_literals;
switch(extension)
{
case Supported_extension::Not_supported:
- return ""_sv;
+ return {};
}
assert(!"unknown extension");
- return ""_sv;
+ return {};
+}
+
+constexpr std::size_t get_extension_count(Extension_scope scope) noexcept
+{
+ std::size_t retval = 0;
+ for(auto extension : util::Enum_traits<Supported_extension>::values)
+ if(get_extension_scope(extension) == scope)
+ retval++;
+ return retval;
+}
+
+template <Extension_scope Scope>
+constexpr util::Constexpr_array<VkExtensionProperties, get_extension_count(Scope)>
+ get_extensions() noexcept
+{
+ util::Constexpr_array<VkExtensionProperties, get_extension_count(Scope)> retval{};
+ std::size_t index = 0;
+ for(auto extension : util::Enum_traits<Supported_extension>::values)
+ if(get_extension_scope(extension) == Scope)
+ retval[index++] = get_extension_properties(extension);
+ assert(index == retval.size());
+ return retval;
}
constexpr Supported_extensions get_extension_dependencies(Supported_extension extension) noexcept
{
if(extension == Supported_extension::Not_supported)
continue;
- if(get_extension_name(extension) == name)
+ if(get_extension_properties(extension).extensionName == name)
return extension;
}
return Supported_extension::Not_supported;
{
Vulkan_instance &instance;
VkPhysicalDeviceProperties properties;
+ static constexpr std::size_t queue_family_property_count = 1;
+ VkQueueFamilyProperties queue_family_properties[queue_family_property_count];
+ VkPhysicalDeviceMemoryProperties memory_properties;
+ VkPhysicalDeviceFeatures features;
+ static VkDeviceSize calculate_heap_size() noexcept
+ {
+ std::uintmax_t total_usable_ram = util::System_memory_info::get().total_usable_ram;
+ constexpr std::uintmax_t transition_memory_size = 4ULL << 30; // 4 GiB
+ std::uintmax_t heap_size;
+ if(total_usable_ram >= transition_memory_size)
+ heap_size = total_usable_ram * 3 / 4;
+ else
+ heap_size = total_usable_ram / 2;
+ if(heap_size > std::numeric_limits<VkDeviceSize>::max())
+ heap_size = std::numeric_limits<VkDeviceSize>::max();
+ return heap_size;
+ }
Vulkan_physical_device(Vulkan_instance &instance) noexcept
: instance(instance),
properties{
.pipelineCacheUUID = {},
.limits =
{
- .maxImageDimension1D = 1UL << 23,
- .maxImageDimension2D = 1UL << 23,
- .maxImageDimension3D = 1UL << 23,
- .maxImageDimensionCube = 1UL << 23,
+ .maxImageDimension1D = 1UL << 20,
+ .maxImageDimension2D = 1UL << 20,
+ .maxImageDimension3D = 1UL << 20,
+ .maxImageDimensionCube = 1UL << 20,
.maxImageArrayLayers = static_cast<std::uint32_t>(-1),
.maxTexelBufferElements = static_cast<std::uint32_t>(-1),
.maxUniformBufferRange = static_cast<std::uint32_t>(-1),
.maxViewports = 1,
.maxViewportDimensions =
{
- 1UL << 23, 1UL << 23,
+ 1UL << 20, 1UL << 20,
+ },
+ .viewportBoundsRange =
+ {
+ static_cast<float>(-1) * (1UL << 21), 1UL << 21,
},
- .viewportBoundsRange = {-1.0f * (1UL << 23), 1UL << 23},
.viewportSubPixelBits = 16,
.minMemoryMapAlignment = 64,
.minTexelBufferOffsetAlignment = alignof(std::max_align_t),
.minInterpolationOffset = 0,
.maxInterpolationOffset = 0,
.subPixelInterpolationOffsetBits = 0,
- .maxFramebufferWidth = 1UL << 23,
- .maxFramebufferHeight = 1UL << 23,
+ .maxFramebufferWidth = 1UL << 20,
+ .maxFramebufferHeight = 1UL << 20,
.maxFramebufferLayers = static_cast<std::uint32_t>(-1),
#warning fix up sample counts after adding multisampling
.framebufferColorSampleCounts = VK_SAMPLE_COUNT_1_BIT,
.residencyAlignedMipSize = false,
.residencyNonResidentStrict = false,
},
+ },
+ queue_family_properties{
+ {
+ .queueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT,
+ .queueCount = 1,
+ .timestampValidBits = std::numeric_limits<std::chrono::steady_clock::rep>::digits
+ + 1, // 1 extra for sign bit
+ .minImageTransferGranularity =
+ {
+ 1, 1, 1,
+ },
+ },
+ },
+ memory_properties{
+ .memoryTypeCount = 1,
+ .memoryTypes =
+ {
+ {
+ .propertyFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT
+ | VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT
+ | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT
+ | VK_MEMORY_PROPERTY_HOST_CACHED_BIT,
+ .heapIndex = 0,
+ },
+ },
+ .memoryHeapCount = 1,
+ .memoryHeaps =
+ {
+ {
+ .size = calculate_heap_size(), .flags = VK_MEMORY_HEAP_DEVICE_LOCAL_BIT,
+ },
+ },
+ },
+ features{
+#warning implement robust buffer access
+ .robustBufferAccess = false,
+ .fullDrawIndexUint32 = true,
+ .imageCubeArray = false,
+ .independentBlend = true,
+ .geometryShader = false,
+ .tessellationShader = false,
+ .sampleRateShading = false,
+ .dualSrcBlend = false,
+ .logicOp = false,
+ .multiDrawIndirect = true,
+ .drawIndirectFirstInstance = true,
+ .depthClamp = false,
+ .depthBiasClamp = false,
+ .fillModeNonSolid = false,
+ .depthBounds = false,
+ .wideLines = false,
+ .largePoints = false,
+ .alphaToOne = false,
+ .multiViewport = false,
+ .samplerAnisotropy = false,
+ .textureCompressionETC2 = false,
+ .textureCompressionASTC_LDR = false,
+ .textureCompressionBC = false,
+ .occlusionQueryPrecise = false,
+ .pipelineStatisticsQuery = false,
+ .vertexPipelineStoresAndAtomics = false,
+ .fragmentStoresAndAtomics = false,
+ .shaderTessellationAndGeometryPointSize = false,
+ .shaderImageGatherExtended = false,
+ .shaderStorageImageExtendedFormats = false,
+ .shaderStorageImageMultisample = false,
+ .shaderStorageImageReadWithoutFormat = false,
+ .shaderStorageImageWriteWithoutFormat = false,
+ .shaderUniformBufferArrayDynamicIndexing = true,
+ .shaderSampledImageArrayDynamicIndexing = true,
+ .shaderStorageBufferArrayDynamicIndexing = true,
+ .shaderStorageImageArrayDynamicIndexing = true,
+ .shaderClipDistance = false,
+ .shaderCullDistance = false,
+ .shaderFloat64 = false,
+ .shaderInt64 = true,
+ .shaderInt16 = false,
+ .shaderResourceResidency = false,
+ .shaderResourceMinLod = false,
+ .sparseBinding = false,
+ .sparseResidencyBuffer = false,
+ .sparseResidencyImage2D = false,
+ .sparseResidencyImage3D = false,
+ .sparseResidency2Samples = false,
+ .sparseResidency4Samples = false,
+ .sparseResidency8Samples = false,
+ .sparseResidency16Samples = false,
+ .sparseResidencyAliased = false,
+ .variableMultisampleRate = false,
+ .inheritedQueries = false,
}
{
}
const VkInstanceCreateInfo &create_info);
#warning finish implementing Vulkan_instance
};
+
+struct Vulkan_device : public Vulkan_dispatchable_object<Vulkan_device, VkDevice>
+{
+ struct Queue
+ {
+ };
+ Vulkan_instance &instance;
+ Vulkan_physical_device &physical_device;
+ VkPhysicalDeviceFeatures enabled_features;
+ static constexpr std::size_t queue_count = 1;
+ Queue queues[queue_count];
+ explicit Vulkan_device(Vulkan_physical_device &physical_device,
+ const VkPhysicalDeviceFeatures &enabled_features) noexcept
+ : instance(physical_device.instance),
+ physical_device(physical_device),
+ enabled_features(enabled_features)
+ {
+ }
+ static util::variant<std::unique_ptr<Vulkan_device>, VkResult> create(
+ Vulkan_physical_device &physical_device, const VkDeviceCreateInfo &create_info);
+};
}
}
}
extern "C" VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFeatures(
- VkPhysicalDevice physicalDevice, VkPhysicalDeviceFeatures *pFeatures)
+ VkPhysicalDevice physical_device, VkPhysicalDeviceFeatures *features)
{
-#warning finish implementing vkGetPhysicalDeviceFeatures
- assert(!"vkGetPhysicalDeviceFeatures is not implemented");
+ assert(physical_device);
+ assert(features);
+ auto *physical_device_pointer = vulkan::Vulkan_physical_device::from_handle(physical_device);
+ *features = physical_device_pointer->features;
}
extern "C" VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceFormatProperties(
}
extern "C" VKAPI_ATTR void VKAPI_CALL
- vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physicalDevice,
- uint32_t *pQueueFamilyPropertyCount,
- VkQueueFamilyProperties *pQueueFamilyProperties)
+ vkGetPhysicalDeviceQueueFamilyProperties(VkPhysicalDevice physical_device,
+ uint32_t *queue_family_property_count,
+ VkQueueFamilyProperties *queue_family_properties)
{
-#warning finish implementing vkGetPhysicalDeviceQueueFamilyProperties
- assert(!"vkGetPhysicalDeviceQueueFamilyProperties is not implemented");
+ assert(physical_device);
+ auto *physical_device_pointer = vulkan::Vulkan_physical_device::from_handle(physical_device);
+ vulkan_icd::vulkan_enumerate_list_helper(
+ queue_family_property_count,
+ queue_family_properties,
+ physical_device_pointer->queue_family_properties,
+ vulkan::Vulkan_physical_device::queue_family_property_count);
}
extern "C" VKAPI_ATTR void VKAPI_CALL vkGetPhysicalDeviceMemoryProperties(
- VkPhysicalDevice physicalDevice, VkPhysicalDeviceMemoryProperties *pMemoryProperties)
+ VkPhysicalDevice physical_device, VkPhysicalDeviceMemoryProperties *memory_properties)
{
-#warning finish implementing vkGetPhysicalDeviceMemoryProperties
- assert(!"vkGetPhysicalDeviceMemoryProperties is not implemented");
+ assert(physical_device);
+ assert(memory_properties);
+ auto *physical_device_pointer = vulkan::Vulkan_physical_device::from_handle(physical_device);
+ *memory_properties = physical_device_pointer->memory_properties;
}
extern "C" VKAPI_ATTR PFN_vkVoidFunction VKAPI_CALL vkGetDeviceProcAddr(VkDevice device,
name, vulkan_icd::Vulkan_loader_interface::Procedure_address_scope::Device);
}
-extern "C" VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physicalDevice,
- const VkDeviceCreateInfo *pCreateInfo,
+extern "C" VKAPI_ATTR VkResult VKAPI_CALL vkCreateDevice(VkPhysicalDevice physical_device,
+ const VkDeviceCreateInfo *create_info,
const VkAllocationCallbacks *allocator,
- VkDevice *pDevice)
+ VkDevice *device)
{
validate_allocator(allocator);
-#warning finish implementing vkCreateDevice
- assert(!"vkCreateDevice is not implemented");
+ assert(create_info);
+ assert(physical_device);
+ return vulkan_icd::catch_exceptions_and_return_result(
+ [&]()
+ {
+ auto create_result = vulkan::Vulkan_device::create(
+ *vulkan::Vulkan_physical_device::from_handle(physical_device), *create_info);
+ if(util::holds_alternative<VkResult>(create_result))
+ return util::get<VkResult>(create_result);
+ *device = move_to_handle(
+ util::get<std::unique_ptr<vulkan::Vulkan_device>>(std::move(create_result)));
+ return VK_SUCCESS;
+ });
}
extern "C" VKAPI_ATTR void VKAPI_CALL vkDestroyDevice(VkDevice device,
const VkAllocationCallbacks *allocator)
{
validate_allocator(allocator);
-#warning finish implementing vkDestroyDevice
- assert(!"vkDestroyDevice is not implemented");
+ vulkan::Vulkan_device::move_from_handle(device).reset();
}
extern "C" VKAPI_ATTR VkResult VKAPI_CALL
const char *layer_name, uint32_t *property_count, VkExtensionProperties *properties) noexcept
{
assert(layer_name == nullptr);
- static constexpr std::initializer_list<VkExtensionProperties> extensions = {};
- return vulkan_enumerate_list_helper(property_count, properties, extensions);
+ static constexpr auto extensions = vulkan::get_extensions<vulkan::Extension_scope::Instance>();
+ return vulkan_enumerate_list_helper(
+ property_count, properties, extensions.data(), extensions.size());
}
VkResult Vulkan_loader_interface::enumerate_device_extension_properties(
VkExtensionProperties *properties) noexcept
{
assert(layer_name == nullptr);
- assert(physical_device != nullptr);
- static constexpr std::initializer_list<VkExtensionProperties> extensions = {};
- return vulkan_enumerate_list_helper(property_count, properties, extensions);
+ assert(physical_device != VK_NULL_HANDLE);
+ static constexpr auto extensions = vulkan::get_extensions<vulkan::Extension_scope::Device>();
+ return vulkan_enumerate_list_helper(
+ property_count, properties, extensions.data(), extensions.size());
}
}