Skip to content

Commit

Permalink
Merge branch 'main' of github.com:eliemichel/LearnWebGPU
Browse files Browse the repository at this point in the history
  • Loading branch information
eliemichel committed Jun 19, 2024
2 parents fc19468 + c6cddc7 commit d7ad46e
Show file tree
Hide file tree
Showing 9 changed files with 16 additions and 16 deletions.
4 changes: 2 additions & 2 deletions advanced-techniques/benchmarking/time.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ submit_to_do_on_gpu(write_current_time, end_timestamp_query)

We must then **fetch** the timestamp values back to the CPU, through a mapped buffer like we see in [Playing with buffers](../../basic-3d-rendering/input-geometry/playing-with-buffers.md#mapping-context).

> 🫡 Okey, got it, so what about actual C++ code?
> 🫡 Okay, got it, so what about actual C++ code?
Whether they measure timestamps or other things, GPU queries are stored in a `QuerySet`. We typically store both the start and end time in the same set:

Expand Down Expand Up @@ -293,7 +293,7 @@ Reading timestamps

### Resolving timestamps

Okey, the render pass writes to our first query when it begins, and writes to the second query when it ends. We only need to compute the difference now, right? But the timestamps still **live in the GPU memory**, so we first need to **fetch them back** to the CPU.
Okay, the render pass writes to our first query when it begins, and writes to the second query when it ends. We only need to compute the difference now, right? But the timestamps still **live in the GPU memory**, so we first need to **fetch them back** to the CPU.

The first step consists in **resolving** the query. This gets the timestamp values from whatever internal representation the WebGPU implementation uses to store query set and write them in a **GPU buffer**.

Expand Down
2 changes: 1 addition & 1 deletion appendices/custom-extensions/with-dawn.md
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ I leave the feature state to `Stable` for the sake of simplicity. If you want to

### Backend change (Vulkan)

Okey now our feature is correctly wired up in the internal API, but so far **none of the backends support it**! At this stage we must focus on **a single one at a time**.
Okay, now our feature is correctly wired up in the internal API, but so far **none of the backends support it**! At this stage we must focus on **a single one at a time**.

We start with **Vulkan**, looking inside `dawn/src/dawn/native/vulkan`. So let's first force the Vulkan backend in our application:

Expand Down
2 changes: 1 addition & 1 deletion basic-3d-rendering/hello-triangle.md
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,7 @@ pipelineDesc.multisample.mask = ~0u;
pipelineDesc.multisample.alphaToCoverageEnabled = false;
```

Okey, we finally **configured all the stages** of the render pipeline. All that remains now is to specify the behavior of the two **programmable stages**, namely give a **vertex** and a **fragment shaders**.
Okay, we finally **configured all the stages** of the render pipeline. All that remains now is to specify the behavior of the two **programmable stages**, namely give a **vertex** and a **fragment shaders**.

Shaders
-------
Expand Down
2 changes: 1 addition & 1 deletion basic-3d-rendering/shader-uniforms/a-first-uniform.md
Original file line number Diff line number Diff line change
Expand Up @@ -354,7 +354,7 @@ The fields `binding.sampler` and `binding.textureView` are only needed when the

### Usage

Okay we are now ready to connect the dots! It is as simple as setting the bind group to use before the draw call:
Okay, we are now ready to connect the dots! It is as simple as setting the bind group to use before the draw call:

````{tab} With webgpu.hpp
```C++
Expand Down
2 changes: 1 addition & 1 deletion basic-3d-rendering/some-interaction/lighting-control.md
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ In this chapter we have:
- Connected lighting with GUI.
- Created a custom GUI.
Okey, we are now ready to dive into material models for real!
Okay, we are now ready to dive into material models for real!
````{tab} With webgpu.hpp
*Resulting code:* [`step100`](https://github.com/eliemichel/LearnWebGPU-Code/tree/step100)
Expand Down
4 changes: 2 additions & 2 deletions basic-compute/compute-pipeline.md
Original file line number Diff line number Diff line change
Expand Up @@ -332,7 +332,7 @@ The workgroup sizes must be constant expressions.

### Workgroup size vs count

> 😟 Okey, that makes a lot of variables just to set a number of jobs that is just the product of them in the end, doesn't it?
> 😟 Okay, that makes a lot of variables just to set a number of jobs that is just the product of them in the end, doesn't it?
The thing is: **all combinations are not equivalent**, even if they multiply to the same number of threads.

Expand All @@ -356,7 +356,7 @@ These rules are somehow contradictory. Only a benchmark on your specific use cas

### Workgroup dimensions

> 😟 Ok I see better now, but what about the different axes $w$, $h$ and $d$? Is a workgroup size of $2 \times 2 \times 4$ different from $16 \times 1 \times 1$?
> 😟 Okay, I see better now, but what about the different axes $w$, $h$ and $d$? Is a workgroup size of $2 \times 2 \times 4$ different from $16 \times 1 \times 1$?
It is different indeed, because this size **gives hints to the hardware** about the potential **consistency of memory access** across threads.

Expand Down
2 changes: 1 addition & 1 deletion getting-started/first-color.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ First, the render pipeline **does not draw directly on the texture that is curre

Second, drawing takes a **different time** than the frame rate required by your application, so the GPU may have to wait until the next frame is needed. There might be more than one off-screen texture waiting in the queue to be presented, so that fluctuations in the render time get amortized.

Last, **these off-screen textures are reused** as much as possible. As soon as a new texture is presented, the previous one can be reused as a target for the next frame. This whole mechanism of called a **Swap Chain** and is handled under teh hood by the **Surface** object.
Last, **these off-screen textures are reused** as much as possible. As soon as a new texture is presented, the previous one can be reused as a target for the next frame. This whole mechanism of called a **Swap Chain** and is handled under the hood by the **Surface** object.

```{note}
Remember that the GPU process runs at its own pace and that our CPU-issued commands are only asynchronously executed. Implementing the swap chain process manually would hence require a lot of boilerplate, so we are glad it is provided by the API!
Expand Down
2 changes: 1 addition & 1 deletion getting-started/hello-webgpu.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ The Dawn-based distribution I provide here fetches the source code of Dawn from
- The initial build takes significantly longer, and occupies more disk space overall.

````{note}
On Linux check out [Dawn's build documentation](https://dawn.googlesource.com/dawn/+/HEAD/docs/building.md) for teh list of packages to install. As of April 7, 2024, the list is the following (for Ubuntu):
On Linux check out [Dawn's build documentation](https://dawn.googlesource.com/dawn/+/HEAD/docs/building.md) for the list of packages to install. As of April 7, 2024, the list is the following (for Ubuntu):
```bash
sudo apt-get install libxrandr-dev libxinerama-dev libxcursor-dev mesa-common-dev libx11-xcb-dev pkg-config nodejs npm
Expand Down
12 changes: 6 additions & 6 deletions getting-started/opening-a-window.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ Application class

### Refactor

Let us **reorganize a bit our project** so that it is more Web-friendly and clearer about the **initialization** versus **main loop** separation.
Let us **reorganize our project a bit** so that it is more Web-friendly and clearer about the **initialization** versus **main loop** separation.

We create functions `Initialize()`, `MainLoop()` and `Terminate()` to split up the three key parts of our program. We also put **all the variables** that these functions share in a common class/struct, that we call for instance `Application`. For better readability, we may have `Initialize()`, `MainLoop()` and `Terminate()` be members of this class:

Expand Down Expand Up @@ -331,10 +331,10 @@ glfwTerminate();
```

```{important}
So **not** move the `emscripten_sleep(100)` line to `MainLoop()`. This line is no longer needed once we **let the browser handle** the main loop, because the browser ticks its WebGPU backend itself.
So **do not** move the `emscripten_sleep(100)` line to `MainLoop()`. This line is no longer needed once we **let the browser handle** the main loop, because the browser ticks its WebGPU backend itself.
```

Once you have move everything, you should end up with the following class attributes shared across init/main:
Once you have moved everything, you should end up with the following class attributes shared across init/main:

```{lit} C++, Application attributes
GLFWwindow *window;
Expand All @@ -348,7 +348,7 @@ The `WGPUInstance` and `WGPUAdapter` are intermediate steps towards getting the

### Emscripten

As mentionned multiple times above, explicitly writing the `while` loop is not possible when building for the **Web** (with Emscripten) because it **conflicts** with the web browser's own loop. We thus write the main loop differently in such a case:
As mentioned multiple times above, explicitly writing the `while` loop is not possible when building for the **Web** (with Emscripten) because it **conflicts** with the web browser's own loop. We thus write the main loop differently in such a case:

```{lit} C++, Main loop (replace)
#ifdef __EMSCRIPTEN__
Expand All @@ -374,7 +374,7 @@ int main() {
}
```

We use here the function [`emscripten_set_main_loop_arg()`](https://emscripten.org/docs/api_reference/emscripten.h.html#c.emscripten_set_main_loop_arg), which is precisely **dedicated to this issue**. This sets a **callback** that the browser will call each time it runs its main rendering loop.
Here we use the function [`emscripten_set_main_loop_arg()`](https://emscripten.org/docs/api_reference/emscripten.h.html#c.emscripten_set_main_loop_arg), which is precisely **dedicated to this issue**. This sets a **callback** that the browser will call each time it runs its main rendering loop.

```C++
// Callback type takes one argument of type 'void*' and returns nothing
Expand Down Expand Up @@ -406,7 +406,7 @@ emscripten_set_main_loop_arg(callback, &app, 0, true);
The extra arguments are recommended to be `0` and `true`:
- `fps` is the **framerate** at which the function gets called. For **better performance**, it is recommended to set it to 0 to leave it up to the browser (equivalent of usign `requestAnimationFrame` in JavaScript)
- `fps` is the **framerate** at which the function gets called. For **better performance**, it is recommended to set it to 0 to leave it up to the browser (equivalent of using `requestAnimationFrame` in JavaScript)
- `simulate_infinite_loop` must be `true` to prevent `app` from being freed. Otherwise, the `main` function **returns before the callback gets invoked**, so the application no longer exists and the `arg` pointer is *dangling* (i.e., points to nothing valid).
The Surface
Expand Down

0 comments on commit d7ad46e

Please sign in to comment.