00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "winGraphicsPipe.h"
00016 #include "config_windisplay.h"
00017 #include "displaySearchParameters.h"
00018 #include "dtool_config.h"
00019 #include "pbitops.h"
00020
00021 #include "psapi.h"
00022 #include "powrprof.h"
00023
00024 #ifdef _WIN64
00025 #include <intrin.h>
00026 #endif
00027
00028
00029 TypeHandle WinGraphicsPipe::_type_handle;
00030
00031 #define MAXIMUM_PROCESSORS 32
00032
00033 typedef struct _PROCESSOR_POWER_INFORMATION
00034 {
00035 ULONG Number;
00036 ULONG MaxMhz;
00037 ULONG CurrentMhz;
00038 ULONG MhzLimit;
00039 ULONG MaxIdleState;
00040 ULONG CurrentIdleState;
00041 }
00042 PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
00043
00044 typedef BOOL (WINAPI *GetProcessMemoryInfoType) (HANDLE Process, PROCESS_MEMORY_COUNTERS *ppsmemCounters, DWORD cb);
00045 typedef BOOL (WINAPI *GlobalMemoryStatusExType) (LPMEMORYSTATUSEX lpBuffer);
00046 typedef long (__stdcall *CallNtPowerInformationType) (POWER_INFORMATION_LEVEL information_level, PVOID InputBuffer, ULONG InputBufferLength, PVOID OutputBuffer, ULONG OutputBufferLength);
00047
00048 static int initialize = false;
00049 static HMODULE psapi_dll = 0;
00050 static HMODULE kernel32_dll = 0;
00051 static HMODULE power_dll = 0;
00052 static GetProcessMemoryInfoType GetProcessMemoryInfoFunction = 0;
00053 static GlobalMemoryStatusExType GlobalMemoryStatusExFunction = 0;
00054 static CallNtPowerInformationType CallNtPowerInformationFunction = 0;
00055
00056 void get_memory_information (DisplayInformation *display_information)
00057 {
00058 if (initialize == false) {
00059 psapi_dll = LoadLibrary ("psapi.dll");
00060 if (psapi_dll) {
00061 GetProcessMemoryInfoFunction = (GetProcessMemoryInfoType) GetProcAddress (psapi_dll, "GetProcessMemoryInfo");
00062 }
00063
00064 kernel32_dll = LoadLibrary ("kernel32.dll");
00065 if (kernel32_dll) {
00066 GlobalMemoryStatusExFunction = (GlobalMemoryStatusExType) GetProcAddress (kernel32_dll, "GlobalMemoryStatusEx");
00067 }
00068
00069 initialize = true;
00070 }
00071
00072 if (GlobalMemoryStatusExFunction) {
00073 MEMORYSTATUSEX memory_status;
00074
00075 memory_status.dwLength = sizeof (MEMORYSTATUSEX);
00076 if (GlobalMemoryStatusExFunction (&memory_status)) {
00077 display_information -> _physical_memory = memory_status.ullTotalPhys;
00078 display_information -> _available_physical_memory = memory_status.ullAvailPhys;
00079 display_information -> _page_file_size = memory_status.ullTotalPageFile;
00080 display_information -> _available_page_file_size = memory_status.ullAvailPageFile;
00081 display_information -> _process_virtual_memory = memory_status.ullTotalVirtual;
00082 display_information -> _available_process_virtual_memory = memory_status.ullAvailVirtual;
00083 display_information -> _memory_load = memory_status.dwMemoryLoad;
00084 }
00085 }
00086 else {
00087 MEMORYSTATUS memory_status;
00088
00089 memory_status.dwLength = sizeof (MEMORYSTATUS);
00090 GlobalMemoryStatus (&memory_status);
00091
00092 display_information -> _physical_memory = memory_status.dwTotalPhys;
00093 display_information -> _available_physical_memory = memory_status.dwAvailPhys;
00094 display_information -> _page_file_size = memory_status.dwTotalPageFile;
00095 display_information -> _available_page_file_size = memory_status.dwAvailPageFile;
00096 display_information -> _process_virtual_memory = memory_status.dwTotalVirtual;
00097 display_information -> _available_process_virtual_memory = memory_status.dwAvailVirtual;
00098 display_information -> _memory_load = memory_status.dwMemoryLoad;
00099 }
00100
00101 if (GetProcessMemoryInfoFunction) {
00102 HANDLE process;
00103 DWORD process_id;
00104 PROCESS_MEMORY_COUNTERS process_memory_counters;
00105
00106 process_id = GetCurrentProcessId();
00107 process = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, process_id);
00108 if (process) {
00109 if (GetProcessMemoryInfoFunction (process, &process_memory_counters, sizeof (PROCESS_MEMORY_COUNTERS))) {
00110 display_information -> _page_fault_count = process_memory_counters.PageFaultCount;
00111 display_information -> _process_memory = process_memory_counters.WorkingSetSize;
00112 display_information -> _peak_process_memory = process_memory_counters.PeakWorkingSetSize;
00113 display_information -> _page_file_usage = process_memory_counters.PagefileUsage;
00114 display_information -> _peak_page_file_usage = process_memory_counters.PeakPagefileUsage;
00115 }
00116
00117 CloseHandle(process);
00118 }
00119 }
00120 }
00121
00122 typedef union
00123 {
00124 PN_uint64 long_integer;
00125 }
00126 LONG_INTEGER;
00127
00128 PN_uint64 cpu_time_function (void) {
00129 #ifdef _WIN64
00130 return __rdtsc();
00131 #else
00132 LONG_INTEGER long_integer;
00133 LONG_INTEGER *long_integer_pointer;
00134
00135 long_integer_pointer = &long_integer;
00136
00137 __asm
00138 {
00139 mov ebx,[long_integer_pointer]
00140 rdtsc
00141 mov [ebx + 0], eax
00142 mov [ebx + 4], edx
00143 }
00144
00145 return long_integer.long_integer;
00146 #endif
00147 }
00148
00149 typedef union
00150 {
00151 struct
00152 {
00153 union
00154 {
00155 struct
00156 {
00157 unsigned char al;
00158 unsigned char ah;
00159 };
00160 unsigned int eax;
00161 };
00162 unsigned int ebx;
00163 unsigned int ecx;
00164 unsigned int edx;
00165 };
00166 }
00167 CPU_ID_REGISTERS;
00168
00169 typedef struct
00170 {
00171 union
00172 {
00173 struct
00174 {
00175 int maximum_cpu_id_input;
00176 char cpu_vendor [16];
00177 };
00178
00179 CPU_ID_REGISTERS cpu_id_registers_0;
00180 };
00181
00182 union
00183 {
00184 CPU_ID_REGISTERS cpu_id_registers_1;
00185
00186 struct
00187 {
00188
00189 union
00190 {
00191 unsigned int eax;
00192 unsigned int version_information;
00193 struct
00194 {
00195 unsigned int stepping_id : 4;
00196 unsigned int model : 4;
00197 unsigned int family : 4;
00198 unsigned int processor_type : 2;
00199 unsigned int reserved_0 : 2;
00200 unsigned int extended_model_id : 4;
00201 unsigned int extended_family_id : 8;
00202 unsigned int reserved_1 : 4;
00203 };
00204 };
00205
00206
00207 union
00208 {
00209 unsigned int ebx;
00210 struct
00211 {
00212 unsigned int brand_index : 8;
00213 unsigned int clflush : 8;
00214 unsigned int maximum_logical_processors : 8;
00215 unsigned int initial_apic_id : 8;
00216 };
00217 };
00218
00219
00220 union
00221 {
00222 unsigned int ecx;
00223 struct
00224 {
00225 unsigned int sse3 : 1;
00226 unsigned int reserved_1_to_2 : 2;
00227 unsigned int monitor : 1;
00228 unsigned int ds_cpl : 1;
00229 unsigned int vmx : 1;
00230 unsigned int reserved_6 : 1;
00231 unsigned int est : 1;
00232 unsigned int tm2 : 1;
00233 unsigned int reserved_9 : 1;
00234 unsigned int cnxt_id : 1;
00235 unsigned int reserved_11_to_12 : 2;
00236 unsigned int cmpxchg16b : 1;
00237 unsigned int xtpr_disable : 1;
00238 unsigned int reserved_15_to_31 : 17;
00239 };
00240 };
00241
00242
00243 union
00244 {
00245 unsigned int edx;
00246 struct
00247 {
00248 unsigned int fpu : 1;
00249 unsigned int vme : 1;
00250 unsigned int de : 1;
00251 unsigned int pse : 1;
00252 unsigned int tsc : 1;
00253 unsigned int msr : 1;
00254 unsigned int pae : 1;
00255 unsigned int mce : 1;
00256 unsigned int cx8 : 1;
00257 unsigned int apic : 1;
00258 unsigned int reserved_10 : 1;
00259 unsigned int sep : 1;
00260 unsigned int mtrr : 1;
00261 unsigned int pge : 1;
00262 unsigned int mca : 1;
00263 unsigned int cmov : 1;
00264 unsigned int pat : 1;
00265 unsigned int pse_36 : 1;
00266 unsigned int psn : 1;
00267 unsigned int cflush : 1;
00268 unsigned int reserved_20 : 1;
00269 unsigned int ds : 1;
00270 unsigned int acpi : 1;
00271 unsigned int mmx : 1;
00272 unsigned int fxsr : 1;
00273 unsigned int sse : 1;
00274 unsigned int sse2 : 1;
00275 unsigned int ss : 1;
00276 unsigned int htt : 1;
00277 unsigned int tm : 1;
00278 unsigned int reserved_30 : 1;
00279 unsigned int pbe : 1;
00280 };
00281 };
00282 };
00283 };
00284
00285 #define MAXIMUM_2 8
00286 #define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof (CPU_ID_REGISTERS))
00287
00288 union
00289 {
00290 CPU_ID_REGISTERS cpu_id_registers_2;
00291 unsigned char character_array_2 [MAXIMUM_CHARACTERS];
00292 CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2];
00293 };
00294
00295 union
00296 {
00297 CPU_ID_REGISTERS cpu_id_registers_0x80000000;
00298 };
00299
00300 union
00301 {
00302 CPU_ID_REGISTERS cpu_id_registers_0x80000001;
00303 };
00304
00305 union
00306 {
00307 char cpu_brand_string [sizeof (CPU_ID_REGISTERS) * 3];
00308 struct
00309 {
00310 CPU_ID_REGISTERS cpu_id_registers_0x80000002;
00311 CPU_ID_REGISTERS cpu_id_registers_0x80000003;
00312 CPU_ID_REGISTERS cpu_id_registers_0x80000004;
00313 };
00314 };
00315
00316 union
00317 {
00318 struct
00319 {
00320
00321 union
00322 {
00323 unsigned int eax;
00324 };
00325
00326
00327 union
00328 {
00329 unsigned int ebx;
00330 };
00331
00332
00333 union
00334 {
00335 unsigned int ecx;
00336 struct
00337 {
00338 unsigned int l1_data_cache_line_size : 8;
00339 unsigned int l1_data_reserved_8_to_15 : 8;
00340 unsigned int l1_data_associativity : 8;
00341 unsigned int l1_data_cache_size : 8;
00342 };
00343 };
00344
00345
00346 union
00347 {
00348 unsigned int edx;
00349 struct
00350 {
00351 unsigned int l1_code_cache_line_size : 8;
00352 unsigned int l1_code_reserved_8_to_15 : 8;
00353 unsigned int l1_code_associativity : 8;
00354 unsigned int l1_code_cache_size : 8;
00355 };
00356 };
00357 };
00358 CPU_ID_REGISTERS cpu_id_registers_0x80000005;
00359 };
00360
00361 union
00362 {
00363 struct
00364 {
00365
00366 union
00367 {
00368 unsigned int eax;
00369 };
00370
00371
00372 union
00373 {
00374 unsigned int ebx;
00375 };
00376
00377
00378 union
00379 {
00380 unsigned int ecx;
00381 struct
00382 {
00383 unsigned int l2_cache_line_size : 8;
00384 unsigned int l2_reserved_8_to_11 : 4;
00385 unsigned int l2_associativity : 4;
00386 unsigned int l2_cache_size : 16;
00387 };
00388 };
00389
00390
00391 union
00392 {
00393 unsigned int edx;
00394 };
00395 };
00396 CPU_ID_REGISTERS cpu_id_registers_0x80000006;
00397 };
00398
00399 union
00400 {
00401 struct
00402 {
00403
00404 union
00405 {
00406 unsigned int eax;
00407 };
00408
00409
00410 union
00411 {
00412 unsigned int ebx;
00413 };
00414
00415
00416 union
00417 {
00418 unsigned int ecx;
00419 };
00420
00421
00422 union
00423 {
00424 unsigned int edx;
00425 };
00426 };
00427 CPU_ID_REGISTERS cpu_id_registers_0x80000008;
00428 };
00429
00430 unsigned int cache_line_size;
00431 unsigned int log_base_2_cache_line_size;
00432 }
00433 CPU_ID;
00434
00435 typedef struct
00436 {
00437 CPU_ID_REGISTERS cpu_id_registers_0;
00438 CPU_ID_REGISTERS cpu_id_registers_1;
00439
00440 CPU_ID_REGISTERS cpu_id_registers_0x80000000;
00441 CPU_ID_REGISTERS cpu_id_registers_0x80000001;
00442 CPU_ID_REGISTERS cpu_id_registers_0x80000002;
00443 CPU_ID_REGISTERS cpu_id_registers_0x80000003;
00444 CPU_ID_REGISTERS cpu_id_registers_0x80000004;
00445
00446 CPU_ID_REGISTERS cpu_id_registers_0x80000006;
00447
00448 CPU_ID_REGISTERS cpu_id_registers_0x80000008;
00449 }
00450 CPU_ID_BINARY_DATA;
00451
00452 typedef struct
00453 {
00454 union
00455 {
00456 CPU_ID_BINARY_DATA cpu_binary_data;
00457 unsigned int data_array [sizeof (CPU_ID_BINARY_DATA) / 4];
00458 };
00459 }
00460 CPU_ID_BINARY_DATA_ARRAY;
00461
00462 void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) {
00463
00464 cpu_id_binary_data -> cpu_id_registers_0 = cpu_id -> cpu_id_registers_0;
00465 cpu_id_binary_data -> cpu_id_registers_1 = cpu_id -> cpu_id_registers_1;
00466 cpu_id_binary_data -> cpu_id_registers_0x80000000 = cpu_id -> cpu_id_registers_0x80000000;
00467 cpu_id_binary_data -> cpu_id_registers_0x80000001 = cpu_id -> cpu_id_registers_0x80000001;
00468 cpu_id_binary_data -> cpu_id_registers_0x80000002 = cpu_id -> cpu_id_registers_0x80000002;
00469 cpu_id_binary_data -> cpu_id_registers_0x80000003 = cpu_id -> cpu_id_registers_0x80000003;
00470 cpu_id_binary_data -> cpu_id_registers_0x80000004 = cpu_id -> cpu_id_registers_0x80000004;
00471 cpu_id_binary_data -> cpu_id_registers_0x80000006 = cpu_id -> cpu_id_registers_0x80000006;
00472 cpu_id_binary_data -> cpu_id_registers_0x80000008 = cpu_id -> cpu_id_registers_0x80000008;
00473 }
00474
00475 void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) {
00476
00477 memset (cpu_id, 0, sizeof (CPU_ID));
00478
00479 cpu_id -> cpu_id_registers_0 = cpu_id_binary_data -> cpu_id_registers_0;
00480 cpu_id -> cpu_id_registers_1 = cpu_id_binary_data -> cpu_id_registers_1;
00481 cpu_id -> cpu_id_registers_0x80000000 = cpu_id_binary_data -> cpu_id_registers_0x80000000;
00482 cpu_id -> cpu_id_registers_0x80000001 = cpu_id_binary_data -> cpu_id_registers_0x80000001;
00483 cpu_id -> cpu_id_registers_0x80000002 = cpu_id_binary_data -> cpu_id_registers_0x80000002;
00484 cpu_id -> cpu_id_registers_0x80000003 = cpu_id_binary_data -> cpu_id_registers_0x80000003;
00485 cpu_id -> cpu_id_registers_0x80000004 = cpu_id_binary_data -> cpu_id_registers_0x80000004;
00486 cpu_id -> cpu_id_registers_0x80000006 = cpu_id_binary_data -> cpu_id_registers_0x80000006;
00487 cpu_id -> cpu_id_registers_0x80000008 = cpu_id_binary_data -> cpu_id_registers_0x80000008;
00488 }
00489
00490 int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
00491 int state;
00492
00493 state = false;
00494 __try
00495 {
00496 if (input_eax == 0) {
00497
00498 #ifdef _WIN64
00499 __cpuid((int*)cpu_id_registers, input_eax);
00500 unsigned int tmp = cpu_id_registers->edx;
00501 cpu_id_registers->edx = cpu_id_registers->ecx;
00502 cpu_id_registers->ecx = tmp;
00503 #else
00504 __asm
00505 {
00506 mov eax, [input_eax]
00507 mov edi, [cpu_id_registers]
00508
00509 cpuid
00510
00511 mov [edi + 0], eax
00512 mov [edi + 4], ebx
00513 mov [edi + 8], edx
00514 mov [edi + 12], ecx
00515 }
00516 #endif
00517 }
00518 else {
00519 #ifdef _WIN64
00520 __cpuid((int*)cpu_id_registers, input_eax);
00521 #else
00522 __asm
00523 {
00524 mov eax, [input_eax]
00525 mov edi, [cpu_id_registers]
00526
00527 cpuid
00528
00529 mov [edi + 0], eax
00530 mov [edi + 4], ebx
00531 mov [edi + 8], ecx
00532 mov [edi + 12], edx
00533 }
00534 #endif
00535 }
00536
00537 state = true;
00538 }
00539 __except (1)
00540 {
00541 state = false;
00542 }
00543
00544 return state;
00545 }
00546
00547 void parse_cpu_id (CPU_ID *cpu_id) {
00548
00549 printf ("CPUID\n");
00550 printf (" vendor = %s \n", cpu_id -> cpu_vendor);
00551 printf (" brand string %s \n", cpu_id -> cpu_brand_string);
00552 printf (" maximum_cpu_id_input = %u \n", cpu_id -> maximum_cpu_id_input);
00553 printf (" maximum extended information = 0x%X \n", cpu_id -> cpu_id_registers_0x80000000.eax);
00554
00555 printf (" MMX = %u \n", cpu_id -> mmx);
00556 printf (" SSE = %u \n", cpu_id -> sse);
00557 printf (" SSE2 = %u \n", cpu_id -> sse2);
00558 printf (" SSE3 = %u \n", cpu_id -> sse3);
00559
00560 printf (" EST = %u \n", cpu_id -> est);
00561
00562 if (cpu_id -> maximum_cpu_id_input >= 1) {
00563 printf (" version_information \n");
00564 printf (" stepping_id %u \n", cpu_id -> stepping_id);
00565 printf (" model %u \n", cpu_id -> model);
00566 printf (" family %u \n", cpu_id -> family);
00567 printf (" processor_type %u \n", cpu_id -> processor_type);
00568 printf (" extended_model_id %u \n", cpu_id -> extended_model_id);
00569 printf (" extended_family_id %u \n", cpu_id -> extended_family_id);
00570
00571 printf (" brand_index %u \n", cpu_id -> brand_index);
00572 printf (" clflush %u \n", cpu_id -> clflush);
00573 printf (" maximum_logical_processors %u \n", cpu_id -> maximum_logical_processors);
00574 printf (" initial_apic_id %u \n", cpu_id -> initial_apic_id);
00575
00576
00577
00578 }
00579
00580 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000005) {
00581 printf (" l1_data_cache_line_size %d \n", cpu_id -> l1_data_cache_line_size);
00582 printf (" l1_data_associativity %d \n", cpu_id -> l1_data_associativity);
00583 printf (" l1_data_cache_size %dK \n", cpu_id -> l1_data_cache_size);
00584
00585 printf (" l1_code_cache_line_size %d \n", cpu_id -> l1_code_cache_line_size);
00586 printf (" l1_code_associativity %d \n", cpu_id -> l1_code_associativity);
00587 printf (" l1_code_cache_size %dK \n", cpu_id -> l1_code_cache_size);
00588 }
00589
00590 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000006) {
00591 printf (" l2_cache_line_size %d \n", cpu_id -> l2_cache_line_size);
00592 printf (" l2_associativity %d \n", cpu_id -> l2_associativity);
00593 printf (" l2_cache_size %dK \n", cpu_id -> l2_cache_size);
00594 }
00595 }
00596
00597 int initialize_cpu_id (CPU_ID *cpu_id) {
00598
00599 int state;
00600 int debug;
00601
00602 state = false;
00603 debug = false;
00604 memset (cpu_id, 0, sizeof (CPU_ID));
00605
00606 if (cpuid (0, &cpu_id -> cpu_id_registers_0)) {
00607 if (cpu_id -> maximum_cpu_id_input >= 1) {
00608 cpuid (1, &cpu_id -> cpu_id_registers_1);
00609 }
00610 if (cpu_id -> maximum_cpu_id_input >= 2) {
00611 unsigned int index;
00612
00613 cpuid (2, &cpu_id -> cpu_id_registers_2);
00614 if (debug) {
00615 printf (" al = %u \n", cpu_id -> cpu_id_registers_2.al);
00616 }
00617
00618 for (index = 1; index < cpu_id -> cpu_id_registers_2.al && index < MAXIMUM_2; index++) {
00619 cpuid (2, &cpu_id -> cpu_id_registers_2_array [index]);
00620 }
00621
00622 for (index = 1; index < MAXIMUM_CHARACTERS; index++) {
00623 if (cpu_id -> character_array_2 [index]) {
00624 if (debug) {
00625 printf (" cache/TLB byte = %X \n", cpu_id -> character_array_2 [index]);
00626 }
00627 switch (cpu_id -> character_array_2 [index])
00628 {
00629 case 0x0A:
00630 case 0x0C:
00631 cpu_id -> cache_line_size = 32;
00632 cpu_id -> log_base_2_cache_line_size = 5;
00633 break;
00634
00635 case 0x2C:
00636 case 0x60:
00637 case 0x66:
00638 case 0x67:
00639 case 0x68:
00640 cpu_id -> cache_line_size = 64;
00641 cpu_id -> log_base_2_cache_line_size = 6;
00642 break;
00643 }
00644 }
00645 }
00646 }
00647
00648 cpuid (0x80000000, &cpu_id -> cpu_id_registers_0x80000000);
00649
00650 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000001) {
00651 cpuid (0x80000001, &cpu_id -> cpu_id_registers_0x80000001);
00652 }
00653
00654 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000004) {
00655 cpuid (0x80000002, &cpu_id -> cpu_id_registers_0x80000002);
00656 cpuid (0x80000003, &cpu_id -> cpu_id_registers_0x80000003);
00657 cpuid (0x80000004, &cpu_id -> cpu_id_registers_0x80000004);
00658 }
00659
00660 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000005) {
00661 cpuid (0x80000005, &cpu_id -> cpu_id_registers_0x80000005);
00662 }
00663
00664 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000006) {
00665 cpuid (0x80000006, &cpu_id -> cpu_id_registers_0x80000006);
00666 }
00667
00668 if (cpu_id -> cpu_id_registers_0x80000000.eax >= 0x80000008) {
00669 cpuid (0x80000008, &cpu_id -> cpu_id_registers_0x80000008);
00670 }
00671
00672 state = true;
00673 }
00674
00675 return state;
00676 }
00677
00678 int update_cpu_frequency_function (int processor_number, DisplayInformation *display_information)
00679 {
00680 int update;
00681
00682 update = false;
00683 display_information -> _maximum_cpu_frequency = 0;
00684 display_information -> _current_cpu_frequency = 0;
00685
00686 if (CallNtPowerInformationFunction) {
00687
00688 int i;
00689 PVOID input_buffer;
00690 PVOID output_buffer;
00691 ULONG input_buffer_size;
00692 ULONG output_buffer_size;
00693 POWER_INFORMATION_LEVEL information_level;
00694 PROCESSOR_POWER_INFORMATION *processor_power_information;
00695 PROCESSOR_POWER_INFORMATION processor_power_information_array [MAXIMUM_PROCESSORS];
00696
00697 memset (processor_power_information_array, 0, sizeof (PROCESSOR_POWER_INFORMATION) * MAXIMUM_PROCESSORS);
00698
00699 processor_power_information = processor_power_information_array;
00700 for (i = 0; i < MAXIMUM_PROCESSORS; i++) {
00701 processor_power_information -> Number = 0xFFFFFFFF;
00702 processor_power_information++;
00703 }
00704
00705 information_level = ProcessorInformation;
00706 input_buffer = NULL;
00707 output_buffer = processor_power_information_array;
00708 input_buffer_size = 0;
00709 output_buffer_size = sizeof (PROCESSOR_POWER_INFORMATION) * MAXIMUM_PROCESSORS;
00710 if (CallNtPowerInformationFunction (information_level, input_buffer, input_buffer_size, output_buffer, output_buffer_size) == 0) {
00711 processor_power_information = processor_power_information_array;
00712 for (i = 0; i < MAXIMUM_PROCESSORS; i++) {
00713 if (processor_power_information -> Number == processor_number) {
00714 PN_uint64 value;
00715
00716 value = processor_power_information -> MaxMhz;
00717 display_information -> _maximum_cpu_frequency = value * 1000000;
00718
00719 value = processor_power_information -> CurrentMhz;
00720 display_information -> _current_cpu_frequency = value * 1000000;
00721 update = true;
00722
00723 break;
00724 }
00725
00726 processor_power_information++;
00727 }
00728 }
00729 }
00730
00731 return update;
00732 }
00733
00734 void
00735 count_number_of_cpus(DisplayInformation *display_information) {
00736 int num_cpu_cores = 0;
00737 int num_logical_cpus = 0;
00738
00739
00740 typedef BOOL (WINAPI *LPFN_GLPI)(PSYSTEM_LOGICAL_PROCESSOR_INFORMATION,
00741 PDWORD);
00742 LPFN_GLPI glpi;
00743 glpi = (LPFN_GLPI)GetProcAddress(GetModuleHandle(TEXT("kernel32")),
00744 "GetLogicalProcessorInformation");
00745 if (glpi == NULL) {
00746 windisplay_cat.info()
00747 << "GetLogicalProcessorInformation is not supported.\n";
00748 return;
00749 }
00750
00751
00752
00753 PSYSTEM_LOGICAL_PROCESSOR_INFORMATION buffer = NULL;
00754 DWORD buffer_length = 0;
00755 DWORD rc = glpi(buffer, &buffer_length);
00756 while (!rc) {
00757 if (GetLastError() == ERROR_INSUFFICIENT_BUFFER) {
00758 if (buffer != NULL) {
00759 PANDA_FREE_ARRAY(buffer);
00760 }
00761
00762 buffer = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)PANDA_MALLOC_ARRAY(buffer_length);
00763 nassertv(buffer != NULL);
00764 } else {
00765 windisplay_cat.info()
00766 << "GetLogicalProcessorInformation failed: " << GetLastError()
00767 << "\n";
00768 return;
00769 }
00770 rc = glpi(buffer, &buffer_length);
00771 }
00772
00773
00774 PSYSTEM_LOGICAL_PROCESSOR_INFORMATION ptr = buffer;
00775 PSYSTEM_LOGICAL_PROCESSOR_INFORMATION end = (PSYSTEM_LOGICAL_PROCESSOR_INFORMATION)((char *)buffer + buffer_length);
00776
00777 while (ptr < end) {
00778 if (ptr->Relationship == RelationProcessorCore) {
00779 num_cpu_cores++;
00780
00781
00782 num_logical_cpus += count_bits_in_word((PN_uint64)(ptr->ProcessorMask));
00783 }
00784 ++ptr;
00785 }
00786
00787 PANDA_FREE_ARRAY(buffer);
00788
00789 windisplay_cat.info()
00790 << num_cpu_cores << " CPU cores, with "
00791 << num_logical_cpus << " logical processors.\n";
00792
00793 display_information->_num_cpu_cores = num_cpu_cores;
00794 display_information->_num_logical_cpus = num_logical_cpus;
00795 }
00796
00797
00798
00799
00800
00801
00802
00803 WinGraphicsPipe::
00804 WinGraphicsPipe() {
00805
00806 bool state;
00807 char string [512];
00808
00809 state = false;
00810 _supported_types = OT_window | OT_fullscreen_window;
00811
00812
00813
00814 _pfnTrackMouseEvent = NULL;
00815
00816 _hUser32 = (HINSTANCE)LoadLibrary("user32.dll");
00817 if (_hUser32 != NULL) {
00818 _pfnTrackMouseEvent =
00819 (PFN_TRACKMOUSEEVENT)GetProcAddress(_hUser32, "TrackMouseEvent");
00820 }
00821
00822 #ifdef HAVE_DX9
00823 if (request_dxdisplay_information){
00824 DisplaySearchParameters display_search_parameters_dx9;
00825 int dx9_display_information (DisplaySearchParameters &display_search_parameters_dx9, DisplayInformation *display_information);
00826
00827 if (state == false && dx9_display_information (display_search_parameters_dx9, _display_information)) {
00828 state = true;
00829 }
00830 }
00831 #endif
00832
00833 #ifdef HAVE_DX8
00834 if (request_dxdisplay_information){
00835 DisplaySearchParameters display_search_parameters_dx8;
00836 int dx8_display_information (DisplaySearchParameters &display_search_parameters_dx8, DisplayInformation *display_information);
00837
00838 if (state == false && dx8_display_information (display_search_parameters_dx8, _display_information)) {
00839 state = true;
00840 }
00841 }
00842 #endif
00843
00844 if (auto_cpu_data) {
00845 lookup_cpu_data();
00846 }
00847
00848 OSVERSIONINFO version_info;
00849
00850 version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
00851 if (GetVersionEx (&version_info)) {
00852 sprintf (string, "OS version: %d.%d.%d.%d \n", version_info.dwMajorVersion, version_info.dwMinorVersion, version_info.dwPlatformId, version_info.dwBuildNumber);
00853 windisplay_cat.info() << string;
00854 windisplay_cat.info() << " " << version_info.szCSDVersion << "\n";
00855
00856 _display_information -> _os_version_major = version_info.dwMajorVersion;
00857 _display_information -> _os_version_minor = version_info.dwMinorVersion;
00858 _display_information -> _os_version_build = version_info.dwBuildNumber;
00859 _display_information -> _os_platform_id = version_info.dwPlatformId;
00860 }
00861
00862 _display_width = GetSystemMetrics(SM_CXSCREEN);
00863 _display_height = GetSystemMetrics(SM_CYSCREEN);
00864
00865 HMODULE power_dll;
00866
00867 power_dll = LoadLibrary ("PowrProf.dll");
00868 if (power_dll) {
00869 CallNtPowerInformationFunction = (CallNtPowerInformationType) GetProcAddress (power_dll, "CallNtPowerInformation");
00870 if (CallNtPowerInformationFunction) {
00871
00872 _display_information -> _update_cpu_frequency_function = update_cpu_frequency_function;
00873 update_cpu_frequency_function(0, _display_information);
00874
00875 sprintf (string, "max Mhz %I64d, current Mhz %I64d \n", _display_information -> _maximum_cpu_frequency, _display_information -> _current_cpu_frequency);
00876
00877 windisplay_cat.info() << string;
00878 }
00879 }
00880
00881 if (state) {
00882
00883 }
00884 }
00885
00886
00887
00888
00889
00890
00891
00892
00893 void WinGraphicsPipe::
00894 lookup_cpu_data() {
00895 char string [512];
00896
00897
00898 _display_information -> _get_memory_information_function = get_memory_information;
00899
00900
00901 _display_information -> _cpu_time_function = cpu_time_function;
00902
00903
00904 PN_uint64 time;
00905 PN_uint64 end_time;
00906 LARGE_INTEGER counter;
00907 LARGE_INTEGER end;
00908 LARGE_INTEGER frequency;
00909
00910 time = 0;
00911 end_time = 0;
00912 counter.QuadPart = 0;
00913 end.QuadPart = 0;
00914 frequency.QuadPart = 0;
00915
00916 int priority;
00917 HANDLE thread;
00918
00919 windisplay_cat.info() << "begin QueryPerformanceFrequency\n";
00920 thread = GetCurrentThread();
00921 priority = GetThreadPriority (thread);
00922 SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL);
00923
00924 if (QueryPerformanceFrequency(&frequency)) {
00925 if (frequency.QuadPart > 0) {
00926 if (QueryPerformanceCounter (&counter)) {
00927 time = cpu_time_function();
00928 end.QuadPart = counter.QuadPart + frequency.QuadPart;
00929 while (QueryPerformanceCounter (&counter) && counter.QuadPart < end.QuadPart) {
00930
00931 }
00932 end_time = cpu_time_function();
00933
00934 _display_information -> _cpu_frequency = end_time - time;
00935 }
00936 }
00937 }
00938
00939 SetThreadPriority(thread, priority);
00940 sprintf (string, "QueryPerformanceFrequency: %I64d\n", frequency.QuadPart);
00941 windisplay_cat.info() << string;
00942 sprintf (string, "CPU frequency: %I64d\n", _display_information -> _cpu_frequency);
00943 windisplay_cat.info() << string;
00944
00945
00946
00947 CPU_ID cpu_id;
00948
00949 windisplay_cat.info() << "start CPU ID\n";
00950
00951 if (initialize_cpu_id (&cpu_id)) {
00952 CPU_ID_BINARY_DATA *cpu_id_binary_data;
00953
00954 cpu_id_binary_data = new (CPU_ID_BINARY_DATA);
00955 if (cpu_id_binary_data) {
00956 cpu_id_to_cpu_id_binary_data (&cpu_id, cpu_id_binary_data);
00957 _display_information -> _cpu_id_size = sizeof (CPU_ID_BINARY_DATA) / sizeof (unsigned int);
00958 _display_information -> _cpu_id_data = (unsigned int *) cpu_id_binary_data;
00959
00960 _display_information -> _cpu_vendor_string = strdup(cpu_id.cpu_vendor);
00961 _display_information -> _cpu_brand_string = strdup(cpu_id.cpu_brand_string);
00962 _display_information -> _cpu_version_information = cpu_id.version_information;
00963 _display_information -> _cpu_brand_index = cpu_id.brand_index;
00964
00965 if (windisplay_cat.is_debug()) {
00966 windisplay_cat.debug()
00967 << hex << _display_information -> _cpu_id_version << dec << "|";
00968
00969 int index;
00970 for (index = 0; index < _display_information -> _cpu_id_size; index++) {
00971 unsigned int data;
00972
00973 data = _display_information -> _cpu_id_data [index];
00974
00975 windisplay_cat.debug(false)
00976 << hex << data << dec;
00977 if (index < (_display_information -> _cpu_id_size - 1)) {
00978 windisplay_cat.debug(false)
00979 << "|";
00980 }
00981 }
00982 windisplay_cat.debug(false)
00983 << "\n";
00984 }
00985 }
00986
00987 if (windisplay_cat.is_debug()) {
00988 parse_cpu_id (&cpu_id);
00989 }
00990 }
00991
00992 windisplay_cat.info() << "end CPU ID\n";
00993
00994
00995 count_number_of_cpus(_display_information);
00996 }
00997
00998
00999
01000
01001
01002
01003 WinGraphicsPipe::
01004 ~WinGraphicsPipe() {
01005 if (_hUser32 != NULL) {
01006 FreeLibrary(_hUser32);
01007 _hUser32 = NULL;
01008 }
01009 }
01010
01011 bool MyGetProcAddr(HINSTANCE hDLL, FARPROC *pFn, const char *szExportedFnName) {
01012 *pFn = (FARPROC) GetProcAddress(hDLL, szExportedFnName);
01013 if (*pFn == NULL) {
01014 windisplay_cat.error() << "GetProcAddr failed for " << szExportedFnName << ", error=" << GetLastError() <<endl;
01015 return false;
01016 }
01017 return true;
01018 }
01019
01020 bool MyLoadLib(HINSTANCE &hDLL, const char *DLLname) {
01021 hDLL = LoadLibrary(DLLname);
01022 if(hDLL == NULL) {
01023 windisplay_cat.error() << "LoadLibrary failed for " << DLLname << ", error=" << GetLastError() <<endl;
01024 return false;
01025 }
01026 return true;
01027 }