5
\$\begingroup\$

I am raytracing on the CPU and I need to display my renders to the screen in realtime. I chose SDL 2 as it seems to be made for low level stuff.

I made this basic test which fills the screen from left to right, one column of pixel per frame. It works as expected, but runs very slowly (~10 fps):

int resolutionX = 1920, resolutionY = 1080;

if (SDL_Init(SDL_INIT_VIDEO) != 0)
    return EXIT_FAILURE;

SDL_Window *window = SDL_CreateWindow("Hello World!", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, resolutionX, resolutionY, SDL_WINDOW_SHOWN);
SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
PixelBuffer *framebuffer = createPixelBuffer(resolutionX, resolutionY);
SDL_Texture *framebufferTexture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, framebuffer->width, framebuffer->height);

for (int x = 0; x < resolutionX; x++)
{
    for (int y = 0; y < resolutionY; y++)
        setPixel(framebuffer, x, y, 0x123456FF);

    SDL_UpdateTexture(framebufferTexture, NULL, framebuffer->pixels, framebuffer->pitch);
    SDL_RenderCopy(renderer, framebufferTexture, NULL, NULL);
    SDL_RenderPresent(renderer);
}

SDL_DestroyTexture(framebufferTexture);
destroyPixelBuffer(framebuffer);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();

I found SDL_UpdateTexture to be the slowdown.

I heard of SDL_LockTexture but I don't think I should be using it for write-only operations.
EDIT : SDL_LockTexture is in fact exactly made for write-only operations.

Am I using this function in a wrong way ? Is there any other way to display my renders in real time ?

\$\endgroup\$
4
  • \$\begingroup\$ Your actual problem is that you're raytracing on the CPU. Sending data to the graphics card is a slow process in general, and if you do it every frame then you're going to have a bad time. If you want to do real-time raytracing, I would recommend looking into CUDA and OpenCL. \$\endgroup\$ Nov 24 '14 at 22:13
  • \$\begingroup\$ I already have an OpenCl version of my raytracer, but branching totally ruined the performance. Moreover, I want my scene to be dynamic and maintaining two acceleration structures on both CPU and GPU was too complex. Is there really no way to upload a simple image every frame ? With todays graphics cards bandwidth I thought it would be trivial task. \$\endgroup\$
    – Toun
    Nov 24 '14 at 22:49
  • \$\begingroup\$ In your sample it appears you are just setting the pixels to a known color to test performance correct? You should get better than 10fps. The code sample is horribly formatted. Are you sure you are writing the whole framebuffer before comitting it? The loop looks funny from my end. \$\endgroup\$
    – Steven
    Nov 25 '14 at 1:17
  • \$\begingroup\$ This code sample simply draws a column of pixels each frame. The framebuffer isn't cleared so I don't need to write every pixels each frame. This piece of code works very well, what do you mean by "horribly formatted"? \$\endgroup\$
    – Toun
    Nov 25 '14 at 7:25
10
\$\begingroup\$

Creating a texture with the pixel format SDL_PIXELFORMAT_RGBA8888 was the error here. This format might be different from the one used on the GPU, and the texture had to be converted each frame.

I found that using SDL_PIXELFORMAT_ARGB8888 instead completely solved this issue, and uploading the texture is now instant.

Although the documentation says that SDL_UpdateTexture is slow and should be optimized by using SDL_LockTexture, I haven't noticed ANY performance boost with it.

\$\endgroup\$
7
\$\begingroup\$

I found SDL_UpdateTexture to be the slowdown.

The SDL documentation for SDL_UpdateTexture explicitly says in the Remarks section that it is a slow function and only meant for static texture uploads.

I heard of SDL_LockTexture but I don't think I should be using it for write-only operations.

The documentation for SDL_LockTexture explicitly says in the Remarks sections that it is intended purely for write operations (which is one of the reasons it's so much faster for this purpose).

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .