diff --git a/src/base/base.h b/src/base/base.h index e1ce672a..6570e9bd 100644 --- a/src/base/base.h +++ b/src/base/base.h @@ -628,7 +628,7 @@ #define CompLit(cstr_lit) { .len = (sizeof((cstr_lit)) - 1), .text = (u8 *)(cstr_lit) } #define StringFromPointers(p0, p1) ((String) { (u8 *)(p1) - (u8 *)(p0), (u8 *)p0 }) #define StringFromStruct(ptr) ((String) { sizeof(*(ptr)), (u8 *)(ptr) }) - #define StringFromArena(arena) (STRING((arena)->pos, ArenaBase(arena))) + #define StringFromArena(arena) (STRING((arena)->pos, ArenaFirst(arena, u8))) /* String from static array */ #define StringFromArray(a) \ diff --git a/src/base/base_gpu.hlsl b/src/base/base_gpu.hlsl index f568796f..268ef3c3 100644 --- a/src/base/base_gpu.hlsl +++ b/src/base/base_gpu.hlsl @@ -38,7 +38,7 @@ template RWTexture3D RWTexture3DFromHandle(RWTexture3DHand SamplerState SamplerStateFromHandle(SamplerStateHandle h) { return SamplerDescriptorHeap[NonUniformResourceIndex(h.v)]; } //////////////////////////////////////////////////////////// -//~ Texture dimension helpers +//~ Dimension helpers u32 Count1D(Texture1D tex) { @@ -85,6 +85,29 @@ Vec3U32 Count3D(RWTexture3D tex) return result; } +//////////////////////////////////////////////////////////// +//~ Color helpers + +Vec4 Vec4FromU32(u32 v) +{ + Vec4 result; + result.x = ((v >> 0) & 0xFF) / 255.0; + result.y = ((v >> 8) & 0xFF) / 255.0; + result.z = ((v >> 16) & 0xFF) / 255.0; + result.w = ((v >> 24) & 0xFF) / 255.0; + return result; +} + +u32 U32FromVec4(Vec4 v) +{ + u32 result; + result |= (((u32)(v.x * 255.0)) & 0xFF) << 0; + result |= (((u32)(v.y * 255.0)) & 0xFF) << 8; + result |= (((u32)(v.z * 255.0)) & 0xFF) << 16; + result |= (((u32)(v.w * 255.0)) & 0xFF) << 24; + return result; +} + //////////////////////////////////////////////////////////// //~ Vertex ID helpers diff --git a/src/config.h b/src/config.h index de83fc90..36009283 100644 --- a/src/config.h +++ b/src/config.h @@ -69,8 +69,8 @@ #define FLOOD_DEBUG 0 -#define GPU_DEBUG 0 -#define GPU_DEBUG_VALIDATION 0 +#define GPU_DEBUG 1 +#define GPU_DEBUG_VALIDATION 1 /* If enabled, bitbuffs will insert/verify magic numbers & length for each read & write */ #define BITBUFF_DEBUG 0 diff --git a/src/gpu/gpu_common.c b/src/gpu/gpu_common.c index 259408d5..bf35b054 100644 --- a/src/gpu/gpu_common.c +++ b/src/gpu/gpu_common.c @@ -23,9 +23,7 @@ void GPU_StartupCommon(void) u16 quad_data[6] = { 0, 1, 2, 0, 2, 3 }; GPU_ResourceHandle quad_indices = GPU_PushBuffer(gpu_perm, u16, countof(quad_data)); GPU_CopyCpuToBuffer(cl, quad_indices, 0, quad_data, RNGU64(0, sizeof(quad_data))); - g->quad_indices.resource = quad_indices; - g->quad_indices.index_size = sizeof(quad_data[0]); - g->quad_indices.index_count = countof(quad_data); + g->quad_indices = GPU_IdxBuff16(quad_indices); } /* TODO: Init noise texture */ @@ -70,18 +68,16 @@ GPU_ArenaHandle GPU_PermArena(void) //- Cpu -> Gpu copy -StructuredBufferHandle GPU_PushStructuredBufferFromCpu_(GPU_ArenaHandle gpu_arena, GPU_CommandListHandle cl, void *src, u32 element_size, u32 element_count) +GPU_ResourceHandle GPU_PushBufferFromCpu(GPU_ArenaHandle gpu_arena, GPU_CommandListHandle cl, String src) { - u64 size = (u64)element_size * (u64)element_count; - GPU_ResourceHandle buffer = GPU_PushBufferEx(gpu_arena, (GPU_BufferDesc) { .size = size }); - GPU_CopyCpuToBuffer(cl, buffer, 0, src, RNGU64(0, size)); - StructuredBufferHandle structured_buffer = GPU_PushStructuredBufferHandleEx(gpu_arena, buffer, element_size, RNGU32(0, element_count)); + GPU_ResourceHandle buffer = GPU_PushBufferEx(gpu_arena, (GPU_BufferDesc) { .size = src.len }); + GPU_CopyCpuToBuffer(cl, buffer, 0, src.text, RNGU64(0, src.len)); GPU_MemorySync( cl, buffer, - GPU_Stage_None, GPU_Access_None, + GPU_Stage_Copy, GPU_Access_CopyWrite, GPU_Stage_AllShading, GPU_Access_ShaderRead ); - return structured_buffer; + return buffer; } //- Viewport / scissor diff --git a/src/gpu/gpu_common.h b/src/gpu/gpu_common.h index 1e1b8bf8..752be9ad 100644 --- a/src/gpu/gpu_common.h +++ b/src/gpu/gpu_common.h @@ -25,9 +25,7 @@ GPU_ArenaHandle GPU_PermArena(void); //- Cpu -> Gpu copy -StructuredBufferHandle GPU_PushStructuredBufferFromCpu_(GPU_ArenaHandle gpu_arena, GPU_CommandListHandle cl, void *src, u32 element_size, u32 element_count); -#define GPU_PushStructuredBufferFromCpu(gpu_arena, cl, ptr, count) \ - GPU_PushStructuredBufferFromCpu_((gpu_arena), (cl), (ptr), sizeof(*ptr), count); +GPU_ResourceHandle GPU_PushBufferFromCpu(GPU_ArenaHandle gpu_arena, GPU_CommandListHandle cl, String src); //- Viewport / scissor diff --git a/src/gpu/gpu_core.h b/src/gpu/gpu_core.h index 40e91e46..e0ce4753 100644 --- a/src/gpu/gpu_core.h +++ b/src/gpu/gpu_core.h @@ -495,9 +495,6 @@ void GPU_Startup(void); GPU_ArenaHandle GPU_AcquireArena(void); void GPU_ReleaseArena(GPU_ArenaHandle arena); -void GPU_ResetArena(GPU_CommandListHandle cl, GPU_ArenaHandle arena); -void GPU_ResetArenaFromQueue(GPU_QueueKind queue, GPU_ArenaHandle arena); - //////////////////////////////////////////////////////////// //~ @hookdecl Resource @@ -544,7 +541,7 @@ GPU_ResourceHandle GPU_PushSampler(GPU_ArenaHandle arena, GPU_SamplerDesc desc); } \ ) -//- Shader resource handle creation +//- Shader handle creation StructuredBufferHandle GPU_PushStructuredBufferHandleEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); RWStructuredBufferHandle GPU_PushRWStructuredBufferHandleEx (GPU_ArenaHandle arena, GPU_ResourceHandle resource, u32 element_size, RngU32 element_range); @@ -559,6 +556,11 @@ SamplerStateHandle GPU_PushSamplerStateHandle (GPU_ArenaHandle #define GPU_PushStructuredBufferHandle(arena, resource, type) GPU_PushStructuredBufferHandleEx((arena), (resource), sizeof(type), RNGU32(0, GPU_CountBuffer((resource), type))) #define GPU_PushRWStructuredBufferHandle(arena, resource, type) GPU_PushRWStructuredBufferHandleEx((arena), (resource), sizeof(type), RNGU32(0, GPU_CountBuffer((resource), type))) +//- Index buffer creation + +#define GPU_IdxBuff16(_res) ((GPU_IndexBufferDesc) { .resource = (_res), .index_size = 2, .index_count = (GPU_CountBuffer((_res), i16)) }) +#define GPU_IdxBuff32(_res) ((GPU_IndexBufferDesc) { .resource = (_res), .index_size = 4, .index_count = (GPU_CountBuffer((_res), i32)) }) + //- Count u64 GPU_CountBufferBytes(GPU_ResourceHandle buffer); @@ -569,7 +571,7 @@ i32 GPU_CountWidth(GPU_ResourceHandle texture); i32 GPU_CountHeight(GPU_ResourceHandle texture); i32 GPU_CountDepth(GPU_ResourceHandle texture); -#define GPU_CountBuffer(buffer, type) GPU_CountBufferSize(buffer) / sizeof(type) +#define GPU_CountBuffer(buffer, type) GPU_CountBufferBytes(buffer) / sizeof(type) //////////////////////////////////////////////////////////// //~ @hookdecl Command @@ -581,6 +583,10 @@ void GPU_CommitCommandListEx(GPU_CommandListHandle cl, u64 fence_ops_count, GPU_ #define GPU_CommitCommandList(cl) GPU_CommitCommandListEx((cl), 0, 0) +//- Arena + +void GPU_ResetArena(GPU_CommandListHandle cl, GPU_ArenaHandle arena); + //- Cpu -> Gpu copy void GPU_CopyCpuToBuffer(GPU_CommandListHandle cl, GPU_ResourceHandle dst, u64 dst_offset, void *src, RngU64 src_copy_range); diff --git a/src/gpu/gpu_dx12/gpu_dx12.c b/src/gpu/gpu_dx12/gpu_dx12.c index c45dad30..2de16cf3 100644 --- a/src/gpu/gpu_dx12/gpu_dx12.c +++ b/src/gpu/gpu_dx12/gpu_dx12.c @@ -519,7 +519,7 @@ GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc) hr = ID3D12Device_CreateGraphicsPipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); if (FAILED(hr)) { - error_str = Lit("Failed to create pipeline state object"); + error_str = Lit("Failed to create graphics pipeline"); ok = 0; } } @@ -534,7 +534,7 @@ GPU_D12_Pipeline *GPU_D12_PipelineFromDesc(GPU_D12_PipelineDesc desc) hr = ID3D12Device_CreateComputePipelineState(g->device, &pso_desc, &IID_ID3D12PipelineState, (void **)&pso); if (FAILED(hr)) { - error_str = Lit("Failed to create pipeline state object"); + error_str = Lit("Failed to create compute pipeline"); ok = 0; } } @@ -761,27 +761,6 @@ void GPU_ReleaseArena(GPU_ArenaHandle arena) /* TODO */ } -void GPU_ResetArena(GPU_CommandListHandle cl_handle, GPU_ArenaHandle arena_handle) -{ - GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); - - /* TODO */ - - /* FIXME: Move descriptors into committed lists */ - - /* FIXME: Release id3d12 resource com object references */ - gpu_arena->heap_pos = 0; -} - -void GPU_ResetArenaFromQueue(GPU_QueueKind queue_kind, GPU_ArenaHandle arena_handle) -{ - GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); - - /* TODO */ - - gpu_arena->heap_pos = 0; -} - //////////////////////////////////////////////////////////// //~ Resource helpers @@ -1058,36 +1037,48 @@ GPU_ResourceHandle GPU_PushSampler(GPU_ArenaHandle arena_handle, GPU_SamplerDesc return GPU_D12_MakeHandle(GPU_ResourceHandle, resource); } -//- Pointer creation +//- Shader handle creation StructuredBufferHandle GPU_PushStructuredBufferHandleEx(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle, u32 element_size, RngU32 element_range) { GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); - GPU_D12_Resource *resource = GPU_D12_ResourceFromHandle(resource_handle); - GPU_D12_Descriptor *descriptor = GPU_D12_PushDescriptor(gpu_arena, GPU_D12_DescriptorHeapKind_CbvSrvUav); + u32 num_elements = element_range.max - element_range.min; + StructuredBufferHandle result = ZI; + if (num_elements > 0) { - D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI; - srv_desc.Format = DXGI_FORMAT_UNKNOWN; - srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; - srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; - srv_desc.Buffer.FirstElement = element_range.min; - srv_desc.Buffer.NumElements = element_range.max - element_range.min; - srv_desc.Buffer.StructureByteStride = element_size; - srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; - ID3D12Device_CreateShaderResourceView(g->device, resource->d3d_resource, &srv_desc, descriptor->handle); + GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); + GPU_D12_Resource *resource = GPU_D12_ResourceFromHandle(resource_handle); + GPU_D12_Descriptor *descriptor = GPU_D12_PushDescriptor(gpu_arena, GPU_D12_DescriptorHeapKind_CbvSrvUav); + { + D3D12_SHADER_RESOURCE_VIEW_DESC srv_desc = ZI; + srv_desc.Format = DXGI_FORMAT_UNKNOWN; + srv_desc.ViewDimension = D3D12_SRV_DIMENSION_BUFFER; + srv_desc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING; + srv_desc.Buffer.FirstElement = element_range.min; + srv_desc.Buffer.NumElements = MaxU32(num_elements, 1); + srv_desc.Buffer.StructureByteStride = element_size; + srv_desc.Buffer.Flags = D3D12_BUFFER_SRV_FLAG_NONE; + ID3D12Device_CreateShaderResourceView(g->device, resource->d3d_resource, &srv_desc, descriptor->handle); + } + result = GPU_D12_MakeHandle(StructuredBufferHandle, descriptor->index); } - return GPU_D12_MakeHandle(StructuredBufferHandle, descriptor->index); + return result; } RWStructuredBufferHandle GPU_PushRWStructuredBufferHandleEx(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle, u32 element_size, RngU32 element_range) { GPU_D12_SharedState *g = &GPU_D12_shared_state; - GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); - GPU_D12_Resource *resource = GPU_D12_ResourceFromHandle(resource_handle); - GPU_D12_Descriptor *descriptor = GPU_D12_PushDescriptor(gpu_arena, GPU_D12_DescriptorHeapKind_CbvSrvUav); - ID3D12Device_CreateUnorderedAccessView(g->device, resource->d3d_resource, 0, 0, descriptor->handle); - return GPU_D12_MakeHandle(RWStructuredBufferHandle, descriptor->index); + u32 num_elements = element_range.max - element_range.min; + RWStructuredBufferHandle result = ZI; + if (num_elements > 0) + { + GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); + GPU_D12_Resource *resource = GPU_D12_ResourceFromHandle(resource_handle); + GPU_D12_Descriptor *descriptor = GPU_D12_PushDescriptor(gpu_arena, GPU_D12_DescriptorHeapKind_CbvSrvUav); + ID3D12Device_CreateUnorderedAccessView(g->device, resource->d3d_resource, 0, 0, descriptor->handle); + result = GPU_D12_MakeHandle(RWStructuredBufferHandle, descriptor->index); + } + return result; } Texture1DHandle GPU_PushTexture1DHandle(GPU_ArenaHandle arena_handle, GPU_ResourceHandle resource_handle) @@ -2128,6 +2119,20 @@ void GPU_CommitCommandListEx(GPU_CommandListHandle cl_handle, u64 fence_ops_coun EndScratch(scratch); } +//- Arena + +void GPU_ResetArena(GPU_CommandListHandle cl_handle, GPU_ArenaHandle arena_handle) +{ + GPU_D12_Arena *gpu_arena = GPU_D12_ArenaFromHandle(arena_handle); + + /* TODO */ + + /* FIXME: Move descriptors into committed lists */ + + /* FIXME: Release id3d12 resource com object references */ + gpu_arena->heap_pos = 0; +} + //- Cpu -> Gpu copy void GPU_CopyCpuToBuffer(GPU_CommandListHandle cl_handle, GPU_ResourceHandle dst_handle, u64 dst_offset, void *src, RngU64 src_copy_range) diff --git a/src/pp/pp_sim/pp_sim_core.c b/src/pp/pp_sim/pp_sim_core.c index efc8839d..e0fefba9 100644 --- a/src/pp/pp_sim/pp_sim_core.c +++ b/src/pp/pp_sim/pp_sim_core.c @@ -25,12 +25,8 @@ void S_Startup(void) output->arena = AcquireArena(Gibi(64)); } - /* Create job pools */ - JobPoolId sim_pool = InitJobPool(1, Lit("Sim"), JobPoolPriority_Simulation); - - /* Start jobs */ - shared->workers_count += RunJob(S_SimWorker, .pool = sim_pool, .fence = &shared->worker_completion_fence); - OnExit(&S_Shutdown); + /* Dispatch sim wave */ + DispatchWave(Lit("Sim"), 1, S_TickForever, 0); } void S_Shutdown(void) @@ -294,9 +290,9 @@ MergesortCompareFuncDef(S_SortEntsByKeyCmp, arg_a, arg_b, _) } //////////////////////////////////////////////////////////// -//~ Sim worker +//~ Sim tick -JobImpl(S_SimWorker, _, __) +void S_TickForever(WaveLaneCtx *lane) { S_SharedState *shared = &S_shared_state; Arena *frame_arena = AcquireArena(Gibi(64)); @@ -325,11 +321,12 @@ JobImpl(S_SimWorker, _, __) i64 frame_begin_ns = TimeNs(); i64 sim_dt_ns = NsFromSeconds(1) / SIM_TICKS_PER_SECOND; f64 sim_dt = SecondsFromNs(sim_dt_ns); + world->tick += 1; ////////////////////////////// //- Create root ent - if (world->tick == 0) + if (world->tick == 1) { S_Ent *root_ent = PushStruct(ents_arena, S_Ent); *root_ent = S_nil_ent; @@ -585,7 +582,6 @@ JobImpl(S_SimWorker, _, __) i64 frame_end_ns = TimeNs(); sim_time_ns += sim_dt_ns; - ++world->tick; ////////////////////////////// //- Sleep diff --git a/src/pp/pp_sim/pp_sim_core.h b/src/pp/pp_sim/pp_sim_core.h index 0e398829..d2f97fba 100644 --- a/src/pp/pp_sim/pp_sim_core.h +++ b/src/pp/pp_sim/pp_sim_core.h @@ -293,6 +293,6 @@ S_World *S_WorldFromSnapshot(Arena *arena, S_Snapshot *snapshot); MergesortCompareFuncDef(S_SortEntsByKeyCmp, arg_a, arg_b, _); //////////////////////////////////////////////////////////// -//~ Sim worker +//~ Sim tick -JobDecl(S_SimWorker, EmptySig); +void S_TickForever(WaveLaneCtx *lane); diff --git a/src/pp/pp_vis/pp_vis.lay b/src/pp/pp_vis/pp_vis.lay index 7dcbd515..f7d6069b 100644 --- a/src/pp/pp_vis/pp_vis.lay +++ b/src/pp/pp_vis/pp_vis.lay @@ -2,7 +2,7 @@ //- Dependencies @Dep gpu -@Dep font +@Dep glyph_cache @Dep platform @Dep window @Dep ui @@ -10,16 +10,16 @@ //- Api @IncludeC pp_vis_widgets.h -@IncludeC pp_vis_gpu.h +@IncludeC pp_vis_shaders.h @IncludeC pp_vis_draw.h @IncludeC pp_vis_core.h -@IncludeGpu pp_vis_gpu.h +@IncludeGpu pp_vis_shaders.h //- Impl @IncludeC pp_vis_widgets.c @IncludeC pp_vis_draw.c @IncludeC pp_vis_core.c -@IncludeGpu pp_vis_gpu.hlsl +@IncludeGpu pp_vis_shaders.hlsl //- Embeds @EmbedDir V_Resources pp_vis_res diff --git a/src/pp/pp_vis/pp_vis_core.c b/src/pp/pp_vis/pp_vis_core.c index 8941ec6c..f902148a 100644 --- a/src/pp/pp_vis/pp_vis_core.c +++ b/src/pp/pp_vis/pp_vis_core.c @@ -1,48 +1,46 @@ -V_SharedState V_shared_state = ZI; +V_State V = ZI; //////////////////////////////////////////////////////////// //~ Startup void V_Startup(void) { - V_SharedState *shared = &V_shared_state; - - /* Create job pools */ - JobPoolId vis_pool = InitJobPool(1, Lit("Vis"), JobPoolPriority_Graphics); - - /* Start jobs */ - shared->workers_count += RunJob(V_VisWorker, .pool = vis_pool, .fence = &shared->worker_completion_fence); - OnExit(&V_Shutdown); + DispatchWave(Lit("Vis"), 1, V_TickForever, 0); } void V_Shutdown(void) { - V_SharedState *shared = &V_shared_state; - Atomic32Set(&shared->shutdown, 1); - YieldOnFence(&shared->worker_completion_fence, shared->workers_count); + Atomic32Set(&V.shutdown, 1); + YieldOnFence(&V.shutdown_complete, 1); } //////////////////////////////////////////////////////////// -//~ Vis worker +//~ Vis tick -JobImpl(V_VisWorker, _, __) +void V_TickForever(WaveLaneCtx *lane) { - V_SharedState *vis_shared = &V_shared_state; + Arena *perm = PermArena(); S_SharedState *sim_shared = &S_shared_state; - Arena *frame_arena = AcquireArena(Gibi(64)); - Arena *perm = PermArena(); + ////////////////////////////// + //- Init vis state - GPU_Arena *frame_gpu_arena = GPU_AcquireArena(Mebi(8), GPU_CpuAccessFlag_Writable); - GPU_Arena *dverts_gpu_arena = GPU_AcquireArena(Mebi(32), GPU_CpuAccessFlag_Writable); - GPU_Arena *dvert_idxs_gpu_arena = GPU_AcquireArena(Mebi(32), GPU_CpuAccessFlag_Writable); + V.world_arena = AcquireArena(Gibi(64)); + V.world = PushStruct(V.world_arena, S_World); + V.player_key = S_RandKey(); + + for (u32 i = 0; i < countof(V.frames); ++i) + { + V_Frame *frame = &V.frames[i]; + frame->arena = AcquireArena(Gibi(64)); + frame->dverts_arena = AcquireArena(Gibi(64)); + frame->dvert_idxs_arena = AcquireArena(Gibi(64)); + frame->gpu_arena = GPU_AcquireArena(); + } ////////////////////////////// //- State - i64 frame_gen = 0; - GPU_Texture *draw_target = 0; - Struct(Persist) { V_CommandsWidget commands_widget; @@ -106,23 +104,50 @@ JobImpl(V_VisWorker, _, __) ////////////////////////////// //- Begin vis loop - Arena *world_arena = AcquireArena(Gibi(64)); - S_World *world = PushStruct(world_arena, S_World); - S_Lookup lookup = ZI; - S_Key player_key = S_RandKey(); - b32 shutdown = 0; while (!shutdown) { - ResetArena(frame_arena); - S_Iter iter = ZI; + ////////////////////////////// + //- Begin frame + u64 last_frame_idx = V.current_frame_idx; + u64 frame_idx = last_frame_idx + 1; + if (frame_idx >= countof(V.frames)) + { + frame_idx = 0; + } + V.current_frame_idx = frame_idx; + + V_Frame *last_frame = &V.frames[last_frame_idx]; + V_Frame *frame = &V.frames[frame_idx]; + + { + Arena *old_arena = frame->arena; + Arena *old_dverts_arena = frame->dverts_arena; + Arena *old_dvert_idxs_arena = frame->dvert_idxs_arena; + GPU_ArenaHandle old_gpu_arena = frame->gpu_arena; + ZeroStruct(frame); + frame->arena = old_arena; + frame->dverts_arena = old_dverts_arena; + frame->dvert_idxs_arena = old_dvert_idxs_arena; + frame->gpu_arena = old_gpu_arena; + } + frame->cl = GPU_PrepareCommandList(GPU_QueueKind_Direct); + ResetArena(frame->arena); + ResetArena(frame->dverts_arena); + ResetArena(frame->dvert_idxs_arena); + GPU_ResetArena(frame->cl, frame->gpu_arena); + + frame->time_ns = TimeNs(); + frame->tick = last_frame->tick + 1; + + S_Iter iter = ZI; S_EntList spawn_ents = ZI; ////////////////////////////// //- Spawn test ents - if (world->tick == 0) + if (V.world->tick == 1) { S_Key child_key = S_RandKey(); S_Key camera_key = S_RandKey(); @@ -130,7 +155,7 @@ JobImpl(V_VisWorker, _, __) i32 count = 3; for (u64 i = 0; i < count; ++i) { - S_EntListNode *n = PushStruct(frame_arena, S_EntListNode); + S_EntListNode *n = PushStruct(frame->arena, S_EntListNode); SllQueuePush(spawn_ents.first, spawn_ents.last, n); ++spawn_ents.count; S_Ent *ent = &n->ent; @@ -141,7 +166,7 @@ JobImpl(V_VisWorker, _, __) case 0: { ent->tint = Color_Red; - ent->key = player_key; + ent->key = V.player_key; ent->camera = camera_key; ent->move_speed = 0.1; { @@ -163,7 +188,7 @@ JobImpl(V_VisWorker, _, __) ent->tint = Color_Cyan; ent->key = child_key; - ent->parent = player_key; + ent->parent = V.player_key; { ent->local_shape = S_ShapeFromDesc( .count = 4, @@ -180,7 +205,7 @@ JobImpl(V_VisWorker, _, __) case 2: { ent->key = camera_key; - ent->follow = player_key; + ent->follow = V.player_key; } break; default: @@ -192,7 +217,7 @@ JobImpl(V_VisWorker, _, __) } ////////////////////////////// - //- Begin vis frame + //- Begin UI frame UI_FrameFlag ui_frame_flags = 0; Vec4 swapchain_color = V_GetWidgetTheme().window_background_color; @@ -203,11 +228,11 @@ JobImpl(V_VisWorker, _, __) /* Restore window */ { - if (frame_gen == 0) + if (frame->tick == 1) { WND_PushCmd(window_frame, .kind = WND_CmdKind_Restore, .restore = window_restore); } - window_restore = PushString(frame_arena, window_frame.restore); + window_restore = PushString(frame->arena, window_frame.restore); } /* Set widget theme */ @@ -244,11 +269,11 @@ JobImpl(V_VisWorker, _, __) } UnlockTicketMutex(&sim_shared->output_back_tm); - if (sim_output->last_snapshot_node && sim_output->last_snapshot_node->snapshot.tick > world->tick) + if (sim_output->last_snapshot_node && sim_output->last_snapshot_node->snapshot.tick > V.world->tick) { - ResetArena(world_arena); - world = S_WorldFromSnapshot(world_arena, &sim_output->last_snapshot_node->snapshot); - lookup = S_LookupFromWorld(world_arena, world); + ResetArena(V.world_arena); + V.world = S_WorldFromSnapshot(V.world_arena, &sim_output->last_snapshot_node->snapshot); + V.lookup = S_LookupFromWorld(V.world_arena, V.world); } ////////////////////////////// @@ -259,13 +284,13 @@ JobImpl(V_VisWorker, _, __) Vec2 camera_pos = ZI; f32 camera_zoom = 1; { - S_Ent *player = S_EntFromKey(&lookup, player_key); - S_Ent *camera = S_EntFromKey(&lookup, player->camera); + S_Ent *player = S_EntFromKey(&V.lookup, V.player_key); + S_Ent *camera = S_EntFromKey(&V.lookup, player->camera); camera_pos = MulXformV2(camera->world_xf, camera->local_shape.centroid); } ////////////////////////////// - //- Initialize world <-> draw <-> ui transforms + //- Initialize V.world <-> draw <-> ui transforms /* World <-> draw */ Xform world_to_draw_xf = XformIdentity; @@ -276,7 +301,7 @@ JobImpl(V_VisWorker, _, __) scale.y = scale.x; world_to_draw_xf = XformFromScale(scale); world_to_draw_xf = TranslateXform(world_to_draw_xf, NegVec2(camera_pos)); - world_to_draw_xf = WorldTranslateXform(world_to_draw_xf, MulVec2(Vec2FromFields(draw_size), 0.5)); + world_to_draw_xf = WorldTranslateXform(world_to_draw_xf, MulVec2(Vec2FromVec(draw_size), 0.5)); draw_to_world_xf = InvertXform(world_to_draw_xf); } @@ -336,7 +361,7 @@ JobImpl(V_VisWorker, _, __) } if (shortcut != 0 && down) { - V_CmdNode *cmd_node = PushStruct(frame_arena, V_CmdNode); + V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode); cmd_node->cmd.name = shortcut->cmd_name; SllQueuePush(first_cmd_node, last_cmd_node, cmd_node); ++cmds_count; @@ -364,7 +389,7 @@ JobImpl(V_VisWorker, _, __) CopyStructs(item_desc.hotkeys, desc.default_hotkeys, MinU32(countof(item_desc.hotkeys), countof(desc.default_hotkeys))); if (V_PushCommandsWidgetItem(&persist.commands_widget, item_desc).pressed > 0) { - V_CmdNode *cmd_node = PushStruct(frame_arena, V_CmdNode); + V_CmdNode *cmd_node = PushStruct(frame->arena, V_CmdNode); cmd_node->cmd.name = desc.name; SllQueuePush(first_cmd_node, last_cmd_node, cmd_node); ++cmds_count; @@ -474,11 +499,11 @@ JobImpl(V_VisWorker, _, __) } Vec2 look = ZI; { - S_Ent *player = S_EntFromKey(&lookup, player_key); + S_Ent *player = S_EntFromKey(&V.lookup, V.player_key); Vec2 center = MulXformV2(player->world_xf, player->local_shape.centroid); look = SubVec2(world_cursor, center); } - cmd->target = player_key; + cmd->target = V.player_key; cmd->move = move; cmd->look = look; } @@ -511,104 +536,105 @@ JobImpl(V_VisWorker, _, __) ////////////////////////////// //- Render - GPU_CommandList *cl = GPU_OpenCommandList(GPU_QueueKind_Direct); { ////////////////////////////// //- Build render data - GPU_ResetArena(cl, gpu_frame_arena); - ResetArena(dverts_arena); - ResetArena(dvert_idxs_arena); - /* Build shape buffers */ - GpuPointer dverts = ZI; - GpuPointer dvert_idxs = ZI; + for (S_Ent *ent = S_FirstEnt(frame->arena, &iter, &V.lookup); ent->active; ent = S_NextEnt(frame->arena, &iter)) { - for (S_Ent *ent = S_FirstEnt(frame_arena, &iter, &lookup); ent->active; ent = S_NextEnt(frame_arena, &iter)) + Xform ent_to_world_xf = ent->world_xf; + Xform ent_to_draw_xf = MulXform(world_to_draw_xf, ent_to_world_xf); + + /* Draw shape */ + b32 is_visible = ent->tint.w != 0; + if (is_visible) { - Xform ent_to_world_xf = ent->world_xf; - Xform ent_to_draw_xf = MulXform(world_to_draw_xf, ent_to_world_xf); - - /* Draw shape */ - b32 is_visible = ent->tint.w != 0; - if (is_visible) - { - Vec4 color = ent->tint; - i32 detail = 32; - S_Shape shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape); - V_DrawShape(dverts_arena, dvert_idxs_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line); - } + Vec4 color = ent->tint; + i32 detail = 32; + S_Shape shape = S_MulXformShape(ent_to_draw_xf, ent->local_shape); + V_DrawShape(frame->dverts_arena, frame->dvert_idxs_arena, shape, LinearFromSrgb(color), detail, V_DrawFlag_Line); } - dverts = GPU_PushCpuStructsToArena(gpu_frame_arena, V_DVert, dverts_arena); - dvert_idxs = GPU_PushCpuStructsToArena(gpu_frame_arena, i32, dvert_idxs_arena); - } - - /* Create draw state */ - if (!draw_target || !MatchVec2I32(draw_size, GPU_Count2D(draw_target))) - { - GPU_ResetArena(cl, gpu_arena); - /* Draw target */ - { - GPU_TextureDesc desc = ZI; - desc.kind = GPU_TextureKind_Texture2D; - desc.flags = GPU_TextureFlag_Writable | GPU_TextureFlag_Rasterizable; - desc.format = GPU_Format_R16G16B16A16_Float; - desc.size = VEC3I32(draw_size.x, draw_size.y, 1); - desc.clear_color = LinearFromSrgb(swapchain_color); - draw_target = GPU_PushTexture(gpu_arena, desc); - } - /* Draw params */ - draw_params = GPU_PushStructNoZero(gpu_arena, V_DParams); - } - - /* Build draw params */ - GpuPointer draw_params = ZI; - { - V_DParams params = ZI; - params.world_to_draw_xf = world_to_draw_xf; - GPU_CopyCpuStructToBuffer(draw_params, 0, ¶ms); } ////////////////////////////// - //- Dispatch shaders + //- Push data to GPU - Rng2 viewport = RNG2(VEC2(0, 0), Vec2FromFields(draw_size)); + /* Target */ + GPU_ResourceHandle draw_target = GPU_PushTexture2D( + frame->gpu_arena, + GPU_Format_R16G16B16A16_Float, + window_frame.monitor_size, + GPU_Layout_DirectQueue_ShaderReadWrite, + .flags = GPU_ResourceFlag_AllowShaderReadWrite | GPU_ResourceFlag_AllowRenderTarget + ); + Texture2DHandle draw_target_ro = GPU_PushTexture2DHandle(frame->gpu_arena, draw_target); + RWTexture2DHandle draw_target_rw = GPU_PushRWTexture2DHandle(frame->gpu_arena, draw_target); + + /* Verts */ + GPU_ResourceHandle dverts_buff = GPU_PushBufferFromCpu(frame->gpu_arena, frame->cl, StringFromArena(frame->dverts_arena)); + GPU_ResourceHandle dvert_idxs_buff = GPU_PushBufferFromCpu(frame->gpu_arena, frame->cl, StringFromArena(frame->dvert_idxs_arena)); + StructuredBufferHandle dverts_ro = GPU_PushStructuredBufferHandle(frame->gpu_arena, dverts_buff, V_DVert); + GPU_IndexBufferDesc dvert_idxs_ib = GPU_IdxBuff32(dvert_idxs_buff); + + /* Params */ + V_DParams params = ZI; { - GPU_SetConstantPtr(cl, V_DrawConst_Params, draw_params); - GPU_SetConstantPtr(cl, V_DrawConst_FinalTarget, draw_target); - GPU_SetConstantPtr(cl, V_DrawConst_Sampler, GPU_GetSharedPointSampler()); - GPU_SetConstantPtr(cl, V_DrawConst_DVerts, dverts); - - /* Backdrop pass */ - { - GPU_SyncAccess(cl, draw_target, GPU_AccessKind_ComputeReadWrite); - GPU_Compute(cl, V_BackdropCS, V_BackdropCSThreadSizeFromTexSize(draw_size)); - } - - /* Shapes pass */ - { - GPU_SyncAccess(cl, draw_target, GPU_AccessKind_RasterTarget) - GPU_Rasterize(cl, - V_DVertVS, V_DVertPS, - 1, dvert_idxs_buffer, - 1, draw_target, - viewport, viewport, - GPU_RasterizeMode_TriangleList); - } - - GPU_SetShaderAccess(cl, draw_target, GPU_ShaderAccessKind_Readonly); + params.target_size = draw_size; + params.target_ro = draw_target_ro; + params.target_rw = draw_target_rw; + params.sampler = GPU_GetSharedPointSampler(); + params.shape_verts = dverts_ro; + params.world_to_draw_xf = world_to_draw_xf; } + GPU_ResourceHandle params_buff = GPU_PushBufferFromCpu(frame->gpu_arena, frame->cl, StringFromStruct(¶ms)); + StructuredBufferHandle params_ro = GPU_PushStructuredBufferHandle(frame->gpu_arena, params_buff, V_DParams); + + /* Constants */ + GPU_SetConstant(frame->cl, V_ShaderConst_Params, params_ro); + + Rng3 viewport = RNG3(VEC3(0, 0, 0), VEC3(draw_size.x, draw_size.y, 1)); + Rng2 scissor = RNG2(VEC2(viewport.p0.x, viewport.p0.y), VEC2(viewport.p1.x, viewport.p1.y)); + + ////////////////////////////// + //- Backdrop pass + + + /* Backdrop pass */ + { + GPU_Compute(frame->cl, V_BackdropCS, V_BackdropCSThreadSizeFromTexSize(draw_size)); + } + + ////////////////////////////// + //- Shapes pass + + GPU_DumbMemoryLayoutSync(frame->cl, draw_target, GPU_Layout_DirectQueue_RenderTargetWrite); + + /* Shapes pass */ + { + GPU_Rasterize(frame->cl, + V_DVertVS, V_DVertPS, + 1, dvert_idxs_ib, + 1, &draw_target, + viewport, scissor, + GPU_RasterMode_TriangleList); + } + + ////////////////////////////// + //- Finalize draw target + + GPU_DumbMemoryLayoutSync(frame->cl, draw_target, GPU_Layout_DirectQueue_ShaderRead); + UI_SetRawTexture(vis_box, draw_target_ro, VEC2(0, 0), VEC2(1, 1)); } - GPU_CloseCommandLiist(cl); ////////////////////////////// - //- End vis frame + //- End frame + + GPU_CommitCommandList(frame->cl); - UI_SetRawTexture(vis_box, draw_target, VEC2(0, 0), VEC2(1, 1)); UI_EndFrame(ui_frame); - ++frame_gen; - shutdown = Atomic32Fetch(&vis_shared->shutdown); + shutdown = Atomic32Fetch(&V.shutdown); } ////////////////////////////// @@ -628,4 +654,6 @@ JobImpl(V_VisWorker, _, __) } EndScratch(scratch); } + + FetchAddFence(&V.shutdown_complete, 1); } diff --git a/src/pp/pp_vis/pp_vis_core.h b/src/pp/pp_vis/pp_vis_core.h index 387d4b99..9ec73dc6 100644 --- a/src/pp/pp_vis/pp_vis_core.h +++ b/src/pp/pp_vis/pp_vis_core.h @@ -73,13 +73,31 @@ Global Readonly V_CmdDesc V_cmd_descs[V_CmdKind_Count] = { //////////////////////////////////////////////////////////// //~ State types -Struct(V_SharedState) +Struct(V_Frame) { - Atomic32 shutdown; - Fence worker_completion_fence; - i64 workers_count; + Arena *arena; + Arena *dverts_arena; + Arena *dvert_idxs_arena; + GPU_ArenaHandle gpu_arena; -} extern V_shared_state; + i64 tick; + i64 time_ns; + GPU_CommandListHandle cl; +}; + +Struct(V_State) +{ + Arena *world_arena; + S_World *world; + S_Lookup lookup; + S_Key player_key; + + Atomic32 shutdown; + Fence shutdown_complete; + + u64 current_frame_idx; + V_Frame frames[2]; +} extern V; //////////////////////////////////////////////////////////// //~ Startup @@ -88,6 +106,6 @@ void V_Startup(void); void V_Shutdown(void); //////////////////////////////////////////////////////////// -//~ Vis worker +//~ Vis tick -JobDecl(V_VisWorker, EmptySig); +void V_TickForever(WaveLaneCtx *lane); diff --git a/src/pp/pp_vis/pp_vis_draw.c b/src/pp/pp_vis/pp_vis_draw.c index c0d20ffd..b3fb8085 100644 --- a/src/pp/pp_vis/pp_vis_draw.c +++ b/src/pp/pp_vis/pp_vis_draw.c @@ -1,7 +1,7 @@ //////////////////////////////////////////////////////////// //~ Shape helpers -void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array points, Vec4 color_lin, V_DrawFlag flags) +void V_DrawPoly(Arena *verts_arena, Arena *idxs_arena, Vec2Array points, Vec4 color_lin, V_DrawFlag flags) { if (flags & V_DrawFlag_Line) { @@ -14,10 +14,10 @@ void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array i32 lines_count = verts_count == 2 ? 1 : verts_count; i32 line_verts_count = lines_count * 4; i32 idx_count = lines_count * 6; - i32 idx_offset = GPU_ArenaCount(verts_gpu_arena, V_DVert); + i32 idx_offset = ArenaCount(verts_arena, V_DVert); /* Push dverts */ - V_DVert *dverts = GPU_PushStructsNoZero(verts_gpu_arena, V_DVert, line_verts_count); + V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, line_verts_count); for (i32 line_idx = 0; line_idx < lines_count; ++line_idx) { i32 a_idx = line_idx; @@ -46,7 +46,7 @@ void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array } /* Generate indices */ - i32 *indices = PushStructsNoZero(idxs_gpu_arena, i32, idx_count); + i32 *indices = PushStructsNoZero(idxs_arena, i32, idx_count); for (i32 line_idx = 0; line_idx < lines_count; ++line_idx) { i32 indices_offset = line_idx * 6; @@ -67,12 +67,12 @@ void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array i32 verts_count = points.count; if (verts_count >= 3) { - i32 idx_offset = GPU_ArenaCount(verts_gpu_arena, V_DVert); + i32 idx_offset = ArenaCount(verts_arena, V_DVert); i32 tris_count = verts_count - 2; i32 idx_count = tris_count * 3; /* Push dverts */ - V_DVert *dverts = GPU_PushStructsNoZero(verts_gpu_arena, V_DVert, verts_count); + V_DVert *dverts = PushStructsNoZero(verts_arena, V_DVert, verts_count); for (i32 point_idx = 0; point_idx < (i32)points.count; ++point_idx) { V_DVert *dvert = &dverts[point_idx]; @@ -81,7 +81,7 @@ void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array } /* Generate indices in a fan pattern */ - i32 *indices = PushStructsNoZero(idxs_gpu_arena, i32, idx_count); + i32 *indices = PushStructsNoZero(idxs_arena, i32, idx_count); for (i32 i = 0; i < tris_count; ++i) { i32 tri_offset = i * 3; @@ -93,14 +93,14 @@ void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array } } -void V_DrawShape(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, S_Shape shape, Vec4 color_lin, i32 detail, V_DrawFlag flags) +void V_DrawShape(Arena *verts_arena, Arena *idxs_arena, S_Shape shape, Vec4 color_lin, i32 detail, V_DrawFlag flags) { if (shape.radius == 0) { Vec2Array draw_points = ZI; draw_points.points = shape.points; draw_points.count = shape.points_count; - V_DrawPoly(verts_gpu_arena, idxs_gpu_arena, draw_points, color_lin, flags); + V_DrawPoly(verts_arena, idxs_arena, draw_points, color_lin, flags); } else { @@ -116,7 +116,7 @@ void V_DrawShape(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, S_Shape Vec2 sp = S_SupportPointFromShape(shape, dir); draw_points.points[i] = sp; } - V_DrawPoly(verts_gpu_arena, idxs_gpu_arena, draw_points, color_lin, flags); + V_DrawPoly(verts_arena, idxs_arena, draw_points, color_lin, flags); } EndScratch(scratch); } diff --git a/src/pp/pp_vis/pp_vis_draw.h b/src/pp/pp_vis/pp_vis_draw.h index fe3a2a8b..7541468e 100644 --- a/src/pp/pp_vis/pp_vis_draw.h +++ b/src/pp/pp_vis/pp_vis_draw.h @@ -10,5 +10,5 @@ Enum(V_DrawFlag) //////////////////////////////////////////////////////////// //~ Shape helpers -void V_DrawPoly(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, Vec2Array points, Vec4 color_lin, V_DrawFlag flags); -void V_DrawShape(GPU_Arena *verts_gpu_arena, GPU_Arena *idxs_gpu_arena, S_Shape shape, Vec4 color_lin, i32 detail, V_DrawFlag flags); +void V_DrawPoly(Arena *verts_arena, Arena *idxs_arena, Vec2Array points, Vec4 color_lin, V_DrawFlag flags); +void V_DrawShape(Arena *verts_arena, Arena *idxs_arena, S_Shape shape, Vec4 color_lin, i32 detail, V_DrawFlag flags); diff --git a/src/pp/pp_vis/pp_vis_gpu.h b/src/pp/pp_vis/pp_vis_gpu.h deleted file mode 100644 index 459619a2..00000000 --- a/src/pp/pp_vis/pp_vis_gpu.h +++ /dev/null @@ -1,72 +0,0 @@ -//////////////////////////////////////////////////////////// -//~ Backdrop shader types - -Struct(V_BackdropSig) -{ - /* ----------------------------------------------------- */ - Vec2I32 target_size; /* 02 consts */ - RWTexture2DRid target_tex; /* 01 consts */ - SamplerStateRid sampler; /* 01 consts */ - /* ----------------------------------------------------- */ - u32 _pad0; /* 01 consts (padding) */ - u32 _pad1; /* 01 consts (padding) */ - u32 _pad2; /* 01 consts (padding) */ - u32 _pad3; /* 01 consts (padding) */ - /* ----------------------------------------------------- */ -}; -AssertRootConst(V_BackdropSig, 8); - -#define V_BackdropCSThreadSizeFromTexSize(tex_size) VEC3U32((tex_size.x + 7) / 8, (tex_size.y + 7) / 8, 1) - -//////////////////////////////////////////////////////////// -//~ Quad shader types - -Struct(V_DQuadSig) -{ - /* ----------------------------------------------------- */ - Vec2I32 target_size; /* 02 consts */ - StructuredBufferRid quads; /* 01 consts */ - SamplerStateRid sampler; /* 01 consts */ - /* ----------------------------------------------------- */ - b32 debug_enabled; /* 01 consts */ - u32 _pad0; /* 01 consts (padding) */ - u32 _pad1; /* 01 consts (padding) */ - u32 _pad2; /* 01 consts (padding) */ - /* ----------------------------------------------------- */ -}; -AssertRootConst(V_DQuadSig, 8); - -Enum(V_DQuadFlag) -{ - V_DQuadFlag_None = 0, - V_DQuadFlag_DrawGrid = (1 << 0), -}; - -Struct(V_DQuad) -{ - V_DQuadFlag flags; -}; - -//////////////////////////////////////////////////////////// -//~ Shape shader types - -Struct(V_DVertSig) -{ - /* ----------------------------------------------------- */ - Vec2I32 target_size; /* 02 consts */ - StructuredBufferRid verts; /* 01 consts */ - SamplerStateRid sampler; /* 01 consts */ - /* ----------------------------------------------------- */ - b32 debug_enabled; /* 01 consts */ - u32 _pad0; /* 01 consts (padding) */ - u32 _pad1; /* 01 consts (padding) */ - u32 _pad2; /* 01 consts (padding) */ - /* ----------------------------------------------------- */ -}; -AssertRootConst(V_DVertSig, 8); - -Struct(V_DVert) -{ - Vec2 pos; - Vec4 color_lin; -}; diff --git a/src/pp/pp_vis/pp_vis_shaders.h b/src/pp/pp_vis/pp_vis_shaders.h new file mode 100644 index 00000000..9c5ddffd --- /dev/null +++ b/src/pp/pp_vis/pp_vis_shaders.h @@ -0,0 +1,43 @@ +//////////////////////////////////////////////////////////// +//~ Constant types + +ShaderConstant(StructuredBufferHandle, V_ShaderConst_Params, 0); + +Struct(V_DParams) +{ + Vec2I32 target_size; + Texture2DHandle target_ro; + RWTexture2DHandle target_rw; + SamplerStateHandle sampler; + StructuredBufferHandle quads; + StructuredBufferHandle shape_verts; + Xform world_to_draw_xf; +}; + +//////////////////////////////////////////////////////////// +//~ Backdrop shader types + +#define V_BackdropCSThreadSizeFromTexSize(tex_size) VEC3I32((tex_size.x + 7) / 8, (tex_size.y + 7) / 8, 1) + +//////////////////////////////////////////////////////////// +//~ Quad shader types + +Enum(V_DQuadFlag) +{ + V_DQuadFlag_None = 0, + V_DQuadFlag_DrawGrid = (1 << 0), +}; + +Struct(V_DQuad) +{ + V_DQuadFlag flags; +}; + +//////////////////////////////////////////////////////////// +//~ Shape shader types + +Struct(V_DVert) +{ + Vec2 pos; + Vec4 color_lin; +}; diff --git a/src/pp/pp_vis/pp_vis_gpu.hlsl b/src/pp/pp_vis/pp_vis_shaders.hlsl similarity index 63% rename from src/pp/pp_vis/pp_vis_gpu.hlsl rename to src/pp/pp_vis/pp_vis_shaders.hlsl index 3926b9d2..841836f5 100644 --- a/src/pp/pp_vis/pp_vis_gpu.hlsl +++ b/src/pp/pp_vis/pp_vis_shaders.hlsl @@ -1,20 +1,17 @@ -ConstantBuffer V_backdrop_sig : register (b0); -ConstantBuffer V_dquad_sig : register (b0); -ConstantBuffer V_dvert_sig : register (b0); - //////////////////////////////////////////////////////////// //~ Backdrop shader ComputeShader2D(V_BackdropCS, 8, 8) { - ConstantBuffer sig = V_backdrop_sig; + V_DParams params = StructuredBufferFromHandle(V_ShaderConst_Params)[0]; + RWTexture2D target = RWTexture2DFromHandle(params.target_rw); + Vec2U32 target_pos = SV_DispatchThreadID; - Vec2I32 target_size = sig.target_size; + Vec2I32 target_size = params.target_size; if (target_pos.x < target_size.x && target_pos.y < target_size.y) { - RWTexture2D target_tex = UniformResourceFromRid(sig.target_tex); Vec4 result = Color_Blue; - target_tex[target_pos] = result; + target[target_pos] = result; } } @@ -23,7 +20,6 @@ ComputeShader2D(V_BackdropCS, 8, 8) Struct(V_DQuadPSInput) { - Semantic(Vec4, SV_Position); Semantic(nointerpolation u32, quad_idx); }; @@ -38,8 +34,10 @@ Struct(V_DQuadPSOutput) VertexShader(V_DQuadVS, V_DQuadPSInput) { - ConstantBuffer sig = V_dquad_sig; - StructuredBuffer quads = UniformResourceFromRid(sig.quads); + V_DParams params = StructuredBufferFromHandle(V_ShaderConst_Params)[0]; + StructuredBuffer quads = StructuredBufferFromHandle(params.quads); + RWTexture2D target = RWTexture2DFromHandle(params.target_rw); + V_DQuad quad = quads[SV_InstanceID]; Vec2 rect_uv = RectUvFromVertexId(SV_VertexID); @@ -48,7 +46,7 @@ VertexShader(V_DQuadVS, V_DQuadPSInput) Vec2 target_pos = 0; V_DQuadPSInput result; - result.SV_Position = Vec4(NdcFromPos(target_pos, sig.target_size).xy, 0, 1); + result.SV_Position = Vec4(NdcFromPos(target_pos, Count2D(target)).xy, 0, 1); result.quad_idx = SV_InstanceID; return result; } @@ -58,8 +56,8 @@ VertexShader(V_DQuadVS, V_DQuadPSInput) PixelShader(V_DQuadPS, V_DQuadPSOutput, V_DQuadPSInput input) { - ConstantBuffer sig = V_dquad_sig; - StructuredBuffer quads = UniformResourceFromRid(sig.quads); + V_DParams params = StructuredBufferFromHandle(V_ShaderConst_Params)[0]; + StructuredBuffer quads = StructuredBufferFromHandle(params.quads); V_DQuad quad = quads[input.quad_idx]; Vec4 final_color = 0; @@ -89,14 +87,16 @@ Struct(V_DVertPSOutput) VertexShader(V_DVertVS, V_DVertPSInput) { - ConstantBuffer sig = V_dvert_sig; - StructuredBuffer verts = UniformResourceFromRid(sig.verts); + V_DParams params = StructuredBufferFromHandle(V_ShaderConst_Params)[0]; + StructuredBuffer verts = StructuredBufferFromHandle(params.shape_verts); + RWTexture2D target = RWTexture2DFromHandle(params.target_rw); + V_DVert vert = verts[SV_VertexID]; Vec2 target_pos = vert.pos; V_DVertPSInput result; - result.SV_Position = Vec4(NdcFromPos(target_pos, sig.target_size).xy, 0, 1); + result.SV_Position = Vec4(NdcFromPos(target_pos, Count2D(target)).xy, 0, 1); result.color_lin = vert.color_lin; return result; } diff --git a/src/pp/pp_vis/pp_vis_widgets.c b/src/pp/pp_vis/pp_vis_widgets.c index 98e9e311..ec0d3355 100644 --- a/src/pp/pp_vis/pp_vis_widgets.c +++ b/src/pp/pp_vis/pp_vis_widgets.c @@ -5,7 +5,7 @@ V_WidgetTheme V_GetWidgetTheme(void) { V_WidgetTheme theme = ZI; - theme.font = ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf")); + theme.font = GC_FontKeyFromResource(ResourceKeyFromStore(&V_Resources, Lit("font/fixedsys.ttf"))); theme.font_size = 16; theme.window_background_color = Rgb32(0xff1a1d1e); diff --git a/src/pp/pp_vis/pp_vis_widgets.h b/src/pp/pp_vis/pp_vis_widgets.h index da584a79..06e8896c 100644 --- a/src/pp/pp_vis/pp_vis_widgets.h +++ b/src/pp/pp_vis/pp_vis_widgets.h @@ -3,7 +3,7 @@ Struct(V_WidgetTheme) { - ResourceKey font; + GC_FontKey font; f32 font_size; f32 window_title_font_size; diff --git a/src/proto/proto.c b/src/proto/proto.c index 2cacd3fa..4a090138 100644 --- a/src/proto/proto.c +++ b/src/proto/proto.c @@ -35,7 +35,7 @@ void PT_RunForever(WaveLaneCtx *lane) { GPU_SetConstant(cl, PT_ShaderConst_TestTarget, final_target_rwhandle); GPU_SetConstant(cl, PT_ShaderConst_TestConst, 3.123); - GPU_SetConstant(cl, PT_ShaderConst_BlitSampler, GPU_GetSharedPointSampler()); + GPU_SetConstant(cl, PT_ShaderConst_BlitSampler, GPU_GetSharedSPointSampler()); GPU_SetConstant(cl, PT_ShaderConst_BlitSrc, final_target_rhandle); GPU_SetConstant(cl, PT_ShaderConst_NoiseTex, GPU_GetSharedNoise()); } diff --git a/src/ui/ui.lay b/src/ui/ui.lay index da57fd4a..616b0194 100644 --- a/src/ui/ui.lay +++ b/src/ui/ui.lay @@ -19,6 +19,8 @@ //- Shaders @VertexShader UI_DRectVS @PixelShader UI_DRectPS +@VertexShader UI_BlitVS +@PixelShader UI_BlitPS //- Embeds @EmbedDir UI_Resources ui_res diff --git a/src/ui/ui_core.c b/src/ui/ui_core.c index 99ebf52d..1ee193f6 100644 --- a/src/ui/ui_core.c +++ b/src/ui/ui_core.c @@ -457,6 +457,8 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) { UI_Frame *frame = &g->frames[i]; frame->arena = AcquireArena(Gibi(64)); + frame->rects_arena = AcquireArena(Gibi(64)); + frame->gpu_arena = GPU_AcquireArena(); } } @@ -465,19 +467,15 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) u64 last_frame_idx = g->current_frame_idx; u64 frame_idx = last_frame_idx + 1; - if (frame_idx > countof(g->frames)) + if (frame_idx >= countof(g->frames)) { frame_idx = 0; } + g->current_frame_idx = frame_idx; + UI_Frame *last_frame = &g->frames[last_frame_idx]; UI_Frame *frame = &g->frames[frame_idx]; - frame->window_frame = WND_BeginFrame(GPU_Format_R16G16B16A16_Float, WND_BackbufferSizeMode_MatchMonitor); - - ////////////////////////////// - //- Reset state - - /* Reset frame data */ { Arena *old_arena = frame->arena; Arena *old_rects_arena = frame->arena; @@ -487,9 +485,11 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags, Vec4 swapchain_color) frame->rects_arena = old_rects_arena; frame->gpu_arena = old_gpu_arena; } + frame->window_frame = WND_BeginFrame(GPU_Format_R16G16B16A16_Float, WND_BackbufferSizeMode_MatchMonitor); + frame->cl = GPU_PrepareCommandList(GPU_QueueKind_Direct); ResetArena(frame->arena); ResetArena(frame->rects_arena); - GPU_ResetArenaFromQueue(GPU_QueueKind_Direct, frame->gpu_arena); + GPU_ResetArena(frame->cl, frame->gpu_arena); { i64 now_ns = TimeNs(); @@ -1208,7 +1208,7 @@ void UI_EndFrame(UI_Frame *frame) ////////////////////////////// //- Render - GPU_CommandListHandle cl = GPU_PrepareCommandList(GPU_QueueKind_Direct); + GPU_ResourceHandle backbuffer = frame->window_frame.backbuffer; { ////////////////////////////// //- Build render data @@ -1370,9 +1370,7 @@ void UI_EndFrame(UI_Frame *frame) ////////////////////////////// //- Push data to GPU - u32 rects_count = ArenaCount(frame->rects_arena, UI_DRect); - UI_DRect *rects = ArenaFirst(frame->rects_arena, UI_DRect); - + /* Target */ GPU_ResourceHandle draw_target = GPU_PushTexture2D( frame->gpu_arena, GPU_Format_R16G16B16A16_Float, @@ -1380,55 +1378,84 @@ void UI_EndFrame(UI_Frame *frame) GPU_Layout_DirectQueue_RenderTargetWrite, .flags = GPU_ResourceFlag_AllowRenderTarget ); + Texture2DHandle draw_target_ro = GPU_PushTexture2DHandle(frame->gpu_arena, draw_target); - StructuredBufferHandle rects_sb = GPU_PushStructuredBufferFromCpu(frame->gpu_arena, cl, rects, rects_count); + /* Rects */ + GPU_ResourceHandle rects_buff = GPU_PushBufferFromCpu(frame->gpu_arena, frame->cl, StringFromArena(frame->rects_arena)); + StructuredBufferHandle rects_ro = GPU_PushStructuredBufferHandle(frame->gpu_arena, rects_buff, UI_DRect); - GPU_SetConstant(cl, UI_ShaderConst_TargetWidth, draw_size.x); - GPU_SetConstant(cl, UI_ShaderConst_TargetHeight, draw_size.y); - GPU_SetConstant(cl, UI_ShaderConst_Rects, rects_sb); - GPU_SetConstant(cl, UI_ShaderConst_Sampler, GPU_GetSharedPointSampler()); + /* Params */ + UI_DParams params = ZI; + { + params.target_size = draw_size; + params.target_ro = draw_target_ro; + params.rects = rects_ro; + params.sampler = GPU_GetSharedPointSampler(); + } + GPU_ResourceHandle params_buff = GPU_PushBufferFromCpu(frame->gpu_arena, frame->cl, StringFromStruct(¶ms)); + StructuredBufferHandle params_ro = GPU_PushStructuredBufferHandle(frame->gpu_arena, params_buff, UI_DParams); + + /* Constants */ + GPU_SetConstant(frame->cl, UI_ShaderConst_Params, params_ro); ////////////////////////////// //- Dispatch shaders - { - //- Prep rect pass - { - GPU_DumbMemoryLayoutSync(cl, draw_target, GPU_Layout_DirectQueue_RenderTargetWrite); - GPU_ClearRenderTarget(cl, draw_target, VEC4(0, 0, 0, 0)); - } + GPU_DumbMemoryLayoutSync(frame->cl, draw_target, GPU_Layout_DirectQueue_RenderTargetWrite); - //- Rect pass - if (rects_count > 0) + //- Clear pass + { + GPU_ClearRenderTarget(frame->cl, draw_target, VEC4(1, 0, 0, 0)); + } + + //- Rect pass + + GPU_DumbMemoryLayoutSync(frame->cl, draw_target, GPU_Layout_DirectQueue_RenderTargetWrite); + + if (GPU_CountBufferBytes(rects_buff) > 0) + { + /* Render rects */ + GPU_Rasterize(frame->cl, + UI_DRectVS, UI_DRectPS, + 1, GPU_GetSharedQuadIndices(), + 1, &draw_target, + draw_viewport, draw_scissor, + GPU_RasterMode_TriangleList); + + /* Render rect wireframes */ + if (AnyBit(frame->frame_flags, UI_FrameFlag_Debug)) { - /* Render rects */ - GPU_Rasterize(cl, + GPU_SetConstant(frame->cl, UI_ShaderConst_DebugDraw, 1); + GPU_Rasterize(frame->cl, UI_DRectVS, UI_DRectPS, 1, GPU_GetSharedQuadIndices(), 1, &draw_target, draw_viewport, draw_scissor, - GPU_RasterMode_TriangleList); - - /* Render rect wireframes */ - if (AnyBit(frame->frame_flags, UI_FrameFlag_Debug)) - { - GPU_SetConstant(cl, UI_ShaderConst_DebugDraw, 1); - GPU_Rasterize(cl, - UI_DRectVS, UI_DRectPS, - 1, GPU_GetSharedQuadIndices(), - 1, &draw_target, - draw_viewport, draw_scissor, - GPU_RasterMode_WireTriangleList); - } + GPU_RasterMode_WireTriangleList); } } - } - GPU_CommitCommandList(cl); + //- Backbuffer blit pass + + GPU_DumbMemoryLayoutSync(frame->cl, draw_target, GPU_Layout_DirectQueue_ShaderRead); + GPU_DumbMemoryLayoutSync(frame->cl, backbuffer, GPU_Layout_DirectQueue_RenderTargetWrite); + + { + GPU_Rasterize(frame->cl, + UI_BlitVS, UI_BlitPS, + 1, GPU_GetSharedQuadIndices(), + 1, &backbuffer, + draw_viewport, draw_scissor, + GPU_RasterMode_TriangleList); + } + + GPU_DumbMemoryLayoutSync(frame->cl, backbuffer, GPU_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present); + } ////////////////////////////// //- End frame + GPU_CommitCommandList(frame->cl); WND_EndFrame(frame->window_frame, VSYNC); EndScratch(scratch); diff --git a/src/ui/ui_core.h b/src/ui/ui_core.h index 86f20bb3..7670b4f9 100644 --- a/src/ui/ui_core.h +++ b/src/ui/ui_core.h @@ -317,6 +317,7 @@ Struct(UI_Frame) WND_Frame window_frame; GPU_ResourceHandle backbuffer; + GPU_CommandListHandle cl; u64 transient_key_seed; diff --git a/src/ui/ui_shaders.h b/src/ui/ui_shaders.h index 85b9715f..72e8282e 100644 --- a/src/ui/ui_shaders.h +++ b/src/ui/ui_shaders.h @@ -1,12 +1,20 @@ +//////////////////////////////////////////////////////////// +//~ Constant types + +ShaderConstant(StructuredBufferHandle, UI_ShaderConst_Params, 0); +ShaderConstant(b32, UI_ShaderConst_DebugDraw, 1); + +Struct(UI_DParams) +{ + Vec2I32 target_size; + Texture2DHandle target_ro; + StructuredBufferHandle rects; + SamplerStateHandle sampler; +}; + //////////////////////////////////////////////////////////// //~ Rect types -ShaderConstant(i32, UI_ShaderConst_TargetWidth, 0); -ShaderConstant(i32, UI_ShaderConst_TargetHeight, 1); -ShaderConstant(StructuredBufferHandle, UI_ShaderConst_Rects, 2); -ShaderConstant(SamplerStateHandle, UI_ShaderConst_Sampler, 3); -ShaderConstant(b32, UI_ShaderConst_DebugDraw, 4); - Struct(UI_DRect) { Vec2 p0; diff --git a/src/ui/ui_shaders.hlsl b/src/ui/ui_shaders.hlsl index 9e9807e5..9180b42c 100644 --- a/src/ui/ui_shaders.hlsl +++ b/src/ui/ui_shaders.hlsl @@ -3,7 +3,6 @@ Struct(UI_DRectPSInput) { - Semantic(Vec4, sv_position); Semantic(nointerpolation u32, rect_idx); Semantic(Vec4, background_lin); @@ -23,15 +22,16 @@ Struct(UI_DRectPSOutput) VertexShader(UI_DRectVS, UI_DRectPSInput) { - StructuredBuffer rects = StructuredBufferFromHandle(UI_ShaderConst_Rects); - UI_DRect rect = rects[SV_InstanceID]; + UI_DParams params = StructuredBufferFromHandle(UI_ShaderConst_Params)[0]; + StructuredBuffer rects = StructuredBufferFromHandle(params.rects); + UI_DRect rect = rects[SV_InstanceID]; Vec2 rect_uv = RectUvFromVertexId(SV_VertexID); Vec2 tex_uv = lerp(rect.tex_uv0, rect.tex_uv1, rect_uv); Vec2 target_pos = lerp(rect.p0, rect.p1, rect_uv); UI_DRectPSInput result; - result.sv_position = Vec4(NdcFromPos(target_pos, Vec2(UI_ShaderConst_TargetWidth, UI_ShaderConst_TargetHeight).xy), 0, 1); + result.sv_position = Vec4(NdcFromPos(target_pos, Vec2(params.target_size).xy), 0, 1); result.background_lin = rect.background_lin; result.border_lin = rect.border_lin; result.tint_lin = rect.tint_lin; @@ -47,8 +47,9 @@ VertexShader(UI_DRectVS, UI_DRectPSInput) PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) { - StructuredBuffer rects = StructuredBufferFromHandle(UI_ShaderConst_Rects); - SamplerState sampler = SamplerStateFromHandle(UI_ShaderConst_Sampler); + UI_DParams params = StructuredBufferFromHandle(UI_ShaderConst_Params)[0]; + StructuredBuffer rects = StructuredBufferFromHandle(params.rects); + SamplerState sampler = SamplerStateFromHandle(params.sampler); UI_DRect rect = rects[input.rect_idx]; @@ -132,3 +133,48 @@ PixelShader(UI_DRectPS, UI_DRectPSOutput, UI_DRectPSInput input) output.sv_target0 = final_color; return output; } + +//////////////////////////////////////////////////////////// +//~ Blit + +Struct(UI_BlitPSInput) +{ + Semantic(Vec4, SV_Position); + Semantic(Vec2, src_uv); +}; + +Struct(UI_BlitPSOutput) +{ + Semantic(Vec4, SV_Target0); +}; + +////////////////////////////// +//- Vertex shader + +VertexShader(UI_BlitVS, UI_BlitPSInput) +{ + Vec2 uv = RectUvFromVertexId(SV_VertexID); + UI_BlitPSInput result; + result.SV_Position = Vec4(NdcFromUv(uv).xy, 0, 1); + result.src_uv = uv; + return result; +} + +////////////////////////////// +//- Pixel shader + +PixelShader(UI_BlitPS, UI_BlitPSOutput, UI_BlitPSInput input) +{ + UI_DParams params = StructuredBufferFromHandle(UI_ShaderConst_Params)[0]; + SamplerState sampler = SamplerStateFromHandle(params.sampler); + Texture2D tex = Texture2DFromHandle(params.target_ro); + + Vec2 uv = input.src_uv; + Vec4 result = tex.Sample(sampler, uv); + + result = Vec4(1, 1, 0, 1); + + UI_BlitPSOutput output; + output.SV_Target0 = result; + return output; +}