From 94bbdb8427751c738517b787dfca229cdcc03679 Mon Sep 17 00:00:00 2001 From: Katajisto Date: Sat, 2 May 2026 13:38:53 +0300 Subject: [PATCH] work on improving trile gathering --- src/audio/backend.jai | 6 +- src/editor/iprof.jai | 2 +- src/rendering/arbtri.jai | 29 ++++--- src/rendering/helpers.jai | 170 +++++++++++--------------------------- src/rendering/tasks.jai | 2 +- 5 files changed, 73 insertions(+), 136 deletions(-) diff --git a/src/audio/backend.jai b/src/audio/backend.jai index ee3a8b1..62d5db4 100644 --- a/src/audio/backend.jai +++ b/src/audio/backend.jai @@ -9,11 +9,15 @@ audio_init_thread_context :: () { audio_thread_context.temporary_storage = *audio_thread_temp_storage; audio_thread_temp_storage.data = audio_thread_temp_storage_data.data; audio_thread_temp_storage.size = audio_thread_temp_storage_data.count; + // Iprof's zone stack/hash are global. The audio callback runs on a separate // thread, so any instrumented call from inside it races with the main thread // and corrupts those globals. Mark this context as "inside profiler runtime" // so Automatic_Zone_Guarded skips the begin/end on this thread. - audio_thread_context.already_inside_profiler_runtime = true; + #if FLAG_IPROF_ENABLED { + audio_thread_context.already_inside_profiler_runtime = true; + } + audio_thread_context_ready = true; } diff --git a/src/editor/iprof.jai b/src/editor/iprof.jai index 880464e..afcfa11 100644 --- a/src/editor/iprof.jai +++ b/src/editor/iprof.jai @@ -101,7 +101,7 @@ draw_profiler :: () { draw_rectangle(.{xx(w-700), 0, 700, xx(h) }, .{0,0,0,1}); __Iprof.draw(xx (w - 700), 20, 699, xx h, *iprof_conf); if profiler_mode == .FULL { - __Iprof.draw_graph(0, 100, xx(w-700), 100, *iprof_conf); + __Iprof.draw_graph(0, 0, xx(w-700), 300, *iprof_conf); } } diff --git a/src/rendering/arbtri.jai b/src/rendering/arbtri.jai index 01406fb..0c6857f 100644 --- a/src/rendering/arbtri.jai +++ b/src/rendering/arbtri.jai @@ -82,24 +82,31 @@ arb_tri_flush :: () { - arbTriState.active = false; + arbTriState.active = false; + + w, h := get_window_size(); + inv_w := 2.0 / cast(float) w; + inv_h := 2.0 / cast(float) h; for tri, i : arbTriState.trilist { bgn := i * 3 * 9; for 0..2 { - gArbtriMem[bgn + it * 9 + 0] = transform_to_screen_x(tri.pos[it].x); - gArbtriMem[bgn + it * 9 + 1] = transform_to_screen_y(tri.pos[it].y) * -1.0; - gArbtriMem[bgn + it * 9 + 2] = 0; - gArbtriMem[bgn + it * 9 + 3] = tri.col[it].x; - gArbtriMem[bgn + it * 9 + 4] = tri.col[it].y; - gArbtriMem[bgn + it * 9 + 5] = tri.col[it].z; - gArbtriMem[bgn + it * 9 + 6] = tri.col[it].w; - gArbtriMem[bgn + it * 9 + 7] = tri.uv[it].x; - gArbtriMem[bgn + it * 9 + 8] = tri.uv[it].y; + gArbtriMem[bgn + it * 9 + 0] = tri.pos[it].x * inv_w - 1.0; + gArbtriMem[bgn + it * 9 + 1] = -(tri.pos[it].y * inv_h - 1.0); + gArbtriMem[bgn + it * 9 + 2] = 0; + gArbtriMem[bgn + it * 9 + 3] = tri.col[it].x; + gArbtriMem[bgn + it * 9 + 4] = tri.col[it].y; + gArbtriMem[bgn + it * 9 + 5] = tri.col[it].z; + gArbtriMem[bgn + it * 9 + 6] = tri.col[it].w; + gArbtriMem[bgn + it * 9 + 7] = tri.uv[it].x; + gArbtriMem[bgn + it * 9 + 8] = tri.uv[it].y; } } - sg_update_buffer(gPipelines.arbtri.bind.vertex_buffers[0], *(sg_range.{ ptr = gArbtriMem.data, size = size_of(type_of(gArbtriMem)) })); + upload_size := arbTriState.trilist.count * 3 * 9 * size_of(float); + if upload_size > 0 { + sg_update_buffer(gPipelines.arbtri.bind.vertex_buffers[0], *(sg_range.{ ptr = gArbtriMem.data, size = xx upload_size })); + } flush_arb_commands(); } diff --git a/src/rendering/helpers.jai b/src/rendering/helpers.jai index 96b564e..621ca9c 100644 --- a/src/rendering/helpers.jai +++ b/src/rendering/helpers.jai @@ -12,17 +12,6 @@ fill_uniform_with_engine_data :: (uniform: *$A, enginedata: *$B) { #insert #run,stallable generate_copy_code(); } -Gathered_Positions :: struct { - name: string; - chunk_key: Chunk_Key; - positions: [..]Vector4; -} - -Gathered_Rdm_Position :: struct { - name: string; - position: Vector4; -} - extract_frustum_planes :: (mvp: Matrix4) -> [6]Vector4 { planes : [6]Vector4; m := mvp; @@ -35,7 +24,7 @@ extract_frustum_planes :: (mvp: Matrix4) -> [6]Vector4 { return planes; } -aabb_in_frustum :: (planes: [6]Vector4, bmin: Vector3, bmax: Vector3) -> bool { +aabb_in_frustum :: inline (planes: [6]Vector4, bmin: Vector3, bmax: Vector3) -> bool { for plane: planes { px := ifx plane.x >= 0 then bmax.x else bmin.x; py := ifx plane.y >= 0 then bmax.y else bmin.y; @@ -57,6 +46,25 @@ LOD_DISTANCES :: float.[50.0, 100.0, 200.0]; FOG_START :: 60.0; FOG_END :: 195.0; + +shad_gathered : [..]Gathered_Positions; +rdm_extra : [..]Gathered_Positions; +rdm_main : [..]Gathered_Rdm_Position; +gathered_per_lod : [3][..]Gathered_Positions; + +Gathered_Positions :: struct { + trile : string; + chunk_key : Chunk_Key; + positions : [..]Vector4; +} + +Gathered_Rdm_Position :: struct { + name: string; + position: Vector4; +} + +gathered_chunk_tasks : [..]Gathered_Positions; + create_world_rendering_tasks :: (world: *World, camera: Camera, plane_height: float = 0) { create_sky_rendering_task(*world.conf); create_set_light_rendering_task(*world.conf); @@ -74,123 +82,41 @@ create_world_rendering_tasks :: (world: *World, camera: Camera, plane_height: fl reflect_mvp := create_viewproj(*reflect_cam); reflect_planes := extract_frustum_planes(reflect_mvp); - // Gather positions for camera-visible instances (all passes) and - // shadow-only instances (chunks visible from sun but not camera). - gathered_per_lod : [3][..]Gathered_Positions; - for i: 0..2 gathered_per_lod[i].allocator = temp; - shad_gathered : [..]Gathered_Positions; - shad_gathered.allocator = temp; - rdm_extra : [..]Gathered_Positions; // RDM-flagged instances visible to camera; shadow/gbuffer/reflection use base pipeline - rdm_extra.allocator = temp; - rdm_main : [..]Gathered_Rdm_Position; // one entry per RDM-flagged instance for the main pass - rdm_main.allocator = temp; + for chunk: world.chunks { + chunk_quadrant_vis : [8]bool; + any_vis : bool; - find_or_create :: (list: *[..]Gathered_Positions, name: string, chunk_key: Chunk_Key) -> *Gathered_Positions { - for *g: list.* { - if g.name == name && g.chunk_key == chunk_key return g; - } - array_add(list, .{name = name, chunk_key = chunk_key}); - g := *list.*[list.count - 1]; - g.positions.allocator = temp; - return g; - } - - for chunk: world.chunks { - bmin := Vector3.{chunk.coord.x * 32.0, chunk.coord.y * 32.0, chunk.coord.z * 32.0}; - bmax := bmin + .{32, 32, 32}; - - in_cam := aabb_in_frustum(cam_planes, bmin, bmax); - in_reflect := aabb_in_frustum(reflect_planes, bmin, bmax); - in_shad := aabb_in_frustum(shadow_planes, bmin, bmax); - if !in_cam && !in_reflect && !in_shad continue; - - for group: chunk.groups { - for inst, idx: group.instances { - if idx < group.is_buried.count && group.is_buried[idx] continue; - wx, wy, wz := chunk_local_to_world(chunk.coord, inst.x, inst.y, inst.z); - imin := Vector3.{cast(float)wx, cast(float)wy, cast(float)wz}; - imax := imin + .{1, 1, 1}; - - inst_cam := in_cam && aabb_in_frustum(cam_planes, imin, imax); - inst_reflect := in_reflect && aabb_in_frustum(reflect_planes, imin, imax); - inst_shad := in_shad && aabb_in_frustum(shadow_planes, imin, imax); - if !inst_cam && !inst_reflect && !inst_shad continue; - - dist := length(imin + .{0.5, 0.5, 0.5} - camera.position); - - lod_idx : s32 = -1; - for i: 0..2 { - if dist < LOD_DISTANCES[i] { - lod_idx = cast(s32) i; - break; - } - } - if lod_idx < 0 continue; // beyond cull distance - - pos := Vector4.{cast(float)wx, cast(float)wy, cast(float)wz, cast(float)inst.orientation}; - is_rdm := is_rdm_instance_enabled(world, wx, wy, wz); - if inst_cam || inst_reflect { - if is_rdm { - target := find_or_create(*rdm_extra, group.trile_name, chunk.coord); - array_add(*target.positions, pos); - if inst_cam { - array_add(*rdm_main, .{name = group.trile_name, position = pos}); - } - } else { - target := find_or_create(*gathered_per_lod[lod_idx], group.trile_name, chunk.coord); - array_add(*target.positions, pos); - } - } else { - target := find_or_create(*shad_gathered, group.trile_name, chunk.coord); - array_add(*target.positions, pos); + for i: 0..1 { + for j: 0..1 { + for k: 0..1 { + bmin := Vector3.{ + chunk.coord.x * 32.0 + i * 16.0, + chunk.coord.y * 32.0 + j * 16.0, + chunk.coord.z * 32.0 + k * 16.0 + }; + bmax := bmin + .{16, 16, 16}; + in_cam := aabb_in_frustum(cam_planes, bmin, bmax); + in_reflect := aabb_in_frustum(reflect_planes, bmin, bmax); + in_shad := aabb_in_frustum(shadow_planes, bmin, bmax); + vis := in_cam || in_reflect || in_shad; + chunk_quadrant_vis[i+j*2+k*2*2] = vis; + if !any_vis then any_vis = vis; } } } - } - for lod_idx: 0..2 { - for g: gathered_per_lod[lod_idx] { - if g.positions.count < 1 continue; - triletask : Rendering_Task_Trile; - triletask.trile = g.name; - triletask.chunk_key = g.chunk_key; - triletask.positions = g.positions; - triletask.worldConf = *world.conf; - triletask.lod_index = cast(s32) lod_idx; - add_rendering_task(triletask); + for group : chunk.group { + task := Rendering_Task_Trile.{ + trile = group.trile_name, + chunk_key = chunk.coord, + positions = group.instances, + worldConf = world.conf + }; + add_rendering_task(*task); } + } - for g: shad_gathered { - if g.positions.count < 1 continue; - triletask : Rendering_Task_Trile; - triletask.trile = g.name; - triletask.chunk_key = g.chunk_key; - triletask.positions = g.positions; - triletask.worldConf = *world.conf; - triletask.shadow_only = true; - add_rendering_task(triletask); - } - for g: rdm_extra { - if g.positions.count < 1 continue; - triletask : Rendering_Task_Trile; - triletask.trile = g.name; - triletask.chunk_key = g.chunk_key; - triletask.positions = g.positions; - triletask.worldConf = *world.conf; - triletask.skip_main = true; - add_rendering_task(triletask); - } - for r: rdm_main { - rect, found := rdm_get_atlas_rect(world, cast(s32) r.position.x, cast(s32) r.position.y, cast(s32) r.position.z); - if !found then continue; - rdmtask : Rendering_Task_Trile_RDM; - rdmtask.trile = r.name; - rdmtask.position = r.position; - rdmtask.atlas_rect = rect; - rdmtask.worldConf = *world.conf; - add_rendering_task(rdmtask); - } - + create_ground_rendering_task(world); } diff --git a/src/rendering/tasks.jai b/src/rendering/tasks.jai index 0e33e4d..4bb8aa6 100644 --- a/src/rendering/tasks.jai +++ b/src/rendering/tasks.jai @@ -57,7 +57,7 @@ Rendering_Task_Trile :: struct { t.type = .TRILE; trile : string; chunk_key : Chunk_Key; - positions : []Vector4; + positions : []Trile_Instance; worldConf : *World_Config; preview_mode : s32 = 0; // 0=normal, 1=add preview (blue), 2=delete preview (red) shadow_only : bool = false; // only submit to shadow bucket (frustum-culled from camera)