666 lines
28 KiB
C
666 lines
28 KiB
C
////////////////////////////////////////////////////////////
|
|
//~ 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);
|