From 86c79c085a8b97ec0286656179d043f809e62947 Mon Sep 17 00:00:00 2001 From: Robert Konrad Date: Sun, 25 Aug 2024 14:01:11 +0200 Subject: [PATCH] Trace rays --- Sources/backends/hlsl.c | 19 ++++++++++++++++--- Sources/functions.c | 25 +++++++++++++++++++++++++ Sources/parser.c | 4 ++++ Sources/parser.h | 11 ++++++++++- tests/in/test.kong | 14 ++++++++------ 5 files changed, 63 insertions(+), 10 deletions(-) diff --git a/Sources/backends/hlsl.c b/Sources/backends/hlsl.c index 58c3ff9..104f1a7 100644 --- a/Sources/backends/hlsl.c +++ b/Sources/backends/hlsl.c @@ -264,6 +264,9 @@ static void write_globals(char *hlsl, size_t *offset, function *main, function * else if (g.type == texcube_type_id) { *offset += sprintf(&hlsl[*offset], "TextureCube _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index); } + else if (g.type == bvh_type_id) { + *offset += sprintf(&hlsl[*offset], "RaytracingAccelerationStructure _%" PRIu64 " : register(t%i);\n\n", g.var_index, register_index); + } else if (g.type == float_id) { *offset += sprintf(&hlsl[*offset], "static const float _%" PRIu64 " = %f;\n\n", g.var_index, g.value.value.floats[0]); } @@ -624,9 +627,19 @@ static void write_functions(char *hlsl, size_t *offset, shader_stage stage, func check(o->op_call.parameters_size == 0, context, "group_index can not have a parameter"); *offset += sprintf(&hlsl[*offset], "%s _%" PRIu64 " = DispatchRaysDimensions();\n", type_string(o->op_call.var.type.type), o->op_call.var.index); } + else if (o->op_call.func == add_name("trace_ray")) { + check(o->op_call.parameters_size == 3, context, "trace_ray requires three parameters"); + *offset += sprintf(&hlsl[*offset], "TraceRay(_%" PRIu64 ", RAY_FLAG_NONE, 0xFF, 0, 0, 0, _%" PRIu64 ", _%" PRIu64 ");\n", o->op_call.parameters[0].index, + o->op_call.parameters[1].index, o->op_call.parameters[2].index); + } else { - *offset += sprintf(&hlsl[*offset], "%s _%" PRIu64 " = %s(", type_string(o->op_call.var.type.type), o->op_call.var.index, - function_string(o->op_call.func)); + if (o->op_call.var.type.type == void_id) { + *offset += sprintf(&hlsl[*offset], "%s(", function_string(o->op_call.func)); + } + else { + *offset += sprintf(&hlsl[*offset], "%s _%" PRIu64 " = %s(", type_string(o->op_call.var.type.type), o->op_call.var.index, + function_string(o->op_call.func)); + } if (o->op_call.parameters_size > 0) { *offset += sprintf(&hlsl[*offset], "_%" PRIu64, o->op_call.parameters[0].index); for (uint8_t i = 1; i < o->op_call.parameters_size; ++i) { @@ -838,7 +851,7 @@ void hlsl_export(char *directory, api_kind d3d) { global_register_indices[i] = sampler_index; sampler_index += 1; } - else if (g.type == tex2d_type_id || g.type == texcube_type_id) { + else if (g.type == tex2d_type_id || g.type == texcube_type_id || g.type == bvh_type_id) { global_register_indices[i] = texture_index; texture_index += 1; } diff --git a/Sources/functions.c b/Sources/functions.c index bc8304e..3afb6dc 100644 --- a/Sources/functions.c +++ b/Sources/functions.c @@ -149,6 +149,31 @@ void functions_init(void) { f->block = NULL; } + { + function_id func = add_function(add_name("trace_ray")); + function *f = get_function(func); + + init_type_ref(&f->return_type, add_name("void")); + f->return_type.type = find_type_by_ref(&f->return_type); + + f->parameter_names[0] = add_name("scene"); + init_type_ref(&f->parameter_types[0], add_name("bvh")); + f->parameter_types[0].type = find_type_by_ref(&f->parameter_types[0]); + f->parameters_size = 1; + + f->parameter_names[1] = add_name("ray"); + init_type_ref(&f->parameter_types[1], add_name("ray")); + f->parameter_types[1].type = find_type_by_ref(&f->parameter_types[1]); + f->parameters_size = 1; + + f->parameter_names[2] = add_name("payload"); + init_type_ref(&f->parameter_types[2], add_name("void")); + f->parameter_types[2].type = find_type_by_ref(&f->parameter_types[2]); + f->parameters_size = 1; + + f->block = NULL; + } + add_func_int("group_id"); add_func_int("group_thread_id"); add_func_int("dispatch_thread_id"); diff --git a/Sources/parser.c b/Sources/parser.c index 2924c48..4a286c6 100644 --- a/Sources/parser.c +++ b/Sources/parser.c @@ -1072,6 +1072,10 @@ static definition parse_const(state_t *state) { d.kind = DEFINITION_SAMPLER; d.global = add_global(sampler_type_id, name.identifier); } + else if (type_name == add_name("bvh")) { + d.kind = DEFINITION_BVH; + d.global = add_global(bvh_type_id, name.identifier); + } else if (type_name == add_name("float")) { debug_context context = {0}; check(value != NULL, context, "const float requires an initialization value"); diff --git a/Sources/parser.h b/Sources/parser.h index 5c4ebe5..d1a80a5 100644 --- a/Sources/parser.h +++ b/Sources/parser.h @@ -120,7 +120,16 @@ typedef struct statement { } statement; typedef struct definition { - enum { DEFINITION_FUNCTION, DEFINITION_STRUCT, DEFINITION_TEX2D, DEFINITION_TEXCUBE, DEFINITION_SAMPLER, DEFINITION_CONST_CUSTOM, DEFINITION_CONST_BASIC } kind; + enum { + DEFINITION_FUNCTION, + DEFINITION_STRUCT, + DEFINITION_TEX2D, + DEFINITION_TEXCUBE, + DEFINITION_SAMPLER, + DEFINITION_CONST_CUSTOM, + DEFINITION_CONST_BASIC, + DEFINITION_BVH + } kind; union { function_id function; diff --git a/tests/in/test.kong b/tests/in/test.kong index 27a22c2..6528389 100644 --- a/tests/in/test.kong +++ b/tests/in/test.kong @@ -43,17 +43,19 @@ fun comp(): void { // based on https://landelare.github.io/2023/02/18/dxr-tutorial.html -const camera: float3 = float3(0, 1.5, -7); -const light: float3 = float3(0, 200, 0); -const skyTop: float3 = float3(0.24, 0.44, 0.72); -const skyBottom: float3 = float3(0.75, 0.86, 0.93); - struct Payload { color: float3; allow_reflection: bool; missed: bool; } +const scene: bvh; + +const camera: float3 = float3(0, 1.5, -7); +const light: float3 = float3(0, 200, 0); +const skyTop: float3 = float3(0.24, 0.44, 0.72); +const skyBottom: float3 = float3(0.75, 0.86, 0.93); + fun sendrays(): void { var idx: uint2 = ray_index().xy; var size: float2 = ray_dimensions().xy; @@ -73,7 +75,7 @@ fun sendrays(): void { payload.allow_reflection = true; payload.missed = false; - //trace_ray(scene, primary, payload); + trace_ray(scene, primary, payload); //uav[idx] = float4(payload.color, 1); }