Skip to content

Commit e2e00c3

Browse files
committed
vk instance and device bindings
1 parent 1027057 commit e2e00c3

File tree

2 files changed

+149
-69
lines changed

2 files changed

+149
-69
lines changed

src/bindings/vk.lua

Lines changed: 138 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ ffi.cdef([[
1212
typedef VkFlags VkSampleCountFlags;
1313
typedef uint64_t VkDeviceSize;
1414
typedef uint32_t VkPhysicalDeviceType;
15+
typedef uint64_t VkBuffer;
16+
typedef VkFlags VkBufferCreateFlags;
17+
typedef VkFlags VkBufferUsageFlags;
18+
typedef uint32_t VkSharingMode;
1519
1620
typedef struct {
1721
VkStructureType sType;
@@ -249,43 +253,55 @@ ffi.cdef([[
249253
const VkPhysicalDeviceFeatures* pEnabledFeatures;
250254
} VkDeviceCreateInfo;
251255
252-
VkResult vkCreateDevice(
253-
VkPhysicalDevice physicalDevice,
254-
const VkDeviceCreateInfo* pCreateInfo,
255-
const void* pAllocator,
256-
VkDevice* pDevice
257-
);
256+
typedef struct {
257+
VkStructureType sType;
258+
const void* pNext;
259+
VkBufferCreateFlags flags;
260+
VkDeviceSize size;
261+
VkBufferUsageFlags usage;
262+
VkSharingMode sharingMode;
263+
uint32_t queueFamilyIndexCount;
264+
const uint32_t* pQueueFamilyIndices;
265+
} VkBufferCreateInfo;
258266
259267
VkResult vkGetPhysicalDeviceProperties(
260268
VkPhysicalDevice physicalDevice,
261269
VkPhysicalDeviceProperties* pProperties
262270
);
263271
]])
264272

273+
---@class vk.BaseStruct
274+
---@field sType vk.StructureType?
275+
---@field pNext userdata?
276+
---@field flags number?
277+
265278
---@class vk.Instance: number
266279
---@class vk.Result: number
267280
---@class vk.PhysicalDevice: ffi.cdata*
268281
---@class vk.Device: number
282+
---@class vk.Buffer*: ffi.cdata*
269283

270-
---@class vk.CreateInstanceInput
271-
---@field pNext userdata?
272-
---@field flags number?
284+
---@class vk.InstanceCreateInfoStruct: vk.BaseStruct
273285
---@field pApplicationInfo userdata?
274286
---@field enabledLayerCount number?
275287
---@field ppEnabledLayerNames userdata?
276288
---@field enabledExtensionCount number?
277289
---@field ppEnabledExtensionNames userdata?
278290

279-
---@class vk.DeviceCreateInfoStruct
280-
---@field sType vk.StructureType
281-
---@field pNext userdata?
282-
---@field flags number
283-
---@field queueCreateInfoCount number
291+
---@class vk.DeviceCreateInfoStruct: vk.BaseStruct
292+
---@field queueCreateInfoCount number?
284293
---@field pQueueCreateInfos userdata?
285-
---@field enabledExtensionCount number
294+
---@field enabledExtensionCount number?
286295
---@field ppEnabledExtensionNames userdata?
287296
---@field pEnabledFeatures userdata?
288297

298+
---@class vk.BufferCreateInfoStruct: vk.BaseStruct
299+
---@field size number
300+
---@field usage vk.BufferUsage
301+
---@field sharingMode vk.SharingMode?
302+
---@field queueFamilyIndexCount number?
303+
---@field pQueueFamilyIndices userdata?
304+
289305
---@class vk.PhysicalDeviceProperties: ffi.cdata*
290306
---@field apiVersion number
291307
---@field driverVersion number
@@ -297,35 +313,27 @@ ffi.cdef([[
297313
---@field limits ffi.cdata*
298314
---@field sparseProperties ffi.cdata*
299315

300-
local core = {
316+
local vkGlobal = {
301317
---@enum vk.StructureType
302318
StructureType = {
303319
APPLICATION_INFO = 0,
304320
INSTANCE_CREATE_INFO = 1,
305321
DEVICE_QUEUE_CREATE_INFO = 2,
306322
DEVICE_CREATE_INFO = 3,
307-
},
308-
309-
---@enum vk.PhysicalDeviceType
310-
PhysicalDeviceType = {
311-
OTHER = 0,
312-
INTEGRATED_GPU = 1,
313-
DISCRETE_GPU = 2,
314-
VIRTUAL_GPU = 3,
315-
CPU = 4,
323+
BUFFER_CREATE_INFO = 12,
316324
},
317325
}
318326

319327
do
320328
local C = ffi.load("vulkan")
321329

322-
---@param info vk.CreateInstanceInput
330+
---@param info vk.InstanceCreateInfoStruct
323331
---@param allocator ffi.cdata*?
324332
---@return vk.Instance
325-
function core.createInstance(info, allocator)
333+
function vkGlobal.createInstance(info, allocator)
326334
local instance = ffi.new("VkInstance[1]")
327335
local info = ffi.new("VkInstanceCreateInfo", info)
328-
info.sType = core.StructureType.INSTANCE_CREATE_INFO
336+
info.sType = vkGlobal.StructureType.INSTANCE_CREATE_INFO
329337

330338
local result = C.vkCreateInstance(info, allocator, instance)
331339
if result ~= 0 then
@@ -337,7 +345,7 @@ do
337345

338346
---@param instance vk.Instance
339347
---@return vk.PhysicalDevice[]
340-
function core.enumeratePhysicalDevices(instance)
348+
function vkGlobal.enumeratePhysicalDevices(instance)
341349
local deviceCount = ffi.new("uint32_t[1]", 0)
342350
local result = C.vkEnumeratePhysicalDevices(instance, deviceCount, nil)
343351
if result ~= 0 then
@@ -359,12 +367,38 @@ do
359367
end
360368

361369
---@param physicalDevice vk.PhysicalDevice
362-
---@param info vk.DeviceCreateInfoStruct
370+
function vkGlobal.getPhysicalDeviceProperties(physicalDevice)
371+
local properties = ffi.new("VkPhysicalDeviceProperties")
372+
C.vkGetPhysicalDeviceProperties(physicalDevice, properties)
373+
return properties --[[@as vk.PhysicalDeviceProperties]]
374+
end
375+
376+
vkGlobal.getInstanceProcAddr = C.vkGetInstanceProcAddr
377+
vkGlobal.getDeviceProcAddr = C.vkGetDeviceProcAddr
378+
end
379+
380+
local globalInstance = vkGlobal.createInstance({})
381+
local globalPhysicalDevice = vkGlobal.enumeratePhysicalDevices(globalInstance)[1]
382+
383+
local vkInstance = {}
384+
do
385+
local types = {
386+
vkCreateDevice = "VkDevice(*)(VkPhysicalDevice, const VkDeviceCreateInfo*, const void*, VkDevice*)",
387+
}
388+
389+
local C = {}
390+
for name, funcType in pairs(types) do
391+
C[name] = ffi.cast(funcType, vkGlobal.getInstanceProcAddr(globalInstance, name))
392+
end
393+
394+
---@param physicalDevice vk.PhysicalDevice
395+
---@param info vk.DeviceCreateInfoStruct?
363396
---@param allocator ffi.cdata*?
364397
---@return vk.Device
365-
function core.createDevice(physicalDevice, info, allocator)
398+
function vkInstance.createDevice(physicalDevice, info, allocator)
366399
local device = ffi.new("VkDevice[1]")
367-
local info = ffi.new("VkDeviceCreateInfo", info)
400+
local info = ffi.new("VkDeviceCreateInfo", info or {})
401+
info.sType = vkGlobal.StructureType.DEVICE_CREATE_INFO
368402

369403
local result = C.vkCreateDevice(physicalDevice, info, allocator, device)
370404
if result ~= 0 then
@@ -373,50 +407,88 @@ do
373407

374408
return device[0]
375409
end
410+
end
376411

377-
---@param physicalDevice vk.PhysicalDevice
378-
function core.getPhysicalDeviceProperties(physicalDevice)
379-
local properties = ffi.new("VkPhysicalDeviceProperties")
380-
C.vkGetPhysicalDeviceProperties(physicalDevice, properties)
381-
return properties --[[@as vk.PhysicalDeviceProperties]]
412+
local globalDevice = vkInstance.createDevice(globalPhysicalDevice, {})
413+
414+
local vkDevice = {}
415+
do
416+
local types = {
417+
vkCreateBuffer = "VkResult(*)(VkDevice, const VkBufferCreateInfo*, const void*, VkBuffer*)",
418+
}
419+
420+
local C = {}
421+
for name, funcType in pairs(types) do
422+
C[name] = ffi.cast(funcType, vkGlobal.getDeviceProcAddr(globalDevice, name))
382423
end
383424

384-
core.getInstanceProcAddr = C.vkGetInstanceProcAddr
385-
core.getDeviceProcAddr = C.vkGetDeviceProcAddr
425+
vkDevice.vkCreateBuffer = C.vkCreateBuffer
386426
end
387427

388-
local globalInstance ---@type vk.Instance
428+
local vk = {}
429+
430+
-- Globals
389431
do
390-
local pCreateInfo = ffi.new("VkInstanceCreateInfo", {
391-
sType = 1, -- VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO
392-
pNext = nil,
393-
flags = 0,
394-
pApplicationInfo = nil,
395-
enabledLayerCount = 0,
396-
ppEnabledLayerNames = nil,
397-
enabledExtensionCount = 0,
398-
ppEnabledExtensionNames = nil,
399-
})
400-
401-
globalInstance = core.createInstance(pCreateInfo, nil)
432+
vk.StructureType = vkGlobal.StructureType
433+
434+
---@enum vk.PhysicalDeviceType
435+
vk.PhysicalDeviceType = {
436+
OTHER = 0,
437+
INTEGRATED_GPU = 1,
438+
DISCRETE_GPU = 2,
439+
VIRTUAL_GPU = 3,
440+
CPU = 4,
441+
}
442+
443+
---@enum vk.BufferUsage
444+
vk.BufferUsage = {
445+
TRANSFER_SRC = 0x00000001,
446+
TRANSFER_DST = 0x00000002,
447+
UNIFORM_TEXEL_BUFFER = 0x00000004,
448+
STORAGE_TEXEL_BUFFER = 0x00000008,
449+
UNIFORM_BUFFER = 0x00000010,
450+
STORAGE_BUFFER = 0x00000020,
451+
INDEX_BUFFER = 0x00000040,
452+
VERTEX_BUFFER = 0x00000080,
453+
INDIRECT_BUFFER = 0x00000100,
454+
}
455+
456+
---@enum vk.SharingMode
457+
vk.SharingMode = {
458+
EXCLUSIVE = 0,
459+
CONCURRENT = 1,
460+
}
461+
462+
vk.getPhysicalDeviceProperties = vkGlobal.getPhysicalDeviceProperties
402463
end
403464

404-
local functionTypes = {}
465+
-- Instance
466+
do
467+
function vk.enumeratePhysicalDevices()
468+
return vkGlobal.enumeratePhysicalDevices(globalInstance)
469+
end
405470

406-
local C = {}
407-
for name, funcType in pairs(functionTypes) do
408-
C[name] = ffi.cast(funcType, core.getInstanceProcAddr(globalInstance, name))
471+
vk.createDevice = vkInstance.createDevice
409472
end
410473

474+
-- Device
475+
do
476+
---@param device vk.Device
477+
---@param info vk.BufferCreateInfoStruct
478+
---@param allocator ffi.cdata*?
479+
---@return vk.Buffer*
480+
function vk.createBuffer(device, info, allocator)
481+
local info = ffi.new("VkBufferCreateInfo", info)
482+
info.sType = vk.StructureType.BUFFER_CREATE_INFO
483+
484+
local buffer = ffi.new("VkBuffer[1]")
485+
local result = vkDevice.vkCreateBuffer(device, info, allocator, buffer)
486+
if result ~= 0 then
487+
error("Failed to create Vulkan buffer, error code: " .. tostring(result))
488+
end
411489

412-
return {
413-
StructureType = core.StructureType,
414-
PhysicalDeviceType = core.PhysicalDeviceType,
490+
return buffer[0]
491+
end
492+
end
415493

416-
createInstance = core.createInstance,
417-
enumeratePhysicalDevices = core.enumeratePhysicalDevices,
418-
createDevice = core.createDevice,
419-
getInstanceProcAddr = core.getInstanceProcAddr,
420-
getDeviceProcAddr = core.getDeviceProcAddr,
421-
getPhysicalDeviceProperties = core.getPhysicalDeviceProperties,
422-
}
494+
return vk

src/main.lua

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -973,11 +973,19 @@ end
973973
local vk = require("bindings.vk")
974974
local ffi = require("ffi")
975975

976-
local instance = vk.createInstance({})
977-
for _, physicalDevice in ipairs(vk.enumeratePhysicalDevices(instance)) do
976+
local gpuDevice ---@type vk.PhysicalDevice?
977+
for _, physicalDevice in ipairs(vk.enumeratePhysicalDevices()) do
978978
local properties = vk.getPhysicalDeviceProperties(physicalDevice)
979+
if properties.deviceType == vk.PhysicalDeviceType.DISCRETE_GPU then
980+
gpuDevice = physicalDevice
981+
break
982+
end
983+
end
979984

980-
print(ffi.string(properties.deviceName), properties.deviceType == vk.PhysicalDeviceType.DISCRETE_GPU)
985+
if gpuDevice then
986+
print("Using discrete GPU for compute")
987+
local device = vk.createDevice(gpuDevice)
988+
local buffer = vk.createBuffer(device, { size = 200, usage = vk.BufferUsage.STORAGE_BUFFER })
981989
end
982990

983991
Arisu.run(App)

0 commit comments

Comments
 (0)