Press ESC to close

Geometry Stress Test WebGPU: Benchmark GPU Langsung di Browser

Setelah di Part 2 kita bongkar bagaimana Basemark menggunakan WebGL 2.0 untuk melakukan pengujian performa, sekarang waktunya kita bikin versi buatan sendiri, Geometry Stress Test berbasis WebGPU.

Tujuan artikel atau tutorial kali ini adalah:

Menggambar ribuan segitiga acak di layar dan mengukur seberapa cepat GPU kamu menyelesaikannya.

▢️ Konsep Stress Test

Kita akan menggunakan WebGPU sebagai alat stress test rendering, dengan membebani GPU langsung dari browser dan menyuruhnya menggambar ribuan vertex segitiga secara acak.

Logika dasarnya:

  1. Buat N segitiga acak di koordinat NDC (-1…+1). Keterangan: NDC adalah Normalized Device Coordinates, atau istilahnya sistem koordinat di dunia grafik komputer.
  2. Render semuanya dalam satu pass.
  3. Ukur waktu render.
  4. Hitung operations per second (Ops/sec).

Output akhirnya semacam ini:

βœ… WebGPU aktif
GPU: ANGLE (Apple, ANGLE Metal Renderer: Apple M1, Unspecified Version) - (Google Inc. (Apple))
🎨 Geometry Stress Test selesai
Triangles     : 10
Vertices      : 30
GPU Time (ms) : 65.500
Ops/Second    : 916
Backend       : WebGPU (bgra8unorm)

▢️ Demo & Implementasi

Demo langsung bisa dicoba disini:

File yang digunakan:

- tests/geometry-test/
└─ test-geometri.js

1. Menyiapkan Data Geometri

Pada file test-geometri.js,

// file test-geometri.js
const triCount = 10000; // jumlah segitiga
const vertexCount = triCount * 3;
const vertexData = new Float32Array(vertexCount * 2);

for (let i = 0; i < vertexData.length; i++) {
  vertexData[i] = Math.random() * 2 - 1; // posisi acak di layar (-1 s.d 1)
}

const vertexBuffer = device.createBuffer({
  size: vertexData.byteLength,
  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST,
});
device.queue.writeBuffer(vertexBuffer, 0, vertexData);

Di bagian ini:

  • Kita mengirim data vertex (titik sudut 2D) ke GPU buffer agar bisa dirender.
  • Membuat ribuan segitiga acak di ruang NDC (Normalized Device Coordinates).
  • Setiap vertex memiliki 2 nilai (x, y).

2. Siapkan Shader Pipeline

const shader = /* wgsl */ `
  @vertex
  fn vs_main(@location(0) pos: vec2f) -> @builtin(position) vec4f {
    return vec4f(pos * 0.9, 0.0, 1.0); // sedikit diskalakan
  }
  @fragment
  fn fs_main() -> @location(0) vec4f {
    return vec4f(0.3, 0.7, 1.0, 1.0); // warna biru muda
  }
`;

const pipeline = device.createRenderPipeline({
  layout: "auto",
  vertex: {
    module: device.createShaderModule({ code: shader }),
    entryPoint: "vs_main",
    buffers: [
      {
        arrayStride: 8,
        attributes: [{ shaderLocation: 0, offset: 0, format: "float32x2" }],
      },
    ],
  },
  fragment: {
    module: device.createShaderModule({ code: shader }),
    entryPoint: "fs_main",
    targets: [{ format }],
  },
  primitive: { topology: "triangle-list", cullMode: "none" },
});

Ini adalah core dari geometry-test, dimana kita menggunakan wgsl untuk membuat gambar segitiga. Code tersebut mencakup beberapa hal, yakni:

  • Menentukan shader untuk vertex dan fragment (mengatur posisi & warna) pada const shader. (Menggunakan wgsl)
  • Membuat render pipeline melalui createRenderPipeline yang akan digunakan untuk menggambar semua segitiga.
  • arrayStride: 8 artinya setiap vertex punya dua angka float (2 Γ— 4 byte).

3. Menjalankan Render & Mengukur Waktu

const start = performance.now();

const encoder = device.createCommandEncoder();
const pass = encoder.beginRenderPass({
  colorAttachments: [
    {
      view: context.getCurrentTexture().createView(),
      clearValue: [0.05, 0.05, 0.07, 1.0],
      loadOp: "clear",
      storeOp: "store",
    },
  ],
});

pass.setPipeline(pipeline);
pass.setVertexBuffer(0, vertexBuffer);
pass.draw(vertexCount);
pass.end();

device.queue.submit([encoder.finish()]);
await device.queue.onSubmittedWorkDone();

const end = performance.now();
const gpuTime = (end - start).toFixed(3);

Di bagian akhir geometry-test.js, kita melakukan langkah finalisasi untuk:

  • Memulai render dan membersihkan layar.
  • Menjalankan pipeline untuk menggambar seluruh segitiga sekaligus.
  • Mengukur waktu dari submit hingga selesai (perkiraan waktu render GPU).

▢️ Kesimpulan

Dari test geometry diatas kita dapat menyimpulkan beberapa hal:

  • WebGPU mampu menggambar ribuan segitiga primitif dengan latency sangat rendah karena pipeline dan command encoder-nya langsung memetakan perintah ke API GPU native (Metal/Vulkan/D3D12).
  • Dalam tes nyata, perbedaan performa antara WebGL 2 vs WebGPU bisa mencapai 2–5Γ— tergantung arsitektur GPU.

Bagian selanjutnya: kita akan mencoba membuat Compute Pass WebGPU untuk simulasi fisika ringan, semacam β€œstress test + mini AI simulation” versi browser. Thanks & Stay tuned!

Muhammad K Huda

A non exhausted blogger person within fullstack engineer (spicy food), open source religion, self-taught driver and maybe you know or don't like it. Simply says, Hello from Me!

Leave a Reply

Your email address will not be published. Required fields are marked *

Cek untuk notifikasi e-mail jika komentar dibalas.

This site uses Akismet to reduce spam. Learn how your comment data is processed.