summaryrefslogtreecommitdiff
path: root/src/renderwindow.c
blob: e9b7a808bbdee7a90b0e562a343d555bc0508f1b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
#include <SDL3/SDL.h>
#include <dawn/webgpu.h>
#include "renderwindow.h"

#if defined(SDL_PLATFORM_LINUX)
#include <X11/Xlib.h>
#include <wayland-client.h>
#endif

RenderWindow InitRenderWindow(int width, int height, const char* title) {
  RenderWindow renderWindow = {0};
  SDL_Init(SDL_INIT_VIDEO);
  renderWindow.window = SDL_CreateWindow(title, width, height, 0);

  renderWindow.wgpuInstance = wgpuCreateInstance(&(const WGPUInstanceDescriptor){
      .requiredFeatureCount = 1,
      .requiredFeatures = (WGPUInstanceFeatureName[]) { WGPUInstanceFeatureName_TimedWaitAny }
    });

  SDL_PropertiesID windowProperties = SDL_GetWindowProperties(renderWindow.window);
#if defined(SDL_PLATFORM_LINUX)
  if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "x11") == 0) {
    Display* xdisplay =
      (Display *)SDL_GetPointerProperty(windowProperties, SDL_PROP_WINDOW_X11_DISPLAY_POINTER, NULL);
    Window xwindow =
      (Window)SDL_GetNumberProperty(windowProperties, SDL_PROP_WINDOW_X11_WINDOW_NUMBER, 0);

    if (xdisplay && xwindow) {
      renderWindow.wgpuSurface =
        wgpuInstanceCreateSurface(renderWindow.wgpuInstance, &(const WGPUSurfaceDescriptor){
            .nextInChain = (WGPUChainedStruct*)&(const WGPUSurfaceSourceXlibWindow) {
              .chain = (WGPUChainedStruct) {
                .next = NULL,
                .sType = WGPUSType_SurfaceSourceXlibWindow
              },

              .display = xdisplay,
              .window = xwindow
            }
          });
    }
  } else if (SDL_strcmp(SDL_GetCurrentVideoDriver(), "wayland") == 0) {
    struct wl_display* wl_display =
      (struct wl_display*)SDL_GetPointerProperty(windowProperties, SDL_PROP_WINDOW_WAYLAND_DISPLAY_POINTER, NULL);
    struct wl_surface* wl_surface =
      (struct wl_surface*)SDL_GetPointerProperty(windowProperties, SDL_PROP_WINDOW_WAYLAND_SURFACE_POINTER, NULL);

    if (wl_display && wl_surface) {
      renderWindow.wgpuSurface =
        wgpuInstanceCreateSurface(renderWindow.wgpuInstance, &(const WGPUSurfaceDescriptor){
            .nextInChain = (WGPUChainedStruct*)&(const WGPUSurfaceSourceWaylandSurface) {
              .chain = (WGPUChainedStruct) {
                .next = NULL,
                .sType = WGPUSType_SurfaceSourceWaylandSurface
              },

              .display = wl_display,
              .surface = wl_surface
            }
          });
    }
  }
#endif

  return renderWindow;
}

void QuitRenderWindow(RenderWindow* renderWindow) {
  wgpuSurfaceRelease(renderWindow->wgpuSurface);
  wgpuInstanceRelease(renderWindow->wgpuInstance);
  SDL_DestroyWindow(renderWindow->window);
  SDL_memset(renderWindow, 0, sizeof(RenderWindow));
  SDL_Quit();
}