yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
591affaf7
master
1// vk-api.cpp 2#include "vk-api.h" 3 4#include "core/slang-list.h" 5 6namespace gfx 7{ 8using namespace Slang ; 9 10// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! VulkanApi !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 11 12#define VK_API_CHECK_FUNCTION (x ) &&hasFunction(#x, (void*)x) 13#define VK_API_CHECK_FUNCTIONS (FUNCTION_LIST ) true FUNCTION_LIST(VK_API_CHECK_FUNCTION) 14 15static bool hasFunction (const char * name ,void * ptr ) 16{ 17if (ptr ) 18return true; 19#if 0 20fprintf (stderr ,"Missing required Vulkan function: %s\n" ,name ); 21#endif 22return false; 23} 24 25bool VulkanApi ::areDefined (ProcType type )const 26{ 27switch (type ) 28 { 29case ProcType ::Global : 30return VK_API_CHECK_FUNCTIONS (VK_API_ALL_GLOBAL_PROCS ); 31case ProcType ::Instance : 32return VK_API_CHECK_FUNCTIONS (VK_API_ALL_INSTANCE_PROCS )&& 33VK_API_CHECK_FUNCTIONS (VK_API_INSTANCE_KHR_PROCS ); 34case ProcType ::Device : 35return VK_API_CHECK_FUNCTIONS (VK_API_DEVICE_PROCS ); 36default : 37 { 38assert (!"Unhandled type" ); 39return false; 40 } 41 } 42} 43 44Slang ::Result VulkanApi ::initGlobalProcs (const VulkanModule & module ) 45{ 46#define VK_API_GET_GLOBAL_PROC (x ) x = (PFN_##x)module.getFunction(#x); 47 48// Initialize all the global functions 49VK_API_ALL_GLOBAL_PROCS (VK_API_GET_GLOBAL_PROC ) 50 51if (!areDefined (ProcType ::Global )) 52 { 53return SLANG_FAIL ; 54 } 55m_module = & module ; 56return SLANG_OK ; 57} 58 59Slang ::Result VulkanApi ::initInstanceProcs (VkInstance instance ) 60{ 61assert (instance && vkGetInstanceProcAddr != nullptr ); 62 63#define VK_API_GET_INSTANCE_PROC (x ) x = (PFN_##x)vkGetInstanceProcAddr(instance, #x); 64 65VK_API_ALL_INSTANCE_PROCS (VK_API_GET_INSTANCE_PROC ) 66 67// Get optional 68VK_API_INSTANCE_PROCS_OPT (VK_API_GET_INSTANCE_PROC ) 69 70if (!areDefined (ProcType ::Instance )) 71 { 72return SLANG_FAIL ; 73 } 74 75 76m_instance = instance ; 77return SLANG_OK ; 78} 79 80Slang ::Result VulkanApi ::initPhysicalDevice (VkPhysicalDevice physicalDevice ) 81{ 82assert (m_physicalDevice == VK_NULL_HANDLE ); 83m_physicalDevice = physicalDevice ; 84 85vkGetPhysicalDeviceProperties (m_physicalDevice ,& m_deviceProperties ); 86vkGetPhysicalDeviceFeatures (m_physicalDevice ,& m_deviceFeatures ); 87vkGetPhysicalDeviceMemoryProperties (m_physicalDevice ,& m_deviceMemoryProperties ); 88 89return SLANG_OK ; 90} 91 92Slang ::Result VulkanApi ::initDeviceProcs (VkDevice device ) 93{ 94assert (m_instance && device && vkGetDeviceProcAddr != nullptr ); 95 96#define VK_API_GET_DEVICE_PROC (x ) x = (PFN_##x)vkGetDeviceProcAddr(device, #x); 97 98VK_API_ALL_DEVICE_PROCS (VK_API_GET_DEVICE_PROC ) 99 100if (!areDefined (ProcType ::Device )) 101 { 102return SLANG_FAIL ; 103 } 104 105if (!vkGetBufferDeviceAddressKHR && vkGetBufferDeviceAddressEXT ) 106vkGetBufferDeviceAddressKHR = vkGetBufferDeviceAddressEXT ; 107if (!vkGetBufferDeviceAddress && vkGetBufferDeviceAddressKHR ) 108vkGetBufferDeviceAddress = vkGetBufferDeviceAddressKHR ; 109if (!vkGetSemaphoreCounterValue && vkGetSemaphoreCounterValueKHR ) 110vkGetSemaphoreCounterValue = vkGetSemaphoreCounterValueKHR ; 111if (!vkSignalSemaphore && vkSignalSemaphoreKHR ) 112vkSignalSemaphore = vkSignalSemaphoreKHR ; 113m_device = device ; 114return SLANG_OK ; 115} 116 117int VulkanApi ::findMemoryTypeIndex (uint32_t typeBits ,VkMemoryPropertyFlags properties )const 118{ 119assert (typeBits ); 120 121const int numMemoryTypes = int (m_deviceMemoryProperties .memoryTypeCount ); 122 123// bit holds current test bit against typeBits. Ie bit == 1 << typeBits 124 125uint32_t bit = 1 ; 126for (int i = 0 ;i < numMemoryTypes ;++ i ,bit += bit ) 127 { 128auto const & memoryType = m_deviceMemoryProperties .memoryTypes [i ]; 129if ((typeBits & bit )&& (memoryType .propertyFlags & properties )== properties ) 130 { 131return i ; 132 } 133 } 134 135// assert(!"failed to find a usable memory type"); 136return -1 ; 137} 138 139int VulkanApi ::findQueue (VkQueueFlags reqFlags )const 140{ 141assert (m_physicalDevice != VK_NULL_HANDLE ); 142 143uint32_t numQueueFamilies = 0 ; 144vkGetPhysicalDeviceQueueFamilyProperties (m_physicalDevice ,& numQueueFamilies ,nullptr ); 145 146Slang ::List < VkQueueFamilyProperties > queueFamilies ; 147queueFamilies .setCount (numQueueFamilies ); 148vkGetPhysicalDeviceQueueFamilyProperties ( 149m_physicalDevice , 150& numQueueFamilies , 151queueFamilies .getBuffer ()); 152 153// Find a queue that can service our needs 154// VkQueueFlags reqQueueFlags = VK_QUEUE_GRAPHICS_BIT | VK_QUEUE_COMPUTE_BIT; 155 156int queueFamilyIndex = -1 ; 157for (int i = 0 ;i < int (numQueueFamilies );++ i ) 158 { 159if ((queueFamilies [i ].queueFlags & reqFlags )== reqFlags ) 160 { 161return i ; 162 } 163 } 164 165return -1 ; 166} 167 168}// namespace gfx