nx_cast_surface_adapter_candidate_t181.nx source
↩ module page · 113 lines · 7752 B
1// Private stage adapter: reuse canonical cast deformation IR without duplicating skinning arithmetic.
2// Input: four vec4 lanes per body vertex (position,normal,joints,weights).
3// Output: two vec4 lanes per actor/source vertex (world position, deformed normal).
4// Header dimensions extend the SAME uniform declaration owner; host uses emitted layout.
5import "nx_cast_shader_src.nx"
6const CSURF_INPUT_BIND:i64=5
7const CSURF_OUTPUT_BIND:i64=6
8const CSURF_INPUT_LANES:i64=4
9const CSURF_OUTPUT_LANES:i64=2
10func csurf_lane(m:*i64,slot:*u8)->i64{
11 return sir_index(m,sir_ident(m,"surfaceIn",T_V4F),cs_iadd(m,cs_imul(m,cs_i(m,"svIndex"),ws_i(m,"4")),ws_i(m,slot)),T_V4F)
12}
13func shsrc_cast_surface_compute_v1(m:*i64)->i64{
14 shsrc_cast_resident_decls(m)
15 // Attributes/varyings become private per-invocation state for compute. Uniforms/textures stay identical.
16 var d:i64=m[M_DECLH];while d!=0{let k:i64=sir_get(m,d,SIR_KIND)
17 if k==K_ATTRIB||k==K_VARY{sir_set(m,d,SIR_KIND,K_PRIVATE);sir_set(m,d,SIR_A,0);sir_set(m,d,SIR_B,0);sir_set(m,d,SIR_C,0)}
18 d=sir_get(m,d,SIR_NEXT)
19 }
20 sir_uniform(m,"uSurfaceVertices",T_I32,0);sir_uniform(m,"uSurfaceActors",T_I32,0)
21 sir_storage(m,"surfaceIn",T_V4F,CSURF_INPUT_BIND,0,0);sir_storage(m,"surfaceOut",T_V4F,CSURF_OUTPUT_BIND,1,0)
22 shsrc_cast_fn_hsh(m)
23 let f:i64=sir_func(m,"main",T_VOID)
24 let gid:i64=sir_builtin(m,"global_invocation_id",T_V3U)
25 ws_st(m,f,sir_var(m,"svIndex",T_I32,cs_i32(m,sir_swz(m,gid,"x",T_U32))))
26 ws_st(m,f,sir_var(m,"ii",T_I32,cs_i32(m,sir_swz(m,gid,"y",T_U32))))
27 let outside:i64=ws_or(m,ws_cmp(m,">=",cs_i(m,"svIndex"),cs_i(m,"uSurfaceVertices")),ws_cmp(m,">=",cs_i(m,"ii"),cs_i(m,"uSurfaceActors")))
28 let unsupported:i64=ws_or(m,ws_cmp(m,"!=",cs_i(m,"uGar"),ws_i(m,"0")),ws_cmp(m,"!=",cs_i(m,"uHM"),ws_i(m,"1")))
29 ws_st(m,f,ws_if(m,ws_or(m,outside,unsupported),sir_return(m,0),0))
30 ws_st(m,f,ws_set(m,cs_v3(m,"aP"),ws_sw(m,csurf_lane(m,"0"),"xyz",T_V3F)))
31 ws_st(m,f,ws_set(m,cs_v3(m,"aN"),ws_sw(m,csurf_lane(m,"1"),"xyz",T_V3F)))
32 ws_st(m,f,ws_set(m,cs_v4(m,"aJ"),csurf_lane(m,"2")))
33 ws_st(m,f,ws_set(m,cs_v4(m,"aW"),csurf_lane(m,"3")))
34 ws_st(m,f,ws_set(m,cs_fl(m,"aHS"),ws_f(m,"0.0")))
35 ws_st(m,f,ws_set(m,cs_fl(m,"vSh"),ws_f(m,"1.0")))
36 ws_st(m,f,sir_var(m,"jit",T_V3F,ws_v1(m,T_V3F,ws_f(m,"0.0"))))
37 cs_slice2_local(m,f);cs_slice3(m,f)
38 // The pre-skin garment branch references vertex_index; compute uses the same explicit source index.
39 var id:i64=1;while id<m[M_NCOUNT]{if sir_get(m,id,SIR_KIND)==E_BUILTIN{
40 if sir_slen(sir_cstr(m,sir_get(m,id,SIR_NAME)))==12{let nm:*u8=sir_cstr(m,sir_get(m,id,SIR_NAME));let expected:*u8="vertex_index";var eq:i64=1;var at:i64=0;while at<12{if nm[at]!=expected[at]{eq=0};at=at+1};if eq==1{
41 sir_set(m,id,SIR_KIND,E_IDENT);sir_set(m,id,SIR_NAME,sir_str(m,"svIndex"))
42 }}
43 };id=id+1}
44 let oi:i64=cs_imul(m,cs_iadd(m,cs_imul(m,cs_i(m,"ii"),cs_i(m,"uSurfaceVertices")),cs_i(m,"svIndex")),ws_i(m,"2"))
45 ws_st(m,f,sir_var(m,"surfaceIndex",T_I32,oi))
46 let op:i64=sir_index(m,sir_ident(m,"surfaceOut",T_V4F),cs_i(m,"surfaceIndex"),T_V4F)
47 let on:i64=sir_index(m,sir_ident(m,"surfaceOut",T_V4F),cs_iadd(m,cs_i(m,"surfaceIndex"),ws_i(m,"1")),T_V4F)
48 ws_st(m,f,ws_set(m,op,ws_v4(m,cs_sx3(m,"wp","x"),cs_sx3(m,"wp","y"),cs_sx3(m,"wp","z"),ws_f(m,"1.0"))))
49 ws_st(m,f,ws_set(m,on,ws_v4(m,cs_sx3(m,"vN","x"),cs_sx3(m,"vN","y"),cs_sx3(m,"vN","z"),ws_f(m,"0.0"))))
50 return f
51}
52
53// Preserve the incumbent smooth normal when it has a direction. Exact cancellation
54// uses the current deformed triangle's geometric normal, not an invented world axis.
55// A collapsed deformed triangle has zero normal and zero normal offset; it is not a fit pass.
56func csurf_finish_normal_v1(m:*i64,f:i64,n:i64,edge_a:i64,edge_b:i64)->i64{
57 ws_st(m,f,sir_var(m,"surfaceNormal",T_V3F,n))
58 ws_st(m,f,ws_set(m,cs_v3(m,"vN"),ws_v1(m,T_V3F,ws_f(m,"0.0"))))
59 let geometric:i64=sir_var(m,"surfaceGeometric",T_V3F,cs_cross(m,edge_a,edge_b))
60 let geom_ok:i64=ws_cmp(m,">",cs_dot(m,cs_v3(m,"surfaceGeometric"),cs_v3(m,"surfaceGeometric")),ws_f(m,"0.0"))
61 let fallback:i64=ws_q2(m,geometric,ws_if(m,geom_ok,ws_set(m,cs_v3(m,"vN"),ws_c1(m,"normalize",cs_v3(m,"surfaceGeometric"),T_V3F)),0))
62 let smooth_ok:i64=ws_cmp(m,">",cs_dot(m,cs_v3(m,"surfaceNormal"),cs_v3(m,"surfaceNormal")),ws_f(m,"0.0"))
63 ws_st(m,f,ws_if(m,smooth_ok,ws_set(m,cs_v3(m,"vN"),ws_c1(m,"normalize",cs_v3(m,"surfaceNormal"),T_V3F)),fallback));return 0
64}
65
66// Post-deformation attachments consume the shared source surface; they never re-skin blended weights.
67// aJ.xyz are validated source vertex indices; aW.xyz are ratios of retained exact rational records;
68// aW.w is normal offset in original model units, aP is original barycentric source position.
69func csurf_attachment_sample(m:*i64,axis:*u8,lane:*u8)->i64{
70 let source:i64=cs_i32(m,ws_sw(m,cs_v4(m,"aJ"),axis,T_F32))
71 let index:i64=cs_iadd(m,cs_imul(m,cs_iadd(m,cs_imul(m,cs_i(m,"ii"),cs_i(m,"uSurfaceVertices")),source),ws_i(m,"2")),ws_i(m,lane))
72 return ws_sw(m,sir_index(m,sir_ident(m,"surfaceOut",T_V4F),index,T_V4F),"xyz",T_V3F)
73}
74func csurf_attachment_blend(m:*i64,lane:*u8)->i64{
75 let x:i64=ws_bin(m,"*",csurf_attachment_sample(m,"x",lane),cs_sx4(m,"aW","x"),T_V3F)
76 let y:i64=ws_bin(m,"*",csurf_attachment_sample(m,"y",lane),cs_sx4(m,"aW","y"),T_V3F)
77 let z:i64=ws_bin(m,"*",csurf_attachment_sample(m,"z",lane),cs_sx4(m,"aW","z"),T_V3F)
78 return ws_bin(m,"+",ws_bin(m,"+",x,y,T_V3F),z,T_V3F)
79}
80func shsrc_cast_attachment_vs_v1(m:*i64)->i64{
81 m[M_CLIP_DEPTH]=SIR_CLIP_NEGATIVE_ONE_TO_ONE;shsrc_cast_resident_decls(m)
82 sir_uniform(m,"uSurfaceVertices",T_I32,0);sir_uniform(m,"uSurfaceActors",T_I32,0)
83 sir_storage(m,"surfaceOut",T_V4F,CSURF_OUTPUT_BIND,0,0)
84 let f:i64=sir_func(m,"main",T_VOID)
85 ws_st(m,f,sir_var(m,"ii",T_I32,sir_builtin(m,"instance_index",T_I32)))
86 ws_st(m,f,ws_set(m,cs_i(m,"vII"),cs_i(m,"ii")))
87 ws_st(m,f,ws_set(m,cs_v3(m,"vB"),cs_v3(m,"aP")))
88 ws_st(m,f,ws_set(m,ws_id(m,"vUV",T_V2F),ws_id(m,"aUV",T_V2F)))
89 ws_st(m,f,ws_set(m,cs_fl(m,"vSh"),ws_f(m,"1.0")))
90 csurf_finish_normal_v1(m,f,csurf_attachment_blend(m,"1"),cs_v3sub(m,csurf_attachment_sample(m,"y","0"),csurf_attachment_sample(m,"x","0")),cs_v3sub(m,csurf_attachment_sample(m,"z","0"),csurf_attachment_sample(m,"x","0")))
91 let scale:i64=cs_fmul(m,cs_fl(m,"uSc"),ws_sw(m,cs_idx(m,"uIH",T_V4F,cs_i(m,"ii")),"z",T_F32))
92 let offset:i64=ws_bin(m,"*",cs_v3(m,"vN"),cs_fmul(m,cs_sx4(m,"aW","w"),scale),T_V3F)
93 ws_st(m,f,sir_var(m,"wp",T_V3F,ws_bin(m,"+",csurf_attachment_blend(m,"0"),offset,T_V3F)))
94 // Reuse canonical wardrobe rejection, shadow projection, camera and clip-depth conventions.
95 cs_slice4(m,f);return f
96}
97
98// Runtime boundary descriptor: vertices,active_rows,native_actor_count,input_bytes,output_bytes,
99// uniform_bytes,max_storage_binding,max_buffer,max_dispatch_x,max_dispatch_y,uGar,uHM.
100// Limits are supplied from the actual device. IDs are the compact render row's stable native IDs.
101// No allocation/dispatch; caller keeps accepted row order unchanged through compute and drawing.
102func csurf_dispatch_validate_v1(d:*i64,dn:i64,ids:*i64,idn:i64)->i64{
103 if (d as i64)==0||dn!=12||(ids as i64)==0{return -50}
104 let nv:i64=d[0];let na:i64=d[1];if nv<1||nv>2147483647||na<1||na>12||idn!=na||d[2]<na{return -51}
105 if nv>2147483647/4||nv>2147483647/2/na{return -53}
106 if d[10]!=0||d[11]!=1{return -52}
107 if d[6]<1||d[7]<1||d[8]<1||d[9]<1||d[5]<3344||d[5]>d[7]{return -53}
108 if nv>d[7]/64||nv>d[6]/64{return -53};let input:i64=nv*64
109 if nv>d[7]/32/na||nv>d[6]/32/na{return -53};let output:i64=nv*32*na
110 if d[3]<input||d[4]<output||d[3]>d[7]||d[4]>d[7]||d[3]>d[6]||d[4]>d[6]{return -53}
111 if (nv-1)/64+1>d[8]||na>d[9]{return -53}
112 var i:i64=0;while i<na{if ids[i]<0||ids[i]>=d[2]{return -54};var j:i64=0;while j<i{if ids[j]==ids[i]{return -54};j=j+1};i=i+1};return 0
113}