Readable-tile variants compile again for pixel shaders with an integer-output entry point (main0_u), from PR #83
Since 626e6a6 a pixel shader whose outputs look like integer writes gets a second entry point, main0_u, appended
after main0. dmsh_fetch.variant, which makes the framebuffer-fetch variant (_bf), rewrote samples to fb0..fb7 in
the whole source, main0_u included, but declared them only on main0, and renamed main0_out's members, which
main0_u still reads: every variant of such a shader failed to compile (use of undeclared identifier 'fb0'), and
the shader lost the tile read (its render passes are not merged). The host takes main0_u from the shader's own
library (nvn_mtl.m entry_u), never from the variant, so the variant is now made from the source cut at
struct main0_out_u, which dmsh_build.py always appends with main0_u at the end. A main0 with no parameters
also got its fb parameters with a leading comma (main0(, float4 fb0 ...)); output-mapping-only variants only.
Checked on Breath of the Wild's library MSL (chain 534b10d1d578, 10,560 pixel shaders), old and new variant()
side by side: the 8,659 shaders without main0_u give byte-identical variants, with and without
output-mapping-only; all 1,639 changed variants of shaders with main0_u failed to compile before and compile now
(Mac), and 1,897 of 1,897 output-mapping-only ones when forced for every key (30 of them the leading comma; no
profile's bf_want.tsv lists a key today); 40 of them compiled for iOS too. A full Mac dmsh_build.py run on the
new chain 657c42552d82: 19,592 of 19,592 shaders and 6,254 variants with no compile failure (main's chain would
lose the 1,639), stamped, both tables made; the Mac host booted Breath of the Wild with it past frame 5,100, its
title presses into play, with no red line. dm/tools/tests pass. dmsh_fetch.py is part of the chain, so
dm/gfx/nvn/dmsh_chain.h is written again and every game's shaders rebuild at their next build.
Co-authored-by: v0lumehi <34629096+v0lumehi@users.noreply.github.com>
This commit is contained in:
1 parent
76545a58a7
commit
4e91a3d053
2 files changed
+9
-2
No files matched your search
@@ -1,3 +1,3 @@
|
||||
// Generated file (dm/gfx/tools/dmsh_chain.py --header): the B shader library translation chain version this source tree expects (default options), one for every game;
|
||||
// the host loads only <library dir>/b-<V>/. Run dmsh_chain.py --header after changing the chain's tools and commit this file with the change
|
||||
#define DMSH_CHAIN "3f4cd4aacd1d"
|
||||
#define DMSH_CHAIN "657c42552d82"
|
||||
@@ -10,6 +10,11 @@ import re
|
||||
NFB = 8
|
||||
|
||||
def variant(msl, bindings, om_only_ok=False):
|
||||
# main0_u (dmsh_build.py int_outputs: integer colour targets) is appended to the source after main0; the host takes it from the shader's own library, never from this variant.
|
||||
# Its body reads main0's output struct, whose members the variant renames, and its samples were rewritten to fb0–fb7, which only main0 declares: 483 of Breath of the
|
||||
# Wild's variants failed to compile once their cached copies were gone (use of undeclared identifier 'fb0'). The variant is built from the source without it
|
||||
cut = msl.find('\nstruct main0_out_u\n')
|
||||
if cut >= 0: msl = msl[:cut + 1]
|
||||
tex = {m.group(1) for m in re.finditer(r'texture2d<float> (\w+) \[\[id\(\d+\)\]\];', msl)}
|
||||
locn = {m.group(1): int(m.group(2)) for m in re.finditer(r'float4 (m_\d+) \[\[user\(locn(\d+)\)\]\];', msl.split('struct main0_in', 1)[-1].split('};', 1)[0])}
|
||||
reg = {b['msl_name']: b['reg'] for b in bindings if b.get('kind') == 'tex' and b.get('msl_name') and b.get('reg') is not None}
|
||||
@@ -46,7 +51,9 @@ def variant(msl, bindings, om_only_ok=False):
|
||||
i0 = body.find('fragment main0_out main0(')
|
||||
i1 = body.find(')\n{', i0) if i0 >= 0 else -1 # end of signature: closing parenthesis immediately followed by a newline and an opening brace (parameter attributes contain brackets such as [[buffer(0)]])
|
||||
if i0 < 0 or i1 < 0: return None, 'main function signature not recognized'
|
||||
body = body[:i1] + ''.join(f', float4 fb{k} [[color({k}), function_constant(FB_{k})]]' for k in range(NFB)) + body[i1:]
|
||||
fbs = ''.join(f', float4 fb{k} [[color({k}), function_constant(FB_{k})]]' for k in range(NFB))
|
||||
if body[i1 - 1] == '(': fbs = fbs[2:] # main0() with no parameters at all: no leading comma (30 of Breath of the Wild's output-mapping-only variants)
|
||||
body = body[:i1] + fbs + body[i1:]
|
||||
decl = ''.join(f' {t} spv_o_{n} = {t}(0);\n' for t, n, c in outs)
|
||||
body = body.replace(' main0_out out = {};\n', ' main0_out out = {};\n' + decl, 1)
|
||||
for t, n, c in outs: body = body.replace(f'out.{n}', f'spv_o_{n}')
|
||||
|
||||
Reference in new issue
Block a user