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 }