Looking for faster DDraw routines..

This is an archive of a topic from NESdev BBS, taken in mid-October 2019 before a server upgrade.
View original topic
Looking for faster DDraw routines..
by on (#3387)
Hi all,

As said above, I'm looking for better "putpixel" routines than mine, if any. This is how I actually handle graphics in my emu.

1.- DDraw is initialized using this class: http://geocities.com/muchaserres/DDraw.cpp.txt
2.- When a frame starts, I call: Nes->DDraw->LockBuffer().
3.- When a scanline starts, I do: Buffer = ( unsigned char* )Nes->DDraw->DDraw.bpBuffer + ( Scln * Nes->DDraw->DDraw.iPitch ).
4.- When "putting" a pixel, I do: memcpy( Nes->Buffer + ClockTicks * Nes->DDraw->DDraw.bPixelWidth, &RGBPal[ Color ], Nes->DDraw->DDraw.bPixelWidth ).
5.- And finally, when the full frame has been drawn, I do: Nes->DDraw->UnlockBuffer(); Nes->DDraw->Draw().

I'm fearing this is a slow scheme, but I'm not too sure.. Well, any possible improvements?

Lotsa thanks.

by on (#3388)
That's probably the fastest you'll be able to get it, though it will likely cause problems on some video hardware. The "safe" method is to render into an alternate buffer and then lock/render/unlock/blit all at once, though that will consume a lot more memory bandwidth.

by on (#3409)
A few things:

Add the flag DDLOCK_WRITEONLY to the locking function if you're not going to read from the buffer (which you really shouldn't). Also, toss in the DDLOCK_NOSYSLOCK flag as well. New drivers usually include it automatically but you can never be sure.

The locking time should be kept as short as possible to avoid stalling the GPU too much. Having an intermediate buffer and then blit everything in one go might be the better option. Alternative, if you have both the primary surface and off-screen surface in video memory the blit will be practically free. Manual writes to the off-screen buffer will be slower but if you can space them out and do other things between that combination might work better.

The *best* improvement however would be to ditch DirectDraw and move on to DirectX Graphics. It might involve a little more work but the pay off is better.

by on (#3410)
Me above.

by on (#3418)
Marty wrote:
The *best* improvement however would be to ditch DirectDraw and move on to DirectX Graphics. It might involve a little more work but the pay off is better.


Er, DirectDraw IS DirectX. Perhaps you're thinking of Direct3D, which is somewhat of a waste if all you're doing is 2D rendering...

by on (#3422)
Quietust wrote:
Er, DirectDraw IS DirectX. Perhaps you're thinking of Direct3D, which is somewhat of a waste if all you're doing is 2D rendering...


I know that. "DirectX Graphics" is what MS began to call their graphic section in the introduction of DX8. The idea was to have Direct3D and DirectDraw combined but resulted in the end that DirectDraw was left behind. It's now completely outside their radar and haven't had an update ever since (that's almost six years). I deliberately said DirectX Graphics instead of Direct3D to avoid a 3D vs 2D debate but I can see it's too late now anyway. :)

I wouldn't say it's a waste. DirectDraw is layered on top of Direct3D on almost every single 3D card today anyway and once you've set up your vertices and texture the process of rendering a frame isn't that different from DirectDraw.

frameloop:
device->Clear(...); // clear screen
texture->LockRect(...); // lock the NES texture
PutPixels();
texture->UnlockRect(...);
device->BeginScene();
device->DrawPrimitive(...); // draw the NES textured quad
device->EndScene();
device->Present(...); // display screen
goto frameloop;

by on (#3423)
Btw, if anyone wants older DirectX SDKs - e.g. documentation for DirectDraw or DirectInput/DirectPlay older than DirectX 8.0, you can find them here. DirectX 7 docs can be tricky to find.

by on (#3426)
openGL anyone?

by on (#3429)
Great. Thank you all for your replies. :wink:

by on (#3430)
Hmmm... screen as a texture... Would it be possible to implement scale2x as a pixel shader on current DX9 hardware?

by on (#3435)
tepples wrote:
Hmmm... screen as a texture... Would it be possible to implement scale2x as a pixel shader on current DX9 hardware?


I think it's possible but it will require quite some work due to the heavy flow control in the algorithm. It would probably require version 1.2 or higher. But yeah, with a dose of creativity it should be doable.

by on (#3444)
I've seen a pixel shader(OpenGL?) implementation of the HQ2x algorithm at a pixel shader archive once, but I'm too lazy to look it up. :p