id_blit.cpp

cross platform rendering playground

src/passes/id_blit/id_blit.cpp

3.33 KB
#include "id_blit.h"

#include "passes/fg.h"
#include "pipelines.h"
#include "renderer.h"
#include "shaders/renderer_types.h"

namespace id_blit {

ImageHandle record(
    rhi::Device &device,
    Pipelines &pipelines,
    rhi::ShaderCompiler &sc,
    FrameGraph &fg,
    BufferHandle indirect,
    BufferHandle draw_count,
    BufferHandle visible,
    ImageHandle depth
) {

    ImageHandle out = fg.add_image(
        {.desc = {.format = rhi::ImageFormat::R32_UINT}, .name = "fg/idblit/id", .size_class = SizeOp::Swapchain}
    );

    rhi::RenderPipelineDesc id_blit_p;
    id_blit_p.device = &device;
    id_blit_p.set_shaders(sc, "src/passes/id_blit/id_blit.slang", "vtx_main", "fs_main");
    id_blit_p.set_cull_mode(rhi::PipelineCullMode::NONE, rhi::PipelineTriangleWindingOrder::CW);
    id_blit_p.set_color_format(rhi::ImageFormat::R32_UINT);
    rhi::RenderPipeline &pipeline = pipelines.add_render("IDBlitPipeline", id_blit_p);

    auto &builder = fg.add_pass("ID_Blit");
    builder.read(depth, rhi::ResourceState::TextureSample);
    builder.read(indirect, rhi::ResourceState::IndirectFetch);
    builder.read(draw_count, rhi::ResourceState::IndirectFetch);
    builder.read(visible, rhi::ResourceState::StorageRead);
    builder.write(out, rhi::ResourceState::ColorDraw);

    builder.execute([=, &pipeline](PassContext &ctx) {
        FrameData &frame = ctx.frame_data[ctx.frame_index];

        auto display_view = ctx.image_view(out, {.aspect = rhi::ImageAspect::Color});

        rhi::AttachmentDesc color_att{};
        color_att.img = &display_view;
        color_att.loadOp = rhi::LoadOp::CLEAR;
        color_att.storeOp = rhi::StoreOp::STORE;
        color_att.clearValue.color.uint32[0] = 0u; // 0 = "no hit"; editor subtracts 1 from stored ids

        rhi::RenderingInfo ri{};
        ri.colorAttachments[0] = color_att;
        ri.colorAttachmentCount = 1;
        ri.width = ctx.render_width;
        ri.height = ctx.render_height;

        rhi::begin_rendering(ctx.cmd, ri);
        rhi::set_pipeline(ctx.cmd, pipeline);

        rhi::Viewport vp{};
        vp.width = (f32)ctx.render_width;
        vp.height = (f32)ctx.render_height;
        rhi::set_viewports(ctx.cmd, &vp);

        rhi::Rect scissor{};
        scissor.width = (i32)ctx.render_width;
        scissor.height = (i32)ctx.render_height;
        rhi::set_scissors(ctx.cmd, &scissor);

        IdBlitPushConstants pc{};
        pc.frame = (u64)ctx.render_data->frame_ubo_view[ctx.frame_index].slot;
        pc.vertex = (u64)ctx.render_data->vertex_view.slot;
        pc.visible_items = rhi::buffer_device_address(ctx.device, ctx.get_buffer(visible));
        pc.depth = (u32)ctx.view(depth);

        {
            static_assert(sizeof(pc) <= 128, "push constants exceed global 128B range");
            char pc128[128] = {};
            std::memcpy(pc128, &pc, sizeof(pc));
            rhi::set_constants(ctx.cmd, pipeline, rhi::ShaderStage::ALL, sizeof(pc128), pc128);
        }

        rhi::set_index_buffer(ctx.cmd, ctx.render_data->index_buffer);
        rhi::draw_indexed_indirect(
            ctx.cmd,
            ctx.get_buffer(indirect),
            &ctx.get_buffer(draw_count),
            ctx.render_data->render_item_count,
            rhi::DRAW_INDEXED_INDIRECT_STRIDE,
            0,
            0
        );

        rhi::end_rendering(ctx.cmd);
    });

    return out;
};

} // namespace id_blit