Harbor

branch main
showing the latest snapshot on main
vk_convert.odin 6.9 KB · Plain text
backend/vulkan/vk_convert.odin 0644 Raw
package vk_backend

import bk ".."
import vk "vendor:vulkan"

// --- Format conversion ---

@(private)
to_vk_format :: proc(fmt: bk.Format) -> vk.Format {
	switch fmt {
	case .Undefined:
		return .UNDEFINED
	case .R8G8B8A8_SRGB:
		return .R8G8B8A8_SRGB
	case .R8G8B8A8_UNORM:
		return .R8G8B8A8_UNORM
	case .B8G8R8A8_SRGB:
		return .B8G8R8A8_SRGB
	case .D32_SFLOAT:
		return .D32_SFLOAT
	case .D32_SFLOAT_S8_UINT:
		return .D32_SFLOAT_S8_UINT
	case .D24_UNORM_S8_UINT:
		return .D24_UNORM_S8_UINT
	}
	return .UNDEFINED
}

@(private)
from_vk_format :: proc(fmt: vk.Format) -> bk.Format {
	#partial switch fmt {
	case .R8G8B8A8_SRGB:
		return .R8G8B8A8_SRGB
	case .R8G8B8A8_UNORM:
		return .R8G8B8A8_UNORM
	case .B8G8R8A8_SRGB:
		return .B8G8R8A8_SRGB
	case .D32_SFLOAT:
		return .D32_SFLOAT
	case .D32_SFLOAT_S8_UINT:
		return .D32_SFLOAT_S8_UINT
	case .D24_UNORM_S8_UINT:
		return .D24_UNORM_S8_UINT
	case:
		return .Undefined
	}
}

// --- Buffer/memory conversion ---

@(private)
to_vk_buffer_usage :: proc(flags: bk.Buffer_Usage_Flags) -> vk.BufferUsageFlags {
	result: vk.BufferUsageFlags
	if .Vertex in flags {result += {.VERTEX_BUFFER}}
	if .Index in flags {result += {.INDEX_BUFFER}}
	if .Uniform in flags {result += {.UNIFORM_BUFFER}}
	if .Storage in flags {result += {.STORAGE_BUFFER}}
	if .Indirect_Argument in flags {result += {.INDIRECT_BUFFER}}
	if .Transfer_Src in flags {result += {.TRANSFER_SRC}}
	if .Transfer_Dst in flags {result += {.TRANSFER_DST}}
	return result
}

@(private)
to_vk_memory_properties :: proc(flags: bk.Memory_Property_Flags) -> vk.MemoryPropertyFlags {
	result: vk.MemoryPropertyFlags
	if .Device_Local in flags {result += {.DEVICE_LOCAL}}
	if .Host_Visible in flags {result += {.HOST_VISIBLE}}
	if .Host_Coherent in flags {result += {.HOST_COHERENT}}
	return result
}

// --- Pipeline state conversion ---

@(private)
to_vk_topology :: proc(t: bk.Topology) -> vk.PrimitiveTopology {
	switch t {
	case .Triangle_List:
		return .TRIANGLE_LIST
	case .Triangle_Strip:
		return .TRIANGLE_STRIP
	case .Line_List:
		return .LINE_LIST
	case .Point_List:
		return .POINT_LIST
	}
	return .TRIANGLE_LIST
}

@(private)
to_vk_cull_mode :: proc(c: bk.Cull_Mode) -> vk.CullModeFlags {
	switch c {
	case .None:
		return {}
	case .Front:
		return {.FRONT}
	case .Back:
		return {.BACK}
	case .Front_And_Back:
		return {.FRONT, .BACK}
	}
	return {}
}

@(private)
to_vk_front_face :: proc(f: bk.Front_Face) -> vk.FrontFace {
	switch f {
	case .Counter_Clockwise:
		return .COUNTER_CLOCKWISE
	case .Clockwise:
		return .CLOCKWISE
	}
	return .COUNTER_CLOCKWISE
}

@(private)
to_vk_shader_stages :: proc(flags: bk.Shader_Stage_Flags) -> vk.ShaderStageFlags {
	result: vk.ShaderStageFlags
	if .Vertex in flags {result += {.VERTEX}}
	if .Fragment in flags {result += {.FRAGMENT}}
	if .Compute in flags {result += {.COMPUTE}}
	return result
}

// --- Image conversion ---

@(private)
to_vk_image_usage :: proc(flags: bk.Image_Usage_Flags) -> vk.ImageUsageFlags {
	result: vk.ImageUsageFlags
	if .Sampled in flags {result += {.SAMPLED}}
	if .Color_Attachment in flags {result += {.COLOR_ATTACHMENT}}
	if .Depth_Stencil_Attachment in flags {result += {.DEPTH_STENCIL_ATTACHMENT}}
	if .Transfer_Dst in flags {result += {.TRANSFER_DST}}
	if .Transfer_Src in flags {result += {.TRANSFER_SRC}}
	return result
}

@(private)
to_vk_image_aspect :: proc(flags: bk.Image_Aspect_Flags) -> vk.ImageAspectFlags {
	result: vk.ImageAspectFlags
	if .Color in flags {result += {.COLOR}}
	if .Depth in flags {result += {.DEPTH}}
	if .Stencil in flags {result += {.STENCIL}}
	return result
}

@(private)
to_vk_image_layout :: proc(l: bk.Image_Layout) -> vk.ImageLayout {
	switch l {
	case .Undefined:
		return .UNDEFINED
	case .Color_Attachment:
		return .COLOR_ATTACHMENT_OPTIMAL
	case .Depth_Stencil_Attachment:
		return .DEPTH_STENCIL_ATTACHMENT_OPTIMAL
	case .Shader_Read_Only:
		return .SHADER_READ_ONLY_OPTIMAL
	case .Depth_Stencil_Read_Only:
		return .DEPTH_STENCIL_READ_ONLY_OPTIMAL
	case .Transfer_Dst:
		return .TRANSFER_DST_OPTIMAL
	case .Present_Src:
		return .PRESENT_SRC_KHR
	}
	return .UNDEFINED
}

@(private)
to_vk_attachment_load_op :: proc(op: bk.Attachment_Load_Op) -> vk.AttachmentLoadOp {
	switch op {
	case .Load:
		return .LOAD
	case .Clear:
		return .CLEAR
	case .Dont_Care:
		return .DONT_CARE
	}
	return .LOAD
}

@(private)
to_vk_attachment_store_op :: proc(op: bk.Attachment_Store_Op) -> vk.AttachmentStoreOp {
	switch op {
	case .Store:
		return .STORE
	case .Dont_Care:
		return .DONT_CARE
	}
	return .STORE
}

// --- Sampler conversion ---

@(private)
to_vk_filter :: proc(f: bk.Filter) -> vk.Filter {
	switch f {
	case .Nearest:
		return .NEAREST
	case .Linear:
		return .LINEAR
	}
	return .LINEAR
}

@(private)
to_vk_address_mode :: proc(m: bk.Address_Mode) -> vk.SamplerAddressMode {
	switch m {
	case .Repeat:
		return .REPEAT
	case .Clamp_To_Edge:
		return .CLAMP_TO_EDGE
	case .Clamp_To_Border:
		return .CLAMP_TO_BORDER
	}
	return .REPEAT
}

@(private)
to_vk_compare_op :: proc(op: bk.Compare_Op) -> vk.CompareOp {
	switch op {
	case .Never:
		return .NEVER
	case .Less:
		return .LESS
	case .Less_Or_Equal:
		return .LESS_OR_EQUAL
	case .Equal:
		return .EQUAL
	case .Greater_Or_Equal:
		return .GREATER_OR_EQUAL
	case .Greater:
		return .GREATER
	case .Not_Equal:
		return .NOT_EQUAL
	case .Always:
		return .ALWAYS
	}
	return .ALWAYS
}

@(private)
to_vk_stencil_op :: proc(op: bk.Stencil_Op) -> vk.StencilOp {
	switch op {
	case .Keep:
		return .KEEP
	case .Zero:
		return .ZERO
	case .Replace:
		return .REPLACE
	case .Increment_Clamp:
		return .INCREMENT_AND_CLAMP
	case .Decrement_Clamp:
		return .DECREMENT_AND_CLAMP
	case .Invert:
		return .INVERT
	}
	return .KEEP
}

@(private)
to_vk_stencil_face :: proc(face: bk.Stencil_Face_State, state: bk.Stencil_State) -> vk.StencilOpState {
	return {
		failOp      = to_vk_stencil_op(face.fail_op),
		passOp      = to_vk_stencil_op(face.pass_op),
		depthFailOp = to_vk_stencil_op(face.depth_fail_op),
		compareOp   = to_vk_compare_op(face.compare_op),
		compareMask = u32(state.read_mask),
		writeMask   = u32(state.write_mask),
		reference   = u32(state.reference),
	}
}

// --- Descriptor conversion ---

@(private)
to_vk_descriptor_type :: proc(t: bk.Descriptor_Type) -> vk.DescriptorType {
	switch t {
	case .Combined_Image_Sampler:
		return .COMBINED_IMAGE_SAMPLER
	case .Uniform_Buffer:
		return .UNIFORM_BUFFER
	case .Storage_Buffer:
		return .STORAGE_BUFFER
	}
	return .COMBINED_IMAGE_SAMPLER
}

// --- Vertex format conversion ---

@(private)
to_vk_vertex_format :: proc(fmt: bk.Vertex_Format) -> vk.Format {
	switch fmt {
	case .Float2:
		return .R32G32_SFLOAT
	case .Float3:
		return .R32G32B32_SFLOAT
	case .Float4:
		return .R32G32B32A32_SFLOAT
	}
	return .UNDEFINED
}

// --- Helpers ---

@(private)
format_pixel_size :: proc(fmt: bk.Format) -> u32 {
	switch fmt {
	case .R8G8B8A8_SRGB, .R8G8B8A8_UNORM, .B8G8R8A8_SRGB:
		return 4
	case .D32_SFLOAT:
		return 4
	case .D32_SFLOAT_S8_UINT:
		return 8
	case .D24_UNORM_S8_UINT:
		return 4
	case .Undefined:
		return 0
	}
	return 0
}