rhi_api.h

cross platform rendering playground

src/backend/rhi_api.h

8.17 KB
#pragma once

#include "rhi_types.h"

#include <cstdint>

namespace rhi {

// Device / Context
void create_context(Device &device, Config &cfg);
void destroy_context(Device &device);
bool create_memory_allocator(Device &device);
void destroy_memory_allocator(Device &device);
MemoryStats memory_stats(Device &device);

// Queue
Queue find_queue(Device &device, u32 required = 1u << 0, u32 excluded = 0);
Queue graphics_queue(Device &device);
u32 queue_family_index(const Queue &queue);

// Buffer
bool create_buffer(Device &device, BufferDesc &desc, Buffer &buffer);
void destroy_buffer(Device &device, Buffer &buffer);
u64 buffer_device_address(Device &device, Buffer &buffer, u64 offset = 0);

void buffer_flush(Device &device, Buffer &buffer, u64 offset, u64 size);
void buffer_invalidate(Device &device, Buffer &buffer, u64 offset, u64 size);

// Image
bool create_image(Device &device, ImageDesc &desc, Image &out);
void destroy_image(Device &device, Image &img);

// Views (descriptors/views idk the term I'll settle on)
bool create_image_view(Device &device, const ImageViewDesc &desc, ImageView &out);
void destroy_image_view(Device &device, ImageView &view);
bool create_buffer_view(Device &device, const BufferViewDesc &desc, BufferView &out);
void destroy_buffer_view(Device &device, BufferView &view);

u64 handle_id(Device &device, ImageView &view);
u64 handle_id(Device &device, Sampler &sampler);
u64 handle_id(Device &device, BufferView &view);

void create_swapchain(Device &device, const SwapchainDesc &desc, Swapchain &swapchain);
void destroy_swapchain(Device &device, Swapchain &swapchain);

bool acquire_swapchain_image(Device &device, Swapchain &swapchain, u32 &out_image_index, CmdBuffer &cmd);
void present_swapchain(Device &device, Swapchain &swapchain, u32 image_index, SyncPoint frame_done);
ImageFormat swapchain_format(const Swapchain &swapchain);
Extent2D swapchain_extent(const Swapchain &swapchain);
Image *swapchain_image(Swapchain &swapchain, u32 index);
bool swapchain_needs_recreate(const Swapchain &swapchain);

// CmdPool
bool create_cmd_pool(Device &device, const CmdPoolDesc &desc, CmdPool &pool);
void destroy_cmd_pool(Device &device, CmdPool &pool);
void reset_cmd_pool(Device &device, CmdPool &pool, u32 flags = 0);

// CmdBuffer
bool create_cmd_buffer(Device &device, const CmdBufferDesc &desc, CmdBuffer &cmd);
void destroy_cmd_buffer(Device &device, CmdPool &pool, CmdBuffer &cmd);
bool begin_cmd_buffer(CmdBuffer &cmd, const CmdBufferBeginDesc &desc = {});
bool end_cmd_buffer(CmdBuffer &cmd);
bool reset_cmd_buffer(CmdBuffer &cmd);
void begin_rendering(CmdBuffer &cmd, RenderingInfo &ri);
void end_rendering(CmdBuffer &cmd);
void set_viewports(CmdBuffer &cmd, Viewport *viewports, u32 viewportCount = 1);
void set_scissors(CmdBuffer &cmd, const Rect *rects, u32 rectCount = 1);
void fill_buffer(CmdBuffer &cmd, Buffer &buffer, u64 offset, u64 size, u32 value);
void dispatch(CmdBuffer &cmd, u32 x = 1, u32 y = 1, u32 z = 1);

// avoid calling while cmd.is_rendering: vkCmdPipelineBarrier2 inside a
// dynamic rendering instance is illegal without, VK_KHR_dynamic_rendering_local_read
// hoist the barrier before begin_rendering instead
void barrier(CmdBuffer &cmd, ResourceState before, ResourceState after);
void barrier(CmdBuffer &cmd, Buffer &buffer, ResourceState before, ResourceState after);
void barrier(CmdBuffer &cmd, Image &image, const ImageRange &range, ResourceState before, ResourceState after);

void draw(CmdBuffer &cmd, u32 vertexCount, u32 instanceCount, u32 firstVertex, u32 firstInstance);
void draw_indexed(CmdBuffer &cmd, u32 indexCount, u32 instanceCount, u32 firstIndex, u32 vtxOff, u32 firstInstance);
void draw_indirect(CmdBuffer &cmd, Buffer &buffer, u32 drawCount, u32 stride, u64 offset);
void draw_indirect_count(
    CmdBuffer &cmd, Buffer &buffer, Buffer &countBuffer, u32 drawCount, u32 stride, u64 offset, u32 countOffset
);
void draw_indexed_indirect(
    CmdBuffer &cmd, Buffer &buffer, Buffer *countBuffer, u32 drawCount, u32 stride, u64 offset = 0, u32 countOffset = 0
);
void set_vertex_buffer(CmdBuffer &cmd, Buffer &buffer, u32 binding = 0, u64 offset = 0);
void set_index_buffer(CmdBuffer &cmd, Buffer &buffer, u32 offset = 0, IndexType type = IndexType::UINT32);

void set_pipeline(CmdBuffer &cmd, RenderPipeline &pipeline);
void set_pipeline(CmdBuffer &cmd, ComputePipeline &pipeline);
void set_constants(CmdBuffer &cmd, RenderPipeline &pipeline, ShaderStage stage, u32 size, const void *data);
void set_constants(CmdBuffer &cmd, ComputePipeline &pipeline, ShaderStage stage, u32 size, const void *data);
void copy_buffer_to_texture(
    CmdBuffer &cmd, Buffer &srcBuffer, ImageView &dstView, const BufferTextureCopyRegion &region
);
void copy_image_to_buffer(CmdBuffer &cmd, ImageView &srcView, Buffer &dstBuffer, const BufferTextureCopyRegion &region);
void blit_image(CmdBuffer &cmd, Image &image, const ImageBlit *regions, u32 region_count);
void set_polygon_mode(CmdBuffer &cmd, PipelineFillMode mode);
void set_depth_write_enable(CmdBuffer &cmd, bool enable);
void cmd_build_acceleration_structures(
    CmdBuffer &cmd,
    const AccelStructBuildGeometryInfo *build_infos,
    const AccelStructBuildRangeInfo *const *ranges,
    u32 count
);
void copy_buffer_to_device(
    Device &device, Buffer &src, u64 src_offset, Buffer &dst, u64 dst_offset, u64 size, CmdBuffer &cmd
);

// Attachment view cache, might not stick around
ImageView get_cached_image_view(Device &device, Image &image, const ImageViewDesc &desc);
void destroy_image_views(Device &device, Image &image);
void destroy_buffer_views(Device &device, Buffer &buffer);

// Pipelines (type-safe: render vs compute)
void destroy_pipeline(Device &device, RenderPipeline &p);
void destroy_pipeline(Device &device, ComputePipeline &p);

// Sampler
bool create_sampler(Device &device, SamplerDesc &desc, Sampler &sampler);
void destroy_sampler(Device &device, Sampler &sampler);

// Shader
bool init_compiler(ShaderCompiler &sc);
u64 get_file_last_write_time(const char *path);

// Queue submission. Pure-SyncPoint edges (sync_refactor.md end-state).
void queue_submit(Device &device, Queue queue, const QueueSubmitDesc &desc);

// QueryPool
bool create_query_pool(Device &device, const QueryPoolDesc &desc, QueryPool &pool);
void reset_query_pool(CmdBuffer &cmd, QueryPool &queryPool, u32 offset, u32 count);
void write_timestamp(CmdBuffer &cmd, QueryPool &queryPool, u32 queryIndex, PipelineStages stage);
void destroy_query_pool(Device &device, QueryPool &queryPool);
bool query_pool_results(
    Device &device,
    const QueryPool &pool,
    u32 first_query,
    u32 query_count,
    u64 *out,
    usize data_size_bytes,
    usize stride_bytes,
    bool with_availability
);

// AccelStruct
bool get_acceleration_structure_build_sizes(
    Device &device,
    const AccelStructBuildGeometryInfo &build_info,
    const u32 *max_primitive_counts,
    AccelStructBuildSizesInfo &sizes
);
bool create_acceleration_structure(Device &device, const AccelStructCreateInfo &info, AccelStruct &out);
void destroy_acceleration_structure(Device &device, AccelStruct &as);
u64 get_acceleration_structure_device_address(Device &device, const AccelStruct &as);

Sync *sync_create(Device &device, u64 initial_value = 0, const char *name = nullptr); // nullptr on failure
void sync_destroy(Sync *sync);                                                        // null-safe
bool sync_host_wait(Sync *sync, u64 value, u64 timeout_ns = UINT64_MAX);              // CPU-blocking wait
u64 sync_get_completed_value(Sync *sync);                                             // completed counter, 0 if null
bool valid(const Sync *sync);
void device_wait_idle(Device &device);
void queue_wait_idle(Device &device);

// TODO: rm
ImageFormat image_format_from_vk(u32 format);
ImageFormat preferred_compressed_format(Device &device, bool srgb);

// TODO: per backend template/macro
bool valid(const Image &img);
bool valid(const Buffer &buffer);
bool valid(const ImageView &view);
bool valid(const BufferView &view);
bool valid(const CmdBuffer &cmd);
bool valid(const CmdPool &pool);
bool valid(const RenderPipeline &pipeline);
bool valid(const ComputePipeline &pipeline);
bool valid(const AccelStruct &as);
bool valid(const Sampler &sampler);
bool valid(const QueryPool &pool);
bool valid(const Swapchain &swapchain);

} // namespace rhi