Skip to content

Commit

Permalink
new wgpu sample: vertexpulling-wgpu.c
Browse files Browse the repository at this point in the history
  • Loading branch information
floooh committed Mar 8, 2024
1 parent b05172b commit 1c6c6f5
Show file tree
Hide file tree
Showing 3 changed files with 179 additions and 2 deletions.
8 changes: 6 additions & 2 deletions metal/vertexpulling-metal.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ static void init(void) {
.logger.func = slog_func,
});

state.pass_action = (sg_pass_action) {
.colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 0.5f, 0.5f, 1.0f, 1.0f } },
};

vertex_t vertices[] = {
{ .pos = { -1.0, -1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.0, 1.0 } },
{ .pos = { 1.0, -1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.0, 1.0 } },
Expand Down Expand Up @@ -83,7 +87,7 @@ static void init(void) {

sg_shader shd = sg_make_shader(&(sg_shader_desc){
.vs.uniform_blocks[0].size = sizeof(vs_params_t),
.vs.storage_buffers[0].item_size = sizeof(vertex_t),
.vs.storage_buffers[0] = { .used = true, .readonly = true },
.vs.source =
"#include <metal_stdlib>\n"
"using namespace metal;\n"
Expand All @@ -95,7 +99,7 @@ static void init(void) {
" float4 color;\n"
"};\n"
"struct ssbo_t {\n"
" vertex_t vtx[1];\n"
" vertex_t vtx[1];\n" // MSL C++ doesn't have flexible array member support
"};\n"
"struct vs_out {\n"
" float4 pos [[position]];\n"
Expand Down
5 changes: 5 additions & 0 deletions wgpu/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,8 @@ fips_begin_app(drawcallperf-wgpu windowed)
fips_files(drawcallperf-wgpu.c)
fips_deps(wgpu_entry cimgui)
fips_end_app()

fips_begin_app(vertexpulling-wgpu windowed)
fips_files(vertexpulling-wgpu.c)
fips_deps(wgpu_entry)
fips_end_app()
168 changes: 168 additions & 0 deletions wgpu/vertexpulling-wgpu.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
//------------------------------------------------------------------------------
// vertexpulling-wgpu.c
//
// Demonstrates vertex pulling from storage buffers.
//------------------------------------------------------------------------------
#include "wgpu_entry.h"
#define SOKOL_IMPL
#define SOKOL_WGPU
#include "sokol_gfx.h"
#include "sokol_log.h"
#define HANDMADE_MATH_IMPLEMENTATION
#define HANDMADE_MATH_NO_SSE
#include "HandmadeMath.h"

static struct {
sg_pass_action pass_action;
sg_pipeline pip;
sg_bindings bind;
float rx, ry;
} state;

typedef struct {
float pos[4];
float color[4];
} vertex_t;

typedef struct {
hmm_mat4 mvp;
} vs_params_t;

static void init(void) {
sg_setup(&(sg_desc){
.environment = wgpu_environment(),
.logger.func = slog_func,
});

state.pass_action = (sg_pass_action) {
.colors[0] = { .load_action = SG_LOADACTION_CLEAR, .clear_value = { 0.5f, 0.5f, 1.0f, 1.0f } },
};

vertex_t vertices[] = {
{ .pos = { -1.0, -1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.0, 1.0 } },
{ .pos = { 1.0, -1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.0, 1.0 } },
{ .pos = { 1.0, 1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.0, 1.0 } },
{ .pos = { -1.0, 1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.0, 1.0 } },

{ .pos = { -1.0, -1.0, 1.0, 1.0 }, .color = { 0.0, 1.0, 0.0, 1.0 } },
{ .pos = { 1.0, -1.0, 1.0, 1.0 }, .color = { 0.0, 1.0, 0.0, 1.0 } },
{ .pos = { 1.0, 1.0, 1.0, 1.0 }, .color = { 0.0, 1.0, 0.0, 1.0 } },
{ .pos = { -1.0, 1.0, 1.0, 1.0 }, .color = { 0.0, 1.0, 0.0, 1.0 } },

{ .pos = { -1.0, -1.0, -1.0, 1.0 }, .color = { 0.0, 0.0, 1.0, 1.0 } },
{ .pos = { -1.0, 1.0, -1.0, 1.0 }, .color = { 0.0, 0.0, 1.0, 1.0 } },
{ .pos = { -1.0, 1.0, 1.0, 1.0 }, .color = { 0.0, 0.0, 1.0, 1.0 } },
{ .pos = { -1.0, -1.0, 1.0, 1.0 }, .color = { 0.0, 0.0, 1.0, 1.0 } },

{ .pos = { 1.0, -1.0, -1.0, 1.0 }, .color = {1.0, 0.5, 0.0, 1.0, } },
{ .pos = { 1.0, 1.0, -1.0, 1.0 }, .color = {1.0, 0.5, 0.0, 1.0, } },
{ .pos = { 1.0, 1.0, 1.0, 1.0 }, .color = {1.0, 0.5, 0.0, 1.0, } },
{ .pos = { 1.0, -1.0, 1.0, 1.0 }, .color = {1.0, 0.5, 0.0, 1.0, } },

{ .pos = { -1.0, -1.0, -1.0, 1.0 }, .color = { 0.0, 0.5, 1.0, 1.0 } },
{ .pos = { -1.0, -1.0, 1.0, 1.0 }, .color = { 0.0, 0.5, 1.0, 1.0 } },
{ .pos = { 1.0, -1.0, 1.0, 1.0 }, .color = { 0.0, 0.5, 1.0, 1.0 } },
{ .pos = { 1.0, -1.0, -1.0, 1.0 }, .color = { 0.0, 0.5, 1.0, 1.0 } },

{ .pos = { -1.0, 1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.5, 1.0 } },
{ .pos = { -1.0, 1.0, 1.0, 1.0 }, .color = { 1.0, 0.0, 0.5, 1.0 } },
{ .pos = { 1.0, 1.0, 1.0, 1.0 }, .color = { 1.0, 0.0, 0.5, 1.0 } },
{ .pos = { 1.0, 1.0, -1.0, 1.0 }, .color = { 1.0, 0.0, 0.5, 1.0 } }
};
state.bind.vs.storage_buffers[0] = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_STORAGEBUFFER,
.data = SG_RANGE(vertices),
});

uint16_t indices[] = {
0, 1, 2, 0, 2, 3,
6, 5, 4, 7, 6, 4,
8, 9, 10, 8, 10, 11,
14, 13, 12, 15, 14, 12,
16, 17, 18, 16, 18, 19,
22, 21, 20, 23, 22, 20
};
state.bind.index_buffer = sg_make_buffer(&(sg_buffer_desc){
.type = SG_BUFFERTYPE_INDEXBUFFER,
.data = SG_RANGE(indices)
});

sg_shader shd = sg_make_shader(&(sg_shader_desc){
.vs.uniform_blocks[0].size = sizeof(vs_params_t),
.vs.storage_buffers[0] = { .used = true, .readonly = true },
.vs.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
"}\n"
"struct vertex {\n"
" pos: vec4f,\n"
" color: vec4f,\n"
"}\n"
"struct sbuf {\n"
" vtx: array<vertex>,\n"
"}\n"
"@group(0) @binding(0) var<uniform> in: vs_params;\n"
"@group(1) @binding(64) var<storage, read> in_sbuf: sbuf;\n"
"struct vs_out {\n"
" @builtin(position) pos: vec4f,\n"
" @location(0) color: vec4f,\n"
"}\n"
"@vertex fn main(@builtin(vertex_index) vidx: u32) -> vs_out {\n"
" var out: vs_out;\n"
" out.pos = in.mvp * in_sbuf.vtx[vidx].pos;\n"
" out.color = in_sbuf.vtx[vidx].color;\n"
" return out;\n"
"}\n",
.fs.source =
"@fragment fn main(@location(0) color: vec4f) -> @location(0) vec4f {\n"
" return color;\n"
"}\n",
});

state.pip = sg_make_pipeline(&(sg_pipeline_desc){
.shader = shd,
.index_type = SG_INDEXTYPE_UINT16,
.depth = {
.compare = SG_COMPAREFUNC_LESS_EQUAL,
.write_enabled = true
},
.cull_mode = SG_CULLMODE_BACK,
});
}

static void frame(void) {
hmm_mat4 proj = HMM_Perspective(60.0f, (float)wgpu_width()/(float)wgpu_height(), 0.01f, 10.0f);
hmm_mat4 view = HMM_LookAt(HMM_Vec3(0.0f, 1.5f, 6.0f), HMM_Vec3(0.0f, 0.0f, 0.0f), HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 view_proj = HMM_MultiplyMat4(proj, view);

vs_params_t vs_params;
state.rx += 1.0f; state.ry += 2.0f;
hmm_mat4 rxm = HMM_Rotate(state.rx, HMM_Vec3(1.0f, 0.0f, 0.0f));
hmm_mat4 rym = HMM_Rotate(state.ry, HMM_Vec3(0.0f, 1.0f, 0.0f));
hmm_mat4 model = HMM_MultiplyMat4(rxm, rym);
vs_params.mvp = HMM_MultiplyMat4(view_proj, model);

sg_begin_pass(&(sg_pass){ .action = state.pass_action, .swapchain = wgpu_swapchain() });
sg_apply_pipeline(state.pip);
sg_apply_bindings(&state.bind);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &SG_RANGE(vs_params));
sg_draw(0, 36, 1);
sg_end_pass();
sg_commit();
}

static void shutdown(void) {
sg_shutdown();
}

int main() {
wgpu_start(&(wgpu_desc_t){
.init_cb = init,
.frame_cb = frame,
.shutdown_cb = shutdown,
.width = 640,
.height = 480,
.title = "vertexpulling-wgpu",
});
return 0;
}

0 comments on commit 1c6c6f5

Please sign in to comment.