Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sokol-gfx: finalize wgpu backend #865

Merged
merged 99 commits into from
Oct 22, 2023
Merged

sokol-gfx: finalize wgpu backend #865

merged 99 commits into from
Oct 22, 2023

Conversation

floooh
Copy link
Owner

@floooh floooh commented Aug 3, 2023

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:

  • changelog
  • finalize sokol-shdc PR: Update for initial sokol-gfx webgpu backend. sokol-tools#107
  • finalize sokol-samples PR: Update for sokol-gfx webgpu backend. sokol-samples#125
  • add a WebGPU caveats section to the sokol_gfx.h doc header:
    • unfilterable_float/nonfiltering texture/sampler combos (also mention new sokol-shdc tags)
    • bindgroup slot conventions for textures and samplers
    • bindgroups cache behaviour
    • unsupported vertex- and pixel-formats
    • viewport clipping behaviour
    • known performance issues (uniform setbindgroup performance?)
  • test/fix language bindings:
    • zig
    • rust
    • nim
    • odin
  • review and code cleanup
  • fix Android problems:
    • 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!)
    • basisu-sapp, cgltf-sapp: Uncaught TypeError: Failed to execute 'createTexture' on 'GPUDevice': Failed to read the 'format' property from 'GPUTextureDescriptor': Required member is undefined.
    • tex3d-sapp (actually also broken on desktop): Texture view array layer range (baseArrayLayer: 0, arrayLayerCount: 32) exceeds the texture's array layer count (1).
  • tweak and cross-link sample webpages
  • fix webpage deploy gh action script
  • add buffer-destroy and texture-destroy calls
  • implement draw-stats (most importantly: wgpu bindcache hits, misses, hash collisions, hash key collisions
    • generic
    • d3d11
    • gl
    • metal
    • wgpu
  • sokol_gfx_imgui.h: frame stats panel
  • add webgpu compile test
  • 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)
  • investigate/improve performance: currently a dumb draw loop like this is much slower than WebGL2: sg_apply_binding() => sg_apply_uniforms() => sg_draw()
    • see WebGL2 sample: https://floooh.github.io/sokol-html5/drawcallperf-sapp.html
    • see WebGPU sample: https://floooh.github.io/sokol-webgpu/drawcallperf-sapp.html
    • duplicate the above sample to 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)
      • do some CPU profiling
    • in sg_apply_bindings: filter redundant vertex- and index-buffer binding
    • add a bindgroup cache
    • in sg_apply_uniforms:
      • attempt 1: copy to intermediate memory chunk, and do a single big writeBuffer at end of frame instead of many small writeBuffer
      • attempt 2: go back to our own uniform buffer conveyor belt implementation
      • any way to optimize the uniform SetBindGroup with dynamic offsets?
  • 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)
    • sokol-shdc
    • sokol-gfx
    • wgpu samples
  • fix all *-wgpu samples
  • fix sg_append_buffer() (is this currently used anywhere in samples?)
  • fix sokol-shdc wgpu output:
    • writes wrong sampler bind slot constant
    • wrong uniform buffer binding for fragment shader generated (e.g. first binding should be @group(0) @binding(4), not @group(0) @binding(0)
    • generated uniform block structs are empty
  • 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).
  • sokol_imgui.h: allow rendering filterable vs non-filterable textures
  • fix ETC2 support (if already testable on Android)
  • apprently the restart-sapp sample is also broken on Android (which must be something else than ETC2)
  • clean up pixel format caps (see https://www.w3.org/TR/webgpu/#texture-format-caps)
  • 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]
    • sokol-gfx: add SG_SAMPLERTYPE_NONFILTERING => WGPUSamplerBindingType_NonFiltering
    • harmonize sg_sampler_type with WGPUSamplerBindingType:
      • SG_SAMPLERTYPE_FILTERING
      • SG_SAMPLERTYPE_COMPARISON
      • SG_SAMPLERTYPE_NONFILTERING
    • sg_make_shader validation:
      • SG_IMAGESAMPLETYPE_UNFILTERABLE_FLOAT, UINT, SINT must be used with SG_SAMPLERTYPE_NONFILTERING
      • SG_IMAGESAMPLETYPE_DEPTH muse be used with SG_SAMPLERTYPE_COMPARISON
    • sg_apply_bindings validation:
      • bound texture pixel format vs shader's sg_image_sample_type
      • sampler filtering vs shader's sg_sampler_type
    • 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)
      • 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
      • samplers in combination with unfilterable-float textures must be reflected as SG_SAMPLERTYPE_NONFILTERING
      • proposal for hint: @image_sample_type [texname] unfilterable_float
      • same for sampler type @sampler_type [smpname] nonfiltering
      • error checking:
        • 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)
        • texture sample type doesn't match sampler type
  • update WebGPU Emscripten setup in sokol_app.h
  • 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)
  • tighten sampler validation: with anisotropy > 0, all filters must be linear in WebGPU
  • separate issue sg_image.data overhaul:
  • write a cubemap sample
  • write a mipmapped cubemap sample (switch through mipmaps with keys)
  • fix cubemap support
  • fix embedded shaders in sokol-headers
    • sokol_debugtext.h
    • sokol_imgui.h
    • sokol_nuklear.h
    • sokol_spine.h
    • sokol_fontstash.h
    • sokol_gl.h (what about pointsize???)
  • fix *-sapp samples:
    • clear
    • triangle
    • quad
    • bufferoffsets
    • cube
    • noninterleaved
    • texcube
    • offscreen
    • offscreen-msaa
    • shadows
    • shadows-depthtex (needs UnfilterableFloat + NonFiltering fix in sokol-shdc and sokol-gfx)
    • instancing
    • mrt
    • mrt-pixelformats
    • arraytex
    • tex3d
    • dyntex
    • mipmap
    • basisu (sokol-gl)
    • blend
    • uvwrap
    • uniformtypes (debugtext?)
    • imgui
    • imgui-dock
    • imgui-highdpi
    • cimgui
    • imgui-usercallback
    • imgui-images
    • imgui-perf
    • events
    • pixelformats
    • sgl
    • sgl-lines
    • sgl-points
    • sgl-context
    • sgl-microui
    • nuklear
    • nuklear-images
    • cubemaprt
    • sdf (WGSL: var ref is a reserved keyword)
    • shapes
    • shapes-transform
    • primtypes (pointsize!)
    • debugtext
    • debugtext-printf
    • debugtext-userfont
    • debugtext-context
    • debugtext-layers
    • saudio
    • icon
    • droptest (currently broken, but unrelated to wgpu)
    • fontstash
    • fontstash-layers
    • modplay
    • restart
    • plmpeg
    • cgltf
    • loadpng
    • spine-simple
    • spine-inspector
    • spine-skinsets
    • spine-layers
    • spine-contexts
    • spine-switch-skinsets
    • ozz-anim
    • ozz-skin (breaks when toggling joint texture -> needs to be fixed in sokol_imgui.h)
    • shdfeatures
    • 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

floooh added 29 commits July 30, 2023 17:58
floooh added 27 commits October 2, 2023 16:56
@floooh floooh marked this pull request as ready for review October 22, 2023 11:52
@floooh floooh merged commit 2f1ccc0 into master Oct 22, 2023
41 of 46 checks passed
@floooh floooh deleted the sgfx-wgpu branch October 22, 2023 12:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant