在HankMoody的评论之后更新这个。我运行了这个,实际上在纹理创建中发生了大约4GB的上下文丢失:
Total size = 4001366016
[Violation] 'setTimeout' handler took 427ms
WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost
context lost; stopping now
context is lost
这几乎与我从chrome://gpu
获得的GPU信息一致:
szDisplayMemoryEnglish 4163 MB
如果我正确读到它,那应该意味着我有大约4GB的内存。
有趣的是,我必须创建一个缓冲区(Float32Array)并传递它,否则代码将永远运行。
因此,我不知道GPU是否实际上正在交换CPU。但是我没有理由这么做,因为我能够达到GPU内存的极限并导致它重置。
为了解释我们在代码中不断丢失上下文的原因,我试图通过无限期地创建纹理来模拟它,直到上下文丢失。
但是,无论我的循环继续创建纹理多长时间,我从未遇到过这个问题。我的笔记本电脑完全没有响应,但我从未在Chrome控制台中看到“上下文丢失”。
GPU是否会以某种方式将纹理内存与CPU内存交换?
这是我正在使用的代码:
let contextLost = false;
function createCanvas(canvasWidth, canvasHeight) {
const canvas = document.createElement('canvas');
canvas.width = canvasWidth + 'px';
canvas.height = canvasHeight + 'px';
canvas.addEventListener("webglcontextlost", function(event) {
//event.preventDefault();
console.log('context is lost');
contextLost = true;
}, false);
canvas.addEventListener(
"webglcontextrestored", function() {
console.log('context is restored');
}, false);
return canvas;
}
function getGLContext(canvas) {
const attributes = { alpha: false, depth: false, antialias: false };
// Only fetch a gl context if we haven't already
const gl = canvas.getContext('webgl2', attributes);
if(!gl) {
throw 'No support for WebGL2';
}
if(!gl.getExtension('EXT_color_buffer_float')) {
throw 'No support for floatingpoint output textures';
}
return gl;
}
function createTexture(gl, width, height, data) {
const texture = gl.createTexture();
// Bind the texture so the following methods effect this texture.
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
// Pixel format and data for the texture
gl.texImage2D(
gl.TEXTURE_2D, // Target, matches bind above.
0, // Level of detail.
gl.R32F, // Internal format.
width, // Width - normalized to s.
height, // Height - normalized to t.
0, // Always 0 in OpenGL ES.
gl.RED, // Format for each pixel.
gl.FLOAT, // Data type for each chanel.
data); // Image data in the described format, or null.
// Unbind the texture.
gl.bindTexture(gl.TEXTURE_2D, null);
return texture;
}
let totalSize = 0;
const buffer = new Float32Array(1024*1024);
function createTexture2() {
const texsize=1024 * 1024 * 4;
const tex = createTexture(gl, 1024, 1024, buffer) ;
if(!tex || contextLost) {
console.log('context lost; stopping now');
return;
}
totalSize += texsize;
console.log('Total size = ' + totalSize);
window.setTimeout(createTexture2, 0);
}
const canvas = createCanvas(1,1);
const gl = getGLContext(canvas);
createTexture2();
console.log('the end');
GPU是否与CPU交换了Textures?
这取决于浏览器/驱动程序/操作系统。
一些驱动程序可以交换纹理有些GPU与CPU共享内存,因此GPU内存会发生与正常CPU内存相同的交换。
有些操作系统虚拟化GPU有些则没有。换句话说,如果你运行一些使用大量GPU内存并且同时运行测试的本机游戏,你可能会得到不同的结果。
一些浏览器可以实现自己的交换。换句话说,如果您同时在2个窗口中运行测试,则可能会得到不同或相同的结果。
没有简单的答案。