Looking for faster DDraw routines..
Moderator: Moderators
-
- Posts: 96
- Joined: Sat Nov 13, 2004 6:25 am
Looking for faster DDraw routines..
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.
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.
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.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
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.
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.
Er, DirectDraw IS DirectX. Perhaps you're thinking of Direct3D, which is somewhat of a waste if all you're doing is 2D rendering...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.
Quietust, QMT Productions
P.S. If you don't get this note, let me know and I'll write you another.
P.S. If you don't get this note, let me know and I'll write you another.
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.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 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;
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.
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.tepples wrote:Hmmm... screen as a texture... Would it be possible to implement scale2x as a pixel shader on current DX9 hardware?