Как вы загружаете данные текстуры в разреженную текстуру, используя TexSubImage в OpenGL?
Я слежу за apitest на github и вижу очень странное поведение в моем рендерере.
Похоже, что виртуальные страницы не получают правильные данные изображения.
Исходное изображение 500x311:
Когда я отрисовываю это изображение, используя Разреженную текстуру, я должен изменить размер хранилища резервных копий до 512x384 (чтобы он был кратным размеру страницы), и мой результат:
Как вы можете видеть, похоже, что часть подизображения (подэлемент изображения) была загружена на каждую отдельную виртуальную страницу.
Чтобы проверить это, я обрезал изображение до размера всего одной виртуальной страницы (256x128): вот результат:
как и ожидалось, единственная вирусная страница была заполнена точным, правильным, обрезанным изображением.
Наконец, я увеличил размер обрезки до 2 виртуальных страниц, 256x256, одна поверх другой. вот результат:
Это доказывает, что вызов texSubimage с количеством texelData больше, чем Virtual_Page_Size, вызывает ошибки.
Нужно ли соблюдать осторожность при передаче данных в glsubimage, размер которого превышает размер виртуальной страницы? Я не вижу никакой логики для этого в apitest, поэтому думаю, что это может быть проблема с драйверами. Или я что-то упускаю.
Вот некоторый код:
Я сохранил текстуру в массиве текстур и для упрощения превратил массив в просто texture2d. оба дают одинаковый точный результат. Вот распределение текстурной памяти:
_check_gl_error();
glGenTextures(1, &mTexId);
glBindTexture(GL_TEXTURE_2D, mTexId);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_SPARSE_ARB, GL_TRUE);
// TODO: This could be done once per internal format. For now, just do it every time.
GLint indexCount = 0,
xSize = 0,
ySize = 0,
zSize = 0;
GLint bestIndex = -1,
bestXSize = 0,
bestYSize = 0;
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_NUM_VIRTUAL_PAGE_SIZES_ARB, 1, &indexCount);
if(indexCount == 0) {
fprintf(stdout, "No Virtual Page Sizes for given format");
fflush(stdout);
}
_check_gl_error();
for (GLint i = 0; i < indexCount; ++i) {
glTexParameteri(GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, i);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_X_ARB, 1, &xSize);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_Y_ARB, 1, &ySize);
glGetInternalformativ(GL_TEXTURE_2D, internalformat, GL_VIRTUAL_PAGE_SIZE_Z_ARB, 1, &zSize);
// For our purposes, the "best" format is the one that winds up with Z=1 and the largest x and y sizes.
if (zSize == 1) {
if (xSize >= bestXSize && ySize >= bestYSize) {
bestIndex = i;
bestXSize = xSize;
bestYSize = ySize;
}
}
}
_check_gl_error();
mXTileSize = bestXSize;
glTexParameteri(GL_TEXTURE_2D, GL_VIRTUAL_PAGE_SIZE_INDEX_ARB, bestIndex);
_check_gl_error();
//Need to ensure that the texture is a multiple of the tile size.
physicalWidth = roundUpToMultiple(width, bestXSize);
physicalHeight = roundUpToMultiple(height, bestYSize);
// We've set all the necessary parameters, now it's time to create the sparse texture.
glTexStorage2D(GL_TEXTURE_2D, levels, GL_RGBA8, physicalWidth, physicalHeight);
_check_gl_error();
for (GLsizei i = 0; i < slices; ++i) {
mFreeList.push(i);
}
_check_gl_error();
mHandle = glGetTextureHandleARB(mTexId);
_check_gl_error();
glMakeTextureHandleResidentARB(mHandle);
_check_gl_error();
mWidth = physicalWidth;
mHeight = physicalHeight;
mLevels = levels;
Вот что происходит после выделения:
glTextureSubImage2DEXT(mTexId, GL_TEXTURE_2D, level, 0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, data);
Я попытался сделать ширину и высоту физической шириной резервного хранилища И шириной / высотой содержимого входящего изображения. Ни один из них не дает желаемых результатов. Сейчас я исключаю уровни MIP. Когда я использовал уровни Mip и массив текстур, я получал разные результаты, но схожее поведение.
Также изображение загружается из SOIL, и до того, как я применил разреженные текстуры, это работало очень хорошо (до разрежения я реализовал bindless).