IMPORTANT NOTE: WebGPU currently has a design bug that viewport rectangles must be contained within the framebuffer boundaries (but technically this is only required for scissor rects). This makes it impossible to make the WebGPU backend behave identical with the other backends for viewport rectangles that clip the framebuffer boundaries (rendering will become distored).
[x] add a WebGPU caveats section to the sokol_gfx.h doc header:
[x] unfilterable_float/nonfiltering texture/sampler combos (also mention new sokol-shdc tags)
[x] bindgroup slot conventions for textures and samplers
[x] bindgroups cache behaviour
[x] unsupported vertex- and pixel-formats
[x] viewport clipping behaviour
[x] known performance issues (uniform setbindgroup performance?)
[x] test/fix language bindings:
[x] zig
[x] rust
[x] nim
[x] odin
[x] review and code cleanup
[x] fix Android problems:
[x] restart-sapp, sgl-sapp: Viewport bounds (x: -397.000000, y: 0.000000, width: 1775.000000, height: 1775.000000) contains a negative value (NOTE: this is actually a bug in WebGPU, negative viewport coordinates should definitely be allowed!)
[x] basisu-sapp, cgltf-sapp: Uncaught TypeError: Failed to execute 'createTexture' on 'GPUDevice': Failed to read the 'format' property from 'GPUTextureDescriptor': Required member is undefined.
[x] tex3d-sapp (actually also broken on desktop): Texture view array layer range (baseArrayLayer: 0, arrayLayerCount: 32) exceeds the texture's array layer count (1).
[x] figure out what to do with internal bindgroup objects whose pipeline, images or samplers are no longer valid... those would still pin their WebGPU textures and samplers, but since the textures are explicitly "destroyed", this probably wouldn't matter...? ...and sg_apply_bindgroup() would skip rendering anyway when trying to apply invalid resource objects... (solution: simply keep stale bindgroups in cache, textures are explicitely destroyed and don't cost much memory even when pinned by stale bindgroups)
[x] investigate/improve performance: currently a dumb draw loop like this is much slower than WebGL2: sg_apply_binding() => sg_apply_uniforms() => sg_draw()
[x] duplicate the above sample to wgpu/ to check against native Dawn:
[x] check what's going on down in the Metal debugger (Dawn doesn't work with the Metal debugger it seems)
[x] do some CPU profiling
[x] in sg_apply_bindings: filter redundant vertex- and index-buffer binding
[x] add a bindgroup cache
[x] in sg_apply_uniforms:
[x] attempt 1: copy to intermediate memory chunk, and do a single big writeBuffer at end of frame instead of many small writeBuffer
[x] attempt 2: go back to our own uniform buffer conveyor belt implementation
[x] any way to optimize the uniform SetBindGroup with dynamic offsets?
[x] fix wgsl binding conventions:
all images and sampler for a vertex/fragment shader pair go into group(1)
vertex stage images start at binding(0)
vertex stage sampler start at binding(16)
fragment stage images start at binding(32)
fragment stage samplers start at binding(48)
[x] sokol-shdc
[x] sokol-gfx
[x] wgpu samples
[x] fix all *-wgpu samples
[x] fix sg_append_buffer() (is this currently used anywhere in samples?)
[x] fix sokol-shdc wgpu output:
[x] writes wrong sampler bind slot constant
[x] wrong uniform buffer binding for fragment shader generated (e.g. first binding should be @group(0) @binding(4), not @group(0) @binding(0)
[x] generated uniform block structs are empty
[x] copy image data for compressed formats needs to take minimal width/height into account: copySize.width (2) is not a multiple of compressed texture format block width (4).
[x] sokol_imgui.h: allow rendering filterable vs non-filterable textures
[x] fix ETC2 support (if already testable on Android)
[x] apprently the restart-sapp sample is also broken on Android (which must be something else than ETC2)
[x] fix unfilterable textures and non-filtering samplers (needed in the shadows-depthtex-sapp sample to filter a depth texture with a regular sampler in the range [0, 1]
[x] harmonize sg_sampler_type with WGPUSamplerBindingType:
SG_SAMPLERTYPE_FILTERING
SG_SAMPLERTYPE_COMPARISON
SG_SAMPLERTYPE_NONFILTERING
[x] sg_make_shader validation:
[x] SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT, UINT, SINT must be used with SG_SAMPLERTYPE_NONFILTERING
[x] SG_IMAGESAMPLETYPE_DEPTH muse be used with SG_SAMPLERTYPE_COMPARISON
[x] sg_apply_bindings validation:
[x] bound texture pixel format vs shader's sg_image_sample_type
[x] sampler filtering vs shader's sg_sampler_type
[x] sokol-shdc:
NOTE: this idea sucks this information doesn't belong in the shader, because the same shader source for a filtering vs non-filtering texture access is the same, the difference is only on the binding side (the bound texture and sampler must match), new approach: patch image-sample-type and sampler-type into sg_shader_desc that's returned from code generation (sucks but should be a fairly rare case)
[x] need a hint that a texture is expected to be 'unfilterable-float' (maybe also sint and uint?), reflect these textures as SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT
[x] samplers in combination with unfilterable-float textures must be reflected as SG_SAMPLERTYPE_NONFILTERING
[x] proposal for hint: @image_sample_type [texname] unfilterable_float
[x] same for sampler type @sampler_type [smpname] nonfiltering
[x] error checking:
[x] tex/smpname doesn't exist this doesn't work when code is conditionally compiled with #ifdef (because tags are not affected by the conditional compilation - so GLSL textures or samplers my be removed by conditional compilation, and that can't be detected by the tag-validation, doh)
[x] texture sample type doesn't match sampler type
[x] update WebGPU Emscripten setup in sokol_app.h
[x] in debug mode, wgpu errors should be reported at function exit, not at end of frame (error reporting is handled automatically when running in browser)
[x] tighten sampler validation: with anisotropy > 0, all filters must be linear in WebGPU
[x] separate issue sg_image.data overhaul:
[x] write a cubemap sample
[x] write a mipmapped cubemap sample (switch through mipmaps with keys)
[x] fix cubemap support
[x] fix embedded shaders in sokol-headers
[x] sokol_debugtext.h
[x] sokol_imgui.h
[x] sokol_nuklear.h
[x] sokol_spine.h
[x] sokol_fontstash.h
[x] sokol_gl.h (what about pointsize???)
[x] fix *-sapp samples:
[x] clear
[x] triangle
[x] quad
[x] bufferoffsets
[x] cube
[x] noninterleaved
[x] texcube
[x] offscreen
[x] offscreen-msaa
[x] shadows
[x] shadows-depthtex (needs UnfilterableFloat + NonFiltering fix in sokol-shdc and sokol-gfx)
[x] instancing
[x] mrt
[x] mrt-pixelformats
[x] arraytex
[x] tex3d
[x] dyntex
[x] mipmap
[x] basisu (sokol-gl)
[x] blend
[x] uvwrap
[x] uniformtypes (debugtext?)
[x] imgui
[x] imgui-dock
[x] imgui-highdpi
[x] cimgui
[x] imgui-usercallback
[x] imgui-images
[x] imgui-perf
[x] events
[x] pixelformats
[x] sgl
[x] sgl-lines
[x] sgl-points
[x] sgl-context
[x] sgl-microui
[x] nuklear
[x] nuklear-images
[x] cubemaprt
[x] sdf (WGSL: var ref is a reserved keyword)
[x] shapes
[x] shapes-transform
[x] primtypes (pointsize!)
[x] debugtext
[x] debugtext-printf
[x] debugtext-userfont
[x] debugtext-context
[x] debugtext-layers
[x] saudio
[x] icon
[x] droptest (currently broken, but unrelated to wgpu)
[x] fontstash
[x] fontstash-layers
[x] modplay
[x] restart
[x] plmpeg
[x] cgltf
[x] loadpng
[x] spine-simple
[x] spine-inspector
[x] spine-skinsets
[x] spine-layers
[x] spine-contexts
[x] spine-switch-skinsets
[x] ozz-anim
[x] ozz-skin (breaks when toggling joint texture -> needs to be fixed in sokol_imgui.h)
[x] shdfeatures
[x] noentry
Breaking changes:
sg_sampler_type renaming
Emscripten-related problems:
WebGPU shim doesn't seem to work with the Closure pass
wgpuDeviceGetLimits JS shim doesn't return a value
wgpuDeviceGetLimits JS shim doesn't set maxBindGroupsPlusVertexBuffers
IMPORTANT NOTE: WebGPU currently has a design bug that viewport rectangles must be contained within the framebuffer boundaries (but technically this is only required for scissor rects). This makes it impossible to make the WebGPU backend behave identical with the other backends for viewport rectangles that clip the framebuffer boundaries (rendering will become distored).
TODO:
wgpu/
to check against native Dawn:check what's going on down in the Metal debugger(Dawn doesn't work with the Metal debugger it seems)attempt 2: go back to our own uniform buffer conveyor belt implementationany way to optimize the uniform SetBindGroup with dynamic offsets?@group(0) @binding(4)
, not@group(0) @binding(0)
copySize.width (2) is not a multiple of compressed texture format block width (4).
SG_SAMPLERTYPE_NONFILTERING
=>WGPUSamplerBindingType_NonFiltering
sokol-shdc:this information doesn't belong in the shader, because the same shader source for a filtering vs non-filtering texture access is the same, the difference is only on the binding side (the bound texture and sampler must match), new approach: patch image-sample-type and sampler-type into sg_shader_desc that's returned from code generation (sucks but should be a fairly rare case)SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT
SG_SAMPLERTYPE_NONFILTERING
@image_sample_type [texname] unfilterable_float
@sampler_type [smpname] nonfiltering
tex/smpname doesn't existthis doesn't work when code is conditionally compiled with#ifdef
(because tags are not affected by the conditional compilation - so GLSL textures or samplers my be removed by conditional compilation, and that can't be detected by the tag-validation, doh)texture sample type doesn't match sampler typein debug mode, wgpu errors should be reported at function exit, not at end of frame(error reporting is handled automatically when running in browser)sg_image.data overhaul:write a mipmapped cubemap sample (switch through mipmaps with keys)Breaking changes:
Emscripten-related problems: