blob: a6431ff98148646f57de0d3d89b7321e103ae2ba [file] [log] [blame]
/*
* Copyright (c) 2015-2016 The Khronos Group Inc.
* Copyright (c) 2015-2016 Valve Corporation
* Copyright (c) 2015-2016 LunarG, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and/or associated documentation files (the "Materials"), to
* deal in the Materials without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Materials, and to permit persons to whom the Materials are
* furnished to do so, subject to the following conditions:
*
* The above copyright notice(s) and this permission notice shall be included in
* all copies or substantial portions of the Materials.
*
* THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
*
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE MATERIALS OR THE
* USE OR OTHER DEALINGS IN THE MATERIALS.
*
* Author: Jeremy Hayes <jeremy@lunarG.com>
*/
#include <algorithm>
#include <iostream>
#include <memory>
#include <string>
#include <vector>
#include <vulkan/vulkan.h>
#include "test_common.h"
namespace VK
{
struct InstanceCreateInfo
{
InstanceCreateInfo() :
info // MSVC can't handle list initialization, thus explicit construction herein.
(
VkInstanceCreateInfo
{
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
nullptr, // pApplicationInfo
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
0, //enabledExtensionCount
nullptr // ppEnabledExtensionNames
}
)
{
}
InstanceCreateInfo& sType(VkStructureType const& sType)
{
info.sType = sType;
return *this;
}
InstanceCreateInfo& pNext(void const*const pNext)
{
info.pNext = pNext;
return *this;
}
InstanceCreateInfo& flags(VkInstanceCreateFlags const& flags)
{
info.flags = flags;
return *this;
}
InstanceCreateInfo& pApplicationInfo(VkApplicationInfo const*const pApplicationInfo)
{
info.pApplicationInfo = pApplicationInfo;
return *this;
}
InstanceCreateInfo& enabledLayerCount(uint32_t const& enabledLayerCount)
{
info.enabledLayerCount = enabledLayerCount;
return *this;
}
InstanceCreateInfo& ppEnabledLayerNames(char const*const*const ppEnabledLayerNames)
{
info.ppEnabledLayerNames = ppEnabledLayerNames;
return *this;
}
InstanceCreateInfo& enabledExtensionCount(uint32_t const& enabledExtensionCount)
{
info.enabledExtensionCount = enabledExtensionCount;
return *this;
}
InstanceCreateInfo& ppEnabledExtensionNames(char const*const*const ppEnabledExtensionNames)
{
info.ppEnabledExtensionNames = ppEnabledExtensionNames;
return *this;
}
operator VkInstanceCreateInfo const*() const
{
return &info;
}
operator VkInstanceCreateInfo*()
{
return &info;
}
VkInstanceCreateInfo info;
};
struct DeviceQueueCreateInfo
{
DeviceQueueCreateInfo() :
info // MSVC can't handle list initialization, thus explicit construction herein.
(
VkDeviceQueueCreateInfo
{
VK_STRUCTURE_TYPE_DEVICE_QUEUE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
0, // queueFamilyIndex
0, // queueCount
nullptr // pQueuePriorities
}
)
{
}
DeviceQueueCreateInfo& sType(VkStructureType const& sType)
{
info.sType = sType;
return *this;
}
DeviceQueueCreateInfo& pNext(void const*const pNext)
{
info.pNext = pNext;
return *this;
}
DeviceQueueCreateInfo& flags(VkDeviceQueueCreateFlags const& flags)
{
info.flags = flags;
return *this;
}
DeviceQueueCreateInfo& queueFamilyIndex(uint32_t const& queueFamilyIndex)
{
info.queueFamilyIndex = queueFamilyIndex;
return *this;
}
DeviceQueueCreateInfo& queueCount(uint32_t const& queueCount)
{
info.queueCount = queueCount;
return *this;
}
DeviceQueueCreateInfo& pQueuePriorities(float const*const pQueuePriorities)
{
info.pQueuePriorities = pQueuePriorities;
return *this;
}
operator VkDeviceQueueCreateInfo()
{
return info;
}
VkDeviceQueueCreateInfo info;
};
struct DeviceCreateInfo
{
DeviceCreateInfo() :
info // MSVC can't handle list initialization, thus explicit construction herein.
(
VkDeviceCreateInfo
{
VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, // sType
nullptr, // pNext
0, // flags
0, // queueCreateInfoCount
nullptr, // pQueueCreateInfos
0, // enabledLayerCount
nullptr, // ppEnabledLayerNames
0, // enabledExtensionCount
nullptr, // ppEnabledExtensionNames
nullptr // pEnabledFeatures
}
)
{
}
DeviceCreateInfo& sType(VkStructureType const& sType)
{
info.sType = sType;
return *this;
}
DeviceCreateInfo& pNext(void const*const pNext)
{
info.pNext = pNext;
return *this;
}
DeviceCreateInfo& flags(VkDeviceQueueCreateFlags const& flags)
{
info.flags = flags;
return *this;
}
DeviceCreateInfo& queueCreateInfoCount(uint32_t const& queueCreateInfoCount)
{
info.queueCreateInfoCount = queueCreateInfoCount;
return *this;
}
DeviceCreateInfo& pQueueCreateInfos(VkDeviceQueueCreateInfo const*const pQueueCreateInfos)
{
info.pQueueCreateInfos = pQueueCreateInfos;
return *this;
}
DeviceCreateInfo& enabledLayerCount(uint32_t const& enabledLayerCount)
{
info.enabledLayerCount = enabledLayerCount;
return *this;
}
DeviceCreateInfo& ppEnabledLayerNames(char const*const*const ppEnabledLayerNames)
{
info.ppEnabledLayerNames = ppEnabledLayerNames;
return *this;
}
DeviceCreateInfo& enabledExtensionCount(uint32_t const& enabledExtensionCount)
{
info.enabledExtensionCount = enabledExtensionCount;
return *this;
}
DeviceCreateInfo& ppEnabledExtensionNames(char const*const*const ppEnabledExtensionNames)
{
info.ppEnabledExtensionNames = ppEnabledExtensionNames;
return *this;
}
DeviceCreateInfo& pEnabledFeatures(VkPhysicalDeviceFeatures const*const pEnabledFeatures)
{
info.pEnabledFeatures = pEnabledFeatures;
return *this;
}
operator VkDeviceCreateInfo const*() const
{
return &info;
}
operator VkDeviceCreateInfo*()
{
return &info;
}
VkDeviceCreateInfo info;
};
}
struct CommandLine : public ::testing::Test
{
static void Initialize(int argc, char **argv)
{
arguments.assign(argv, argv + argc);
};
static void SetUpTestCase() {};
static void TearDownTestCase() {};
static std::vector<std::string> arguments;
};
std::vector<std::string> CommandLine::arguments;
struct EnumerateInstanceLayerProperties : public CommandLine {};
struct EnumerateInstanceExtensionProperties : public CommandLine {};
// Test groups:
// LX = lunar exchange
// LVLGH = loader and validation github
// LVLGL = lodaer and validation gitlab
TEST(LX435, InstanceCreateInfoConst)
{
VkInstanceCreateInfo const info =
{
VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
nullptr,
0,
nullptr,
0,
nullptr,
0,
nullptr
};
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(&info, VK_NULL_HANDLE, &instance);
EXPECT_EQ(result, VK_SUCCESS);
vkDestroyInstance(instance, nullptr);
}
TEST(LX475, DestroyInstanceNullHandle)
{
vkDestroyInstance(VK_NULL_HANDLE, nullptr);
}
TEST(LX475, DestroyDeviceNullHandle)
{
vkDestroyDevice(VK_NULL_HANDLE, nullptr);
}
TEST(CreateInstance, ExtensionNotPresent)
{
char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
auto const info = VK::InstanceCreateInfo().
enabledExtensionCount(1).
ppEnabledExtensionNames(names);
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
// It's not necessary to destroy the instance because it will not be created successfully.
}
TEST(CreateInstance, LayerNotPresent)
{
char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
auto const info = VK::InstanceCreateInfo().
enabledLayerCount(1).
ppEnabledLayerNames(names);
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_ERROR_LAYER_NOT_PRESENT);
// It's not necessary to destroy the instance because it will not be created successfully.
}
// Used by run_loader_tests.sh to test for layer insertion.
TEST(CreateInstance, LayerPresent)
{
char const*const names[] = {"VK_LAYER_LUNARG_parameter_validation"}; // Temporary required due to MSVC bug.
auto const info = VK::InstanceCreateInfo().
enabledLayerCount(1).
ppEnabledLayerNames(names);
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(info, VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
vkDestroyInstance(instance, nullptr);
}
TEST(CreateDevice, ExtensionNotPresent)
{
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
uint32_t physicalCount = 0;
result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
for(uint32_t p = 0; p < physicalCount; ++p)
{
uint32_t familyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(familyCount, 0u);
std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(familyCount, 0u);
for(uint32_t q = 0; q < familyCount; ++q)
{
if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
continue;
}
float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
VkDeviceQueueCreateInfo const queueInfo[1]
{
VK::DeviceQueueCreateInfo().
queueFamilyIndex(q).
queueCount(1).
pQueuePriorities(priorities)
};
char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
auto const deviceInfo = VK::DeviceCreateInfo().
queueCreateInfoCount(1).
pQueueCreateInfos(queueInfo).
enabledExtensionCount(1).
ppEnabledExtensionNames(names);
VkDevice device;
result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
ASSERT_EQ(result, VK_ERROR_EXTENSION_NOT_PRESENT);
// It's not necessary to destroy the device because it will not be created successfully.
}
}
vkDestroyInstance(instance, nullptr);
}
// LX535 / MI-76: Device layers are deprecated.
// For backwards compatibility, they are allowed, but must be ignored.
// Ensure that no errors occur if a bogus device layer list is passed to vkCreateDevice.
TEST(CreateDevice, LayersNotPresent)
{
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
uint32_t physicalCount = 0;
result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
for(uint32_t p = 0; p < physicalCount; ++p)
{
uint32_t familyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(familyCount, 0u);
std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(familyCount, 0u);
for(uint32_t q = 0; q < familyCount; ++q)
{
if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
continue;
}
float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
VkDeviceQueueCreateInfo const queueInfo[1]
{
VK::DeviceQueueCreateInfo().
queueFamilyIndex(q).
queueCount(1).
pQueuePriorities(priorities)
};
char const*const names[] = {"NotPresent"}; // Temporary required due to MSVC bug.
auto const deviceInfo = VK::DeviceCreateInfo().
queueCreateInfoCount(1).
pQueueCreateInfos(queueInfo).
enabledLayerCount(1).
ppEnabledLayerNames(names);
VkDevice device;
result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
ASSERT_EQ(result, VK_SUCCESS);
vkDestroyDevice(device, nullptr);
}
}
vkDestroyInstance(instance, nullptr);
}
TEST_F(EnumerateInstanceLayerProperties, PropertyCountLessThanAvailable)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
// We need atleast two for the test to be relevant.
if(count < 2u)
{
return;
}
std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
count = 1;
result = vkEnumerateInstanceLayerProperties(&count, properties.get());
ASSERT_EQ(result, VK_INCOMPLETE);
}
TEST(EnumerateDeviceLayerProperties, PropertyCountLessThanAvailable)
{
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
uint32_t physicalCount = 0;
result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
for(uint32_t p = 0; p < physicalCount; ++p)
{
uint32_t count = 0u;
result = vkEnumerateDeviceLayerProperties(physical[p], &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
// We need atleast two for the test to be relevant.
if(count < 2u)
{
continue;
}
std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
count = 1;
result = vkEnumerateDeviceLayerProperties(physical[p], &count, properties.get());
ASSERT_EQ(result, VK_INCOMPLETE);
}
vkDestroyInstance(instance, nullptr);
}
TEST_F(EnumerateInstanceLayerProperties, Count)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
{
std::cout << "count=" << count << '\n';
}
}
TEST_F(EnumerateInstanceLayerProperties, OnePass)
{
// Count required for this test.
if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
{
return;
}
uint32_t count = std::stoul(arguments[2]);
std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
VkResult result = vkEnumerateInstanceLayerProperties(&count, properties.get());
ASSERT_EQ(result, VK_SUCCESS);
if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
{
for(uint32_t p = 0; p < count; ++p)
{
std::cout << "properties[" << p << "] ="
<< ' ' << properties[p].layerName
<< ' ' << properties[p].specVersion
<< ' ' << properties[p].implementationVersion
<< ' ' << properties[p].description << '\n';
}
}
}
TEST_F(EnumerateInstanceLayerProperties, TwoPass)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceLayerProperties(&count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
std::unique_ptr<VkLayerProperties[]> properties(new VkLayerProperties[count]);
result = vkEnumerateInstanceLayerProperties(&count, properties.get());
ASSERT_EQ(result, VK_SUCCESS);
if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
{
for(uint32_t p = 0; p < count; ++p)
{
std::cout << "properties[" << p << "] ="
<< ' ' << properties[p].layerName
<< ' ' << properties[p].specVersion
<< ' ' << properties[p].implementationVersion
<< ' ' << properties[p].description << '\n';
}
}
}
TEST_F(EnumerateInstanceExtensionProperties, PropertyCountLessThanAvailable)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
// We need atleast two for the test to be relevant.
if(count < 2u)
{
return;
}
std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
count = 1;
result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
ASSERT_EQ(result, VK_INCOMPLETE);
}
TEST(EnumerateDeviceExtensionProperties, PropertyCountLessThanAvailable)
{
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
uint32_t physicalCount = 0;
result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
for(uint32_t p = 0; p < physicalCount; ++p)
{
uint32_t count = 0u;
result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
// We need atleast two for the test to be relevant.
if(count < 2u)
{
continue;
}
std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
count = 1;
result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
ASSERT_EQ(result, VK_INCOMPLETE);
}
vkDestroyInstance(instance, nullptr);
}
TEST_F(EnumerateInstanceExtensionProperties, Count)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
if(std::find(arguments.begin(), arguments.end(), "count") != arguments.end())
{
std::cout << "count=" << count << '\n';
}
}
TEST_F(EnumerateInstanceExtensionProperties, OnePass)
{
// Count required for this test.
if(std::find(arguments.begin(), arguments.end(), "count") == arguments.end())
{
return;
}
uint32_t count = std::stoul(arguments[2]);
std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
ASSERT_EQ(result, VK_SUCCESS);
if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
{
for(uint32_t p = 0; p < count; ++p)
{
std::cout << "properties[" << p << "] ="
<< ' ' << properties[p].extensionName
<< ' ' << properties[p].specVersion << '\n';
}
}
}
TEST_F(EnumerateInstanceExtensionProperties, TwoPass)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
ASSERT_EQ(result, VK_SUCCESS);
if(std::find(arguments.begin(), arguments.end(), "properties") != arguments.end())
{
for(uint32_t p = 0; p < count; ++p)
{
std::cout << "properties[" << p << "] ="
<< ' ' << properties[p].extensionName
<< ' ' << properties[p].specVersion << '\n';
}
}
}
TEST_F(EnumerateInstanceExtensionProperties, InstanceExtensionEnumerated)
{
uint32_t count = 0u;
VkResult result = vkEnumerateInstanceExtensionProperties(nullptr, &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
result = vkEnumerateInstanceExtensionProperties(nullptr, &count, properties.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_NE(std::find_if(
&properties[0],
&properties[count],
[](VkExtensionProperties const& properties)
{
return strcmp(properties.extensionName, "VK_KHR_surface") == 0;
}),
&properties[count]);
}
TEST(EnumerateDeviceExtensionProperties, DeviceExtensionEnumerated)
{
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
uint32_t physicalCount = 0;
result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
for(uint32_t p = 0; p < physicalCount; ++p)
{
uint32_t count = 0u;
result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
std::unique_ptr<VkExtensionProperties[]> properties(new VkExtensionProperties[count]);
result = vkEnumerateDeviceExtensionProperties(physical[p], nullptr, &count, properties.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_NE(std::find_if(
&properties[0],
&properties[count],
[](VkExtensionProperties const& properties)
{
return strcmp(properties.extensionName, "VK_KHR_swapchain") == 0;
}),
&properties[count]);
}
vkDestroyInstance(instance, nullptr);
}
TEST(WrapObjects, Insert)
{
VkInstance instance = VK_NULL_HANDLE;
VkResult result = vkCreateInstance(VK::InstanceCreateInfo(), VK_NULL_HANDLE, &instance);
ASSERT_EQ(result, VK_SUCCESS);
uint32_t physicalCount = 0;
result = vkEnumeratePhysicalDevices(instance, &physicalCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
std::unique_ptr<VkPhysicalDevice[]> physical(new VkPhysicalDevice[physicalCount]);
result = vkEnumeratePhysicalDevices(instance, &physicalCount, physical.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(physicalCount, 0u);
for(uint32_t p = 0; p < physicalCount; ++p)
{
uint32_t familyCount = 0;
vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, nullptr);
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(familyCount, 0u);
std::unique_ptr<VkQueueFamilyProperties[]> family(new VkQueueFamilyProperties[familyCount]);
vkGetPhysicalDeviceQueueFamilyProperties(physical[p], &familyCount, family.get());
ASSERT_EQ(result, VK_SUCCESS);
ASSERT_GT(familyCount, 0u);
for(uint32_t q = 0; q < familyCount; ++q)
{
if(~family[q].queueFlags & VK_QUEUE_GRAPHICS_BIT)
{
continue;
}
float const priorities[] = {0.0f}; // Temporary required due to MSVC bug.
VkDeviceQueueCreateInfo const queueInfo[1]
{
VK::DeviceQueueCreateInfo().
queueFamilyIndex(q).
queueCount(1).
pQueuePriorities(priorities)
};
auto const deviceInfo = VK::DeviceCreateInfo().
queueCreateInfoCount(1).
pQueueCreateInfos(queueInfo);
VkDevice device;
result = vkCreateDevice(physical[p], deviceInfo, nullptr, &device);
ASSERT_EQ(result, VK_SUCCESS);
vkDestroyDevice(device, nullptr);
}
}
vkDestroyInstance(instance, nullptr);
}
int main(int argc, char **argv)
{
int result;
::testing::InitGoogleTest(&argc, argv);
if(argc > 0)
{
CommandLine::Initialize(argc, argv);
}
result = RUN_ALL_TESTS();
return result;
}