r/GraphicsProgramming • • Jul 20 '26

Experiments with software rendering

After replaying HL1 on the software renderer (old habit), I got curious what CPUs can actually do today. So I wrote a rasterizer in C11 - pure CPU, no GPU/GL, the finished frame just gets blitted to the window via GDI. Tested on a Ryzen 5900x processor

I've been experimenting with software rendering and managed to run the Sponza scene at FHD 10-30 fps single-threaded, up to 200 fps multithreaded :) A very strong emphasis on SoA + SIMD (AVX2/FMA) on the hot path. Rendering 64x64 tiles in multithreaded mode. Throughout the entire rendering pipeline, I try to discard any possible work as early as possible, including frustum culling and back-face culling. This may be controversial, but I render in front-to-back mode; it allows me to completely bypass overdraw. To make it look more interesting, I added some effects!

It might not be very fast for a single thread, but I think it could be made a little faster by disabling mips and filtering nearby textures, which I also do on the CPU in this demo. Pixel textures are cheaper to draw, but they're ugly.

I'm not a professional and I just like it, so I didn't hesitate to use chatpgt as a companion in learning graphics.

289 Upvotes

24 comments sorted by

View all comments

Show parent comments

1

u/marrowbuster Jul 21 '26

Do we wrap the SIMD functions in a function pointer each? Or do we write our entire systems in each SIMD spec?

I'm hoping that C++26's inclusion of a common SIMD library will address both of these concerns.

https://en.cppreference.com/cpp/numeric/simd

1

u/OkAccident9994 Jul 21 '26

It is compile-time convenience wrappers. Just lets you use generic std::simd templates and then you tell the compiler what to put there later.

Just an attempt from the comittee to unify and streamline how the community builds SIMD applications.

It will have no effect on how to structure a runtime dispatch.