yum-mirror/slang

Making it easier to work with shaders

git clone https://git.yummers.dev/yum-mirror/slang

Jay KwakCheck the available VK extensions before using CoopVec APIs in GFX (#6849)591affaf7

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