To get nvtuner save the following text to a file named nvtuner.cc and enter the following command:
Type: g++ -o nvtuner nvtuner.cc -lstdc++
Quote:
|
#include <stdio.h> #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <iostream> using namespace std; // for future programming adventures i made an class that deals // with the memory access. just scroll over if you are not // interessted class MemAccess { int mem_desc,mem_size; unsigned char *mapped_ptr; public: struct Exception:public exception,public string { Exception(const char *text=0):exception(),string(text) {} Exception(const Exception &e):exception(e),string(e) {} virtual ~Exception() throw() {} }; MemAccess(unsigned long address,unsigned int size): mem_size((size/0x1000+(size%0x1000?1:0))*0x1000) { //increases mem_size to a multiple of 4KB if(size>0x01000000) throw Exception("invalid size parameter.\n"); mem_desc=open("/dev/mem",O_RDWR); if(mem_desc==-1) throw Exception("cannot open /dev/mem (are you logged in as root?).\n"); mapped_ptr=(unsigned char *)mmap(0,mem_size, PROT_READ|PROT_WRITE,MAP_SHARED, mem_desc,address); if(mapped_ptr==MAP_FAILED) { close(mem_desc); throw Exception("cannot map specified Address.\n"); } } unsigned long& operator[](unsigned long offset) throw() { if(offset>mem_size-4) throw Exception("out of range.\n"); return *((unsigned long *)(mapped_ptr+offset)); } const unsigned long& operator[](unsigned long offset) const throw() { if(offset>mem_size-4) throw Exception("out of range.\n"); return *((unsigned long *)(mapped_ptr+offset)); } void sync(void) { msync(mapped_ptr,mem_size,MS_SYNC); } virtual ~MemAccess() { msync(mapped_ptr,mem_size,MS_SYNC); munmap(mapped_ptr,mem_size); close(mem_desc); } }; // the implemention of the above described idea of unlocking class NVTuner { MemAccess NVMem; public: NVTuner(unsigned long NVAddress):NVMem(NVAddress,0x10000) {} unsigned short GetPixelMask(void) const { return (unsigned short)(NVMem[0x1540]); } void SetPixelMask(unsigned short mask) { NVMem[0xc020]=NVMem[0xc024]=NVMem[0xc028]=NVMem[0xc02c]=0; NVMem[0x1540]=0x00010000|mask; NVMem.sync(); } }; //the rest of the program concerns about parsing the command //line and telling the user what's wrong or what to do. void useage(void) { cout<<"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!USE AT YOUR OWN RISK!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n\nUseage: \t\tnvtuner <memory address>\t :returns current pixel mask\n\t\tnvtuner <mask> <memory address> :sets pixel mask\nWhere <memory address> specifies the primary memory address of the graphic card.\nThis address can be obtained through 'cat /proc/pci'.\n\nExample:\tnvtuner 0x3f0f 0xfd000000\nEnables all pixel pipelines and vertex shaders on a graphic card using\n0xfd000000 as memory address.\n\n"; } int main(int argc,char *argv[]) { try { switch(argc) { case 2: { if(!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")) { useage(); return 0; } unsigned long addr=strtoul(argv[1],0,0); if(addr&0x00ffffff || addr==0) { cout<<"I do not trust this memory address\n"; return 0; } NVTuner nt(addr); printf("The current pixel mask is: 0x%.4x\n",nt.GetPixelMask()); } break; case 3: { if(!strcmp(argv[1],"-h") || !strcmp(argv[1],"--help")) { useage(); return 0; } unsigned short mask=strtoul(argv[1],0,0); unsigned long addr=strtoul(argv[2],0,0); if(addr&0x00ffffff || addr==0) { cout<<"I do not trust this memory address\n"; return 0; } NVTuner nt(addr); printf("Setting pixel mask 0x%.4x\n",mask); nt.SetPixelMask(mask); printf("New pixel mask is: 0x%.4x\n",nt.GetPixelMask()); } break; default: useage(); break; } }catch(MemAccess::Exception& e) {cout<<e;} return 0; } |
Type: lspci -v
Look for ur vid card info at the line indicated by the arrow below, eg.
Quote:
|
0000:01:00.0 VGA compatible controller: nVidia Corporation: Unknown device 0042 (rev a1) (prog-if 00 [VGA]) Subsystem: LeadTek Research Inc.: Unknown device 299b Flags: bus master, 66MHz, medium devsel, latency 248, IRQ 16 -> Memory at fd000000 (32-bit, non-prefetchable) [size=16M] Memory at e0000000 (32-bit, prefetchable) [size=128M] Memory at fc000000 (32-bit, non-prefetchable) [size=16M] |
Type: ./nvtuner 0xfd000000
will return u ur current pixel mask, eg. 0x3f0b
Steps
1. Press: CTRL-ALT-BACKSPACE to end ur current X session
2. Press: CTRL-ALT-F1 to use another screen
3. Either login as root or use sudo for the following commands
4. Type: /etc/init.d/xdm stop (or kdm, to kill ur login manager session)
5. Type: rmmod nvidia
6. Type: /path/to/nvtuner 0x3f0b 0xfd000000
change 0x3f0b to ur desired pixel mask (FYI 0x3f0b is 12x1,6vp)
change fd000000 to the value u found with lspci
7. Type: modprobe nvidia
8. Type: /etc/init.d/xdm start
To get the pixel mask values, it's fastest to use rivatuner in windows and jot down all the possible combinations.
eg. 0x1f0a -> 8x1, 5vp
0x1f0b -> 12x1, 5vp
0x3f0b -> 12x1, 6vp, etcetc
With the values, u can go back to linux and do the 8 steps above which is going to be way faster than windows since u only need to restart X as compared to restarting windows.
To make it run on startup check with ur distro, (k)ubuntu or possibly most debian based distros can do the following:
1. Save the following to a script in /etc/init.d/ (eg. nvidia-unlock.sh). Change the pixel mask values to urs of course
Quote:
|
rmmod nvidia /path/to/nvtuner 0x3f0b 0xfd000000 modprobe nvidia |
Works for me but use at ur own risk of course.




Linear Mode
21 OCZ Fans!