2020-10-21 11:43:18 +08:00
# include < hgl / graph / VKDevice . h >
2021-04-06 19:13:53 +08:00
# include<hgl / graph / VKIndexBuffer.h>
# include<hgl / graph / VKVertexAttribBuffer.h>
2021-06-22 21:33:47 +08:00
# include<hgl / graph / VKPhysicalDevice.h>
2023-07-28 20:17:46 +08:00
# include<iostream>
2019-04-27 21:49:22 +08:00
VK_NAMESPACE_BEGIN
2025-05-17 20:26:36 +08:00
const VkDeviceSize VulkanDevice : : GetUBOAlign ( ) { return attr - > physical_device - > GetUBOAlign ( ) ; }
const VkDeviceSize VulkanDevice : : GetSSBOAlign ( ) { return attr - > physical_device - > GetSSBOAlign ( ) ; }
const VkDeviceSize VulkanDevice : : GetUBORange ( ) { return attr - > physical_device - > GetUBORange ( ) ; }
const VkDeviceSize VulkanDevice : : GetSSBORange ( ) { return attr - > physical_device - > GetSSBORange ( ) ; }
2023-03-24 22:14:05 +08:00
2025-05-17 20:26:36 +08:00
bool VulkanDevice : : CreateBuffer ( DeviceBufferData * buf , VkBufferUsageFlags buf_usage , VkDeviceSize range , VkDeviceSize size , const void * data , SharingMode sharing_mode )
2019-04-27 21:49:22 +08:00
{
2023-09-07 18:09:31 +08:00
if ( size < = 0 ) return ( false ) ;
2020-09-27 20:58:25 +08:00
BufferCreateInfo buf_info ;
2020-09-02 18:36:24 +08:00
buf_info . usage = buf_usage ;
buf_info . size = size ;
buf_info . queueFamilyIndexCount = 0 ;
buf_info . pQueueFamilyIndices = nullptr ;
buf_info . sharingMode = VkSharingMode ( sharing_mode ) ;
2019-11-25 22:05:05 +08:00
if ( vkCreateBuffer ( attr - > device , & buf_info , nullptr , & buf - > buffer ) ! = VK_SUCCESS )
return ( false ) ;
2019-04-27 21:49:22 +08:00
2019-11-25 22:05:05 +08:00
VkMemoryRequirements mem_reqs ;
2019-04-27 21:49:22 +08:00
2019-11-25 22:05:05 +08:00
vkGetBufferMemoryRequirements ( attr - > device , buf - > buffer , & mem_reqs ) ;
2019-04-27 21:49:22 +08:00
2023-04-25 15:21:23 +08:00
DeviceMemory * dm = CreateMemory ( mem_reqs , VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT //CPU端可以Map
| VK_MEMORY_PROPERTY_HOST_COHERENT_BIT ) ; //CPU端无需Flush,即可被GPU访问
//注:这个模式并非最佳效能,但是在开发时最为方便
//Device Local模式仅支持GPU访问, 是性能最佳, 考虑在一些极端情况下使用
2019-04-27 21:49:22 +08:00
2019-11-25 22:05:05 +08:00
if ( dm & & dm - > BindBuffer ( buf - > buffer ) )
{
buf - > info . buffer = buf - > buffer ;
buf - > info . offset = 0 ;
2021-06-22 21:33:47 +08:00
buf - > info . range = range ;
2019-06-26 18:38:35 +08:00
2019-11-25 22:05:05 +08:00
buf - > memory = dm ;
2019-04-27 21:49:22 +08:00
2019-11-25 22:05:05 +08:00
if ( ! data )
2019-06-26 17:08:01 +08:00
return ( true ) ;
2023-04-25 15:21:23 +08:00
2021-06-23 18:50:11 +08:00
dm - > Write ( data , 0 , size ) ;
2019-11-25 22:05:05 +08:00
return ( true ) ;
2019-04-27 21:49:22 +08:00
}
2019-11-25 22:05:05 +08:00
delete dm ;
vkDestroyBuffer ( attr - > device , buf - > buffer , nullptr ) ;
return ( false ) ;
}
2019-04-27 21:49:22 +08:00
2025-05-17 20:26:36 +08:00
VAB * VulkanDevice : : CreateVAB ( VkFormat format , uint32_t count , const void * data , SharingMode sharing_mode )
2019-04-27 21:49:22 +08:00
{
2023-09-07 18:09:31 +08:00
if ( count = = 0 ) return ( nullptr ) ;
2019-04-27 21:49:22 +08:00
const uint32_t stride = GetStrideByFormat ( format ) ;
if ( stride = = 0 )
{
2025-05-17 20:26:36 +08:00
std : : cerr < < " format[ " < < format < < " ] stride length is 0,please use \" VulkanDevice::CreateBuffer(VkBufferUsageFlags,VkDeviceSize,VkSharingMode) \" function. " ;
2019-04-27 21:49:22 +08:00
return ( nullptr ) ;
}
const VkDeviceSize size = stride * count ;
2022-10-14 17:52:35 +08:00
DeviceBufferData buf ;
2019-04-27 21:49:22 +08:00
2021-06-22 21:33:47 +08:00
if ( ! CreateBuffer ( & buf , VK_BUFFER_USAGE_VERTEX_BUFFER_BIT , size , size , data , sharing_mode ) )
2019-04-27 21:49:22 +08:00
return ( nullptr ) ;
2020-07-14 14:03:26 +08:00
return ( new VertexAttribBuffer ( attr - > device , buf , format , stride , count ) ) ;
2019-04-27 21:49:22 +08:00
}
2025-05-17 20:26:36 +08:00
const IndexType VulkanDevice : : ChooseIndexType ( const VkDeviceSize & vertex_count ) const
2024-04-19 00:40:51 +08:00
{
if ( vertex_count < = 0 ) return ( IndexType : : ERR ) ;
2024-05-05 15:12:14 +08:00
if ( attr - > uint8_index_type & & vertex_count < = 0xFF ) return IndexType : : U8 ; else
if ( vertex_count < = 0xFFFF ) return IndexType : : U16 ; else
if ( attr - > uint32_index_type ) return IndexType : : U32 ; else
2024-04-19 00:40:51 +08:00
return IndexType : : ERR ;
}
2025-05-17 20:26:36 +08:00
const bool VulkanDevice : : CheckIndexType ( const IndexType it , const VkDeviceSize & vertex_count ) const
2024-04-19 00:40:51 +08:00
{
if ( vertex_count < = 0 ) return ( false ) ;
if ( it = = IndexType : : U16 & & vertex_count < = 0xFFFF ) return ( true ) ;
2024-05-05 15:12:14 +08:00
if ( it = = IndexType : : U32 & & attr - > uint32_index_type ) return ( true ) ;
2024-04-19 00:40:51 +08:00
2024-05-05 15:12:14 +08:00
if ( it = = IndexType : : U8 & & vertex_count < = 0xFF & & attr - > uint8_index_type ) return ( true ) ;
2024-04-19 00:40:51 +08:00
return ( false ) ;
}
2025-05-17 20:26:36 +08:00
IndexBuffer * VulkanDevice : : CreateIBO ( IndexType index_type , uint32_t count , const void * data , SharingMode sharing_mode )
2019-04-27 21:49:22 +08:00
{
2023-09-07 18:09:31 +08:00
if ( count = = 0 ) return ( nullptr ) ;
2019-04-27 21:49:22 +08:00
uint32_t stride ;
2023-05-11 21:07:26 +08:00
if ( index_type = = IndexType : : U8 ) stride = 1 ; else
2020-09-02 19:06:12 +08:00
if ( index_type = = IndexType : : U16 ) stride = 2 ; else
if ( index_type = = IndexType : : U32 ) stride = 4 ; else
2019-05-06 12:00:03 +08:00
return ( nullptr ) ;
2019-04-27 21:49:22 +08:00
const VkDeviceSize size = stride * count ;
2022-10-14 17:52:35 +08:00
DeviceBufferData buf ;
2019-04-27 21:49:22 +08:00
2019-11-25 22:05:05 +08:00
if ( ! CreateBuffer ( & buf , VK_BUFFER_USAGE_INDEX_BUFFER_BIT , size , data , sharing_mode ) )
2019-04-27 21:49:22 +08:00
return ( nullptr ) ;
2019-11-25 22:05:05 +08:00
return ( new IndexBuffer ( attr - > device , buf , index_type , count ) ) ;
2019-04-27 21:49:22 +08:00
}
2025-05-17 20:26:36 +08:00
DeviceBuffer * VulkanDevice : : CreateBuffer ( VkBufferUsageFlags buf_usage , VkDeviceSize range , VkDeviceSize size , const void * data , SharingMode sharing_mode )
2019-04-27 21:49:22 +08:00
{
2023-09-07 18:09:31 +08:00
if ( size < = 0 ) return ( nullptr ) ;
2022-10-14 17:52:35 +08:00
DeviceBufferData buf ;
2019-04-27 21:49:22 +08:00
2021-06-22 21:33:47 +08:00
if ( ! CreateBuffer ( & buf , buf_usage , range , size , data , sharing_mode ) )
2019-04-27 21:49:22 +08:00
return ( nullptr ) ;
2022-10-14 17:52:35 +08:00
return ( new DeviceBuffer ( attr - > device , buf ) ) ;
2019-04-27 21:49:22 +08:00
}
VK_NAMESPACE_END