DF-4032 / texmip_sim.c
/* * texmip_sim.c — host-runnable proof for DF-4032. * * Replicates r600_mip_minify()/r600_texture_size() * (sys/dev/drm/radeon/r600_cs.c:1399-1457) for the PoC texture: * 512x512, COLOR_8 (1 byte/px), blevel=0, llevel=9, nfaces=1, * nsamples=1, pitch_align=1 (linear), height_align=1, base_align=1 * and shows mipmap_size >> 256-byte mipmap BO while the only check that * would catch it (r600_cs.c:1603-1606) is commented out. */ #include <stdio.h> #include <stdint.h> static unsigned mip_minify(unsigned size, unsigned level) { unsigned val = size >> level; if (val == 0) val = 1; if (level > 0) { /* roundup_pow_of_two */ unsigned v = 1; while (v < val) v <<= 1; val = v; } return val; } int main(void) { unsigned w0 = 512, h0 = 512, d0 = 1, blevel = 0, llevel = 9; unsigned blocksize = 1, nsamples = 1, nfaces = 1; unsigned block_align = 1, height_align = 1, base_align = 1; unsigned offset = 0, level, i; unsigned l0_size = (unsigned)-1, mipmap_size; for (i = 0, level = blevel; i <= llevel - blevel; i++, level++) { unsigned width = mip_minify(w0, i); unsigned nbx = width; /* nblocksx for 1x1 blocks */ unsigned height = mip_minify(h0, i); unsigned nby = height; unsigned depth = mip_minify(d0, i); unsigned size = nbx * nby * blocksize * nsamples; size *= nfaces ? nfaces : depth; if (i == 0) l0_size = size; if (i == 0 || i == 1) offset = offset; /* round_up(0,1)=0 */ offset += size; printf("level %u: %ux%u -> %u bytes (offset %u)\n", level, width, height, size, offset); } mipmap_size = offset; if (llevel == 0) mipmap_size = l0_size; if (!blevel) mipmap_size -= l0_size; printf("\nl0_size = %u (checked vs 1 MiB texture BO: PASS)\n", l0_size); printf("mipmap_size = %u vs 256-byte mipmap BO\n", mipmap_size); printf("r600_cs.c:1603 check is COMMENTED OUT -> submission ACCEPTED;\n" "GPU mip walks %u bytes past a 256-byte BO.\n", mipmap_size - 256); return 0; } |