As far as I understand it, the rendering process goes that, every frame, you build a header and shoot it to vram, then shoot vertex over to vram location indicating segments of a linked list of a specific type of polygon (opaque, punch-thru, etc) until you shoot a vertex with a flag indicating it's the end of a primitive, and you repeat the process until all the vertexes are in memory for that list type, and then that process repeats for all different types of polygons. Then you indicate to the PVR that the scene has ended and it can begin the bining process.
The tile accelerator goes through this vertex list for polygon types and places them into bins, which are linked list objects placed in an area of vram allocated to bining for each polygon type. By looking at pvr.h I see that the sizes you can allocate to these bins are as so:
Code: Select all
1060 #define PVR_BINSIZE_0 0 /**< \brief 0-length (disables the list) */
1061 #define PVR_BINSIZE_8 8 /**< \brief 8-word (32-byte) length */
1062 #define PVR_BINSIZE_16 16 /**< \brief 16-word (64-byte) length */
1063 #define PVR_BINSIZE_32 32 /**< \brief 32-word (128-byte) length */
Code: Select all
Object Pointer Buffer
This buffer possesses the most complex structure of the three. Fortunately most
of it is managed by the PVR so the user doesn't have to worry too much about
its internal structure.
There are two different parts to this buffer. The first part consists of 5
matrices of Object Pointer Segments, one for each primitive type, arranged
in a special order, to be referenced from the Tile Buffer (described later).
This part of the buffer is fixed at a known size. The other part is variable
in size as new segments are allocated and linked from the first part.
The Object Pointer Segments are separate linked lists with the following
appearance;
Segment 0 for Tile 0, 0;
Object Pointer 0
Object Pointer 1
...
Object Pointer n
Pointer to Segment 1 for Tile 0, 0
The arrangement of the segments in memory is;
Segment 0, Tile 0, 0, opaque polygon
Segment 0, Tile 1, 0, opaque polygon
Segment 0, Tile 2, 0, opaque polygon
...
Segment 0, Tile x, 0, opaque polygon
Segment 0, Tile 0, 1, opaque polygon
Segment 0, Tile 1, 1, opaque polygon
Segment 0, Tile 2, 1, opaque polygon
...
Segment 0, Tile x, y, opaque polygon
The above is the Opaque Polygon Object Pointer Buffer Matrix. It is followed by
matrices for the rest of the primitives. The order (important) should be:
* Opaque Polygon
* Opaque Modifier
* Translucent Polygons
* Translucent Modifiers
* Punch-through Polygons
The sizes of the segments are controlled by register a05f8140;
a05f8140: (object pointer buffer control)
+---------------------------------------------------------------------
| 31-21 | 20 | 19-18 | 17-16 | 15-14 | 13-12 | 11-10 |
| n/a | unknown | n/a | punch-through | n/a | transmod | n/a |
+---------------------------------------------------------------------
-------------------------------------------------+
| 9-8 | 7-6 | 5-4 | 3-2 | 1-0 |
| transpoly | n/a | opaquemod | n/a | opaquepoly |
-------------------------------------------------+
unknown:
like name indicates :(
seems to always be set though
punch-through:
0: size_0: Punch-through Polygons disabled
1: size_8: 7 Object Pointers + 1 Segment Pointer
2: size_16: 15 Object Pointers + 1 Segment Pointer
3: size_32: 31 Object Pointers + 1 Segment Pointer
transmod:
0: size_0: Translucent Modifiers disabled
1: size_8: 7 Object Pointers + 1 Segment Pointer
2: size_16: 15 Object Pointers + 1 Segment Pointer
3: size_32: 31 Object Pointers + 1 Segment Pointer
transpoly:
0: size_0: Translucent Polygons disabled
1: size_8: 7 Object Pointers + 1 Segment Pointer
2: size_16: 15 Object Pointers + 1 Segment Pointer
3: size_32: 31 Object Pointers + 1 Segment Pointer
opaquemod:
0: size_0: Opaque Modifiers disabled
1: size_16: 7 Object Pointers + 1 Segment Pointer
2: size_32: 15 Object Pointers + 1 Segment Pointer
3: size_64: 31 Object Pointers + 1 Segment Pointer
opaquepoly:
0: size_0: opaque polygons disabled
1: size_16: 7 Object Pointers + 1 Segment Pointer
2: size_32: 15 Object Pointers + 1 Segment Pointer
3: size_64: 31 Object Pointers + 1 Segment Pointer
The Object Pointers are references to objects that appear inside the tile
associated with the segment. If there are more objects in one tile than fits
into one segment, the last word in the segment points to a new segment.
Notable here is that these new segments are allocated BEFORE the first
Object Pointer Buffer Matrix, so the linked lists actually grow downwards in
memory.
I guess, then, that when you configure the PVR and allocate these bin sizes, like so:
Code: Select all
pvr_init_params_t pvr_params = {
.opb_sizes = { PVR_BINSIZE_8, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_0, PVR_BINSIZE_8 },
.vertex_buf_size = 512 * 1024
};
if(pvr_init(&pvr_params)) {
result = 1;
goto cleanup;
}
My question about the rasterization process is related to how this bining is accomplished. Marcus Comstedt explains the bining process a bit more here: http://mc.pp.se/dc/pvr.html
An example to explain what I'm confused about: Say we have a frame buffer that is 640x480 big. The bining process is going to divide the frame buffer into 32x32 tiles, so the bin resolution basically drops down to 20x15 (32x32 tiles). If a vertex buffer object resides in one of those 20x15 tiles, a pointer to it is created in the Object Pointer buffer bin associated with that tile.
So let's examine just 4 32x32 tiles and a polygon that straddles between them all. Say the following 64x64 area of space is assumed, and it is aligned to the 32-pixel bins, with the following 3 vertexes existing:
which bin is this polygon placed in? It occupies all 4 tiles in varying degrees, is it only placed in one bin according to direction? Or is the same object pointed to by all 4 bins? For that matter, let's look at the shapes of the polygon in each bin:
these would be the 4 32x32 tiles that create the image of the triangle. How are these tiles rasterized? As I understand it, the PVR doesn't actually draw the frame buffer until after the tile bining, so it's not like it is cutting up a raw series of pixels already rasterized. If each tile bin has a copy to the same vertex object, does that mean the same polygon is rasterized in portions 4 different times? I.e. tile 1 figures this:
Tile 2, this:
Tile 3, this:
Tile 4, this:
Isn't that inefficient for that particular polygon? I understand the benefit of this deferred rendering is that you get to avoid having to draw polygons behind the top most polygon (without a true z-buffer, or resorting to a painter's algorithm), but doesn't that come at the cost of having to calculate polygons that extend beyond tile edges multiple times? Or am I misunderstanding the rasterization process?
Any input or thoughts about the subject?