Size NVN textures as MacNativeGames 3c482a7 does: packaged byte 0 holds block height and block depth nibbles, cube map arrays count layer-faces in depth, linear block-compressed textures count pixel rows

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Valiantsin DzerakhandClaude Opus 5.5 committed 2026-10-26 14:31:41 +03:00
1 parent 734eee4383
commit f25c818f7b
2 files changed
+8 -4

No files matched your search

+1 -1
View File
@@ -17,7 +17,7 @@
typedef struct {
int target, format, flags, samples; // NVNtextureTarget / NVNformat / NVNtextureFlags / sample count (0 or 1 = single-sampled)
uint32_t width, height, depth, levels, stride;
signed int pkg_block_h:8; unsigned int swizzle_r:3,swizzle_g:3,swizzle_b:3,swizzle_a:3,swizzle_pad:12; // Byte 0 of the packaged texture layout parameters (log2 of block height) + 1; 0 = use the automatic algorithm
signed int pkg_block_h:8; unsigned int swizzle_r:3,swizzle_g:3,swizzle_b:3,swizzle_a:3,swizzle_pad:12; // Byte 0 of the packaged texture layout parameters + 1 (low nibble log2 block height, high nibble log2 block depth); 0 = use the automatic algorithm
} nvn_texdesc;
typedef struct {
+7 -3
View File
@@ -75,7 +75,7 @@ static void shape(const nvn_texdesc *d, unsigned *dpl, int *layered, uint32_t *w
case 2: *dpl = 3; break; // 3D
case 4: case 6: *dpl = 2; *layered = 1; break; // 2D_ARRAY / MS_ARRAY
case 8: *dpl = 2; *z = 6; *layered = 1; break; // CUBEMAP
case 9: *dpl = 2; *z = d->depth * 6; *layered = 1; break; // CUBEMAP_ARRAY
case 9: *dpl = 2; *layered = 1; break; // CUBEMAP_ARRAY: depth already counts layer-faces
default: *dpl = 2; *z = 1; break; // 2D / MS / RECTANGLE
}
if (*z == 0) *z = 1;
@@ -140,14 +140,18 @@ void nvn_tex_layout(const nvn_texdesc *d, nvn_texlayout *o) {
if (nvn_tex_is_linear(d)) { // Pitch storage: explicit stride, otherwise 32-byte (LINEAR) / 128-byte (LINEAR_RENDER_TARGET) alignment
o->align = (d->flags & 0x40) ? 128 : 32;
uint32_t stride = nvn_tex_linear_stride(d);
o->layer_size = o->size = (uint64_t)stride * blk(h, t.bh);
o->layer_size = o->size = (uint64_t)stride * h; // the driver counts pixel rows, also for block-compressed formats
return;
}
unsigned tileH = 0, tileD = 0;
/* NVN truncates height*1.5 to whole GOB rows before choosing the power of
two. Rounding up here changes e.g. 40 BC rows from H2 to H3 even when
the total allocation size is unchanged, so padding becomes black texels. */
if (dpl == 2) { uint32_t ah = blk(h * sy, t.bh); tileH = d->pkg_block_h ? (unsigned)d->pkg_block_h - 1 : pick_tile((ah + ah / 2) / 8); }
if (d->pkg_block_h) { // packaged byte 0: low nibble block height, high nibble block depth
unsigned pl = (unsigned)(d->pkg_block_h - 1) & 0xFF;
if (dpl >= 2) tileH = pl & 0xF;
if (dpl == 3) tileD = pl >> 4;
} else if (dpl == 2) { uint32_t ah = blk(h * sy, t.bh); tileH = pick_tile((ah + ah / 2) / 8); }
else if (dpl == 3) tileD = pick_tile(z + z / 2);
uint64_t ls = layer_bytes(d, dpl, layered, w, h, z, tileH, tileD, t);
if ((d->flags & 0x200) && !d->pkg_block_h && minimal_layout_on()) {