Problems on the VMWare SVGA2 FIFO

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
cycl0ne
Posts: 22
Joined: Tue Sep 02, 2008 11:17 am

Problems on the VMWare SVGA2 FIFO

Post by cycl0ne »

Hi,

i have a small problem. Im programming a graphics driver for the vmware api. Everything works and i can directly draw into the Framebuffer. BUT: I cant use the FIFO correctly:

Code: Select all

void SVGA_FillRect(VgaGfxBase *VgaGfxBase, UINT32 color, UINT32 x, UINT32 y, UINT32 width, UINT32 height ) 
{
	SVGA_FifoBeginWrite(VgaGfxBase);
	SVGA_FifoWrite(VgaGfxBase, SVGA_CMD_RECT_FILL );
	SVGA_FifoWrite(VgaGfxBase, color );
	SVGA_FifoWrite(VgaGfxBase, x );
	SVGA_FifoWrite(VgaGfxBase, y );
	SVGA_FifoWrite(VgaGfxBase, width );
	SVGA_FifoWrite(VgaGfxBase, height );
	SVGA_FifoEndWrite(VgaGfxBase);
	SVGA_FifoSync(VgaGfxBase);
}
If i call:
SVGA_FillRect(VgaGfxBase, 0xff00ff00, 5, 5, 30, 240);
SVGA_FifoUpdateFullscreen(VgaGfxBase);

Nothing happens.
if i do the following:

for(;;) SVGA_FillRect(VgaGfxBase, 0xff00ff00, 5, 5, 30, 240);

I can see my green box.
My "testing" system: Qemu -vga vmware and vmware workstation.

Anyone knows where i need to look at?
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Re: Problems on the VMWare SVGA2 FIFO

Post by Combuster »

Either the known QEMU issue that it stops doing graphics updates when the processor is halted, or the FIFO requires an explicit flush so that it doesn't wait until it has a bunch of commands before rendering them all together.

To cover a few cases, put the infinite loop after either one or two draw calls.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
cycl0ne
Posts: 22
Joined: Tue Sep 02, 2008 11:17 am

Re: Problems on the VMWare SVGA2 FIFO

Post by cycl0ne »

Hmm i forgot some code, was late in the night ;)

Code: Select all


void SVGA_FifoStart(VgaGfxBase *VgaGfxBase)
{
	WriteReg(VgaGfxBase, SVGA_REG_ENABLE, 1);
	WriteReg(VgaGfxBase, SVGA_REG_CONFIG_DONE, 1);
}

void SVGA_FifoStop(VgaGfxBase *VgaGfxBase)
{
	WriteReg(VgaGfxBase, SVGA_REG_CONFIG_DONE, 0);
	WriteReg(VgaGfxBase, SVGA_REG_ENABLE, 0);
}
			
void SVGA_FifoSync(VgaGfxBase *VgaGfxBase)
{
	WriteReg(VgaGfxBase, SVGA_REG_SYNC, 1);
	while (ReadReg(VgaGfxBase, SVGA_REG_BUSY));
}

void SVGA_FifoBeginWrite(VgaGfxBase *VgaGfxBase)
{
	// TODO Get Fifo Semaphore
}

void SVGA_FifoWrite(VgaGfxBase *VgaGfxBase, UINT32 value)
{
	register UINT32 *fifo = VgaGfxBase->fifo;
	register UINT32 fifoCapacity = fifo[SVGA_FIFO_MAX] - fifo[SVGA_FIFO_MIN];

	/* If the fifo is full, sync it */
	if (fifo[SVGA_FIFO_STOP] == fifo[SVGA_FIFO_NEXT_CMD] + 4 ||
		fifo[SVGA_FIFO_STOP] + fifoCapacity == fifo[SVGA_FIFO_NEXT_CMD] + 4)
		SVGA_FifoSync(VgaGfxBase);

	fifo[VgaGfxBase->fifoNext / 4] = value;
	VgaGfxBase->fifoNext = fifo[SVGA_FIFO_MIN] +
		(VgaGfxBase->fifoNext + 4 - fifo[SVGA_FIFO_MIN]) % fifoCapacity;
}

void SVGA_FifoEndWrite(VgaGfxBase *VgaGfxBase)
{
	register UINT32 *fifo = VgaGfxBase->fifo;
	fifo[SVGA_FIFO_NEXT_CMD] = VgaGfxBase->fifoNext;
	//Todo Release Semaphore
}

As you can see i flush often but no effect, i even tried: asm volatile("wbinvd");. Interessting thing, on VMware its also not working 100%. Interessting thing: The screen update is taken from fifo. On qemu the CopyRest also doesnt work, on VMware it works.
what i noticed: if i flush too often, i can see some green line from 0,0 - 200, 0... but not the rectangular box where it supposed to be.

i had a look into the qemu source for vmwaregfx. the api from qemu looks easy to create an own gfxdriver. perhaps someday i find the time to develop a new driver for qemu with more acceleration.
Post Reply