diff options
Diffstat (limited to 'c2.cpp')
-rw-r--r-- | c2.cpp | 134 |
1 files changed, 111 insertions, 23 deletions
@@ -80,6 +80,7 @@ static Sampler_Id create_clamped_linear(Device* dev) { Sampler_State s{}; s.min = Filter_Mode::linear; s.mag = Filter_Mode::linear; + s.mip = Filter_Mode::linear; s.address_u = Address_Mode::repeat; s.address_v = Address_Mode::repeat; return dev->create_sampler("repeated linear", s); @@ -281,12 +282,16 @@ struct Sky { }; struct Env_Probe { - Texture_Id cubemap; + static constexpr int mip_count = 9; + Texture_Id cubemap[2]; Texture_Id cubemap_depth; - Texture_Id faces[6]; + Texture_Id faces[2][6][mip_count]; Sampler_Id sampler; int cubemap_res; + int completed; Staged_Buffer config; + Shader* shader; + int src_binding, vert_binding; void init(Device* dev, Asset_Arena* assets, int res) { int i; @@ -294,8 +299,10 @@ struct Env_Probe { cubemap_res = res; s.min = Filter_Mode::linear; s.mag = Filter_Mode::linear; + s.mip = Filter_Mode::linear; s.address_u = Address_Mode::repeat; s.address_v = Address_Mode::repeat; + s.address_w = Address_Mode::repeat; sampler = dev->create_sampler("env probe sampler", s); cubemap_depth = dev->create_texture( "env cubemap depth", @@ -308,8 +315,8 @@ struct Env_Probe { 1, 0 ); - cubemap = dev->create_texture( - "env cubemap", + cubemap[0] = dev->create_texture( + "env cubemap A", texture_format_rgba16f, Texture_Flags::cubemap | Texture_Flags::colour_target | @@ -317,25 +324,59 @@ struct Env_Probe { res, res, 1, - 0, + mip_count, + 1, + Buffer_Id(0) + ); + cubemap[1] = dev->create_texture( + "env cubemap B", + texture_format_rgba16f, + Texture_Flags::cubemap | + Texture_Flags::colour_target | + Texture_Flags::sampleable, + res, + res, + 1, + mip_count, 1, Buffer_Id(0) ); for (i = 0; i < 6; i++) { - faces[i] = dev->alias_texture( - cubemap, - "env cubemap face", - texture_format_rgba16f, - Texture_Flags::colour_target | - Texture_Flags::sampleable, - res, - res, - 1, - 1, - 1, - 0, - i - ); + int j; + int w = res; + int h = res; + for (j = 0; j < mip_count; j++) { + faces[0][i][j] = dev->alias_texture( + cubemap[0], + "env cubemap face A", + texture_format_rgba16f, + Texture_Flags::colour_target | + Texture_Flags::sampleable, + w, + h, + 1, + 1, + 1, + j, + i + ); + faces[1][i][j] = dev->alias_texture( + cubemap[1], + "env cubemap face B", + texture_format_rgba16f, + Texture_Flags::colour_target | + Texture_Flags::sampleable, + w, + h, + 1, + 1, + 1, + j, + i + ); + w /= 2; + h /= 2; + } } config.init( dev, @@ -343,16 +384,26 @@ struct Env_Probe { sizeof(Sky::Cbuffer) * 6, Buffer_Flags::constant_buffer ); + shader = (Shader*)assets->load("mip_spec.csh"); + src_binding = shader->descriptor_binding("src"); + vert_binding = shader->binding_index("verts"); + assert(src_binding >= 0); + assert(vert_binding >= 0); } void destroy(Device* dev) { int i; for (i = 0; i < 6; i++) { - dev->destroy_texture(faces[i]); + int j; + for (j = 0; j < mip_count; j++) { + dev->destroy_texture(faces[0][i][j]); + dev->destroy_texture(faces[1][i][j]); + } } dev->destroy_texture(cubemap_depth); dev->destroy_sampler(sampler); - dev->destroy_texture(cubemap); + dev->destroy_texture(cubemap[0]); + dev->destroy_texture(cubemap[1]); config.destroy(dev); } @@ -399,7 +450,7 @@ struct Env_Probe { update_cbuffer(dev); for (i = 0; i < 6; i++) { pb.begin_rp(); - pb.rp_target(faces[i], Clear_Mode::discard); + pb.rp_target(faces[0][i][0], Clear_Mode::discard); pb.rp_depth_target(cubemap_depth, 1.0f); sky.render_imp( dev, @@ -412,6 +463,43 @@ struct Env_Probe { cubemap_res ); } + completed = 0; + for (i = 0; i < 6; i++) { + int j; + for (j = 0; j < mip_count; j++) { + Texture& t = dev->get_texture(faces[completed ^ 1][i][j]); + pb.begin_rp(); + pb.rp_target(t.id, Clear_Mode::discard); + Render_Pass& pass = pb.build_rp(); + pb.begin(); + pb.viewport(0, 0, t.w, t.h); + pb.scissor(0, 0, t.w, t.h); + pb.texture( + src_binding, + faces[completed][i][0], + sampler + ); + pb.shader(shader->id); + pb.vertex_format(shader->vf); + Pipeline& pip = pb.build(); + + Vertex_Buffer_Binding vbb[] = {{ + .id = sky.vb, + .offset = 0, + .target = vert_binding + }, {}}; + Draw draw{}; + draw.verts = vbb; + draw.vertex_count = 3; + draw.instance_count = 1; + ctx.submit(draw, pip, pass); + } + } + completed = 1; + } + + Texture_Id get_cubemap() { + return cubemap[completed]; } }; @@ -612,7 +700,7 @@ struct C2 : public App { scene.render(dev, &frame_arena, depth_prepass, 0, clamped_linear); ctx.debug_pop(); ctx.debug_push("forward"); - scene.render(dev, &frame_arena, pass2, eprobe.cubemap, clamped_linear); + scene.render(dev, &frame_arena, pass2, eprobe.get_cubemap(), clamped_linear); ctx.debug_pop(); ctx.debug_pop(); |