Skip to content

Conversation

@ygdrasil-io
Copy link
Contributor

Still a lot of work to do.
Most of the scenes on web are working perfectly, but there are some artifacts like this:

image

Any idea what is wrong ?

Introduced a new WebGPU rendering backend, including resource management for textures, timestamp queries, and pipeline operations. Updated build configurations and existing backend to integrate the new functionality seamlessly.
Replaced deprecated WebGPU API references and improved naming consistency in alignment with the latest standards. Adjustments include changes to enums, method parameters, and buffer descriptors to ensure compatibility and better code clarity.
Updated WebGPU code to align with new type system and API conventions, ensuring stronger type safety and removing deprecated functions. Introduced coroutine support in rendering workflow for improved thread management and data handling. Adjusted texture operations, render pipelines, and GPU interactions for consistency and performance enhancements.
Adapted type handling for UInt and updated WebGPU API calls for better clarity and correctness. Introduced `ComputePassTimestampWrites` and refined handling of depth and color attachments. Changed relevant functions to be `suspend` to align with coroutine-based execution.
Introduced `asArrayBuffer` for `Float32Buffer` with platform-specific implementations on Android, desktop, and JS. Made modifications for WebGPU-related types and methods to align better with updated APIs. Also refactored storage texture and buffer handling to improve type safety and ensure compatibility.
This commit extends the asArrayBuffer function to Int32Buffer and MixedBuffer across all platforms. It ensures consistent handling of buffer types and updates relevant usages to utilize the new method. Miscellaneous fixes to GPU binding and resource management are also included.
Introduced the `RenderBackendWebGpu` implementation and `createWebGpuRenderBackend` function for desktop, JS, and Android platforms. Updated backend selection logic to include the new WebGPU backend under the `WGPU` enum. Functionality is not yet fully implemented but lays the groundwork for future extensions.
Streamline texture handling by replacing intArray dimensions with Extent3D and updating GPUTextureUsage enums. Introduced multi-platform support for WgpuSurface and simplified buffer and surface operations for improved readability and maintainability. Added GlobalScope coroutine usage for rendering tasks on WebGPU backend.
This adds a new `asUInt32Array` function for converting `ArrayBuffer` to `UIntArray` across platforms. The implementation ensures better handling of typed array operations in WebGPU workflows, improving compatibility and utility.
Eliminated the WgpuRenderTarget interface and its implementation, WgpuCanvasRenderTarget, as they were unused and incomplete. Updated the backend selection in the demo code to recognize "wgpu" as a valid backend option.
Update size calculation to account for data element size (4 bytes). This ensures correct buffer allocation and prevents potential memory issues.
Replaced `_canvasFormat` with direct access to `surface.format` for improved clarity. Added a `format` property to `WgpuSurface` to ensure consistent texture format retrieval across the WebGPU pipeline.
Moved screen size update checks from platform-specific JS implementation to the common WebGPU backend. This ensures consistency and proper handling of resizing across all platforms.
Introduced `copyNativeTextureData` with platform-specific implementations for JS, Android, and Desktop. This enables handling platform-specific texture copying while maintaining common API structure. Unsupported platforms will throw an error for unimplemented cases.
Updated the texture views to use GPUTextureViewDimension.TwoD instead of ThreeD when creating source and destination views. This ensures compatibility and correct behavior for 2D texture rendering layers.
Updated the mapping of TexFormat.RG11B10_F to the correct GPUTextureFormat.RGBA16Float. This resolves an issue with incorrect format handling in texture processing.
This change sets `depthClearValue` to 1.0f during the render pass configuration. It ensures proper depth buffer initialization, preventing potential rendering issues.
Add support for `stripIndexFormat` in `PrimitiveState` to handle specific topologies like `TriangleStrip` and `LineList`. Updated pipelines to accommodate this change, improving render pipeline flexibility and compatibility.
Moved custom Maven repository to `settings.gradle.kts` for better management. Updated `webgpu-ktypes` to version `0.0.7-SNAPSHOT` and adjusted related library definitions. Cleaned up redundant repository declarations in `build.gradle.kts`.
Updated the conditional check to only set stripIndexFormat for TriangleStrip topology. This ensures correct behavior and avoids unnecessary settings for unsupported topologies.
Streamlined the conversion of `ArrayBuffer` to `UIntArray` by using `Int32Array` and added a safer cast. Removed redundant functions and imports for cleaner and more maintainable code.
This refactor standardizes naming conventions and improves clarity by using a more concise and consistent class name. All references, associated types, and methods have been updated accordingly.
Remove redundant canvas context setup and refactor surface configuration using `SurfaceConfiguration`. Simplifies rendering loop initialization and enhances code clarity.
Implemented a new WebGPU rendering backend for the desktop platform, including OS-specific surface creation and configuration. Updated build files to include necessary dependencies and provided a fallback mechanism when initialized in Lwjgl3Context.
The unused imports `glfwCreateWindow` and `MemoryUtil.NULL` were removed for cleaner code and improved maintainability. Additionally, included a call to `computeSurfaceCapabilities` to determine supported format and opacity for the surface.
Replaces `getCompilationInfo` with GPU error scopes for shader module error handling. Simplifies the process by logging validation errors directly, improving clarity and aligning with WebGPU best practices.
This change introduces error scopes with GPUErrorFilter.Validation during shader module creation for both fragment and compute shaders. It helps in catching and handling GPU validation errors more effectively, improving debugging and stability.
Replaced direct ArrayBuffer access methods with a callback-based approach for handling ArrayBuffer operations. This improves flexibility and ensures safer resource management across platforms. Updated related code to adopt the new callback pattern consistently.
ygdrasil-io and others added 4 commits May 27, 2025 14:34
The webgpu-ktypes library has been removed from the dependencies in both the individual listing and the wgpu4k bundle. This streamlines the setup by eliminating unused or unnecessary dependencies.
The webgpu-ktypes dependency has been removed from the project as it is no longer used. This cleanup helps reduce potential confusion and maintain a leaner dependency list.
This update introduces the webgpu-ktypes library (version 0.0.7) to the project. It will support functionalities related to WebGPU Kotlin types.
* Replace GPUBuffer with WGPUBuffer for WebGPU integration.

Changed all instances of `GPUBuffer` to `WGPUBuffer` to align with the updated WebGPU API. Simplified imports and adjusted associated method calls to reflect the new type.

* Refactor WebGPU enums to use string values directly

Replaced enum-like classes with direct string usage and removed unused or redundant values. The changes simplify the codebase, reduce redundancy, and improve maintainability by leveraging the `enumValue` property for direct string access. This also removes unnecessary enum definitions no longer in use.

* Refactor WebGPU enums to use string values directly

Replaced enum-like classes with direct string usage and removed unused or redundant values. The changes simplify the codebase, reduce redundancy, and improve maintainability by leveraging the `enumValue` property for direct string access. This also removes unnecessary enum definitions no longer in use.

* Refactor texture format handling to use string-based enum values.

Replaces GPUTextureFormat references with string-based `enumValue` usage for texture formats. This simplifies the code, removes the wgpuStorage extension, and aligns format handling for improved consistency across WebGPU pipelines.

* Rename `GpuBufferWgpu` to `GpuBufferWgpu2` and update references.

This change adjusts the naming convention to `GpuBufferWgpu2` for better alignment with the `GPUBuffer` type from `io.ygdrasil.webgpu`. All references and related code were updated accordingly to maintain consistency and ensure correct functionality.

* Refactor GPU buffer handling for consistency and clarity

Updated the GPU buffer API to use `oldBuffer` for handling underlying WGPU buffers and added a `toJs()` extension for conversion. This change aligns naming conventions, improves readability, and ensures consistent management of buffer operations across the codebase.

* Replace `oldBuffer` references with `buffer.toJs()`.

This refactor streamlines the code by replacing all occurrences of `oldBuffer` with the updated `buffer.toJs()` syntax. The changes improve compatibility with the new buffer handling approach while maintaining functionality throughout the WebGPU backend components.

* Refactor: Replace `GpuBufferWgpu2` with type alias

Simplified `GpuBufferWgpu2` by converting it to a type alias for `GpuBufferWgpu`. Removed redundant class implementation to reduce code duplication and improve maintainability.

* Refactor: Replace GpuBufferWgpu2 with GpuBufferWgpu

Unified the buffer type throughout the codebase by replacing the GpuBufferWgpu2 alias with GpuBufferWgpu directly. This improves code consistency and removes unnecessary typealias usage, simplifying future maintenance.

* Refactor GPUTextureUsage to use set-based flags.

Replaced bitwise OR operations with a set-based approach for GPUTextureUsage, converting sets to flags using `toFlagInt()` where necessary. This improves code clarity, aligns with modern practices, and simplifies handling of usage flags. Adjusted related imports and function calls accordingly.

* Refactor WebGPU texture handling to use `io.ygdrasil.webgpu`.

Replaced legacy `GPUTextureDescriptor` and related constructs with `io.ygdrasil.webgpu` equivalents (`TextureDescriptor`, `Extent3D`, etc.) for improved type safety and clarity. Adjusted all texture creation, dimension definitions, and usage flags to align with the new API structure.

* Refactor WebGPU backend to introduce GPUBackend interface

Extracted common GPU operations into a new GPUBackend interface for better modularity and reuse. Updated WgpuRenderBackend to implement the new interface and removed unused constants and functions from related classes.

* Rename WgpuTextureResource to OldWgpuTextureResource.

This change updates references and types throughout the codebase to reflect the renaming of `WgpuTextureResource` to `OldWgpuTextureResource`. Additionally, helper properties `oldImageInfo` and `oldGpuTexture` were introduced for compatibility where relevant.

* Refactor WebGPU code to use `oldDevice` abstraction

Replaced direct `backend.device` usage with `backend.oldDevice` across various classes. Introduced `oldDevice` property to abstract the device handling and streamline compatibility with updated WebGPU implementations.

* Refactor `WgpuTextureLoader` to use `GPUBackend` interface

Updated `WgpuTextureLoader` to depend on the `GPUBackend` interface instead of the concrete `RenderBackendWebGpu` class, improving modularity. Adjusted internal device access to handle type casting and compatibility with the updated backend structure.

* Refactor texture loader to use WgpuTextureLoader2.

Replaced `WgpuTextureLoader` with `WgpuTextureLoader2` for improved modularity and clarity. Adjusted related references and updated mipmap generation logic to align with the new structure.

* Refactor texture loading to use updated mipmap generator

Replaced `oldMipmapGenerator` with the existing `mipmapGenerator` for generating mip levels, ensuring consistency across texture operations. Removed the redundant `MipmapGenerator` inner class and associated logic, simplifying the codebase and reducing duplication.

* Refactor texture loading and enhance type consistency.

Replace `IntArray` with `Extent3D` for texture dimensions to improve type safety and consistency. Modify visibility of methods and properties in `WgpuTextureLoader` for planned optimization, with internal access for further encapsulation.

* Refactor texture handling to use `GPUOrigin3D` and cleanup.

Updated texture copy operations to use `GPUOrigin3D` instead of integer arrays for origin definitions. Added conversion utilities for `GPUOrigin3D` and refactored related code to improve clarity and maintainability.

* Refactor texture copy utilities to support GPUOrigin3D parameter

Introduces `GPUOrigin3D` handling across texture copying methods for better alignment with WebGPU specifications. Refactors related functions to maintain consistency and improve code readability while preserving backward compatibility.

* Refactor texture data handling for BufferedImageData

Replaced platform-specific implementations to better handle BufferedImageData processing using common functions. Improved type handling and added utilities for F32-to-F16 conversion to ensure compatibility across platforms.

* Refactor WebGPU texture loading for improved code reuse

Simplified `WgpuTextureLoader2` by delegating texture loading to `WgpuTextureLoader`. Removed duplicate texture loading and data copying logic. This enhances maintainability and reduces redundancy in texture handling code.

* Refactor WebGPU texture handling and update command encoding.

Replaced old GPU texture references with updated `gpuTexture` usage. Introduced `CommandEncoder` for more robust command encoding. Updated `WgpuTextureLoader2` to `WgpuTextureLoader3` to reflect changes in functionality.

* Remove unused WgpuTextureLoader2 class.

The WgpuTextureLoader2 class was redundant and has been removed, simplifying the codebase. References to it have been replaced with the existing WgpuTextureLoader class to maintain functionality.

* Refactor GPU buffer creation for better type safety.

Replaced raw integer usages with strongly-typed enums and updated buffer descriptor handling for improved clarity. Centralized and standardized `createBuffer` logic across backend implementations.

* Refactor texture data handling and buffer conversions

Refactored how texture data is copied and buffer types are converted, including support for Float16 buffers. Introduced `arrayBufferView` extension property and streamlined buffer handling logic to improve flexibility and maintainability. Added error handling for unsupported buffer types.

* Make texture loader methods and properties private.

Converted internal methods and properties in `WgpuTextureLoader` to private for better encapsulation and to adhere to proper access control practices. Removed redundant TODO comments as the changes address them directly.

* Change texture format selection to prefer 8Unorm without Srgb

Updated the format selection logic to prioritize formats containing "8Unorm" and excluding "Srgb". This ensures better compatibility and adheres to specific rendering requirements when such formats are available.

* Remove deprecated WebGPU backend code.

The old WebGPU backend implementation has been entirely removed to clean up the codebase. This includes multiple classes, helper utilities, and rendering-related components specific to the outdated backend. This prepares the project for newer, streamlined implementations.

* Update README to correct Android gradle task command

The documentation was updated to include the correct command for enabling the Android target (`./gradlew enableAndroidPlatform`). This ensures clarity for users setting up Android support.

* Add `asUIntArray` implementation and annotate with `OptIn`

Introduced the `asUIntArray` function in `ArrayBuffer` across multiple platforms, with required `@OptIn(ExperimentalUnsignedTypes::class)` annotations. Also updated `copyNativeTextureData` to include a new `dstOrigin` parameter for enhanced texture manipulation.
@ygdrasil-io
Copy link
Contributor Author

I've made quite a bit of progress. I had skipped the FP16 texture processing, but that's now fixed. Now all the examples work perfectly on the web, even those that aren't in the menu. I removed the old WebGPU backend since the behavior is now identical.

As for the desktop, it's more complicated. I fixed the colors by better selecting the surface texture format. I prioritize 8Unorm formats without sRGB, and now I have the same colors as on the web.

However, certain scenes like the island crash with the following logs:

   1,235 s|f:   9  D  AssetLoader.loadBlob: Loaded blob https://kool.blob.core.windows.net/kool-demo/heightmaps/terrain_ocean.raw (0.5 mb, 16.091667ms)
   1,432 s|f:  10  D  Wind: Generated wind density in 0.179 s, tex saturation: min = 0.08506501, max = 0.9578181
   1,488 s|f:  12  I  OpticalDepthLutPass: Updating atmosphere depth LUT: atmosphere radius = 65.0, surface radius: 60.0, falloff: 9.0
19 actionable tasks: 5 executed, 14 up-to-date

thread '<unnamed>' panicked at src/lib.rs:417:5:
wgpu uncaptured error:
Validation Error

Caused by:
  In wgpuRenderPassEncoderEnd
    In a pass parameter
      The color attachment at index 0's texture view is not renderable:
        The dimension of this texture view is not 2D. View dimension: D2Array

Not sure what is causing the crash yet, but that happened during the offscreen pass of "sky-cube". Maybe it's an issue when creating the texture, but that works on the web, so... @fabmax, any idea where to dig?

@fabmax
Copy link
Collaborator

fabmax commented May 29, 2025

Hmm that sounds like something is going wrong with rendering to cube textures. Iirc these are represented as 2d array textures with an array size of 6 (one for each side of the cube). Rendering to a cube texture than basically is a loop where you create a 2d view for each cube side and set that as the render target. The error sounds like it is trying to set the entire array as color attachment and not only a single side.

Enhanced ArrayBuffer operations by introducing new methods for memory segment conversion. Updated buffer manipulation logic for cleaner and more efficient handling.
Introduced `getCurrentTextureView()` for improved texture handling and updated `present()` to properly close and reset resources after presentation.
@ygdrasil-io ygdrasil-io marked this pull request as ready for review June 2, 2025 17:35
@ygdrasil-io
Copy link
Contributor Author

Not all examples necessarily work, but we now have similar behaviors between Firefox and the desktop (which is logical since it's the same backend).

There are still some samples that crash with the message:

  In wgpuDeviceCreateBindGroupLayout, label = 'up-sample-shader-bindGroupLayout[PIPELINE]'
    Binding 4 entry is invalid
      Read-write and read-only storage textures are not allowed by baseline webgpu, they require the native only feature TEXTURE_ADAPTER_SPECIFIC_FORMAT_FEATURES

But wgpu4k does not yet support enabling platform-specific features, I will fix this in the next version.

(Almost) the same code on Java/Firefox/Chrome/Safari (Island is crahsing on safari)
image

I tried on Mac and Windows, not sure if that is working on Linux.

Android-specific implementation still needs to be implemented, but that can be done in the next iteration.

@fabmax can we merge it in the current state, or do you want some changes?

@fabmax
Copy link
Collaborator

fabmax commented Jun 2, 2025

That is pretty awesome! On first glance it looks good already. I will give it a closer look + try tomorrow.

For the read-write storage texture access, I remember vaguely that that used to be a problem but at some point was supported by Chrome.

@fabmax
Copy link
Collaborator

fabmax commented Jun 3, 2025

I gave it a test. A few observations:

Browser (I only tried Chrome)

  • Everything works fine, but the instancing test (with instancing disabled) is a lot slower than it was. That test is a stress-test which draws 5000 individual cubes (one draw call per cube). The Scene recording time basically is the time spent in the backend. This isn't super critical because its a rather synthetic test and for typical browser scenes the number of draw calls is usually not the bottleneck. But the size of the difference is weird never the less. I haven't looked into the code too much yet. Maybe it's caused by the changed buffer data upload or something like that.

    Left is yours, right is how it was:
    image

Desktop (with WGPU backend)

  • Scaled display resolutions seem to not work. If I try to start it on a scaled display, it immediately crashes with this message (I only tried macOS):
wgpu uncaptured error:
Validation Error

Caused by:
  In wgpuRenderPassEncoderEnd
    In a set_viewport command
      Viewport has invalid rect Rect { x: 0.0, y: 0.0, w: 3200.0, h: 1800.0 }; origin and/or size is less than or equal to 0, and/or is not contained in the render target (1600, 900, 1)

  • When running the Fighting Bees demo, the console gets spammed with the following log message:
    20:41:16.761 [main] INFO io.ygdrasil.webgpu.Buffer_native -- mapped
    The log output even continues after switching away to another demo (but after restarting, it only begins when opening Fighting Bees)

  • Demos that use a skybox seem to only render the first mip-level of the skybox. That results in very glossy looking surfaces, because the higher mip-levels of the skybox are missing (the higher mip-levels are usually used for reflections of surfaces with higher roughness values). In the browser it looks fine.
    image2

@fabmax
Copy link
Collaborator

fabmax commented Jun 15, 2025

Ok, I changed stuff a little bit, since there were a few things I didn't like:

  • wgpu4k seems to require jdk version at least 22 (correct me if I'm wrong, but 21 doesn't work because some dependecies require at least v22). I wouldn't mind moving to a newer min jdk version but it should at least be an LTS version, so 21 currently. As a solution I moved wgpu4k into a separate module kool-backend-wgpu4k, so that kool-core can stay the way it is jdk version-wise.
  • The way the suspending functions were wrapped on js (with GlobalScope.launch {}) seemed a bit unsafe. Especially the way the backend was created with a lateinit member. I therefore reverted these functions to be non-suspending and moved the suspend wrapper code into the wgpu4k backend implementation. Only weird thing is that now GPUShaderModule.checkErrors in WgpuPipelineManager fails with some coroutine handler exception. I commented it out, so no error message currently if shader compilation fails.
  • I also restored the old WebGPU implementation in kool-core for now, since it seems to be faster.

kool-demo adds kool-backend-wgpu4k as a dependency so it is usable by simply setting config.renderBackend = Wgpu4kBackendProvider in code and adding &backend=wgpu4k to the url if it's running in the browser.

I think this is now mergable.

@ygdrasil-io
Copy link
Contributor Author

Thanks for the changes.

The project indeed requires Java 22 to use the stable Panama API. The next LTS is in September, which gives us time to fix the remaining issues.

I'm a little busy right now, but I will get back to this in a few weeks. If that's alright with you, you can merge it as is, and I will create dedicated issues and merge requests to fix what's wrong, starting with the web.

@fabmax fabmax merged commit a9a7ced into kool-engine:main Jun 17, 2025
@ygdrasil-io ygdrasil-io deleted the feature/wgpu4k-backend branch June 18, 2025 08:02
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.

2 participants