diff --git a/src/native/shaders/spirv/skate3_native_shaders_spirv.h b/src/native/shaders/spirv/skate3_native_shaders_spirv.h index 49cdaf7..ca352a4 100644 --- a/src/native/shaders/spirv/skate3_native_shaders_spirv.h +++ b/src/native/shaders/spirv/skate3_native_shaders_spirv.h @@ -32766,6 +32766,426 @@ static const uint32_t k_ssao_ps_debug[] = { 0x0003003e, 0x00000003, 0x0000001b, 0x000100fd, 0x00010038, }; +// ssao.hlsl : ps_depth_max (13292 bytes) +static const uint32_t k_ssao_ps_depth_max[] = { + 0x07230203, 0x00010300, 0x000e0000, 0x00000267, 0x00000000, 0x00020011, 0x00000001, 0x0006000b, + 0x00000001, 0x4c534c47, 0x6474732e, 0x3035342e, 0x00000000, 0x0003000e, 0x00000000, 0x00000001, + 0x0009000f, 0x00000004, 0x00000002, 0x645f7370, 0x68747065, 0x78616d5f, 0x00000000, 0x00000003, + 0x00000004, 0x00030010, 0x00000002, 0x00000007, 0x00030003, 0x00000005, 0x00000258, 0x00040005, + 0x00000005, 0x65707974, 0x0000432e, 0x00050006, 0x00000005, 0x00000000, 0x657a6973, 0x00000000, + 0x00050006, 0x00000005, 0x00000001, 0x6a6f7270, 0x00000000, 0x00040006, 0x00000005, 0x00000002, + 0x00003070, 0x00040006, 0x00000005, 0x00000003, 0x00003170, 0x00030005, 0x00000006, 0x00000043, + 0x00060005, 0x00000007, 0x65707974, 0x2e64322e, 0x67616d69, 0x00000065, 0x00040005, 0x00000008, + 0x30786574, 0x00000000, 0x00060005, 0x00000009, 0x65707974, 0x6d61732e, 0x72656c70, 0x00000000, + 0x00050005, 0x0000000a, 0x5f706d73, 0x6e696f70, 0x00000074, 0x00070005, 0x00000003, 0x762e6e69, + 0x542e7261, 0x4f435845, 0x3044524f, 0x00000000, 0x00070005, 0x00000004, 0x2e74756f, 0x2e726176, + 0x545f5653, 0x65677261, 0x00000074, 0x00060005, 0x00000002, 0x645f7370, 0x68747065, 0x78616d5f, + 0x00000000, 0x00070005, 0x0000000b, 0x65707974, 0x6d61732e, 0x64656c70, 0x616d692e, 0x00006567, + 0x00040047, 0x00000003, 0x0000001e, 0x00000000, 0x00040047, 0x00000004, 0x0000001e, 0x00000000, + 0x00040047, 0x00000006, 0x00000022, 0x00000000, 0x00040047, 0x00000006, 0x00000021, 0x00000000, + 0x00040047, 0x00000008, 0x00000022, 0x00000001, 0x00040047, 0x00000008, 0x00000021, 0x00000000, + 0x00040047, 0x0000000a, 0x00000022, 0x00000000, 0x00040047, 0x0000000a, 0x00000021, 0x00000001, + 0x00050048, 0x00000005, 0x00000000, 0x00000023, 0x00000000, 0x00050048, 0x00000005, 0x00000001, + 0x00000023, 0x00000010, 0x00050048, 0x00000005, 0x00000002, 0x00000023, 0x00000020, 0x00050048, + 0x00000005, 0x00000003, 0x00000023, 0x00000030, 0x00030047, 0x00000005, 0x00000002, 0x00030016, + 0x0000000c, 0x00000020, 0x00040017, 0x0000000d, 0x0000000c, 0x00000002, 0x00040015, 0x0000000e, + 0x00000020, 0x00000001, 0x0004002b, 0x0000000e, 0x0000000f, 0x00000000, 0x0004002b, 0x0000000c, + 0x00000010, 0x00000000, 0x00040017, 0x00000011, 0x0000000c, 0x00000004, 0x0006001e, 0x00000005, + 0x00000011, 0x00000011, 0x00000011, 0x00000011, 0x00040020, 0x00000012, 0x00000002, 0x00000005, + 0x00090019, 0x00000007, 0x0000000c, 0x00000001, 0x00000002, 0x00000000, 0x00000000, 0x00000001, + 0x00000000, 0x00040020, 0x00000013, 0x00000000, 0x00000007, 0x0002001a, 0x00000009, 0x00040020, + 0x00000014, 0x00000000, 0x00000009, 0x00040020, 0x00000015, 0x00000001, 0x0000000d, 0x00040020, + 0x00000016, 0x00000003, 0x0000000c, 0x00020013, 0x00000017, 0x00030021, 0x00000018, 0x00000017, + 0x00040020, 0x00000019, 0x00000002, 0x00000011, 0x0003001b, 0x0000000b, 0x00000007, 0x0004003b, + 0x00000012, 0x00000006, 0x00000002, 0x0004003b, 0x00000013, 0x00000008, 0x00000000, 0x0004003b, + 0x00000014, 0x0000000a, 0x00000000, 0x0004003b, 0x00000015, 0x00000003, 0x00000001, 0x0004003b, + 0x00000016, 0x00000004, 0x00000003, 0x0004002b, 0x0000000c, 0x0000001a, 0x3d800000, 0x0005002c, + 0x0000000d, 0x0000001b, 0x0000001a, 0x0000001a, 0x0004002b, 0x0000000c, 0x0000001c, 0xbee00000, + 0x0005002c, 0x0000000d, 0x0000001d, 0x0000001c, 0x0000001c, 0x0004002b, 0x0000000c, 0x0000001e, + 0x3e400000, 0x0005002c, 0x0000000d, 0x0000001f, 0x0000001e, 0x0000001a, 0x0004002b, 0x0000000c, + 0x00000020, 0xbea00000, 0x0005002c, 0x0000000d, 0x00000021, 0x00000020, 0x0000001c, 0x0004002b, + 0x0000000c, 0x00000022, 0x3ea00000, 0x0005002c, 0x0000000d, 0x00000023, 0x00000022, 0x0000001a, + 0x0004002b, 0x0000000c, 0x00000024, 0xbe400000, 0x0005002c, 0x0000000d, 0x00000025, 0x00000024, + 0x0000001c, 0x0004002b, 0x0000000c, 0x00000026, 0x3ee00000, 0x0005002c, 0x0000000d, 0x00000027, + 0x00000026, 0x0000001a, 0x0004002b, 0x0000000c, 0x00000028, 0xbd800000, 0x0005002c, 0x0000000d, + 0x00000029, 0x00000028, 0x0000001c, 0x0005002c, 0x0000000d, 0x0000002a, 0x0000001a, 0x0000001c, + 0x0005002c, 0x0000000d, 0x0000002b, 0x0000001e, 0x0000001c, 0x0005002c, 0x0000000d, 0x0000002c, + 0x00000022, 0x0000001c, 0x0005002c, 0x0000000d, 0x0000002d, 0x00000026, 0x0000001c, 0x0005002c, + 0x0000000d, 0x0000002e, 0x0000001a, 0x0000001e, 0x0005002c, 0x0000000d, 0x0000002f, 0x0000001c, + 0x00000020, 0x0005002c, 0x0000000d, 0x00000030, 0x0000001e, 0x0000001e, 0x0005002c, 0x0000000d, + 0x00000031, 0x00000020, 0x00000020, 0x0005002c, 0x0000000d, 0x00000032, 0x00000022, 0x0000001e, + 0x0005002c, 0x0000000d, 0x00000033, 0x00000024, 0x00000020, 0x0005002c, 0x0000000d, 0x00000034, + 0x00000026, 0x0000001e, 0x0005002c, 0x0000000d, 0x00000035, 0x00000028, 0x00000020, 0x0005002c, + 0x0000000d, 0x00000036, 0x0000001a, 0x00000020, 0x0005002c, 0x0000000d, 0x00000037, 0x0000001e, + 0x00000020, 0x0005002c, 0x0000000d, 0x00000038, 0x00000022, 0x00000020, 0x0005002c, 0x0000000d, + 0x00000039, 0x00000026, 0x00000020, 0x0005002c, 0x0000000d, 0x0000003a, 0x0000001a, 0x00000022, + 0x0005002c, 0x0000000d, 0x0000003b, 0x0000001c, 0x00000024, 0x0005002c, 0x0000000d, 0x0000003c, + 0x0000001e, 0x00000022, 0x0005002c, 0x0000000d, 0x0000003d, 0x00000020, 0x00000024, 0x0005002c, + 0x0000000d, 0x0000003e, 0x00000022, 0x00000022, 0x0005002c, 0x0000000d, 0x0000003f, 0x00000024, + 0x00000024, 0x0005002c, 0x0000000d, 0x00000040, 0x00000026, 0x00000022, 0x0005002c, 0x0000000d, + 0x00000041, 0x00000028, 0x00000024, 0x0005002c, 0x0000000d, 0x00000042, 0x0000001a, 0x00000024, + 0x0005002c, 0x0000000d, 0x00000043, 0x0000001e, 0x00000024, 0x0005002c, 0x0000000d, 0x00000044, + 0x00000022, 0x00000024, 0x0005002c, 0x0000000d, 0x00000045, 0x00000026, 0x00000024, 0x0005002c, + 0x0000000d, 0x00000046, 0x0000001a, 0x00000026, 0x0005002c, 0x0000000d, 0x00000047, 0x0000001c, + 0x00000028, 0x0005002c, 0x0000000d, 0x00000048, 0x0000001e, 0x00000026, 0x0005002c, 0x0000000d, + 0x00000049, 0x00000020, 0x00000028, 0x0005002c, 0x0000000d, 0x0000004a, 0x00000022, 0x00000026, + 0x0005002c, 0x0000000d, 0x0000004b, 0x00000024, 0x00000028, 0x0005002c, 0x0000000d, 0x0000004c, + 0x00000026, 0x00000026, 0x0005002c, 0x0000000d, 0x0000004d, 0x00000028, 0x00000028, 0x0005002c, + 0x0000000d, 0x0000004e, 0x0000001a, 0x00000028, 0x0005002c, 0x0000000d, 0x0000004f, 0x0000001e, + 0x00000028, 0x0005002c, 0x0000000d, 0x00000050, 0x00000022, 0x00000028, 0x0005002c, 0x0000000d, + 0x00000051, 0x00000026, 0x00000028, 0x0005002c, 0x0000000d, 0x00000052, 0x0000001c, 0x0000001a, + 0x0005002c, 0x0000000d, 0x00000053, 0x00000020, 0x0000001a, 0x0005002c, 0x0000000d, 0x00000054, + 0x00000024, 0x0000001a, 0x0005002c, 0x0000000d, 0x00000055, 0x00000028, 0x0000001a, 0x0005002c, + 0x0000000d, 0x00000056, 0x0000001c, 0x0000001e, 0x0005002c, 0x0000000d, 0x00000057, 0x00000020, + 0x0000001e, 0x0005002c, 0x0000000d, 0x00000058, 0x00000024, 0x0000001e, 0x0005002c, 0x0000000d, + 0x00000059, 0x00000028, 0x0000001e, 0x0005002c, 0x0000000d, 0x0000005a, 0x0000001c, 0x00000022, + 0x0005002c, 0x0000000d, 0x0000005b, 0x00000020, 0x00000022, 0x0005002c, 0x0000000d, 0x0000005c, + 0x00000024, 0x00000022, 0x0005002c, 0x0000000d, 0x0000005d, 0x00000028, 0x00000022, 0x0005002c, + 0x0000000d, 0x0000005e, 0x0000001c, 0x00000026, 0x0005002c, 0x0000000d, 0x0000005f, 0x00000020, + 0x00000026, 0x0005002c, 0x0000000d, 0x00000060, 0x00000024, 0x00000026, 0x0005002c, 0x0000000d, + 0x00000061, 0x00000028, 0x00000026, 0x00050036, 0x00000017, 0x00000002, 0x00000000, 0x00000018, + 0x000200f8, 0x00000062, 0x0004003d, 0x0000000d, 0x00000063, 0x00000003, 0x00050041, 0x00000019, + 0x00000064, 0x00000006, 0x0000000f, 0x0004003d, 0x00000011, 0x00000065, 0x00000064, 0x0007004f, + 0x0000000d, 0x00000066, 0x00000065, 0x00000065, 0x00000002, 0x00000003, 0x00050088, 0x0000000d, + 0x00000067, 0x0000001d, 0x00000066, 0x00050081, 0x0000000d, 0x00000068, 0x00000063, 0x00000067, + 0x0004003d, 0x00000007, 0x00000069, 0x00000008, 0x0004003d, 0x00000009, 0x0000006a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000006b, 0x00000069, 0x0000006a, 0x00070058, 0x00000011, 0x0000006c, + 0x0000006b, 0x00000068, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000006d, 0x0000006c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000006e, 0x00000001, 0x00000050, 0x00000010, 0x0000006d, + 0x00050088, 0x0000000d, 0x0000006f, 0x00000021, 0x00000066, 0x00050081, 0x0000000d, 0x00000070, + 0x00000063, 0x0000006f, 0x0004003d, 0x00000007, 0x00000071, 0x00000008, 0x0004003d, 0x00000009, + 0x00000072, 0x0000000a, 0x00050056, 0x0000000b, 0x00000073, 0x00000071, 0x00000072, 0x00070058, + 0x00000011, 0x00000074, 0x00000073, 0x00000070, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000075, 0x00000074, 0x00000000, 0x0007000c, 0x0000000c, 0x00000076, 0x00000001, 0x00000050, + 0x0000006e, 0x00000075, 0x00050088, 0x0000000d, 0x00000077, 0x00000025, 0x00000066, 0x00050081, + 0x0000000d, 0x00000078, 0x00000063, 0x00000077, 0x0004003d, 0x00000007, 0x00000079, 0x00000008, + 0x0004003d, 0x00000009, 0x0000007a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000007b, 0x00000079, + 0x0000007a, 0x00070058, 0x00000011, 0x0000007c, 0x0000007b, 0x00000078, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000007d, 0x0000007c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000007e, + 0x00000001, 0x00000050, 0x00000076, 0x0000007d, 0x00050088, 0x0000000d, 0x0000007f, 0x00000029, + 0x00000066, 0x00050081, 0x0000000d, 0x00000080, 0x00000063, 0x0000007f, 0x0004003d, 0x00000007, + 0x00000081, 0x00000008, 0x0004003d, 0x00000009, 0x00000082, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000083, 0x00000081, 0x00000082, 0x00070058, 0x00000011, 0x00000084, 0x00000083, 0x00000080, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000085, 0x00000084, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000086, 0x00000001, 0x00000050, 0x0000007e, 0x00000085, 0x00050088, 0x0000000d, + 0x00000087, 0x0000002a, 0x00000066, 0x00050081, 0x0000000d, 0x00000088, 0x00000063, 0x00000087, + 0x0004003d, 0x00000007, 0x00000089, 0x00000008, 0x0004003d, 0x00000009, 0x0000008a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000008b, 0x00000089, 0x0000008a, 0x00070058, 0x00000011, 0x0000008c, + 0x0000008b, 0x00000088, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000008d, 0x0000008c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000008e, 0x00000001, 0x00000050, 0x00000086, 0x0000008d, + 0x00050088, 0x0000000d, 0x0000008f, 0x0000002b, 0x00000066, 0x00050081, 0x0000000d, 0x00000090, + 0x00000063, 0x0000008f, 0x0004003d, 0x00000007, 0x00000091, 0x00000008, 0x0004003d, 0x00000009, + 0x00000092, 0x0000000a, 0x00050056, 0x0000000b, 0x00000093, 0x00000091, 0x00000092, 0x00070058, + 0x00000011, 0x00000094, 0x00000093, 0x00000090, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000095, 0x00000094, 0x00000000, 0x0007000c, 0x0000000c, 0x00000096, 0x00000001, 0x00000050, + 0x0000008e, 0x00000095, 0x00050088, 0x0000000d, 0x00000097, 0x0000002c, 0x00000066, 0x00050081, + 0x0000000d, 0x00000098, 0x00000063, 0x00000097, 0x0004003d, 0x00000007, 0x00000099, 0x00000008, + 0x0004003d, 0x00000009, 0x0000009a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000009b, 0x00000099, + 0x0000009a, 0x00070058, 0x00000011, 0x0000009c, 0x0000009b, 0x00000098, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000009d, 0x0000009c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000009e, + 0x00000001, 0x00000050, 0x00000096, 0x0000009d, 0x00050088, 0x0000000d, 0x0000009f, 0x0000002d, + 0x00000066, 0x00050081, 0x0000000d, 0x000000a0, 0x00000063, 0x0000009f, 0x0004003d, 0x00000007, + 0x000000a1, 0x00000008, 0x0004003d, 0x00000009, 0x000000a2, 0x0000000a, 0x00050056, 0x0000000b, + 0x000000a3, 0x000000a1, 0x000000a2, 0x00070058, 0x00000011, 0x000000a4, 0x000000a3, 0x000000a0, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000000a5, 0x000000a4, 0x00000000, 0x0007000c, + 0x0000000c, 0x000000a6, 0x00000001, 0x00000050, 0x0000009e, 0x000000a5, 0x00050088, 0x0000000d, + 0x000000a7, 0x0000002f, 0x00000066, 0x00050081, 0x0000000d, 0x000000a8, 0x00000063, 0x000000a7, + 0x0004003d, 0x00000007, 0x000000a9, 0x00000008, 0x0004003d, 0x00000009, 0x000000aa, 0x0000000a, + 0x00050056, 0x0000000b, 0x000000ab, 0x000000a9, 0x000000aa, 0x00070058, 0x00000011, 0x000000ac, + 0x000000ab, 0x000000a8, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000000ad, 0x000000ac, + 0x00000000, 0x0007000c, 0x0000000c, 0x000000ae, 0x00000001, 0x00000050, 0x000000a6, 0x000000ad, + 0x00050088, 0x0000000d, 0x000000af, 0x00000031, 0x00000066, 0x00050081, 0x0000000d, 0x000000b0, + 0x00000063, 0x000000af, 0x0004003d, 0x00000007, 0x000000b1, 0x00000008, 0x0004003d, 0x00000009, + 0x000000b2, 0x0000000a, 0x00050056, 0x0000000b, 0x000000b3, 0x000000b1, 0x000000b2, 0x00070058, + 0x00000011, 0x000000b4, 0x000000b3, 0x000000b0, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x000000b5, 0x000000b4, 0x00000000, 0x0007000c, 0x0000000c, 0x000000b6, 0x00000001, 0x00000050, + 0x000000ae, 0x000000b5, 0x00050088, 0x0000000d, 0x000000b7, 0x00000033, 0x00000066, 0x00050081, + 0x0000000d, 0x000000b8, 0x00000063, 0x000000b7, 0x0004003d, 0x00000007, 0x000000b9, 0x00000008, + 0x0004003d, 0x00000009, 0x000000ba, 0x0000000a, 0x00050056, 0x0000000b, 0x000000bb, 0x000000b9, + 0x000000ba, 0x00070058, 0x00000011, 0x000000bc, 0x000000bb, 0x000000b8, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x000000bd, 0x000000bc, 0x00000000, 0x0007000c, 0x0000000c, 0x000000be, + 0x00000001, 0x00000050, 0x000000b6, 0x000000bd, 0x00050088, 0x0000000d, 0x000000bf, 0x00000035, + 0x00000066, 0x00050081, 0x0000000d, 0x000000c0, 0x00000063, 0x000000bf, 0x0004003d, 0x00000007, + 0x000000c1, 0x00000008, 0x0004003d, 0x00000009, 0x000000c2, 0x0000000a, 0x00050056, 0x0000000b, + 0x000000c3, 0x000000c1, 0x000000c2, 0x00070058, 0x00000011, 0x000000c4, 0x000000c3, 0x000000c0, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000000c5, 0x000000c4, 0x00000000, 0x0007000c, + 0x0000000c, 0x000000c6, 0x00000001, 0x00000050, 0x000000be, 0x000000c5, 0x00050088, 0x0000000d, + 0x000000c7, 0x00000036, 0x00000066, 0x00050081, 0x0000000d, 0x000000c8, 0x00000063, 0x000000c7, + 0x0004003d, 0x00000007, 0x000000c9, 0x00000008, 0x0004003d, 0x00000009, 0x000000ca, 0x0000000a, + 0x00050056, 0x0000000b, 0x000000cb, 0x000000c9, 0x000000ca, 0x00070058, 0x00000011, 0x000000cc, + 0x000000cb, 0x000000c8, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000000cd, 0x000000cc, + 0x00000000, 0x0007000c, 0x0000000c, 0x000000ce, 0x00000001, 0x00000050, 0x000000c6, 0x000000cd, + 0x00050088, 0x0000000d, 0x000000cf, 0x00000037, 0x00000066, 0x00050081, 0x0000000d, 0x000000d0, + 0x00000063, 0x000000cf, 0x0004003d, 0x00000007, 0x000000d1, 0x00000008, 0x0004003d, 0x00000009, + 0x000000d2, 0x0000000a, 0x00050056, 0x0000000b, 0x000000d3, 0x000000d1, 0x000000d2, 0x00070058, + 0x00000011, 0x000000d4, 0x000000d3, 0x000000d0, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x000000d5, 0x000000d4, 0x00000000, 0x0007000c, 0x0000000c, 0x000000d6, 0x00000001, 0x00000050, + 0x000000ce, 0x000000d5, 0x00050088, 0x0000000d, 0x000000d7, 0x00000038, 0x00000066, 0x00050081, + 0x0000000d, 0x000000d8, 0x00000063, 0x000000d7, 0x0004003d, 0x00000007, 0x000000d9, 0x00000008, + 0x0004003d, 0x00000009, 0x000000da, 0x0000000a, 0x00050056, 0x0000000b, 0x000000db, 0x000000d9, + 0x000000da, 0x00070058, 0x00000011, 0x000000dc, 0x000000db, 0x000000d8, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x000000dd, 0x000000dc, 0x00000000, 0x0007000c, 0x0000000c, 0x000000de, + 0x00000001, 0x00000050, 0x000000d6, 0x000000dd, 0x00050088, 0x0000000d, 0x000000df, 0x00000039, + 0x00000066, 0x00050081, 0x0000000d, 0x000000e0, 0x00000063, 0x000000df, 0x0004003d, 0x00000007, + 0x000000e1, 0x00000008, 0x0004003d, 0x00000009, 0x000000e2, 0x0000000a, 0x00050056, 0x0000000b, + 0x000000e3, 0x000000e1, 0x000000e2, 0x00070058, 0x00000011, 0x000000e4, 0x000000e3, 0x000000e0, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000000e5, 0x000000e4, 0x00000000, 0x0007000c, + 0x0000000c, 0x000000e6, 0x00000001, 0x00000050, 0x000000de, 0x000000e5, 0x00050088, 0x0000000d, + 0x000000e7, 0x0000003b, 0x00000066, 0x00050081, 0x0000000d, 0x000000e8, 0x00000063, 0x000000e7, + 0x0004003d, 0x00000007, 0x000000e9, 0x00000008, 0x0004003d, 0x00000009, 0x000000ea, 0x0000000a, + 0x00050056, 0x0000000b, 0x000000eb, 0x000000e9, 0x000000ea, 0x00070058, 0x00000011, 0x000000ec, + 0x000000eb, 0x000000e8, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000000ed, 0x000000ec, + 0x00000000, 0x0007000c, 0x0000000c, 0x000000ee, 0x00000001, 0x00000050, 0x000000e6, 0x000000ed, + 0x00050088, 0x0000000d, 0x000000ef, 0x0000003d, 0x00000066, 0x00050081, 0x0000000d, 0x000000f0, + 0x00000063, 0x000000ef, 0x0004003d, 0x00000007, 0x000000f1, 0x00000008, 0x0004003d, 0x00000009, + 0x000000f2, 0x0000000a, 0x00050056, 0x0000000b, 0x000000f3, 0x000000f1, 0x000000f2, 0x00070058, + 0x00000011, 0x000000f4, 0x000000f3, 0x000000f0, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x000000f5, 0x000000f4, 0x00000000, 0x0007000c, 0x0000000c, 0x000000f6, 0x00000001, 0x00000050, + 0x000000ee, 0x000000f5, 0x00050088, 0x0000000d, 0x000000f7, 0x0000003f, 0x00000066, 0x00050081, + 0x0000000d, 0x000000f8, 0x00000063, 0x000000f7, 0x0004003d, 0x00000007, 0x000000f9, 0x00000008, + 0x0004003d, 0x00000009, 0x000000fa, 0x0000000a, 0x00050056, 0x0000000b, 0x000000fb, 0x000000f9, + 0x000000fa, 0x00070058, 0x00000011, 0x000000fc, 0x000000fb, 0x000000f8, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x000000fd, 0x000000fc, 0x00000000, 0x0007000c, 0x0000000c, 0x000000fe, + 0x00000001, 0x00000050, 0x000000f6, 0x000000fd, 0x00050088, 0x0000000d, 0x000000ff, 0x00000041, + 0x00000066, 0x00050081, 0x0000000d, 0x00000100, 0x00000063, 0x000000ff, 0x0004003d, 0x00000007, + 0x00000101, 0x00000008, 0x0004003d, 0x00000009, 0x00000102, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000103, 0x00000101, 0x00000102, 0x00070058, 0x00000011, 0x00000104, 0x00000103, 0x00000100, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000105, 0x00000104, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000106, 0x00000001, 0x00000050, 0x000000fe, 0x00000105, 0x00050088, 0x0000000d, + 0x00000107, 0x00000042, 0x00000066, 0x00050081, 0x0000000d, 0x00000108, 0x00000063, 0x00000107, + 0x0004003d, 0x00000007, 0x00000109, 0x00000008, 0x0004003d, 0x00000009, 0x0000010a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000010b, 0x00000109, 0x0000010a, 0x00070058, 0x00000011, 0x0000010c, + 0x0000010b, 0x00000108, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000010d, 0x0000010c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000010e, 0x00000001, 0x00000050, 0x00000106, 0x0000010d, + 0x00050088, 0x0000000d, 0x0000010f, 0x00000043, 0x00000066, 0x00050081, 0x0000000d, 0x00000110, + 0x00000063, 0x0000010f, 0x0004003d, 0x00000007, 0x00000111, 0x00000008, 0x0004003d, 0x00000009, + 0x00000112, 0x0000000a, 0x00050056, 0x0000000b, 0x00000113, 0x00000111, 0x00000112, 0x00070058, + 0x00000011, 0x00000114, 0x00000113, 0x00000110, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000115, 0x00000114, 0x00000000, 0x0007000c, 0x0000000c, 0x00000116, 0x00000001, 0x00000050, + 0x0000010e, 0x00000115, 0x00050088, 0x0000000d, 0x00000117, 0x00000044, 0x00000066, 0x00050081, + 0x0000000d, 0x00000118, 0x00000063, 0x00000117, 0x0004003d, 0x00000007, 0x00000119, 0x00000008, + 0x0004003d, 0x00000009, 0x0000011a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000011b, 0x00000119, + 0x0000011a, 0x00070058, 0x00000011, 0x0000011c, 0x0000011b, 0x00000118, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000011d, 0x0000011c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000011e, + 0x00000001, 0x00000050, 0x00000116, 0x0000011d, 0x00050088, 0x0000000d, 0x0000011f, 0x00000045, + 0x00000066, 0x00050081, 0x0000000d, 0x00000120, 0x00000063, 0x0000011f, 0x0004003d, 0x00000007, + 0x00000121, 0x00000008, 0x0004003d, 0x00000009, 0x00000122, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000123, 0x00000121, 0x00000122, 0x00070058, 0x00000011, 0x00000124, 0x00000123, 0x00000120, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000125, 0x00000124, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000126, 0x00000001, 0x00000050, 0x0000011e, 0x00000125, 0x00050088, 0x0000000d, + 0x00000127, 0x00000047, 0x00000066, 0x00050081, 0x0000000d, 0x00000128, 0x00000063, 0x00000127, + 0x0004003d, 0x00000007, 0x00000129, 0x00000008, 0x0004003d, 0x00000009, 0x0000012a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000012b, 0x00000129, 0x0000012a, 0x00070058, 0x00000011, 0x0000012c, + 0x0000012b, 0x00000128, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000012d, 0x0000012c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000012e, 0x00000001, 0x00000050, 0x00000126, 0x0000012d, + 0x00050088, 0x0000000d, 0x0000012f, 0x00000049, 0x00000066, 0x00050081, 0x0000000d, 0x00000130, + 0x00000063, 0x0000012f, 0x0004003d, 0x00000007, 0x00000131, 0x00000008, 0x0004003d, 0x00000009, + 0x00000132, 0x0000000a, 0x00050056, 0x0000000b, 0x00000133, 0x00000131, 0x00000132, 0x00070058, + 0x00000011, 0x00000134, 0x00000133, 0x00000130, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000135, 0x00000134, 0x00000000, 0x0007000c, 0x0000000c, 0x00000136, 0x00000001, 0x00000050, + 0x0000012e, 0x00000135, 0x00050088, 0x0000000d, 0x00000137, 0x0000004b, 0x00000066, 0x00050081, + 0x0000000d, 0x00000138, 0x00000063, 0x00000137, 0x0004003d, 0x00000007, 0x00000139, 0x00000008, + 0x0004003d, 0x00000009, 0x0000013a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000013b, 0x00000139, + 0x0000013a, 0x00070058, 0x00000011, 0x0000013c, 0x0000013b, 0x00000138, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000013d, 0x0000013c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000013e, + 0x00000001, 0x00000050, 0x00000136, 0x0000013d, 0x00050088, 0x0000000d, 0x0000013f, 0x0000004d, + 0x00000066, 0x00050081, 0x0000000d, 0x00000140, 0x00000063, 0x0000013f, 0x0004003d, 0x00000007, + 0x00000141, 0x00000008, 0x0004003d, 0x00000009, 0x00000142, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000143, 0x00000141, 0x00000142, 0x00070058, 0x00000011, 0x00000144, 0x00000143, 0x00000140, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000145, 0x00000144, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000146, 0x00000001, 0x00000050, 0x0000013e, 0x00000145, 0x00050088, 0x0000000d, + 0x00000147, 0x0000004e, 0x00000066, 0x00050081, 0x0000000d, 0x00000148, 0x00000063, 0x00000147, + 0x0004003d, 0x00000007, 0x00000149, 0x00000008, 0x0004003d, 0x00000009, 0x0000014a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000014b, 0x00000149, 0x0000014a, 0x00070058, 0x00000011, 0x0000014c, + 0x0000014b, 0x00000148, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000014d, 0x0000014c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000014e, 0x00000001, 0x00000050, 0x00000146, 0x0000014d, + 0x00050088, 0x0000000d, 0x0000014f, 0x0000004f, 0x00000066, 0x00050081, 0x0000000d, 0x00000150, + 0x00000063, 0x0000014f, 0x0004003d, 0x00000007, 0x00000151, 0x00000008, 0x0004003d, 0x00000009, + 0x00000152, 0x0000000a, 0x00050056, 0x0000000b, 0x00000153, 0x00000151, 0x00000152, 0x00070058, + 0x00000011, 0x00000154, 0x00000153, 0x00000150, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000155, 0x00000154, 0x00000000, 0x0007000c, 0x0000000c, 0x00000156, 0x00000001, 0x00000050, + 0x0000014e, 0x00000155, 0x00050088, 0x0000000d, 0x00000157, 0x00000050, 0x00000066, 0x00050081, + 0x0000000d, 0x00000158, 0x00000063, 0x00000157, 0x0004003d, 0x00000007, 0x00000159, 0x00000008, + 0x0004003d, 0x00000009, 0x0000015a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000015b, 0x00000159, + 0x0000015a, 0x00070058, 0x00000011, 0x0000015c, 0x0000015b, 0x00000158, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000015d, 0x0000015c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000015e, + 0x00000001, 0x00000050, 0x00000156, 0x0000015d, 0x00050088, 0x0000000d, 0x0000015f, 0x00000051, + 0x00000066, 0x00050081, 0x0000000d, 0x00000160, 0x00000063, 0x0000015f, 0x0004003d, 0x00000007, + 0x00000161, 0x00000008, 0x0004003d, 0x00000009, 0x00000162, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000163, 0x00000161, 0x00000162, 0x00070058, 0x00000011, 0x00000164, 0x00000163, 0x00000160, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000165, 0x00000164, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000166, 0x00000001, 0x00000050, 0x0000015e, 0x00000165, 0x00050088, 0x0000000d, + 0x00000167, 0x00000052, 0x00000066, 0x00050081, 0x0000000d, 0x00000168, 0x00000063, 0x00000167, + 0x0004003d, 0x00000007, 0x00000169, 0x00000008, 0x0004003d, 0x00000009, 0x0000016a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000016b, 0x00000169, 0x0000016a, 0x00070058, 0x00000011, 0x0000016c, + 0x0000016b, 0x00000168, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000016d, 0x0000016c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000016e, 0x00000001, 0x00000050, 0x00000166, 0x0000016d, + 0x00050088, 0x0000000d, 0x0000016f, 0x00000053, 0x00000066, 0x00050081, 0x0000000d, 0x00000170, + 0x00000063, 0x0000016f, 0x0004003d, 0x00000007, 0x00000171, 0x00000008, 0x0004003d, 0x00000009, + 0x00000172, 0x0000000a, 0x00050056, 0x0000000b, 0x00000173, 0x00000171, 0x00000172, 0x00070058, + 0x00000011, 0x00000174, 0x00000173, 0x00000170, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000175, 0x00000174, 0x00000000, 0x0007000c, 0x0000000c, 0x00000176, 0x00000001, 0x00000050, + 0x0000016e, 0x00000175, 0x00050088, 0x0000000d, 0x00000177, 0x00000054, 0x00000066, 0x00050081, + 0x0000000d, 0x00000178, 0x00000063, 0x00000177, 0x0004003d, 0x00000007, 0x00000179, 0x00000008, + 0x0004003d, 0x00000009, 0x0000017a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000017b, 0x00000179, + 0x0000017a, 0x00070058, 0x00000011, 0x0000017c, 0x0000017b, 0x00000178, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000017d, 0x0000017c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000017e, + 0x00000001, 0x00000050, 0x00000176, 0x0000017d, 0x00050088, 0x0000000d, 0x0000017f, 0x00000055, + 0x00000066, 0x00050081, 0x0000000d, 0x00000180, 0x00000063, 0x0000017f, 0x0004003d, 0x00000007, + 0x00000181, 0x00000008, 0x0004003d, 0x00000009, 0x00000182, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000183, 0x00000181, 0x00000182, 0x00070058, 0x00000011, 0x00000184, 0x00000183, 0x00000180, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000185, 0x00000184, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000186, 0x00000001, 0x00000050, 0x0000017e, 0x00000185, 0x00050088, 0x0000000d, + 0x00000187, 0x0000001b, 0x00000066, 0x00050081, 0x0000000d, 0x00000188, 0x00000063, 0x00000187, + 0x0004003d, 0x00000007, 0x00000189, 0x00000008, 0x0004003d, 0x00000009, 0x0000018a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000018b, 0x00000189, 0x0000018a, 0x00070058, 0x00000011, 0x0000018c, + 0x0000018b, 0x00000188, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000018d, 0x0000018c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000018e, 0x00000001, 0x00000050, 0x00000186, 0x0000018d, + 0x00050088, 0x0000000d, 0x0000018f, 0x0000001f, 0x00000066, 0x00050081, 0x0000000d, 0x00000190, + 0x00000063, 0x0000018f, 0x0004003d, 0x00000007, 0x00000191, 0x00000008, 0x0004003d, 0x00000009, + 0x00000192, 0x0000000a, 0x00050056, 0x0000000b, 0x00000193, 0x00000191, 0x00000192, 0x00070058, + 0x00000011, 0x00000194, 0x00000193, 0x00000190, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000195, 0x00000194, 0x00000000, 0x0007000c, 0x0000000c, 0x00000196, 0x00000001, 0x00000050, + 0x0000018e, 0x00000195, 0x00050088, 0x0000000d, 0x00000197, 0x00000023, 0x00000066, 0x00050081, + 0x0000000d, 0x00000198, 0x00000063, 0x00000197, 0x0004003d, 0x00000007, 0x00000199, 0x00000008, + 0x0004003d, 0x00000009, 0x0000019a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000019b, 0x00000199, + 0x0000019a, 0x00070058, 0x00000011, 0x0000019c, 0x0000019b, 0x00000198, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000019d, 0x0000019c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000019e, + 0x00000001, 0x00000050, 0x00000196, 0x0000019d, 0x00050088, 0x0000000d, 0x0000019f, 0x00000027, + 0x00000066, 0x00050081, 0x0000000d, 0x000001a0, 0x00000063, 0x0000019f, 0x0004003d, 0x00000007, + 0x000001a1, 0x00000008, 0x0004003d, 0x00000009, 0x000001a2, 0x0000000a, 0x00050056, 0x0000000b, + 0x000001a3, 0x000001a1, 0x000001a2, 0x00070058, 0x00000011, 0x000001a4, 0x000001a3, 0x000001a0, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000001a5, 0x000001a4, 0x00000000, 0x0007000c, + 0x0000000c, 0x000001a6, 0x00000001, 0x00000050, 0x0000019e, 0x000001a5, 0x00050088, 0x0000000d, + 0x000001a7, 0x00000056, 0x00000066, 0x00050081, 0x0000000d, 0x000001a8, 0x00000063, 0x000001a7, + 0x0004003d, 0x00000007, 0x000001a9, 0x00000008, 0x0004003d, 0x00000009, 0x000001aa, 0x0000000a, + 0x00050056, 0x0000000b, 0x000001ab, 0x000001a9, 0x000001aa, 0x00070058, 0x00000011, 0x000001ac, + 0x000001ab, 0x000001a8, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000001ad, 0x000001ac, + 0x00000000, 0x0007000c, 0x0000000c, 0x000001ae, 0x00000001, 0x00000050, 0x000001a6, 0x000001ad, + 0x00050088, 0x0000000d, 0x000001af, 0x00000057, 0x00000066, 0x00050081, 0x0000000d, 0x000001b0, + 0x00000063, 0x000001af, 0x0004003d, 0x00000007, 0x000001b1, 0x00000008, 0x0004003d, 0x00000009, + 0x000001b2, 0x0000000a, 0x00050056, 0x0000000b, 0x000001b3, 0x000001b1, 0x000001b2, 0x00070058, + 0x00000011, 0x000001b4, 0x000001b3, 0x000001b0, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x000001b5, 0x000001b4, 0x00000000, 0x0007000c, 0x0000000c, 0x000001b6, 0x00000001, 0x00000050, + 0x000001ae, 0x000001b5, 0x00050088, 0x0000000d, 0x000001b7, 0x00000058, 0x00000066, 0x00050081, + 0x0000000d, 0x000001b8, 0x00000063, 0x000001b7, 0x0004003d, 0x00000007, 0x000001b9, 0x00000008, + 0x0004003d, 0x00000009, 0x000001ba, 0x0000000a, 0x00050056, 0x0000000b, 0x000001bb, 0x000001b9, + 0x000001ba, 0x00070058, 0x00000011, 0x000001bc, 0x000001bb, 0x000001b8, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x000001bd, 0x000001bc, 0x00000000, 0x0007000c, 0x0000000c, 0x000001be, + 0x00000001, 0x00000050, 0x000001b6, 0x000001bd, 0x00050088, 0x0000000d, 0x000001bf, 0x00000059, + 0x00000066, 0x00050081, 0x0000000d, 0x000001c0, 0x00000063, 0x000001bf, 0x0004003d, 0x00000007, + 0x000001c1, 0x00000008, 0x0004003d, 0x00000009, 0x000001c2, 0x0000000a, 0x00050056, 0x0000000b, + 0x000001c3, 0x000001c1, 0x000001c2, 0x00070058, 0x00000011, 0x000001c4, 0x000001c3, 0x000001c0, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000001c5, 0x000001c4, 0x00000000, 0x0007000c, + 0x0000000c, 0x000001c6, 0x00000001, 0x00000050, 0x000001be, 0x000001c5, 0x00050088, 0x0000000d, + 0x000001c7, 0x0000002e, 0x00000066, 0x00050081, 0x0000000d, 0x000001c8, 0x00000063, 0x000001c7, + 0x0004003d, 0x00000007, 0x000001c9, 0x00000008, 0x0004003d, 0x00000009, 0x000001ca, 0x0000000a, + 0x00050056, 0x0000000b, 0x000001cb, 0x000001c9, 0x000001ca, 0x00070058, 0x00000011, 0x000001cc, + 0x000001cb, 0x000001c8, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000001cd, 0x000001cc, + 0x00000000, 0x0007000c, 0x0000000c, 0x000001ce, 0x00000001, 0x00000050, 0x000001c6, 0x000001cd, + 0x00050088, 0x0000000d, 0x000001cf, 0x00000030, 0x00000066, 0x00050081, 0x0000000d, 0x000001d0, + 0x00000063, 0x000001cf, 0x0004003d, 0x00000007, 0x000001d1, 0x00000008, 0x0004003d, 0x00000009, + 0x000001d2, 0x0000000a, 0x00050056, 0x0000000b, 0x000001d3, 0x000001d1, 0x000001d2, 0x00070058, + 0x00000011, 0x000001d4, 0x000001d3, 0x000001d0, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x000001d5, 0x000001d4, 0x00000000, 0x0007000c, 0x0000000c, 0x000001d6, 0x00000001, 0x00000050, + 0x000001ce, 0x000001d5, 0x00050088, 0x0000000d, 0x000001d7, 0x00000032, 0x00000066, 0x00050081, + 0x0000000d, 0x000001d8, 0x00000063, 0x000001d7, 0x0004003d, 0x00000007, 0x000001d9, 0x00000008, + 0x0004003d, 0x00000009, 0x000001da, 0x0000000a, 0x00050056, 0x0000000b, 0x000001db, 0x000001d9, + 0x000001da, 0x00070058, 0x00000011, 0x000001dc, 0x000001db, 0x000001d8, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x000001dd, 0x000001dc, 0x00000000, 0x0007000c, 0x0000000c, 0x000001de, + 0x00000001, 0x00000050, 0x000001d6, 0x000001dd, 0x00050088, 0x0000000d, 0x000001df, 0x00000034, + 0x00000066, 0x00050081, 0x0000000d, 0x000001e0, 0x00000063, 0x000001df, 0x0004003d, 0x00000007, + 0x000001e1, 0x00000008, 0x0004003d, 0x00000009, 0x000001e2, 0x0000000a, 0x00050056, 0x0000000b, + 0x000001e3, 0x000001e1, 0x000001e2, 0x00070058, 0x00000011, 0x000001e4, 0x000001e3, 0x000001e0, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000001e5, 0x000001e4, 0x00000000, 0x0007000c, + 0x0000000c, 0x000001e6, 0x00000001, 0x00000050, 0x000001de, 0x000001e5, 0x00050088, 0x0000000d, + 0x000001e7, 0x0000005a, 0x00000066, 0x00050081, 0x0000000d, 0x000001e8, 0x00000063, 0x000001e7, + 0x0004003d, 0x00000007, 0x000001e9, 0x00000008, 0x0004003d, 0x00000009, 0x000001ea, 0x0000000a, + 0x00050056, 0x0000000b, 0x000001eb, 0x000001e9, 0x000001ea, 0x00070058, 0x00000011, 0x000001ec, + 0x000001eb, 0x000001e8, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x000001ed, 0x000001ec, + 0x00000000, 0x0007000c, 0x0000000c, 0x000001ee, 0x00000001, 0x00000050, 0x000001e6, 0x000001ed, + 0x00050088, 0x0000000d, 0x000001ef, 0x0000005b, 0x00000066, 0x00050081, 0x0000000d, 0x000001f0, + 0x00000063, 0x000001ef, 0x0004003d, 0x00000007, 0x000001f1, 0x00000008, 0x0004003d, 0x00000009, + 0x000001f2, 0x0000000a, 0x00050056, 0x0000000b, 0x000001f3, 0x000001f1, 0x000001f2, 0x00070058, + 0x00000011, 0x000001f4, 0x000001f3, 0x000001f0, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x000001f5, 0x000001f4, 0x00000000, 0x0007000c, 0x0000000c, 0x000001f6, 0x00000001, 0x00000050, + 0x000001ee, 0x000001f5, 0x00050088, 0x0000000d, 0x000001f7, 0x0000005c, 0x00000066, 0x00050081, + 0x0000000d, 0x000001f8, 0x00000063, 0x000001f7, 0x0004003d, 0x00000007, 0x000001f9, 0x00000008, + 0x0004003d, 0x00000009, 0x000001fa, 0x0000000a, 0x00050056, 0x0000000b, 0x000001fb, 0x000001f9, + 0x000001fa, 0x00070058, 0x00000011, 0x000001fc, 0x000001fb, 0x000001f8, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x000001fd, 0x000001fc, 0x00000000, 0x0007000c, 0x0000000c, 0x000001fe, + 0x00000001, 0x00000050, 0x000001f6, 0x000001fd, 0x00050088, 0x0000000d, 0x000001ff, 0x0000005d, + 0x00000066, 0x00050081, 0x0000000d, 0x00000200, 0x00000063, 0x000001ff, 0x0004003d, 0x00000007, + 0x00000201, 0x00000008, 0x0004003d, 0x00000009, 0x00000202, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000203, 0x00000201, 0x00000202, 0x00070058, 0x00000011, 0x00000204, 0x00000203, 0x00000200, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000205, 0x00000204, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000206, 0x00000001, 0x00000050, 0x000001fe, 0x00000205, 0x00050088, 0x0000000d, + 0x00000207, 0x0000003a, 0x00000066, 0x00050081, 0x0000000d, 0x00000208, 0x00000063, 0x00000207, + 0x0004003d, 0x00000007, 0x00000209, 0x00000008, 0x0004003d, 0x00000009, 0x0000020a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000020b, 0x00000209, 0x0000020a, 0x00070058, 0x00000011, 0x0000020c, + 0x0000020b, 0x00000208, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000020d, 0x0000020c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000020e, 0x00000001, 0x00000050, 0x00000206, 0x0000020d, + 0x00050088, 0x0000000d, 0x0000020f, 0x0000003c, 0x00000066, 0x00050081, 0x0000000d, 0x00000210, + 0x00000063, 0x0000020f, 0x0004003d, 0x00000007, 0x00000211, 0x00000008, 0x0004003d, 0x00000009, + 0x00000212, 0x0000000a, 0x00050056, 0x0000000b, 0x00000213, 0x00000211, 0x00000212, 0x00070058, + 0x00000011, 0x00000214, 0x00000213, 0x00000210, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000215, 0x00000214, 0x00000000, 0x0007000c, 0x0000000c, 0x00000216, 0x00000001, 0x00000050, + 0x0000020e, 0x00000215, 0x00050088, 0x0000000d, 0x00000217, 0x0000003e, 0x00000066, 0x00050081, + 0x0000000d, 0x00000218, 0x00000063, 0x00000217, 0x0004003d, 0x00000007, 0x00000219, 0x00000008, + 0x0004003d, 0x00000009, 0x0000021a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000021b, 0x00000219, + 0x0000021a, 0x00070058, 0x00000011, 0x0000021c, 0x0000021b, 0x00000218, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000021d, 0x0000021c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000021e, + 0x00000001, 0x00000050, 0x00000216, 0x0000021d, 0x00050088, 0x0000000d, 0x0000021f, 0x00000040, + 0x00000066, 0x00050081, 0x0000000d, 0x00000220, 0x00000063, 0x0000021f, 0x0004003d, 0x00000007, + 0x00000221, 0x00000008, 0x0004003d, 0x00000009, 0x00000222, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000223, 0x00000221, 0x00000222, 0x00070058, 0x00000011, 0x00000224, 0x00000223, 0x00000220, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000225, 0x00000224, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000226, 0x00000001, 0x00000050, 0x0000021e, 0x00000225, 0x00050088, 0x0000000d, + 0x00000227, 0x0000005e, 0x00000066, 0x00050081, 0x0000000d, 0x00000228, 0x00000063, 0x00000227, + 0x0004003d, 0x00000007, 0x00000229, 0x00000008, 0x0004003d, 0x00000009, 0x0000022a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000022b, 0x00000229, 0x0000022a, 0x00070058, 0x00000011, 0x0000022c, + 0x0000022b, 0x00000228, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000022d, 0x0000022c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000022e, 0x00000001, 0x00000050, 0x00000226, 0x0000022d, + 0x00050088, 0x0000000d, 0x0000022f, 0x0000005f, 0x00000066, 0x00050081, 0x0000000d, 0x00000230, + 0x00000063, 0x0000022f, 0x0004003d, 0x00000007, 0x00000231, 0x00000008, 0x0004003d, 0x00000009, + 0x00000232, 0x0000000a, 0x00050056, 0x0000000b, 0x00000233, 0x00000231, 0x00000232, 0x00070058, + 0x00000011, 0x00000234, 0x00000233, 0x00000230, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000235, 0x00000234, 0x00000000, 0x0007000c, 0x0000000c, 0x00000236, 0x00000001, 0x00000050, + 0x0000022e, 0x00000235, 0x00050088, 0x0000000d, 0x00000237, 0x00000060, 0x00000066, 0x00050081, + 0x0000000d, 0x00000238, 0x00000063, 0x00000237, 0x0004003d, 0x00000007, 0x00000239, 0x00000008, + 0x0004003d, 0x00000009, 0x0000023a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000023b, 0x00000239, + 0x0000023a, 0x00070058, 0x00000011, 0x0000023c, 0x0000023b, 0x00000238, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000023d, 0x0000023c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000023e, + 0x00000001, 0x00000050, 0x00000236, 0x0000023d, 0x00050088, 0x0000000d, 0x0000023f, 0x00000061, + 0x00000066, 0x00050081, 0x0000000d, 0x00000240, 0x00000063, 0x0000023f, 0x0004003d, 0x00000007, + 0x00000241, 0x00000008, 0x0004003d, 0x00000009, 0x00000242, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000243, 0x00000241, 0x00000242, 0x00070058, 0x00000011, 0x00000244, 0x00000243, 0x00000240, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000245, 0x00000244, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000246, 0x00000001, 0x00000050, 0x0000023e, 0x00000245, 0x00050088, 0x0000000d, + 0x00000247, 0x00000046, 0x00000066, 0x00050081, 0x0000000d, 0x00000248, 0x00000063, 0x00000247, + 0x0004003d, 0x00000007, 0x00000249, 0x00000008, 0x0004003d, 0x00000009, 0x0000024a, 0x0000000a, + 0x00050056, 0x0000000b, 0x0000024b, 0x00000249, 0x0000024a, 0x00070058, 0x00000011, 0x0000024c, + 0x0000024b, 0x00000248, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x0000024d, 0x0000024c, + 0x00000000, 0x0007000c, 0x0000000c, 0x0000024e, 0x00000001, 0x00000050, 0x00000246, 0x0000024d, + 0x00050088, 0x0000000d, 0x0000024f, 0x00000048, 0x00000066, 0x00050081, 0x0000000d, 0x00000250, + 0x00000063, 0x0000024f, 0x0004003d, 0x00000007, 0x00000251, 0x00000008, 0x0004003d, 0x00000009, + 0x00000252, 0x0000000a, 0x00050056, 0x0000000b, 0x00000253, 0x00000251, 0x00000252, 0x00070058, + 0x00000011, 0x00000254, 0x00000253, 0x00000250, 0x00000002, 0x00000010, 0x00050051, 0x0000000c, + 0x00000255, 0x00000254, 0x00000000, 0x0007000c, 0x0000000c, 0x00000256, 0x00000001, 0x00000050, + 0x0000024e, 0x00000255, 0x00050088, 0x0000000d, 0x00000257, 0x0000004a, 0x00000066, 0x00050081, + 0x0000000d, 0x00000258, 0x00000063, 0x00000257, 0x0004003d, 0x00000007, 0x00000259, 0x00000008, + 0x0004003d, 0x00000009, 0x0000025a, 0x0000000a, 0x00050056, 0x0000000b, 0x0000025b, 0x00000259, + 0x0000025a, 0x00070058, 0x00000011, 0x0000025c, 0x0000025b, 0x00000258, 0x00000002, 0x00000010, + 0x00050051, 0x0000000c, 0x0000025d, 0x0000025c, 0x00000000, 0x0007000c, 0x0000000c, 0x0000025e, + 0x00000001, 0x00000050, 0x00000256, 0x0000025d, 0x00050088, 0x0000000d, 0x0000025f, 0x0000004c, + 0x00000066, 0x00050081, 0x0000000d, 0x00000260, 0x00000063, 0x0000025f, 0x0004003d, 0x00000007, + 0x00000261, 0x00000008, 0x0004003d, 0x00000009, 0x00000262, 0x0000000a, 0x00050056, 0x0000000b, + 0x00000263, 0x00000261, 0x00000262, 0x00070058, 0x00000011, 0x00000264, 0x00000263, 0x00000260, + 0x00000002, 0x00000010, 0x00050051, 0x0000000c, 0x00000265, 0x00000264, 0x00000000, 0x0007000c, + 0x0000000c, 0x00000266, 0x00000001, 0x00000050, 0x0000025e, 0x00000265, 0x0003003e, 0x00000004, + 0x00000266, 0x000100fd, 0x00010038, +}; + // hdr.hlsl : vs_main (800 bytes) static const uint32_t k_hdr_vs_main[] = { 0x07230203, 0x00010300, 0x000e0000, 0x00000024, 0x00000000, 0x00020011, 0x00000001, 0x0003000e, @@ -35420,6 +35840,7 @@ static const NativeSpirvBlob kNativeSpirvBlobs[] = { {"ssao.hlsl", "ps_luma", "HDR=1", k_ssao_ps_luma_HDR_1, sizeof(k_ssao_ps_luma_HDR_1)}, {"ssao.hlsl", "ps_composite", "", k_ssao_ps_composite, sizeof(k_ssao_ps_composite)}, {"ssao.hlsl", "ps_debug", "", k_ssao_ps_debug, sizeof(k_ssao_ps_debug)}, + {"ssao.hlsl", "ps_depth_max", "", k_ssao_ps_depth_max, sizeof(k_ssao_ps_depth_max)}, {"hdr.hlsl", "vs_main", "", k_hdr_vs_main, sizeof(k_hdr_vs_main)}, {"hdr.hlsl", "ps_bloom_down", "", k_hdr_ps_bloom_down, sizeof(k_hdr_ps_bloom_down)}, {"hdr.hlsl", "ps_bloom_down", "BLOOM_FIRST=1", k_hdr_ps_bloom_down_BLOOM_FIRST_1, sizeof(k_hdr_ps_bloom_down_BLOOM_FIRST_1)}, diff --git a/src/native/shaders/ssao.hlsl b/src/native/shaders/ssao.hlsl index 872c67b..f25efdb 100644 --- a/src/native/shaders/ssao.hlsl +++ b/src/native/shaders/ssao.hlsl @@ -259,3 +259,25 @@ float4 ps_debug(VSOut i) : SV_Target { float ao = tex0.SampleLevel(smp_linear, i.uv, 0); return float4(ao, ao, ao, 1.0f); } + +// Tile MAX-reduce of the linear-depth plane (t0) into the small occlusion- +// attribution grid the per-item profiler reads back to the CPU: a scene +// item whose nearest bbox corner is farther than the FARTHEST depth in +// every grid tile it covers cannot contribute pixels. b0 is repurposed for +// this pass: size.xy = linear-depth dims, size.zw = grid dims. 8x8 point +// taps spread across each tile's footprint (a ~24x24-texel tile at 4K is +// sampled at stride ~3, so a sub-3-px background hole can be missed; the +// consumer is telemetry, not culling, and errs toward "occluded" only +// through such holes). +float ps_depth_max(VSOut i) : SV_Target { + float2 half_tile = 0.5f / size.zw; + float m = 0.0f; + [unroll] for (int ty = 0; ty < 8; ++ty) { + [unroll] for (int tx = 0; tx < 8; ++tx) { + float2 f = (float2(float(tx), float(ty)) + 0.5f) / 8.0f; + float2 uv = i.uv + (f * 2.0f - 1.0f) * half_tile; + m = max(m, tex0.SampleLevel(smp_point, uv, 0)); + } + } + return m; +} diff --git a/src/skate3_native_scene.cpp b/src/skate3_native_scene.cpp index 15750c3..91885fb 100644 --- a/src/skate3_native_scene.cpp +++ b/src/skate3_native_scene.cpp @@ -1157,7 +1157,24 @@ REXCVAR_DECLARE(bool, readback_resolve_half_pixel_offset); REXCVAR_DECLARE(bool, async_shader_compilation); REXCVAR_DEFINE_BOOL(skate3_native_render_scene_perf_log, false, "Skate 3", "Log periodic native-renderer performance breakdown lines " - "(600-frame windows)") + "(see skate3_native_render_scene_perf_interval)") + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_INT32(skate3_native_render_scene_perf_interval, 600, "Skate 3", + "Frames between native-scene perf/stats log lines. Lower " + "values give finer windows for chasing transient frame-" + "rate dips at the cost of log volume.") + .range(60, 6000) + .lifecycle(rex::cvar::Lifecycle::kHotReload); + +REXCVAR_DEFINE_BOOL(skate3_native_render_scene_perf_items, false, "Skate 3", + "Deep per-item CPU profiling: adds a perf-items log line " + "per perf window attributing per-item cost to pipeline " + "stages (mesh/texture/constants/submit; cache validate/" + "fingerprint/walk/fetch) and splitting draw time between " + "items inside vs outside the rendered view frustum. Adds " + "measurable overhead at high item counts; leave off " + "outside investigations.") .lifecycle(rex::cvar::Lifecycle::kHotReload); REXCVAR_DEFINE_BOOL(skate3_native_render_scene_ring, false, "Skate 3", @@ -2451,6 +2468,7 @@ namespace { bool BuildItemFromMeshCached(uint8_t* base, uint32_t mesh, DrawItem& item) { const uint64_t frame = g_guest_frame; + const bool prof = REXCVAR_GET(skate3_native_render_scene_perf_items); { std::lock_guard lock(g_item_cache_mutex); auto it = g_item_cache.find(mesh); @@ -2479,7 +2497,12 @@ bool BuildItemFromMeshCached(uint8_t* base, uint32_t mesh, DrawItem& item) { // registration invalidation immediately). const bool dynamic_payload = core.item.skinned || core.item.ropa; if (dynamic_payload || frame >= core.fp_frame) { - if (!ComputeItemFingerprint(base, core.item)) { + const auto fp_t0 = prof ? PerfClock::now() : PerfClock::time_point{}; + const bool fp_ok = ComputeItemFingerprint(base, core.item); + if (prof) { + g_pw_bi_fp.Add(PerfNsSince(fp_t0)); + } + if (!fp_ok) { g_rej_geom.fetch_add(1, std::memory_order_relaxed); g_item_cache.erase(it); return false; @@ -2493,7 +2516,12 @@ bool BuildItemFromMeshCached(uint8_t* base, uint32_t mesh, DrawItem& item) { g_item_cache.erase(it); } } - if (!BuildItemFromMesh(base, mesh, item)) { + const auto walk_t0 = prof ? PerfClock::now() : PerfClock::time_point{}; + const bool walked = BuildItemFromMesh(base, mesh, item); + if (prof) { + g_pw_bi_walk.Add(PerfNsSince(walk_t0)); + } + if (!walked) { return false; } g_item_cache_builds.fetch_add(1, std::memory_order_relaxed); @@ -2526,12 +2554,22 @@ bool BuildItemGeometry(uint8_t* base, uint32_t ctx, DrawItem& item) { g_rej_chain.fetch_add(1, std::memory_order_relaxed); return false; } - if (!BuildItemFromMeshCached(base, mesh, item)) { + const bool prof = REXCVAR_GET(skate3_native_render_scene_perf_items); + const auto core_t0 = prof ? PerfClock::now() : PerfClock::time_point{}; + const bool built = BuildItemFromMeshCached(base, mesh, item); + if (prof) { + g_pw_bi_core.Add(PerfNsSince(core_t0)); + } + if (!built) { return false; } // Draw-time fetch overrides are per-frame state, applied after the cached // core, on every build. + const auto fetch_t0 = prof ? PerfClock::now() : PerfClock::time_point{}; AdoptDrawFetchOverrides(base, item); + if (prof) { + g_pw_bi_fetch.Add(PerfNsSince(fetch_t0)); + } // Culled island draw list from the context. const uint32_t draw_count = REX_LOAD_U16(ctx + kCtxDrawCountU16); @@ -9390,6 +9428,8 @@ void BuildFrameScene(uint8_t* base, const SubmitRecord* records, size_t count) { if (REXCVAR_GET(skate3_native_render_scene_retain_offscreen) && g_synpan_active.load(std::memory_order_relaxed) == 0 && !REXCVAR_GET(skate3_native_render_scene_freecam)) { + const auto retain_t0 = PerfClock::now(); + uint64_t retain_appended = 0; if (g_retained_clear.exchange(false, std::memory_order_relaxed)) { g_retained_items.clear(); g_dyn_retained.clear(); @@ -9446,9 +9486,13 @@ void BuildFrameScene(uint8_t* base, const SubmitRecord* records, size_t count) { // behind the camera stays retained but costs nothing. if (!ItemOutsideFrustum(r.item, scene.view_proj, 1.05f / wide_hor_scale)) { scene.items.push_back(r.item); + ++retain_appended; } ++rit; } + g_pw_bi_retain.Add(PerfNsSince(retain_t0)); + g_retained_appended.fetch_add(retain_appended, std::memory_order_relaxed); + g_retained_live.store(g_retained_items.size(), std::memory_order_relaxed); } // Camera-signal recorder: per-frame raw + smoothed heading while the diff --git a/src/skate3_native_scene.h b/src/skate3_native_scene.h index 02d3784..dceb249 100644 --- a/src/skate3_native_scene.h +++ b/src/skate3_native_scene.h @@ -516,6 +516,13 @@ bool LoadingOrFrontendActive(); // by the render passes. float CharFadeAlpha(const DrawItem& item); +// True when all 8 corners of the item's world-space bbox fall outside one +// clip plane of `vp` (row-vector view*proj). `margin` scales the tested +// frustum: < 1 shrinks it, > 1 widens it. Defined in +// skate3_native_scene.cpp; consumed by the off-screen retention pass and the +// per-item profiling attribution. +bool ItemOutsideFrustum(const DrawItem& it, const float vp[16], float margin); + // Called from the cProcessArenaAsset::RegisterTexture hook: guid -> guest // renderengine::Texture object. void OnRegisterTexture(uint64_t guid, uint32_t texture); diff --git a/src/skate3_native_scene_gpu.cpp b/src/skate3_native_scene_gpu.cpp index b527c9f..ed14e51 100644 --- a/src/skate3_native_scene_gpu.cpp +++ b/src/skate3_native_scene_gpu.cpp @@ -86,6 +86,8 @@ REXCVAR_DECLARE(bool, skate3_native_render_scene_menu_unsuppress); REXCVAR_DECLARE(bool, skate3_native_render_scene_mesh_revalidate); REXCVAR_DECLARE(bool, skate3_native_render_scene_pause_native); REXCVAR_DECLARE(bool, skate3_native_render_scene_perf_log); +REXCVAR_DECLARE(int32_t, skate3_native_render_scene_perf_interval); +REXCVAR_DECLARE(bool, skate3_native_render_scene_perf_items); REXCVAR_DECLARE(bool, skate3_native_render_scene_photo_display_yield); REXCVAR_DECLARE(bool, skate3_native_render_scene_photo_grab_native); REXCVAR_DECLARE(bool, skate3_native_render_scene_photo_native); @@ -7014,13 +7016,15 @@ void RenderOutlineComposite(const NativeGuestOutputRenderContext& context, nrhi::ResourceState::kRenderTarget); } -// 600-frame perf + telemetry log lines (verbatim from the former tail of -// RenderScene). +// Windowed perf + telemetry log lines (verbatim from the former tail of +// RenderScene). Window length in frames = the perf-interval cvar. void LogFrameStats(const FrameScene& scene, uint64_t frames, uint32_t drawn, uint32_t drawn_2d, uint32_t drawn_spline, bool shadow_ready, uint32_t shadow_draws) { - if (frames % 600 == 0 && REXCVAR_GET(skate3_native_render_scene_perf_log)) { - // CPU-side perf snapshot for this 600-frame window. guest_fps is derived + const uint64_t interval = uint64_t( + std::max(60, REXCVAR_GET(skate3_native_render_scene_perf_interval))); + if (frames % interval == 0 && REXCVAR_GET(skate3_native_render_scene_perf_log)) { + // CPU-side perf snapshot for this window. guest_fps is derived // from the guest frame interval; capture/build run on the guest render // thread (they extend guest frame time directly), render/items/shadow on // the command processor thread, decode inline on the render thread @@ -7063,11 +7067,53 @@ void LogFrameStats(const FrameScene& scene, uint64_t frames, uint32_t drawn, g_cam_changes.exchange(0, std::memory_order_relaxed), g_cam_repeats.exchange(0, std::memory_order_relaxed), g_cam_max_streak.exchange(0, std::memory_order_relaxed)); + // Deep per-item attribution (see the perf-items cvar): visibility-class + // draw costs, completed-draw stage split, build-walk decomposition, and + // the off-screen retention pass. Averages are per item (the windows Add + // once per item), so av= is the per-item unit cost in microseconds. + if (REXCVAR_GET(skate3_native_render_scene_perf_items)) { + const auto avg_us = [](const PerfWindow& w) { return w.AvgMs() * 1000.0; }; + REXLOG_INFO( + "native-scene perf-items: draw[vis n={} av={:.2f}us mx={:.2f}ms | " + "occ n={} av={:.2f}us mx={:.2f}ms | out n={} av={:.2f}us " + "mx={:.2f}ms ret_out={}] idx_k[vis={} occ={} out={}] " + "grid[valid={} age={}] " + "stages_us[mesh={:.2f} tex={:.2f} const={:.2f} submit={:.2f} n={}] " + "build_us[core n={} av={:.2f} fp n={} av={:.2f} walk n={} av={:.2f} " + "fetch av={:.2f}] retain[{:.2f}/{:.2f}ms app={} live={}]", + g_pw_di_in.count.load(std::memory_order_relaxed), avg_us(g_pw_di_in), + g_pw_di_in.MaxMs(), + g_pw_di_occ.count.load(std::memory_order_relaxed), + avg_us(g_pw_di_occ), g_pw_di_occ.MaxMs(), + g_pw_di_out.count.load(std::memory_order_relaxed), + avg_us(g_pw_di_out), g_pw_di_out.MaxMs(), + g_vis_out_retained.exchange(0, std::memory_order_relaxed), + g_vis_in_indices.exchange(0, std::memory_order_relaxed) / 1000, + g_vis_occ_indices.exchange(0, std::memory_order_relaxed) / 1000, + g_vis_out_indices.exchange(0, std::memory_order_relaxed) / 1000, + g_r.occl_grid_valid ? 1 : 0, + g_r.occl_grid_valid ? frames - g_r.occl_grid_frame : 0, + avg_us(g_pw_di_mesh), avg_us(g_pw_di_tex), avg_us(g_pw_di_const), + avg_us(g_pw_di_submit), + g_pw_di_submit.count.load(std::memory_order_relaxed), + g_pw_bi_core.count.load(std::memory_order_relaxed), + avg_us(g_pw_bi_core), + g_pw_bi_fp.count.load(std::memory_order_relaxed), avg_us(g_pw_bi_fp), + g_pw_bi_walk.count.load(std::memory_order_relaxed), + avg_us(g_pw_bi_walk), avg_us(g_pw_bi_fetch), g_pw_bi_retain.AvgMs(), + g_pw_bi_retain.MaxMs(), + g_retained_appended.exchange(0, std::memory_order_relaxed), + g_retained_live.load(std::memory_order_relaxed)); + } for (PerfWindow* w : {&g_pw_guest_dt, &g_pw_capture, &g_pw_build, &g_pw_pal_tail, &g_pw_b2d, &g_pw_bspl, &g_pw_bpal, &g_pw_render, &g_pw_items, &g_pw_shadow, &g_pw_pre, &g_pw_settle, &g_pw_tail, &g_pw_2d, &g_pw_mesh_decode, - &g_pw_tex_decode, &g_pw_commit}) { + &g_pw_tex_decode, &g_pw_commit, + &g_pw_di_in, &g_pw_di_occ, &g_pw_di_out, + &g_pw_di_mesh, &g_pw_di_tex, &g_pw_di_const, + &g_pw_di_submit, &g_pw_bi_core, &g_pw_bi_fp, + &g_pw_bi_walk, &g_pw_bi_fetch, &g_pw_bi_retain}) { w->Reset(); } // Refill the settle offender-log + slow-frame budgets for the next window. @@ -7075,7 +7121,7 @@ void LogFrameStats(const FrameScene& scene, uint64_t frames, uint32_t drawn, g_warm_tex_log_budget.store(4, std::memory_order_relaxed); g_slow_frame_log_budget.store(3, std::memory_order_relaxed); } - if (frames % 600 == 0 && REXCVAR_GET(skate3_native_render_scene_perf_log)) { + if (frames % interval == 0 && REXCVAR_GET(skate3_native_render_scene_perf_log)) { uint32_t lw_ctxs = 0, lw_ents = 0; skate3::native_lw::QueryLwStats(&lw_ctxs, &lw_ents); REXLOG_INFO( @@ -7360,6 +7406,72 @@ static void TickShowcase(uint32_t output_width, bool hdr_on) { } } +// True when the item's world-space bbox is provably hidden behind already- +// rendered geometry: its NEAREST corner view-depth is farther than the +// FARTHEST scene depth (tile MAX) in every occlusion-grid tile it covers. +// The corners are projected with the view_proj the grid's depth was +// rendered with (1-2 frames old; see the reduce in ApplySsaoPass), keeping +// bounds and depth consistent under camera motion. Anything not provable - +// invalid grid, a near-plane crosser, bounds leaving that frame's frustum - +// classifies as visible; the consumers (telemetry and the occlusion cull) +// must never overstate occlusion. `depth_margin` is the extra distance (m) +// the item must sit behind every tile's far depth: the telemetry uses a +// small margin (0.25, enough that an item's own last-frame depth counts as +// visible), the cull a larger one for disocclusion safety at speed. +bool ItemOccludedByGrid(const DrawItem& it, float depth_margin) { + if (!g_r.occl_grid_valid || + g_r.occl_grid.size() < + size_t(RendererState::kOcclGridW) * RendererState::kOcclGridH) { + return false; + } + const float* vp = g_r.occl_grid_vp; + float u0 = 1.0f, v0 = 1.0f, u1 = 0.0f, v1 = 0.0f; + float min_z = 3.4e38f; + for (int c = 0; c < 8; ++c) { + const float l[3] = {c & 1 ? it.bbox_max[0] : it.bbox_min[0], + c & 2 ? it.bbox_max[1] : it.bbox_min[1], + c & 4 ? it.bbox_max[2] : it.bbox_min[2]}; + const float* w = it.world; + float p[3]; + for (int k = 0; k < 3; ++k) { + p[k] = l[0] * w[0 * 4 + k] + l[1] * w[1 * 4 + k] + l[2] * w[2 * 4 + k] + + w[3 * 4 + k]; + } + float clip[4]; + for (int k = 0; k < 4; ++k) { + clip[k] = p[0] * vp[0 * 4 + k] + p[1] * vp[1 * 4 + k] + + p[2] * vp[2 * 4 + k] + vp[3 * 4 + k]; + } + if (clip[3] < 0.25f || clip[2] < 0.0f || clip[0] < -clip[3] || + clip[0] > clip[3] || clip[1] < -clip[3] || clip[1] > clip[3]) { + return false; + } + const float u = 0.5f + 0.5f * clip[0] / clip[3]; + const float v = 0.5f - 0.5f * clip[1] / clip[3]; + u0 = std::min(u0, u); + v0 = std::min(v0, v); + u1 = std::max(u1, u); + v1 = std::max(v1, v); + min_z = std::min(min_z, clip[3]); // row-vector proj: w == view Z + } + const int gw = int(RendererState::kOcclGridW); + const int gh = int(RendererState::kOcclGridH); + const int tx0 = std::clamp(int(u0 * float(gw)), 0, gw - 1); + const int tx1 = std::clamp(int(u1 * float(gw)), 0, gw - 1); + const int ty0 = std::clamp(int(v0 * float(gh)), 0, gh - 1); + const int ty1 = std::clamp(int(v1 * float(gh)), 0, gh - 1); + const float need = min_z - depth_margin; + for (int ty = ty0; ty <= ty1; ++ty) { + const float* row = &g_r.occl_grid[size_t(ty) * gw]; + for (int tx = tx0; tx <= tx1; ++tx) { + if (row[tx] >= need) { + return false; + } + } + } + return true; +} + bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_data*/) { if (!SceneEnabled() || (context.backend != NativeGuestOutputBackend::kD3D12 && @@ -8109,7 +8221,20 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat scene.proj[11] == 1.0f && scene.proj[0] != 0.0f && scene.proj[5] != 0.0f && scene.proj[14] != 0.0f; + // Deep per-item profiling (perf-items log line): stage timestamps inside + // draw_item plus an in/out-of-frustum split of each item's total draw + // cost. Sampled once per RenderScene call; the per-item clock reads only + // happen while the cvar is on. + const bool prof_items = REXCVAR_GET(skate3_native_render_scene_perf_items); const auto draw_item = [&](const DrawItem& item) { + // Stage split points (profiling only): t0..t1 mesh serve, t1..t2 texture + // serve, t2..t3 constants assembly, t3..end binds + draw recording. + // Early returns skip the stage windows; the caller's in/out totals still + // capture them. + PerfClock::time_point di_t0{}, di_t1{}, di_t2{}, di_t3{}; + if (prof_items) { + di_t0 = PerfClock::now(); + } // NO per-frame inline decodes here. Static content (world geometry, // props) loads/heals on the decode workers via the miss queue; a // texture decode averages ~10 ms and panning surfaces dozens of new @@ -8185,6 +8310,9 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat } it->second.last_used_frame = frame_number; const MeshBuffers& buffers = it->second; + if (prof_items) { + di_t1 = PerfClock::now(); + } // Double-sided sheet props draw with backface culling; without it the // front/back copies z-fight into lightmap flicker at range (banners/ @@ -8597,6 +8725,9 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat // + material tint + overlay params + misc. tint.a > 0 selects debug // solid colors; tint.r > 0 marks a bound lightmap. For transparent // items misc.yzw carries the fog ramp and mat_tint the fog color. + if (prof_items) { + di_t2 = PerfClock::now(); + } float constants[52] = {}; std::memcpy(constants, item.world, sizeof(item.world)); if (item.unlit) { @@ -9257,6 +9388,9 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat si.item = &item; ssr_items.push_back(si); } + if (prof_items) { + di_t3 = PerfClock::now(); + } cmd->SetRootConstants(0, 52, constants, 0); cmd->SetTexture(1, diffuse->srv); @@ -9426,6 +9560,101 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat } } } + // Stage attribution for draws that reached submission (early returns + // above skip this; their time still lands in the caller's in/out + // windows). + if (prof_items && di_t3 != PerfClock::time_point{}) { + const auto di_t4 = PerfClock::now(); + const auto ns = [](PerfClock::time_point a, PerfClock::time_point b) { + return uint64_t( + std::chrono::duration_cast(b - a).count()); + }; + g_pw_di_mesh.Add(ns(di_t0, di_t1)); + g_pw_di_tex.Add(ns(di_t1, di_t2)); + g_pw_di_const.Add(ns(di_t2, di_t3)); + g_pw_di_submit.Add(ns(di_t3, di_t4)); + } + }; + // Profiling-mode consumption of the occlusion-grid readback ring (filled + // by the perf-items reduce in ApplySsaoPass on previous frames): newest + // completed slot wins, every completed slot retires. A grid that stops + // refreshing (AO off, loading flows) goes invalid instead of classifying + // against ancient depth. + if (prof_items && !g_r.occl_failed && g_r.occl_readback_ptr[1] != nullptr) { + const uint64_t occl_done = context.device->CompletedSubmission(); + int newest = -1; + for (int i = 0; i < 2; ++i) { + if (g_r.occl_pending[i] && g_r.occl_submission[i] < occl_done && + (newest < 0 || + g_r.occl_submission[i] > g_r.occl_submission[newest])) { + newest = i; + } + } + if (newest >= 0) { + context.device->InvalidateForRead( + g_r.occl_readback[newest], 0, + uint64_t(RendererState::kOcclRowPitch) * RendererState::kOcclGridH); + g_r.occl_grid.resize(size_t(RendererState::kOcclGridW) * + RendererState::kOcclGridH); + for (uint32_t row = 0; row < RendererState::kOcclGridH; ++row) { + std::memcpy(&g_r.occl_grid[size_t(row) * RendererState::kOcclGridW], + g_r.occl_readback_ptr[newest] + + size_t(row) * RendererState::kOcclRowPitch, + RendererState::kOcclGridW * sizeof(float)); + } + std::memcpy(g_r.occl_grid_vp, g_r.occl_vp[newest], + sizeof(g_r.occl_grid_vp)); + g_r.occl_grid_frame = frame_number; + g_r.occl_grid_valid = true; + for (int i = 0; i < 2; ++i) { + if (g_r.occl_pending[i] && g_r.occl_submission[i] < occl_done) { + g_r.occl_pending[i] = false; + } + } + } else if (g_r.occl_grid_valid && + frame_number - g_r.occl_grid_frame > 240) { + g_r.occl_grid_valid = false; + } + } + // Per-draw wrapper for the profiling mode: attribute each item's total + // draw_item cost to its visibility class. Out-of-frustum items and + // occlusion-proven-hidden items cost CPU here but can never contribute + // pixels; a large share in either class is a visibility-culling gap, not + // a scene-density cost. + const auto timed_draw = [&](const DrawItem& item) { + if (!prof_items) { + draw_item(item); + return; + } + // Statics only (same gate as the retention pass): a skinned/ropa item's + // pose lives in its bone palette, its identity world + bind-pose bbox + // say nothing about where it is; those always classify as visible. + const bool classifiable = !item.skinned && !item.ropa && + !item.cloth_quads && item.bones.empty(); + const bool off = + classifiable && ItemOutsideFrustum(item, scene.view_proj, 1.0f); + const bool occluded = + classifiable && !off && ItemOccludedByGrid(item, 0.25f); + uint64_t indices = 0; + for (const DrawEntry& e : item.draws) { + indices += e.index_count; + } + const auto t0 = PerfClock::now(); + draw_item(item); + const uint64_t total_ns = perf_ns_since(t0); + if (off) { + g_pw_di_out.Add(total_ns); + g_vis_out_indices.fetch_add(indices, std::memory_order_relaxed); + if (item.retained) { + g_vis_out_retained.fetch_add(1, std::memory_order_relaxed); + } + } else if (occluded) { + g_pw_di_occ.Add(total_ns); + g_vis_occ_indices.fetch_add(indices, std::memory_order_relaxed); + } else { + g_pw_di_in.Add(total_ns); + g_vis_in_indices.fetch_add(indices, std::memory_order_relaxed); + } }; // Opaque items first; environment.transparent items are deferred to an @@ -9671,7 +9900,7 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat [](const auto& a, const auto& b) { return a.first < b.first; }); } for (const auto& [dist, item] : opaque_items) { - draw_item(*item); + timed_draw(*item); } if (!transparent_items.empty() && g_r.pso_transparent != nullptr) { std::stable_sort(transparent_items.begin(), transparent_items.end(), @@ -9694,7 +9923,7 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat cmd->SetPipeline(g_r.pso_fade); blend_bound = g_r.pso_fade; } - draw_item(*item); + timed_draw(*item); continue; } const bool hair = item->char_family >= 4 && item->char_family <= 5 && @@ -9704,9 +9933,9 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat // same shader: keeps far-side strands from compositing over // near-side ones (one uncull(ed) pass reads as crunchy noise). cmd->SetPipeline(g_r.pso_hair_a); - draw_item(*item); + timed_draw(*item); cmd->SetPipeline(g_r.pso_hair_b); - draw_item(*item); + timed_draw(*item); cmd->SetPipeline(blend_bound); continue; } @@ -9728,14 +9957,14 @@ bool RenderScene(const NativeGuestOutputRenderContext& context, void* /*user_dat cmd->SetPipeline(want); blend_bound = want; } - draw_item(*item); + timed_draw(*item); continue; } if (blend_bound != (use_depth ? g_r.pso_transparent : g_r.pso_nodepth)) { blend_bound = use_depth ? g_r.pso_transparent : g_r.pso_nodepth; cmd->SetPipeline(blend_bound); } - draw_item(*item); + timed_draw(*item); } } g_pw_items.Add(perf_ns_since(items_t0)); diff --git a/src/skate3_native_scene_gpu_internal.h b/src/skate3_native_scene_gpu_internal.h index 5003a3a..dab7b00 100644 --- a/src/skate3_native_scene_gpu_internal.h +++ b/src/skate3_native_scene_gpu_internal.h @@ -626,6 +626,30 @@ struct RendererState { // consume at t2 (replacing the classic full-res composite draw); // ApplyHdrPost restores it to RENDER_TARGET and clears the flag. bool ao_plane_in_psr = false; + // Occlusion-attribution grid (perf-items profiling only): a small + // conservative tile-MAX reduce of ao_lin_depth (ssao.hlsl ps_depth_max), + // read back through a two-deep never-waited ring (the photo-grab pattern) + // and consumed on the render thread 1-2 frames later to classify scene + // items as fully occluded by already-rendered geometry. Each slot stores + // the view_proj its depth was rendered with; the CPU test projects with + // THAT matrix so grid and bounds stay consistent under camera motion. + static constexpr uint32_t kOcclGridW = 160; + static constexpr uint32_t kOcclGridH = 90; + static constexpr uint32_t kOcclRowPitch = 768; // 160*4 aligned to 256 + nrhi::Pipeline* pso_occl_reduce = nullptr; + nrhi::Texture* occl_tex = nullptr; // R32F grid, idles in RENDER_TARGET + nrhi::Buffer* occl_readback[2] = {}; + uint8_t* occl_readback_ptr[2] = {}; + uint64_t occl_submission[2] = {}; + float occl_vp[2][16] = {}; + bool occl_pending[2] = {}; + int occl_write_index = 0; + bool occl_failed = false; + // Newest completed grid, CPU-side (render thread only). + std::vector occl_grid; + float occl_grid_vp[16] = {}; + uint64_t occl_grid_frame = 0; // frame_number the grid was captured on + bool occl_grid_valid = false; // HDR pipeline (hdr.hlsl): the scene renders pre-tonemap linear into a // float intermediate (the MSAA color target and/or hdr_resolved), a bloom // pyramid extracts real HDR energy, and ps_tonemap applies the game's diff --git a/src/skate3_native_scene_post.cpp b/src/skate3_native_scene_post.cpp index dac7e0f..14d5716 100644 --- a/src/skate3_native_scene_post.cpp +++ b/src/skate3_native_scene_post.cpp @@ -57,6 +57,7 @@ // Cvars defined in skate3_native_scene.cpp. REXCVAR_DECLARE(double, skate3_menu_blur_sigma); +REXCVAR_DECLARE(bool, skate3_native_render_scene_perf_items); REXCVAR_DECLARE(bool, skate3_native_render_scene_bloom); REXCVAR_DECLARE(double, skate3_native_render_scene_bloom_intensity); REXCVAR_DECLARE(double, skate3_native_render_scene_bloom_knee); @@ -441,6 +442,106 @@ bool ApplySsaoPass(const NativeGuestOutputRenderContext& context, nrhi::ResourceState::kRenderTarget); } + // Occlusion-attribution grid (perf-items profiling): while the linear + // depth is still bound as an SRV, tile-MAX reduce it into the small R32F + // grid and queue a never-waited copy into the readback ring (the + // photo-grab pattern; consumed 1-2 frames later by the item classifier + // in RenderScene). Any creation failure disables only this attribution. + if (REXCVAR_GET(skate3_native_render_scene_perf_items) && !g_r.occl_failed) { + if (g_r.pso_occl_reduce == nullptr) { + nrhi::Shader* rvs = device->CreateShader( + MakeShaderDesc(nrhi::ShaderStage::kVertex, "ssao.hlsl", + kSsaoShaderSource, "vs_main", nullptr, "")); + nrhi::Shader* rps = device->CreateShader( + MakeShaderDesc(nrhi::ShaderStage::kPixel, "ssao.hlsl", + kSsaoShaderSource, "ps_depth_max", nullptr, "")); + if (rvs != nullptr && rps != nullptr) { + nrhi::GraphicsPipelineDesc rp; + rp.layout = g_r.ao_layout; + rp.vs = rvs; + rp.ps = rps; + rp.cull = nrhi::CullMode::kNone; + rp.sample_count = 1; + rp.rtv_format = nrhi::Format::kR32_FLOAT; + g_r.pso_occl_reduce = device->CreateGraphicsPipeline(rp); + } + if (rvs != nullptr) { + device->DestroyDeferred(rvs); + } + if (rps != nullptr) { + device->DestroyDeferred(rps); + } + if (g_r.pso_occl_reduce == nullptr) { + g_r.occl_failed = true; + REXLOG_WARN( + "native-scene: occlusion-grid PSO creation failed - occluded-item " + "attribution disabled"); + } + } + if (!g_r.occl_failed && g_r.occl_tex == nullptr) { + nrhi::TextureDesc td; + td.width = RendererState::kOcclGridW; + td.height = RendererState::kOcclGridH; + td.mip_levels = 1; + td.format = nrhi::Format::kR32_FLOAT; + td.usage = nrhi::kTextureUsageRenderTarget; + td.initial_state = nrhi::ResourceState::kRenderTarget; + g_r.occl_tex = device->CreateTexture(td); + nrhi::BufferDesc bd; + bd.size = uint64_t(RendererState::kOcclRowPitch) * RendererState::kOcclGridH; + bd.heap = nrhi::HeapKind::kReadback; + for (int i = 0; i < 2 && g_r.occl_tex != nullptr; ++i) { + g_r.occl_readback[i] = device->CreateBuffer(bd); + if (g_r.occl_readback[i] == nullptr || + (g_r.occl_readback_ptr[i] = static_cast( + device->Map(g_r.occl_readback[i]))) == nullptr) { + break; + } + } + if (g_r.occl_tex == nullptr || g_r.occl_readback_ptr[1] == nullptr) { + g_r.occl_failed = true; + REXLOG_WARN( + "native-scene: occlusion-grid readback creation failed - " + "occluded-item attribution disabled"); + } + } + // Skip the frame rather than ever waiting when both ring slots are + // still in flight (the consumer retires completed slots). + const int w = g_r.occl_write_index; + if (!g_r.occl_failed && + (!g_r.occl_pending[w] || + g_r.occl_submission[w] < device->CompletedSubmission())) { + float rc[4] = {float(width), float(height), + float(RendererState::kOcclGridW), + float(RendererState::kOcclGridH)}; + cmd->SetRootConstants(0, 4, rc, 0); + cmd->SetViewport(nrhi::Viewport{0.0f, 0.0f, + float(RendererState::kOcclGridW), + float(RendererState::kOcclGridH), 0.0f, + 1.0f}); + cmd->SetScissor(nrhi::Rect{0, 0, int32_t(RendererState::kOcclGridW), + int32_t(RendererState::kOcclGridH)}); + cmd->SetRenderTargets(g_r.occl_tex, nullptr); + cmd->SetPipeline(g_r.pso_occl_reduce); + cmd->SetTexture(1, g_r.ao_lin_srv); + cmd->Draw(3, 0); + cmd->Barrier(g_r.occl_tex, nrhi::ResourceState::kRenderTarget, + nrhi::ResourceState::kCopySource); + cmd->FlushBarriers(); + cmd->CopyTextureToBuffer(g_r.occl_readback[w], 0, + RendererState::kOcclRowPitch, g_r.occl_tex, 0, + RendererState::kOcclGridW, + RendererState::kOcclGridH); + cmd->Barrier(g_r.occl_tex, nrhi::ResourceState::kCopySource, + nrhi::ResourceState::kRenderTarget); + cmd->FlushBarriers(); + std::memcpy(g_r.occl_vp[w], scene.view_proj, sizeof(g_r.occl_vp[w])); + g_r.occl_submission[w] = device->CurrentSubmission(); + g_r.occl_pending[w] = true; + g_r.occl_write_index = 1 - w; + } + } + // Restore intermediate steady states. cmd->Barrier(g_r.ao_tex[1], nrhi::ResourceState::kPixelShaderResource, nrhi::ResourceState::kRenderTarget); diff --git a/src/skate3_native_scene_state.h b/src/skate3_native_scene_state.h index 6361c08..cba7e1d 100644 --- a/src/skate3_native_scene_state.h +++ b/src/skate3_native_scene_state.h @@ -830,7 +830,7 @@ inline std::atomic g_rej_geom{0}; inline std::atomic g_rej_draws{0}; inline std::atomic g_rej_bbox{0}; -// ---- Perf telemetry (windowed; logged + reset with the 600-frame stats) ---- +// ---- Perf telemetry (windowed; logged + reset with the interval stats) ---- // Written by the guest render thread (capture/build) and the command // processor thread (render segments); read by the render thread's stats log. // Atomics with relaxed ordering: telemetry, not synchronization. @@ -939,6 +939,39 @@ inline std::atomic g_capture_foreign_bank{0}; inline std::atomic g_item_cache_hits{0}; inline std::atomic g_item_cache_builds{0}; +// ---- Per-item pipeline profiling (skate3_native_render_scene_perf_items) -- +// Deep attribution of the per-item CPU cost, logged as a perf-items line on +// the perf-log interval. Two questions: where the per-item time goes (mesh +// serve, texture serve, constants, submit on the render side; cache +// validate, fingerprint, full walk, fetch overrides on the build side), and +// whether it is spent on items the rendered frustum can actually see (in +// vs out draw windows, indices, retained-item share). All of it is opt-in: +// the extra clock reads cost real time at 2000+ items/frame. +// Render thread (command processor): per-draw_item totals split by the +// item's bbox-vs-frustum verdict, and per-stage sections of completed draws. +inline PerfWindow g_pw_di_in; // draw_item total, item potentially visible +inline PerfWindow g_pw_di_occ; // draw_item total, in-frustum but occlusion-grid-proven hidden +inline PerfWindow g_pw_di_out; // draw_item total, bbox fully outside the rendered frustum +inline PerfWindow g_pw_di_mesh; // mesh store lookup/heal (incl. rare inline decodes) +inline PerfWindow g_pw_di_tex; // texture route/serve section +inline PerfWindow g_pw_di_const; // constants assembly +inline PerfWindow g_pw_di_submit; // buffer binds + DrawIndexed recording +inline std::atomic g_vis_in_indices{0}; // indices submitted, visible items +inline std::atomic g_vis_occ_indices{0}; // indices submitted, occluded items +inline std::atomic g_vis_out_indices{0}; // indices submitted, out-of-frustum items +inline std::atomic g_vis_out_retained{0}; // out-of-frustum draws from retention +// Guest render thread: decomposition of the per-item build walk. +inline PerfWindow g_pw_bi_core; // BuildItemFromMeshCached total (hit validate + misses) +inline PerfWindow g_pw_bi_fp; // ComputeItemFingerprint on the cache-hit path +inline PerfWindow g_pw_bi_walk; // full BuildItemFromMesh rebuilds (cache miss) +inline PerfWindow g_pw_bi_fetch; // AdoptDrawFetchOverrides per-frame guest reads +// Off-screen retention pass (always measured, one Add per frame: two clock +// reads): its cost and how many items it re-appends beyond the guest's own +// submission are core visibility-culling telemetry, not deep profiling. +inline PerfWindow g_pw_bi_retain; +inline std::atomic g_retained_appended{0}; // re-appended items this window +inline std::atomic g_retained_live{0}; // retained-map size after the sweep + // ---- Photo-editor postfx capture (FrameScene::PhotoFx / photo_fx.hlsl) ---- // While a photo flow is active (g_photo_flow_frame, armed by // UpdatePhotoGrabWindow), the OnDrawDone hook snapshots each postfx pass's