set internal profiler thread affinities

This commit is contained in:
jacob 2025-07-12 05:29:15 -05:00
parent bf3e71c859
commit c3f94380c2
8 changed files with 57 additions and 38 deletions

View File

@ -17,11 +17,7 @@ struct draw_startup_receipt draw_startup(struct font_startup_receipt *font_sr)
{ {
(UNUSED)font_sr; (UNUSED)font_sr;
u32 pixel_white = 0xFFFFFFFF; u32 pixel_white = 0xFFFFFFFF;
{ G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white);
struct snc_counter counter = ZI;
G.solid_white_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(1, 1), &pixel_white, &counter);
snc_counter_wait(&counter);
}
return (struct draw_startup_receipt) { 0 }; return (struct draw_startup_receipt) { 0 };
} }

View File

@ -110,12 +110,7 @@ INTERNAL SYS_JOB_DEF(font_load_asset_job, job)
resource_close(&res); resource_close(&res);
/* Send texture to GPU */ /* Send texture to GPU */
struct gp_resource *texture = 0; struct gp_resource *texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_data.width, result.image_data.height), result.image_data.pixels);
{
struct snc_counter counter = ZI;
texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(result.image_data.width, result.image_data.height), result.image_data.pixels, &counter);
snc_counter_wait(&counter);
}
/* Allocate store memory */ /* Allocate store memory */
struct font *font = 0; struct font *font = 0;

View File

@ -39,7 +39,7 @@ enum gp_texture_flag {
GP_TEXTURE_FLAG_TARGETABLE = (1 << 0) GP_TEXTURE_FLAG_TARGETABLE = (1 << 0)
}; };
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data, struct snc_counter *counter); struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data);
struct v2i32 gp_texture_get_size(struct gp_resource *texture); struct v2i32 gp_texture_get_size(struct gp_resource *texture);

View File

@ -2230,7 +2230,7 @@ INTERNAL SYS_JOB_DEF(dx12_wait_fence_job, job)
* Texture * Texture
* ========================== */ * ========================== */
struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data, struct snc_counter *counter) struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, struct v2i32 size, void *initial_data)
{ {
__prof; __prof;
struct dxgi_format_info { DXGI_FORMAT format; u32 size; }; struct dxgi_format_info { DXGI_FORMAT format; u32 size; };
@ -2373,11 +2373,14 @@ struct gp_resource *gp_texture_alloc(enum gp_texture_format format, u32 flags, s
u64 fence_target = command_list_close(cl); u64 fence_target = command_list_close(cl);
/* Submit wait job */ /* Submit wait job */
if (counter && ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) { /* TODO: Make wait optional */
if (ID3D12Fence_GetCompletedValue(cq->submit_fence) < fence_target) {
struct dx12_wait_fence_job_sig sig = ZI; struct dx12_wait_fence_job_sig sig = ZI;
sig.fence = cq->submit_fence; sig.fence = cq->submit_fence;
sig.target = fence_target; sig.target = fence_target;
sys_run(1, dx12_wait_fence_job, &sig, SYS_POOL_FLOATING, SYS_PRIORITY_LOW, counter); struct snc_counter counter = ZI;
sys_run(1, dx12_wait_fence_job, &sig, SYS_POOL_FLOATING, SYS_PRIORITY_LOW, &counter);
snc_counter_wait(&counter);
} }
} }

View File

@ -7,10 +7,12 @@
#if PROFILING #if PROFILING
#define PROFILING_SYSTEM_TRACE 1 #define PROFILING_SYSTEM_TRACE 0
#define PROFILING_CAPTURE_FRAME_IMAGE 0 #define PROFILING_CAPTURE_FRAME_IMAGE 0
#define PROFILING_LOCKS 0 #define PROFILING_LOCKS 0
#define PROFILING_D3D 1 #define PROFILING_D3D 1
#define PROFILER_THREAD_AFFINITY_MASK 0
#define PROFILER_THREAD_PREFIX_WSTR L"Tracy"
#define PROFILING_FILE_WSTR L".tracy" #define PROFILING_FILE_WSTR L".tracy"
#define PROFILING_CMD_WSTR L"cmd /C start \"\" /wait tracy-capture.exe -o .tracy -a 127.0.0.1 && start \"\" tracy-profiler.exe .tracy" #define PROFILING_CMD_WSTR L"cmd /C start \"\" /wait tracy-capture.exe -o .tracy -a 127.0.0.1 && start \"\" tracy-profiler.exe .tracy"
//#define PROFILING_CMD_WSTR L"tracy-profiler.exe -a 127.0.0.1" //#define PROFILING_CMD_WSTR L"tracy-profiler.exe -a 127.0.0.1"

View File

@ -221,11 +221,7 @@ struct sprite_startup_receipt sprite_startup(void)
{ {
struct arena_temp scratch = scratch_begin_no_conflict(); struct arena_temp scratch = scratch_begin_no_conflict();
struct image_rgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64); struct image_rgba purple_black_image = generate_purple_black_image(scratch.arena, 64, 64);
{ G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(purple_black_image.width, purple_black_image.height), purple_black_image.pixels);
struct snc_counter counter = ZI;
G.nil_texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, 0, V2I32(purple_black_image.width, purple_black_image.height), purple_black_image.pixels, &counter);
snc_counter_wait(&counter);
}
scratch_end(scratch); scratch_end(scratch);
} }
@ -372,11 +368,7 @@ INTERNAL void cache_entry_load_texture(struct cache_ref ref, struct sprite_tag t
e->texture->height = decoded.image.height; e->texture->height = decoded.image.height;
e->texture->valid = 1; e->texture->valid = 1;
e->texture->loaded = 1; e->texture->loaded = 1;
{ e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels);
struct snc_counter counter = ZI;
e->texture->gp_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM_SRGB, 0, V2I32(decoded.image.width, decoded.image.height), decoded.image.pixels, &counter);
snc_counter_wait(&counter);
}
/* TODO: Query gpu for more accurate texture size in VRAM */ /* TODO: Query gpu for more accurate texture size in VRAM */
memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels); memory_size += (decoded.image.width * decoded.image.height) * sizeof(*decoded.image.pixels);
success = 1; success = 1;

View File

@ -19,6 +19,7 @@
# include <dwmapi.h> # include <dwmapi.h>
# include <bcrypt.h> # include <bcrypt.h>
# include <avrt.h> # include <avrt.h>
# include <TlHelp32.h>
#pragma warning(pop) #pragma warning(pop)
#pragma comment(lib, "kernel32") #pragma comment(lib, "kernel32")
@ -991,13 +992,11 @@ INTERNAL SYS_THREAD_DEF(job_worker_entry, worker_ctx_arg)
(UNUSED)success; (UNUSED)success;
} }
#if 0
if (pool->thread_affinity_mask) { if (pool->thread_affinity_mask) {
b32 success = SetThreadAffinityMask(thread_handle, pool->thread_affinity_mask) != 0; b32 success = SetThreadAffinityMask(thread_handle, pool->thread_affinity_mask) != 0;
ASSERT(success); ASSERT(success);
(UNUSED)success; (UNUSED)success;
} }
#endif
if (pool->thread_mm_characteristics) { if (pool->thread_mm_characteristics) {
/* https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service#registry-settings */ /* https://learn.microsoft.com/en-us/windows/win32/procthread/multimedia-class-scheduler-service#registry-settings */
@ -1391,14 +1390,14 @@ INTERNAL SYS_THREAD_DEF(test_entry, _)
case SYS_POOL_BACKGROUND: case SYS_POOL_BACKGROUND:
{ {
name_fmt = LIT("Background worker #%F"); name_fmt = LIT("Background worker #%F");
pool->thread_affinity_mask = 0x0000000000003000ull; pool->thread_affinity_mask = 0x0000000000000C00ull;
pool->num_worker_threads = 2; pool->num_worker_threads = 2;
} break; } break;
case SYS_POOL_FLOATING: case SYS_POOL_FLOATING:
{ {
name_fmt = LIT("Floating worker #%F"); name_fmt = LIT("Floating worker #%F");
pool->thread_affinity_mask = 0xFFFFFFFFFFFFFFFFull; pool->thread_affinity_mask = 0x0000000000000FFFull;
pool->thread_priority = 0; pool->thread_priority = 0;
pool->num_worker_threads = 8; pool->num_worker_threads = 8;
} break; } break;
@ -3185,8 +3184,11 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
(UNUSED)cmdline_wstr; (UNUSED)cmdline_wstr;
(UNUSED)show_code; (UNUSED)show_code;
__profthread("Main thread", PROF_THREAD_GROUP_MAIN);
#if PROFILING #if PROFILING
/* Start profiler */
{ {
__profn("Launch profiler"); __profn("Launch profiler");
STARTUPINFO si = ZI; STARTUPINFO si = ZI;
@ -3200,10 +3202,44 @@ int CALLBACK wWinMain(_In_ HINSTANCE instance, _In_opt_ HINSTANCE prev_instance,
MessageBoxExW(0, L"Failed to launch profiler using command '" PROFILING_CMD_WSTR L"'.", L"Error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0); MessageBoxExW(0, L"Failed to launch profiler using command '" PROFILING_CMD_WSTR L"'.", L"Error", MB_ICONSTOP | MB_SETFOREGROUND | MB_TOPMOST, 0);
} }
} }
/* Set internal profiler thread affinities */
{
__profn("Set profiler thread affinities");
wchar_t *prefix_name_wstr = PROFILER_THREAD_PREFIX_WSTR;
u64 prefix_name_wstr_len = ((i32)sizeof(PROFILER_THREAD_PREFIX_WSTR) >> 1) - 1;
if (prefix_name_wstr_len > 0 && PROFILER_THREAD_AFFINITY_MASK != 0) {
DWORD proc_id = GetCurrentProcessId();
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (snapshot != INVALID_HANDLE_VALUE) {
THREADENTRY32 te = ZI;
te.dwSize = sizeof(THREADENTRY32);
if (Thread32First(snapshot, &te)) {
do {
if (te.th32OwnerProcessID == proc_id) {
i32 thread_id = te.th32ThreadID;
HANDLE thread = OpenThread(THREAD_ALL_ACCESS, FALSE, thread_id);
if (thread) {
wchar_t *thread_name_wstr = 0;
HRESULT hr = GetThreadDescription(thread, &thread_name_wstr);
if (SUCCEEDED(hr)) {
u64 thread_name_len = wstr_len_no_limit(thread_name_wstr);
if (thread_name_len >= prefix_name_wstr_len && MEMEQ(thread_name_wstr, prefix_name_wstr, prefix_name_wstr_len)) {
b32 success = SetThreadAffinityMask(thread, PROFILER_THREAD_AFFINITY_MASK) != 0;
ASSERT(success);
(UNUSED)success;
}
}
CloseHandle(thread);
}
}
} while (Thread32Next(snapshot, &te));
}
}
CloseHandle(snapshot);
}
}
#endif #endif
__profthread("Main thread", PROF_THREAD_GROUP_MAIN);
/* ========================== * /* ========================== *
* Sys startup * Sys startup
* ========================== */ * ========================== */

View File

@ -2019,12 +2019,7 @@ INTERNAL void user_update(struct sys_window *window)
if (G.user_texture) { if (G.user_texture) {
gp_resource_release(G.user_texture); gp_resource_release(G.user_texture);
} }
{ G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, 0);
/* TODO: Don't wait here */
struct snc_counter counter = ZI;
G.user_texture = gp_texture_alloc(GP_TEXTURE_FORMAT_R8G8B8A8_UNORM, GP_TEXTURE_FLAG_TARGETABLE, user_resolution, 0, &counter);
snc_counter_wait(&counter);
}
} }
/* Render world to user texture */ /* Render world to user texture */