Reintroduce display mode information in Windows via Win32 API

Also clean up the CPUID code in winGraphicsPipe a bit
This commit is contained in:
rdb 2015-07-19 21:11:43 +02:00
parent 23441aa5bb
commit e515cbdbd1
3 changed files with 353 additions and 396 deletions

View File

@ -15,6 +15,48 @@
#include "graphicsStateGuardian.h"
#include "displayInformation.h"
////////////////////////////////////////////////////////////////////
// Function: DisplayMode::Comparison Operator
// Access: Published
// Description: Returns true if these two DisplayModes are identical.
////////////////////////////////////////////////////////////////////
bool DisplayMode::
operator == (const DisplayMode &other) const {
return (width == other.width && height == other.height &&
bits_per_pixel == other.bits_per_pixel &&
refresh_rate == other.refresh_rate &&
fullscreen_only == other.fullscreen_only);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayMode::Comparison Operator
// Access: Published
// Description: Returns false if these two DisplayModes are identical.
////////////////////////////////////////////////////////////////////
bool DisplayMode::
operator != (const DisplayMode &other) const {
return !operator == (other);
}
////////////////////////////////////////////////////////////////////
// Function: DisplayMode::output
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void DisplayMode::
output(ostream &out) const {
out << width << 'x' << height;
if (bits_per_pixel > 0) {
out << ' ' << bits_per_pixel << "bpp";
}
if (refresh_rate > 0) {
out << ' ' << refresh_rate << "Hz";
}
if (fullscreen_only > 0) {
out << " (fullscreen only)";
}
}
////////////////////////////////////////////////////////////////////
// Function: DisplayInformation::Destructor
// Access: Published
@ -181,6 +223,21 @@ get_total_display_modes() {
return _total_display_modes;
}
////////////////////////////////////////////////////////////////////
// Function: DisplayInformation::get_display_mode
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
const DisplayMode &DisplayInformation::
get_display_mode(int display_index) {
#ifndef NDEBUG
static DisplayMode err_mode = {0};
nassertr(display_index >= 0 && display_index < _total_display_modes, err_mode);
#endif
return _display_mode_array[display_index];
}
////////////////////////////////////////////////////////////////////
// Function: DisplayInformation::get_display_mode_width
// Access: Published

View File

@ -17,24 +17,25 @@
#include "typedef.h"
typedef struct {
struct EXPCL_PANDA_DISPLAY DisplayMode {
PUBLISHED:
int width;
int height;
int bits_per_pixel;
int refresh_rate;
int fullscreen_only;
}
DisplayMode;
bool operator == (const DisplayMode &other) const;
bool operator != (const DisplayMode &other) const;
void output(ostream &out) const;
};
////////////////////////////////////////////////////////////////////
// Class : DisplayInformation
// Description : This class contains various display information.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA_DISPLAY DisplayInformation {
PUBLISHED:
enum DetectionState {
DS_unknown,
DS_success,
@ -54,6 +55,10 @@ PUBLISHED:
int get_window_bits_per_pixel();
int get_total_display_modes();
const DisplayMode &get_display_mode(int display_index);
MAKE_SEQ(get_display_modes, get_total_display_modes, get_display_mode);
// Older interface for display modes.
int get_display_mode_width(int display_index);
int get_display_mode_height(int display_index);
int get_display_mode_bits_per_pixel(int display_index);

View File

@ -15,6 +15,7 @@
#include "winGraphicsPipe.h"
#include "config_windisplay.h"
#include "displaySearchParameters.h"
#include "displayInformation.h"
#include "dtool_config.h"
#include "pbitops.h"
@ -52,8 +53,7 @@ static GetProcessMemoryInfoType GetProcessMemoryInfoFunction = 0;
static GlobalMemoryStatusExType GlobalMemoryStatusExFunction = 0;
static CallNtPowerInformationType CallNtPowerInformationFunction = 0;
void get_memory_information (DisplayInformation *display_information)
{
void get_memory_information (DisplayInformation *display_information) {
if (initialize == false) {
psapi_dll = LoadLibrary("psapi.dll");
if (psapi_dll) {
@ -81,8 +81,7 @@ void get_memory_information (DisplayInformation *display_information)
display_information->_available_process_virtual_memory = memory_status.ullAvailVirtual;
display_information->_memory_load = memory_status.dwMemoryLoad;
}
}
else {
} else {
MEMORYSTATUS memory_status;
memory_status.dwLength = sizeof(MEMORYSTATUS);
@ -118,8 +117,7 @@ void get_memory_information (DisplayInformation *display_information)
}
}
typedef union
{
typedef union {
PN_uint64 long_integer;
}
LONG_INTEGER;
@ -133,8 +131,7 @@ PN_uint64 cpu_time_function (void) {
long_integer_pointer = &long_integer;
__asm
{
__asm {
mov ebx,[long_integer_pointer]
rdtsc
mov [ebx + 0], eax
@ -145,14 +142,10 @@ PN_uint64 cpu_time_function (void) {
#endif
}
typedef union
{
struct
{
union
{
struct
{
typedef union {
struct {
union {
struct {
unsigned char al;
unsigned char ah;
};
@ -162,15 +155,11 @@ typedef union
unsigned int ecx;
unsigned int edx;
};
}
CPU_ID_REGISTERS;
} CPU_ID_REGISTERS;
typedef struct
{
union
{
struct
{
typedef struct {
union {
struct {
int maximum_cpu_id_input;
char cpu_vendor [16];
};
@ -178,19 +167,15 @@ typedef struct
CPU_ID_REGISTERS cpu_id_registers_0;
};
union
{
union {
CPU_ID_REGISTERS cpu_id_registers_1;
struct
{
struct {
// eax
union
{
union {
unsigned int eax;
unsigned int version_information;
struct
{
struct {
unsigned int stepping_id : 4;
unsigned int model : 4;
unsigned int family : 4;
@ -203,11 +188,9 @@ typedef struct
};
// ebx
union
{
union {
unsigned int ebx;
struct
{
struct {
unsigned int brand_index : 8;
unsigned int clflush : 8;
unsigned int maximum_logical_processors : 8;
@ -216,11 +199,9 @@ typedef struct
};
// ecx
union
{
union {
unsigned int ecx;
struct
{
struct {
unsigned int sse3 : 1;
unsigned int reserved_1_to_2 : 2;
unsigned int monitor : 1;
@ -239,11 +220,9 @@ typedef struct
};
// edx
union
{
union {
unsigned int edx;
struct
{
struct {
unsigned int fpu : 1;
unsigned int vme : 1;
unsigned int de : 1;
@ -284,69 +263,45 @@ typedef struct
#define MAXIMUM_2 8
#define MAXIMUM_CHARACTERS (MAXIMUM_2 * sizeof(CPU_ID_REGISTERS))
union
{
union {
CPU_ID_REGISTERS cpu_id_registers_2;
unsigned char character_array_2 [MAXIMUM_CHARACTERS];
CPU_ID_REGISTERS cpu_id_registers_2_array [MAXIMUM_2];
};
union
{
union {
CPU_ID_REGISTERS cpu_id_registers_0x80000000;
};
union
{
union {
CPU_ID_REGISTERS cpu_id_registers_0x80000001;
};
union
{
union {
char cpu_brand_string [sizeof(CPU_ID_REGISTERS) * 3];
struct
{
struct {
CPU_ID_REGISTERS cpu_id_registers_0x80000002;
CPU_ID_REGISTERS cpu_id_registers_0x80000003;
CPU_ID_REGISTERS cpu_id_registers_0x80000004;
};
};
union
{
struct
{
// eax
union
{
union {
struct {
unsigned int eax;
};
// ebx
union
{
unsigned int ebx;
};
// ecx
union
{
union {
unsigned int ecx;
struct
{
struct {
unsigned int l1_data_cache_line_size : 8;
unsigned int l1_data_reserved_8_to_15 : 8;
unsigned int l1_data_associativity : 8;
unsigned int l1_data_cache_size : 8;
};
};
// edx
union
{
union {
unsigned int edx;
struct
{
struct {
unsigned int l1_code_cache_line_size : 8;
unsigned int l1_code_reserved_8_to_15 : 8;
unsigned int l1_code_associativity : 8;
@ -357,82 +312,31 @@ typedef struct
CPU_ID_REGISTERS cpu_id_registers_0x80000005;
};
union
{
struct
{
// eax
union
{
union {
struct {
unsigned int eax;
};
// ebx
union
{
unsigned int ebx;
};
// ecx
union
{
union {
unsigned int ecx;
struct
{
struct {
unsigned int l2_cache_line_size : 8;
unsigned int l2_reserved_8_to_11 : 4;
unsigned int l2_associativity : 4;
unsigned int l2_cache_size : 16;
};
};
// edx
union
{
unsigned int edx;
};
};
CPU_ID_REGISTERS cpu_id_registers_0x80000006;
};
union
{
struct
{
// eax
union
{
unsigned int eax;
};
// ebx
union
{
unsigned int ebx;
};
// ecx
union
{
unsigned int ecx;
};
// edx
union
{
unsigned int edx;
};
};
CPU_ID_REGISTERS cpu_id_registers_0x80000008;
};
unsigned int cache_line_size;
unsigned int log_base_2_cache_line_size;
}
CPU_ID;
} CPU_ID;
typedef struct
{
typedef struct {
CPU_ID_REGISTERS cpu_id_registers_0;
CPU_ID_REGISTERS cpu_id_registers_1;
@ -445,21 +349,9 @@ typedef struct
CPU_ID_REGISTERS cpu_id_registers_0x80000006;
CPU_ID_REGISTERS cpu_id_registers_0x80000008;
}
CPU_ID_BINARY_DATA;
typedef struct
{
union
{
CPU_ID_BINARY_DATA cpu_binary_data;
unsigned int data_array [sizeof (CPU_ID_BINARY_DATA) / 4];
};
}
CPU_ID_BINARY_DATA_ARRAY;
} CPU_ID_BINARY_DATA;
void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_binary_data) {
cpu_id_binary_data->cpu_id_registers_0 = cpu_id->cpu_id_registers_0;
cpu_id_binary_data->cpu_id_registers_1 = cpu_id->cpu_id_registers_1;
cpu_id_binary_data->cpu_id_registers_0x80000000 = cpu_id->cpu_id_registers_0x80000000;
@ -472,7 +364,6 @@ void cpu_id_to_cpu_id_binary_data (CPU_ID *cpu_id, CPU_ID_BINARY_DATA *cpu_id_bi
}
void cpu_id_binary_data_to_cpu_id (CPU_ID_BINARY_DATA *cpu_id_binary_data, CPU_ID *cpu_id) {
memset (cpu_id, 0, sizeof(CPU_ID));
cpu_id->cpu_id_registers_0 = cpu_id_binary_data->cpu_id_registers_0;
@ -490,8 +381,7 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
int state;
state = false;
__try
{
__try {
if (input_eax == 0) {
// the order of ecx and edx is swapped when saved to make a proper vendor string
#ifdef _WIN64
@ -500,8 +390,7 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
cpu_id_registers->edx = cpu_id_registers->ecx;
cpu_id_registers->ecx = tmp;
#else
__asm
{
__asm {
mov eax, [input_eax]
mov edi, [cpu_id_registers]
@ -513,13 +402,11 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
mov [edi + 12], ecx
}
#endif
}
else {
} else {
#ifdef _WIN64
__cpuid((int*)cpu_id_registers, input_eax);
#else
__asm
{
__asm {
mov eax, [input_eax]
mov edi, [cpu_id_registers]
@ -535,8 +422,7 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
state = true;
}
__except (1)
{
__except (1) {
state = false;
}
@ -544,7 +430,6 @@ int cpuid (int input_eax, CPU_ID_REGISTERS *cpu_id_registers) {
}
void parse_cpu_id(CPU_ID *cpu_id) {
printf("CPUID\n");
printf(" vendor = %s\n", cpu_id->cpu_vendor);
printf(" brand string %s\n", cpu_id->cpu_brand_string);
@ -594,12 +479,7 @@ void parse_cpu_id (CPU_ID *cpu_id) {
}
int initialize_cpu_id(CPU_ID *cpu_id) {
int state;
int debug;
state = false;
debug = false;
int debug = false;
memset(cpu_id, 0, sizeof(CPU_ID));
if (cpuid(0, &cpu_id->cpu_id_registers_0)) {
@ -623,8 +503,7 @@ int initialize_cpu_id (CPU_ID *cpu_id) {
if (debug) {
printf(" cache/TLB byte = %X\n", cpu_id->character_array_2 [index]);
}
switch (cpu_id -> character_array_2 [index])
{
switch (cpu_id->character_array_2 [index]) {
case 0x0A:
case 0x0C:
cpu_id->cache_line_size = 32;
@ -668,14 +547,13 @@ int initialize_cpu_id (CPU_ID *cpu_id) {
cpuid(0x80000008, &cpu_id->cpu_id_registers_0x80000008);
}
state = true;
return true;
}
return state;
return false;
}
int update_cpu_frequency_function (int processor_number, DisplayInformation *display_information)
{
int update_cpu_frequency_function(int processor_number, DisplayInformation *display_information) {
int update;
update = false;
@ -801,11 +679,8 @@ count_number_of_cpus(DisplayInformation *display_information) {
////////////////////////////////////////////////////////////////////
WinGraphicsPipe::
WinGraphicsPipe() {
bool state;
char string [512];
state = false;
_supported_types = OT_window | OT_fullscreen_window;
// these fns arent defined on win95, so get dynamic ptrs to them
@ -819,15 +694,38 @@ WinGraphicsPipe() {
}
#ifdef HAVE_DX9
// Use D3D to get display info. This is disabled by default as it is slow.
if (request_dxdisplay_information) {
DisplaySearchParameters display_search_parameters_dx9;
int dx9_display_information (DisplaySearchParameters &display_search_parameters_dx9, DisplayInformation *display_information);
if (state == false && dx9_display_information (display_search_parameters_dx9, _display_information)) {
state = true;
}
}
dx9_display_information(display_search_parameters_dx9, _display_information);
} else
#endif
{
// Use the Win32 API to query the available display modes.
pvector<DisplayMode> display_modes;
DEVMODE dm = {0};
dm.dmSize = sizeof(dm);
for (int i = 0; EnumDisplaySettings(NULL, i, &dm) != 0; ++i) {
DisplayMode mode;
mode.width = dm.dmPelsWidth;
mode.height = dm.dmPelsHeight;
mode.bits_per_pixel = dm.dmBitsPerPel;
mode.refresh_rate = dm.dmDisplayFrequency;
mode.fullscreen_only = 0;
if (i == 0 || mode != display_modes.back()) {
display_modes.push_back(mode);
}
}
// Copy this information to the DisplayInformation object.
_display_information->_total_display_modes = display_modes.size();
if (!display_modes.empty()) {
_display_information->_display_mode_array = new DisplayMode[display_modes.size()];
std::copy(display_modes.begin(), display_modes.end(),
_display_information->_display_mode_array);
}
}
if (auto_cpu_data) {
lookup_cpu_data();
@ -837,9 +735,11 @@ WinGraphicsPipe() {
version_info.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
if (GetVersionEx(&version_info)) {
if (windisplay_cat.is_info()) {
sprintf(string, "OS version: %d.%d.%d.%d\n", version_info.dwMajorVersion, version_info.dwMinorVersion, version_info.dwPlatformId, version_info.dwBuildNumber);
windisplay_cat.info() << string;
windisplay_cat.info() << " " << version_info.szCSDVersion << "\n";
}
_display_information->_os_version_major = version_info.dwMajorVersion;
_display_information->_os_version_minor = version_info.dwMinorVersion;
@ -865,10 +765,6 @@ WinGraphicsPipe() {
windisplay_cat.info() << string;
}
}
if (state) {
}
}
////////////////////////////////////////////////////////////////////
@ -955,14 +851,13 @@ lookup_cpu_data() {
<< hex << _display_information->_cpu_id_version << dec << "|";
int index;
for (index = 0; index < _display_information -> _cpu_id_size; index++) {
for (index = 0; index < _display_information->_cpu_id_size; ++index) {
unsigned int data;
data = _display_information->_cpu_id_data[index];
windisplay_cat.debug(false)
<< hex << data << dec;
if (index < (_display_information -> _cpu_id_size - 1)) {
if (index < _display_information->_cpu_id_size - 1) {
windisplay_cat.debug(false)
<< "|";
}