For the record, it's, per-dimension (width, height, depth), max(dimension >> mip, 1)
Always just recompute from start, apply any padding to multiples of e.g. block size after
do _not_ update incrementally in a loop (e.g. width>>=1 every mip level) and then mix with padding or similar. just don't do it
Also, the total number of mip levels (base level included) is, _always_, floor(log2(max(width, height, depth))) + 1. No ceils. No separate rules for pow2/non-pow2. For 2D or 1D textures, set depth=1 and height=1 as required.
you're welcome
While we're at SUPAH SEKRIT graphics PROTIPS: if you set up a 2D image abstraction, just make sure to keep separate width, height, and stride (the latter being the number of pixels - or sometimes, depending on context, bytes - between adjacent rows).
This is super-simple to do if you always have it from the beginning and having the ability to have stride!=width is really really useful