首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将WebAsembly内存传递给WebGL2

将WebAsembly内存传递给WebGL2
EN

Stack Overflow用户
提问于 2018-07-07 19:49:44
回答 1查看 242关注 0票数 1

在WebGL2中,大多数现有函数的附加版本都接受允许在这些缓冲区中传递偏移量和长度的ArrayBuffer。据推测,这将使在不创建临时视图的情况下从WebAssembly内存传递数据变得更容易,但有一个问题:这些函数只接受ArrayBufferView

  1. 这种限制的原因是什么?为什么将字节复制到GPU的函数应该关心它们的语义,例如Uint8 8/Int32 32/Float32 32等等?
  2. 如何避免每次创建DataView (这将完全违背使用这些函数的目的)?创建DataView一次将无法工作,因为WebAssembly内存可以重新分配其缓冲区,并且无法设置回调以调整内存大小。
EN

回答 1

Stack Overflow用户

发布于 2018-07-07 20:57:18

我不知道为什么texImage2D等人会选择ArrayBufferView,而不仅仅是ArrayBuffer。我同意这似乎毫无意义。

在最坏的情况下,您应该只能在缓冲区更改时创建一个新视图。

示例:

代码语言:javascript
复制
;; hello.wat
(module
  ;; Import our trace function so that we can call it in main
  (import "env" "trace" (func $trace (param i32)))
  ;; Define our initial memory with a single page (64KiB).
  (memory $0 1)
  ;; Store a null terminated string at byte offset 0. 
  (data (i32.const 0) "Hello world!\00")
  ;; Export the memory so it can be read in the host environment.
  (export "memory" (memory $0))
  (func $alloc (param $0 i32) (result i32)
    get_local $0
    grow_memory
  )
  (export "alloc" (func $alloc))
  ;; Define the main function with no parameters.
  (func $main
    ;; Call the trace function with the constant value 0.
    (call $trace (i32.const 0))
  )
  ;; Export the main function so that the host can call it.
  (export "main" (func $main))
)

而那些叫它的js

代码语言:javascript
复制
// hello.js
async function doit() {
  const response = await fetch('../out/main.wasm');
  const buffer = await response.arrayBuffer();
  const module = await WebAssembly.compile(buffer);
  const instance = await WebAssembly.instantiate(module, {
    env: {
      trace
    }
  });

  let exports = instance.exports;

  let view = new Uint8Array(exports.memory.buffer);
  function getView() {
    if (view.buffer !== exports.memory.buffer) {
      console.log('new view');
      view = new Uint8Array(exports.memory.buffer);
    }
    return view;
  }

  function trace(byteOffset) {
    let s = '';
    const view = getView();
    for (let i = byteOffset; view[i]; i++) {
      s += String.fromCharCode(view[i]);
    }
    console.log(s);
  }

  exports.main();
  exports.main();
  exports.main();
  exports.alloc(10);
  exports.main();
  exports.main();
  exports.main();
}

doit().then(() => {
  console.log("done");
});

创建新视图的唯一时间是WebAssembly重新分配缓冲区时。

显然,您需要一种不同类型的视图,这取决于传递给WebGL2的WebGL2参数,因此您需要一组视图,而不仅仅是一个视图,并且根据类型参数,需要获得正确的视图类型。

抄录自评论:

  1. texImage2D和bufferData等函数通常不是在一个严格的循环中调用的函数,因此,通过以上点对它们进行优化看起来不是什么大事吗?检查很简单,不太可能影响性能,避免了GC。
  2. grow_memory被调用时,我没有找到任何方法来获得回调。另一方面,如果您正在编写自己的组件,则可以轻松地让所有grow_memory调用通过自己的函数,并将该函数调用到JavaScript中以更新视图。我猜这就是应征码的功劳。它有一个运行库。我假设运行库是在它们想要增长内存时调用的,这样它们就可以更新它们的视图。
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/51226502

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档