package d3d12_backend import d3d12 "vendor:directx/d3d12" import dxgi "vendor:directx/dxgi" import bk ".." // --- Format conversion --- @(private) to_dxgi_format :: proc(fmt: bk.Format) -> dxgi.FORMAT { switch fmt { case .Undefined: return .UNKNOWN case .R8G8B8A8_SRGB: return .R8G8B8A8_UNORM_SRGB case .R8G8B8A8_UNORM: return .R8G8B8A8_UNORM case .B8G8R8A8_SRGB: return .B8G8R8A8_UNORM_SRGB case .D32_SFLOAT: return .D32_FLOAT case .D32_SFLOAT_S8_UINT: return .D32_FLOAT_S8X24_UINT case .D24_UNORM_S8_UINT: return .D24_UNORM_S8_UINT } return .UNKNOWN } @(private) from_dxgi_format :: proc(fmt: dxgi.FORMAT) -> bk.Format { #partial switch fmt { case .R8G8B8A8_UNORM_SRGB: return .R8G8B8A8_SRGB case .R8G8B8A8_UNORM: return .R8G8B8A8_UNORM case .B8G8R8A8_UNORM_SRGB: return .B8G8R8A8_SRGB case .D32_FLOAT: return .D32_SFLOAT case .D32_FLOAT_S8X24_UINT: return .D32_SFLOAT_S8_UINT case .D24_UNORM_S8_UINT: return .D24_UNORM_S8_UINT case: return .Undefined } } // --- Topology conversion (PSO type) --- @(private) to_d3d12_topology_type :: proc(t: bk.Topology) -> d3d12.PRIMITIVE_TOPOLOGY_TYPE { switch t { case .Triangle_List, .Triangle_Strip: return .TRIANGLE case .Line_List: return .LINE case .Point_List: return .POINT } return .TRIANGLE } // --- Topology conversion (draw-time) --- @(private) to_d3d12_topology :: proc(t: bk.Topology) -> d3d12.PRIMITIVE_TOPOLOGY { switch t { case .Triangle_List: return .TRIANGLELIST case .Triangle_Strip: return .TRIANGLESTRIP case .Line_List: return .LINELIST case .Point_List: return .POINTLIST } return .TRIANGLELIST } // --- Cull mode conversion --- @(private) to_d3d12_cull_mode :: proc(c: bk.Cull_Mode) -> d3d12.CULL_MODE { switch c { case .None: return .NONE case .Front: return .FRONT case .Back: return .BACK case .Front_And_Back: return .BACK } return .NONE } // --- Filter conversion --- @(private) to_d3d12_filter :: proc(mag, min, mip: bk.Filter) -> d3d12.FILTER { mag_linear := mag == .Linear min_linear := min == .Linear mip_linear := mip == .Linear if mag_linear && min_linear && mip_linear { return .MIN_MAG_MIP_LINEAR } else if mag_linear && min_linear && !mip_linear { return .MIN_MAG_LINEAR_MIP_POINT } else if !mag_linear && !min_linear && !mip_linear { return .MIN_MAG_MIP_POINT } else if !mag_linear && !min_linear && mip_linear { return .MIN_MAG_POINT_MIP_LINEAR } else if mag_linear && !min_linear { return .MIN_POINT_MAG_LINEAR_MIP_POINT } else if !mag_linear && min_linear { return .MIN_LINEAR_MAG_MIP_POINT } return .MIN_MAG_MIP_LINEAR } // --- Address mode conversion --- @(private) to_d3d12_address_mode :: proc(m: bk.Address_Mode) -> d3d12.TEXTURE_ADDRESS_MODE { switch m { case .Repeat: return .WRAP case .Clamp_To_Edge: return .CLAMP case .Clamp_To_Border: return .BORDER } return .WRAP } // --- Compare op conversion --- @(private) to_d3d12_compare_func :: proc(op: bk.Compare_Op) -> d3d12.COMPARISON_FUNC { switch op { case .Never: return .NEVER case .Less: return .LESS case .Less_Or_Equal: return .LESS_EQUAL case .Equal: return .EQUAL case .Greater_Or_Equal: return .GREATER_EQUAL case .Greater: return .GREATER case .Not_Equal: return .NOT_EQUAL case .Always: return .ALWAYS } return .ALWAYS } @(private) to_d3d12_stencil_op :: proc(op: bk.Stencil_Op) -> d3d12.STENCIL_OP { switch op { case .Keep: return .KEEP case .Zero: return .ZERO case .Replace: return .REPLACE case .Increment_Clamp: return .INCR_SAT case .Decrement_Clamp: return .DECR_SAT case .Invert: return .INVERT } return .KEEP } @(private) to_d3d12_stencil_face :: proc(face: bk.Stencil_Face_State) -> d3d12.DEPTH_STENCILOP_DESC { return { StencilFailOp = to_d3d12_stencil_op(face.fail_op), StencilDepthFailOp = to_d3d12_stencil_op(face.depth_fail_op), StencilPassOp = to_d3d12_stencil_op(face.pass_op), StencilFunc = to_d3d12_compare_func(face.compare_op), } } // --- Vertex format conversion --- @(private) to_dxgi_vertex_format :: proc(fmt: bk.Vertex_Format) -> dxgi.FORMAT { switch fmt { case .Float2: return .R32G32_FLOAT case .Float3: return .R32G32B32_FLOAT case .Float4: return .R32G32B32A32_FLOAT } return .UNKNOWN } // --- 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 } @(private) depth_format_to_typeless :: proc(fmt: dxgi.FORMAT) -> dxgi.FORMAT { #partial switch fmt { case .D32_FLOAT: return .R32_TYPELESS case .D32_FLOAT_S8X24_UINT: return .R32G8X24_TYPELESS case .D24_UNORM_S8_UINT: return .R24G8_TYPELESS case: return fmt } } @(private) depth_format_to_srv :: proc(fmt: dxgi.FORMAT) -> dxgi.FORMAT { #partial switch fmt { case .D32_FLOAT: return .R32_FLOAT case .D32_FLOAT_S8X24_UINT: return .R32_FLOAT_X8X24_TYPELESS case .D24_UNORM_S8_UINT: return .R24_UNORM_X8_TYPELESS case: return fmt } }