work on improving trile gathering
This commit is contained in:
parent
dcad1dbe7f
commit
94bbdb8427
@ -9,11 +9,15 @@ audio_init_thread_context :: () {
|
|||||||
audio_thread_context.temporary_storage = *audio_thread_temp_storage;
|
audio_thread_context.temporary_storage = *audio_thread_temp_storage;
|
||||||
audio_thread_temp_storage.data = audio_thread_temp_storage_data.data;
|
audio_thread_temp_storage.data = audio_thread_temp_storage_data.data;
|
||||||
audio_thread_temp_storage.size = audio_thread_temp_storage_data.count;
|
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
|
// 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
|
// thread, so any instrumented call from inside it races with the main thread
|
||||||
// and corrupts those globals. Mark this context as "inside profiler runtime"
|
// and corrupts those globals. Mark this context as "inside profiler runtime"
|
||||||
// so Automatic_Zone_Guarded skips the begin/end on this thread.
|
// so Automatic_Zone_Guarded skips the begin/end on this thread.
|
||||||
|
#if FLAG_IPROF_ENABLED {
|
||||||
audio_thread_context.already_inside_profiler_runtime = true;
|
audio_thread_context.already_inside_profiler_runtime = true;
|
||||||
|
}
|
||||||
|
|
||||||
audio_thread_context_ready = true;
|
audio_thread_context_ready = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -101,7 +101,7 @@ draw_profiler :: () {
|
|||||||
draw_rectangle(.{xx(w-700), 0, 700, xx(h) }, .{0,0,0,1});
|
draw_rectangle(.{xx(w-700), 0, 700, xx(h) }, .{0,0,0,1});
|
||||||
__Iprof.draw(xx (w - 700), 20, 699, xx h, *iprof_conf);
|
__Iprof.draw(xx (w - 700), 20, 699, xx h, *iprof_conf);
|
||||||
if profiler_mode == .FULL {
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -84,11 +84,15 @@ 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 {
|
for tri, i : arbTriState.trilist {
|
||||||
bgn := i * 3 * 9;
|
bgn := i * 3 * 9;
|
||||||
for 0..2 {
|
for 0..2 {
|
||||||
gArbtriMem[bgn + it * 9 + 0] = transform_to_screen_x(tri.pos[it].x);
|
gArbtriMem[bgn + it * 9 + 0] = tri.pos[it].x * inv_w - 1.0;
|
||||||
gArbtriMem[bgn + it * 9 + 1] = transform_to_screen_y(tri.pos[it].y) * -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 + 2] = 0;
|
||||||
gArbtriMem[bgn + it * 9 + 3] = tri.col[it].x;
|
gArbtriMem[bgn + it * 9 + 3] = tri.col[it].x;
|
||||||
gArbtriMem[bgn + it * 9 + 4] = tri.col[it].y;
|
gArbtriMem[bgn + it * 9 + 4] = tri.col[it].y;
|
||||||
@ -99,7 +103,10 @@ arb_tri_flush :: () {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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();
|
flush_arb_commands();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,17 +12,6 @@ fill_uniform_with_engine_data :: (uniform: *$A, enginedata: *$B) {
|
|||||||
#insert #run,stallable generate_copy_code();
|
#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 {
|
extract_frustum_planes :: (mvp: Matrix4) -> [6]Vector4 {
|
||||||
planes : [6]Vector4;
|
planes : [6]Vector4;
|
||||||
m := mvp;
|
m := mvp;
|
||||||
@ -35,7 +24,7 @@ extract_frustum_planes :: (mvp: Matrix4) -> [6]Vector4 {
|
|||||||
return planes;
|
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 {
|
for plane: planes {
|
||||||
px := ifx plane.x >= 0 then bmax.x else bmin.x;
|
px := ifx plane.x >= 0 then bmax.x else bmin.x;
|
||||||
py := ifx plane.y >= 0 then bmax.y else bmin.y;
|
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_START :: 60.0;
|
||||||
FOG_END :: 195.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_world_rendering_tasks :: (world: *World, camera: Camera, plane_height: float = 0) {
|
||||||
create_sky_rendering_task(*world.conf);
|
create_sky_rendering_task(*world.conf);
|
||||||
create_set_light_rendering_task(*world.conf);
|
create_set_light_rendering_task(*world.conf);
|
||||||
@ -74,121 +82,39 @@ create_world_rendering_tasks :: (world: *World, camera: Camera, plane_height: fl
|
|||||||
reflect_mvp := create_viewproj(*reflect_cam);
|
reflect_mvp := create_viewproj(*reflect_cam);
|
||||||
reflect_planes := extract_frustum_planes(reflect_mvp);
|
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;
|
|
||||||
|
|
||||||
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 {
|
for chunk: world.chunks {
|
||||||
bmin := Vector3.{chunk.coord.x * 32.0, chunk.coord.y * 32.0, chunk.coord.z * 32.0};
|
chunk_quadrant_vis : [8]bool;
|
||||||
bmax := bmin + .{32, 32, 32};
|
any_vis : bool;
|
||||||
|
|
||||||
|
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_cam := aabb_in_frustum(cam_planes, bmin, bmax);
|
||||||
in_reflect := aabb_in_frustum(reflect_planes, bmin, bmax);
|
in_reflect := aabb_in_frustum(reflect_planes, bmin, bmax);
|
||||||
in_shad := aabb_in_frustum(shadow_planes, bmin, bmax);
|
in_shad := aabb_in_frustum(shadow_planes, bmin, bmax);
|
||||||
if !in_cam && !in_reflect && !in_shad continue;
|
vis := in_cam || in_reflect || in_shad;
|
||||||
|
chunk_quadrant_vis[i+j*2+k*2*2] = vis;
|
||||||
for group: chunk.groups {
|
if !any_vis then any_vis = vis;
|
||||||
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 lod_idx: 0..2 {
|
for group : chunk.group {
|
||||||
for g: gathered_per_lod[lod_idx] {
|
task := Rendering_Task_Trile.{
|
||||||
if g.positions.count < 1 continue;
|
trile = group.trile_name,
|
||||||
triletask : Rendering_Task_Trile;
|
chunk_key = chunk.coord,
|
||||||
triletask.trile = g.name;
|
positions = group.instances,
|
||||||
triletask.chunk_key = g.chunk_key;
|
worldConf = world.conf
|
||||||
triletask.positions = g.positions;
|
};
|
||||||
triletask.worldConf = *world.conf;
|
add_rendering_task(*task);
|
||||||
triletask.lod_index = cast(s32) lod_idx;
|
|
||||||
add_rendering_task(triletask);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
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);
|
create_ground_rendering_task(world);
|
||||||
|
|||||||
@ -57,7 +57,7 @@ Rendering_Task_Trile :: struct {
|
|||||||
t.type = .TRILE;
|
t.type = .TRILE;
|
||||||
trile : string;
|
trile : string;
|
||||||
chunk_key : Chunk_Key;
|
chunk_key : Chunk_Key;
|
||||||
positions : []Vector4;
|
positions : []Trile_Instance;
|
||||||
worldConf : *World_Config;
|
worldConf : *World_Config;
|
||||||
preview_mode : s32 = 0; // 0=normal, 1=add preview (blue), 2=delete preview (red)
|
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)
|
shadow_only : bool = false; // only submit to shadow bucket (frustum-culled from camera)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user