skybox.cpp

cross platform rendering playground

src/passes/skybox/skybox.cpp

3.08 KB
#include "skybox.h"

#include "backend/rhi.h"
#include "pipelines.h"
#include "renderer.h"

void skybox::record(
    rhi::Device &device,
    Pipelines &pipelines,
    rhi::ShaderCompiler &sc,
    FrameGraph &fg,
    ImageHandle main_image,
    ImageHandle depth_image,
    ImageHandle env_image
) {

    rhi::RenderPipelineDesc pd;
    pd.device = &device;
    pd.set_shaders(sc, "src/passes/skybox/skybox.slang", "vsMain", "fsMain");
    pd.set_depth_testing(true, false, rhi::PipelineCompareOp::GREATER_EQUAL);
    pd.set_cull_mode(rhi::PipelineCullMode::NONE, rhi::PipelineTriangleWindingOrder::CW);
    pd.set_color_format(rhi::ImageFormat::RGBA16_FLOAT);
    pd.set_depth_format(rhi::ImageFormat::D32_FLOAT);
    rhi::RenderPipeline &pipeline = pipelines.add_render("Skybox", pd);

    fg.add_pass("Skybox")
        .read(env_image, rhi::ResourceState::TextureSample)
        .write(main_image, rhi::ResourceState::ColorDraw)
        .write(depth_image, rhi::ResourceState::DepthDraw)
        .execute([=, &pipeline](PassContext &ctx) {
            auto main_view = ctx.image_view(main_image, {.aspect = rhi::ImageAspect::Color, .mip_count = 1});
            auto depth_attach = ctx.image_view(depth_image, {.aspect = rhi::ImageAspect::Depth, .mip_count = 1});

            rhi::AttachmentDesc color_att{};
            color_att.img = &main_view;
            color_att.loadOp = rhi::LoadOp::LOAD;
            color_att.storeOp = rhi::StoreOp::STORE;
            rhi::AttachmentDesc depth_att{};
            depth_att.img = &depth_attach;
            depth_att.loadOp = rhi::LoadOp::LOAD;
            depth_att.storeOp = rhi::StoreOp::STORE;

            rhi::RenderingInfo ri{};
            ri.colorAttachments[0] = color_att;
            ri.colorAttachmentCount = 1;
            ri.depthAttachment = depth_att;
            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);

            auto &frame = ctx.frame_data[ctx.frame_index];
            SkyboxPushConstants pc{};
            // Persistent IBL cubemap slot, written once at startup — no per-frame write.
            pc.cubemap = ctx.scene->env.environmentIdx;
            pc.depth_tex_idx = ctx.view(depth_image);
            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);
            }

            rhi::draw(ctx.cmd, 3, 1, 0, 0);
            rhi::end_rendering(ctx.cmd);
        });
}