110 likes | 244 Vues
The PlayStation2 and its ADC bit. Why the Clipping Example Works with 0x3FFFF and not with 0x3F ( see http://www.hsfortuna.co.uk/vutut6/vutut6.htm ). 1) Clear Clipping Flags. As we know, the clipping flags are first zeroed at the beginning of the vector unit code: fcset 0x000000
E N D
The PlayStation2and its ADC bit Why the Clipping Example Works with 0x3FFFF and not with 0x3F ( see http://www.hsfortuna.co.uk/vutut6/vutut6.htm )
1) Clear Clipping Flags As we know, the clipping flags are first zeroed at the beginning of the vector unit code: fcset 0x000000 Clipping Flags: [000000] [000000] [000000] [000000] • The clipping flags represent a set of four 6 bit values. The rightmost set is the current vertex, and the three prior vertexes are listed in order as you move to the left.
2) Set Clipping Flags Then, for each vertex, prior clipping flags are left shifted and the new flags set: clipw.xyz Vert, Vert Clipping Flags: [000000] [000000] [000000] [101010] • Each is marked only if that vertex falls outside the clipping frustrum. [ –z +z –y +y –x +x ]
3) Compare Only 3 Vertices FCAND calculates the AND (logical product) of the clipping flags and returns a 1 unless the result is 0. fcand vi01, 0x3FFFF [000000] [000000] [000000] [101010] AND [000000] [111111] [111111] [111111] ------------------------------------------------- Result != 0 [000000] [000000] [000000] [101010] If the result is zero, then vi01 = 0; If the result is not zero, then vi01 = 1;
4) ADC: Add and Carry We then perform a special bit-wise addition that allows us to set an ADC (ADd and Carry) bit if vi01 indicates that any clipping flags are set. iaddiu iADC, vi01, 0x7FFF [00000000][00000001] (vi01) + [01111111][11111111] (0x7FFF) ------------------------------------------------- iADC = [10000000][00000000]
5) Store the ADC bit The ADC bit is then stored back in memory: isw.w iADC, StartVert(iVertPtr)
6) End Result? • IF the ADC bit is not set, the vertex is output to the XYZ2 register as expected. • IF the ADC bit is set, the vertex is instead output to the XYZ3 register.
What’s the difference? • The XYZ2 register can perform a vertex kick AND a drawing kick. • The XYZ3 register can only perform a vertex kick. • A vertex kick uploads the vertex data to the GS, and is performed every time the XYZ register is written to. • The drawing kick tells the GS to start drawing the primitive, and is performed only when enough vertex data has been uploaded to begin the drawing process.
So… If the drawing kick is not performed, then the primitive described by the current contents of the vertex registers will not be drawn. Therefore, when drawing triangles, in order for the clipping to occur, the drawing kick has to be suppressed on third vertex!
Example Consider the following example: The first triangle has the 2nd and 3rd vertexes outside the clipping frustum. The second triangle is completely inside the clipping frustum. Triangle Vertex Clipping flags for the this NumberNumberand two prior verticesADCRegisterKick Performed? 1 1 [000000][000000][000000] 0 XYZ2 Vertex 1 2 [000000][000000][101010] 1 XYZ3 Vertex 1 3 [000000][101010][010101] 1 XYZ3 Vertex ONLY 2 1 [101010][010101][000000] 1 XYZ3 Vertex 2 2 [010101][000000][000000] 1 XYZ3 Vertex 2 3 [000000][000000][000000] 0 XYZ2 Vertex&Drawing
Check out the followingsites for more information: • http://www.hsfortuna.co.uk/vutut6/vutut6.htm • http://portfolio.brokencube.co.uk/BUGGI_Report.pdf • http://portfolio.brokencube.co.uk/BUGGI_Appendices.pdf • http://en.wikipedia.org/wiki/Carry_flag Explained by John Pile Jr, 2008 http://www.alaskjaohn.com http://gamedev.alaskajohn.net