1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
package gpu_core
import "core:log"
import vk "vendor:vulkan"
create_command_pool :: proc(dev: ^Gpu_Device, queue_family: u32) -> (pool: vk.CommandPool, ok: bool) {
info := vk.CommandPoolCreateInfo{
sType = .COMMAND_POOL_CREATE_INFO,
flags = {.RESET_COMMAND_BUFFER},
queueFamilyIndex = queue_family,
}
result := vk.CreateCommandPool(dev.device, &info, nil, &pool)
if result != .SUCCESS {
log.errorf("gpu/core: vkCreateCommandPool failed: %v", result)
return 0, false
}
return pool, true
}
allocate_command_buffers :: proc(dev: ^Gpu_Device, pool: vk.CommandPool, count: u32) -> (bufs: []vk.CommandBuffer, ok: bool) {
bufs = make([]vk.CommandBuffer, count)
alloc_info := vk.CommandBufferAllocateInfo{
sType = .COMMAND_BUFFER_ALLOCATE_INFO,
commandPool = pool,
level = .PRIMARY,
commandBufferCount = count,
}
result := vk.AllocateCommandBuffers(dev.device, &alloc_info, raw_data(bufs))
if result != .SUCCESS {
log.errorf("gpu/core: vkAllocateCommandBuffers failed: %v", result)
delete(bufs)
return nil, false
}
return bufs, true
}
// Begin a single-use command buffer for transfer operations
begin_single_time_commands :: proc(dev: ^Gpu_Device, pool: vk.CommandPool) -> (cmd: vk.CommandBuffer, ok: bool) {
alloc_info := vk.CommandBufferAllocateInfo{
sType = .COMMAND_BUFFER_ALLOCATE_INFO,
commandPool = pool,
level = .PRIMARY,
commandBufferCount = 1,
}
result := vk.AllocateCommandBuffers(dev.device, &alloc_info, &cmd)
if result != .SUCCESS {
return nil, false
}
begin_info := vk.CommandBufferBeginInfo{
sType = .COMMAND_BUFFER_BEGIN_INFO,
flags = {.ONE_TIME_SUBMIT},
}
result = vk.BeginCommandBuffer(cmd, &begin_info)
if result != .SUCCESS {
return nil, false
}
return cmd, true
}
// End and submit a single-use command buffer, wait for completion
end_single_time_commands :: proc(dev: ^Gpu_Device, pool: vk.CommandPool, queue: vk.Queue, cmd: vk.CommandBuffer) {
vk.EndCommandBuffer(cmd)
cmd_buf := cmd
submit_info := vk.SubmitInfo{
sType = .SUBMIT_INFO,
commandBufferCount = 1,
pCommandBuffers = &cmd_buf,
}
vk.QueueSubmit(queue, 1, &submit_info, 0)
vk.QueueWaitIdle(queue)
vk.FreeCommandBuffers(dev.device, pool, 1, &cmd_buf)
}