Какая команда в webgl вызывает обработку текстурной памяти - PullRequest
0 голосов
/ 19 сентября 2019

При настройке одной текстурной программы WebGL какая команда на самом деле заставляет "работать"?

Мне кажется, что команда textImage2D загружает html-данные изображения в графический процессор:

gl.texImage2D(target, level, internalformat, format, type, HTMLImageElement);

Однако, как только эти данные загружены и привязаны к текстуре, эту текстуру все равно необходимо «привязать» к сэмплеру.

setActiveTexture(gl, 0, this['textureRef0']);
var samplerRef = gl.getUniformLocation(program, 'sampler0');
gl.uniform1i(samplerRef, 0);

Нужно ли выделять память для привязки текстуры к семплеру?Или это просто указатель, который изменяет указатель сэмплера на данные текстуры?

А как насчет привязки текстур к буферам кадров?

gl.bindFramebuffer(gl.FRAMEBUFFER, this.globalFB);
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, textureRef0, 0);

Это действие само по себе вызывает какие-либо существенные проблемы с производительностью?Или «настоящая» работа выполняется только тогда, когда вызывается программа и данные отображаются в этой текстуре?

1 Ответ

1 голос
/ 20 сентября 2019

texImage2D выделяет память, потому что драйверу необходимо сделать копию данных, которые вы передаете, поскольку momment texImage2D возвращает вы можете изменить свою память.

кадровые буферы не выделяют много памяти,память это вложения.Но кадровые буферы должны быть проверены, поэтому лучше создавать несколько кадровых буферов с каждой комбинацией вложений, а не менять вложения в одном кадровом буфере

Другими словами, например, если вы выполняете пинг-понгтекстуры для постобработки, например

 // init time
 const fb = gl.createFramebuffer();

 // render time
 for each pass
    gl.framebufferTexture2D(...., dstTex);   // bad!
    ...
    gl.drawXXX
    const t = srcTex; srcTex = dstTex; dstTex = t;  // swap textures
 }

vs

 // init time
 let srcFB = gl.createFramebuffer();
 gl.framebufferTexture(...., srcTex);
 let dstFB = gl.createFramebuffer();
 gl.framebufferTexture(...., dstTex);

 // render time
 for each pass
    gl.bindFramebuffer(dstFB);   // good
    ...
    gl.drawXXX
    const t = srcFB; srcFB = dstFB; dstFB = t;  // swap framebuffers
 }

Текстуры также имеют проблему, заключающуюся в том, что из-за дизайна API у GL есть куча работы, которую нужно выполнить при первом рисовании стекстура (и каждый раз, когда вы меняете ее содержимое).

Учтите, что это нормальная последовательность в WebGL для предоставления mips

texImage2D level 0, 16x16
texImage2D level 1, 8x8
texImage2D level 2, 4x4
texImage2D level 3, 2x2
texImage2D level 4, 1x1

Но это также полностью допустимые вызовы API

texImage2D level 0, 16x16
texImage2D level 1, 8x8
texImage2D level 2, 137x324    // nothing in the spec prevents this. It's fully valid
texImage2D level 3, 2x2
texImage2D level 4, 1x1
texImage2D level 2, 4x4        // fix level 2 before drawing

Этот вызов уровня 2 со странным размером действителен.Не допускается выдавать ошибку.Конечно, если вы не замените уровень 2 перед рисованием, он не сможет рисовать, но загрузка данных не является ошибкой в ​​соответствии с API.Это означает, что до тех пор, пока текстура не будет фактически использована, драйвер сможет просматривать данные, форматы и размеры для каждого mip, проверять, все ли они правильные, а затем, наконец, размещать данные на графическом процессоре.

texStorage было добавлено для устранения этой проблемы (доступно в WebGL2 / OpenGL ES 3.0)

Вызов activeTexture, привязка текстур с bindTexture и настройка униформ не занимают памяти и не имеют существенных проблем с производительностью.

...