fwd_cpu.cpp

cross platform rendering playground

src/passes/fwd_cpu/fwd_cpu.cpp

4.16 KB
#include "fwd_cpu.h"
#include "renderer.h"
#include "shaders/renderer_types.h"

namespace fwd_cpu {

Resources record(
    rhi::Device &device, Pipelines &pipelines, rhi::ShaderCompiler &sc, FrameGraph &fg, BufferHandle vb, BufferHandle ib
) {
    rhi::RenderPipelineDesc fwd_cpu_p;
    fwd_cpu_p.device = &device;
    fwd_cpu_p.set_shaders(sc, "src/passes/fwd_cpu/fwd_cpu.slang", "vsMain", "fsMain");
    fwd_cpu_p.add_vertex_binding(0, sizeof(Vertex));
    fwd_cpu_p.add_vertex_attribute(0, 0, rhi::ImageFormat::RGB32_FLOAT, offsetof(Vertex, pos));
    fwd_cpu_p.add_vertex_attribute(1, 0, rhi::ImageFormat::RGB32_FLOAT, offsetof(Vertex, normal));
    fwd_cpu_p.add_vertex_attribute(2, 0, rhi::ImageFormat::RG32_FLOAT, offsetof(Vertex, uv));
    fwd_cpu_p.add_vertex_attribute(3, 0, rhi::ImageFormat::RGBA32_FLOAT, offsetof(Vertex, tangent));
    fwd_cpu_p.set_depth_testing(true, true, rhi::PipelineCompareOp::GREATER_EQUAL);
    fwd_cpu_p.set_color_format(rhi::ImageFormat::RGBA16_FLOAT);
    fwd_cpu_p.set_cull_mode(rhi::PipelineCullMode::BACK, rhi::PipelineTriangleWindingOrder::CW);
    fwd_cpu_p.set_depth_format(rhi::ImageFormat::D32_FLOAT);
    fwd_cpu_p.set_multisampling(MSAA_SAMPLE_COUNT);
    pipelines.add_render("ForwardCpuPipeline", fwd_cpu_p);
    Resources res = {};
    res.hdr = fg.add_image({.desc = {.format = rhi::ImageFormat::RGBA16_FLOAT}, .name = "fg/fwdcpu/hdr"});
    res.depth = fg.add_image({.desc = {.format = rhi::ImageFormat::D32_FLOAT}, .name = "fg/fwdcpu/depth"});
    auto &builder = fg.add_pass("FwdCpu");
    builder.read(vb, rhi::ResourceState::VertexFetch);
    builder.read(ib, rhi::ResourceState::IndexFetch);
    builder.write(res.hdr, rhi::ResourceState::ColorDraw);
    builder.write(res.depth, rhi::ResourceState::DepthDraw);

    rhi::RenderPipeline &pipeline = pipelines.get_render("ForwardCpuPipeline");
    builder.execute([=, &pipeline](PassContext &ctx) {
        FrameData &frame = ctx.frame_data[ctx.frame_index];
        auto main_view = ctx.image_view(res.hdr, {.aspect = rhi::ImageAspect::Color, .mip_count = 1});
        auto depth_view = ctx.image_view(res.depth, {.aspect = rhi::ImageAspect::Depth, .mip_count = 1});
        rhi::RenderingInfo ri{};
        ri.colorAttachmentCount = 1;
        ri.colorAttachments[0].loadOp = rhi::LoadOp::CLEAR;
        ri.colorAttachments[0].clearValue.color.float32[0] = 0.0f;
        ri.colorAttachments[0].clearValue.color.float32[1] = 0.0f;
        ri.colorAttachments[0].clearValue.color.float32[2] = 0.0f;
        ri.colorAttachments[0].clearValue.color.float32[3] = 1.0f;
        ri.depthAttachment.loadOp = rhi::LoadOp::CLEAR;
        ri.depthAttachment.clearValue.depthStencil = {0.0f, 0};
        ri.colorAttachments[0].img = &main_view;
        ri.colorAttachments[0].storeOp = rhi::StoreOp::STORE;
        ri.depthAttachment.img = &depth_view;
        ri.depthAttachment.storeOp = rhi::StoreOp::STORE;

        ri.width = ctx.render_width;
        ri.height = ctx.render_height;

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

        rhi::set_vertex_buffer(ctx.cmd, ctx.render_data->vertex_buffer);
        rhi::set_index_buffer(ctx.cmd, ctx.render_data->index_buffer);

        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);

        FwdPC pc{};
        pc.frame = (u64)ctx.render_data->frame_ubo_view[ctx.frame_index].slot;
        {
            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);
        }

        for (u32 i = 0; i < ctx.render_data->submeshes.size(); i++) {
            SubmeshGPU &sm = ctx.render_data->submeshes[i];
            rhi::draw_indexed(ctx.cmd, sm.index_count, 1, sm.first_index, sm.base_vertex, 0);
        }

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

} // namespace fwd_cpu