@@ -17,6 +17,69 @@ local res = build_lua(
1717 c_header ,
1818 parser :GetExpandedDefinitions (),
1919 [[
20+
21+ do
22+ local cache = {}
23+ function mod.EnumToString(enum_type, index)
24+ if not index then
25+ index = tonumber(enum_type)
26+ end
27+ local enum_id = tonumber(ffi.typeof(enum_type))
28+
29+ if cache[enum_id] ~= nil then return cache[enum_id] end
30+
31+ local enum_ctype = ffi.typeinfo(enum_id)
32+ local current_index = 0
33+ local sib = enum_ctype.sib
34+
35+ while sib do
36+ local sib_ctype = ffi.typeinfo(sib)
37+ local CT_code = bit.rshift(sib_ctype.info, 28)
38+
39+ if CT_code == 11 then -- constant
40+ if current_index == index then
41+ cache[enum_id] = sib_ctype.name
42+ return cache[enum_id]
43+ end
44+
45+ current_index = current_index + 1
46+ end
47+
48+ sib = sib_ctype.sib
49+ end
50+
51+ cache[enum_id] = false
52+
53+ return nil
54+ end
55+ end
56+
57+ do
58+ local t_cache = {}
59+
60+ local function array_type(t, len)
61+ if len then
62+ t_cache[t] = t_cache[t] or ffi.typeof("$[" .. len .. "]", t)
63+ return t_cache[t]
64+ end
65+
66+ t_cache[t] = t_cache[t] or ffi.typeof("$[?]", t)
67+ return t_cache[t]
68+ end
69+
70+ function mod.Array(t, len, ctor)
71+ if ctor then return array_type(t, len)(ctor) end
72+
73+ return array_type(t, len)
74+ end
75+
76+ function mod.Box(t, ctor)
77+ if ctor then return array_type(t, 1)({ctor}) end
78+
79+ return array_type(t, 1)
80+ end
81+ end
82+
2083 function mod.find_library()
2184 local function try_load(tbl)
2285 local errors = {}
@@ -64,101 +127,88 @@ local res = build_lua(
64127local f = io.open (" vulkan.lua" , " w" )
65128f :write (res )
66129f :close ()
130+ local ffi = require (" ffi" )
67131
68132do
69- local ffi = require (" ffi" )
70133 local vk = require (" vulkan" )
71134 local lib = vk .find_library ()
72- -- Simple Vulkan example: Query physical device properties
73- print (" \n === Vulkan Physical Device Query ===\n " )
74- -- Create a Vulkan instance
75- local VkApplicationInfoBox = ffi .typeof (" $[1]" , vk .VkApplicationInfo )
76- local appInfo = VkApplicationInfoBox ()
77- appInfo [0 ].sType = 0 -- VK_STRUCTURE_TYPE_APPLICATION_INFO
78- appInfo [0 ].pApplicationName = " NattLua Vulkan Test"
79- appInfo [0 ].applicationVersion = 1
80- appInfo [0 ].pEngineName = " No Engine"
81- appInfo [0 ].engineVersion = 1
82- appInfo [0 ].apiVersion = vk .VK_API_VERSION_1_0
83- -- Create info struct - initialize with table to avoid const issues
84- local VkInstanceCreateInfoBox = ffi .typeof (" $[1]" , vk .VkInstanceCreateInfo )
85- local createInfo = VkInstanceCreateInfoBox (
135+ local appInfo = vk .Box (
136+ vk .VkApplicationInfo ,
86137 {
87- {
88- sType = " VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO" ,
89- pNext = nil ,
90- flags = 0 ,
91- pApplicationInfo = appInfo ,
92- enabledLayerCount = 0 ,
93- ppEnabledLayerNames = nil ,
94- enabledExtensionCount = 0 ,
95- ppEnabledExtensionNames = nil ,
96- },
138+ sType = " VK_STRUCTURE_TYPE_APPLICATION_INFO" ,
139+ pApplicationName = " NattLua Vulkan Test" ,
140+ applicationVersion = 1 ,
141+ pEngineName = " No Engine" ,
142+ engineVersion = 1 ,
143+ apiVersion = vk .VK_API_VERSION_1_0 ,
97144 }
98145 )
99- local VkInstanceBox = ffi .typeof (" $[1]" , vk .VkInstance )
100- local instance = VkInstanceBox ()
146+ local createInfo = vk .Box (
147+ vk .VkInstanceCreateInfo ,
148+ {
149+ sType = " VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO" ,
150+ pNext = nil ,
151+ flags = 0 ,
152+ pApplicationInfo = appInfo ,
153+ enabledLayerCount = 0 ,
154+ ppEnabledLayerNames = nil ,
155+ enabledExtensionCount = 0 ,
156+ ppEnabledExtensionNames = nil ,
157+ }
158+ )
159+ local instance = vk .Box (vk .VkInstance )()
101160 local result = lib .vkCreateInstance (createInfo , nil , instance )
102161
103162 if result ~= 0 then
104- print (" Failed to create Vulkan instance. Error code: " .. tostring (result ))
105- os.exit (1 )
163+ error (" failed to create vulkan instance: " .. vk .EnumToString (result ))
106164 end
107165
108- print (" ✓ Created Vulkan instance successfully" )
109- -- Enumerate physical devices
166+ print (" vulkan instance created successfully: " .. vk .EnumToString (result ))
110167 local deviceCount = ffi .new (" uint32_t[1]" , 0 )
111168 result = lib .vkEnumeratePhysicalDevices (instance [0 ], deviceCount , nil )
112169
113- if result ~= 0 or deviceCount [0 ] == 0 then
114- print (" No Vulkan devices found!" )
115- os.exit (1 )
116- end
170+ if result ~= 0 or deviceCount [0 ] == 0 then error (" devices found" ) end
117171
118- print (string.format (" ✓ Found %d physical device(s)" , deviceCount [0 ]))
119- local VkPhysicalDeviceArray = ffi .typeof (" $[?]" , vk .VkPhysicalDevice )
120- local devices = VkPhysicalDeviceArray (deviceCount [0 ])
172+ print (string.format (" found %d physical device(s)" , deviceCount [0 ]))
173+ local devices = vk .Array (vk .VkPhysicalDevice )(deviceCount [0 ])
121174 result = lib .vkEnumeratePhysicalDevices (instance [0 ], deviceCount , devices )
122- local VkPhysicalDevicePropertiesBox = ffi .typeof (" $[1]" , vk .VkPhysicalDeviceProperties )
123175
124- -- Query properties for each device
125176 for i = 0 , deviceCount [0 ] - 1 do
126- local properties = VkPhysicalDevicePropertiesBox ()
177+ local properties = vk . Box ( vk . VkPhysicalDeviceProperties ) ()
127178 lib .vkGetPhysicalDeviceProperties (devices [i ], properties )
128- local deviceName = ffi .string (properties [0 ].deviceName )
129- local apiVersion = properties [0 ].apiVersion
130- local driverVersion = properties [0 ].driverVersion
131- local vendorID = properties [0 ].vendorID
132- local deviceID = properties [0 ].deviceID
179+ local props = properties [0 ]
133180 -- Decode API version (major.minor.patch)
134- local apiMajor = bit .rshift (apiVersion , 22 )
135- local apiMinor = bit .band (bit .rshift (apiVersion , 12 ), 0x3FF )
136- local apiPatch = bit .band (apiVersion , 0xFFF )
137- print (string.format (" \n Device %d:" , i ))
138- print (string.format (" Name: %s" , deviceName ))
139- print (string.format (" API Version: %d.%d.%d" , apiMajor , apiMinor , apiPatch ))
140- print (string.format (" Driver Version: 0x%08X" , driverVersion ))
141- print (string.format (" Vendor ID: 0x%04X" , vendorID ))
142- print (string.format (" Device ID: 0x%04X" , deviceID ))
143- print (string.format (" Device Type: %d" , tonumber (properties [0 ].deviceType )))
181+ print (string.format (" device %d:" , i ))
182+ print (string.format (" name: %s" , ffi .string (props .deviceName )))
183+ local apiVersion = props .apiVersion
184+ print (
185+ string.format (
186+ " api version: %d.%d.%d" ,
187+ bit .rshift (apiVersion , 22 ),
188+ bit .band (bit .rshift (apiVersion , 12 ), 0x3FF ),
189+ bit .band (apiVersion , 0xFFF )
190+ )
191+ )
192+ print (string.format (" driver version: 0x%08X" , props .driverVersion ))
193+ print (string.format (" vendor id: 0x%04X" , props .vendorID ))
194+ print (string.format (" device id: 0x%04X" , props .deviceID ))
195+ print (string.format (" device type: %s" , vk .EnumToString (props .deviceType )))
144196 -- Print some limits
145- local limits = properties [ 0 ] .limits
146- print (string.format (" Max Image Dimension 2D: %d" , tonumber (limits .maxImageDimension2D )))
197+ local limits = props .limits
198+ print (string.format (" max image dimension 2D: %d" , tonumber (limits .maxImageDimension2D )))
147199 print (
148200 string.format (
149- " Max Compute Shared Memory Size : %d bytes" ,
201+ " max compute shared memory size : %d bytes" ,
150202 tonumber (limits .maxComputeSharedMemorySize )
151203 )
152204 )
153205 print (
154206 string.format (
155- " Max Compute Work Group Count : [%d, %d, %d]" ,
207+ " max compute work group count : [%d, %d, %d]" ,
156208 tonumber (limits .maxComputeWorkGroupCount [0 ]),
157209 tonumber (limits .maxComputeWorkGroupCount [1 ]),
158210 tonumber (limits .maxComputeWorkGroupCount [2 ])
159211 )
160212 )
161213 end
162-
163- print (" \n === Query Complete ===\n " )
164214end
0 commit comments