/usr/share/psychtoolbox-3/PsychTests/DriftTexturePrecisionTest.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 | function DriftTexturePrecisionTest(highprecision, verbose, filterMode)
% DriftTexturePrecisionTest([highprecision=0][, verbose=0][, filterMode=1])
%
% This test finds the minimum useful subtexel stepsize of the graphics hardwares
% texture coordinate interpolators. The minimum stepsize is the finest
% subpixel stepwidth that the gfx-hardware can resolve into an image in a
% meaningful way, e.g., for slow subpixel scrolling, drifting gratings and
% such.
%
% It draws an alternating black-white pattern, reads it back, then draws
% the pattern shifted by some small horizontal amount, reads it back and
% compares the two drawn images. If they are different then the hardware
% could resolve the subpixel increment into two different, properly shifted
% images via bilinear texture interpolation. If they are the same then the
% increment was too small to resolve for this hardware. The smallest
% stepsize is found in multiple iterations that reduce the stepsize until
% no difference is found anymore.
%
% The minimum resolvable stepsize for an ATI Mobility Radeon X1600 (e.g.,
% MacBook Pro) is 1/64 th of a pixel, which corresponds to 6 bits subpixel
% accuracy.
%
% If the optional flag 'highprecision' is set to 1 or 2, then floating
% point textures are used, instead of integer textures with 8 bit
% resolution. 1 selects 16bpc float textures, 2 selects 32bpc float
% textures. A setting of 3 or 4 selects also 16bpc or 32bpc float textures,
% but additionally a special PTB GLSL interpolation shader is used instead
% of the hard-wired interpolator of your gfx chip. This is computationally
% more demanding and therefore slower, but it should provide higher
% precision and better resolution.
% History:
% 15.04.2007 Written (MK).
if nargin < 1 || isempty(highprecision)
highprecision = 0;
end
if nargin < 2|| isempty(verbose)
verbose = 0;
end
if highprecision > 2
highprecision = highprecision - 2;
sflags = 2;
else
sflags = 0;
end
if nargin < 3
filterMode = [];
end
AssertOpenGL;
screenNumber=max(Screen('Screens'));
texsize=256; % Half-Size of the grating image.
skewden = inf;
KbReleaseWait;
try
% Open a double buffered fullscreen window and draw a gray background
% to front and back buffers:
[w screenRect]=Screen('OpenWindow',screenNumber, 128);
Screen('Flip', w);
% Create one single static alternating black-white image:
grating=zeros(2*texsize, 2*texsize);
if highprecision
mfactor = 1;
else
mfactor = 255;
end
for x=1:2*texsize
for y=1:2*texsize
% Contrast is 255, so we can resolve stepsizes down to 1/255th.
grating(y,x)=mod(x,2)*mfactor;
end
end
% Store testpattern in texture:
tex=Screen('MakeTexture', w, grating, [], sflags, highprecision);
% Definition of the drawn rectangle on the screen:
dstRect=[0 0 texsize texsize];
dstRect=CenterRect(dstRect, screenRect);
% We only sample one single pixel in the center of the display:
sampleRect = OffsetRect(CenterRect([0 0 1 texsize], dstRect), 0, 0);
den = 1;
skewcount = 0;
% Test for stepsizes down to 1/512 th of a texel.
while den <= 512 && ~KbCheck
shiftperframe = 1/den;
count = 0;
for i=0:texsize
% Shift the aperture by "shiftperframe" pixels per frame:
xoffset = mod(i*shiftperframe,2*texsize);
% Define shifted srcRect that cuts out the properly shifted rectangular
% area from the texture:
srcRect=[xoffset 0 xoffset + texsize texsize];
% Draw texture:
Screen('DrawTexture', w, tex, srcRect, dstRect, [], filterMode);
% Read back 1 sample pixel from drawn texture for comparison:
readimgin = Screen('GetImage', w, sampleRect, 'backBuffer');
readimg = double(readimgin(10,1,1));
readimg2 = double(readimgin(:,1,1));
diffv = (abs(readimg - readimg2) > 0);
if any(diffv)
skewcount = skewcount + 1;
end
Screen('FillRect', w, [255 255 0], sampleRect)
Screen('Flip', w);
if (i > 0)
% Any difference in pixels value?
difference=abs(readimg - oldreadimg);
if verbose
fprintf('Sample was %f --> Delta for offset %f is %f\n', readimg, xoffset, difference);
end
% Count number of frames with non-differences:
if difference == 0
count = count + 1;
end
else
%KbWait;
%while KbCheck; end;
end
% Update:
oldreadimg = readimg;
% Abort test if any key is pressed:
if KbCheck
break;
end;
end;
% Output number of identical pixels in texsize samples sample set.
% A count of 0 means that the chosen stepsize is still below the
% resolution of the hardwares texture interpolators:
fprintf('Stepsize 1 / %i th pixel. Nr. of identical frames: %i', den, count);
if skewcount > 0
fprintf(' -- Warning: Interpolator skew detected! Your hardware is sampling inaccurate!\n');
skewden = min(skewden, den);
else
fprintf('\n');
end
skewcount = 0;
if count < 2
% Store this stepsize as our current best:
bestden = den;
end
% Half the stepsize for next test run:
den = den * 2;
end
if den > 512
% Output smallest stepsize that the texture coordinate interpolators of
% the hardware can reliably resolve:
fprintf('\n\nMinimum useable stepsize for interpolator is 1 / %i th of a pixel.\n', bestden);
else
fprintf('\n\nTest prematurely aborted, results therefore incomplete:\nFinest tested useable stepsize for interpolator is 1 / %i th of a pixel.\n', bestden);
end
if bestden > skewden || skewden == 1
fprintf('However, due to interpolator skew in your hardware, you may already encounter precision issues at a\nstepsize of 1 / %i th of a pixel.\n', skewden);
fprintf('If you need absolute precision, e.g, for very strictly controlled low-level stimuli, you should not use a\n');
fprintf('stepsize finer than that. You may retry with "highprecision" settings greater than the currenly selected\n');
fprintf('setting, to see if your hardware behaves more accurately with such settings.\n\n');
end
Screen('CloseAll');
catch
%this "catch" section executes in case of an error in the "try" section
%above. Importantly, it closes the onscreen window if its open.
Screen('CloseAll');
psychrethrow(psychlasterror);
end %try..catch..
|