#### Archived

This topic is now archived and is closed to further replies.

# quicker video memory writes?

This topic is 6545 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Now I haven''t actually attempted to do this, but it seemed like a good idea to me when I thought of it yesterday. If I am WAY off, someone please let me know. Now, it''s constantly said that writing to video memory is slow, considerably slower than system ram. Also, DirectDraw doesn''t grant you any hardware help with it either. From what I can tell, to draw a single pixel in DDraw, you do something along these lines:
// you have the target surface defined and created prior...
LPDIRECTDRAWSURFACE	Surface = NULL;
.
.
.
// now for speed sake, you might make this global...
DDSURFACEDESC DDsd;
ZeroMemory(&DDsd, 0,sizeof(DDSURFACEDESC));
DDsd.dwSize = sizeof(DDSURFACEDESC);

// lock the surface, get a buffer pointer...
Surface->Lock(NULL, &DDsd, DDLOCK_SURFACEMEMORYPTR / DDLOCK_WAIT,NULL);

int Pitch = DDsd.lPitch;
// 32-bit color, so UINT...
*UINT VideoBuffer = (UINT *) DDsd.lpSurface;

// write pixel to memory
// parems instead of brackets because of forum ...
VideoBuffer(y * Pitch + x) = color;

// unlock
Surface->Unlock(NULL);

So, my idea was to use the blitter. This would give you access to hardware acceleration, right? So, would the following be faster?
RECT rect;

rect.left = x;
rect.right = x;
rect.top = y;
rect.bottom = y;

DDBLTFX ddbltfx;
ZeroMemory(&ddbltfx, sizeof(DDBLTFX));
ddbltfx.dwSize = sizeof(DDBLTFX);
ddbltfx.dwFillColor = color;
Surface->Blt(&rect, NULL, NULL, DDBLT_COLORFILL / DDBLT_WAIT, &ddbltfx);

Now, in each case, you could make things global for speed sake. Perhaps you would have to do something like this to get the desired pixel:
rect.left = x;
rect.right = x + 1;
rect.top = y;
rect.bottom = y + 1;

Now, is this crazy? slow? Would this really have any speed increase over the first method? Just wondering...all comments welcome! (Also, I wrote this from memory, so there are more than likely a few bugs... ) -> Briar LoDeran <-

##### Share on other sites
I would not imagine you would get any speed increase:

PROS:

surface->Blt() uses hardware accleration.

CONS:

surface->Blt() calls an internal form of lock(), so your stuck with the call anyway.
you have to program a 4-variable RECT struct for each pixel.
I sure internal overhead present when setting up for a hardware blit. (for each pixel...)

really DirectX needs a pixel rendering API... I would make particle effects much easier..

nice thought though,

ill-lusion.com

ziggy@ill-lusion.com

##### Share on other sites
Once you have a lock you can write to the VRAM as if it was sysram. And because it is locked you avoid wait states. So if you wanted to draw lots of single pixels. Locking the surface, drawing the pixels and unlocking the surface would be faster than blitting each pixel one by one. If you want to fill a rectangle, Blt is faster than memset.

##### Share on other sites
Try it and see which one was faster?

##### Share on other sites
Once you lock, you are writing to system memory

##### Share on other sites
I never heard anyone say that writing to video memory was slow before. Reading from it, yes. Writing, no.

I seriously doubt that calling Blt() for every pixel is going to gain you any speed. The function call overhead probably kills the speed pretty much dead.

##### Share on other sites
Well, thanks to everyone who responded. I think Kylotan was right. I think I confused slow video memory reads with writes...

We can all talk about this stuff, but its kind of pointless until we put the theory to the test. Since I had some free time at work this morning, I decided to do just that. First I''ll give you the setup and then the unsuprising results....

The test was done in 640x480x16. All I did was draw a single pixel 5,000,000 times a frame. It was at the same place. First I calculated the point and the color and just did the write. This was so there was no math getting in the way. Also, I used GetTickCount for the timing. I know there are more accurate methods, but once you see the results, you can probably forgive me. Here is what I did for the pixel write:
DDSURFACEDESC ddsd;ZeroMemory(&ddsd, sizeof(DDSURFACEDESC));ddsd.dwSize = sizeof(DDSURFACEDESC);	lpddsprimary->Lock(NULL, &ddsd, DDLOCK_WAIT / DDLOCK_SURFACEMEMORYPTR, NULL);USHORT *buffer = (USHORT*)ddsd.lpSurface;int pitch = ddsd.lPitch / 2;USHORT color = RGB16BIT565(255,0,0);int point = (y * pitch) + x;startTime = GetTickCount();	for(unsigned int i = 0; i (less than) 5000000; i++){  buffer[point] = color;}finishTime = GetTickCount() - startTime;

I tried to make the blt as fast as possible too:
RECT rect;rect.left = x;rect.right = x + 1;rect.top = y;rect.bottom = y + 1;DDBLTFX ddbltfx;ZeroMemory(&ddbltfx, sizeof(DDBLTFX));ddbltfx.dwSize = sizeof(DDBLTFX);ddbltfx.dwFillColor = RGB16BIT565(0,255,0);startTime = GetTickCount();	for(unsigned int i = 0; i (less than) 5000000; i++){  lpddsprimary->Blt(&rect, NULL, NULL, DDBLT_COLORFILL / DDBLT_WAIT, &ddbltfx);}	finishTime = GetTickCount() - startTime;

Now, the real meat of it:

So, after 475 loops of this, the direct pixel writing method averaged 67.4549ms per 5,000,000 writes.

After a pathetic 7 loops, the blt method averaged 23433.6ms per 5,000,000 blts. It stopped responding, but luckily WinNT recovered it. (This would have been reboot time at home on Win98...)

So, incase someone is still questioning it, DO NOT use blts for pixel draing . I realize I was the one who proposed it, and probably the only person foolish enough to entertain the idea of it, but I still feel obligated to give the public service announcement. Anyway, it gave me something to do this morning....

-> Briar LoDeran <-

• 10
• 17
• 9
• 14
• 41
• ### Forum Statistics

• Total Topics
631067
• Total Posts
2997736
×