summaryrefslogtreecommitdiff
path: root/src/tests/common/test_3d_helpers.cc
blob: 13e1cfe83129672a84e3085eeecbdb6a9f75c8be (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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// This file is part of the 64k demo project.
// Common WGPU initialization for 3D visual tests with surfaces.

#include "test_3d_helpers.h"
#include <cstdio>
#include <cstdlib>

WgpuSurfaceContext init_wgpu_with_surface(PlatformState* platform_state) {
  WgpuSurfaceContext ctx = {};

  WGPUInstance instance = wgpuCreateInstance(nullptr);
  if (!instance) {
    fprintf(stderr, "Failed to create WGPU instance.\n");
    exit(1);
  }

  ctx.surface = platform_create_wgpu_surface(instance, platform_state);
  if (!ctx.surface) {
    fprintf(stderr, "Failed to create WGPU surface.\n");
    exit(1);
  }

  WGPURequestAdapterOptions adapter_opts = {};
  adapter_opts.compatibleSurface = ctx.surface;
  adapter_opts.powerPreference = WGPUPowerPreference_HighPerformance;

#if defined(DEMO_CROSS_COMPILE_WIN32)
  auto on_adapter = [](WGPURequestAdapterStatus status, WGPUAdapter adapter,
                       const char* message, void* userdata) {
    if (status == WGPURequestAdapterStatus_Success) {
      *(WGPUAdapter*)userdata = adapter;
    }
  };
  wgpuInstanceRequestAdapter(instance, &adapter_opts, on_adapter, &ctx.adapter);
#else
  auto on_adapter = [](WGPURequestAdapterStatus status, WGPUAdapter adapter,
                       WGPUStringView message, void* userdata, void* user2) {
    (void)user2;
    if (status == WGPURequestAdapterStatus_Success) {
      *(WGPUAdapter*)userdata = adapter;
    }
  };
  WGPURequestAdapterCallbackInfo adapter_cb = {};
  adapter_cb.mode = WGPUCallbackMode_WaitAnyOnly;
  adapter_cb.callback = on_adapter;
  adapter_cb.userdata1 = &ctx.adapter;
  wgpuInstanceRequestAdapter(instance, &adapter_opts, adapter_cb);
#endif

  while (!ctx.adapter) {
    platform_wgpu_wait_any(instance);
  }

  WGPUDeviceDescriptor device_desc = {};

#if defined(DEMO_CROSS_COMPILE_WIN32)
  auto on_device = [](WGPURequestDeviceStatus status, WGPUDevice device,
                      const char* message, void* userdata) {
    if (status == WGPURequestDeviceStatus_Success) {
      *(WGPUDevice*)userdata = device;
    }
  };
  wgpuAdapterRequestDevice(ctx.adapter, &device_desc, on_device, &ctx.device);
#else
  auto on_device = [](WGPURequestDeviceStatus status, WGPUDevice device,
                      WGPUStringView message, void* userdata, void* user2) {
    (void)user2;
    if (status == WGPURequestDeviceStatus_Success) {
      *(WGPUDevice*)userdata = device;
    }
  };
  WGPURequestDeviceCallbackInfo device_cb = {};
  device_cb.mode = WGPUCallbackMode_WaitAnyOnly;
  device_cb.callback = on_device;
  device_cb.userdata1 = &ctx.device;
  wgpuAdapterRequestDevice(ctx.adapter, &device_desc, device_cb);
#endif

  while (!ctx.device) {
    platform_wgpu_wait_any(instance);
  }

  ctx.queue = wgpuDeviceGetQueue(ctx.device);

  WGPUSurfaceCapabilities caps = {};
  wgpuSurfaceGetCapabilities(ctx.surface, ctx.adapter, &caps);
  ctx.format = caps.formats[0];

  WGPUSurfaceConfiguration config = {};
  config.device = ctx.device;
  config.format = ctx.format;
  config.usage = WGPUTextureUsage_RenderAttachment;
  config.width = platform_state->width;
  config.height = platform_state->height;
  config.presentMode = WGPUPresentMode_Fifo;
  config.alphaMode = WGPUCompositeAlphaMode_Opaque;
  wgpuSurfaceConfigure(ctx.surface, &config);

  return ctx;
}