Suppose we have an Instance class in which VkInstance is created.
class Instance
{
public:
Instance();
~Instance();
static VkInstance& getInstance() { return instance; }
private:
static VkInstance instance;
void createInstance();
std::vector<const char*> getRequiredExtensions();
std::vector<const char*> getRequiredLayers();
operator const VkInstance& () const { return instance; }
}
In the cpp file, we initialize the variable VkInstance Instance::instance, as well as create VkInstance.
VkInstance Instance::instance;
Instance::Instance() {createInstance();}
void Instance::createInstance(){
...code...
if (vkCreateInstance(&createInfo, nullptr, &instance) != VK_SUCCESS)
std::cerr << "Failed to create Vulkan Instance" << std::endl;
}
And there is also another class where we connect VkPhysicleDevice.
class PhysicalDevice
{
public:
PhysicalDevice(const VkInstance& instance) {connectionPhysicleDevice();};
~PhysicalDevice() = default;
VkPhysicalDevice& getPhysiclDevice() { return physicalDevice; };
private:
VkPhysicalDevice physicalDevice;
void connectionPhysicalDevice();
bool deviceVerification(VkPhysicalDevice device);
operator const VkPhysicalDevice& () const { return physicalDevice; }
};
void connectionPhysicalDevice()
{
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(Instance::getInstance(), &deviceCount, nullptr);
if (!deviceCount)
std::cerr << "Failed to find GPUs with Vulkan support!" << std::endl;
std::vector<VkPhysicalDevice> device(deviceCount);
vkEnumeratePhysicalDevices(Instance::getInstance(), &deviceCount, device.data());
for (const auto& pDevice : device)
if (deviceVerification(pDevice)) //findDevice
{
physicalDevice = pDevice;
break;
}
if (physicalDevice == VK_NULL_HANDLE)
std::cerr << "Failed to find a suitable GPU";
}
main.cpp()
Engine::Instance instance = Engine::Instance();
Engine::PhysicalDevice pDevice();
We will have an error popping up: Failed to find GPUs with Vulkan support! and Failed to find a suitable GPU. But if we change the code as follows.
class Instance
{
public:
Instance();
~Instance();
VkInstance& getInstance() { return instance; }
private:
VkInstance instance;
void createInstance();
std::vector<const char*> getRequiredExtensions();
std::vector<const char*> getRequiredLayers();
operator const VkInstance& () const { return instance; }
};
class PhysicalDevice
{
public:
PhysicalDevice(const VkInstance& instance) {connectionPhysicleDevice();};
~PhysicalDevice() = default;
VkPhysicalDevice& getPhysiclDevice() { return physicalDevice; };
private:
VkPhysicalDevice physicalDevice;
void connectionPhysicalDevice(const VkInstance& instance);
bool deviceVerification(VkPhysicalDevice device);
operator const VkPhysicalDevice& () const { return physicalDevice; }
};
void PhysicalDevice::connectionPhysicalDevice(const VkInstance& instance)
{
uint32_t deviceCount = 0;
vkEnumeratePhysicalDevices(instance, &deviceCount, nullptr);
if (!deviceCount)
std::cerr << "Failed to find GPUs with Vulkan support!" << std::endl;
std::vector<VkPhysicalDevice> device(deviceCount);
vkEnumeratePhysicalDevices(instance, &deviceCount, device.data());
for (const auto& pDevice : device)
if (deviceVerification(pDevice)) //findDevice
{
physicalDevice = pDevice;
break;
}
if (physicalDevice == VK_NULL_HANDLE)
std::cerr << "Failed to find a suitable GPU";
}
Everything will work correctly for us. And there is such a problem when creating validationLayer and VkDevice. The question is why this happens if getInstance() passes to point to a static variable that is initialized in a single variant, that is, it must pass the actual instance of.