/usr/share/psychtoolbox-3/PsychOneliners/LoadIdentityClut.m is in psychtoolbox-3-common 3.0.11.20131230.dfsg1-1build1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 | function oldClut = LoadIdentityClut(windowPtr, loadOnNextFlip, lutType)
% oldClut = LoadIdentityClut(windowPtr [, loadOnNextFlip=0][, lutType=auto])
%
% Loads the identity clut on the windows specified by windowPtr. If
% loadOnNextFlip is set to 1, then the clut will be loaded on the next call
% to Screen('Flip'). By default, the clut will be loaded immediately or on
% the next vertical retrace.
%
% If you use Linux and run Matlab or Octave as root user via the "sudo"
% command, or if you use OS/X and have the PsychtoolboxKernelDriver loaded
% ("help PsychtoolboxKernelDriver") and the graphics card is a GPU of the
% ATI/AMD Radeon X1000 series or a HD series card (e.g., HD-2000) or a
% equivalent model of the FireGL or FirePro series, then this routine will
% try to use special low-level setup code for optimal identity mapping.
% Otherwise it will just make a best effort to upload a suitable clut, as
% follows:
%
% This mechanism relies on heuristics to detect the exact type of LUT to
% upload into your graphics card. These heuristics may go wrong, thanks to
% the ever increasing amount of graphics hardware driver bugs in both
% Windows and MacOS/X. For that reason you can also use the function
% SaveIdentityClut() to manually specify either the type of LUT to use
% (overriding the automatic choice), or to specify the complete LUT, or to
% capture the current identity LUT of a display that works. That function
% will store the override Clut in a per-user, per-GPU, per-Screen configuration
% file. If LoadIdentityClut finds such a matching configuration file, it
% will use the LUT specified there, instead of performing an automatic
% selection.
%
% The routine optionally returns the old clut in 'oldClut'.
%
% You can restore the old "original" LUT at any time by calling
% RestoreCluts, or sca, but only until you call clear all! The original
% LUT's are backed up in a global variable for this to work.
%
% History:
% ??/??/?? mk Written.
% 05/31/08 mk Add code to save backup copy of LUT's for later restore.
% 09/09/09 mk Add more LUT workarounds for Apple's latest f$%#%$#.
% 09/16/09 mk Even more workarounds for ATI's latest %#$%#$ on Windows.
% 09/20/09 mk Add option to load LUT type or LUT from config file to
% override the auto-detection here.
% 05/30/11 mk Add option to use Screen's built in low-level GPU setup
% methods to achieve an identity mapping. Fallback to old
% heuristics if that is unsupported, disabled or failed.
%
global ptb_original_gfx_cluts;
if nargin < 1
error('Invalid number of arguments to LoadIdentityClut.');
end
% If not specified, we'll set the clut to load right away.
if nargin < 2
loadOnNextFlip = [];
end
if isempty(loadOnNextFlip)
loadOnNextFlip = 0;
end
if nargin < 3
lutType = [];
end
% Get screen id for this window:
screenid = Screen('WindowScreenNumber', windowPtr);
% Query what kind of graphics hardware is
% installed to drive the display corresponding to 'windowPtr':
% Query vendor of associated graphics hardware:
winfo = Screen('GetWindowInfo', windowPtr);
% Get current clut for use as backup copy later on:
oldClut = Screen('ReadNormalizedGammaTable', windowPtr);
% Try to use PsychGPUControl() method to disable display dithering
% globally on all connected GPUs and displays. As of March 2013, this
% function is only supported on Linux and Windows with AMD/ATI GPU's,
% and only when running the proprietary Catalyst display driver.
% It will no-op silently on other system configurations.
%
% We don't use the success status return code of the function, because
% we don't know how trustworthy it is. Also this only affects dithering,
% not gamma table identity setup, so the code-pathes below must run anyway
% for proper setup, even if their dithering disable effect may be redundant.
PsychGPUControl('SetDitheringEnabled', 0);
% Ask Screen to use low-level setup code to configure the GPU for
% untampered framebuffer pixel paththrough. This is only supported on a
% subset of GPU's under certain conditions if the PsychtoolboxKernelDriver
% is loaded, but should be the most reliable solution if it works:
if ~IsWin
passthroughrc = Screen('LoadNormalizedGammatable', windowPtr, []);
else
passthroughrc = intmax;
end
if ismember(passthroughrc, [1, 2])
% Success. How well did we do?
if passthroughrc == 2
fprintf('LoadIdentityClut: Info: Used GPU low-level setup code to configure (hopefully) perfect identity pixel passthrough.\n');
else
fprintf('LoadIdentityClut: Warning: Used GPU low-level setup code to configure a perfect identity gamma table, but failed at\n');
fprintf('LoadIdentityClut: Warning: configuring rest of color conversion hardware. This may or may not work.\n');
end
else
% No success. Either the low-level setup is unsupported, or it failed:
if passthroughrc == 0
fprintf('LoadIdentityClut: Warning: GPU low-level setup code for pixel passthrough failed for some reason! Using fallback...\n');
elseif IsOSX || IsLinux
fprintf('LoadIdentityClut: Info: Could not use GPU low-level setup for setup of pixel passthrough. Will use fallback method.\n');
fprintf('LoadIdentityClut: Info: If you have an AMD/ATI GPU, you may get this working by loading the PsychtoolboxKernelDriver\n');
fprintf('LoadIdentityClut: Info: on OS/X or using a Linux system properly setup with PsychLinuxConfiguration.\n');
end
% Carry on with our bag of clut heuristics and other tricks...
% Raw renderer string, with leading or trailing whitespace trimmed:
gpuname = strtrim(winfo.GLRenderer);
% Replace blanks and '/' with underscores:
gpuname(isspace(gpuname)) = '_';
gpuname = regexprep( gpuname, '/', '_' );
% Same game for version string:
glversion = strtrim(winfo.GLVersion);
% Replace blanks with underscores:
glversion(isspace(glversion)) = '_';
glversion(glversion == '.') = '_';
% Is there a predefined configuration file for the proper type of LUT to
% load? Build kind'a unique path and filename for our system config:
lpath = sprintf('%sIdentityLUT_%s_%s_%s_Screen%i.mat', PsychtoolboxConfigDir, OSName, gpuname, glversion, screenid);
if exist(lpath, 'file')
% Configfile! Load it: This will define a variable lutconfig in the
% workspace:
load(lpath);
if isscalar(lutconfig)
% Single scalar id code given to select among our hard-coded LUT's
% below:
gfxhwtype = lutconfig;
fprintf('Applying the gamma lookup table of type %i, as specified in the following configuration file:\n%s\n', gfxhwtype, lpath);
else
% Full blown LUT given:
lut = lutconfig;
if ~isnumeric(lut) || size(lut,1) < 1 || size(lut,2) ~= 3
sca;
error('LoadIdentityClut: Loaded data from config file is not a valid LUT! Not a numeric matrix or less than 1 row, or not 3 columns!');
end
fprintf('Applying the gamma lookup table for identity mapping from the following configuration file:\n%s\n', lpath);
gfxhwtype = -1;
end
else
% No specific config file. Try our best at auto-detection of flawed
% systems:
% Query OS type and version:
if IsOSX
% Which OS/X version?
compinfo = Screen('Computer');
osxversion = sscanf(compinfo.system, '%*s %*s %i.%i.%i');
end
% We derive type of hardware and thereby our strategy from the vendor name:
gfxhwtype = winfo.GLVendor;
if ~isempty(strfind(gfxhwtype, 'NVIDIA')) || ~isempty(strfind(gfxhwtype, 'nouveau'))
% NVidia card:
% We start with assumption that it is a "normal" one:
gfxhwtype = 0;
% GeForce 250 (e.g., GeForce GTS 250) under MS-Windows?
if IsWin && ~isempty(strfind(winfo.GPUCoreId, 'G80')) && ~isempty(strfind(winfo.GLRenderer, '250'))
% GeForce 250 on MS-Windows. Needs LUT type 1, according to Jon Peirce:
gfxhwtype = 1;
end
% Is it a Geforce-8000 or later (G80 core or later) and is this OS/X?
if ~isempty(strfind(winfo.GPUCoreId, 'G80')) && IsOSX
% 10.5.x Leopard?
if (osxversion(1) == 10) && (osxversion(2) == 5) && (osxversion(3) >=0)
% Yes. One of the releases with an embarassing amount of bugs,
% brought to you by Apple. Need to apply an especially ugly
% clut to force these cards into an identity mapping:
fprintf('LoadIdentityClut: NVidia Geforce 8000 or later on OS/X 10.5.x detected. Enabling special type-I LUT hacks for totally broken operating systems.\n');
gfxhwtype = 2;
end
% 10.6.x Snow Leopard or later?
if (osxversion(1) == 10) && (osxversion(2) >= 6) && (osxversion(3) >=0)
% Yes. One of the releases with an embarassing amount of bugs,
% brought to you by Apple. Need to apply an especially ugly
% clut to force these cards into an identity mapping:
% Peter April reports his GeForce GT 330M on 10.6.8
% needs a type 0 LUT, so we handle this case:
if ~isempty(strfind(winfo.GLRenderer, '330'))
fprintf('LoadIdentityClut: NVidia Geforce GT 330 or later on OS/X 10.6.x or later detected. Enabling type-0 LUT.\n');
gfxhwtype = 0;
else
% Something else: LUT-III is so far correct.
fprintf('LoadIdentityClut: NVidia Geforce 8000 or later on OS/X 10.6.x or later detected. Enabling special type-II LUT hacks for totally broken operating systems.\n');
gfxhwtype = 3;
end
end
end
% Is this a latest generation NVidia QuadroFX card under Linux with NVidia binary blob?
[dummy, dummy2, nrslots] = Screen('ReadNormalizedGammatable', windowPtr); %#ok<ASGLU>
if IsLinux && ~isempty(strfind(winfo.GLRenderer, 'Quadro')) && (nrslots > 256)
% LUT type 3:
gfxhwtype = 3;
fprintf('LoadIdentityClut: NVidia Quadro or later on Linux with binary Blob detected. Enabling special type-III LUT.\n');
end
else
if ~isempty(strfind(gfxhwtype, 'ATI')) || ~isempty(strfind(gfxhwtype, 'AMD')) || ~isempty(strfind(gfxhwtype, 'Advanced Micro Devices')) || ...
~isempty(strfind(winfo.GLRenderer, 'DRI R')) || ~isempty(strfind(winfo.GLRenderer, 'on ATI R'))
% ATI card:
% A good default at least on OS/X is type 1:
gfxhwtype = 1;
if (IsWin || IsLinux) && ~isempty(strfind(winfo.GPUCoreId, 'R600'))
% At least the Radeon HD 3470 under Windows Vista and Linux needs type 0
% LUT's. Let's assume for the moment this is true for all R600
% cores, ie., all Radeon HD series cards.
fprintf('LoadIdentityClut: ATI Radeon HD-2000 or later detected. Enabling special type-0 LUT hacks for totally broken drivers.\n');
gfxhwtype = 0;
elseif (IsLinux) && (~isempty(strfind(winfo.GLRenderer, 'DRI R')) || ~isempty(strfind(winfo.GLRenderer, 'on ATI R')))
% At least the Radeon R3xx/4xx/5xx under Linux with DRI2 Mesa needs type 0
% LUT's. Let's assume for the moment this is true for all R600
% cores, ie., all Radeon HD series cards.
fprintf('LoadIdentityClut: ATI Radeon R3xx/R4xx/R5xx on Linux DRI2 detected. Using type-0 LUT.\n');
gfxhwtype = 0;
elseif IsOSX && (~isempty(strfind(winfo.GLRenderer, 'Radeon HD 5')))
% At least on OS/X 10.6 with ATI Radeon HD-5000 series,
% type 2 seems to be the correct choice, according to Cesar
% Ramirez (NASA):
fprintf('LoadIdentityClut: ATI Radeon HD-5000 Evergreen on OS/X detected. Using type-2 LUT.\n');
gfxhwtype = 2;
end
else
% Unknown card: Default to NVidia behaviour:
gfxhwtype = 0;
warning('LoadIdentityClut: Warning! Unknown graphics hardware detected. Set up identity CLUT may be wrong!'); %#ok<WNTAG>
end
end
end
% Use LUT type override from command line, if any is given:
if ~isempty(lutType)
gfxhwtype = lutType;
fprintf('LoadIdentityClut: OVERRIDE: Will use identity LUT of type %i, as specified in function call argument.\n', gfxhwtype);
end
% We have different CLUT setup code for the different gfxhw-vendors:
if gfxhwtype == -1;
% Upload the lut defined in 'lut':
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, lut, loadOnNextFlip);
end
if gfxhwtype == 0
% This works on WindowsXP with NVidia GeForce 7800 and OS/X 10.4.9 PPC
% with GeForceFX-5200. Both are NVidia cards, so we assume this is a
% correct setup for NVidia hardware:
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, (0:1/255:1)' * ones(1, 3), loadOnNextFlip);
end
if gfxhwtype == 1
% This works on OS/X 10.4.9 on Intel MacBookPro with ATI Mobility
% Radeon X1600, also on 10.5.8 with ATI Radeon HD-2600: We assume this
% is the correct setup for ATI hardware:
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, ((1/256:1/256:1)' * ones(1, 3)), loadOnNextFlip);
end
if gfxhwtype == 2 && IsOSX
% This works on OS/X 10.5 with NVidia GeForce 8800. It is an ugly hack
% to compensate for the absolutely horrible, embarassing bugs in Apple's NVidia
% graphics drivers and their clut handling. Does this company still
% have a functioning Quality control department, or are they all
% fully occupied fiddling with their iPhones?!?
% This works on 10.5.8 with Geforce-9200M in the MacMini according to
% CRS, and with 10.5.8 with Geforce-8800 in the MacPro according to
% me. We assume this works on all G80 et al. GPU's:
loadlut = (linspace(0,(1023/1024),1024)' * ones(1, 3));
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, loadlut, loadOnNextFlip);
end
if gfxhwtype == 3 && IsOSX
% This works on OS/X 10.6.0 with NVidia Geforce-9200M according to CRS
% and with 10.6.0 with Geforce-8800 in the MacPro according to
% me. We assume this works on all G80 et al. GPU's:
for i=0:1023
if ((i / 1024.0) < 0.5)
loadlut(i+1) = (i / 1024.0);
else
loadlut(i+1) = (i / 1024.0) - (1.0/256.0);
end
end
loadlut = loadlut' * ones(1, 3);
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, loadlut, loadOnNextFlip);
end
if gfxhwtype == 3 && IsWin
% This is an experimental variant of the OS/X type 3 lut, but with 256
% slots. It is supposed for WindowsXP, assuming some NVidia GPU's,
% e.g., some QuadroFX 3700 GPU's have similar problems:
for i=0:255
if ((i / 255.0) < 0.5)
loadlut(i+1) = (i / 255.0);
else
loadlut(i+1) = (i / 255.0) - (1.0/256.0);
end
end
loadlut = loadlut' * ones(1, 3);
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, loadlut, loadOnNextFlip);
end
if gfxhwtype == 3 && IsLinux
% NVidia QuadroFX cards with binary blob and lut's with more than
% 256 slots. Upload a standard linear lut with matching number of
% slots:
[dummy, dummy2, nrslots] = Screen('ReadNormalizedGammatable', windowPtr); %#ok<ASGLU>
loadlut = (linspace(0,((nrslots-1) / nrslots), nrslots)' * ones(1, 3));
oldClut = Screen('LoadNormalizedGammaTable', windowPtr, loadlut, loadOnNextFlip);
end
if ~ismember(gfxhwtype, [-1,0,1,2,3])
sca;
error('Could not upload identity CLUT to GPU! Invalid LUT or invalid LUT id or other invalid arguments passed?!?');
end
% End of high level lut setup path.
end
% Store backup copies of clut's for later restoration by RestoreCluts():
% Create global clut backup cell array if it does not exist yet:
if isempty(ptb_original_gfx_cluts)
% Create 10 slots for out up to 10 screens:
ptb_original_gfx_cluts = cell(10,1);
end
% Do we have already a backed up original clut for 'screenid'?
% If so, we don't store this clut, as an earlier invocation of a clut
% manipulation command will have stored the really real original lut:
if isempty(ptb_original_gfx_cluts{screenid + 1})
% Nope. Store backup:
ptb_original_gfx_cluts{screenid + 1} = oldClut;
end
return;
|