forked from juj/wasm_webgpu
-
Notifications
You must be signed in to change notification settings - Fork 0
/
hello_triangle_minimal.c
98 lines (75 loc) · 3.27 KB
/
hello_triangle_minimal.c
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
#include "lib_webgpu.h"
WGpuAdapter adapter;
WGpuCanvasContext canvasContext;
WGpuDevice device;
WGpuQueue queue;
WGpuRenderPipeline renderPipeline;
EM_BOOL raf(double time, void *userData)
{
WGpuCommandEncoder encoder = wgpu_device_create_command_encoder(device, 0);
WGpuRenderPassColorAttachment colorAttachment = WGPU_RENDER_PASS_COLOR_ATTACHMENT_DEFAULT_INITIALIZER;
colorAttachment.view = wgpu_texture_create_view(wgpu_canvas_context_get_current_texture(canvasContext), 0);
WGpuRenderPassDescriptor passDesc = {};
passDesc.numColorAttachments = 1;
passDesc.colorAttachments = &colorAttachment;
WGpuRenderPassEncoder pass = wgpu_command_encoder_begin_render_pass(encoder, &passDesc);
wgpu_render_pass_encoder_set_pipeline(pass, renderPipeline);
wgpu_render_pass_encoder_draw(pass, 3, 1, 0, 0);
wgpu_render_pass_encoder_end(pass);
WGpuCommandBuffer commandBuffer = wgpu_command_encoder_finish(encoder);
wgpu_queue_submit_one_and_destroy(queue, commandBuffer);
return EM_FALSE; // Render just one frame, static content
}
void ObtainedWebGpuDevice(WGpuDevice result, void *userData)
{
device = result;
queue = wgpu_device_get_queue(device);
canvasContext = wgpu_canvas_get_webgpu_context("canvas");
WGpuCanvasConfiguration config = WGPU_CANVAS_CONFIGURATION_DEFAULT_INITIALIZER;
config.device = device;
config.format = navigator_gpu_get_preferred_canvas_format();
wgpu_canvas_context_configure(canvasContext, &config);
const char *vertexShader =
"@vertex\n"
"fn main(@builtin(vertex_index) vertexIndex : u32) -> @builtin(position) vec4<f32> {\n"
"var pos = array<vec2<f32>, 3>(\n"
"vec2<f32>(0.0, 0.5),\n"
"vec2<f32>(-0.5, -0.5),\n"
"vec2<f32>(0.5, -0.5)\n"
");\n"
"return vec4<f32>(pos[vertexIndex], 0.0, 1.0);\n"
"}\n";
const char *fragmentShader =
"@fragment\n"
"fn main() -> @location(0) vec4<f32> {\n"
"return vec4<f32>(1.0, 0.5, 0.3, 1.0);\n"
"}\n";
WGpuShaderModuleDescriptor shaderModuleDesc = {};
shaderModuleDesc.code = vertexShader;
WGpuShaderModule vs = wgpu_device_create_shader_module(device, &shaderModuleDesc);
shaderModuleDesc.code = fragmentShader;
WGpuShaderModule fs = wgpu_device_create_shader_module(device, &shaderModuleDesc);
WGpuRenderPipelineDescriptor renderPipelineDesc = WGPU_RENDER_PIPELINE_DESCRIPTOR_DEFAULT_INITIALIZER;
renderPipelineDesc.vertex.module = vs;
renderPipelineDesc.vertex.entryPoint = "main";
renderPipelineDesc.fragment.module = fs;
renderPipelineDesc.fragment.entryPoint = "main";
WGpuColorTargetState colorTarget = WGPU_COLOR_TARGET_STATE_DEFAULT_INITIALIZER;
colorTarget.format = config.format;
renderPipelineDesc.fragment.numTargets = 1;
renderPipelineDesc.fragment.targets = &colorTarget;
renderPipeline = wgpu_device_create_render_pipeline(device, &renderPipelineDesc);
emscripten_request_animation_frame_loop(raf, 0);
}
void ObtainedWebGpuAdapter(WGpuAdapter result, void *userData)
{
adapter = result;
WGpuDeviceDescriptor deviceDesc = {};
wgpu_adapter_request_device_async(adapter, &deviceDesc, ObtainedWebGpuDevice, 0);
}
int main()
{
WGpuRequestAdapterOptions options = {};
options.powerPreference = WGPU_POWER_PREFERENCE_LOW_POWER;
navigator_gpu_request_adapter_async(&options, ObtainedWebGpuAdapter, 0);
}