From 386c2fc045d9d79f2622260401262d2d4254c799 Mon Sep 17 00:00:00 2001 From: kotofyt Date: Thu, 30 Apr 2026 22:03:31 +0300 Subject: [PATCH] prototype for spirv linking --- funnyassets/shaders/funny_basic_pbr.shader | 11 ++- funnyassets/shaders/funny_error.shader | 14 +++- funnyassets/shaders/macros.hlsl | 33 +++++---- funnyassets/shaders/mesh_raster.shader | 2 - funnyassets/shaders/mesh_trace.shader | 7 +- materialsystem/compiledshader.cpp | 4 -- materialsystem/vulkan/rtlinker.cpp | 78 +++++++++++++++++++-- minispv/minispv.h | 5 ++ shadercompiler/CallableMain | Bin 376 -> 720 bytes shadercompiler/rayMain | Bin 1220 -> 1140 bytes 10 files changed, 120 insertions(+), 34 deletions(-) diff --git a/funnyassets/shaders/funny_basic_pbr.shader b/funnyassets/shaders/funny_basic_pbr.shader index f40afb5..ffb98a8 100644 --- a/funnyassets/shaders/funny_basic_pbr.shader +++ b/funnyassets/shaders/funny_basic_pbr.shader @@ -2,13 +2,18 @@ COMMON { - + struct RayPayload + { + float3 m_vOrigin; + float3 m_vDirection; + float3 m_vColor; + }; } CALLABLE { #include "textures.hlsl" - float4 brdfMain() + void brdfMain( inout RayPayload payload ) { - return float4(1); + payload.m_vColor = float3(1.0,0.0,1.0); } } diff --git a/funnyassets/shaders/funny_error.shader b/funnyassets/shaders/funny_error.shader index f28d341..a20057d 100644 --- a/funnyassets/shaders/funny_error.shader +++ b/funnyassets/shaders/funny_error.shader @@ -1,9 +1,19 @@ #include "macros.hlsl" +COMMON +{ + struct RayPayload + { + float3 m_vOrigin; + float3 m_vDirection; + float3 m_vColor; + }; +} CALLABLE { - float4 CallableMain() + #include "textures.hlsl" + void CallableMain( inout RayPayload payload ) { - return float4(1); + payload.m_vColor = float3(1.0,0.0,1.0); } } diff --git a/funnyassets/shaders/macros.hlsl b/funnyassets/shaders/macros.hlsl index 7625fb4..5c53579 100644 --- a/funnyassets/shaders/macros.hlsl +++ b/funnyassets/shaders/macros.hlsl @@ -27,26 +27,29 @@ #define CALLABLE namespace CallableShader_DO_NOT_USE #endif -float4 Test() +/* + * we kinda want to lookup OpExecuteCallableKHR inside of runtime linker + * and replace _CallShader with our own + * but stupid slangc can't do noinline + * so we have to do id += 1 and id -= 1 + * overall trick 5/10 + */ +[noinline] +void _CallShader2( uint32_t id, inout Payload data ) { - return float4(1,0.5,1,1); + id -= 1; + spirv_asm + { + OpExecuteCallableKHR $id $data; + }; } -#ifndef USE_CALLABLE_SHADERS -#define USE_CALLABLE_SHADERS -#endif - -struct RunShaderResult_t -{ - A val; - -}; - [noinline] -[builtin] -RunShaderResult_t RunShader( uint32_t id, B data ) where optional B +void _CallShader( uint32_t id, inout Payload data ) { - return {}; + id += 1; + _CallShader2(id, data); } +#define CallShader _CallShader #endif diff --git a/funnyassets/shaders/mesh_raster.shader b/funnyassets/shaders/mesh_raster.shader index ec57bf6..337cd65 100644 --- a/funnyassets/shaders/mesh_raster.shader +++ b/funnyassets/shaders/mesh_raster.shader @@ -2,8 +2,6 @@ #include "funny_shared.hlsl" -USE_CALLABLE_SHADERS; - COMMON { cbuffer CameraInfo { diff --git a/funnyassets/shaders/mesh_trace.shader b/funnyassets/shaders/mesh_trace.shader index 4bcb5f6..d50a107 100644 --- a/funnyassets/shaders/mesh_trace.shader +++ b/funnyassets/shaders/mesh_trace.shader @@ -3,12 +3,12 @@ struct MeshPayload { - float3 m_vColor; } struct RayPayload { float3 m_vOrigin; float3 m_vDirection; + float3 m_vColor; }; RAY @@ -23,9 +23,8 @@ RAY void rayMain() { RayPayload p = {}; - RunShaderResult_t m = RunShader(0, p); - m.val.m_vColor; - printf("%f\n", m.val.m_vColor.x); + CallShader(0, p); + printf("%f\n", p.m_vColor.x); /* uint2 pixel = DispatchRaysIndex().xy; diff --git a/materialsystem/compiledshader.cpp b/materialsystem/compiledshader.cpp index 18ccd46..aeb7ced 100644 --- a/materialsystem/compiledshader.cpp +++ b/materialsystem/compiledshader.cpp @@ -28,12 +28,8 @@ ShaderObject_t *CCompiledShader::AllocateShader() ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, EShaderStage eStage ) { - V_printf("%i\n", m_objects.GetSize()); - V_printf("%i\n", m_lumps.GetSize()); for ( auto &o: m_objects ) { - V_printf("%i\n", o.m_eBackend); - V_printf("%i\n", o.m_eStage); if ( o.m_eBackend != eBackend ) continue; diff --git a/materialsystem/vulkan/rtlinker.cpp b/materialsystem/vulkan/rtlinker.cpp index c1b99ef..065f6af 100644 --- a/materialsystem/vulkan/rtlinker.cpp +++ b/materialsystem/vulkan/rtlinker.cpp @@ -36,6 +36,12 @@ void CVkShaderLinker::Build() uint32_t last = 0; uint32_t current = 0; + + CUtlVector callers = {}; + mspv_array(mspv_function) functions_orig; + V_memcpy(&functions_orig, &mod->functions, sizeof(functions_orig)); + mod->functions = {}; + for ( int i = 0; i < mod->types.count; i++ ) { SET_LAST(mod->types.data[i].id); @@ -50,13 +56,20 @@ void CVkShaderLinker::Build() SET_LAST(mod->variables.data[i].result); SET_LAST(mod->variables.data[i].resulttype); } - for ( int i = 0; i < mod->functions.count; i++ ) + for ( int i = 0; i < functions_orig.count; i++ ) { - SET_LAST(mod->functions.data[i].result); - mspv_function &f = mod->functions.data[i]; + SET_LAST(functions_orig.data[i].result); + mspv_function &f = functions_orig.data[i]; + bool bIsCaller = false; for ( int u = 0; u < f.instructions.len; ) { SpvOp op = (SpvOp)(f.instructions.data[u]&0xFFFF); + if (op == SpvOpExecuteCallableKHR) + { + bIsCaller = true; + callers.AppendTail(i); + V_printf("found caller: %i %u\n", i, f.result); + } uint32_t uOpLen = f.instructions.data[u]>>16; uint32_t uOpCount = SpvGetOperandCount(op); if (uOpCount == 0) @@ -90,13 +103,16 @@ void CVkShaderLinker::Build() } u+=uOpLen; V_free(peOps); - + V_free(peFlags); } + if (!bIsCaller) + mspv_array_push(mod->functions, f); } current = last; /* now we can combine shaders*/ CUtlVector functions = {}; + CUtlVector f = {}; for (auto &shader: m_shaders) { mspv_module *s = mspv_read_module(shader.m_size, shader.m_data); @@ -117,6 +133,14 @@ void CVkShaderLinker::Build() for ( int i = 0; i < s->entry_points.count; i++ ) { functions.AppendTail(s->entry_points.data[i].id+current); + for ( uint32_t u = 0; u < s->functions.count; u++ ) + { + if (s->functions.data[u].result != s->entry_points.data[i].id) + continue; + f.AppendTail(s->functions.data[u]); + break; + + } SET_LAST(s->entry_points.data[i].id+current); } @@ -222,6 +246,52 @@ void CVkShaderLinker::Build() } current = last; } + /* generate trace call */ + V_printf("functions %i\n", functions.GetSize()); + uint32_t n = 0; + for ( auto &c: callers ) + { + CUtlVector ops = {}; + mspv_function fn = functions_orig.data[c]; + mspv_data_view dv = fn.instructions; + uint32_t u; + CUtlVector inputs = {}; + + u = 0; + while(u < fn.instructions.len) + { + SpvOp op = (SpvOp)(dv.data[u]&0xFFFF); + uint32_t uOpLen = dv.data[u]>>16; + if (op != SpvOpFunctionParameter) + { + break; + } + ops.AppendTail(&dv.data[u], uOpLen); + inputs.AppendTail(dv.data[u+2]); + u += uOpLen; + } + ops.AppendTail(mspv_make_op(SpvOpLabel, 1)); + ops.AppendTail(current++); + + ops.AppendTail(mspv_make_op(SpvOpFunctionCall, 5)); + ops.AppendTail(f[n].resulttype); + ops.AppendTail(current++); + ops.AppendTail(f[n].result); + ops.AppendTail(inputs[0]); + ops.AppendTail(inputs[1]); + + ops.AppendTail(mspv_make_op(SpvOpReturn, 0)); + + + + fn.instructions.data = (uint32_t*)V_malloc(ops.GetSize()*sizeof(uint32_t)); + V_memcpy(fn.instructions.data, ops.GetData(), ops.GetSize()*sizeof(uint32_t)); + fn.instructions.len = ops.GetSize(); + mspv_array_push(mod->functions, fn); + + n++; + + } mspv_spv spv = mspv_write_module(mod); mspv_close_module(mod); diff --git a/minispv/minispv.h b/minispv/minispv.h index a85458b..a9ef9c6 100644 --- a/minispv/minispv.h +++ b/minispv/minispv.h @@ -353,6 +353,11 @@ static inline void mspv_write_op( mspv_spv *as, SpvOp op, uint16_t ops ) mspv_array_push((*as), op | (ops+1) << 16); }; +static inline uint32_t mspv_make_op( SpvOp op, uint16_t ops ) +{ + return op | (ops+1) << 16; +}; + static inline void mspv_write_string( mspv_spv *as, mspv_string_view s ) { uint32_t u; diff --git a/shadercompiler/CallableMain b/shadercompiler/CallableMain index 5998eec25b5b67b248d4a97f3ac53907dde7ae94..5bbecc0cc05b5967d210b88aee9ea16080a7b8a9 100644 GIT binary patch literal 720 zcmZ9JNlODk5QQtt#69j2FG0ygP()Bf5EY4{7cuA$2(1}(U>2DSf!zGrUIgFQ&VbmV zQeCfJRlTlh)O$15s+rlIZR?-2YIOr?Tf@iPm#t-id|j5fC?&BVTM-VnDuY*9L$&0I z1JelkewHLzdidm~12>H`HxkzJKV5W^;p8!o-hA^`Swp?>no3ebkm@Lvs_z~=nh`Yw*$OB_DG zyHS`QR^bC{xYIkUz1;ul-=l%fdb!J8@z^Hs>F72iza!hSrc|4c$#>O*U4d1$BhFmO zA=fQuf{~k-=Z=m|#fu*QowZ-aOTswt+w$O#!y JZ*@PD{Q&MHJXin# literal 376 zcmZuty9&ZU5FGOo@s%iOClMP#u@phj!oo@j_yKZaKp{p5Y3%%L8^M{7fQ1WlyEB>H z+njAp>hNj+rs(lh1h62b1H0g=yYS#LTg2VmQhjI>K6PmUAzuZXz0H!lbjlm2dG?GR zw=|DTX6~n*NfL8T;^Wm^;%rgTgT}jP6mu)_pJxxJm^&NCSzhVul51CKGje%-0(fob;8U^Eze@YXl1|;Hw@|46O{RM`WSXhI4_zzb E3vtdP!~g&Q diff --git a/shadercompiler/rayMain b/shadercompiler/rayMain index c8159b9c0daba89366eb0694a04c5a87639b2575..b1f056fffa3e6811dc77903ad504188edbaafe94 100644 GIT binary patch literal 1140 zcmZvb?Q0W35XQ%(xvQgkhlhlLcPR>}!f9@B- z=eOB~65KGE=b4#(W_FjW*V?f~SIlh7PV~=eTFr>8*s}GLuj!YA)3hjy^w)5b71R7I z&5Kc~{HpS=;%BsVL@(*1Hb1~vrOEt?Lb02rbZ@KtfkNh2~3@X$}xw#BG>Bx_wVbf0)GXKR{eU7neVGXq-SXEN5VYRJ=v#TovHEy=&tKXZMS z(J%0W1^#J)e^}uA3%qlQGZSx!{(E)r$a5|*`vOK2{7y4b`%y+L@SZUBfp>*FGIW>^ z4rX?0!JG@7u;*BqSl~y()CYbjj8>xi=N%InG3wZhCTAi3Mm5~)V_93qeUsbQPVV%% z=e%*yf8paNs^Ps~%80S9>D1`$%J_!Cd}q}B6?-iUZ%MzJjJMy@OuYAo$K3a(j5pqr Rr#ENW_VI7cx~qi;-G8iwRH6U? literal 1220 zcmZ9L(N7aW5XJ{euLwpZM19cIR>YWScvKM;i9DDX6!K}xn4>7pZlWm z`|aJCrrS*C`@Wf-*_~}0t2-?VR?O^~rTS)V*{Y#z*t+$@@6qQ^y(rDnXc|vkS|pcI zk`6P)Hx)mW|B|KsDztYTU(Bw;JV}e8-Li(F=4;)yraq?1W)qkAR(CA$e5=Z#C)Uts zv%)RmBjMfQhOa=4o|}hmKF-|0R3Y$nCEFyrKFyOWUp%mu*QqD{ILYJ7BFTJTPVz|l zNjx3Zg{XtZQvSzmoaNxA>a^v1v$Q{QgE;TS)7iL)3Tc6@`51ZEZmisfJrPcHuBKwU z!UI=0;`Hpw|F7eMXUuM&hbv-Z7dZt~>^Np+{W1*EZ zDD_(7z23?W5VUS8i+O&K9m>E*GIIWiy_PX^`gUc^oi}==bMY?xR>91T-zsnMRKA}5 zFX6?v7%uUPigQo!;(YZN@ES4p!Rwiggwcr61763*!f2u1iMdQ