代码之家  ›  专栏  ›  技术社区  ›  Jeff Saremi

GPU是否与CPU交换创建的纹理?

  •  0
  • Jeff Saremi  · 技术社区  · 6 年前

    在穆迪发表评论后更新。

    Total size = 4001366016                        
    [Violation] 'setTimeout' handler took 427ms    
    WebGL: CONTEXT_LOST_WEBGL: loseContext: context lost 
    context lost; stopping now 
    context is lost
    

    这几乎与我可以从中获得的GPU信息一致 chrome://gpu :

    szDisplayMemoryEnglish  4163 MB
    

    有趣的是,我必须创建一个缓冲区(Float32Array)并传递它,否则代码将永远运行。


    为了弄清代码中不断丢失上下文的原因,我尝试通过无限期地创建纹理来模拟,直到上下文丢失为止。

    然而,不管我的循环持续创建纹理多长时间,我从来没有碰到过这个问题。我的笔记本电脑变得完全没有反应,但我从来没有看到一个'上下文丢失'在Chrome控制台。

    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');
    1 回复  |  直到 6 年前
        1
  •  1
  •   gman    6 年前

    一些驱动程序可以交换纹理。一些GPU与CPU共享内存,因此与普通CPU内存相同的交换也发生在GPU内存中。

    有些操作系统虚拟化了GPU,有些没有。换句话说,如果你运行一些使用大量GPU内存的本地游戏,同时运行测试,你可能会得到不同的结果。

    没有简单的答案。