拆分PhysicalDevice属性为独立的PhysicalDevice类,并提供根据类型查找GPU的功能

This commit is contained in:
HuYingzhuo 2019-04-13 21:44:26 +08:00
parent 31921d69c6
commit 82eef1c375
10 changed files with 162 additions and 79 deletions

View File

@ -8,6 +8,7 @@ ENDIF()
SET(VULKAN_TEST_SOURCE_FILES main.cpp SET(VULKAN_TEST_SOURCE_FILES main.cpp
${RENDER_WINDOW_SOURCE} ${RENDER_WINDOW_SOURCE}
VKInstance.cpp VKInstance.cpp
VKPhysicalDevice.cpp
VKCommandBuffer.cpp VKCommandBuffer.cpp
RenderSurfaceAttribute.cpp RenderSurfaceAttribute.cpp
RenderSurfaceCreater.cpp RenderSurfaceCreater.cpp
@ -20,6 +21,7 @@ SET(VULKAN_TEST_SOURCE_FILES main.cpp
SET(VULKAN_TEST_HEADER_FILES VK.h SET(VULKAN_TEST_HEADER_FILES VK.h
VKInstance.h VKInstance.h
VKPhysicalDevice.h
VKSurfaceExtensionName.h VKSurfaceExtensionName.h
RenderSurfaceAttribute.h RenderSurfaceAttribute.h
RenderSurface.h RenderSurface.h

View File

@ -20,7 +20,7 @@ class RenderSurface
private: private:
friend RenderSurface *CreateRenderSuface(VkInstance,VkPhysicalDevice,Window *); friend RenderSurface *CreateRenderSuface(VkInstance,const PhysicalDevice *,Window *);
RenderSurface(RefRenderSurfaceAttribute &ref_rsa) RenderSurface(RefRenderSurfaceAttribute &ref_rsa)
{ {
@ -31,8 +31,8 @@ public:
virtual ~RenderSurface()=default; virtual ~RenderSurface()=default;
VkPhysicalDevice GetPhysicalDevice () { return rsa->physical_device; } VkSurfaceKHR GetSurface () {return rsa->surface;}
VkSurfaceKHR GetSurface () { return rsa->surface; } const PhysicalDevice *GetPhysicalDevice ()const {return rsa->physical_device;}
public: public:

View File

@ -2,39 +2,16 @@
#include<iostream> #include<iostream>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice pd,VkSurfaceKHR s)
RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,const PhysicalDevice *pd,VkSurfaceKHR s)
{ {
instance=inst; instance=inst;
physical_device=pd; physical_device=pd;
surface=s; surface=s;
vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device,surface,&surface_caps); VkPhysicalDevice pdevice=physical_device->physical_device;
vkGetPhysicalDeviceFeatures(physical_device,&features); vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdevice,surface,&surface_caps);
vkGetPhysicalDeviceProperties(physical_device,&properties);
vkGetPhysicalDeviceMemoryProperties(physical_device,&memory_properties);
{
uint32_t property_count;
vkEnumerateDeviceLayerProperties(physical_device,&property_count,nullptr);
layer_properties.SetCount(property_count);
vkEnumerateDeviceLayerProperties(physical_device,&property_count,layer_properties.GetData());
debug_out(layer_properties);
}
{
uint32_t exten_count;
vkEnumerateDeviceExtensionProperties(physical_device,nullptr,&exten_count,nullptr);
extension_properties.SetCount(exten_count);
vkEnumerateDeviceExtensionProperties(physical_device,nullptr,&exten_count,extension_properties.GetData());
debug_out(extension_properties);
}
{ {
if(surface_caps.supportedTransforms&VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) if(surface_caps.supportedTransforms&VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR)
@ -65,11 +42,11 @@ RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice
{ {
uint32_t format_count; uint32_t format_count;
if(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device,surface,&format_count,nullptr)==VK_SUCCESS) if(vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice,surface,&format_count,nullptr)==VK_SUCCESS)
{ {
surface_formts.SetCount(format_count); surface_formts.SetCount(format_count);
if(vkGetPhysicalDeviceSurfaceFormatsKHR(physical_device,surface,&format_count,surface_formts.GetData())!=VK_SUCCESS) if(vkGetPhysicalDeviceSurfaceFormatsKHR(pdevice,surface,&format_count,surface_formts.GetData())!=VK_SUCCESS)
{ {
surface_formts.Clear(); surface_formts.Clear();
format=VK_FORMAT_B8G8R8A8_UNORM; format=VK_FORMAT_B8G8R8A8_UNORM;
@ -88,26 +65,26 @@ RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice
{ {
uint32_t mode_count; uint32_t mode_count;
if(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,surface,&mode_count,nullptr)==VK_SUCCESS) if(vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice,surface,&mode_count,nullptr)==VK_SUCCESS)
{ {
present_modes.SetCount(mode_count); present_modes.SetCount(mode_count);
if(vkGetPhysicalDeviceSurfacePresentModesKHR(physical_device,surface,&mode_count,present_modes.GetData())!=VK_SUCCESS) if(vkGetPhysicalDeviceSurfacePresentModesKHR(pdevice,surface,&mode_count,present_modes.GetData())!=VK_SUCCESS)
present_modes.Clear(); present_modes.Clear();
} }
} }
{ {
uint32_t family_count; uint32_t family_count;
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,nullptr); vkGetPhysicalDeviceQueueFamilyProperties(pdevice,&family_count,nullptr);
family_properties.SetCount(family_count); family_properties.SetCount(family_count);
vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,family_properties.GetData()); vkGetPhysicalDeviceQueueFamilyProperties(pdevice,&family_count,family_properties.GetData());
{ {
supports_present.SetCount(family_count); supports_present.SetCount(family_count);
VkBool32 *sp=supports_present.GetData(); VkBool32 *sp=supports_present.GetData();
for(uint32_t i=0; i<family_count; i++) for(uint32_t i=0; i<family_count; i++)
{ {
vkGetPhysicalDeviceSurfaceSupportKHR(physical_device,i,surface,sp); vkGetPhysicalDeviceSurfaceSupportKHR(pdevice,i,surface,sp);
++sp; ++sp;
} }
} }
@ -192,24 +169,4 @@ RenderSurfaceAttribute::~RenderSurfaceAttribute()
if(surface) if(surface)
vkDestroySurfaceKHR(instance,surface,nullptr); vkDestroySurfaceKHR(instance,surface,nullptr);
} }
bool RenderSurfaceAttribute::CheckMemoryType(uint32_t typeBits,VkFlags requirements_mask,uint32_t *typeIndex)
{
// Search memtypes to find first index with those properties
for(uint32_t i=0; i<memory_properties.memoryTypeCount; i++)
{
if((typeBits&1)==1)
{
// Type is available, does it match user properties?
if((memory_properties.memoryTypes[i].propertyFlags&requirements_mask)==requirements_mask)
{
*typeIndex=i;
return true;
}
}
typeBits>>=1;
}
// No memory types matched, return failure
return false;
}
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -1,6 +1,7 @@
#pragma once #pragma once
#include"VK.h" #include"VK.h"
#include"VKPhysicalDevice.h"
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
@ -9,7 +10,8 @@ constexpr uint32_t ERROR_FAMILY_INDEX=UINT32_MAX;
struct RenderSurfaceAttribute struct RenderSurfaceAttribute
{ {
VkInstance instance =nullptr; VkInstance instance =nullptr;
VkPhysicalDevice physical_device =nullptr; const PhysicalDevice * physical_device =nullptr;
VkSurfaceKHR surface =nullptr; VkSurfaceKHR surface =nullptr;
VkSurfaceCapabilitiesKHR surface_caps; VkSurfaceCapabilitiesKHR surface_caps;
VkExtent2D swapchain_extent; VkExtent2D swapchain_extent;
@ -20,12 +22,6 @@ struct RenderSurfaceAttribute
List<VkQueueFamilyProperties> family_properties; List<VkQueueFamilyProperties> family_properties;
List<VkBool32> supports_present; List<VkBool32> supports_present;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceMemoryProperties memory_properties;
List<VkLayerProperties> layer_properties;
List<VkExtensionProperties> extension_properties;
List<VkSurfaceFormatKHR> surface_formts; List<VkSurfaceFormatKHR> surface_formts;
VkFormat format; VkFormat format;
List<VkPresentModeKHR> present_modes; List<VkPresentModeKHR> present_modes;
@ -53,9 +49,12 @@ struct RenderSurfaceAttribute
public: public:
RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice pd,VkSurfaceKHR s); RenderSurfaceAttribute(VkInstance inst,const PhysicalDevice *pd,VkSurfaceKHR s);
~RenderSurfaceAttribute(); ~RenderSurfaceAttribute();
bool CheckMemoryType(uint32_t,VkFlags,uint32_t *); bool CheckMemoryType(uint32_t typeBits,VkFlags requirements_mask,uint32_t *typeIndex)
{
return physical_device->CheckMemoryType(typeBits,requirements_mask,typeIndex);
}
};//class RenderSurfaceAttribute };//class RenderSurfaceAttribute
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -201,7 +201,7 @@ namespace
const VkFormat depth_format=VK_FORMAT_D16_UNORM; const VkFormat depth_format=VK_FORMAT_D16_UNORM;
VkFormatProperties props; VkFormatProperties props;
vkGetPhysicalDeviceFormatProperties(rsa->physical_device,depth_format,&props); vkGetPhysicalDeviceFormatProperties(rsa->physical_device->physical_device,depth_format,&props);
if(props.linearTilingFeatures&VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT) if(props.linearTilingFeatures&VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT)
image_info.tiling=VK_IMAGE_TILING_LINEAR; image_info.tiling=VK_IMAGE_TILING_LINEAR;
@ -288,7 +288,7 @@ namespace
} }
}//namespace }//namespace
RenderSurface *CreateRenderSuface(VkInstance inst,VkPhysicalDevice physical_device,Window *win) RenderSurface *CreateRenderSuface(VkInstance inst,const PhysicalDevice *physical_device,Window *win)
{ {
VkSurfaceKHR surface=CreateSurface(inst,win); VkSurfaceKHR surface=CreateSurface(inst,win);
@ -302,7 +302,7 @@ RenderSurface *CreateRenderSuface(VkInstance inst,VkPhysicalDevice physical_devi
if(rsa->graphics_family==ERROR_FAMILY_INDEX) if(rsa->graphics_family==ERROR_FAMILY_INDEX)
return(nullptr); return(nullptr);
rsa->device=CreateDevice(inst,physical_device,rsa->graphics_family); rsa->device=CreateDevice(inst,physical_device->physical_device,rsa->graphics_family);
if(!rsa->device) if(!rsa->device)
return(nullptr); return(nullptr);

View File

@ -4,7 +4,7 @@
#include<iostream> #include<iostream>
VK_NAMESPACE_BEGIN VK_NAMESPACE_BEGIN
RenderSurface *CreateRenderSuface(VkInstance,VkPhysicalDevice,Window *); RenderSurface *CreateRenderSuface(VkInstance,const PhysicalDevice *,Window *);
namespace namespace
{ {
@ -201,8 +201,11 @@ Instance::Instance(VkInstance i,CharPointerList &el)
if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS) if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS)
{ {
physical_devices.SetCount(gpu_count); VkPhysicalDevice *pd_list=new VkPhysicalDevice[gpu_count];
vkEnumeratePhysicalDevices(inst, &gpu_count,physical_devices.GetData()); vkEnumeratePhysicalDevices(inst, &gpu_count,pd_list);
for(uint32_t i=0;i<gpu_count;i++)
physical_devices.Add(new PhysicalDevice(inst,pd_list[i]));
} }
} }
@ -235,16 +238,34 @@ const bool Instance::CheckLayerSupport(const UTF8String &layer_name)const
return(false); return(false);
} }
RenderSurface *Instance::CreateSurface(Window *win,int pd_index) const PhysicalDevice *Instance::GetDevice(VkPhysicalDeviceType type)const
{
const uint32_t count=physical_devices.GetCount();
PhysicalDevice **pd=physical_devices.GetData();
for(uint32_t i=0;i<count;i++)
{
if((*pd)->GetDeviceType()==type)
return(*pd);
++pd;
}
return(nullptr);
}
RenderSurface *Instance::CreateSurface(Window *win,const PhysicalDevice *pd)
{ {
if(!win) if(!win)
return(nullptr); return(nullptr);
VkPhysicalDevice pd=GetDevice(pd_index); if(!pd)pd=GetDevice(VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU); //先找独显
if(!pd)pd=GetDevice(VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU); //再找集显
if(!pd)pd=GetDevice(VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU); //最后找虚拟显卡
if(!pd) if(!pd)
return(nullptr); return(nullptr);
return CreateRenderSuface(inst,pd,win); return CreateRenderSuface(inst,pd,win);
} }
VK_NAMESPACE_END VK_NAMESPACE_END

View File

@ -20,7 +20,7 @@ VK_NAMESPACE_BEGIN
CharPointerList ext_list; CharPointerList ext_list;
List<VkPhysicalDevice> physical_devices; ObjectList<PhysicalDevice> physical_devices;
private: private:
@ -37,10 +37,10 @@ VK_NAMESPACE_BEGIN
const List<VkLayerProperties> & GetLayerProperties ()const{return layer_properties;} const List<VkLayerProperties> & GetLayerProperties ()const{return layer_properties;}
const bool CheckLayerSupport (const UTF8String &)const; const bool CheckLayerSupport (const UTF8String &)const;
const CharPointerList & GetExtList ()const {return ext_list;} const CharPointerList & GetExtList ()const {return ext_list;}
const List<VkPhysicalDevice> & GetDeviceList ()const {return physical_devices;} const ObjectList<PhysicalDevice> &GetDeviceList ()const {return physical_devices;}
VkPhysicalDevice GetDevice (int index){return GetObject(physical_devices,index);} const PhysicalDevice * GetDevice (VkPhysicalDeviceType)const;
RenderSurface * CreateSurface (Window *,int pd_index=0); RenderSurface * CreateSurface (Window *,const PhysicalDevice *pd=nullptr);
};//class Instance };//class Instance
Instance *CreateInstance(const UTF8String &); ///<创建一个Vulkan实例 Instance *CreateInstance(const UTF8String &); ///<创建一个Vulkan实例

View File

@ -0,0 +1,55 @@
#include"VKPhysicalDevice.h"
VK_NAMESPACE_BEGIN
PhysicalDevice::PhysicalDevice(VkInstance inst,VkPhysicalDevice pd)
{
instance=inst;
physical_device=pd;
vkGetPhysicalDeviceFeatures(physical_device,&features);
vkGetPhysicalDeviceProperties(physical_device,&properties);
vkGetPhysicalDeviceMemoryProperties(physical_device,&memory_properties);
{
uint32_t property_count;
vkEnumerateDeviceLayerProperties(physical_device,&property_count,nullptr);
layer_properties.SetCount(property_count);
vkEnumerateDeviceLayerProperties(physical_device,&property_count,layer_properties.GetData());
debug_out(layer_properties);
}
{
uint32_t exten_count;
vkEnumerateDeviceExtensionProperties(physical_device,nullptr,&exten_count,nullptr);
extension_properties.SetCount(exten_count);
vkEnumerateDeviceExtensionProperties(physical_device,nullptr,&exten_count,extension_properties.GetData());
debug_out(extension_properties);
}
}
const bool PhysicalDevice::CheckMemoryType(uint32_t typeBits,VkFlags requirements_mask,uint32_t *typeIndex)const
{
// Search memtypes to find first index with those properties
for(uint32_t i=0; i<memory_properties.memoryTypeCount; i++)
{
if((typeBits&1)==1)
{
// Type is available, does it match user properties?
if((memory_properties.memoryTypes[i].propertyFlags&requirements_mask)==requirements_mask)
{
*typeIndex=i;
return true;
}
}
typeBits>>=1;
}
// No memory types matched, return failure
return false;
}
VK_NAMESPACE_END

View File

@ -0,0 +1,43 @@
#pragma once
#include"VK.h"
VK_NAMESPACE_BEGIN
struct PhysicalDevice
{
VkInstance instance=nullptr;
VkPhysicalDevice physical_device=nullptr;
VkPhysicalDeviceFeatures features;
VkPhysicalDeviceProperties properties;
VkPhysicalDeviceMemoryProperties memory_properties;
List<VkLayerProperties> layer_properties;
List<VkExtensionProperties> extension_properties;
public:
PhysicalDevice(VkInstance,VkPhysicalDevice);
~PhysicalDevice()=default;
const bool CheckMemoryType(uint32_t,VkFlags,uint32_t *)const;
VkPhysicalDeviceType GetDeviceType()const{return properties.deviceType;}
const char *GetDeviceName()const{return properties.deviceName;}
/**
*
*/
const bool isGPU()const
{
if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)return(true);
if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU)return(true);
if(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU)return(true);
return(false);
}
const bool isDiscreteGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU);} ///<是否是独立显卡
const bool isIntegratedGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU);} ///<是否是集成显卡
const bool isVirtualGPU ()const{return(properties.deviceType==VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU);} ///<是否是虚拟显卡
};//struct PhysicalDevice
VK_NAMESPACE_END

View File

@ -28,6 +28,12 @@ int main(int,char **)
return(-2); return(-2);
} }
{
const vulkan::PhysicalDevice *render_device=render->GetPhysicalDevice();
std::cout<<"auto select physical device: "<<render_device->GetDeviceName()<<std::endl;
}
vulkan::CommandBuffer *cmd_buf=render->CreateCommandBuffer(); vulkan::CommandBuffer *cmd_buf=render->CreateCommandBuffer();
vulkan::Buffer *ubo=render->CreateUBO(1024); vulkan::Buffer *ubo=render->CreateUBO(1024);