summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAaron Plattner <aplattner@nvidia.com>2013-07-01 08:51:18 -0700
committerAaron Plattner <aplattner@nvidia.com>2013-07-01 08:51:18 -0700
commitd5c86902432529996ef5ac12cb7721a18516b000 (patch)
tree713aaf2e33f153756fac7232e2ba192de82b8520
parentcd967db6d5dc839b9fe1cb797f54965674994802 (diff)
319.32319.32
-rw-r--r--doc/version.mk2
-rw-r--r--samples/version.mk2
-rw-r--r--src/gtk+-2.x/ctkcolorcontrols.c34
-rw-r--r--src/gtk+-2.x/ctkcolorcontrols.h1
-rw-r--r--src/gtk+-2.x/ctkditheringcontrols.c28
-rw-r--r--src/gtk+-2.x/ctkditheringcontrols.h2
-rw-r--r--src/gtk+-2.x/ctkevent.c3
-rw-r--r--src/gtk+-2.x/ctkpowermizer.c672
-rw-r--r--src/gtk+-2.x/ctkpowermizer.h8
-rw-r--r--src/libXNVCtrl/NVCtrl.h89
-rw-r--r--src/parse.c3
-rw-r--r--src/version.mk2
-rw-r--r--version.mk2
13 files changed, 667 insertions, 181 deletions
diff --git a/doc/version.mk b/doc/version.mk
index 6b57a0b..47298b6 100644
--- a/doc/version.mk
+++ b/doc/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 319.23
+NVIDIA_VERSION = 319.32
diff --git a/samples/version.mk b/samples/version.mk
index 6b57a0b..47298b6 100644
--- a/samples/version.mk
+++ b/samples/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 319.23
+NVIDIA_VERSION = 319.32
diff --git a/src/gtk+-2.x/ctkcolorcontrols.c b/src/gtk+-2.x/ctkcolorcontrols.c
index 97b5d87..913e0e7 100644
--- a/src/gtk+-2.x/ctkcolorcontrols.c
+++ b/src/gtk+-2.x/ctkcolorcontrols.c
@@ -35,6 +35,11 @@
#include "ctkdropdownmenu.h"
/* function prototypes */
+static void
+ctk_color_controls_class_init(CtkColorControlsClass *ctk_object_class);
+
+static void ctk_color_controls_finalize(GObject *object);
+
static gboolean build_color_space_table(CtkColorControls *ctk_color_controls,
NVCTRLAttributeValidValuesRec valid);
@@ -87,7 +92,7 @@ GType ctk_color_controls_get_type(void)
sizeof (CtkColorControlsClass),
NULL, /* base_init */
NULL, /* base_finalize */
- NULL, /* class_init, */
+ (GClassInitFunc) ctk_color_controls_class_init, /* class_init, */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (CtkColorControls),
@@ -105,6 +110,32 @@ GType ctk_color_controls_get_type(void)
return ctk_color_controls_type;
} /* ctk_color_controls_get_type() */
+
+
+static void
+ctk_color_controls_class_init(CtkColorControlsClass *ctk_object_class)
+{
+ GObjectClass *gobject_class = (GObjectClass *)ctk_object_class;
+ gobject_class->finalize = ctk_color_controls_finalize;
+}
+
+
+
+static void ctk_color_controls_finalize(GObject *object)
+{
+ CtkColorControls *ctk_object = CTK_COLOR_CONTROLS(object);
+
+ g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ (gpointer) ctk_object);
+}
+
+
+
GtkWidget* ctk_color_controls_new(NvCtrlAttributeHandle *handle,
CtkConfig *ctk_config,
CtkEvent *ctk_event,
@@ -141,6 +172,7 @@ GtkWidget* ctk_color_controls_new(NvCtrlAttributeHandle *handle,
ctk_color_controls = CTK_COLOR_CONTROLS(object);
ctk_color_controls->handle = handle;
ctk_color_controls->ctk_config = ctk_config;
+ ctk_color_controls->ctk_event = ctk_event;
ctk_color_controls->reset_button = reset_button;
ctk_color_controls->name = strdup(name);
diff --git a/src/gtk+-2.x/ctkcolorcontrols.h b/src/gtk+-2.x/ctkcolorcontrols.h
index cdfd233..8888af0 100644
--- a/src/gtk+-2.x/ctkcolorcontrols.h
+++ b/src/gtk+-2.x/ctkcolorcontrols.h
@@ -54,6 +54,7 @@ struct _CtkColorControls
NvCtrlAttributeHandle *handle;
CtkConfig *ctk_config;
+ CtkEvent *ctk_event;
GtkWidget *reset_button;
GtkWidget *color_controls_box;
diff --git a/src/gtk+-2.x/ctkditheringcontrols.c b/src/gtk+-2.x/ctkditheringcontrols.c
index f8204de..46431c9 100644
--- a/src/gtk+-2.x/ctkditheringcontrols.c
+++ b/src/gtk+-2.x/ctkditheringcontrols.c
@@ -35,6 +35,11 @@
#include "ctkdropdownmenu.h"
/* function prototypes */
+static void
+ctk_dither_controls_class_init(CtkDitheringControlsClass *ctk_object_class);
+
+static void ctk_dither_controls_finalize(GObject *object);
+
static gboolean build_dithering_mode_table(CtkDitheringControls *ctk_dithering_controls);
static gint map_nvctrl_value_to_table(CtkDitheringControls *ctk_dithering_controls,
@@ -107,7 +112,7 @@ GType ctk_dithering_controls_get_type(void)
sizeof (CtkDitheringControlsClass),
NULL, /* base_init */
NULL, /* base_finalize */
- NULL, /* class_init, */
+ (GClassInitFunc) ctk_dither_controls_class_init, /* class_init, */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (CtkDitheringControls),
@@ -125,6 +130,26 @@ GType ctk_dithering_controls_get_type(void)
return ctk_dithering_controls_type;
} /* ctk_dithering_controls_get_type() */
+static void
+ctk_dither_controls_class_init(CtkDitheringControlsClass *ctk_object_class)
+{
+ GObjectClass *gobject_class = (GObjectClass *)ctk_object_class;
+ gobject_class->finalize = ctk_dither_controls_finalize;
+}
+
+static void ctk_dither_controls_finalize(GObject *object)
+{
+ CtkDitheringControls *ctk_object = CTK_DITHERING_CONTROLS(object);
+
+ g_signal_handlers_disconnect_matched(G_OBJECT(ctk_object->ctk_event),
+ G_SIGNAL_MATCH_DATA,
+ 0,
+ 0,
+ NULL,
+ NULL,
+ (gpointer) ctk_object);
+}
+
GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
CtkConfig *ctk_config,
CtkEvent *ctk_event,
@@ -153,6 +178,7 @@ GtkWidget* ctk_dithering_controls_new(NvCtrlAttributeHandle *handle,
ctk_dithering_controls = CTK_DITHERING_CONTROLS(object);
ctk_dithering_controls->handle = handle;
+ ctk_dithering_controls->ctk_event = ctk_event;
ctk_dithering_controls->ctk_config = ctk_config;
ctk_dithering_controls->reset_button = reset_button;
ctk_dithering_controls->name = strdup(name);
diff --git a/src/gtk+-2.x/ctkditheringcontrols.h b/src/gtk+-2.x/ctkditheringcontrols.h
index f87ac9c..4cb00b8 100644
--- a/src/gtk+-2.x/ctkditheringcontrols.h
+++ b/src/gtk+-2.x/ctkditheringcontrols.h
@@ -57,6 +57,8 @@ struct _CtkDitheringControls
char *name;
GtkWidget *reset_button;
+ CtkEvent *ctk_event;
+
GtkWidget *dithering_controls_box;
GtkWidget *dithering_mode_box;
GtkWidget *dithering_depth_box;
diff --git a/src/gtk+-2.x/ctkevent.c b/src/gtk+-2.x/ctkevent.c
index 40054c0..0cc1cd1 100644
--- a/src/gtk+-2.x/ctkevent.c
+++ b/src/gtk+-2.x/ctkevent.c
@@ -326,6 +326,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
MAKE_SIGNAL(NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_IMMEDIATE);
MAKE_SIGNAL(NV_CTRL_GPU_DOUBLE_PRECISION_BOOST_REBOOT);
MAKE_SIGNAL(NV_CTRL_DPY_HDMI_3D);
+ MAKE_SIGNAL(NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE);
#undef MAKE_SIGNAL
/*
@@ -335,7 +336,7 @@ static void ctk_event_class_init(CtkEventClass *ctk_event_class)
* knows about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DPY_HDMI_3D
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE
#warning "There are attributes that do not emit signals!"
#endif
diff --git a/src/gtk+-2.x/ctkpowermizer.c b/src/gtk+-2.x/ctkpowermizer.c
index a900c5c..d4c8208 100644
--- a/src/gtk+-2.x/ctkpowermizer.c
+++ b/src/gtk+-2.x/ctkpowermizer.c
@@ -49,17 +49,6 @@ static void dp_configuration_update_received(GtkObject *, gpointer, gpointer);
static void post_dp_configuration_update(CtkPowermizer *);
static void show_dp_toggle_warning_dlg(CtkPowermizer *ctk_powermizer);
-typedef struct {
- const char *label;
- int attr;
-} PowerMizerMode;
-
-PowerMizerMode __powermizer_modes[] =
-{
- { "Adaptive", NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE },
- { "Prefer Maximum Performance", NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE },
-};
-
static const char *__adaptive_clock_help =
"The Adaptive Clocking status describes if this feature "
"is currently enabled in this GPU.";
@@ -97,11 +86,24 @@ static const char *__performance_levels_table_help =
static const char *__powermizer_menu_help =
"The Preferred Mode menu allows you to choose the preferred Performance "
"State for the GPU, provided the GPU has multiple Performance Levels. "
+"If a single X server is running, the mode selected in nvidia-settings is what "
+"the system will be using; if two or more X servers are running, the behavior "
+"is undefined. ";
+
+static const char *__powermizer_auto_mode_help =
+"'Auto' mode lets the driver choose the best Performance State for your GPU. ";
+
+static const char *__powermizer_adaptive_mode_help =
"'Adaptive' mode allows the GPU clocks to be adjusted based on GPU "
-"utilization. 'Prefer Maximum Performance' hints to the driver to prefer "
-"higher GPU clocks, when possible. If a single X server is running, the "
-"mode selected in nvidia-settings is what the system will be using; if two or "
-"more X servers are running, the behavior is undefined.";
+"utilization. ";
+
+static const char *__powermizer_prefer_maximum_performance_help =
+"'Prefer Maximum Performance' hints to the driver to prefer higher GPU clocks, "
+"when possible. ";
+
+static const char *__powermizer_prefer_consistent_performance_help =
+"'Prefer Consistent Performance' hints to the driver to lock to GPU base clocks, "
+"when possible. ";
static const char *__dp_configuration_button_help =
"CUDA - Double Precision lets you enable "
@@ -144,6 +146,12 @@ typedef struct {
gint nvclock;
gint memclock;
gint processorclock;
+ gint nvclockmin;
+ gint nvclockmax;
+ gint memclockmin;
+ gint memclockmax;
+ gint processorclockmin;
+ gint processorclockmax;
} perfModeEntry, * perfModeEntryPtr;
@@ -155,10 +163,22 @@ static void apply_perf_mode_token(char *token, char *value, void *data)
pEntry->perf_level = atoi(value);
} else if (!strcasecmp("nvclock", token)) {
pEntry->nvclock = atoi(value);
+ } else if (!strcasecmp("nvclockmin", token)) {
+ pEntry->nvclockmin = atoi(value);
+ } else if (!strcasecmp("nvclockmax", token)) {
+ pEntry->nvclockmax = atoi(value);
} else if (!strcasecmp("memclock", token)) {
pEntry->memclock = atoi(value);
+ } else if (!strcasecmp("memclockmin", token)) {
+ pEntry->memclockmin = atoi(value);
+ } else if (!strcasecmp("memclockmax", token)) {
+ pEntry->memclockmax = atoi(value);
} else if (!strcasecmp("processorclock", token)) {
pEntry->processorclock = atoi(value);
+ } else if (!strcasecmp("processorclockmin", token)) {
+ pEntry->processorclockmin = atoi(value);
+ } else if (!strcasecmp("processorclockmax", token)) {
+ pEntry->processorclockmax = atoi(value);
} else {
nv_warning_msg("Unknown Perf Mode token value pair: %s=%s",
token, value);
@@ -172,97 +192,322 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
GtkWidget *table;
GtkWidget *label;
char *perf_modes = NULL;
+ char *tmp_perf_modes = NULL;
char *tokens;
char tmp_str[24];
- perfModeEntry entry;
gint ret;
- gint row_idx; /* Where to insert into the perf mode table */
+ gint row_idx = 0; /* Where to insert into the perf mode table */
gboolean active;
+ GtkWidget *vsep;
+ perfModeEntryPtr pEntry = NULL;
+ perfModeEntryPtr tmpEntry = NULL;
+ gint index = 0;
+ gint i = 0;
+
+ /* Get the current list of perf levels */
+
+ ret = NvCtrlGetStringAttribute(ctk_powermizer->attribute_handle,
+ NV_CTRL_STRING_PERFORMANCE_MODES,
+ &perf_modes);
+
+ if (ret != NvCtrlSuccess) {
+ /* Bail */
+ return;
+ }
+
+ /* Calculate the number of rows we needed vseparator in the table */
+ tmp_perf_modes = g_strdup(perf_modes);
+ for (tokens = strtok(tmp_perf_modes, ";");
+ tokens;
+ tokens = strtok(NULL, ";")) {
+
+ tmpEntry = realloc(pEntry, sizeof(*pEntry) * (index + 1));
+
+ if (!tmpEntry) {
+ continue;
+ }
+ pEntry = tmpEntry;
+ tmpEntry = NULL;
+
+ /* Invalidate perf mode entry */
+ memset(pEntry + index, -1, sizeof(*pEntry));
+
+ parse_token_value_pairs(tokens, apply_perf_mode_token,
+ (void *) &pEntry[index]);
+
+ /* Only add complete perf mode entries */
+ if ((pEntry[index].perf_level != -1) &&
+ (pEntry[index].nvclockmax != -1) &&
+ (pEntry[index].memclockmax != -1)) {
+ /* Set hasDecoupledClocks flag to decide new/old clock
+ * interface to show.
+ */
+ if (!ctk_powermizer->hasDecoupledClock &&
+ ((pEntry[index].nvclockmax != pEntry[index].nvclockmin) ||
+ (pEntry[index].memclockmax != pEntry[index].memclockmin) ||
+ (pEntry[index].processorclockmax !=
+ pEntry[index].processorclockmin))) {
+ ctk_powermizer->hasDecoupledClock = TRUE;
+ }
+ row_idx++;
+ }
+ index++;
+ }
+ g_free(tmp_perf_modes);
/* Since table cell management in GTK lacks, just remove and rebuild
* the table from scratch.
*/
-
+
/* Dump out the old table */
ctk_empty_container(ctk_powermizer->performance_table_hbox);
/* Generate a new table */
- table = gtk_table_new(1, 4, FALSE);
- gtk_table_set_row_spacings(GTK_TABLE(table), 3);
- gtk_table_set_col_spacings(GTK_TABLE(table), 15);
- gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+ if (ctk_powermizer->hasDecoupledClock) {
+ table = gtk_table_new(2, 15, FALSE);
+ row_idx = row_idx + 3;
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 15);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
- gtk_box_pack_start(GTK_BOX(ctk_powermizer->performance_table_hbox),
- table, FALSE, FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(ctk_powermizer->performance_table_hbox),
+ table, FALSE, FALSE, 0);
- if (ctk_powermizer->performance_level) {
- label = gtk_label_new("Performance Level");
- gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
- gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
- GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- }
+ if (ctk_powermizer->performance_level) {
+ label = gtk_label_new("Level");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, 1, 2, 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+ }
- if (ctk_powermizer->gpu_clock && ctk_powermizer->memory_clock) {
- label = gtk_label_new("Graphics Clock");
- gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
- gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
- GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ if (ctk_powermizer->gpu_clock && ctk_powermizer->memory_clock) {
+ /* Graphics clock */
+ label = gtk_label_new("Graphics Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 2, 5, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Min");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Max");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 4, 5, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- label = gtk_label_new("Memory Clock");
- gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
- gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1,
- GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- }
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, 5, 6, 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+
+ /* Memory clock */
+ label = gtk_label_new("Memory Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 6, 9, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 6, 7, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Min");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 7, 8, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Max");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 8, 9, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, 9, 10, 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+ }
+ if (ctk_powermizer->processor_clock) {
+ /* Processor clock */
+ label = gtk_label_new("Processor Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 10, 11, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 11, 12, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Min");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 12, 13, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Max");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 13, 14, 1, 2,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ /* Vertical separator */
+ vsep = gtk_vseparator_new();
+ gtk_table_attach(GTK_TABLE(table), vsep, 14, 15, 0, row_idx,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 0, 0);
+ }
+ } else {
- if (ctk_powermizer->processor_clock) {
- label = gtk_label_new("Processor Clock");
- gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
- gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1,
- GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- }
- /* Get the current list of perf levels */
+ table = gtk_table_new(1, 4, FALSE);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 15);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
- ret = NvCtrlGetStringAttribute(ctk_powermizer->attribute_handle,
- NV_CTRL_STRING_PERFORMANCE_MODES,
- &perf_modes);
+ gtk_box_pack_start(GTK_BOX(ctk_powermizer->performance_table_hbox),
+ table, FALSE, FALSE, 0);
- if (ret != NvCtrlSuccess) {
- gtk_widget_show_all(table);
- /* Bail */
- return;
+ if (ctk_powermizer->performance_level) {
+ label = gtk_label_new("Performance Level");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+
+ if (ctk_powermizer->gpu_clock && ctk_powermizer->memory_clock) {
+ label = gtk_label_new("Graphics Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+
+ label = gtk_label_new("Memory Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 2, 3, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+
+ if (ctk_powermizer->processor_clock) {
+ label = gtk_label_new("Processor Clock");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 3, 4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
}
/* Parse the perf levels and populate the table */
+ row_idx = 0; //reset value used to calculate vseparator.
+ row_idx = 3;
+ for (i = 0; i < index; i++) {
+ /* Only add complete perf mode entries */
+ if (ctk_powermizer->hasDecoupledClock &&
+ (pEntry[i].perf_level != -1) &&
+ (pEntry[i].nvclockmax != -1) &&
+ (pEntry[i].memclockmax != -1)) {
- row_idx = 1;
- for (tokens = strtok(perf_modes, ";");
- tokens;
- tokens = strtok(NULL, ";")) {
+ active = (pEntry[i].perf_level == perf_level);
- /* Invalidate perf mode entry */
- entry.perf_level = -1;
- entry.nvclock = -1;
- entry.memclock = -1;
- entry.processorclock = -1;
-
- parse_token_value_pairs(tokens, apply_perf_mode_token,
- &entry);
-
- /* Only add complete perf mode entries */
- if ((entry.perf_level != -1) &&
- (entry.nvclock != -1) &&
- (entry.memclock != -1)) {
-
- active = (entry.perf_level == perf_level);
+ /* XXX Assume the perf levels are sorted by the server */
+
+ gtk_table_resize(GTK_TABLE(table), row_idx+1, 10);
+
+ if (ctk_powermizer->performance_level) {
+ g_snprintf(tmp_str, 24, "%d", pEntry[i].perf_level);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 0, 1,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+
+ if (ctk_powermizer->gpu_clock && ctk_powermizer->memory_clock) {
+ if (active) {
+ g_snprintf(tmp_str, 24, "%d MHz", ctk_powermizer->nvclock);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 2, 3,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].nvclockmin);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 3, 4,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].nvclockmax);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 4, 5,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+
+ if (active) {
+ g_snprintf(tmp_str, 24, "%d MHz", ctk_powermizer->memclock);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 6, 7,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].memclockmin);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 7, 8,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].memclockmax);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 8, 9,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+ if (ctk_powermizer->processor_clock) {
+ if (active) {
+ g_snprintf(tmp_str, 24, "%d MHz", ctk_powermizer->processorclock);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 11, 12, row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].processorclockmin);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 12, 13,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].processorclockmax);
+ label = gtk_label_new(tmp_str);
+ gtk_widget_set_sensitive(label, active);
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_table_attach(GTK_TABLE(table), label, 13, 14,
+ row_idx, row_idx+1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ }
+ row_idx++;
+ } else if ((pEntry[i].perf_level != -1) &&
+ (pEntry[i].nvclock != -1) &&
+ (pEntry[i].memclock != -1)) {
+
+ active = (pEntry[i].perf_level == perf_level);
/* XXX Assume the perf levels are sorted by the server */
- gtk_table_resize(GTK_TABLE(table), row_idx+1, 4);
+ gtk_table_resize(GTK_TABLE(table), row_idx+1, 10);
if (ctk_powermizer->performance_level) {
- g_snprintf(tmp_str, 24, "%d", entry.perf_level);
+ g_snprintf(tmp_str, 24, "%d", pEntry[i].perf_level);
label = gtk_label_new(tmp_str);
gtk_widget_set_sensitive(label, active);
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
@@ -272,7 +517,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
}
if (ctk_powermizer->gpu_clock && ctk_powermizer->memory_clock) {
- g_snprintf(tmp_str, 24, "%d MHz", entry.nvclock);
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].nvclock);
label = gtk_label_new(tmp_str);
gtk_widget_set_sensitive(label, active);
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
@@ -280,7 +525,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
row_idx, row_idx+1,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- g_snprintf(tmp_str, 24, "%d MHz", entry.memclock);
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].memclock);
label = gtk_label_new(tmp_str);
gtk_widget_set_sensitive(label, active);
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
@@ -289,7 +534,7 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
}
if (ctk_powermizer->processor_clock) {
- g_snprintf(tmp_str, 24, "%d MHz", entry.processorclock);
+ g_snprintf(tmp_str, 24, "%d MHz", pEntry[i].processorclock);
label = gtk_label_new(tmp_str);
gtk_widget_set_sensitive(label, active);
gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
@@ -300,14 +545,16 @@ static void update_perf_mode_table(CtkPowermizer *ctk_powermizer,
} else {
nv_warning_msg("Incomplete Perf Mode (perf=%d, nvclock=%d,"
" memclock=%d)",
- entry.perf_level, entry.nvclock,
- entry.memclock);
+ pEntry[i].perf_level, pEntry[i].nvclock,
+ pEntry[i].memclock);
}
}
gtk_widget_show_all(table);
XFree(perf_modes);
+ XFree(pEntry);
+ pEntry = NULL;
}
@@ -351,6 +598,9 @@ static gboolean update_powermizer_info(gpointer user_data)
memory_clock = clockret & 0x0000FFFF;
gpu_clock = (clockret >> 16);
+ ctk_powermizer->nvclock = gpu_clock;
+ ctk_powermizer->memclock = memory_clock;
+
s = g_strdup_printf("%d Mhz", gpu_clock);
gtk_label_set_text(GTK_LABEL(ctk_powermizer->gpu_clock), s);
g_free(s);
@@ -364,6 +614,7 @@ static gboolean update_powermizer_info(gpointer user_data)
NV_CTRL_GPU_CURRENT_PROCESSOR_CLOCK_FREQS,
&processor_clock);
if (ret == NvCtrlSuccess && ctk_powermizer->processor_clock) {
+ ctk_powermizer->processorclock = processor_clock;
s = g_strdup_printf("%d Mhz", processor_clock);
gtk_label_set_text(GTK_LABEL(ctk_powermizer->processor_clock), s);
g_free(s);
@@ -415,9 +666,83 @@ static gboolean update_powermizer_info(gpointer user_data)
update_perf_mode_table(ctk_powermizer, perf_level);
}
+ update_powermizer_menu_info(ctk_powermizer);
+
return TRUE;
}
+
+
+static gchar* get_powermizer_menu_label(const unsigned int val)
+{
+ gchar *label = NULL;
+
+ switch (val) {
+ case NV_CTRL_GPU_POWER_MIZER_MODE_AUTO:
+ label = g_strdup_printf("Auto");
+ break;
+ case NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE:
+ label = g_strdup_printf("Adaptive");
+ break;
+ case NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE:
+ label = g_strdup_printf("Prefer Maximum Performance");
+ break;
+ case NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE:
+ label = g_strdup_printf("Prefer Consistent Performance");
+ break;
+ default:
+ label = g_strdup_printf("");
+ break;
+ }
+
+ return label;
+}
+
+
+
+static gchar* get_powermizer_help_text(const unsigned int bit_mask)
+{
+ const gboolean bAuto =
+ bit_mask & (1 << NV_CTRL_GPU_POWER_MIZER_MODE_AUTO);
+ const gboolean bAdaptive =
+ bit_mask & (1 << NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE);
+ const gboolean bMaximum =
+ bit_mask & (1 << NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE);
+ const gboolean bConsistent =
+ bit_mask & (1 << NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE);
+
+ gchar *text = NULL;
+
+ text =
+ g_strdup_printf("%s%s%s%s%s",
+ __powermizer_menu_help,
+ bAuto ? __powermizer_auto_mode_help : "",
+ bAdaptive ? __powermizer_adaptive_mode_help : "",
+ bMaximum ? __powermizer_prefer_maximum_performance_help : "",
+ bConsistent ? __powermizer_prefer_consistent_performance_help : "");
+
+ return text;
+}
+
+
+static void create_powermizer_menu_entry(CtkDropDownMenu *menu,
+ const unsigned int bit_mask,
+ const unsigned int val)
+{
+ gchar *label;
+
+ if (!(bit_mask & (1 << val))) {
+ return;
+ }
+
+ label = get_powermizer_menu_label(val);
+
+ ctk_drop_down_menu_append_item(menu, label, val);
+ g_free(label);
+}
+
+
+
GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
CtkConfig *ctk_config,
CtkEvent *ctk_event)
@@ -433,7 +758,6 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
gint row = 0;
gchar *s = NULL;
gint tmp;
- gint i;
gboolean processor_clock_available = FALSE;
gboolean power_source_available = FALSE;
gboolean perf_level_available = FALSE;
@@ -441,11 +765,12 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
gboolean clock_freqs_available = FALSE;
gboolean cuda_dp_ui = FALSE;
gboolean pcie_gen_queriable = FALSE;
+ NVCTRLAttributeValidValuesRec valid_modes;
/* make sure we have a handle */
g_return_val_if_fail(handle != NULL, NULL);
-
+
/* check if this screen supports powermizer querying */
ret = NvCtrlGetAttribute(handle, NV_CTRL_GPU_POWER_SOURCE, &val);
@@ -483,7 +808,7 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
if (ret == NvCtrlSuccess) {
pcie_gen_queriable = TRUE;
}
-
+
/* return early if query to attributes fail */
if (!power_source_available && !perf_level_available &&
!adaptive_clock_state_available && clock_freqs_available &&
@@ -493,11 +818,12 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
/* create the CtkPowermizer object */
object = g_object_new(CTK_TYPE_POWERMIZER, NULL);
-
+
ctk_powermizer = CTK_POWERMIZER(object);
ctk_powermizer->attribute_handle = handle;
ctk_powermizer->ctk_config = ctk_config;
ctk_powermizer->pcie_gen_queriable = pcie_gen_queriable;
+ ctk_powermizer->hasDecoupledClock = FALSE;
/* set container properties for the CtkPowermizer widget */
@@ -687,7 +1013,7 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
s = g_strdup_printf("PowerMizer Monitor (GPU %d)",
NvCtrlGetTargetId(handle));
-
+
ctk_config_add_timer(ctk_powermizer->ctk_config,
DEFAULT_UPDATE_POWERMIZER_INFO_TIME_INTERVAL,
s,
@@ -697,65 +1023,103 @@ GtkWidget* ctk_powermizer_new(NvCtrlAttributeHandle *handle,
/* PowerMizer Settings */
- hbox = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+ ret = NvCtrlGetValidAttributeValues(ctk_powermizer->attribute_handle,
+ NV_CTRL_GPU_POWER_MIZER_MODE,
+ &valid_modes);
- vbox2 = gtk_vbox_new(FALSE, 5);
- gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
- ctk_powermizer->box_powermizer_menu = vbox2;
+ if ((ret == NvCtrlSuccess) &&
+ (valid_modes.type == ATTRIBUTE_TYPE_INT_BITS)) {
+ const unsigned int bit_mask = valid_modes.u.bits.ints;
- /* H-separator */
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
- hbox2 = gtk_hbox_new(FALSE, 0);
- gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
+ vbox2 = gtk_vbox_new(FALSE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox), vbox2, TRUE, TRUE, 0);
- label = gtk_label_new("PowerMizer Settings");
- gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
+ ctk_powermizer->box_powermizer_menu = vbox2;
- hsep = gtk_hseparator_new();
- gtk_box_pack_start(GTK_BOX(hbox2), hsep, TRUE, TRUE, 5);
+ /* H-separator */
- /* Specifying drop down list */
+ hbox2 = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(vbox2), hbox2, FALSE, FALSE, 0);
- menu = (CtkDropDownMenu *)
- ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+ label = gtk_label_new("PowerMizer Settings");
+ gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
- for (i=0; i < ARRAY_LEN(__powermizer_modes); i++) {
- ctk_drop_down_menu_append_item(menu, __powermizer_modes[i].label, i);
- }
+ hsep = gtk_hseparator_new();
+ gtk_box_pack_start(GTK_BOX(hbox2), hsep, TRUE, TRUE, 5);
+
+ /* Specifying drop down list */
+
+ menu = (CtkDropDownMenu *)
+ ctk_drop_down_menu_new(CTK_DROP_DOWN_MENU_FLAG_COMBO);
+
+ create_powermizer_menu_entry(
+ menu, bit_mask,
+ NV_CTRL_GPU_POWER_MIZER_MODE_AUTO);
+ create_powermizer_menu_entry(
+ menu, bit_mask,
+ NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE);
+ create_powermizer_menu_entry(
+ menu, bit_mask,
+ NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE);
+ create_powermizer_menu_entry(
+ menu, bit_mask,
+ NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE);
+
+ ctk_powermizer->powermizer_menu = GTK_WIDGET(menu);
+
+ g_signal_connect(G_OBJECT(ctk_powermizer->powermizer_menu), "changed",
+ G_CALLBACK(powermizer_menu_changed),
+ (gpointer) ctk_powermizer);
- ctk_powermizer->powermizer_menu = GTK_WIDGET(menu);
- update_powermizer_menu_info(ctk_powermizer);
+ ctk_powermizer->powermizer_menu_help =
+ get_powermizer_help_text(bit_mask);
- g_signal_connect(G_OBJECT(ctk_powermizer->powermizer_menu), "changed",
- G_CALLBACK(powermizer_menu_changed),
- (gpointer) ctk_powermizer);
+ ctk_config_set_tooltip(ctk_config,
+ ctk_powermizer->powermizer_menu,
+ ctk_powermizer->powermizer_menu_help);
+
+ /* Packing the drop down list */
+
+ table = gtk_table_new(1, 4, FALSE);
+ gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0);
+ gtk_table_set_row_spacings(GTK_TABLE(table), 3);
+ gtk_table_set_col_spacings(GTK_TABLE(table), 0);
+ gtk_container_set_border_width(GTK_CONTAINER(table), 5);
+
+ hbox2 = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Preferred Mode:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
- ctk_config_set_tooltip(ctk_config,
+ hbox2 = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox2, 1, 2, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ gtk_box_pack_start(GTK_BOX(hbox2),
ctk_powermizer->powermizer_menu,
- __powermizer_menu_help);
+ FALSE, FALSE, 0);
- /* Packing the drop down list */
+ hbox2 = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox2, 2, 3, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("Current Mode:");
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
- table = gtk_table_new(1, 2, FALSE);
- gtk_box_pack_start(GTK_BOX(vbox2), table, FALSE, FALSE, 0);
- gtk_table_set_row_spacings(GTK_TABLE(table), 3);
- gtk_table_set_col_spacings(GTK_TABLE(table), 15);
- gtk_container_set_border_width(GTK_CONTAINER(table), 5);
-
- hbox2 = gtk_hbox_new(FALSE, 0);
- gtk_table_attach(GTK_TABLE(table), hbox2, 0, 1, 0, 1,
- GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- label = gtk_label_new("Preferred Mode:");
- gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
- gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
-
- hbox2 = gtk_hbox_new(FALSE, 0);
- gtk_table_attach(GTK_TABLE(table), hbox2, 1, 2, 0, 1,
- GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
- gtk_box_pack_start(GTK_BOX(hbox2),
- ctk_powermizer->powermizer_menu,
- FALSE, FALSE, 0);
+ hbox2 = gtk_hbox_new(FALSE, 0);
+ gtk_table_attach(GTK_TABLE(table), hbox2, 3, 4, 0, 1,
+ GTK_FILL, GTK_FILL | GTK_EXPAND, 5, 0);
+ label = gtk_label_new("");
+ ctk_powermizer->powermizer_txt = label;
+ gtk_misc_set_alignment(GTK_MISC(label), 0.0f, 0.5f);
+ gtk_box_pack_start(GTK_BOX(hbox2), label, FALSE, FALSE, 0);
+
+ update_powermizer_menu_info(ctk_powermizer);
+ }
/*
* check if CUDA - Double Precision Boost support available.
@@ -883,30 +1247,41 @@ static void update_powermizer_menu_event(GtkObject *object,
static void update_powermizer_menu_info(gpointer user_data)
{
CtkPowermizer *ctk_powermizer = CTK_POWERMIZER(user_data);
- gint powerMizerMode = NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE;
- NVCTRLAttributeValidValuesRec valid;
- ReturnStatus ret0, ret1;
+ gint powerMizerMode, defaultPowerMizerMode, actualPowerMizerMode;
+
+ gchar* label;
+ ReturnStatus ret1, ret2;
CtkDropDownMenu *menu;
menu = CTK_DROP_DOWN_MENU(ctk_powermizer->powermizer_menu);
- ret0 = NvCtrlGetValidAttributeValues(ctk_powermizer->attribute_handle,
- NV_CTRL_GPU_POWER_MIZER_MODE,
- &valid);
-
ret1 = NvCtrlGetAttribute(ctk_powermizer->attribute_handle,
- NV_CTRL_GPU_POWER_MIZER_MODE,
- &powerMizerMode);
+ NV_CTRL_GPU_POWER_MIZER_MODE,
+ &powerMizerMode);
- if ((ret0 != NvCtrlSuccess) || (ret1 != NvCtrlSuccess)) {
+ ret2 = NvCtrlGetAttribute(ctk_powermizer->attribute_handle,
+ NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE,
+ &defaultPowerMizerMode);
+
+ if ((ret1 != NvCtrlSuccess) || (ret2 != NvCtrlSuccess)) {
gtk_widget_hide(ctk_powermizer->box_powermizer_menu);
} else {
g_signal_handlers_block_by_func(G_OBJECT(ctk_powermizer->powermizer_menu),
G_CALLBACK(powermizer_menu_changed),
(gpointer) ctk_powermizer);
+ if (powerMizerMode == NV_CTRL_GPU_POWER_MIZER_MODE_AUTO) {
+ actualPowerMizerMode = defaultPowerMizerMode;
+ } else {
+ actualPowerMizerMode = powerMizerMode;
+ }
+
ctk_drop_down_menu_set_current_value(menu, powerMizerMode);
+ label = get_powermizer_menu_label(actualPowerMizerMode);
+ gtk_label_set_text(GTK_LABEL(ctk_powermizer->powermizer_txt), label);
+ g_free(label);
+
g_signal_handlers_unblock_by_func(G_OBJECT(ctk_powermizer->powermizer_menu),
G_CALLBACK(powermizer_menu_changed),
(gpointer) ctk_powermizer);
@@ -919,23 +1294,28 @@ static void powermizer_menu_changed(GtkWidget *widget,
gpointer user_data)
{
CtkPowermizer *ctk_powermizer;
- gint history, powerMizerMode = NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE;
+ guint powerMizerMode;
CtkDropDownMenu *menu = CTK_DROP_DOWN_MENU(widget);
- ctk_powermizer = CTK_POWERMIZER(user_data);
+ const char *label = ctk_drop_down_menu_get_current_name(menu);
- history = ctk_drop_down_menu_get_current_value(menu);
+ ctk_powermizer = CTK_POWERMIZER(user_data);
- powerMizerMode = __powermizer_modes[history].attr;
+ powerMizerMode = ctk_drop_down_menu_get_current_value(menu);
if (NvCtrlSuccess != NvCtrlSetAttribute(ctk_powermizer->attribute_handle,
NV_CTRL_GPU_POWER_MIZER_MODE,
powerMizerMode)) {
+ ctk_config_statusbar_message(ctk_powermizer->ctk_config,
+ "Unable to set Preferred Mode to %s.",
+ label);
return;
}
ctk_config_statusbar_message(ctk_powermizer->ctk_config,
"Preferred Mode set to %s.",
- __powermizer_modes[history].label);
+ label);
+
+ update_powermizer_menu_info(user_data);
}
@@ -1153,7 +1533,7 @@ GtkTextBuffer *ctk_powermizer_create_help(GtkTextTagTable *table,
if (ctk_powermizer->powermizer_menu) {
ctk_help_heading(b, &i, "PowerMizer Settings");
- ctk_help_para(b, &i, __powermizer_menu_help);
+ ctk_help_para(b, &i, ctk_powermizer->powermizer_menu_help);
}
if (ctk_powermizer->configuration_button) {
diff --git a/src/gtk+-2.x/ctkpowermizer.h b/src/gtk+-2.x/ctkpowermizer.h
index adb179f..e1919e8 100644
--- a/src/gtk+-2.x/ctkpowermizer.h
+++ b/src/gtk+-2.x/ctkpowermizer.h
@@ -62,13 +62,19 @@ struct _CtkPowermizer
GtkWidget *performance_level;
GtkWidget *performance_table_hbox;
GtkWidget *powermizer_menu;
+ GtkWidget *powermizer_txt;
GtkWidget *box_powermizer_menu;
+ gchar *powermizer_menu_help;
+
GtkWidget *configuration_button;
gboolean dp_enabled;
gboolean dp_toggle_warning_dlg_shown;
+ gboolean hasDecoupledClock;
gint attribute;
- gchar *dp_enabled_string;
+ gint nvclock;
+ gint memclock;
+ gint processorclock;
GtkWidget *status;
GtkWidget *link_width;
diff --git a/src/libXNVCtrl/NVCtrl.h b/src/libXNVCtrl/NVCtrl.h
index 4933f49..0a7d8de 100644
--- a/src/libXNVCtrl/NVCtrl.h
+++ b/src/libXNVCtrl/NVCtrl.h
@@ -2679,16 +2679,21 @@
* NV_CTRL_GPU_POWER_MIZER_MODE - Provides a hint to the driver
* as to how to manage the performance of the GPU.
*
- * ADAPTIVE - adjust GPU clocks based on GPU
- * utilization
- * PREFER_MAXIMUM_PERFORMANCE - raise GPU clocks to favor
- * maximum performance, to the extent
- * that thermal and other constraints
- * allow
- */
-#define NV_CTRL_GPU_POWER_MIZER_MODE 334 /* RW-G */
-#define NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE 0
-#define NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE 1
+ * ADAPTIVE - adjust GPU clocks based on GPU
+ * utilization
+ * PREFER_MAXIMUM_PERFORMANCE - raise GPU clocks to favor
+ * maximum performance, to the extent
+ * that thermal and other constraints
+ * allow
+ * AUTO - let the driver choose the performance
+ * policy
+ * PREFER_CONSISTENT_PERFORMANCE - lock to GPU base clocks
+ */
+#define NV_CTRL_GPU_POWER_MIZER_MODE 334 /* RW-G */
+#define NV_CTRL_GPU_POWER_MIZER_MODE_ADAPTIVE 0
+#define NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_MAXIMUM_PERFORMANCE 1
+#define NV_CTRL_GPU_POWER_MIZER_MODE_AUTO 2
+#define NV_CTRL_GPU_POWER_MIZER_MODE_PREFER_CONSISTENT_PERFORMANCE 3
/*
* NV_CTRL_GVI_SYNC_OUTPUT_FORMAT - Returns the output sync signal
@@ -3267,7 +3272,13 @@
#define NV_CTRL_DPY_HDMI_3D_DISABLED 0
#define NV_CTRL_DPY_HDMI_3D_ENABLED 1
-#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_DPY_HDMI_3D
+/*
+ * NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE - Returns the default PowerMizer mode
+ * for the given GPU.
+ */
+#define NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE 400 /* R--G */
+
+#define NV_CTRL_LAST_ATTRIBUTE NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE
/**************************************************************************/
@@ -3652,20 +3663,37 @@
* NV_CTRL_STRING_PERFORMANCE_MODES - returns a string with all the
* performance modes defined for this GPU along with their associated
* NV Clock and Memory Clock values.
+ * Not all tokens will be reported on all GPUs, and additional tokens
+ * may be added in the future.
+ * For backwards compatibility we still provide nvclock, memclock, and
+ * processorclock those are the same as nvclockmin, memclockmin and
+ * processorclockmin.
*
* Each performance modes are returned as a comma-separated list of
* "token=value" pairs. Each set of performance mode tokens are separated
* by a ";". Valid tokens:
*
- * Token Value
- * "perf" integer - the Performance level
- * "nvclock" integer - the GPU clocks (in MHz) for the perf level
- * "memclock" integer - the memory clocks (in MHz) for the perf level
- *
+ * Token Value
+ * "perf" integer - the Performance level
+ * "nvclock" integer - the GPU clocks (in MHz) for the perf level
+ * "nvclockmin" integer - the GPU clocks min (in MHz) for the perf level
+ * "nvclockmax" integer - the GPU clocks max (in MHz) for the perf level
+ * "memclock" integer - the memory clocks (in MHz) for the perf level
+ * "memclockmin" integer - the memory clocks min (in MHz) for the perf level
+ * "memclockmax" integer - the memory clocks max (in MHz) for the perf level
+ * "processorclock" integer - the processor clocks (in MHz)
+ * for the perf level
+ * "processorclockmin" integer - the processor clocks min (in MHz)
+ * for the perf level
+ * "processorclockmax" integer - the processor clocks max (in MHz)
+ * for the perf level
*
* Example:
*
- * perf=0, nvclock=500, memclock=505 ; perf=1, nvclock=650, memclock=505
+ * perf=0, nvclock=324, nvclockmin=324, nvclockmax=324, memclock=324,
+ * memclockmin=324, memclockmax=324 ;
+ * perf=1, nvclock=324, nvclockmin=324, nvclockmax=640, memclock=810,
+ * memclockmin=810, memclockmax=810 ;
*
* This attribute may be queried through XNVCTRLQueryTargetStringAttribute()
* using a NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
@@ -3777,7 +3805,9 @@
* NV_CTRL_STRING_GPU_CURRENT_CLOCK_FREQS - returns a string with the
* associated NV Clock, Memory Clock and Processor Clock values.
*
- * Current valid tokens are "nvclock", "memclock", and "processorclock".
+ * Current valid tokens are "nvclock", "nvclockmin", "nvclockmax",
+ * "memclock", "memclockmin", "memclockmax", "processorclock",
+ * "processorclockmin" and "processorclockmax".
* Not all tokens will be reported on all GPUs, and additional tokens
* may be added in the future.
*
@@ -3785,17 +3815,24 @@
* "token=value" pairs.
* Valid tokens:
*
- * Token Value
- * "nvclock" integer - the GPU clocks (in MHz) for the current
- * perf level
- * "memclock" integer - the memory clocks (in MHz) for the current
- * perf level
- * "processorclock" integer - the processor clocks (in MHz) for the perf level
- *
+ * Token Value
+ * "nvclock" integer - the GPU clocks (in MHz) for the perf level
+ * "nvclockmin" integer - the GPU clocks min (in MHz) for the perf level
+ * "nvclockmax" integer - the GPU clocks max (in MHz) for the perf level
+ * "memclock" integer - the memory clocks (in MHz) for the perf level
+ * "memclockmin" integer - the memory clocks min (in MHz) for the perf level
+ * "memclockmax" integer - the memory clocks (max in MHz) for the perf level
+ * "processorclock" integer - the processor clocks (in MHz)
+ * for the perf level
+ * "processorclockmin" integer - the processor clocks min (in MHz)
+ * for the perf level
+ * "processorclockmax" integer - the processor clocks max (in MHz)
+ * for the perf level
*
* Example:
*
- * nvclock=459, memclock=400, processorclock=918
+ * nvclock=324, nvclockmin=324, nvclockmax=324,
+ * memclock=324, memclockmin=324, memclockmax=324
*
* This attribute may be queried through XNVCTRLQueryTargetStringAttribute()
* using an NV_CTRL_TARGET_TYPE_GPU or NV_CTRL_TARGET_TYPE_X_SCREEN target.
diff --git a/src/parse.c b/src/parse.c
index 4e83e97..c547abc 100644
--- a/src/parse.c
+++ b/src/parse.c
@@ -165,6 +165,7 @@ const AttributeTableEntry attributeTable[] = {
{ "GPUAdaptiveClockState", NV_CTRL_GPU_ADAPTIVE_CLOCK_STATE, N, "Reports if Adaptive Clocking is Enabled on the GPU driving the X screen." },
{ "GPUPerfModes", NV_CTRL_STRING_PERFORMANCE_MODES, S|N, "Returns a string with all the performance modes defined for this GPU along with their associated NV Clock and Memory Clock values." },
{ "GPUPowerMizerMode", NV_CTRL_GPU_POWER_MIZER_MODE, 0, "Allows setting different GPU powermizer modes." },
+ { "GPUPowerMizerDefaultMode", NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE, N, "Reports the default powermizer mode of the GPU, if any." },
{ "ECCSupported", NV_CTRL_GPU_ECC_SUPPORTED, N, "Reports whether the underlying GPU supports ECC. All of the other ECC attributes are only applicable if this attribute indicates that ECC is supported." },
{ "ECCStatus", NV_CTRL_GPU_ECC_STATUS, N, "Reports whether ECC is enabled." },
{ "ECCConfigurationSupported", NV_CTRL_GPU_ECC_CONFIGURATION_SUPPORTED, N, "Reports whether ECC whether the ECC configuration setting can be changed." },
@@ -368,7 +369,7 @@ const AttributeTableEntry attributeTable[] = {
* about.
*/
-#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_DPY_HDMI_3D
+#if NV_CTRL_LAST_ATTRIBUTE != NV_CTRL_GPU_POWER_MIZER_DEFAULT_MODE
#warning "Have you forgotten to add a new integer attribute to attributeTable?"
#endif
diff --git a/src/version.mk b/src/version.mk
index 6b57a0b..47298b6 100644
--- a/src/version.mk
+++ b/src/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 319.23
+NVIDIA_VERSION = 319.32
diff --git a/version.mk b/version.mk
index 6b57a0b..47298b6 100644
--- a/version.mk
+++ b/version.mk
@@ -1 +1 @@
-NVIDIA_VERSION = 319.23
+NVIDIA_VERSION = 319.32