From 58d51090746647c523ddda207a5ecd5cc3cc1d58 Mon Sep 17 00:00:00 2001 From: Greggman Date: Mon, 9 Dec 2024 16:29:31 -0800 Subject: [PATCH] Add back unicode for texture diagrams (#4074) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Example: ``` 0 1 2 3 ╔═══╤═══╦═══╤═══╗ 0 ║ a │ ║ │ ║ ╟───┼───╫───┼───╢ 1 ║ │ ║ │ ║ ╠═══╪═══╬═══╪═══╣ 2 ║ │ ║ │ ║ ╟───┼───╫───┼───╢ 3 ║ │ ║ │ b ║ ╚═══╧═══╩═══╧═══╝ ``` --- .../expression/call/builtin/texture_utils.ts | 123 +++++++++++++----- 1 file changed, 89 insertions(+), 34 deletions(-) diff --git a/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts b/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts index ba8a58ae861c..b9013281e2cc 100644 --- a/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts +++ b/src/webgpu/shader/execution/expression/call/builtin/texture_utils.ts @@ -3430,25 +3430,72 @@ async function identifySamplePoints( // example when blockWidth = 2, blockHeight = 2 // // 0 1 2 3 - // +===+===+===+===+ - // 0 # a | # | # - // +---+---+---+---+ - // 1 # | # | # - // +===+===+===+===+ - // 2 # | # | # - // +---+---+---+---+ - // 3 # | # | b # - // +===+===+===+===+ + // ╔═══╤═══╦═══╤═══╗ + // 0 ║ a │ ║ │ ║ + // ╟───┼───╫───┼───╢ + // 1 ║ │ ║ │ ║ + // ╠═══╪═══╬═══╪═══╣ + // 2 ║ │ ║ │ ║ + // ╟───┼───╫───┼───╢ + // 3 ║ │ ║ │ b ║ + // ╚═══╧═══╩═══╧═══╝ + + /* prettier-ignore */ + const blockParts = { + top: { left: '╔', fill: '═══', right: '╗', block: '╦', texel: '╤' }, + mid: { left: '╠', fill: '═══', right: '╣', block: '╬', texel: '╪' }, + bot: { left: '╚', fill: '═══', right: '╝', block: '╩', texel: '╧' }, + texelMid: { left: '╟', fill: '───', right: '╢', block: '╫', texel: '┼' }, + value: { left: '║', fill: ' ', right: '║', block: '║', texel: '│' }, + } as const; + /* prettier-ignore */ + const nonBlockParts = { + top: { left: '┌', fill: '───', right: '┐', block: '┬', texel: '┬' }, + mid: { left: '├', fill: '───', right: '┤', block: '┼', texel: '┼' }, + bot: { left: '└', fill: '───', right: '┘', block: '┴', texel: '┴' }, + texelMid: { left: '├', fill: '───', right: '┤', block: '┼', texel: '┼' }, + value: { left: '│', fill: ' ', right: '│', block: '│', texel: '│' }, + } as const; const lines: string[] = []; const letter = (idx: number) => String.fromCodePoint(idx < 30 ? 97 + idx : idx + 9600 - 30); // 97: 'a' let idCount = 0; const { blockWidth, blockHeight } = kTextureFormatInfo[texture.descriptor.format]; - const [blockHChar, blockVChar] = Math.max(blockWidth, blockHeight) > 1 ? ['=', '#'] : ['-', '|']; - const blockHCell = '+'.padStart(4, blockHChar); // generates ---+ or ===+ // range + concatenate results. const rangeCat = (num: number, fn: (i: number) => T) => range(num, fn).join(''); + const joinFn = (arr: string[], fn: (i: number) => string) => { + const joins = range(arr.length - 1, fn); + return arr.map((s, i) => `${s}${joins[i] ?? ''}`).join(''); + }; + const parts = Math.max(blockWidth, blockHeight) > 1 ? blockParts : nonBlockParts; + /** + * Makes a row that's [left, fill, texel, fill, block, fill, texel, fill, right] + * except if `contents` is supplied then it would be + * [left, contents[0], texel, contents[1], block, contents[2], texel, contents[3], right] + */ + const makeRow = ( + blockPaddedWidth: number, + width: number, + { + left, + fill, + right, + block, + texel, + }: { + left: string; + fill: string; + right: string; + block: string; + texel: string; + }, + contents?: string[] + ) => { + return `${left}${joinFn(contents ?? range(blockPaddedWidth, x => fill), x => { + return (x + 1) % blockWidth === 0 ? block : texel; + })}${right}`; + }; for (let mipLevel = 0; mipLevel < mipLevelCount; ++mipLevel) { const level = levels[mipLevel]; @@ -3478,31 +3525,39 @@ async function identifySamplePoints( continue; } + const blockPaddedHeight = align(height, blockHeight); + const blockPaddedWidth = align(width, blockWidth); lines.push(` ${rangeCat(width, x => ` ${x.toString().padEnd(2)}`)}`); - lines.push(` +${rangeCat(width, () => blockHCell)}`); - for (let y = 0; y < height; y++) { - { - let line = `${y.toString().padStart(2)} ${blockVChar}`; - for (let x = 0; x < width; x++) { - const colChar = (x + 1) % blockWidth === 0 ? blockVChar : '|'; - const texelIdx = x + y * texelsPerRow; - const weight = layerEntries.get(texelIdx); - if (weight !== undefined) { - line += ` ${letter(idCount + orderedTexelIndices.length)} ${colChar}`; - orderedTexelIndices.push(texelIdx); - } else { - line += ` ${colChar}`; - } - } - lines.push(line); - } - if (y < height - 1) { - lines.push( - ` +${rangeCat(width, () => ((y + 1) % blockHeight === 0 ? blockHCell : '---+'))}` - ); - } + lines.push(` ${makeRow(blockPaddedWidth, width, parts.top)}`); + for (let y = 0; y < blockPaddedHeight; y++) { + lines.push( + `${y.toString().padStart(2)} ${makeRow( + blockPaddedWidth, + width, + parts.value, + range(blockPaddedWidth, x => { + const texelIdx = x + y * texelsPerRow; + const weight = layerEntries.get(texelIdx); + const outside = y >= height || x >= width; + if (outside || weight === undefined) { + return outside ? '░░░' : ' '; + } else { + const id = letter(idCount + orderedTexelIndices.length); + orderedTexelIndices.push(texelIdx); + return ` ${id} `; + } + }) + )}` + ); + // It's either a block row, a texel row, or the last row. + const end = y < blockPaddedHeight - 1; + const lineParts = end + ? (y + 1) % blockHeight === 0 + ? parts.mid + : parts.texelMid + : parts.bot; + lines.push(` ${makeRow(blockPaddedWidth, width, lineParts)}`); } - lines.push(` +${range(width, () => blockHCell).join('')}`); const pad2 = (n: number) => n.toString().padStart(2); const pad3 = (n: number) => n.toString().padStart(3);