#pragma once
#include <string>
#include <vector>
#include "core/globals.h"
namespace rhi {
struct Memory;
struct Queue;
struct Buffer;
struct BufferView;
struct Image;
struct ImageView;
struct CmdPool;
struct CmdBuffer;
struct RenderPipeline;
struct ComputePipeline;
struct Sampler;
struct QueryPool;
struct AccelStruct;
struct Swapchain;
struct Device;
struct Sync;
struct SyncPoint;
struct QueueWait;
struct QueueSignal;
struct QueueSubmitDesc;
struct ShaderCompiler;
struct ShaderModule;
enum class PipelineTopology : u8 {
TRIANGLES,
LINES,
POINTS
};
enum class PipelineFillMode : u8 {
SOLID,
WIREFRAME
};
enum class PipelineCullMode : u8 {
NONE,
FRONT,
BACK
};
enum class PipelineTriangleWindingOrder : u8 {
CW,
CCW,
};
enum class PipelineCompareOp : u8 {
NEVER,
LESS,
EQUAL,
LESS_EQUAL,
GREATER,
NOT_EQUAL,
GREATER_EQUAL,
ALWAYS
};
enum class PipelineBlendFactor : u8 {
ZERO,
ONE,
SRC_ALPHA,
ONE_MINUS_SRC_ALPHA,
DST_ALPHA,
ONE_MINUS_DST_ALPHA,
SRC_COLOR,
ONE_MINUS_SRC_COLOR,
DST_COLOR,
ONE_MINUS_DST_COLOR,
SRC_ALPHA_SATURATE,
};
enum class PipelineBlendOp : u8 {
ADD,
SUBTRACT,
REVERSE_SUBTRACT,
MIN,
MAX,
};
enum class SampleCount : u8 {
Sample1 = 1,
Sample2 = 2,
Sample4 = 4,
Sample8 = 8,
Sample16 = 16,
Sample32 = 32,
Sample64 = 64
};
enum class ShaderStage : u32 {
NONE = BIT(0),
VERTEX = BIT(1),
FRAGMENT = BIT(2),
COMPUTE = BIT(3),
MESH = BIT(4),
TASK = BIT(5),
GEOMETRY = BIT(6),
RAYGEN = BIT(9),
CLOSEST_HIT = BIT(10),
ANY_HIT = BIT(11),
MISS = BIT(12),
INTERSECTION = BIT(13),
CALLABLE = BIT(14),
ALL = BIT(8)
};
ENUM_BIT_OPS(ShaderStage);
enum class ImageType : u8 {
TYPE_2D,
TYPE_3D,
TYPE_CUBE
};
struct Extent2D {
u32 width = 0;
u32 height = 0;
};
enum class BufferUsage : u32 {
None = 0,
VertexBuffer = BIT(1),
IndexBuffer = BIT(2),
UniformBuffer = BIT(3),
StorageBuffer = BIT(4),
IndirectBuffer = BIT(5),
CopySrc = BIT(6),
CopyDst = BIT(7),
ShaderAddr = BIT(8),
AccelStructBuildInput = BIT(9),
AccelStructStorage = BIT(10),
};
ENUM_BIT_OPS(BufferUsage);
enum class BufferMemType : u8 {
Device,
Upload, // cpu write, mapped for lifetime
Readback, // gpu write, mapped for lifetime
};
struct BufferDesc {
u64 size = 0;
BufferUsage usage = BufferUsage::StorageBuffer;
BufferMemType memory = BufferMemType::Device;
bool dedicated = false; // VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT, Metal MTLStorageModePrivate
std::string name;
};
enum class BufferViewType : u8 {
Uniform,
Storage,
Vertex,
Index,
Indirect,
Texel,
};
enum class ImageViewType : u8 {
Sampled,
Storage,
// Sentinel: "no view declared,
// ImageResource uses it to mean "not shader-visible".
// Kind of a sentinal hack for FG, need a better solution
None,
};
enum class ImageUsage : u32 {
None = 0,
ColorAttachment = BIT(1),
DepthAttachment = BIT(2),
StencilAttachment = BIT(3),
Sampled = BIT(4),
Storage = BIT(5),
TransferSrc = BIT(6),
TransferDst = BIT(7),
InputAttachment = BIT(8),
};
ENUM_BIT_OPS(ImageUsage);
enum class ImageAspect : u32 {
None = BIT(0),
Color = BIT(1),
Depth = BIT(2),
Stencil = BIT(3),
};
ENUM_BIT_OPS(ImageAspect);
enum class ImageFormat : u8 {
UNDEFINED,
R8_UNORM,
RGBA8_UNORM,
RGBA8_SRGB,
BGRA8_UNORM,
D32_FLOAT,
RGBA16_FLOAT,
RGBA32_FLOAT,
RGB32_FLOAT,
R10G10B10A2_UNORM,
RG16_FLOAT,
RG32_FLOAT,
R32_FLOAT,
R32_UINT,
R16_FLOAT,
BC7_UNORM,
BC7_SRGB,
ASTC6X6_UNORM,
ASTC6X6_SRGB
};
enum class TextureViewDimension : u8 {
TEXTURE_2D,
TEXTURE_2D_ARRAY,
TEXTURE_3D,
TEXTURE_CUBE
};
enum class ComponentSwizzle : u8 {
Identity,
R,
G,
B,
A,
Zero,
One
};
struct ImageDesc {
u32 width = 0;
u32 height = 0;
u32 depth = 1;
u32 mip_levels = 1;
u32 layers = 1;
bool is_cubemap = false;
SampleCount sample_count = SampleCount::Sample1;
ImageFormat format = ImageFormat::UNDEFINED;
ImageUsage usage = ImageUsage::Sampled;
std::string name;
};
enum class CmdPoolUsage : u32 {
None = BIT(0),
Transient = BIT(1),
ResetCommandBuffer = BIT(2),
Protected = BIT(3),
};
ENUM_BIT_OPS(CmdPoolUsage);
struct CmdPoolDesc {
u32 queue_family_index = UINT32_MAX;
CmdPoolUsage flags;
};
struct Viewport {
f32 x = 0.0f;
f32 y = 0.0f;
f32 width;
f32 height;
f32 depth_min = 0.0f;
f32 depth_max = 1.0f;
bool flip_y = true;
};
struct Rect {
i16 x = 0;
i16 y = 0;
i16 width;
i16 height;
};
enum class IndexType : u8 {
UINT16,
UINT32,
};
enum class CmdBufferLevel : u8 {
Primary,
Secondary,
};
enum class CmdBufferUsage : u32 {
None = BIT(0),
OneTimeSubmit = BIT(1),
RenderPassContinue = BIT(2),
SimultaneousUse = BIT(3),
};
ENUM_BIT_OPS(CmdBufferUsage);
struct CmdBufferBeginDesc {
CmdBufferUsage usage;
};
enum class PipelineStages : u64 {
NONE = 0,
TOP_OF_PIPE = 0x1,
DRAW_INDIRECT = 0x2,
VERTEX_INPUT = 0x4,
VERTEX_SHADER = 0x8,
TESS_CONTROL_SHADER = 0x10,
TESS_EVALUATION_SHADER = 0x20,
GEOMETRY_SHADER = 0x40,
FRAGMENT_SHADER = 0x80,
EARLY_FRAGMENT_TESTS = 0x100,
LATE_FRAGMENT_TESTS = 0x200,
COLOR_ATTACHMENT_OUTPUT = 0x400,
COMPUTE_SHADER = 0x800,
// ALL_TRANSFER = 0x1000, // vksync2 mismatch?
BOTTOM_OF_PIPE = 0x2000,
HOST = 0x4000,
ALL_GRAPHICS = 0x8000,
ALL_COMMANDS = 0x10000,
TASK_SHADER = 0x80000,
MESH_SHADER = 0x100000,
RAY_TRACING_SHADER = 0x200000,
ACCELERATION_STRUCTURE_BUILD = 0x2000000,
ACCELERATION_STRUCTURE_COPY = 0x10000000,
MICROMAP_BUILD = 0x4000000,
COPY = 0x100000000ULL,
RESOLVE = 0x200000000ULL,
BLIT = 0x400000000ULL,
CLEAR = 0x800000000ULL,
INDEX_INPUT = 0x1000000000ULL,
VERTEX_ATTRIBUTE_INPUT = 0x2000000000ULL,
PRE_RASTERIZATION_SHADERS = 0x4000000000ULL,
// backwards compat names, remove
COLOR_ATTACHMENT = COLOR_ATTACHMENT_OUTPUT,
INDIRECT = DRAW_INDIRECT,
CLEAR_STORAGE = CLEAR,
ACCELERATION_STRUCTURE = ACCELERATION_STRUCTURE_BUILD,
MICROMAP = MICROMAP_BUILD,
// wrapper aliases
DEPTH_STENCIL_ATTACHMENT = EARLY_FRAGMENT_TESTS | LATE_FRAGMENT_TESTS,
TESSELLATION_SHADERS = TESS_CONTROL_SHADER | TESS_EVALUATION_SHADER,
MESH_SHADERS = TASK_SHADER | MESH_SHADER,
RASTER_SHADERS = INDEX_INPUT | VERTEX_SHADER | FRAGMENT_SHADER | DEPTH_STENCIL_ATTACHMENT | COLOR_ATTACHMENT_OUTPUT,
// Legacy alias
ALL = ALL_COMMANDS,
};
ENUM_BIT_OPS_64(PipelineStages);
enum class ResourceState : u8 {
Idle = 0, // no access, no stage (fresh / aliased transient)
ColorDraw, // write in color-output stage
ColorFetch, // read in color-output stage (blend / input / resolve-src)
DepthDraw, // write in depth-stencil-test stage
DepthFetch, // read in depth-stencil-test stage
TextureSample, // read in fragment/vertex stage (sampled texture)
TextureSampleNonFragment, // read in vertex/compute stage (sampled texture)
StorageRead, // read in compute stage (storage image/buffer)
StorageReadWrite, // read+write in compute stage (storage image/buffer)
VertexFetch, // read in vertex-fetch stage (vertex buffer)
IndexFetch, // read in index-fetch stage (index buffer)
IndirectFetch, // read in indirect-draw stage (indirect args)
UniformRead, // read in any shader stage (uniform buffer)
TransferFrom, // read in transfer stage (copy/blit/resolve src)
TransferTo, // write in transfer stage (copy/blit/resolve dst, clear dst)
HostRead, // read by host stage (destination-only barrier)
AccelBuild, // read+write in accel-build stage (TLAS/BLAS build)
AccelTrace, // read in accel-trace stage (ray trace / AS read)
Display, // no access, handed to swapchain (was Present)
};
struct ImageRange {
u32 mip = 0;
u32 mip_count = REMAINING_MIPS;
u32 layer = 0;
u32 layer_count = REMAINING_LAYERS;
ImageAspect aspect = ImageAspect::Color;
};
struct MemoryStats {
u32 block_count = 0;
u32 allocation_count = 0;
u64 allocation_bytes = 0;
u64 used_bytes = 0;
};
enum class LoadOp : u8 {
LOAD,
CLEAR
};
enum class StoreOp : u8 {
STORE,
DISCARD
};
enum class ResolveOp : u8 {
NONE,
AVERAGE,
MIN,
MAX,
SAMPLE_ZERO,
};
struct ClearDepthStencil {
f32 depth;
u32 stencil;
};
union ClearColorValue {
f32 float32[4];
i32 int32[4];
u32 uint32[4];
};
union ClearValue {
ClearColorValue color;
ClearDepthStencil depthStencil;
};
struct TextureCopyRegion {
u32 SrcMipLevel;
u32 SrcBaseArrayLayer;
u32 SrcOffsetX;
u32 SrcOffsetY;
u32 SrcOffsetZ;
u32 DstMipLevel;
u32 DstBaseArrayLayer;
u32 DstOffsetX;
u32 DstOffsetY;
u32 DstOffsetZ;
u32 ExtentWidth;
u32 ExtentHeight;
u32 ExtentDepth;
};
struct BufferTextureCopyRegion {
u64 buffer_offset;
u32 buffer_row_length;
u32 buffer_image_height;
u32 mip_level;
u32 base_array_layer;
u32 layer_count;
u32 texture_offset_x;
u32 texture_offset_y;
u32 texture_offset_z;
u32 texture_extent_width;
u32 texture_extent_height;
u32 texture_extent_depth;
};
#define SWAPCHAIN_IMAGE_COUNT 3
#define MAX_FRAMES_IN_FLIGHT 2
struct Config {
bool enable_validation = false;
void *app_info = nullptr;
std::vector<const char *> device_extensions;
std::vector<const char *> instance_extensions;
std::vector<const char *> instance_layers;
u32 swapchain_image_count = SWAPCHAIN_IMAGE_COUNT;
u32 max_frames_in_flight = MAX_FRAMES_IN_FLIGHT;
bool vsync_enabled = true;
};
struct SwapchainDesc {
void *native_window = nullptr;
u32 width = 0;
u32 height = 0;
ImageFormat format = ImageFormat::UNDEFINED;
u32 image_count = SWAPCHAIN_IMAGE_COUNT;
bool vsync_enabled = true;
};
struct BufferViewDesc {
Buffer *buffer = nullptr;
u64 offset = 0;
u64 size = 0;
BufferViewType type = BufferViewType::Storage;
};
struct ImageViewDesc {
Image *image = nullptr;
ImageAspect aspect = ImageAspect::None;
TextureViewDimension dimension = TextureViewDimension::TEXTURE_2D;
ImageViewType type = ImageViewType::Sampled;
u32 mip_start = 0;
u32 mip_count = 1;
u32 layer_start = 0;
u32 layer_count = 1;
ComponentSwizzle swizzle_r = ComponentSwizzle::Identity;
ComponentSwizzle swizzle_g = ComponentSwizzle::Identity;
ComponentSwizzle swizzle_b = ComponentSwizzle::Identity;
ComponentSwizzle swizzle_a = ComponentSwizzle::Identity;
};
enum class SamplerAddressMode : u8 {
WRAP,
MIRROR,
CLAMP,
BORDER
};
enum class SamplerFilter : u8 {
POINT,
LINEAR,
ANISOTROPIC
};
enum class SamplerComparisonFunc : u8 {
NEVER,
LESS,
EQUAL,
LESS_EQUAL,
GREATER,
NOT_EQUAL,
GREATER_EQUAL,
ALWAYS
};
struct SamplerDesc {
SamplerAddressMode address = SamplerAddressMode::WRAP;
SamplerFilter filter = SamplerFilter::LINEAR;
SamplerComparisonFunc comparison_func = SamplerComparisonFunc::NEVER;
bool use_mips = false;
std::string name;
};
enum class QueryType : u8 {
TIMESTAMP,
TIMESTAMP_COPY_QUEUE,
OCCLUSION,
PIPELINE_STATISTICS,
ACCELERATION_STRUCTURE_SIZE,
ACCELERATION_STRUCTURE_COMPACTED_SIZE,
MICROMAP_COMPACTED_SIZE
};
struct QueryPoolDesc {
QueryType queryType;
u32 capacity;
std::string name;
};
struct AccelStructTransform {
f32 matrix[3][4];
};
struct AccelStructInstance {
AccelStructTransform transform;
u32 instance_custom_index : 24;
u32 mask : 8;
u32 sbt_record_offset : 24;
u32 flags : 8;
u64 acceleration_structure_reference;
};
enum class AccelStructInstanceFlags : u8 {
None = 0,
TriangleFacingCullDisable = BIT(0),
TriangleFlipFacing = BIT(1),
ForceOpaque = BIT(2),
ForceNoOpaque = BIT(3),
};
ENUM_BIT_OPS(AccelStructInstanceFlags);
enum class AccelStructType : u8 {
BottomLevel,
TopLevel,
};
enum class AccelStructGeometryType : u8 {
Triangles,
Instances,
};
enum class AccelStructGeometryFlags : u8 {
None = 0,
Opaque = BIT(0),
NoDuplicateAnyHitInvocation = BIT(1),
};
ENUM_BIT_OPS(AccelStructGeometryFlags);
enum class AccelStructBuildFlags : u8 {
None = 0,
AllowUpdate = BIT(0),
AllowCompaction = BIT(1),
PreferFastTrace = BIT(2),
PreferFastBuild = BIT(3),
LowMemory = BIT(4),
};
ENUM_BIT_OPS(AccelStructBuildFlags);
enum class VertexFormat : u8 {
Undefined,
R32G32B32_FLOAT,
R32G32B32A32_FLOAT,
};
struct AccelStructGeometryTrianglesData {
VertexFormat vertex_format = VertexFormat::R32G32B32_FLOAT;
u64 vertex_data = 0;
u64 vertex_stride = 0;
u32 max_vertex = 0;
IndexType index_type = IndexType::UINT32;
u64 index_data = 0;
u64 transform_data = 0;
};
struct AccelStructGeometryInstancesData {
u64 data = 0;
bool array_of_pointers = false;
};
struct AccelStructGeometry {
AccelStructGeometryType type = AccelStructGeometryType::Triangles;
AccelStructGeometryFlags flags = AccelStructGeometryFlags::None;
union {
AccelStructGeometryTrianglesData triangles;
AccelStructGeometryInstancesData instances;
};
};
struct AccelStructBuildRangeInfo {
u32 primitive_count = 0;
u32 primitive_offset = 0;
u32 first_vertex = 0;
u32 transform_offset = 0;
};
struct AccelStructBuildSizesInfo {
u64 acceleration_structure_size = 0;
u64 update_scratch_size = 0;
u64 build_scratch_size = 0;
};
struct ImageBlit {
u32 src_mip = 0;
u32 dst_mip = 0;
u32 src_layer = 0;
u32 dst_layer = 0;
i32 src_x0 = 0, src_y0 = 0, src_x1 = 0, src_y1 = 0;
i32 dst_x0 = 0, dst_y0 = 0, dst_x1 = 0, dst_y1 = 0;
};
// VkDrawIndexedIndirectCommand
inline constexpr u32 DRAW_INDEXED_INDIRECT_STRIDE = 5 * sizeof(u32);
struct CmdBufferDesc {
CmdPool *pool = nullptr;
CmdBufferLevel level = CmdBufferLevel::Primary;
};
struct AttachmentDesc {
ImageView *img = nullptr;
ImageView *resolveImg = nullptr;
LoadOp loadOp = LoadOp::LOAD;
StoreOp storeOp = StoreOp::STORE;
ResolveOp resolveOp = ResolveOp::NONE;
ClearValue clearValue{};
};
struct RenderingInfo {
AttachmentDesc colorAttachments[8];
u32 colorAttachmentCount;
AttachmentDesc depthAttachment;
u32 width;
u32 height;
};
// Barrier descs removed; see barrier() overloads in rhi_api.h.
struct VertexAttribute {
u32 location;
u32 binding;
ImageFormat format;
u32 offset;
};
struct VertexBinding {
u32 binding;
u32 stride;
bool is_instanced{false};
};
struct AccelStructBuildGeometryInfo {
AccelStructType type = AccelStructType::BottomLevel;
AccelStructBuildFlags flags = AccelStructBuildFlags::None;
AccelStruct *dst_acceleration_structure = nullptr;
AccelStructGeometry *geometries = nullptr;
u32 geometry_count = 0;
u64 scratch_data = 0;
};
struct AccelStructCreateInfo {
Buffer *buffer = nullptr;
u64 offset = 0;
u64 size = 0;
AccelStructType type = AccelStructType::BottomLevel;
std::string name;
};
} // namespace rhi