tile sprite testing
This commit is contained in:
parent
d332315c16
commit
86b12bf909
@ -1,8 +1,4 @@
|
||||
//
|
||||
// Aseprite (.ase) file parser
|
||||
//
|
||||
// DEFLATE decoder based on Handmade Hero's png parser
|
||||
//
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Shared constants
|
||||
|
||||
@ -769,14 +769,16 @@ u64 MixU64s(u64 seed_a, u64 seed_b)
|
||||
}
|
||||
|
||||
#if IsLanguageC
|
||||
#define Fnv64Basis 0xCBF29CE484222325
|
||||
|
||||
// FNV-1a parameters for different hash sizes:
|
||||
// https://en.wikipedia.org/wiki/Fowler%E2%80%93Noll%E2%80%93Vo_hash_function#FNV_hash_parameters
|
||||
Inline u64 HashFnv64(u64 seed, String s)
|
||||
Inline u64 HashFnv64(u64 seed, String str)
|
||||
{
|
||||
u64 hash = seed;
|
||||
for (u64 i = 0; i < s.len; ++i)
|
||||
for (u64 i = 0; i < str.len; ++i)
|
||||
{
|
||||
hash ^= (u8)s.text[i];
|
||||
hash ^= (u8)str.text[i];
|
||||
hash *= 0x100000001B3;
|
||||
}
|
||||
return hash;
|
||||
|
||||
@ -497,6 +497,38 @@ String PathFromString(Arena *arena, String str, u8 path_delimiter)
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hash helpers
|
||||
|
||||
u64 HashStringEx(u64 seed, String str)
|
||||
{
|
||||
u64 result = HashFnv64(seed, str);
|
||||
result = MixU64(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
u64 HashString(String str)
|
||||
{
|
||||
return HashStringEx(Fnv64Basis, str);
|
||||
}
|
||||
|
||||
u64 HashF_(String fmt, ...)
|
||||
{
|
||||
u64 result = 0;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
{
|
||||
String str = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||
result = HashString(str);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ String list helpers
|
||||
|
||||
|
||||
@ -102,6 +102,14 @@ b32 StringEndsWith(String str, String substring);
|
||||
String StringFromArray(Arena *arena, StringArray a);
|
||||
String PathFromString(Arena *arena, String str, u8 path_delimiter);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hash helpers
|
||||
|
||||
u64 HashStringEx(u64 seed, String str);
|
||||
u64 HashString(String str);
|
||||
u64 HashF_(String fmt, ...);
|
||||
#define HashF(fmt_cstr, ...) HashF_(StringFromCstrNoLimit(fmt_cstr), __VA_ARGS__, FmtEnd)
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Trimming helpers
|
||||
|
||||
|
||||
@ -13,7 +13,7 @@ String TweakEx(Arena *arena, TweakVar desc, b32 update_existing)
|
||||
{
|
||||
String result = Zi;
|
||||
Arena *perm = PermArena();
|
||||
u64 hash = MixU64(HashFnv64(Fnv64Basis, desc.name));
|
||||
u64 hash = HashString(desc.name);
|
||||
TweakVarEntryBin *bin = &Base.tweak.entry_bins[hash % countof(Base.tweak.entry_bins)];
|
||||
LockTicketMutex(&Base.tweak.tm);
|
||||
{
|
||||
|
||||
@ -1,8 +1,3 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hash types
|
||||
|
||||
#define Fnv64Basis 0xCBF29CE484222325
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Mergesort types
|
||||
|
||||
@ -41,27 +36,6 @@ Struct(Dict)
|
||||
DictEntry *last;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Hash utils
|
||||
|
||||
#define HashF(fmt_cstr, ...) HashF_(StringFromCstrNoLimit(fmt_cstr), __VA_ARGS__, FmtEnd)
|
||||
Inline u64 HashF_(String fmt, ...)
|
||||
{
|
||||
u64 result = 0;
|
||||
TempArena scratch = BeginScratchNoConflict();
|
||||
{
|
||||
va_list args;
|
||||
va_start(args, fmt);
|
||||
{
|
||||
String str = FormatString(scratch.arena, fmt, FmtArgsFromVaList(scratch.arena, args));
|
||||
result = HashFnv64(Fnv64Basis, str);
|
||||
}
|
||||
va_end(args);
|
||||
}
|
||||
EndScratch(scratch);
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Mergesort utils
|
||||
|
||||
|
||||
@ -91,7 +91,7 @@ Struct(GC_Run)
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Cmd types
|
||||
//~ Async cmd types
|
||||
|
||||
Struct(GC_Cmd)
|
||||
{
|
||||
|
||||
@ -19,10 +19,40 @@ void G_BootstrapCommon(void)
|
||||
G.quad_indices = G_IdxBuff16(quad_indices);
|
||||
}
|
||||
|
||||
// Init point sampler
|
||||
// Init point clamp sampler
|
||||
{
|
||||
G_ResourceHandle pt_sampler = G_PushSampler(gpu_perm, cl, .filter = G_Filter_MinMagMipPoint);
|
||||
G.basic_sampler = G_PushSamplerStateRef(gpu_perm, pt_sampler);
|
||||
G_ResourceHandle pt_sampler = G_PushSampler(
|
||||
gpu_perm, cl,
|
||||
.filter = G_Filter_MinMagMipPoint,
|
||||
.x = G_AddressMode_Clamp,
|
||||
.y = G_AddressMode_Clamp,
|
||||
.z = G_AddressMode_Clamp,
|
||||
);
|
||||
G.basic_point_clamp_sampler = G_PushSamplerStateRef(gpu_perm, pt_sampler);
|
||||
}
|
||||
|
||||
// Init point wrap sampler
|
||||
{
|
||||
G_ResourceHandle pt_sampler = G_PushSampler(
|
||||
gpu_perm, cl,
|
||||
.filter = G_Filter_MinMagMipPoint,
|
||||
.x = G_AddressMode_Wrap,
|
||||
.y = G_AddressMode_Wrap,
|
||||
.z = G_AddressMode_Wrap,
|
||||
);
|
||||
G.basic_point_wrap_sampler = G_PushSamplerStateRef(gpu_perm, pt_sampler);
|
||||
}
|
||||
|
||||
// Init blank texture
|
||||
{
|
||||
G_ResourceHandle blank_tex = G_PushTexture2D(
|
||||
gpu_perm, cl,
|
||||
G_Format_R8G8B8A8_Uint,
|
||||
VEC2I32(8, 8),
|
||||
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present,
|
||||
.flags = G_ResourceFlag_ZeroMemory
|
||||
);
|
||||
G.blank_tex = G_PushTexture2DRef(gpu_perm, blank_tex);
|
||||
}
|
||||
|
||||
// Init noise texture
|
||||
@ -46,7 +76,6 @@ void G_BootstrapCommon(void)
|
||||
noise_data.text, noise_dims,
|
||||
RNG3I32(VEC3I32(0, 0, 0), noise_dims)
|
||||
);
|
||||
|
||||
G.basic_noise = G_PushTexture3DRef(gpu_perm, noise_tex);
|
||||
}
|
||||
|
||||
@ -101,9 +130,19 @@ G_IndexBufferDesc G_QuadIndices(void)
|
||||
return G.quad_indices;
|
||||
}
|
||||
|
||||
G_SamplerStateRef G_BasicSampler(void)
|
||||
G_SamplerStateRef G_BasicPointClampSampler(void)
|
||||
{
|
||||
return G.basic_sampler;
|
||||
return G.basic_point_clamp_sampler;
|
||||
}
|
||||
|
||||
G_SamplerStateRef G_BasicPointWrapSampler(void)
|
||||
{
|
||||
return G.basic_point_wrap_sampler;
|
||||
}
|
||||
|
||||
G_Texture2DRef G_BlankTexture2D(void)
|
||||
{
|
||||
return G.blank_tex;
|
||||
}
|
||||
|
||||
G_Texture3DRef G_BasicNoiseTexture(void)
|
||||
|
||||
@ -5,7 +5,9 @@ Struct(G_Ctx)
|
||||
{
|
||||
// Common shared resources
|
||||
G_IndexBufferDesc quad_indices;
|
||||
G_SamplerStateRef basic_sampler;
|
||||
G_SamplerStateRef basic_point_clamp_sampler;
|
||||
G_SamplerStateRef basic_point_wrap_sampler;
|
||||
G_Texture2DRef blank_tex;
|
||||
G_Texture3DRef basic_noise;
|
||||
};
|
||||
|
||||
@ -26,22 +28,20 @@ void G_BootstrapCommon(void);
|
||||
//~ Utils
|
||||
|
||||
//- Arena
|
||||
|
||||
G_ArenaHandle G_PermArena(void);
|
||||
|
||||
//- Push resource from cpu
|
||||
|
||||
G_ResourceHandle G_PushBufferFromCpuCopy_(G_ArenaHandle gpu_arena, G_CommandListHandle cl, String src, G_BufferDesc desc);
|
||||
#define G_PushBufferFromCpuCopy(_arena, _cl, _src, ...) \
|
||||
G_PushBufferFromCpuCopy_((_arena), (_cl), (_src), (G_BufferDesc) { .size = (_src).len, __VA_ARGS__ })
|
||||
|
||||
//- Viewport / scissor
|
||||
|
||||
Rng3 G_ViewportFromTexture(G_ResourceHandle texture);
|
||||
Rng2 G_ScissorFromTexture(G_ResourceHandle texture);
|
||||
|
||||
//- Shared resources
|
||||
|
||||
G_IndexBufferDesc G_QuadIndices(void);
|
||||
G_SamplerStateRef G_BasicSampler(void);
|
||||
G_SamplerStateRef G_BasicPointClampSampler(void);
|
||||
G_SamplerStateRef G_BasicPointWrapSampler(void);
|
||||
G_Texture2DRef G_BlankTexture2D(void);
|
||||
G_Texture3DRef G_BasicNoiseTexture(void);
|
||||
|
||||
@ -271,6 +271,7 @@ Enum(G_Layout)
|
||||
G_Layout_DirectComputeQueue_ShaderReadWrite, // D3D12_BARRIER_LAYOUT_UNORDERED_ACCESS
|
||||
G_Layout_DirectComputeQueue_ShaderRead, // D3D12_BARRIER_LAYOUT_SHADER_RESOURCE
|
||||
G_Layout_DirectComputeQueue_CopyRead, // D3D12_BARRIER_LAYOUT_COPY_SOURCE
|
||||
G_Layout_DirectComputeQueue_CopyWrite, // D3D12_BARRIER_LAYOUT_COPY_DEST
|
||||
|
||||
//////////////////////////////
|
||||
//- Direct queue
|
||||
@ -281,6 +282,7 @@ Enum(G_Layout)
|
||||
G_Layout_DirectQueue_ShaderReadWrite, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS
|
||||
G_Layout_DirectQueue_ShaderRead, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE
|
||||
G_Layout_DirectQueue_CopyRead, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE
|
||||
G_Layout_DirectQueue_CopyWrite, // D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST
|
||||
|
||||
G_Layout_DirectQueue_DepthStencilRead_DepthStencilWrite, // D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE
|
||||
G_Layout_DirectQueue_DepthStencilRead, // D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ
|
||||
@ -295,6 +297,7 @@ Enum(G_Layout)
|
||||
G_Layout_ComputeQueue_ShaderReadWrite, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_UNORDERED_ACCESS
|
||||
G_Layout_ComputeQueue_ShaderRead, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE
|
||||
G_Layout_ComputeQueue_CopyRead, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE
|
||||
G_Layout_ComputeQueue_CopyWrite, // D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST
|
||||
};
|
||||
|
||||
// Barrier will execute after previous stages specified by `stage_prev`, and before next stages specified by `stage_next`.
|
||||
|
||||
@ -425,11 +425,13 @@ D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
|
||||
[G_Layout_DirectComputeQueue_ShaderRead_CopyRead] = D3D12_BARRIER_LAYOUT_GENERIC_READ,
|
||||
[G_Layout_DirectComputeQueue_ShaderRead] = D3D12_BARRIER_LAYOUT_SHADER_RESOURCE,
|
||||
[G_Layout_DirectComputeQueue_CopyRead] = D3D12_BARRIER_LAYOUT_COPY_SOURCE,
|
||||
[G_Layout_DirectComputeQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_COPY_DEST,
|
||||
[G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COMMON,
|
||||
[G_Layout_DirectQueue_ShaderReadWrite] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_UNORDERED_ACCESS,
|
||||
[G_Layout_DirectQueue_ShaderRead_CopyRead_DepthStencilRead] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_GENERIC_READ,
|
||||
[G_Layout_DirectQueue_ShaderRead] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_SHADER_RESOURCE,
|
||||
[G_Layout_DirectQueue_CopyRead] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_SOURCE,
|
||||
[G_Layout_DirectQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_DIRECT_QUEUE_COPY_DEST,
|
||||
[G_Layout_DirectQueue_DepthStencilRead_DepthStencilWrite] = D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_WRITE,
|
||||
[G_Layout_DirectQueue_DepthStencilRead] = D3D12_BARRIER_LAYOUT_DEPTH_STENCIL_READ,
|
||||
[G_Layout_DirectQueue_RenderTargetWrite] = D3D12_BARRIER_LAYOUT_RENDER_TARGET,
|
||||
@ -438,6 +440,7 @@ D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
|
||||
[G_Layout_ComputeQueue_ShaderRead_CopyRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_GENERIC_READ,
|
||||
[G_Layout_ComputeQueue_ShaderRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_SHADER_RESOURCE,
|
||||
[G_Layout_ComputeQueue_CopyRead] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_SOURCE,
|
||||
[G_Layout_ComputeQueue_CopyWrite] = D3D12_BARRIER_LAYOUT_COMPUTE_QUEUE_COPY_DEST,
|
||||
};
|
||||
return translate[layout];
|
||||
};
|
||||
@ -447,7 +450,7 @@ D3D12_BARRIER_LAYOUT G_D12_BarrierLayoutFromLayout(G_Layout layout)
|
||||
|
||||
G_D12_Pipeline *G_D12_PipelineFromDesc(G_D12_PipelineDesc desc)
|
||||
{
|
||||
u64 hash = MixU64(HashFnv64(Fnv64Basis, StringFromStruct(&desc)));
|
||||
u64 hash = HashString(StringFromStruct(&desc));
|
||||
|
||||
// Fetch pipeline from cache
|
||||
G_D12_Pipeline *pipeline = 0;
|
||||
|
||||
@ -283,7 +283,8 @@ void BuildEntryPoint(WaveLaneCtx *lane)
|
||||
for (StringListNode *n = check_files.first; n; n = n->next)
|
||||
{
|
||||
String file = n->s;
|
||||
new_metahash = MixU64s(HashFnv64(new_metahash, file), OS_LastWriteTimestampFromPath(file));
|
||||
new_metahash = MixU64s(new_metahash, OS_LastWriteTimestampFromPath(file));
|
||||
new_metahash = HashStringEx(new_metahash , file);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BIN
src/pp/pp_res/sprite/tiles.ase
(Stored with Git LFS)
Normal file
BIN
src/pp/pp_res/sprite/tiles.ase
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
src/pp/pp_res/sprite/tiles_real.ase
(Stored with Git LFS)
Normal file
BIN
src/pp/pp_res/sprite/tiles_real.ase
(Stored with Git LFS)
Normal file
Binary file not shown.
@ -1221,7 +1221,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
{
|
||||
UI_BuildColumnEx(panel->key);
|
||||
}
|
||||
UI_Push(Tag, panel->key.hash);
|
||||
UI_Push(Tag, panel->key.v);
|
||||
panel_dfs->cp = UI_PushCP(panel->key);
|
||||
|
||||
if (!panel->is_organizing_panel && !panel->is_viewport_panel)
|
||||
@ -1325,7 +1325,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
for (DrawableTab *tab = first_drawable_tab; tab; tab = tab->next)
|
||||
{
|
||||
UI_Push(Tag, tab->key.hash);
|
||||
UI_Push(Tag, tab->key.v);
|
||||
UI_BoxReport tab_rep = UI_ReportsFromKey(tab->key).draw;
|
||||
|
||||
if (tab == first_drawable_tab)
|
||||
@ -1538,7 +1538,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_SetNext(Flags, UI_BoxFlag_CaptureMouse);
|
||||
UI_PushCP(UI_BuildColumn());
|
||||
{
|
||||
UI_Push(Tag, window->key.hash);
|
||||
UI_Push(Tag, window->key.v);
|
||||
if (window->is_tile_window)
|
||||
{
|
||||
for (S_TileKind tile_kind = 0; tile_kind < S_TileKind_COUNT; ++tile_kind)
|
||||
@ -1679,7 +1679,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
palette->key = UI_KeyF("command palette");
|
||||
UI_Checkpoint palette_cp = UI_PushCP(UI_NilKey);
|
||||
{
|
||||
UI_Push(Tag, palette->key.hash);
|
||||
UI_Push(Tag, palette->key.v);
|
||||
UI_Key titlebar_key = UI_KeyF("title bar");
|
||||
UI_BoxReports titlebar_reps = UI_ReportsFromKey(titlebar_key);
|
||||
UI_BoxReports palette_reps = UI_ReportsFromKey(palette->key);
|
||||
@ -1880,7 +1880,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
UI_SetNext(Flags, UI_BoxFlag_DrawText | UI_BoxFlag_CaptureMouse);
|
||||
UI_PushCP(UI_BuildRowEx(item->key));
|
||||
{
|
||||
UI_Push(Tag, item->key.hash);
|
||||
UI_Push(Tag, item->key.v);
|
||||
|
||||
// Begin spacer
|
||||
UI_BuildSpacer(UI_PIX(spacing, 1), Axis_X);
|
||||
@ -2816,7 +2816,7 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
|
||||
|
||||
|
||||
if (0)
|
||||
// if (0)
|
||||
{
|
||||
for (S_Ent *bullet = S_FirstEnt(world); bullet->valid; bullet = S_NextEnt(bullet))
|
||||
{
|
||||
@ -3163,6 +3163,8 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
params.xf = frame->xf;
|
||||
params.seed = RandU64FromState(&frame->rand);
|
||||
|
||||
params.pt_wrap_sampler = G_BasicPointWrapSampler();
|
||||
|
||||
params.selection_mode = frame->selection_mode;
|
||||
params.equipped_tile = frame->equipped_tile;
|
||||
|
||||
@ -3190,27 +3192,27 @@ void V_TickForever(WaveLaneCtx *lane)
|
||||
params.cells = gpu_cells_ref;
|
||||
params.stains = gpu_stains_ref;
|
||||
params.drynesses = gpu_drynesses_ref;
|
||||
|
||||
// Fill tile textures
|
||||
{
|
||||
ResourceKey sheet_resource = ResourceKeyFromStore(&P_Resources, Lit("sprite/tiles.ase"));
|
||||
for (S_TileKind tile_kind = 0; tile_kind < S_TileKind_COUNT; ++tile_kind)
|
||||
{
|
||||
String tile_name = S_TileNameFromKind(tile_kind);
|
||||
SPR_SheetKey sheet = SPR_SheetKeyFromResource(sheet_resource);
|
||||
SPR_Slice tile_slice = SPR_SliceFromSheet(sheet, tile_name);
|
||||
params.tile_slices[tile_kind] = tile_slice;
|
||||
}
|
||||
}
|
||||
}
|
||||
G_ResourceHandle gpu_params = G_PushBufferFromCpuCopy(frame->gpu_arena, frame->cl, StringFromStruct(¶ms));
|
||||
G_StructuredBufferRef gpu_params_ref = G_PushStructuredBufferRef(frame->gpu_arena, gpu_params, V_GpuParams);
|
||||
|
||||
// Fill tile textures
|
||||
{
|
||||
ResourceKey tiles_resource = ResourceKeyFromStore(&P_Resources, Lit("sprite/tiles.ase"));
|
||||
for (S_TileKind tile_kind = 0; tile_kind < S_TileKind_COUNT; ++tile_kind)
|
||||
{
|
||||
String tile_name = S_TileNameFromKind(tile_kind);
|
||||
SPR_Key sprite_key = SPR_KeyFromResource(tiles_resource);
|
||||
SPR_Slice tile_slice = SPR_SliceFromKey(sprite_key, tile_name);
|
||||
params.tile_slices[tile_kind] = tile_slice;
|
||||
}
|
||||
}
|
||||
|
||||
// Upload tiles
|
||||
if (tiles_dirty)
|
||||
{
|
||||
LogDebugF("Uploading tiles to gpu");
|
||||
G_DumbMemoryLayoutSync(frame->cl, gpu_tiles, G_Layout_DirectQueue_ShaderRead_ShaderReadWrite_CopyRead_CopyWrite);
|
||||
G_DumbMemoryLayoutSync(frame->cl, gpu_tiles, G_Layout_DirectQueue_CopyWrite);
|
||||
G_CopyCpuToTexture(
|
||||
frame->cl,
|
||||
gpu_tiles, VEC3I32(0, 0, 0),
|
||||
|
||||
@ -88,8 +88,8 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
|
||||
f32 half_thickness = 1;
|
||||
f32 half_bounds_size = S_WorldPitch * 0.5;
|
||||
Vec2 bounds_screen_p0 = mul(params.xf.world_to_draw, Vec3(-half_bounds_size, -half_bounds_size, 1));
|
||||
Vec2 bounds_screen_p1 = mul(params.xf.world_to_draw, Vec3(half_bounds_size, half_bounds_size, 1));
|
||||
Vec2 bounds_screen_p0 = mul(params.xf.world_to_ui, Vec3(-half_bounds_size, -half_bounds_size, 1));
|
||||
Vec2 bounds_screen_p1 = mul(params.xf.world_to_ui, Vec3(half_bounds_size, half_bounds_size, 1));
|
||||
bool is_in_bounds = ui_pos.x > (bounds_screen_p0.x - half_thickness) &&
|
||||
ui_pos.y > (bounds_screen_p0.y - half_thickness) &&
|
||||
ui_pos.x < (bounds_screen_p1.x + half_thickness) &&
|
||||
@ -125,8 +125,8 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
}
|
||||
// Grid outline
|
||||
{
|
||||
Vec2 grid_screen_p0 = mul(params.xf.world_to_draw, Vec3(floor(world_pos), 1));
|
||||
Vec2 grid_screen_p1 = mul(params.xf.world_to_draw, Vec3(ceil(world_pos), 1));
|
||||
Vec2 grid_screen_p0 = mul(params.xf.world_to_ui, Vec3(floor(world_pos), 1));
|
||||
Vec2 grid_screen_p1 = mul(params.xf.world_to_ui, Vec3(ceil(world_pos), 1));
|
||||
f32 grid_dist = 100000;
|
||||
grid_dist = min(grid_dist, abs(ui_pos.x - grid_screen_p0.x));
|
||||
grid_dist = min(grid_dist, abs(ui_pos.x - grid_screen_p1.x));
|
||||
@ -137,27 +137,9 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
result = grid_color;
|
||||
}
|
||||
}
|
||||
// Tile
|
||||
{
|
||||
switch (tile)
|
||||
{
|
||||
default: break;
|
||||
|
||||
case S_TileKind_Floor:
|
||||
{
|
||||
result = Color_Blue;
|
||||
} break;
|
||||
|
||||
case S_TileKind_Wall:
|
||||
{
|
||||
// result = Color_Red;
|
||||
result = Color_Black;
|
||||
} break;
|
||||
}
|
||||
}
|
||||
// Axis
|
||||
{
|
||||
Vec2 zero_screen = mul(params.xf.world_to_draw, Vec3(0, 0, 1));
|
||||
Vec2 zero_screen = mul(params.xf.world_to_ui, Vec3(0, 0, 1));
|
||||
f32 x_dist = abs(ui_pos.x - zero_screen.x);
|
||||
f32 y_dist = abs(ui_pos.y - zero_screen.y);
|
||||
if (y_dist <= half_thickness)
|
||||
@ -186,6 +168,44 @@ ComputeShader2D(V_BackdropCS, 8, 8)
|
||||
|
||||
|
||||
|
||||
|
||||
// Tile test
|
||||
// TODO: Remove this
|
||||
{
|
||||
if (tile == S_TileKind_Floor)
|
||||
{
|
||||
SamplerState wrap_sampler = G_Dereference(params.pt_wrap_sampler);
|
||||
SPR_Slice slice = params.tile_slices[tile];
|
||||
Texture2D<Vec4> tile_tex = G_Dereference<Vec4>(slice.tex);
|
||||
result = tile_tex.Sample(wrap_sampler, world_pos);
|
||||
}
|
||||
else if (tile == S_TileKind_Wall)
|
||||
{
|
||||
result = Color_Black;
|
||||
}
|
||||
|
||||
|
||||
// switch (tile)
|
||||
// {
|
||||
// default: break;
|
||||
|
||||
// case S_TileKind_Floor:
|
||||
// {
|
||||
// result = Color_Blue;
|
||||
// } break;
|
||||
|
||||
// case S_TileKind_Wall:
|
||||
// {
|
||||
// // result = Color_Red;
|
||||
// result = Color_Black;
|
||||
// } break;
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// TODO: Remove this
|
||||
// Cells test
|
||||
{
|
||||
@ -370,7 +390,6 @@ ComputeShader(V_SimParticlesCS, 64)
|
||||
u64 seed0 = MixU64(emitter.seed + particle.seq);
|
||||
u64 seed1 = MixU64(seed0);
|
||||
|
||||
|
||||
f32 rand_speed = (f32)((seed0 >> 0) & 0xFFFF) / (f32)0xFFFF;
|
||||
f32 rand_angle = (f32)((seed0 >> 16) & 0xFFFF) / (f32)0xFFFF;
|
||||
f32 rand_offset = (f32)((seed0 >> 32) & 0xFFFF) / (f32)0xFFFF;
|
||||
|
||||
@ -53,9 +53,10 @@ Struct(V_GpuParams)
|
||||
G_Texture2DRef target_ro;
|
||||
G_RWTexture2DRef target_rw;
|
||||
V_Xforms xf;
|
||||
|
||||
u64 seed;
|
||||
|
||||
G_SamplerStateRef pt_wrap_sampler;
|
||||
|
||||
V_SelectionMode selection_mode;
|
||||
S_TileKind equipped_tile;
|
||||
|
||||
|
||||
@ -11,23 +11,110 @@ void SPR_Bootstrap(void)
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Key helpers
|
||||
|
||||
SPR_Key SPR_KeyFromResource(ResourceKey resource)
|
||||
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource)
|
||||
{
|
||||
SPR_Key result = Zi;
|
||||
SPR_SheetKey result = Zi;
|
||||
result.r = resource;
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Lookup
|
||||
|
||||
SPR_Slice SPR_SliceFromKey(SPR_Key key, String slice_name)
|
||||
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, String slice_name)
|
||||
{
|
||||
SPR_Slice result = Zi;
|
||||
|
||||
// u64 hash = key.hash;
|
||||
// hash = Mi
|
||||
u64 hash = sheet.r.v;
|
||||
hash = HashStringEx(hash, slice_name);
|
||||
|
||||
// SPR_SliceBin *bin = &SPR.slice_bins[
|
||||
i64 completion = G_CompletionValueFromQueue(G_QueueKind_AsyncCopy);
|
||||
|
||||
// Search for existing entry
|
||||
b32 found = 0;
|
||||
SPR_SliceBin *bin = &SPR.slice_bins[hash % countof(SPR.slice_bins)];
|
||||
{
|
||||
Lock bin_lock = LockS(&bin->mutex);
|
||||
{
|
||||
SPR_SliceEntry *entry = bin->first;
|
||||
for (; entry; entry = entry->next)
|
||||
{
|
||||
if (entry->hash == hash)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry)
|
||||
{
|
||||
if (completion >= Atomic64Fetch(&entry->async_copy_completion_target))
|
||||
{
|
||||
result = entry->slice;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
Unlock(&bin_lock);
|
||||
}
|
||||
|
||||
// Push new entry
|
||||
if (!found)
|
||||
{
|
||||
Lock submit_lock = LockE(&SPR.submit.mutex);
|
||||
Lock bin_lock = LockE(&bin->mutex);
|
||||
{
|
||||
SPR_SliceEntry *entry = bin->first;
|
||||
for (; entry; entry = entry->next)
|
||||
{
|
||||
if (entry->hash == hash)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (entry)
|
||||
{
|
||||
if (completion >= Atomic64Fetch(&entry->async_copy_completion_target))
|
||||
{
|
||||
result = entry->slice;
|
||||
}
|
||||
found = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
|
||||
entry = PushStruct(perm, SPR_SliceEntry);
|
||||
entry->hash = hash;
|
||||
Atomic64FetchSet(&entry->async_copy_completion_target, I64Max);
|
||||
entry->sheet = sheet;
|
||||
entry->slice_name = PushString(perm, slice_name);
|
||||
SllStackPush(bin->first, entry);
|
||||
|
||||
SPR_CmdNode *n = SPR.submit.first_free;
|
||||
if (n)
|
||||
{
|
||||
ZeroStruct(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = PushStruct(perm, SPR_CmdNode);
|
||||
}
|
||||
n->cmd.entry = entry;
|
||||
SllQueuePush(SPR.submit.first, SPR.submit.last, n);
|
||||
++SPR.submit.count;
|
||||
Atomic32FetchSet(&SPR.new_cmds_present, 1);
|
||||
SignalAsyncTick();
|
||||
}
|
||||
}
|
||||
Unlock(&bin_lock);
|
||||
Unlock(&submit_lock);
|
||||
}
|
||||
|
||||
if (G_IsRefNil(result.tex))
|
||||
{
|
||||
result.tex = G_BlankTexture2D();
|
||||
result.uv_rect.p0 = VEC2(0, 0);
|
||||
result.uv_rect.p1 = VEC2(1, 1);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -37,4 +124,117 @@ SPR_Slice SPR_SliceFromKey(SPR_Key key, String slice_name)
|
||||
|
||||
void SPR_TickAsync(WaveLaneCtx *lane, AsyncFrameLaneCtx *base_async_lane_frame)
|
||||
{
|
||||
Arena *perm = PermArena();
|
||||
SPR_AsyncCtx *async = &SPR.async;
|
||||
Arena *frame_arena = base_async_lane_frame->arena;
|
||||
|
||||
// TODO: Go wide
|
||||
if (lane->idx == 0)
|
||||
{
|
||||
if (Atomic32Fetch(&SPR.new_cmds_present))
|
||||
{
|
||||
Atomic32Set(&SPR.new_cmds_present, 0);
|
||||
SPR_CmdNode *first_cmd_node = 0;
|
||||
SPR_CmdNode *last_cmd_node = 0;
|
||||
u64 cmds_count = 0;
|
||||
{
|
||||
Lock lock = LockE(&SPR.submit.mutex);
|
||||
{
|
||||
first_cmd_node = SPR.submit.first;
|
||||
last_cmd_node = SPR.submit.last;
|
||||
cmds_count = SPR.submit.count;
|
||||
SPR.submit.first = 0;
|
||||
SPR.submit.last = 0;
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
if (cmds_count > 0)
|
||||
{
|
||||
for (SPR_CmdNode *n = first_cmd_node; n; n = n->next)
|
||||
{
|
||||
SPR_Cmd cmd = n->cmd;
|
||||
SPR_SliceEntry *slice_entry = cmd.entry;
|
||||
|
||||
SPR_SheetBin *sheet_bin = &async->sheet_bins[slice_entry->sheet.r.v % countof(async->sheet_bins)];
|
||||
SPR_SheetEntry *sheet = sheet_bin->first;
|
||||
for (; sheet; sheet = sheet->next)
|
||||
{
|
||||
if (sheet->key.r.v == slice_entry->sheet.r.v)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Decode sheet
|
||||
// TODO: Distribute chunk decoding accross wave
|
||||
// TODO: Use atlas allocator and separate slices into unique textures
|
||||
// TODO: Reuse command list for all uploads
|
||||
if (!sheet)
|
||||
{
|
||||
sheet = PushStruct(perm, SPR_SheetEntry);
|
||||
sheet->key = slice_entry->sheet;
|
||||
SllStackPush(sheet_bin->first, sheet);
|
||||
|
||||
String encoded = DataFromResource(sheet->key.r);
|
||||
String name = NameFromResource(sheet->key.r);
|
||||
LogInfoF("Decoding sprite sheet \"%F\" (%F bytes)", FmtString(name), FmtUint(encoded.len));
|
||||
|
||||
ASE_DecodedImage decoded_image = ASE_DecodeImage(frame_arena, encoded);
|
||||
ASE_DecodedSheet decoded_sheet = ASE_DecodeSheet(frame_arena, encoded);
|
||||
|
||||
if (decoded_image.ok)
|
||||
{
|
||||
G_ResourceHandle gpu_resource = Zi;
|
||||
G_ArenaHandle gpu_perm = G_PermArena();
|
||||
G_CommandListHandle cl = G_PrepareCommandList(G_QueueKind_AsyncCopy);
|
||||
{
|
||||
Vec3I32 dims = Zi;
|
||||
dims.x = decoded_image.width;
|
||||
dims.y = decoded_image.height;
|
||||
dims.z = 1;
|
||||
gpu_resource = G_PushTexture2D(
|
||||
gpu_perm, cl,
|
||||
G_Format_R8G8B8A8_Unorm_Srgb,
|
||||
dims,
|
||||
G_Layout_AnyQueue_ShaderRead_CopyRead_CopyWrite_Present
|
||||
);
|
||||
G_CopyCpuToTexture(
|
||||
cl,
|
||||
gpu_resource, VEC3I32(0, 0, 0),
|
||||
decoded_image.pixels, dims,
|
||||
RNG3I32(
|
||||
VEC3I32(0, 0, 0),
|
||||
dims
|
||||
)
|
||||
);
|
||||
}
|
||||
i64 completion_target = G_CommitCommandList(cl);
|
||||
sheet->async_copy_completion_target = completion_target;
|
||||
sheet->tex = G_PushTexture2DRef(gpu_perm, gpu_resource);
|
||||
// LogDebugF("Decoded with ref: %F", FmtUint(slice_entry->slice.tex.v));
|
||||
}
|
||||
else
|
||||
{
|
||||
// TODO: Use 'missing' texture
|
||||
sheet->tex = G_BlankTexture2D();
|
||||
sheet->async_copy_completion_target = 0;
|
||||
}
|
||||
}
|
||||
slice_entry->slice.tex = sheet->tex;
|
||||
// FIXME: Real uv
|
||||
slice_entry->slice.uv_rect.p0 = VEC2(0, 0);
|
||||
slice_entry->slice.uv_rect.p1= VEC2(1, 1);
|
||||
Atomic64Set(&slice_entry->async_copy_completion_target, sheet->async_copy_completion_target);
|
||||
}
|
||||
|
||||
// Free cmds
|
||||
Lock lock = LockE(&SPR.submit.mutex);
|
||||
{
|
||||
last_cmd_node->next = SPR.submit.first_free;
|
||||
SPR.submit.first_free = first_cmd_node;
|
||||
}
|
||||
Unlock(&lock);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,9 +1,83 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Key types
|
||||
|
||||
Struct(SPR_SheetKey)
|
||||
{
|
||||
ResourceKey r;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Cache types
|
||||
|
||||
Struct(SPR_SliceEntry)
|
||||
{
|
||||
SPR_SliceEntry *next;
|
||||
|
||||
SPR_SheetKey sheet;
|
||||
u64 hash;
|
||||
Atomic64 async_copy_completion_target;
|
||||
|
||||
String slice_name;
|
||||
|
||||
SPR_Slice slice;
|
||||
};
|
||||
|
||||
Struct(SPR_SliceBin)
|
||||
{
|
||||
Mutex mutex;
|
||||
SPR_SliceEntry *first;
|
||||
};
|
||||
|
||||
Struct(SPR_SheetEntry)
|
||||
{
|
||||
SPR_SheetEntry *next;
|
||||
SPR_SheetKey key;
|
||||
i64 async_copy_completion_target;
|
||||
G_Texture2DRef tex;
|
||||
};
|
||||
|
||||
Struct(SPR_SheetBin)
|
||||
{
|
||||
SPR_SheetEntry *first;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async cmd types
|
||||
|
||||
Struct(SPR_Cmd)
|
||||
{
|
||||
SPR_SliceEntry *entry;
|
||||
};
|
||||
|
||||
Struct(SPR_CmdNode)
|
||||
{
|
||||
SPR_CmdNode *next;
|
||||
SPR_Cmd cmd;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ State types
|
||||
|
||||
Struct(SPR_AsyncCtx)
|
||||
{
|
||||
SPR_SheetBin sheet_bins[Kibi(16)];
|
||||
};
|
||||
|
||||
Struct(SPR_Ctx)
|
||||
{
|
||||
i32 _;
|
||||
SPR_SliceBin slice_bins[Kibi(16)];
|
||||
|
||||
Atomic32 new_cmds_present;
|
||||
struct
|
||||
{
|
||||
Mutex mutex;
|
||||
SPR_CmdNode *first;
|
||||
SPR_CmdNode *last;
|
||||
SPR_CmdNode *first_free;
|
||||
u64 count;
|
||||
} submit;
|
||||
|
||||
SPR_AsyncCtx async;
|
||||
};
|
||||
|
||||
extern SPR_Ctx SPR;
|
||||
@ -16,12 +90,12 @@ void SPR_Bootstrap(void);
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Key helpers
|
||||
|
||||
SPR_Key SPR_KeyFromResource(ResourceKey resource);
|
||||
SPR_SheetKey SPR_SheetKeyFromResource(ResourceKey resource);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Lookup
|
||||
|
||||
SPR_Slice SPR_SliceFromKey(SPR_Key key, String slice_name);
|
||||
SPR_Slice SPR_SliceFromSheet(SPR_SheetKey sheet, String slice_name);
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Async
|
||||
|
||||
@ -1,16 +1,8 @@
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Key types
|
||||
|
||||
Struct(SPR_Key)
|
||||
{
|
||||
u64 v;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
//~ Slice types
|
||||
|
||||
Struct(SPR_Slice)
|
||||
{
|
||||
G_Texture2DRef tex;
|
||||
Rng2 uv;
|
||||
Rng2 uv_rect;
|
||||
};
|
||||
|
||||
@ -12,19 +12,19 @@ void UI_Bootstrap(void)
|
||||
|
||||
b32 UI_MatchKey(UI_Key a, UI_Key b)
|
||||
{
|
||||
return a.hash == b.hash;
|
||||
return a.v == b.v;
|
||||
}
|
||||
|
||||
b32 UI_IsKeyNil(UI_Key key)
|
||||
{
|
||||
return key.hash == 0;
|
||||
return key.v == 0;
|
||||
}
|
||||
|
||||
UI_Key UI_KeyFromString(String str)
|
||||
{
|
||||
u64 top_tag = UI_Top(Tag);
|
||||
UI_Key key = Zi;
|
||||
key.hash = HashFnv64(top_tag, str);
|
||||
key.v = HashFnv64(top_tag, str);
|
||||
return key;
|
||||
}
|
||||
|
||||
@ -45,18 +45,17 @@ UI_Key UI_KeyF_(String fmt, ...)
|
||||
|
||||
UI_Key UI_RandKey(void)
|
||||
{
|
||||
u64 seed = ++UI.rand_key_seed;
|
||||
UI_Key key = Zi;
|
||||
key.hash = MixU64(seed);
|
||||
key.v = RandU64FromState(&UI.rand);
|
||||
return key;
|
||||
}
|
||||
|
||||
UI_Box *UI_BoxFromKey(UI_Key key)
|
||||
{
|
||||
UI_Box *box = 0;
|
||||
if (key.hash != 0)
|
||||
if (key.v != 0)
|
||||
{
|
||||
UI_BoxBin *bin = &UI.box_bins[key.hash % countof(UI.box_bins)];
|
||||
UI_BoxBin *bin = &UI.box_bins[key.v % countof(UI.box_bins)];
|
||||
for (box = bin->first; box; box = box->next_in_bin)
|
||||
{
|
||||
if (UI_MatchKey(box->key, key))
|
||||
@ -284,7 +283,7 @@ UI_Checkpoint UI_PushCP(UI_Key parent)
|
||||
UI_Frame *frame = UI_CurrentFrame();
|
||||
UI_Stack *stack = frame->top_stack;
|
||||
stack->top_checkpoint.v += 1;
|
||||
if (parent.hash != 0)
|
||||
if (parent.v != 0)
|
||||
{
|
||||
UI_Push(Parent, parent);
|
||||
}
|
||||
@ -574,7 +573,7 @@ UI_Frame *UI_BeginFrame(UI_FrameFlag frame_flags)
|
||||
box->key = UI_RootKey;
|
||||
box->gen = 1;
|
||||
UI.boxes_count += 1;
|
||||
UI_BoxBin *bin = &UI.box_bins[box->key.hash % countof(UI.box_bins)];
|
||||
UI_BoxBin *bin = &UI.box_bins[box->key.v % countof(UI.box_bins)];
|
||||
bin->first = box;
|
||||
bin->last = box;
|
||||
UI.root_box = box;
|
||||
@ -938,7 +937,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
|
||||
UI_Key key = cmd.box.key;
|
||||
UI_Box *box = 0;
|
||||
{
|
||||
UI_BoxBin *bin = &UI.box_bins[key.hash % countof(UI.box_bins)];
|
||||
UI_BoxBin *bin = &UI.box_bins[key.v % countof(UI.box_bins)];
|
||||
for (box = bin->first; box; box = box->next_in_bin)
|
||||
{
|
||||
if (UI_MatchKey(box->key, key))
|
||||
@ -1069,7 +1068,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
|
||||
{
|
||||
UI_Box *box = prunes[prune_idx];
|
||||
UI_Box *parent = box->parent;
|
||||
UI_BoxBin *bin = &UI.box_bins[box->key.hash % countof(UI.box_bins)];
|
||||
UI_BoxBin *bin = &UI.box_bins[box->key.v % countof(UI.box_bins)];
|
||||
// Re-parent children
|
||||
if (box->first)
|
||||
{
|
||||
@ -1704,7 +1703,7 @@ void UI_EndFrame(UI_Frame *frame, i32 vsync)
|
||||
params.target_size = draw_size;
|
||||
params.target_ro = draw_target_ro;
|
||||
params.rects = rects_ro;
|
||||
params.sampler = G_BasicSampler();
|
||||
params.sampler = G_BasicPointClampSampler();
|
||||
params.cursor_pos = frame->cursor_pos;
|
||||
params.aa = TweakFloat("UI anti-aliasing", 1, 0, 1);
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
Struct(UI_Key)
|
||||
{
|
||||
u64 hash;
|
||||
u64 v;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////
|
||||
@ -412,7 +412,7 @@ Struct(UI_Ctx)
|
||||
UI_BoxBin box_bins[Kibi(256)];
|
||||
UI_Box *first_free_box;
|
||||
|
||||
u64 rand_key_seed;
|
||||
RandState rand;
|
||||
|
||||
i64 current_frame_tick;
|
||||
UI_Frame frames[2];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user