void XNVCTRLSetAttribute ( Display *dpy, int screen, unsigned int display_mask, unsigned int attribute, int value ) { XNVCTRLSetTargetAttribute (dpy, NV_CTRL_TARGET_TYPE_X_SCREEN, screen, display_mask, attribute, value); }
// List the configuration space of the GVI device. void do_listconfig(Display *dpy, int gvi) { NVCTRLAttributeValidValuesRec values; unsigned int fmts[3]; int i; char *pOut = NULL; Bool ret; // Assume GVI device has been configured already. if (gvi < 0) { gvi = 0; } printf("Querying Valid Configuring Space of GVI device %d:\n\n", gvi); /* Query stream (link to jack+channel) topology */ ret = XNVCTRLStringOperation(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, // target_id 0, // display_mask NV_CTRL_STRING_OPERATION_GVI_CONFIGURE_STREAMS, NULL, // pIn &pOut); if (!ret || !pOut) { printf(" - Failed to query stream topology configuration of " "GVI %d.\n", gvi); return; } printf("- Current Topology:\n\n"); printf(" %s\n\n", pOut ? pOut : "No streams are configured."); XFree(pOut); pOut = NULL; ret = XNVCTRLQueryValidTargetAttributeValues(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // display_mask NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, &values); if (!ret) { printf("- Failed to query valid video format values(1) of " "GVI %d.\n", gvi); return; } fmts[0] = values.u.bits.ints; ret = XNVCTRLQueryValidTargetAttributeValues(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // display_mask NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2, &values); if (!ret) { printf("- Failed to query valid video format values(2) of " "GVI %d.\n", gvi); return; } fmts[1] = values.u.bits.ints; ret = XNVCTRLQueryValidTargetAttributeValues(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // display_mask NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3, &values); if (!ret) { printf("- Failed to query valid video format values(3) of " "GVI %d.\n", gvi); return; } fmts[2] = values.u.bits.ints; printf("- Valid Formats (NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT): %08x\n", fmts[0]); printf("- Valid Formats (NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT2): %08x\n", fmts[1]); printf("- Valid Formats (NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT3): %08x\n", fmts[2]); printf("\n"); for (i = 0; i < 3; i++) { unsigned int fmt_list = fmts[i]; unsigned int fmt_bit; unsigned int fmt; unsigned int fmt_flags; unsigned int bpcs; unsigned int bpc_bit; unsigned int bpc; unsigned int samplings; unsigned int smp_bit; unsigned int sampling; while (fmt_list) { fmt_bit = firstbit(fmt_list); fmt_list &= (~fmt_bit); fmt = ffs(fmt_bit) - 1 + (32*i); printf("\n%s", VideoFormatName(fmt)); ret = XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, fmt, // display_mask NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS, (int *)&fmt_flags); if (!ret) { printf(" - Failed to query flag bits for video format for " "GVI %d.\n", gvi); } else if (fmt_flags == NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_NONE) { printf(" (No flags set): \n"); } else { printf(" (Flags:"); printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_INTERLACED) ? 'I' : '_'); printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PROGRESSIVE) ? 'P' : '_'); printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_PSF) ? 'F' : '_'); printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_A) ? 'A' : '_'); printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_LEVEL_B) ? 'B' : '_'); printf("%c", (fmt_flags & NV_CTRL_GVIO_VIDEO_FORMAT_FLAGS_3G_1080P_NO_12BPC) ? 'N' : '_'); printf("):\n"); } // Set the video format XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // display_mask NV_CTRL_GVIO_REQUESTED_VIDEO_FORMAT, fmt); // Get all bits per component (on first jack/channel) ret = XNVCTRLQueryValidTargetAttributeValues(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // jack 0, channel 0 NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT, &values); if (!ret) { printf(" - Failed to query valid bits per component " "of GVI %d.\n", gvi); continue; } bpcs = values.u.bits.ints; while (bpcs) { bpc_bit = firstbit(bpcs); bpcs &= (~bpc_bit); bpc = ffs(bpc_bit) -1; printf(" %s:\n", BPCName(bpc)); // Set the bits per component XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // jack 0, channel 0 NV_CTRL_GVI_REQUESTED_STREAM_BITS_PER_COMPONENT, bpc); // Get all component samplings (on first jack/channel) ret = XNVCTRLQueryValidTargetAttributeValues(dpy, NV_CTRL_TARGET_TYPE_GVI, gvi, 0, // display_mask NV_CTRL_GVI_REQUESTED_STREAM_COMPONENT_SAMPLING, &values); if (!ret) { printf(" - Failed to query valid component sampling " "values of GVI %d.\n", gvi); continue; } samplings = values.u.bits.ints; while (samplings) { smp_bit = firstbit(samplings); samplings &= (~smp_bit); sampling = ffs(smp_bit) -1; printf(" %s\n", SamplingName(sampling)); } // All component samplings } // Add BPC } // All formats } // All format lists } /* do_listconfig() */
/* * do_enable() * * Enables frame lock on the X Server by setting the first capable/available * display device as the frame lock server (master) and setting all other * display devices as clients (slaves). * * NOTE: It is up to the user to ensure that each display device is set with * the same refresh rate (mode timings). * */ static void do_enable(Display *dpy) { Bool ret; int num_framelocks; int framelock; int gpu; unsigned int mask; int *data; int len; int i; int enabled; int masterable; int pick_server = 1; int server_set = 0; /* Query the number of frame lock devices to enable */ ret = XNVCTRLQueryTargetCount(dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK, &num_framelocks); if (!ret) { printf("Failed to query number of frame lock devices!\n"); return; } printf("Found %d frame lock device(s) on server.\n", num_framelocks); if ( !num_framelocks ) { return; } /* Enable frame lock on all GPUs connected to each frame lock device */ for (framelock = 0; framelock < num_framelocks; framelock++) { printf("\n"); printf("- Frame Lock Board %d :\n", framelock); /* Query the GPUs connected to this frame lock device */ ret = XNVCTRLQueryTargetBinaryData (dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK, framelock, // target_id 0, // display_mask NV_CTRL_BINARY_DATA_GPUS_USING_FRAMELOCK, (unsigned char **) &data, &len); if (!ret) { printf(" - Failed to query list of GPUs!\n"); continue; } /* Enable frame lock on all GPUs connected to the frame lock device */ if ( !data[0] ) { printf(" - No GPUs found!\n"); } else { printf(" - Found %d GPU(s).\n", data[0]); } for (i = 1; i <= data[0]; i++) { gpu = data[i]; printf(" - Enabling G-Sync Device %d - GPU %d... ", framelock, gpu); /* Make sure frame lock is disabled */ XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_SYNC, &enabled); if (enabled != NV_CTRL_FRAMELOCK_SYNC_DISABLE) { printf("Frame lock already enabled!\n"); continue; } /* Get the list of displays to enable */ ret = XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_ENABLED_DISPLAYS, (int *)&mask); if (!ret) { printf("Failed to query enabled displays!\n"); continue; } /* Query if any of the enabled displays can be set as a * master on this GPU. */ ret = XNVCTRLQueryTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id mask, // display_mask NV_CTRL_FRAMELOCK_MASTERABLE, &masterable); if (!ret) { printf("Failed to query masterable!\n"); continue; } /* Clear the master setting if any */ if (masterable) { XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_MASTER, 0); } /* Clear the slaves setting if any */ XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_SLAVES, 0); printf("\n"); /* Pick the first available/capable display device as master */ if (pick_server && masterable) { /* Just pick the first enabled display */ unsigned int master = (1<<31); while (master && !(master & masterable)) { master >>= 1; } if (master) { mask &= ~master; /* Make sure we're not using the House Sync signal. */ XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_FRAMELOCK, framelock, // target_id 0, // display_mask NV_CTRL_USE_HOUSE_SYNC, NV_CTRL_USE_HOUSE_SYNC_FALSE); /* Set the master */ XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_MASTER, master); printf(" - Set Server Display : 0x%08x\n", master); pick_server = 0; server_set = 1; } } /* Set rest of enabled display devices as clients (slaves) */ if (mask) { XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_SLAVES, mask); printf(" - Set Client Display(s) : 0x%08x\n", mask); } /* Enable frame lock */ XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_SYNC, NV_CTRL_FRAMELOCK_SYNC_ENABLE); XFlush(dpy); printf(" - Frame Lock Sync Enabled.\n"); /* If we just enabled the server, also toggle the test signal * to guarentee accuracy of the universal frame count (as * returned by the glXQueryFrameCountNV() function in the * GLX_NV_swap_group extension). */ if (server_set) { XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_TEST_SIGNAL, NV_CTRL_FRAMELOCK_TEST_SIGNAL_ENABLE); XNVCTRLSetTargetAttribute(dpy, NV_CTRL_TARGET_TYPE_GPU, gpu, // target_id 0, // display_mask NV_CTRL_FRAMELOCK_TEST_SIGNAL, NV_CTRL_FRAMELOCK_TEST_SIGNAL_DISABLE); printf(" - Frame Lock Test Signal Toggled.\n"); server_set = 0; } } /* Done enabling GPUs */ XFree(data); } /* Done enabling framelocks */