| ▲ | delta_p_delta_x 3 hours ago | |
I'm clearly super old-school when it comes to rasterisation, and a lot of this has flown above my head. I have a ton of questions; I hope you can answer them. > (1) discard (fast but not a great user experience) What are we discarding here, and why is it fast but not a great user experience? > (2) primitive synthesis I assume this is retriangulating clipped triangles that are now no longer triangles? > reverse transformed clipping rectangle Which spaces does this reverse transformation map from and to? I assume the clipping rectangle here is the triangle's AABB in raster space (or as you say, barycentric space). > integer fixed point, but that is historical — modern fixed point can be handled with careful control of the fp unit in the mantissa So we are no longer doing 16.16 fixed point, but tweaking the FP representation itself? > The major issue is regenerating the Z and the 1/Z values for the new vertices Why is this a major issue? > deferred attribute synthesis rasterizer I assume this means attributes are perspective-correct interpolated in raster space. | ||
| ▲ | thechao 2 hours ago | parent | next [-] | |
Sorry I was so terse! Let's ignore guard band, for now. Our rasterization surface is a rectangle. We don't need to "geometrically clip" a triangle to the rectangle's surface. Instead, we just walk the surface of the rectangle and ask two questions: (1) does the triangle capture this (sub)sample; and, (2) what's the interpolated value of the attributes at this (sub)sample. In practice, for software rasterizers, we're working on tiny subrectangles (the tile), e.g., 4x4 or 2x8, whatever. So, we can be a little "inefficient" with our walking with respect to the edge testing for interiority. (This is roughly how HW works at the 2x2 level, as well.) Because the (sub)sample is "pulling" the attribute, we don't need to geometrically "clip" the triangle to the tile: the tile's (x,y) subsamples do that "for free". On the flip side, if a triangle is 'really big' we need a guard band to either reject or subdivide triangles. The first one is fairly cheap -- we're throwing away the triangle! -- the second one is a better user experience, but requires synthesizing primitives. (The worst case is that a single triangle becomes 5 triangles, I think.) Each of those triangles needs its Z and 1/Z calculated in fixed precision. The precision of that fixed precision (though) can be clamped to the local tile; so, even though the global precision might need to be 25.25 (or whatever), the tile-local precision is only 4.9 (or whatever), with an intermediate 24.24 that can be handled with a float-float patch-up. The computation should all occur in the triangle's barycentric space: that means you need the inverted barycentric mapping to invert the guard band into the triangle's barycentric space. You do that because it lets you control the fixed point calculations better. (You can leave off the inverted determinant multiplication until the last moment.) When I say "deferred attribute synthesis" I mean that we don't calculate attributes in the vertex shader. Instead, we calculate the barycentric, Z, and 1/Z values and pass those along. When we fire up the tile walker for the triangle (in general we only need 1-3 tiles), we calculate the attributes "on the fly, as they're used" and then let the compiler do CSE to fold down the replicated constructions. | ||
| ▲ | ack_complete 3 hours ago | parent | prev [-] | |
My own knowledge of GPU rasterization may be dated, but IIRC GPUs tend to rely on guard band clipping up to a guard band threshold before using geometric clipping. The guard band clipping involves rejecting 2D coarse rasterization blocks that are fully outside of the scissor rect. This is just a quick rectangle check, but the tradeoff is that a larger guard band means more GPU time lost in over-rasterization and potential higher precision requirements for rasterization values (which could be fixed point). Beyond the guard band, the triangles are clipped in floating point against the frustum clip planes. | ||