//////////////////////////////////////////////////////////// //~ Handle types Struct(G_ArenaHandle) { u64 v; }; Struct(G_CommandListHandle) { u64 v; }; Struct(G_ResourceHandle) { u64 v; }; Struct(G_SwapchainHandle) { u64 v; }; #define G_IsArenaNil(h) ((h).v == 0) #define G_IsCommandListNil(h) ((h).v == 0) #define G_IsResourceNil(h) ((h).v == 0) #define G_IsSwapchainNil(h) ((h).v == 0) //////////////////////////////////////////////////////////// //~ Queue types #define G_IsMultiQueueEnabled 1 Enum(G_QueueKind) { G_QueueKind_Direct = 0, #if G_IsMultiQueueEnabled G_QueueKind_AsyncCompute = 1, G_QueueKind_AsyncCopy = 2, #else G_QueueKind_AsyncCompute = G_QueueKind_Direct, G_QueueKind_AsyncCopy = G_QueueKind_Direct, #endif G_QueueKind_COUNT }; Enum(G_QueueMask) { G_QueueMask_None = 0, G_QueueMask_Direct = (1 << 0), #if G_IsMultiQueueEnabled G_QueueMask_AsyncCompute = (1 << 1), G_QueueMask_AsyncCopy = (1 << 2), #else G_QueueMask_AsyncCompute = G_QueueMask_Direct, G_QueueMask_AsyncCopy = G_QueueMask_Direct, #endif G_QueueMask_All = (0xFFFFFFFF >> (32 - G_QueueKind_COUNT)) }; #define G_QueueMaskFromKind(queue_kind) (1 << queue_kind) Struct(G_QueueCompletions) { i64 v[G_QueueKind_COUNT]; // Array of completions indexed by queue kind }; // All waiters will wait until specified queues reach their value in the `completions` array Struct(G_QueueBarrierDesc) { G_QueueCompletions completions; // Completions that waiters should wait for G_QueueMask wait_queues; // Mask of queues that will wait for completions b32 wait_cpu; // Will the cpu wait for completion }; //////////////////////////////////////////////////////////// //~ Format types // NOTE: Matches DirectX DXGI_FORMAT Enum(G_Format) { G_Format_Unknown = 0, G_Format_R32G32B32A32_Typeless = 1, G_Format_R32G32B32A32_Float = 2, G_Format_R32G32B32A32_Uint = 3, G_Format_R32G32B32A32_Sint = 4, G_Format_R32G32B32_Typeless = 5, G_Format_R32G32B32_Float = 6, G_Format_R32G32B32_Uint = 7, G_Format_R32G32B32_Sint = 8, G_Format_R16G16B16A16_Typeless = 9, G_Format_R16G16B16A16_Float = 10, G_Format_R16G16B16A16_Unorm = 11, G_Format_R16G16B16A16_Uint = 12, G_Format_R16G16B16A16_Snorm = 13, G_Format_R16G16B16A16_Sint = 14, G_Format_R32G32_Typeless = 15, G_Format_R32G32_Float = 16, G_Format_R32G32_Uint = 17, G_Format_R32G32_Sint = 18, G_Format_R32G8X24_Typeless = 19, G_Format_D32_Float_S8X24_Uint = 20, G_Format_R32_Float_X8X24_Typeless = 21, G_Format_X32_Typeless_G8X24_Uint = 22, G_Format_R10G10B10A2_Typeless = 23, G_Format_R10G10B10A2_Unorm = 24, G_Format_R10G10B10A2_Uint = 25, G_Format_R11G11B10_Float = 26, G_Format_R8G8B8A8_Typeless = 27, G_Format_R8G8B8A8_Unorm = 28, G_Format_R8G8B8A8_Unorm_Srgb = 29, G_Format_R8G8B8A8_Uint = 30, G_Format_R8G8B8A8_Snorm = 31, G_Format_R8G8B8A8_Sint = 32, G_Format_R16G16_Typeless = 33, G_Format_R16G16_Float = 34, G_Format_R16G16_Unorm = 35, G_Format_R16G16_Uint = 36, G_Format_R16G16_Snorm = 37, G_Format_R16G16_Sint = 38, G_Format_R32_Typeless = 39, G_Format_D32_Float = 40, G_Format_R32_Float = 41, G_Format_R32_Uint = 42, G_Format_R32_Sint = 43, G_Format_R24G8_Typeless = 44, G_Format_D24_Unorm_S8_Uint = 45, G_Format_R24_Unorm_X8_Typeless = 46, G_Format_X24_Typeless_G8_Uint = 47, G_Format_R8G8_Typeless = 48, G_Format_R8G8_Unorm = 49, G_Format_R8G8_Uint = 50, G_Format_R8G8_Snorm = 51, G_Format_R8G8_Sint = 52, G_Format_R16_Typeless = 53, G_Format_R16_Float = 54, G_Format_D16_Unorm = 55, G_Format_R16_Unorm = 56, G_Format_R16_Uint = 57, G_Format_R16_Snorm = 58, G_Format_R16_Sint = 59, G_Format_R8_Typeless = 60, G_Format_R8_Unorm = 61, G_Format_R8_Uint = 62, G_Format_R8_Snorm = 63, G_Format_R8_Sint = 64, G_Format_A8_Unorm = 65, G_Format_R1_Unorm = 66, G_Format_R9G9B9E5_SharedXP = 67, G_Format_R8G8_B8G8_Unorm = 68, G_Format_G8R8_G8B8_Unorm = 69, G_Format_BC1_Typeless = 70, G_Format_BC1_Unorm = 71, G_Format_BC1_Unorm_Srgb = 72, G_Format_BC2_Typeless = 73, G_Format_BC2_Unorm = 74, G_Format_BC2_Unorm_Srgb = 75, G_Format_BC3_Typeless = 76, G_Format_BC3_Unorm = 77, G_Format_BC3_Unorm_Srgb = 78, G_Format_BC4_Typeless = 79, G_Format_BC4_Unorm = 80, G_Format_BC4_Snorm = 81, G_Format_BC5_Typeless = 82, G_Format_BC5_Unorm = 83, G_Format_BC5_Snorm = 84, G_Format_B5G6R5_Unorm = 85, G_Format_B5G5R5A1_Unorm = 86, G_Format_B8G8R8A8_Unorm = 87, G_Format_B8G8R8X8_Unorm = 88, G_Format_R10G10B10_XR_BIAS_A2_Unorm = 89, G_Format_B8G8R8A8_Typeless = 90, G_Format_B8G8R8A8_Unorm_Srgb = 91, G_Format_B8G8R8X8_Typeless = 92, G_Format_B8G8R8X8_Unorm_Srgb = 93, G_Format_BC6H_Typeless = 94, G_Format_BC6H_UF16 = 95, G_Format_BC6H_SF16 = 96, G_Format_BC7_Typeless = 97, G_Format_BC7_Unorm = 98, G_Format_BC7_Unorm_Srgb = 99, G_Format_AYUV = 100, G_Format_Y410 = 101, G_Format_Y416 = 102, G_Format_NV12 = 103, G_Format_P010 = 104, G_Format_P016 = 105, G_Format_420_Opaque = 106, G_Format_YUY2 = 107, G_Format_Y210 = 108, G_Format_Y216 = 109, G_Format_NV11 = 110, G_Format_AI44 = 111, G_Format_IA44 = 112, G_Format_P8 = 113, G_Format_A8P8 = 114, G_Format_B4G4R4A4_Unorm = 115, G_Format_P208 = 130, G_Format_V208 = 131, G_Format_V408 = 132, G_Format_SamplerFeedbackMinMipOpaque = 189, G_Format_SamplerFeedbackMipRegionUsedOpaque = 190, G_Format_A4B4G4R4_Unorm = 191, G_Format_COUNT = 192 }; //////////////////////////////////////////////////////////// //~ Texture layout types Enum(G_Layout) { // Supports any read access with up to 1 write access to non overlapping regions from any queue. // Cannot be transitioned to/from. // Depth-stencil textures cannot use this layout. G_Layout_Simultaneous, // Supports present, shader-read, and copy-read/write in any queue kind. // Transitionable from `G_Layout_Exclusive` in non-copy queue. G_Layout_Common, // Supports any access in the current queue kind. // Transitionable from `G_Layout_Common` in non-copy queue. G_Layout_Exclusive, }; //////////////////////////////////////////////////////////// //~ Filter types // NOTE: Matches DirectX D3D12_FILTER Enum(G_Filter) { // Standard filter G_Filter_MinMagMipPoint = 0, G_Filter_MinMagPointMipLinear = 0x1, G_Filter_MinPointMagLinearMipPoint = 0x4, G_Filter_MinPointMagMipLinear = 0x5, G_Filter_MinLinearMagMipPoint = 0x10, G_Filter_MinLinearMagPointMipLinear = 0x11, G_Filter_MinMagLinearMipPoint = 0x14, G_Filter_MinMagMipLinear = 0x15, G_Filter_MinMagAnisotropicMipPoint = 0x54, G_Filter_Anisotropic = 0x55, // Comparison filter G_Filter_Comparison_MinMagMipPoint = 0x80, G_Filter_Comparison_MinMagPointMipLinear = 0x81, G_Filter_Comparison_MinPointMagLinearMipPoint = 0x84, G_Filter_Comparison_MinPointMagMipLinear = 0x85, G_Filter_Comparison_MinLinearMagMipPoint = 0x90, G_Filter_Comparison_MinLinearMagPointMipLinear = 0x91, G_Filter_Comparison_MinMagLinearMipPoint = 0x94, G_Filter_Comparison_MinMagMipLinear = 0x95, G_Filter_Comparison_MinMagAnisotropicMipPoint = 0xd4, G_Filter_Comparison_Anisotropic = 0xd5, // Minimum filter G_Filter_Minimum_MinMagMipPoint = 0x100, G_Filter_Minimum_MinMagPointMipLinear = 0x101, G_Filter_Minimum_MinPointMagLinearMipPoint = 0x104, G_Filter_Minimum_MinPointMagMipLinear = 0x105, G_Filter_Minimum_MinLinearMagMipPoint = 0x110, G_Filter_Minimum_MinLinearMagPointMipLinear = 0x111, G_Filter_Minimum_MinMagLinearMipPoint = 0x114, G_Filter_Minimum_MinMagMipLinear = 0x115, G_Filter_Minimum_MinMagAnisotropicMipPoint = 0x155, G_Filter_Minimum_Anisotropic = 0x155, // Maximum filter G_Filter_Maximum_MinMagMipPoint = 0x180, G_Filter_Maximum_MinMagPointMipLinear = 0x181, G_Filter_Maximum_MinPointMagLinearMipPoint = 0x184, G_Filter_Maximum_MinPointMagMipLinear = 0x185, G_Filter_Maximum_MinLinearMagMipPoint = 0x190, G_Filter_Maximum_MinLinearMagPointMipLinear = 0x191, G_Filter_Maximum_MinMagLinearMipPoint = 0x194, G_Filter_Maximum_MinMagMipLinear = 0x195, G_Filter_Maximum_MinMagAnisotropicMipPoint = 0x1d4, G_Filter_Maximum_Anisotropic = 0x1d5 }; // NOTE: Matches DirectX D3D12_TEXTURE_ADDRESS_MODE Enum(G_AddressMode) { G_AddressMode_Wrap = 1, G_AddressMode_Mirror = 2, G_AddressMode_Clamp = 3, // Default G_AddressMode_Border = 4, G_AddressMode_MirrorOnce = 5 }; // NOTE: Matches DirectX D3D12_COMPARISON_FUNC Enum(G_ComparisonFunc) { G_ComparisonFunc_None = 0, G_ComparisonFunc_Never = 1, G_ComparisonFunc_Less = 2, G_ComparisonFunc_Equal = 3, G_ComparisonFunc_LessEqual = 4, G_ComparisonFunc_Greater = 5, G_ComparisonFunc_NotEqual = 6, G_ComparisonFunc_GreaterEqual = 7, G_ComparisonFunc_Always = 8 }; //////////////////////////////////////////////////////////// //~ Resource types Enum(G_ResourceKind) { G_ResourceKind_Buffer, G_ResourceKind_Texture1D, G_ResourceKind_Texture2D, G_ResourceKind_Texture3D, G_ResourceKind_Sampler, }; Enum(G_ResourceFlag) { G_ResourceFlag_None = 0, G_ResourceFlag_AllowShaderReadWrite = (1 << 1), G_ResourceFlag_AllowRenderTarget = (1 << 2), G_ResourceFlag_AllowDepthStencil = (1 << 3), G_ResourceFlag_ZeroMemory = (1 << 4), G_ResourceFlag_HostMemory = (1 << 5), // Resource will be mapped into the cpu's address space G_ResourceFlag_Uncached = (1 << 6), // Cpu writes will be combined & reads will be uncached G_ResourceFlag_ForceNoReuse = (1 << 7), }; Struct(G_BufferDesc) { G_ResourceFlag flags; u64 size; String name; }; Struct(G_TextureDesc) { G_ResourceFlag flags; G_Format format; Vec3I32 dims; G_Layout initial_layout; Vec4 clear_color; i32 max_mips; // Will be clamped to range [1, max mips] String name; }; Struct(G_SamplerDesc) { G_ResourceFlag flags; G_Filter filter; G_AddressMode x; G_AddressMode y; G_AddressMode z; f32 mip_lod_bias; u32 max_anisotropy; G_ComparisonFunc comparison; Vec4 border_color; f32 min_lod; f32 max_lod; String name; }; Struct(G_ResourceDesc) { G_ResourceKind kind; G_BufferDesc buffer; G_TextureDesc texture; G_SamplerDesc sampler; }; //////////////////////////////////////////////////////////// //~ Ref types Struct(G_RefDesc) { G_RefKind kind; u64 element_size; u64 element_offset; RngI32 mips; // Inclusive range of texture mip indices to reference }; //////////////////////////////////////////////////////////// //~ Draw types Enum(G_DrawMode) { G_DrawMode_None, G_DrawMode_PointList, G_DrawMode_LineList, G_DrawMode_LineStrip, G_DrawMode_TriangleList, G_DrawMode_TriangleStrip, G_DrawMode_WireTriangleList, G_DrawMode_WireTriangleStrip, }; Enum(G_BlendMode) { G_BlendMode_Opaque, G_BlendMode_CompositeStraightAlpha, G_BlendMode_CompositePremultipliedAlpha, }; Struct(G_IndexBufferDesc) { u32 count; u32 stride; // Either 2 for u16 indices, or 4 for u32 indices G_ResourceHandle resource; }; Struct(G_RenderTargetDesc) { G_ResourceHandle resource; G_BlendMode blend; i32 mip; }; //////////////////////////////////////////////////////////// //~ Statistic types Struct(G_Stats) { // Memory usage u64 device_committed; u64 device_budget; u64 host_committed; u64 host_budget; // Other stats u64 arenas_count; u64 cumulative_nonreuse_count; }; //////////////////////////////////////////////////////////// //~ @hookdecl Bootstrap void G_Bootstrap(void); //////////////////////////////////////////////////////////// //~ @hookdecl Arena G_ArenaHandle G_AcquireArena(void); void G_ReleaseArena(G_CommandListHandle cl_handle, G_ArenaHandle arena); void G_ResetArena(G_CommandListHandle cl_handle, G_ArenaHandle arena_handle); //////////////////////////////////////////////////////////// //~ @hookdecl Resource //- Resource creation G_ResourceHandle G_PushResource(G_ArenaHandle arena, G_CommandListHandle cl, G_ResourceDesc desc); #define G_PushBuffer(arena, cl, _type, _count, ...) G_PushResource((arena), (cl), \ (G_ResourceDesc) { \ .kind = G_ResourceKind_Buffer, \ .buffer = { \ .size = sizeof(_type) * (_count), \ __VA_ARGS__ \ } \ } \ ) #define G_PushTexture1D(arena, cl, _format, _size, _initial_layout, ...) G_PushResource((arena), (cl), \ (G_ResourceDesc) { \ .kind = G_ResourceKind_Texture1D, \ .texture = { \ .format = (_format), \ .dims = VEC3I32((_size), 1, 1), \ .initial_layout = (_initial_layout), \ __VA_ARGS__ \ } \ } \ ) #define G_PushTexture2D(arena, cl, _format, _size, _initial_layout, ...) G_PushResource((arena), (cl), \ (G_ResourceDesc) { \ .kind = G_ResourceKind_Texture2D, \ .texture = { \ .format = (_format), \ .dims = VEC3I32((_size).x, (_size).y, 1), \ .initial_layout = (_initial_layout), \ __VA_ARGS__ \ } \ } \ ) #define G_PushTexture3D(arena, cl, _format, _size, _initial_layout, ...) G_PushResource((arena), (cl), \ (G_ResourceDesc) { \ .kind = G_ResourceKind_Texture3D, \ .texture = { \ .format = (_format), \ .dims = (_size), \ .initial_layout = (_initial_layout), \ __VA_ARGS__ \ } \ } \ ) #define G_PushSampler(arena, cl, ...) G_PushResource((arena), (cl), \ (G_ResourceDesc) { \ .kind = G_ResourceKind_Sampler, \ .sampler = { \ .filter = G_Filter_MinMagMipPoint, \ __VA_ARGS__ \ } \ } \ ) //- Index buffer helpers #define G_IdxBuff16(_res) ((G_IndexBufferDesc) { .resource = (_res), .stride = 2, .count = (G_CountBuffer((_res), i16)) }) #define G_IdxBuff32(_res) ((G_IndexBufferDesc) { .resource = (_res), .stride = 4, .count = (G_CountBuffer((_res), i32)) }) //- Render target helpers #define G_Rt(_res, _blend_mode) ((G_RenderTargetDesc) { .resource = (_res), .blend = (_blend_mode) }) //- Count u64 G_CountBufferBytes(G_ResourceHandle buffer); i32 G_Count1D(G_ResourceHandle texture); Vec2I32 G_Count2D(G_ResourceHandle texture); Vec3I32 G_Count3D(G_ResourceHandle texture); i32 G_CountWidth(G_ResourceHandle texture); i32 G_CountHeight(G_ResourceHandle texture); i32 G_CountDepth(G_ResourceHandle texture); i32 G_CountMips(G_ResourceHandle texture); #define G_CountBuffer(buffer, type) G_CountBufferBytes(buffer) / sizeof(type) //- Map void *G_HostPointerFromResource(G_ResourceHandle resource); #define G_StructFromResource(resource, type) (type *)G_HostPointerFromResource(resource) //////////////////////////////////////////////////////////// //~ @hookdecl Shader resource reference u32 G_PushRef(G_ArenaHandle arena, G_ResourceHandle resource, G_RefDesc desc); #define G_PushStructuredBufferRef(arena, resource, type, ...) (G_StructuredBufferRef) { \ .v = G_PushRef( \ (arena), (resource), \ (G_RefDesc) { .kind = G_RefKind_StructuredBuffer, .element_size = sizeof(type), __VA_ARGS__ } \ ) \ } #define G_PushByteAddressBufferRef(arena, resource, ...) (G_ByteAddressBufferRef) { \ .v = G_PushRef( \ (arena), (resource), \ (G_RefDesc) { .kind = G_RefKind_ByteAddressBuffer, __VA_ARGS__ } \ ) \ } #define G_PushTexture1DRef(arena, resource, ...) (G_Texture1DRef) { \ .v = G_PushRef( \ (arena), (resource), \ (G_RefDesc) { .kind = G_RefKind_Texture1D, .mips.max = G_MaxMips, __VA_ARGS__ } \ ) \ } #define G_PushTexture2DRef(arena, resource, ...) (G_Texture2DRef) { \ .v = G_PushRef( \ (arena), (resource), \ (G_RefDesc) { .kind = G_RefKind_Texture2D, .mips.max = G_MaxMips, __VA_ARGS__ } \ ) \ } #define G_PushTexture3DRef(arena, resource, ...) (G_Texture3DRef) { \ .v = G_PushRef( \ (arena), (resource), \ (G_RefDesc) { .kind = G_RefKind_Texture3D, .mips.max = G_MaxMips, __VA_ARGS__ } \ ) \ } #define G_PushSamplerStateRef(arena, resource, ...) (G_SamplerStateRef) { \ .v = G_PushRef( \ (arena), (resource), \ (G_RefDesc) { .kind = G_RefKind_SamplerState, __VA_ARGS__ } \ ) \ } //////////////////////////////////////////////////////////// //~ @hookdecl Command //- Command list G_CommandListHandle G_PrepareCommandList(G_QueueKind queue); i64 G_CommitCommandList(G_CommandListHandle cl); //- Constant void G_SetConstantEx(G_CommandListHandle cl, i32 slot, void *src_32bit, u32 size); #define G_SetConstant(cl, name, value) do { \ CAT(name, __shaderconstanttype) __src; \ __src.v = value; \ G_SetConstantEx((cl), (name), &__src, sizeof(__src)); \ } while (0) //- Barrier void G_Sync(G_CommandListHandle cl); void G_SyncLayout(G_CommandListHandle cl, G_ResourceHandle resource, G_Layout layout); //- Zone void G_PushZone(G_CommandListHandle cl, char *name_lit_cstr); void G_PopZone(G_CommandListHandle cl); #define G_ZoneDF(cl, name_lit_cstr) DeferFor(G_PushZone((cl), (name_lit_cstr)), G_PopZone(cl)) //- Cpu -> Gpu staged copy void G_CopyCpuToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, u64 dst_offset, void *src, RngU64 src_copy_range); void G_CopyCpuToTexture(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, void *src, Vec3I32 src_dims, Rng3I32 src_copy_range); //- Gpu <-> Gpu copy void G_CopyBufferToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, u64 dst_offset, G_ResourceHandle src, RngU64 src_copy_range); void G_CopyBufferToTexture(G_CommandListHandle cl_handle, G_ResourceHandle dst_handle, Rng3I32 dst_copy_range, G_ResourceHandle src_handle, u64 src_offset); void G_CopyTextureToTexture(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, G_ResourceHandle src, Rng3I32 src_copy_range); void G_CopyTextureToBuffer(G_CommandListHandle cl, G_ResourceHandle dst, Vec3I32 dst_offset, G_ResourceHandle src, Rng3I32 src_copy_range); //- Compute void G_ComputeEx(G_CommandListHandle cl, ComputeShaderDesc cs, Vec3I32 threads); #define G_Compute(cl, cs, threads) G_ComputeEx((cl), (cs), VEC3I32((threads), 1, 1)) #define G_Compute2D(cl, cs, threads) G_ComputeEx((cl), (cs), VEC3I32((threads).x, (threads).y, 1)) #define G_Compute3D(cl, cs, threads) G_ComputeEx((cl), (cs), VEC3I32((threads).x, (threads).y, (threads).z)) //- Draw void G_Draw( G_CommandListHandle cl, VertexShaderDesc vs, PixelShaderDesc ps, u32 instances_count, G_IndexBufferDesc index_buffer, u32 render_targets_count, G_RenderTargetDesc *render_targets, Rng3 viewport, Rng2 scissor, G_DrawMode draw_mode ); //- Clear void G_ClearRenderTarget(G_CommandListHandle cl, G_ResourceHandle render_target, Vec4 color, i32 mip); //////////////////////////////////////////////////////////// //~ @hookdecl Queue synchronization i64 G_CompletionValueFromQueue(G_QueueKind queue_kind); i64 G_CompletionTargetFromQueue(G_QueueKind queue_kind); G_QueueCompletions G_CompletionValuesFromQueues(G_QueueMask queue_mask); G_QueueCompletions G_CompletionTargetsFromQueues(G_QueueMask queue_mask); void G_QueueSyncEx(G_QueueBarrierDesc desc); #define G_QueueSync(completion_mask, ...) \ G_QueueSyncEx((G_QueueBarrierDesc) { \ .completions = G_CompletionTargetsFromQueues(completion_mask), \ __VA_ARGS__ \ }) #define G_QueueSyncGpu(completion_mask, wait_mask) G_QueueSync((completion_mask), .wait_queues = (wait_mask)) #define G_QueueSyncCpu(completion_mask) G_QueueSync((completion_mask), .wait_cpu = 1); //////////////////////////////////////////////////////////// //~ @hookdecl Statistics G_Stats G_QueryStats(void); //////////////////////////////////////////////////////////// //~ @hookdecl Swapchain G_SwapchainHandle G_AcquireSwapchain(u64 os_window_handle); void G_ReleaseSwapchain(G_SwapchainHandle swapchain); // Waits until a new backbuffer is ready from the swapchain. // This should be called before rendering for minimum latency. G_ResourceHandle G_PrepareBackbuffer(G_SwapchainHandle swapchain_handle, G_Format format, Vec2I32 size); void G_CommitBackbuffer(G_ResourceHandle backbuffer, i32 vsync);