vmware-svga/examples/screen-gmr-discontig/main.c
Micah Dowty 68478eab4b There are many new tests and examples that we wrote internally at VMware,
but couldn't release immediately since they depended on virtual GPU features
which were not yet publicly released in any products.  This checkin moves those
features from our internal repository to the open source repository. Future   
development on these tests and examples will take place directly in the open
source repository.

The primary feature added by this patch is 'Screen Object', a new dynamic
display management extension supported by Workstation 7.0 and Fusion 3.0.
See the README for a quick explanation.
2009-10-21 20:20:49 +00:00

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;
}