yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// vk-buffer.cpp 2#include "vk-buffer.h" 3 4#include "vk-util.h" 5#if SLANG_WINDOWS_FAMILY 6#include <dxgi1_2.h> 7#endif 8 9namespace gfx 10{ 11 12using namespace Slang ; 13 14namespace vk 15{ 16 17Result VKBufferHandleRAII ::init ( 18const VulkanApi & api , 19Size bufferSize , 20VkBufferUsageFlags usage , 21VkMemoryPropertyFlags reqMemoryProperties , 22bool isShared , 23VkExternalMemoryHandleTypeFlagsKHR extMemHandleType ) 24{ 25assert (!isInitialized ()); 26 27m_api = & api ; 28m_memory = VK_NULL_HANDLE ; 29m_buffer = VK_NULL_HANDLE ; 30 31VkBufferCreateInfo bufferCreateInfo = {VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO }; 32bufferCreateInfo .size = bufferSize ; 33bufferCreateInfo .usage = usage ; 34bufferCreateInfo .sharingMode = VK_SHARING_MODE_EXCLUSIVE ; 35 36VkExternalMemoryBufferCreateInfo externalMemoryBufferCreateInfo = { 37VK_STRUCTURE_TYPE_EXTERNAL_MEMORY_BUFFER_CREATE_INFO }; 38if (isShared ) 39 { 40externalMemoryBufferCreateInfo .handleTypes = extMemHandleType ; 41bufferCreateInfo .pNext = & externalMemoryBufferCreateInfo ; 42 } 43 44SLANG_VK_RETURN_ON_FAIL ( 45api .vkCreateBuffer (api .m_device ,& bufferCreateInfo ,nullptr ,& m_buffer )); 46 47VkMemoryRequirements memoryReqs = {}; 48api .vkGetBufferMemoryRequirements (api .m_device ,m_buffer ,& memoryReqs ); 49 50int memoryTypeIndex = api .findMemoryTypeIndex (memoryReqs .memoryTypeBits ,reqMemoryProperties ); 51assert (memoryTypeIndex >=0 ); 52 53VkMemoryPropertyFlags actualMemoryProperites = 54api .m_deviceMemoryProperties .memoryTypes [memoryTypeIndex ].propertyFlags ; 55VkMemoryAllocateInfo allocateInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_INFO }; 56allocateInfo .allocationSize = memoryReqs .size ; 57allocateInfo .memoryTypeIndex = memoryTypeIndex ; 58#if SLANG_WINDOWS_FAMILY 59VkExportMemoryWin32HandleInfoKHR exportMemoryWin32HandleInfo = { 60VK_STRUCTURE_TYPE_EXPORT_MEMORY_WIN32_HANDLE_INFO_KHR }; 61#endif 62VkExportMemoryAllocateInfoKHR exportMemoryAllocateInfo = { 63VK_STRUCTURE_TYPE_EXPORT_MEMORY_ALLOCATE_INFO_KHR }; 64if (isShared ) 65 { 66#if SLANG_WINDOWS_FAMILY 67exportMemoryWin32HandleInfo .pNext = nullptr ; 68exportMemoryWin32HandleInfo .pAttributes = nullptr ; 69exportMemoryWin32HandleInfo .dwAccess = 70DXGI_SHARED_RESOURCE_READ |DXGI_SHARED_RESOURCE_WRITE ; 71exportMemoryWin32HandleInfo .name = NULL ; 72 73exportMemoryAllocateInfo .pNext = 74extMemHandleType & VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT_KHR 75 ?& exportMemoryWin32HandleInfo 76 :nullptr ; 77#endif 78exportMemoryAllocateInfo .handleTypes = extMemHandleType ; 79allocateInfo .pNext = & exportMemoryAllocateInfo ; 80 } 81VkMemoryAllocateFlagsInfo flagInfo = {VK_STRUCTURE_TYPE_MEMORY_ALLOCATE_FLAGS_INFO }; 82if (usage & VK_BUFFER_USAGE_SHADER_DEVICE_ADDRESS_BIT ) 83 { 84flagInfo .deviceMask = 1 ; 85flagInfo .flags = VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT ; 86 87flagInfo .pNext = allocateInfo .pNext ; 88allocateInfo .pNext = & flagInfo ; 89 } 90 91SLANG_VK_RETURN_ON_FAIL (api .vkAllocateMemory (api .m_device ,& allocateInfo ,nullptr ,& m_memory )); 92SLANG_VK_RETURN_ON_FAIL (api .vkBindBufferMemory (api .m_device ,m_buffer ,m_memory ,0 )); 93 94return SLANG_OK ; 95} 96 97BufferResourceImpl ::BufferResourceImpl (const IBufferResource ::Desc & desc ,DeviceImpl * renderer ) 98 :Parent (desc ),m_renderer (renderer ) 99{ 100assert (renderer ); 101} 102 103BufferResourceImpl ::~BufferResourceImpl () 104{ 105if (sharedHandle .handleValue != 0 ) 106 { 107#if SLANG_WINDOWS_FAMILY 108CloseHandle ((HANDLE )sharedHandle .handleValue ); 109#endif 110 } 111} 112 113DeviceAddress BufferResourceImpl ::getDeviceAddress () 114{ 115if (!m_buffer .m_api -> vkGetBufferDeviceAddress ) 116return 0 ; 117VkBufferDeviceAddressInfo info = {}; 118info .sType = VK_STRUCTURE_TYPE_BUFFER_DEVICE_ADDRESS_INFO ; 119info .buffer = m_buffer .m_buffer ; 120return (DeviceAddress )m_buffer .m_api -> vkGetBufferDeviceAddress (m_buffer .m_api -> m_device ,& info ); 121} 122 123Result BufferResourceImpl ::getNativeResourceHandle (InteropHandle * outHandle ) 124{ 125outHandle -> handleValue = (uint64_t )m_buffer .m_buffer ; 126outHandle -> api = InteropHandleAPI ::Vulkan ; 127return SLANG_OK ; 128} 129 130Result BufferResourceImpl ::getSharedHandle (InteropHandle * outHandle ) 131{ 132// Check if a shared handle already exists for this resource. 133if (sharedHandle .handleValue != 0 ) 134 { 135* outHandle = sharedHandle ; 136return SLANG_OK ; 137 } 138 139// If a shared handle doesn't exist, create one and store it. 140#if SLANG_WINDOWS_FAMILY 141VkMemoryGetWin32HandleInfoKHR info = {}; 142info .sType = VK_STRUCTURE_TYPE_MEMORY_GET_WIN32_HANDLE_INFO_KHR ; 143info .pNext = nullptr ; 144info .memory = m_buffer .m_memory ; 145info .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_WIN32_BIT ; 146 147auto api = m_buffer .m_api ; 148PFN_vkGetMemoryWin32HandleKHR vkCreateSharedHandle ; 149vkCreateSharedHandle = api -> vkGetMemoryWin32HandleKHR ; 150if (!vkCreateSharedHandle ) 151 { 152return SLANG_FAIL ; 153 } 154SLANG_VK_RETURN_ON_FAIL ( 155vkCreateSharedHandle (api -> m_device ,& info , (HANDLE * )& outHandle -> handleValue )); 156#else 157VkMemoryGetFdInfoKHR info = {}; 158info .sType = VK_STRUCTURE_TYPE_MEMORY_GET_FD_INFO_KHR ; 159info .pNext = nullptr ; 160info .memory = m_buffer .m_memory ; 161info .handleType = VK_EXTERNAL_MEMORY_HANDLE_TYPE_OPAQUE_FD_BIT ; 162 163auto api = m_buffer .m_api ; 164PFN_vkGetMemoryFdKHR vkCreateSharedHandle ; 165vkCreateSharedHandle = api -> vkGetMemoryFdKHR ; 166if (!vkCreateSharedHandle ) 167 { 168return SLANG_FAIL ; 169 } 170SLANG_VK_RETURN_ON_FAIL ( 171vkCreateSharedHandle (api -> m_device ,& info , (int * )& outHandle -> handleValue )); 172#endif 173outHandle -> api = InteropHandleAPI ::Vulkan ; 174return SLANG_OK ; 175} 176 177Result BufferResourceImpl ::map (MemoryRange * rangeToRead ,void ** outPointer ) 178{ 179SLANG_UNUSED (rangeToRead ); 180auto api = m_buffer .m_api ; 181SLANG_VK_RETURN_ON_FAIL ( 182api -> vkMapMemory (api -> m_device ,m_buffer .m_memory ,0 ,VK_WHOLE_SIZE ,0 ,outPointer )); 183return SLANG_OK ; 184} 185 186Result BufferResourceImpl ::unmap (MemoryRange * writtenRange ) 187{ 188SLANG_UNUSED (writtenRange ); 189auto api = m_buffer .m_api ; 190api -> vkUnmapMemory (api -> m_device ,m_buffer .m_memory ); 191return SLANG_OK ; 192} 193 194Result BufferResourceImpl ::setDebugName (const char * name ) 195{ 196Parent ::setDebugName (name ); 197auto api = m_buffer .m_api ; 198if (api -> vkDebugMarkerSetObjectNameEXT ) 199 { 200VkDebugMarkerObjectNameInfoEXT nameDesc = {}; 201nameDesc .sType = VK_STRUCTURE_TYPE_DEBUG_MARKER_OBJECT_NAME_INFO_EXT ; 202nameDesc .object = (uint64_t )m_buffer .m_buffer ; 203nameDesc .objectType = VK_DEBUG_REPORT_OBJECT_TYPE_BUFFER_EXT ; 204nameDesc .pObjectName = name ; 205api -> vkDebugMarkerSetObjectNameEXT (api -> m_device ,& nameDesc ); 206 } 207return SLANG_OK ; 208} 209 210}// namespace vk 211}// namespace gfx