#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