Force the software renderer with an environment variable. This will cover both SDL’s 2D render API and trying to use SDL_UpdateWindowSurface, which also checks this environment variable before trying to use OpenGL as a fast-path.
My SDL knowledge is very limited and I am trying to make a simple example work.
https://pastebin.com/Qnk5m5vr, this example doesn’t use SDL_UpdateWindowSurface and I don’t know if there’s call that can be replaced by SDL_UpdateWindowSurface. Since this example uses OpenGL, perhaps it is now a OpenGL thing?
If you use the 2D render API, and force it to use the software renderer, this will also tell it not to use OpenGL behind the scenes (just to get the image to the screen, but not for any actual rendering work, because even for software rendering, this tends to be the fastest way to get a block of pixels to the screen on many platforms, plus it lets things like the Steam Overlay work with the game).
While you can use SDL_UpdateWindowSurface if you definitely just want to manually manage every pixel in software, you almost certainly shouldn’t. Even for entirely software-rendered things, it’s best to use SDL’s render API to get them to the screen for a variety of reasons.