diff --git a/example/Vulkan/CMakeLists.txt b/example/Vulkan/CMakeLists.txt index 4a25ce83..641a9051 100644 --- a/example/Vulkan/CMakeLists.txt +++ b/example/Vulkan/CMakeLists.txt @@ -8,6 +8,7 @@ ENDIF() SET(VULKAN_TEST_SOURCE_FILES main.cpp ${RENDER_WINDOW_SOURCE} VKInstance.cpp + VKPhysicalDevice.cpp VKCommandBuffer.cpp RenderSurfaceAttribute.cpp RenderSurfaceCreater.cpp @@ -20,6 +21,7 @@ SET(VULKAN_TEST_SOURCE_FILES main.cpp SET(VULKAN_TEST_HEADER_FILES VK.h VKInstance.h + VKPhysicalDevice.h VKSurfaceExtensionName.h RenderSurfaceAttribute.h RenderSurface.h diff --git a/example/Vulkan/RenderSurface.h b/example/Vulkan/RenderSurface.h index ee095bed..750b4231 100644 --- a/example/Vulkan/RenderSurface.h +++ b/example/Vulkan/RenderSurface.h @@ -20,7 +20,7 @@ class RenderSurface private: - friend RenderSurface *CreateRenderSuface(VkInstance,VkPhysicalDevice,Window *); + friend RenderSurface *CreateRenderSuface(VkInstance,const PhysicalDevice *,Window *); RenderSurface(RefRenderSurfaceAttribute &ref_rsa) { @@ -31,8 +31,8 @@ public: 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: diff --git a/example/Vulkan/RenderSurfaceAttribute.cpp b/example/Vulkan/RenderSurfaceAttribute.cpp index 933a5051..45389ceb 100644 --- a/example/Vulkan/RenderSurfaceAttribute.cpp +++ b/example/Vulkan/RenderSurfaceAttribute.cpp @@ -2,39 +2,16 @@ #include VK_NAMESPACE_BEGIN -RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice pd,VkSurfaceKHR s) + +RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,const PhysicalDevice *pd,VkSurfaceKHR s) { instance=inst; physical_device=pd; surface=s; - vkGetPhysicalDeviceSurfaceCapabilitiesKHR(physical_device,surface,&surface_caps); + VkPhysicalDevice pdevice=physical_device->physical_device; - 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); - } + vkGetPhysicalDeviceSurfaceCapabilitiesKHR(pdevice,surface,&surface_caps); { if(surface_caps.supportedTransforms&VK_SURFACE_TRANSFORM_IDENTITY_BIT_KHR) @@ -65,11 +42,11 @@ RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice { 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); - 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(); format=VK_FORMAT_B8G8R8A8_UNORM; @@ -88,26 +65,26 @@ RenderSurfaceAttribute::RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice { 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); - 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(); } } { uint32_t family_count; - vkGetPhysicalDeviceQueueFamilyProperties(physical_device,&family_count,nullptr); + vkGetPhysicalDeviceQueueFamilyProperties(pdevice,&family_count,nullptr); 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); VkBool32 *sp=supports_present.GetData(); for(uint32_t i=0; i>=1; - } - // No memory types matched, return failure - return false; -} VK_NAMESPACE_END diff --git a/example/Vulkan/RenderSurfaceAttribute.h b/example/Vulkan/RenderSurfaceAttribute.h index 2cf38a43..4db0e2a2 100644 --- a/example/Vulkan/RenderSurfaceAttribute.h +++ b/example/Vulkan/RenderSurfaceAttribute.h @@ -1,6 +1,7 @@ #pragma once #include"VK.h" +#include"VKPhysicalDevice.h" VK_NAMESPACE_BEGIN @@ -9,7 +10,8 @@ constexpr uint32_t ERROR_FAMILY_INDEX=UINT32_MAX; struct RenderSurfaceAttribute { VkInstance instance =nullptr; - VkPhysicalDevice physical_device =nullptr; + const PhysicalDevice * physical_device =nullptr; + VkSurfaceKHR surface =nullptr; VkSurfaceCapabilitiesKHR surface_caps; VkExtent2D swapchain_extent; @@ -20,12 +22,6 @@ struct RenderSurfaceAttribute List family_properties; List supports_present; - VkPhysicalDeviceFeatures features; - VkPhysicalDeviceProperties properties; - VkPhysicalDeviceMemoryProperties memory_properties; - List layer_properties; - List extension_properties; - List surface_formts; VkFormat format; List present_modes; @@ -53,9 +49,12 @@ struct RenderSurfaceAttribute public: - RenderSurfaceAttribute(VkInstance inst,VkPhysicalDevice pd,VkSurfaceKHR s); + RenderSurfaceAttribute(VkInstance inst,const PhysicalDevice *pd,VkSurfaceKHR s); ~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 VK_NAMESPACE_END diff --git a/example/Vulkan/RenderSurfaceCreater.cpp b/example/Vulkan/RenderSurfaceCreater.cpp index 224f0380..b5cd67de 100644 --- a/example/Vulkan/RenderSurfaceCreater.cpp +++ b/example/Vulkan/RenderSurfaceCreater.cpp @@ -201,7 +201,7 @@ namespace const VkFormat depth_format=VK_FORMAT_D16_UNORM; 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) image_info.tiling=VK_IMAGE_TILING_LINEAR; @@ -288,7 +288,7 @@ 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); @@ -302,7 +302,7 @@ RenderSurface *CreateRenderSuface(VkInstance inst,VkPhysicalDevice physical_devi if(rsa->graphics_family==ERROR_FAMILY_INDEX) 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) return(nullptr); diff --git a/example/Vulkan/VKInstance.cpp b/example/Vulkan/VKInstance.cpp index b88e2c73..1c76b6ff 100644 --- a/example/Vulkan/VKInstance.cpp +++ b/example/Vulkan/VKInstance.cpp @@ -4,7 +4,7 @@ #include VK_NAMESPACE_BEGIN -RenderSurface *CreateRenderSuface(VkInstance,VkPhysicalDevice,Window *); +RenderSurface *CreateRenderSuface(VkInstance,const PhysicalDevice *,Window *); namespace { @@ -201,8 +201,11 @@ Instance::Instance(VkInstance i,CharPointerList &el) if(vkEnumeratePhysicalDevices(inst, &gpu_count, nullptr)==VK_SUCCESS) { - physical_devices.SetCount(gpu_count); - vkEnumeratePhysicalDevices(inst, &gpu_count,physical_devices.GetData()); + VkPhysicalDevice *pd_list=new VkPhysicalDevice[gpu_count]; + vkEnumeratePhysicalDevices(inst, &gpu_count,pd_list); + + for(uint32_t i=0;iGetDeviceType()==type) + return(*pd); + + ++pd; + } + + return(nullptr); +} + +RenderSurface *Instance::CreateSurface(Window *win,const PhysicalDevice *pd) { if(!win) 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) return(nullptr); - + return CreateRenderSuface(inst,pd,win); } VK_NAMESPACE_END diff --git a/example/Vulkan/VKInstance.h b/example/Vulkan/VKInstance.h index ba2e9c87..0d688051 100644 --- a/example/Vulkan/VKInstance.h +++ b/example/Vulkan/VKInstance.h @@ -20,7 +20,7 @@ VK_NAMESPACE_BEGIN CharPointerList ext_list; - List physical_devices; + ObjectList physical_devices; private: @@ -37,10 +37,10 @@ VK_NAMESPACE_BEGIN const List & GetLayerProperties ()const{return layer_properties;} const bool CheckLayerSupport (const UTF8String &)const; const CharPointerList & GetExtList ()const {return ext_list;} - const List & GetDeviceList ()const {return physical_devices;} - VkPhysicalDevice GetDevice (int index){return GetObject(physical_devices,index);} + const ObjectList &GetDeviceList ()const {return physical_devices;} + const PhysicalDevice * GetDevice (VkPhysicalDeviceType)const; - RenderSurface * CreateSurface (Window *,int pd_index=0); + RenderSurface * CreateSurface (Window *,const PhysicalDevice *pd=nullptr); };//class Instance Instance *CreateInstance(const UTF8String &); ///<创建一个Vulkan实例 diff --git a/example/Vulkan/VKPhysicalDevice.cpp b/example/Vulkan/VKPhysicalDevice.cpp new file mode 100644 index 00000000..d0c161f1 --- /dev/null +++ b/example/Vulkan/VKPhysicalDevice.cpp @@ -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>=1; + } + // No memory types matched, return failure + return false; +} +VK_NAMESPACE_END \ No newline at end of file diff --git a/example/Vulkan/VKPhysicalDevice.h b/example/Vulkan/VKPhysicalDevice.h new file mode 100644 index 00000000..aaac1102 --- /dev/null +++ b/example/Vulkan/VKPhysicalDevice.h @@ -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 layer_properties; + List 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 \ No newline at end of file diff --git a/example/Vulkan/main.cpp b/example/Vulkan/main.cpp index 2098f906..e63ae6d9 100644 --- a/example/Vulkan/main.cpp +++ b/example/Vulkan/main.cpp @@ -28,6 +28,12 @@ int main(int,char **) return(-2); } + { + const vulkan::PhysicalDevice *render_device=render->GetPhysicalDevice(); + + std::cout<<"auto select physical device: "<GetDeviceName()<CreateCommandBuffer(); vulkan::Buffer *ubo=render->CreateUBO(1024);