PDA

View Full Version : glTexturePageCommittment segfaults with mip level that isn't a multiple of tilesize.



JoeSSU
06-04-2015, 04:07 PM
pretty straightforward, as i divide down and come up with the mip map width and heights, i arrive at a width that is not an integer multiple of the tile size, and i get a segfault.

From the spec:

When the mipmap chain reaches a level that is not an integer
multiple of the virtual page size in any dimension, padding and memory
layout considerations may make it impossible to treat that level and
subsequent smaller ones as partially populated. The set of levels that
can be partially populated is implementation-dependent. The total number
of levels that may be partially populated may be queried by calling
GetTexParameteriv with the <pname> NUM_SPARSE_LEVELS_ARB.

when i query that number, i get 1000.

here is my storage code


glTexStorage3D(GL_TEXTURE_2D_ARRAY,levels,internal format,physicalWidth,physicalHeight,slices);


here is my commit call:

int levelWidth = physicalWidth;
int levelHeight = physicalHeight;
for (int level = 0; level < numLevels; ++level) {
glTexturePageCommitmentEXT(mTexId, level, 0, 0, slice, levelWidth, levelHeight, 1, commit);
levelWidth = glm::max(levelWidth / 2, 1);
levelHeight = glm::max(levelHeight / 2, 1);
}

JoeSSU
06-05-2015, 09:57 AM
I think my problem is that I am not passing in filtered, resized image data for the mip map level, and it is over running. Manually generating mipmaps on the fly requires an extra step of resizing and filtering the image. I think I can use imagemagick to take care of that.

Osbios
06-10-2015, 11:08 AM
Just a guess from how compressed textures work with there block size:



static inline int align(int value, int alignment)
{
return value + ((value % alignment) ? (alignment - (value % alignment)) : 0);
}

int levelWidth = physicalWidth;
int levelHeight = physicalHeight;
for (int level = 0; level < numLevels; ++level) {
glTexturePageCommitmentEXT(mTexId, level, 0, 0, slice, align(levelWidth, valueFrom_VIRTUAL_PAGE_SIZE_X_ARB), align(levelHeight, valueFrom_VIRTUAL_PAGE_SIZE_Y_ARB), 1, commit);
levelWidth = glm::max(levelWidth / 2, 1);
levelHeight = glm::max(levelHeight / 2, 1);
}