Skip to content

Commit

Permalink
update standalone wgpu samples for bindings cleanup (all except drawc…
Browse files Browse the repository at this point in the history
…allperf-wgpu)
  • Loading branch information
floooh committed Oct 2, 2024
1 parent 2137f17 commit 5007ea3
Show file tree
Hide file tree
Showing 8 changed files with 370 additions and 314 deletions.
34 changes: 17 additions & 17 deletions wgpu/imgui-wgpu.cc
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,6 @@
#include "sokol_log.h"
#include "imgui.h"

#if !defined(__EMSCRIPTEN__)
#include "GLFW/glfw3.h"
#endif

static const size_t MaxVertices = 64 * 1024;
static const size_t MaxIndices = MaxVertices * 3;
static const int Width = 1024;
Expand Down Expand Up @@ -98,17 +94,16 @@ static void init(void) {
img_desc.height = font_height;
img_desc.pixel_format = SG_PIXELFORMAT_RGBA8;
img_desc.data.subimage[0][0] = sg_range{ font_pixels, size_t(font_width * font_height * 4) };
state.bind.fs.images[0] = sg_make_image(&img_desc);
state.bind.images[0] = sg_make_image(&img_desc);

sg_sampler_desc smp_desc = { };
smp_desc.wrap_u = SG_WRAP_CLAMP_TO_EDGE;
smp_desc.wrap_v = SG_WRAP_CLAMP_TO_EDGE;
state.bind.fs.samplers[0] = sg_make_sampler(&smp_desc);
state.bind.samplers[0] = sg_make_sampler(&smp_desc);

// shader object for imgui rendering
sg_shader_desc shd_desc = { };
shd_desc.vs.uniform_blocks[0].size = sizeof(vs_params_t);
shd_desc.vs.source =
shd_desc.vertex_func.source =
"struct vs_params {\n"
" disp_size: vec2f,\n"
"}\n"
Expand All @@ -125,17 +120,22 @@ static void init(void) {
" out.color = color;\n"
" return out;\n"
"}\n";
shd_desc.fs.images[0].used = true;
shd_desc.fs.samplers[0].used = true;
shd_desc.fs.image_sampler_pairs[0].used = true;
shd_desc.fs.image_sampler_pairs[0].image_slot = 0;
shd_desc.fs.image_sampler_pairs[0].sampler_slot = 0;
shd_desc.fs.source =
"@group(1) @binding(48) var tex: texture_2d<f32>;\n"
"@group(1) @binding(64) var smp: sampler;\n"
shd_desc.fragment_func.source =
"@group(1) @binding(0) var tex: texture_2d<f32>;\n"
"@group(1) @binding(1) var smp: sampler;\n"
"@fragment fn main(@location(0) uv: vec2f, @location(1) color: vec4f) -> @location(0) vec4f {\n"
" return textureSample(tex, smp, uv) * color;\n"
"}\n";
shd_desc.uniform_blocks[0].stage = SG_SHADERSTAGE_VERTEX;
shd_desc.uniform_blocks[0].size = sizeof(vs_params_t);
shd_desc.uniform_blocks[0].wgsl_group0_binding_n = 0;
shd_desc.images[0].stage = SG_SHADERSTAGE_FRAGMENT;
shd_desc.images[0].wgsl_group1_binding_n = 0;
shd_desc.samplers[0].stage = SG_SHADERSTAGE_FRAGMENT;
shd_desc.samplers[0].wgsl_group1_binding_n = 1;
shd_desc.image_sampler_pairs[0].stage = SG_SHADERSTAGE_FRAGMENT;
shd_desc.image_sampler_pairs[0].image_slot = 0;
shd_desc.image_sampler_pairs[0].sampler_slot = 0;
sg_shader shd = sg_make_shader(&shd_desc);

// pipeline object for imgui rendering
Expand Down Expand Up @@ -220,7 +220,7 @@ void draw_imgui(ImDrawData* draw_data) {
vs_params.disp_size.x = ImGui::GetIO().DisplaySize.x;
vs_params.disp_size.y = ImGui::GetIO().DisplaySize.y;
sg_apply_pipeline(state.pip);
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, SG_RANGE(vs_params));
sg_apply_uniforms(0, SG_RANGE(vs_params));
for (int cl_index = 0; cl_index < draw_data->CmdListsCount; cl_index++) {
const ImDrawList* cl = draw_data->CmdLists[cl_index];

Expand Down
97 changes: 59 additions & 38 deletions wgpu/inject-wgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,17 @@
#define IMG_WIDTH (32)
#define IMG_HEIGHT (32)

// FIXME: temp workaround until emsdk webgpu.h catches up
#if defined(__EMSCRIPTEN__)
static const char* strview(const char* str) {
return str;
}
#else
static WGPUStringView strview(const char* str) {
return (WGPUStringView){ .data = str, .length = strlen(str) };
}
#endif

static struct {
sg_pass_action pass_action;
sg_pipeline pip;
Expand Down Expand Up @@ -100,7 +111,7 @@ static void init(void) {
};

state.wgpu_vbuf = wgpuDeviceCreateBuffer(wgpu_dev, &(WGPUBufferDescriptor){
.label = "wgpu-vertex-buffer",
.label = strview("wgpu-vertex-buffer"),
.size = sizeof(vertices),
.usage = WGPUBufferUsage_Vertex | WGPUBufferUsage_CopyDst,
.mappedAtCreation = true,
Expand All @@ -111,7 +122,7 @@ static void init(void) {
wgpuBufferUnmap(state.wgpu_vbuf);

state.wgpu_ibuf = wgpuDeviceCreateBuffer(wgpu_dev, &(WGPUBufferDescriptor){
.label = "wgpu-index-buffer",
.label = strview("wgpu-index-buffer"),
.size = roundup(sizeof(indices), 4),
.usage = WGPUBufferUsage_Index | WGPUBufferUsage_CopyDst,
.mappedAtCreation = true,
Expand Down Expand Up @@ -140,7 +151,7 @@ static void init(void) {

// create dynamically updated WebGPU texture object
state.wgpu_tex = wgpuDeviceCreateTexture(wgpu_dev, &(WGPUTextureDescriptor) {
.label = "wgpu-texture",
.label = strview("wgpu-texture"),
.usage = WGPUTextureUsage_TextureBinding | WGPUTextureUsage_CopyDst,
.dimension = WGPUTextureDimension_2D,
.size = {
Expand All @@ -159,20 +170,20 @@ static void init(void) {
sg_reset_state_cache();

// ... and the sokol-gfx texture object with the injected WGPU texture
state.bind.fs.images[0] = sg_make_image(&(sg_image_desc){
state.bind.images[0] = sg_make_image(&(sg_image_desc){
.usage = SG_USAGE_STREAM,
.width = IMG_WIDTH,
.height = IMG_HEIGHT,
.pixel_format = SG_PIXELFORMAT_RGBA8,
.wgpu_texture = state.wgpu_tex,
.wgpu_texture_view = state.wgpu_tex_view,
});
assert(sg_wgpu_query_image_info(state.bind.fs.images[0]).tex == state.wgpu_tex);
assert(sg_wgpu_query_image_info(state.bind.fs.images[0]).view == state.wgpu_tex_view);
assert(sg_wgpu_query_image_info(state.bind.images[0]).tex == state.wgpu_tex);
assert(sg_wgpu_query_image_info(state.bind.images[0]).view == state.wgpu_tex_view);

// a WebGPU sampler object...
state.wgpu_smp = wgpuDeviceCreateSampler(wgpu_dev, &(WGPUSamplerDescriptor){
.label = "wgpu-sampler",
.label = strview("wgpu-sampler"),
.addressModeU = WGPUAddressMode_Repeat,
.addressModeV = WGPUAddressMode_Repeat,
.magFilter = WGPUFilterMode_Linear,
Expand All @@ -182,45 +193,55 @@ static void init(void) {
sg_reset_state_cache();

// ...and a matching sokol-gfx sampler with injected WebGPU sampler
state.bind.fs.samplers[0] = sg_make_sampler(&(sg_sampler_desc){
state.bind.samplers[0] = sg_make_sampler(&(sg_sampler_desc){
.wrap_u = SG_WRAP_REPEAT,
.wrap_v = SG_WRAP_REPEAT,
.min_filter = SG_FILTER_LINEAR,
.mag_filter = SG_FILTER_LINEAR,
.wgpu_sampler = state.wgpu_smp,
});
assert(sg_wgpu_query_sampler_info(state.bind.fs.samplers[0]).smp == state.wgpu_smp);
assert(sg_wgpu_query_sampler_info(state.bind.samplers[0]).smp == state.wgpu_smp);

// a sokol-gfx shader object
sg_shader shd = sg_make_shader(&(sg_shader_desc){
.vs = {
.uniform_blocks[0].size = sizeof(vs_params_t),
.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
"}\n"
"@group(0) @binding(0) var<uniform> in: vs_params;\n"
"struct vs_out {\n"
" @builtin(position) pos: vec4f,\n"
" @location(0) uv: vec2f,\n"
"}\n"
"@vertex fn main(@location(0) pos: vec4f, @location(1) uv: vec2f) -> vs_out {\n"
" var out: vs_out;\n"
" out.pos = in.mvp * pos;\n"
" out.uv = uv;\n"
" return out;\n"
"}\n"
.vertex_func.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
"}\n"
"@group(0) @binding(0) var<uniform> in: vs_params;\n"
"struct vs_out {\n"
" @builtin(position) pos: vec4f,\n"
" @location(0) uv: vec2f,\n"
"}\n"
"@vertex fn main(@location(0) pos: vec4f, @location(1) uv: vec2f) -> vs_out {\n"
" var out: vs_out;\n"
" out.pos = in.mvp * pos;\n"
" out.uv = uv;\n"
" return out;\n"
"}\n",
.fragment_func.source =
"@group(1) @binding(0) var tex: texture_2d<f32>;\n"
"@group(1) @binding(1) var smp: sampler;\n"
"@fragment fn main(@location(0) uv: vec2f) -> @location(0) vec4f {\n"
" return textureSample(tex, smp, uv);\n"
"}\n",
.uniform_blocks[0] = {
.stage = SG_SHADERSTAGE_VERTEX,
.size = sizeof(vs_params_t),
.wgsl_group0_binding_n = 0,
},
.images[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.wgsl_group1_binding_n = 0,
},
.samplers[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.wgsl_group1_binding_n = 1,
},
.fs = {
.images[0].used = true,
.samplers[0].used = true,
.image_sampler_pairs[0] = { .used = true, .image_slot = 0, .sampler_slot = 0 },
.source =
"@group(1) @binding(48) var tex: texture_2d<f32>;\n"
"@group(1) @binding(64) var smp: sampler;\n"
"@fragment fn main(@location(0) uv: vec2f) -> @location(0) vec4f {\n"
" return textureSample(tex, smp, uv);\n"
"}\n"
.image_sampler_pairs[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.image_slot = 0,
.sampler_slot = 0,
},
});
assert(sg_wgpu_query_shader_info(shd).vs_mod != 0);
Expand Down Expand Up @@ -274,12 +295,12 @@ void frame() {
}
state.counter++;
sg_image_data content = { .subimage[0][0] = SG_RANGE(state.pixels) };
sg_update_image(state.bind.fs.images[0], &content);
sg_update_image(state.bind.images[0], &content);

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_apply_uniforms(0, &SG_RANGE(vs_params));
sg_draw(0, 36, 1);
sg_end_pass();
sg_commit();
Expand Down
72 changes: 41 additions & 31 deletions wgpu/mipmap-wgpu.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ static void init(void) {
}

// create a single image and 12 samplers
state.bind.fs.images[0] = sg_make_image(&(sg_image_desc){
state.bind.images[0] = sg_make_image(&(sg_image_desc){
.width = 256,
.height = 256,
.num_mipmaps = 9,
Expand Down Expand Up @@ -135,35 +135,45 @@ static void init(void) {

// a shader object
sg_shader shd = sg_make_shader(&(sg_shader_desc){
.vs = {
.uniform_blocks[0].size = sizeof(vs_params_t),
.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
"}\n"
"@group(0) @binding(0) var<uniform> in: vs_params;\n"
"struct vs_out {\n"
" @builtin(position) pos: vec4f,\n"
" @location(0) uv: vec2f,\n"
"}\n"
"@vertex fn main(@location(0) pos: vec4f, @location(1) uv: vec2f) -> vs_out {\n"
" var out: vs_out;\n"
" out.pos = in.mvp * pos;\n"
" out.uv = uv;\n"
" return out;\n"
"}\n"
.vertex_func.source =
"struct vs_params {\n"
" mvp: mat4x4f,\n"
"}\n"
"@group(0) @binding(0) var<uniform> in: vs_params;\n"
"struct vs_out {\n"
" @builtin(position) pos: vec4f,\n"
" @location(0) uv: vec2f,\n"
"}\n"
"@vertex fn main(@location(0) pos: vec4f, @location(1) uv: vec2f) -> vs_out {\n"
" var out: vs_out;\n"
" out.pos = in.mvp * pos;\n"
" out.uv = uv;\n"
" return out;\n"
"}\n",
.fragment_func.source =
"@group(1) @binding(0) var tex: texture_2d<f32>;\n"
"@group(1) @binding(1) var smp: sampler;\n"
"@fragment fn main(@location(0) uv: vec2f) -> @location(0) vec4f {\n"
" return textureSample(tex, smp, uv);\n"
"}\n",
.uniform_blocks[0] = {
.stage = SG_SHADERSTAGE_VERTEX,
.size = sizeof(vs_params_t),
.wgsl_group0_binding_n = 0,
},
.images[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.wgsl_group1_binding_n = 0,
},
.samplers[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.wgsl_group1_binding_n = 1,
},
.image_sampler_pairs[0] = {
.stage = SG_SHADERSTAGE_FRAGMENT,
.image_slot = 0,
.sampler_slot = 0,
},
.fs = {
.images[0].used = true,
.samplers[0].used = true,
.image_sampler_pairs[0] = { .used = true, .image_slot = 0, .sampler_slot = 0 },
.source =
"@group(1) @binding(48) var tex: texture_2d<f32>;\n"
"@group(1) @binding(64) var smp: sampler;\n"
"@fragment fn main(@location(0) uv: vec2f) -> @location(0) vec4f {\n"
" return textureSample(tex, smp, uv);\n"
"}\n"
}
});

// pipeline state
Expand Down Expand Up @@ -192,10 +202,10 @@ static void frame(void) {
const float x = ((float)(i & 3) - 1.5f) * 2.0f;
const float y = ((float)(i / 4) - 1.0f) * -2.0f;
hmm_mat4 model = HMM_MultiplyMat4(HMM_Translate(HMM_Vec3(x, y, 0.0f)), rm);
state.bind.fs.samplers[0] = state.smp[i];
state.bind.samplers[0] = state.smp[i];
sg_apply_bindings(&state.bind);
const vs_params_t vs_params = { .mvp = HMM_MultiplyMat4(view_proj, model) };
sg_apply_uniforms(SG_SHADERSTAGE_VS, 0, &SG_RANGE(vs_params));
sg_apply_uniforms(0, &SG_RANGE(vs_params));
sg_draw(0, 4, 1);
}
sg_end_pass();
Expand Down
Loading

0 comments on commit 5007ea3

Please sign in to comment.