108 lines
2.9 KiB
C
108 lines
2.9 KiB
C
|
/*
|
||
|
* Stress test for GMR-to-screen blits with a static but highly
|
||
|
* discontiguous mapping.
|
||
|
*
|
||
|
* In this test, we define a single large discontiguous GMR, and blit
|
||
|
* to the screen from random addresses in this GMR.
|
||
|
*
|
||
|
* To measure this test's performance, use mksPerfTool to read the
|
||
|
* number of SWB messages processed per second on the host.
|
||
|
*/
|
||
|
|
||
|
#include "svga.h"
|
||
|
#include "gmr.h"
|
||
|
#include "screen.h"
|
||
|
#include "intr.h"
|
||
|
#include "math.h"
|
||
|
|
||
|
|
||
|
int
|
||
|
main(void)
|
||
|
{
|
||
|
Intr_Init();
|
||
|
Intr_SetFaultHandlers(SVGA_DefaultFaultHandler);
|
||
|
SVGA_Init();
|
||
|
GMR_Init();
|
||
|
Heap_Reset();
|
||
|
SVGA_SetMode(0, 0, 32);
|
||
|
Screen_Init();
|
||
|
|
||
|
SVGAScreenObject myScreen = {
|
||
|
.structSize = sizeof(SVGAScreenObject),
|
||
|
.id = 0,
|
||
|
.flags = SVGA_SCREEN_HAS_ROOT | SVGA_SCREEN_IS_PRIMARY,
|
||
|
.size = { 1600, 1200 },
|
||
|
.root = { -1234, 5678 },
|
||
|
};
|
||
|
Screen_Define(&myScreen);
|
||
|
|
||
|
const uint32 gmrId = 0;
|
||
|
uint32 numPages = 1 + (myScreen.size.width * myScreen.size.height *
|
||
|
sizeof(uint32)) / PAGE_SIZE;
|
||
|
|
||
|
PPN pages = GMR_DefineEvenPages(gmrId, numPages);
|
||
|
|
||
|
const uint32 bitsPerPixel = 32;
|
||
|
const uint32 colorDepth = 24;
|
||
|
const uint32 bytesPerLine = myScreen.size.width * sizeof(uint32);
|
||
|
|
||
|
const SVGAGMRImageFormat format = {{{
|
||
|
.bitsPerPixel = bitsPerPixel,
|
||
|
.colorDepth = colorDepth,
|
||
|
}}};
|
||
|
|
||
|
SVGAGuestPtr gPtr = {
|
||
|
.gmrId = gmrId,
|
||
|
.offset = 0,
|
||
|
};
|
||
|
Screen_DefineGMRFB(gPtr, bytesPerLine, format);
|
||
|
|
||
|
/*
|
||
|
* This is much like the tiny-2d-updates test, except with Screen
|
||
|
* Object and with larger blits... We emit an endless series of
|
||
|
* frames, each one of which has a different screen color (we XOR a
|
||
|
* constant with the GMR). For each frame, we update the screen in
|
||
|
* a grid of small tiles.
|
||
|
*/
|
||
|
|
||
|
const uint32 tileSize = 21; // Some random odd size...
|
||
|
|
||
|
while (1) {
|
||
|
PPN p;
|
||
|
int x, y;
|
||
|
|
||
|
/*
|
||
|
* We don't synchronize these writes to the host's DMA
|
||
|
* completion. This means we'll get tearing- you'll see a
|
||
|
* horizontal line at some point, which indicates how far along
|
||
|
* in this repaint we are at the time the host gets around to
|
||
|
* refreshing the screen.
|
||
|
*
|
||
|
* No big deal. This isn't intended to be an example of correct
|
||
|
* rendering, we're just testing to see how fast the host can
|
||
|
* perform these blits out of discontiguous memory.
|
||
|
*/
|
||
|
|
||
|
p = pages;
|
||
|
for (x = 0; x < numPages; x++) {
|
||
|
uint32 *pageData = PPN_POINTER(p);
|
||
|
for (y = 0; y < PAGE_SIZE / sizeof(uint32); y++) {
|
||
|
pageData[y] ^= 0xFFFFFF;
|
||
|
}
|
||
|
p += 2;
|
||
|
}
|
||
|
|
||
|
for (y = 0; y < myScreen.size.height; y += tileSize) {
|
||
|
for (x = 0; x < myScreen.size.width; x += tileSize) {
|
||
|
|
||
|
SVGASignedPoint blitOrigin = { x, y };
|
||
|
SVGASignedRect blitDest = { x, y, x+tileSize, y+tileSize };
|
||
|
|
||
|
Screen_BlitFromGMRFB(&blitOrigin, &blitDest, myScreen.id);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|