fullscreen.cpp

cross platform rendering playground

src/passes/fullscreen/fullscreen.cpp

3.43 KB
#include "fullscreen.h"

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

namespace fullscreen_fg {

Resources record(
    rhi::Device &device,
    Pipelines &pipelines,
    rhi::ShaderCompiler &sc,
    FrameGraph &fg,
    ImageHandle main,
    ImageHandle depth,
    rhi::ImageFormat output_format,
    ImageHandle output,
    ImageHandle ssr
) {

    rhi::RenderPipelineDesc pd;
    pd.device = &device;
    pd.set_shaders(sc, "src/passes/fullscreen/fullscreen.slang", "vsMain", "fsMain");
    pd.set_depth_testing(false, false, rhi::PipelineCompareOp::LESS_EQUAL);
    pd.set_cull_mode(rhi::PipelineCullMode::NONE, rhi::PipelineTriangleWindingOrder::CW);
    pd.set_color_format(output_format);
    rhi::RenderPipeline &pipeline = pipelines.add_render("Fullscreen", pd);

    Resources out;
    if (output.is_valid()) {
        out.display = output;
    } else {
        out.display = fg.add_image(
            {.desc = {.format = output_format}, .name = "fg/fullscreen/display", .size_class = SizeOp::Swapchain}
        );
    }

    auto &builder = fg.add_pass("Fullscreen");
    builder.read(main, rhi::ResourceState::TextureSample);
    builder.read(depth, rhi::ResourceState::TextureSample);
    if (ssr.is_valid()) {
        builder.read(ssr, rhi::ResourceState::TextureSample);
    }
    builder.write(out.display, rhi::ResourceState::ColorDraw);

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

        auto main_view = ctx.image_view(main, {.aspect = rhi::ImageAspect::Color, .mip_count = 1});
        auto depth_view = ctx.image_view(depth, {.aspect = rhi::ImageAspect::Depth, .mip_count = 1});
        auto display_view = ctx.image_view(out.display, {.aspect = rhi::ImageAspect::Color, .mip_count = 1});

        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.float32[0] = 0.0f;
        color_att.clearValue.color.float32[1] = 0.0f;
        color_att.clearValue.color.float32[2] = 0.0f;
        color_att.clearValue.color.float32[3] = 1.0f;

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

        FullscreenPushConstants pc{};
        pc.lighting = (u32)ctx.view(main);
        pc.depth = (u32)ctx.view(depth);
        pc.ssr = ssr.is_valid() ? (u32)ctx.view(ssr) : UINT64_MAX; // canonical null handle
        pc.samp = ctx.render_data->linear_clamp;

        {
            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::draw(ctx.cmd, 3, 1, 0, 0);
        rhi::end_rendering(ctx.cmd);
    });

    return out;
};

} // namespace fullscreen_fg