Page 1 of 1

Problems on the VMWare SVGA2 FIFO

Posted: Fri Mar 29, 2013 6:53 pm
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?

Re: Problems on the VMWare SVGA2 FIFO

Posted: Sat Mar 30, 2013 4:55 am
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.

Re: Problems on the VMWare SVGA2 FIFO

Posted: Sat Mar 30, 2013 5:52 am
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.