From 7cf8da0b4381a4cea66ef7ebb2d1f92b42416633 Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Tue, 26 Mar 2024 11:50:44 -0700 Subject: [PATCH] eliminate fallback key/hash pair cache in texture cache layer; we can rely on rewinding purely via the hash store layer --- src/df/gfx/df_view_rule_hooks.c | 16 ++++- src/df/gfx/df_views.c | 14 ++-- src/texture_cache/texture_cache.c | 103 ++++++------------------------ src/texture_cache/texture_cache.h | 28 ++------ 4 files changed, 46 insertions(+), 115 deletions(-) diff --git a/src/df/gfx/df_view_rule_hooks.c b/src/df/gfx/df_view_rule_hooks.c index 2c63c1d4..15b3f965 100644 --- a/src/df/gfx/df_view_rule_hooks.c +++ b/src/df/gfx/df_view_rule_hooks.c @@ -877,6 +877,17 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap) U64 expected_size = topology_info.width*topology_info.height*r_tex2d_format_bytes_per_pixel_table[topology_info.fmt]; Rng1U64 vaddr_range = r1u64(base_vaddr, base_vaddr+expected_size); + //- rjf: obtain key for this data range + U128 texture_key = ctrl_hash_store_key_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0); + // HACK(rjf): we should not need to explicitly inform the process memory cache layer here - + // want a joined "get me the key & load it" operation here + ctrl_stored_hash_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0, 0, 0); + + //- rjf: hash & topology -> texture + TEX_Topology topology = tex_topology_make(v2s32((S32)topology_info.width, (S32)topology_info.height), topology_info.fmt); + R_Handle texture = tex_texture_from_key_topology(tex_scope, texture_key, topology); + +#if 0 //- rjf: unique identifying info about this address -> unique key U128 texture_key = {0}; { @@ -892,10 +903,8 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap) //- rjf: address range -> hash U128 hash = ctrl_stored_hash_from_process_vaddr_range(process->ctrl_machine_id, process->ctrl_handle, vaddr_range, 0, 0, 0); - - //- rjf: hash & topology -> texture - TEX_Topology topology = tex_topology_make(v2s32((S32)topology_info.width, (S32)topology_info.height), topology_info.fmt); R_Handle texture = tex_texture_from_key_hash_topology(tex_scope, texture_key, hash, topology); +#endif //- rjf: build preview F32 rate = 1 - pow_f32(2, (-15.f * df_dt())); @@ -941,6 +950,7 @@ DF_GFX_VIEW_RULE_BLOCK_UI_FUNCTION_DEF(bitmap) { if(dim.y > (F32)topology_info.height) { + U128 hash = hs_hash_from_key(texture_key, 0); String8 data = hs_data_from_hash(hs_scope, hash); U64 bytes_per_pixel = r_tex2d_format_bytes_per_pixel_table[topology.fmt]; U64 mouse_pixel_off = mouse_bitmap_px_off.y*topology_info.width + mouse_bitmap_px_off.x; diff --git a/src/df/gfx/df_views.c b/src/df/gfx/df_views.c index 8084be2c..d10e8d73 100644 --- a/src/df/gfx/df_views.c +++ b/src/df/gfx/df_views.c @@ -5024,7 +5024,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code) { ProfBeginFunction(); Temp scratch = scratch_begin(0, 0); - DBGI_Scope *scope = dbgi_scope_open(); + DBGI_Scope *dbgi_scope = dbgi_scope_open(); + TXT_Scope *txt_scope = txt_scope_open(); DF_CodeViewState *tv = df_view_user_state(view, DF_CodeViewState); ////////////////////////////// @@ -5050,10 +5051,10 @@ DF_VIEW_UI_FUNCTION_DEF(Code) U64 unwind_count = ctrl_ctx.unwind_count; U64 rip_vaddr = df_query_cached_rip_from_thread_unwind(thread, unwind_count); DF_Entity *process = df_entity_ancestor_from_kind(thread, DF_EntityKind_Process); - EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(scope, process, rip_vaddr); + EVAL_ParseCtx parse_ctx = df_eval_parse_ctx_from_process_vaddr(dbgi_scope, process, rip_vaddr); ////////////////////////////// - //- rjf: unpack entity info + //- rjf: unpack file/text entity info // B32 entity_is_missing = !!(entity->flags & DF_EntityFlag_IsMissing && !(entity->flags & DF_EntityFlag_Output)); TXTI_Handle txti_handle = df_txti_handle_from_entity(entity); @@ -5467,7 +5468,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) String8 expr = txti_string_from_handle_txt_rng(scratch.arena, txti_handle, expr_rng); if(expr.size != 0) { - DF_Eval eval = df_eval_from_string(scratch.arena, scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); + DF_Eval eval = df_eval_from_string(scratch.arena, dbgi_scope, &ctrl_ctx, &parse_ctx, &eval_string2expr_map_nil, expr); if(eval.mode != EVAL_EvalMode_NULL) { df_set_hover_eval(ws, sig.mouse_expr_baseline_pos, ctrl_ctx, entity, sig.mouse_pt, 0, expr); @@ -5788,7 +5789,7 @@ DF_VIEW_UI_FUNCTION_DEF(Code) String8 full_path = df_full_path_from_entity(scratch.arena, entity); TXTI_Handle handle = txti_handle_from_path(full_path); TXTI_BufferInfo info = txti_buffer_info_from_handle(scratch.arena, handle); - DBGI_Parse *parse = df_dbgi_parse_from_binary_file(scope, binary); + DBGI_Parse *parse = df_dbgi_parse_from_binary_file(dbgi_scope, binary); if(parse->exe_props.modified < info.timestamp) { file_is_out_of_date = 1; @@ -5851,7 +5852,8 @@ DF_VIEW_UI_FUNCTION_DEF(Code) } } - dbgi_scope_close(scope); + txt_scope_close(txt_scope); + dbgi_scope_close(dbgi_scope); scratch_end(scratch); ProfEnd(); } diff --git a/src/texture_cache/texture_cache.c b/src/texture_cache/texture_cache.c index 9ef652e8..300eda12 100644 --- a/src/texture_cache/texture_cache.c +++ b/src/texture_cache/texture_cache.c @@ -34,16 +34,6 @@ tex_init(void) tex_shared->stripes[idx].rw_mutex = os_rw_mutex_alloc(); tex_shared->stripes[idx].cv = os_condition_variable_alloc(); } - tex_shared->fallback_slots_count = 1024; - tex_shared->fallback_stripes_count = Min(tex_shared->fallback_slots_count, os_logical_core_count()); - tex_shared->fallback_slots = push_array(arena, TEX_KeyFallbackSlot, tex_shared->fallback_slots_count); - tex_shared->fallback_stripes = push_array(arena, TEX_Stripe, tex_shared->fallback_stripes_count); - for(U64 idx = 0; idx < tex_shared->fallback_stripes_count; idx += 1) - { - tex_shared->fallback_stripes[idx].arena = arena_alloc(); - tex_shared->fallback_stripes[idx].rw_mutex = os_rw_mutex_alloc(); - tex_shared->fallback_stripes[idx].cv = os_condition_variable_alloc(); - } tex_shared->u2x_ring_size = KB(64); tex_shared->u2x_ring_base = push_array_no_zero(arena, U8, tex_shared->u2x_ring_size); tex_shared->u2x_ring_cv = os_condition_variable_alloc(); @@ -158,10 +148,9 @@ tex_scope_touch_node__stripe_r_guarded(TEX_Scope *scope, TEX_Node *node) //~ rjf: Cache Lookups internal R_Handle -tex_texture_from_key_hash_topology(TEX_Scope *scope, U128 key, U128 hash, TEX_Topology topology) +tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topology) { R_Handle handle = {0}; - if(!u128_match(u128_zero(), hash)) { U64 slot_idx = hash.u64[1]%tex_shared->slots_count; U64 stripe_idx = slot_idx%tex_shared->stripes_count; @@ -217,42 +206,23 @@ tex_texture_from_key_hash_topology(TEX_Scope *scope, U128 key, U128 hash, TEX_To } if(node_is_new) { - tex_u2x_enqueue_req(key, hash, topology, max_U64); + tex_u2x_enqueue_req(hash, topology, max_U64); } - if(r_handle_match(handle, r_handle_zero())) + } + return handle; +} + +internal R_Handle +tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology) +{ + R_Handle handle = {0}; + for(U64 rewind_idx = 0; rewind_idx < 2; rewind_idx += 1) + { + U128 hash = hs_hash_from_key(key, rewind_idx); + handle = tex_texture_from_hash_topology(scope, hash, topology); + if(!r_handle_match(handle, r_handle_zero())) { - U128 fallback_hash = {0}; - U64 fallback_slot_idx = key.u64[1]%tex_shared->fallback_slots_count; - U64 fallback_stripe_idx = fallback_slot_idx%tex_shared->fallback_stripes_count; - TEX_KeyFallbackSlot *fallback_slot = &tex_shared->fallback_slots[fallback_slot_idx]; - TEX_Stripe *fallback_stripe = &tex_shared->fallback_stripes[fallback_stripe_idx]; - OS_MutexScopeR(fallback_stripe->rw_mutex) for(TEX_KeyFallbackNode *n = fallback_slot->first; n != 0; n = n->next) - { - if(u128_match(key, n->key)) - { - fallback_hash = n->hash; - break; - } - } - if(!u128_match(fallback_hash, u128_zero())) - { - U64 retry_slot_idx = fallback_hash.u64[1]%tex_shared->slots_count; - U64 retry_stripe_idx = retry_slot_idx%tex_shared->stripes_count; - TEX_Slot *retry_slot = &tex_shared->slots[retry_slot_idx]; - TEX_Stripe *retry_stripe = &tex_shared->stripes[retry_stripe_idx]; - OS_MutexScopeR(retry_stripe->rw_mutex) - { - for(TEX_Node *n = retry_slot->first; n != 0; n = n->next) - { - if(u128_match(fallback_hash, n->hash) && MemoryMatchStruct(&topology, &n->topology)) - { - handle = n->texture; - tex_scope_touch_node__stripe_r_guarded(scope, n); - break; - } - } - } - } + break; } } return handle; @@ -262,17 +232,16 @@ tex_texture_from_key_hash_topology(TEX_Scope *scope, U128 key, U128 hash, TEX_To //~ rjf: Transfer Threads internal B32 -tex_u2x_enqueue_req(U128 key, U128 hash, TEX_Topology top, U64 endt_us) +tex_u2x_enqueue_req(U128 hash, TEX_Topology top, U64 endt_us) { B32 good = 0; OS_MutexScope(tex_shared->u2x_ring_mutex) for(;;) { U64 unconsumed_size = tex_shared->u2x_ring_write_pos-tex_shared->u2x_ring_read_pos; U64 available_size = tex_shared->u2x_ring_size-unconsumed_size; - if(available_size >= sizeof(key)+sizeof(hash)+sizeof(top)) + if(available_size >= sizeof(hash)+sizeof(top)) { good = 1; - tex_shared->u2x_ring_write_pos += ring_write_struct(tex_shared->u2x_ring_base, tex_shared->u2x_ring_size, tex_shared->u2x_ring_write_pos, &key); tex_shared->u2x_ring_write_pos += ring_write_struct(tex_shared->u2x_ring_base, tex_shared->u2x_ring_size, tex_shared->u2x_ring_write_pos, &hash); tex_shared->u2x_ring_write_pos += ring_write_struct(tex_shared->u2x_ring_base, tex_shared->u2x_ring_size, tex_shared->u2x_ring_write_pos, &top); break; @@ -291,14 +260,13 @@ tex_u2x_enqueue_req(U128 key, U128 hash, TEX_Topology top, U64 endt_us) } internal void -tex_u2x_dequeue_req(U128 *key_out, U128 *hash_out, TEX_Topology *top_out) +tex_u2x_dequeue_req(U128 *hash_out, TEX_Topology *top_out) { OS_MutexScope(tex_shared->u2x_ring_mutex) for(;;) { U64 unconsumed_size = tex_shared->u2x_ring_write_pos-tex_shared->u2x_ring_read_pos; - if(unconsumed_size >= sizeof(*key_out)+sizeof(*hash_out)+sizeof(*top_out)) + if(unconsumed_size >= sizeof(*hash_out)+sizeof(*top_out)) { - tex_shared->u2x_ring_read_pos += ring_read_struct(tex_shared->u2x_ring_base, tex_shared->u2x_ring_size, tex_shared->u2x_ring_read_pos, key_out); tex_shared->u2x_ring_read_pos += ring_read_struct(tex_shared->u2x_ring_base, tex_shared->u2x_ring_size, tex_shared->u2x_ring_read_pos, hash_out); tex_shared->u2x_ring_read_pos += ring_read_struct(tex_shared->u2x_ring_base, tex_shared->u2x_ring_size, tex_shared->u2x_ring_read_pos, top_out); break; @@ -316,10 +284,9 @@ tex_xfer_thread__entry_point(void *p) HS_Scope *scope = hs_scope_open(); //- rjf: decode - U128 key = {0}; U128 hash = {0}; TEX_Topology top = {0}; - tex_u2x_dequeue_req(&key, &hash, &top); + tex_u2x_dequeue_req(&hash, &top); //- rjf: unpack hash U64 slot_idx = hash.u64[1]%tex_shared->slots_count; @@ -370,34 +337,6 @@ tex_xfer_thread__entry_point(void *p) } } - //- rjf: commit this key/hash pair to fallback cache - if(got_task && !u128_match(key, u128_zero()) && !u128_match(hash, u128_zero())) - { - U64 fallback_slot_idx = key.u64[1]%tex_shared->fallback_slots_count; - U64 fallback_stripe_idx = fallback_slot_idx%tex_shared->fallback_stripes_count; - TEX_KeyFallbackSlot *fallback_slot = &tex_shared->fallback_slots[fallback_slot_idx]; - TEX_Stripe *fallback_stripe = &tex_shared->fallback_stripes[fallback_stripe_idx]; - OS_MutexScopeW(fallback_stripe->rw_mutex) - { - TEX_KeyFallbackNode *node = 0; - for(TEX_KeyFallbackNode *n = fallback_slot->first; n != 0; n = n->next) - { - if(u128_match(n->key, key)) - { - node = n; - break; - } - } - if(node == 0) - { - node = push_array(fallback_stripe->arena, TEX_KeyFallbackNode, 1); - SLLQueuePush(fallback_slot->first, fallback_slot->last, node); - } - node->key = key; - node->hash = hash; - } - } - hs_scope_close(scope); } } diff --git a/src/texture_cache/texture_cache.h b/src/texture_cache/texture_cache.h index 8245ccdd..ff8ac5a5 100644 --- a/src/texture_cache/texture_cache.h +++ b/src/texture_cache/texture_cache.h @@ -17,21 +17,6 @@ struct TEX_Topology //////////////////////////////// //~ rjf: Cache Types -typedef struct TEX_KeyFallbackNode TEX_KeyFallbackNode; -struct TEX_KeyFallbackNode -{ - TEX_KeyFallbackNode *next; - U128 key; - U128 hash; -}; - -typedef struct TEX_KeyFallbackSlot TEX_KeyFallbackSlot; -struct TEX_KeyFallbackSlot -{ - TEX_KeyFallbackNode *first; - TEX_KeyFallbackNode *last; -}; - typedef struct TEX_Node TEX_Node; struct TEX_Node { @@ -109,12 +94,6 @@ struct TEX_Shared TEX_Stripe *stripes; TEX_Node **stripes_free_nodes; - // rjf: fallback cache - U64 fallback_slots_count; - U64 fallback_stripes_count; - TEX_KeyFallbackSlot *fallback_slots; - TEX_Stripe *fallback_stripes; - // rjf: user -> xfer thread U64 u2x_ring_size; U8 *u2x_ring_base; @@ -168,13 +147,14 @@ internal void tex_scope_touch_node__stripe_r_guarded(TEX_Scope *scope, TEX_Node //////////////////////////////// //~ rjf: Cache Lookups -internal R_Handle tex_texture_from_key_hash_topology(TEX_Scope *scope, U128 key, U128 hash, TEX_Topology topology); +internal R_Handle tex_texture_from_hash_topology(TEX_Scope *scope, U128 hash, TEX_Topology topology); +internal R_Handle tex_texture_from_key_topology(TEX_Scope *scope, U128 key, TEX_Topology topology); //////////////////////////////// //~ rjf: Transfer Threads -internal B32 tex_u2x_enqueue_req(U128 key, U128 hash, TEX_Topology top, U64 endt_us); -internal void tex_u2x_dequeue_req(U128 *key_out, U128 *hash_out, TEX_Topology *top_out); +internal B32 tex_u2x_enqueue_req(U128 hash, TEX_Topology top, U64 endt_us); +internal void tex_u2x_dequeue_req(U128 *hash_out, TEX_Topology *top_out); internal void tex_xfer_thread__entry_point(void *p); ////////////////////////////////