Harbor

branch main
showing the latest snapshot on main
commands.odin 2.3 KB · Plain text
core/commands.odin 0644 Raw
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)
}