SDL_CreateRenderer with Vulkan

I’m trying to make a game using SDL2 and Vulkan. It compiles and run correctly on Windows 10, but SDL_CreateRenderer fails on Ubuntu and Linux Mint.

My question is am I doing something incorrectly in the code or this an issue with SDL not being linked with Vulkan or possibly something else that doesn’t have to do with SDL (such as Vulkan drivers not being installed correctly)?

I posted a code sample below that has the issue I described. It prints “Failed to created renderer” on Linux. I see and can close the window, but since the renderer isn’t created, I can’t do any Vulkan things. I think that since SDL can create a Window with the SDL_WINDOW_VULKAN flag successfully, SDL is correctly linked with Vulkan, but I wanted to ask here as a sanity check. I’m using SDL 2.0.12.

#include <iostream> 

#include <SDL2/SDL.h>
#include <SDL2/SDL_vulkan.h>

using namespace std;

int main() {
   cout << "Starting program..." << endl;

   // retutns zero on success else non-zero 
   if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { 
      cout << "error initializing SDL: " << SDL_GetError() << endl; 
   }
   bool fullscreen = false;
   uint32_t flags = SDL_WINDOW_VULKAN | SDL_WINDOW_SHOWN | (fullscreen ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_RESIZABLE);
   SDL_Window* win = SDL_CreateWindow("GAME", // creates a window 
                                      SDL_WINDOWPOS_CENTERED, 
                                      SDL_WINDOWPOS_CENTERED, 
                                      800, 600, flags); 

   if (win == nullptr) {
      cout << "Failed to create window" << endl;
   }

   // triggers the program that controls 
   // your graphics hardware and sets flags
   Uint32 render_flags = SDL_RENDERER_ACCELERATED; 

   // creates a renderer to render our images 
   SDL_Renderer* rend = SDL_CreateRenderer(win, -1, render_flags); 

   if (rend == nullptr) {
      cout << "Failed to create renderer" << endl;
   }

   // let us control our image position 
   // so that we can move it with our keyboard. 
   SDL_Rect dest{};

   // adjust height and width of our image box. 
   dest.w /= 6; 
   dest.h /= 6; 

   // sets initial x-position of object 
   dest.x = (1000 - dest.w) / 2; 

   // sets initial y-position of object 
   dest.y = (1000 - dest.h) / 2; 

   // controls annimation loop 
   int close = 0; 

   // speed of box 
   int speed = 300; 

   // animation loop 
   while (!close) { 
      SDL_Event event; 

      // Events mangement 
      while (SDL_PollEvent(&event)) { 
         switch (event.type) { 

         case SDL_QUIT: 
            // handling of close button 
            close = 1; 
            break; 

         case SDL_KEYDOWN: 
            // keyboard API for key pressed 
            switch (event.key.keysym.scancode) { 
            case SDL_SCANCODE_W: 
            case SDL_SCANCODE_UP: 
               dest.y -= speed / 30; 
               break; 
            case SDL_SCANCODE_A: 
            case SDL_SCANCODE_LEFT: 
               dest.x -= speed / 30; 
               break; 
            case SDL_SCANCODE_S: 
            case SDL_SCANCODE_DOWN: 
               dest.y += speed / 30; 
               break; 
            case SDL_SCANCODE_D: 
            case SDL_SCANCODE_RIGHT: 
               dest.x += speed / 30; 
               break; 
            } 
         } 
      } 

      // right boundary 
      if (dest.x + dest.w > 1000) 
         dest.x = 1000 - dest.w; 

      // left boundary 
      if (dest.x < 0) 
         dest.x = 0; 

      // bottom boundary 
      if (dest.y + dest.h > 1000) 
         dest.y = 1000 - dest.h; 

      // upper boundary 
      if (dest.y < 0) 
         dest.y = 0; 

      // clears the screen 
      SDL_RenderClear(rend); 

      // triggers the double buffers 
      // for multiple rendering 
      SDL_RenderPresent(rend); 

       // calculates to 60 fps 
      SDL_Delay(1000 / 60); 
   } 

   // destroy renderer 
   SDL_DestroyRenderer(rend); 

   // destroy window 
   SDL_DestroyWindow(win); 

   return 0;
}

I don’t think SDL Renderer has a Vulkan backend. Anyway, the SDL_WINDOW_VULKAN flag is there to make sure the window is compatible with Vulkan so you can do your own Vulkan stuff; it doesn’t have anything to do with SDL Renderer.

Passing -1 as the second argument to SDL_CreateRenderer() tells it to pick the first backend that matches the supplied flags (btw, use SDL_RENDERER_PRESENTVSYNC for vsync instead of doing your own), so the question is: which backends are available, if any?

You can determine this with something like this, before you create the renderer:

int renderCount = SDL_GetNumRenderDrivers();
printf("Total render drivers: %d\n", renderCount);
for(int i = 0; i < renderCount; i++) {
    printf("Render driver: %d\n", i);
    SDL_RendererInfo info;
    memset(&info, 0, sizeof(info));
    if(!SDL_GetRenderDriverInfo(i, &info)) {
        printf("\tName: %s\n", info.name);
        printf("\tAccelerated: %s\n", info.flags & SDL_RENDERER_ACCELERATED ? "YES" : "NO");
    } else {
        printf("No driver info available\n");
    }
}

And that will tell you what SDL Renderer backend drivers are available.