I'm still iffy about when to uncache things. I'll describe the scenarios I currently have.
Scenario 1:
I have an array of sprites to draw. It's filled every frame, drawn, and then reset.
Timeline:
(main cpu): I go through every game entity in the scene and each entity fills the sprite array with the sprites it needs to draw for the frame.
(main cpu): call the scene's drawing function, which does:
(main cpu): For each sprite in the sprite array, I pass the sprite as a pointer to a function that draws the top part on the main cpu and then send the same pointer to the seconary cpu for it to draw the bottom half.
(main cpu): draws top part of a sprite
(secondary cpu): draws the bottom part of a sprite
If I want the data the pointer refers to to be current on the secondary cpu do I need to use the uncached version of the pointer, or do I flush it? or both?
Also, the sprite points to a struct of pixel data. The pointer to the pixel data is set every frame on the sprite struct, but pixel data itself doesn't change after being loaded. Do I need to use the uncached pointer to the pixel data too?
Scenario 2:
I have a global pointer to a game entity that manages the scaling cloud layer, DrawManager_skyEntity.
Timeline:
(main cpu): update the cloud layer state (timers, etc. No drawing yet)
(main cpu): in the scene's draw function, tell the secondary cpu to draw the cloud layer while we do other work
(secondary cpu): call the DrawManager_skyEntity's draw function, which will draw all the clouds.
Code: Select all
// on the secondary cpu, we've received the message from the main cpu to draw the clouds
Entity* skyEntity = (Entity*)((u32)DrawManager_skyEntity | 0x20000000); // necessary?
skyEntity->draw(skyEntity, NULL);
Do I use an uncached pointer to skyEntity at that point?
The entity's drawing function looks like
Code: Select all
// on secondary cpu
static void draw(CloudsEntity* clouds)
{
drawClouds(clouds->clouds, clouds->terrainZ); // helper draw function
}
And the helper function. The cloud layer is basically "terrain" like the tree layer, just different sprites.
Code: Select all
// on secondary cpu
void drawClouds(const Terrain* terrain, const SceneData* sceneData, fixedp cloudZ)
{
// draw the clouds to screen
}
In this scenario, I don't know what I should be doing. Flush the clouds entity? The terrain?
Scenario 3:
I have an XY array of dirty areas that is filled when I draw sprites. Every element covers an 8x8 area of the screen. At the start of every frame, I go through the array and erase the corresponding areas of the screen. I divide the screen in two and each cpu clears its half.
On the secondary cpu, do I have to flush its half of the dirty rectangle array?
As you can see, I don't quite have a handle on it yet. Right now I know I'm doing it wrong. The game runs and there are performance improvements but I've noticed small graphical glitches that smell like the secondary cpu isn't working with up to date data. I want to figure out the proper rules of thumb for this. I appreciate the support!