prototype for spirv linking

This commit is contained in:
2026-04-30 22:03:31 +03:00
parent 9569555347
commit 386c2fc045
10 changed files with 120 additions and 34 deletions

View File

@@ -2,13 +2,18 @@
COMMON COMMON
{ {
struct RayPayload
{
float3 m_vOrigin;
float3 m_vDirection;
float3 m_vColor;
};
} }
CALLABLE CALLABLE
{ {
#include "textures.hlsl" #include "textures.hlsl"
float4 brdfMain() void brdfMain( inout RayPayload payload )
{ {
return float4(1); payload.m_vColor = float3(1.0,0.0,1.0);
} }
} }

View File

@@ -1,9 +1,19 @@
#include "macros.hlsl" #include "macros.hlsl"
COMMON
{
struct RayPayload
{
float3 m_vOrigin;
float3 m_vDirection;
float3 m_vColor;
};
}
CALLABLE CALLABLE
{ {
float4 CallableMain() #include "textures.hlsl"
void CallableMain( inout RayPayload payload )
{ {
return float4(1); payload.m_vColor = float3(1.0,0.0,1.0);
} }
} }

View File

@@ -27,26 +27,29 @@
#define CALLABLE namespace CallableShader_DO_NOT_USE #define CALLABLE namespace CallableShader_DO_NOT_USE
#endif #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<Payload>( 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>
{
A val;
};
[noinline] [noinline]
[builtin] void _CallShader<Payload>( uint32_t id, inout Payload data )
RunShaderResult_t<A> RunShader<A, B>( uint32_t id, B data ) where optional B
{ {
return {}; id += 1;
_CallShader2(id, data);
} }
#define CallShader _CallShader
#endif #endif

View File

@@ -2,8 +2,6 @@
#include "funny_shared.hlsl" #include "funny_shared.hlsl"
USE_CALLABLE_SHADERS;
COMMON { COMMON {
cbuffer CameraInfo cbuffer CameraInfo
{ {

View File

@@ -3,12 +3,12 @@
struct MeshPayload struct MeshPayload
{ {
float3 m_vColor;
} }
struct RayPayload struct RayPayload
{ {
float3 m_vOrigin; float3 m_vOrigin;
float3 m_vDirection; float3 m_vDirection;
float3 m_vColor;
}; };
RAY RAY
@@ -23,9 +23,8 @@ RAY
void rayMain() void rayMain()
{ {
RayPayload p = {}; RayPayload p = {};
RunShaderResult_t<MeshPayload> m = RunShader<MeshPayload, RayPayload>(0, p); CallShader<RayPayload>(0, p);
m.val.m_vColor; printf("%f\n", p.m_vColor.x);
printf("%f\n", m.val.m_vColor.x);
/* /*
uint2 pixel = DispatchRaysIndex().xy; uint2 pixel = DispatchRaysIndex().xy;

View File

@@ -28,12 +28,8 @@ ShaderObject_t *CCompiledShader::AllocateShader()
ShaderObject_t *CCompiledShader::FindShaderObject( EShaderBackend eBackend, EShaderStage eStage ) 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 ) for ( auto &o: m_objects )
{ {
V_printf("%i\n", o.m_eBackend);
V_printf("%i\n", o.m_eStage);
if ( o.m_eBackend != eBackend ) if ( o.m_eBackend != eBackend )
continue; continue;

View File

@@ -36,6 +36,12 @@ void CVkShaderLinker::Build()
uint32_t last = 0; uint32_t last = 0;
uint32_t current = 0; uint32_t current = 0;
CUtlVector<uint32_t> 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++ ) for ( int i = 0; i < mod->types.count; i++ )
{ {
SET_LAST(mod->types.data[i].id); 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].result);
SET_LAST(mod->variables.data[i].resulttype); 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); SET_LAST(functions_orig.data[i].result);
mspv_function &f = mod->functions.data[i]; mspv_function &f = functions_orig.data[i];
bool bIsCaller = false;
for ( int u = 0; u < f.instructions.len; ) for ( int u = 0; u < f.instructions.len; )
{ {
SpvOp op = (SpvOp)(f.instructions.data[u]&0xFFFF); 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 uOpLen = f.instructions.data[u]>>16;
uint32_t uOpCount = SpvGetOperandCount(op); uint32_t uOpCount = SpvGetOperandCount(op);
if (uOpCount == 0) if (uOpCount == 0)
@@ -90,13 +103,16 @@ void CVkShaderLinker::Build()
} }
u+=uOpLen; u+=uOpLen;
V_free(peOps); V_free(peOps);
V_free(peFlags);
} }
if (!bIsCaller)
mspv_array_push(mod->functions, f);
} }
current = last; current = last;
/* now we can combine shaders*/ /* now we can combine shaders*/
CUtlVector<uint32_t> functions = {}; CUtlVector<uint32_t> functions = {};
CUtlVector<mspv_function> f = {};
for (auto &shader: m_shaders) for (auto &shader: m_shaders)
{ {
mspv_module *s = mspv_read_module(shader.m_size, shader.m_data); 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++ ) for ( int i = 0; i < s->entry_points.count; i++ )
{ {
functions.AppendTail(s->entry_points.data[i].id+current); 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); SET_LAST(s->entry_points.data[i].id+current);
} }
@@ -222,6 +246,52 @@ void CVkShaderLinker::Build()
} }
current = last; current = last;
} }
/* generate trace call */
V_printf("functions %i\n", functions.GetSize());
uint32_t n = 0;
for ( auto &c: callers )
{
CUtlVector<uint32_t> ops = {};
mspv_function fn = functions_orig.data[c];
mspv_data_view dv = fn.instructions;
uint32_t u;
CUtlVector<uint32_t> 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_spv spv = mspv_write_module(mod);
mspv_close_module(mod); mspv_close_module(mod);

View File

@@ -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); 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 ) static inline void mspv_write_string( mspv_spv *as, mspv_string_view s )
{ {
uint32_t u; uint32_t u;

Binary file not shown.

Binary file not shown.