diff --git a/Sources/backends/hlsl.c b/Sources/backends/hlsl.c index 838d23d..e2851c3 100644 --- a/Sources/backends/hlsl.c +++ b/Sources/backends/hlsl.c @@ -607,6 +607,14 @@ 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 " = WorldRayDirection();\n", type_string(o->op_call.var.type.type), o->op_call.var.index); } + else if (o->op_call.func == add_name("ray_index")) { + check(o->op_call.parameters_size == 0, context, "group_index can not have a parameter"); + *offset += sprintf(&hlsl[*offset], "%s _%" PRIu64 " = DispatchRaysIndex();\n", type_string(o->op_call.var.type.type), o->op_call.var.index); + } + else if (o->op_call.func == add_name("ray_dimensions")) { + 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 { *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)); diff --git a/Sources/functions.c b/Sources/functions.c index 1e70a9c..bc8304e 100644 --- a/Sources/functions.c +++ b/Sources/functions.c @@ -49,6 +49,15 @@ static void add_func_float3(char *name) { f->block = NULL; } +static void add_func_uint3(char *name) { + function_id func = add_function(add_name(name)); + function *f = get_function(func); + init_type_ref(&f->return_type, add_name("uint3")); + f->return_type.type = find_type_by_ref(&f->return_type); + f->parameters_size = 0; + f->block = NULL; +} + static void add_func_float_float(char *name) { function_id func = add_function(add_name(name)); function *f = get_function(func); @@ -149,6 +158,8 @@ void functions_init(void) { add_func_float3("world_ray_direction"); add_func_float3_float3("normalize"); add_func_float_float("saturate"); + add_func_uint3("ray_index"); + add_func_float3("ray_dimensions"); } static void grow_if_needed(uint64_t size) { diff --git a/Sources/kong.c b/Sources/kong.c index 142f14a..54381cc 100644 --- a/Sources/kong.c +++ b/Sources/kong.c @@ -108,7 +108,7 @@ void resolve_member_type(statement *parent_block, type_ref parent_type, expressi e->type = e->member.right->type; } -static bool types_compatible(type_id left, type_id right){ +static bool types_compatible(type_id left, type_id right) { if (left == right) { return true; } @@ -126,6 +126,32 @@ static bool types_compatible(type_id left, type_id right){ return true; } + if ((left == uint_id && right == float_id) || (left == float_id && right == uint_id)) { + return true; + } + if ((left == uint2_id && right == float2_id) || (left == float2_id && right == uint2_id)) { + return true; + } + if ((left == uint3_id && right == float3_id) || (left == float3_id && right == uint3_id)) { + return true; + } + if ((left == uint4_id && right == float4_id) || (left == float4_id && right == uint4_id)) { + return true; + } + + if ((left == uint_id && right == int_id) || (left == int_id && right == uint_id)) { + return true; + } + if ((left == uint2_id && right == int2_id) || (left == int2_id && right == uint2_id)) { + return true; + } + if ((left == uint3_id && right == int3_id) || (left == int3_id && right == uint3_id)) { + return true; + } + if ((left == uint4_id && right == int4_id) || (left == int4_id && right == uint4_id)) { + return true; + } + return false; } @@ -162,6 +188,56 @@ static type_ref upgrade_type(type_ref left_type, type_ref right_type) { return left_type; } + if (left == uint_id && right == float_id) { + return right_type; + } + if (left == float_id && right == uint_id) { + return left_type; + } + if (left == uint2_id && right == float2_id) { + return right_type; + } + if (left == float2_id && right == uint2_id) { + return left_type; + } + if (left == uint3_id && right == float3_id) { + return right_type; + } + if (left == float3_id && right == uint3_id) { + return left_type; + } + if (left == uint4_id && right == float4_id) { + return right_type; + } + if (left == float4_id && right == uint4_id) { + return left_type; + } + + if (left == uint_id && right == int_id) { + return right_type; + } + if (left == int_id && right == uint_id) { + return left_type; + } + if (left == uint2_id && right == int2_id) { + return right_type; + } + if (left == int2_id && right == uint2_id) { + return left_type; + } + if (left == uint3_id && right == int3_id) { + return right_type; + } + if (left == int3_id && right == uint3_id) { + return left_type; + } + if (left == uint4_id && right == int4_id) { + return right_type; + } + if (left == int4_id && right == uint4_id) { + return left_type; + } + kong_log(LOG_LEVEL_WARNING, "Suspicious type upgrade"); return left_type; } diff --git a/Sources/types.c b/Sources/types.c index 2f46964..d69bd2c 100644 --- a/Sources/types.c +++ b/Sources/types.c @@ -20,6 +20,10 @@ type_id int_id; type_id int2_id; type_id int3_id; type_id int4_id; +type_id uint_id; +type_id uint2_id; +type_id uint3_id; +type_id uint4_id; type_id bool_id; type_id function_type_id; type_id tex2d_type_id; @@ -232,6 +236,96 @@ static void int4_found_int4(char *permutation) { ++t->members.size; } +static void uint2_found_uint(char *permutation) { + type *t = get_type(uint2_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint2_found_uint2(char *permutation) { + type *t = get_type(uint2_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint2_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint3_found_uint(char *permutation) { + type *t = get_type(uint3_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint3_found_uint2(char *permutation) { + type *t = get_type(uint3_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint2_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint3_found_uint3(char *permutation) { + type *t = get_type(uint3_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint3_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint4_found_uint(char *permutation) { + type *t = get_type(uint4_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint4_found_uint2(char *permutation) { + type *t = get_type(uint4_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint2_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint4_found_uint3(char *permutation) { + type *t = get_type(uint4_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint3_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + +static void uint4_found_uint4(char *permutation) { + type *t = get_type(uint4_id); + debug_context context = {0}; + check(t->members.size < MAX_MEMBERS, context, "Out of members"); + t->members.m[t->members.size].name = add_name(permutation); + t->members.m[t->members.size].type.type = uint4_id; + t->members.m[t->members.size].type.array_size = 0; + ++t->members.size; +} + void init_type_ref(type_ref *t, name_id name) { t->name = name; t->type = NO_TYPE; @@ -261,6 +355,8 @@ void types_init(void) { get_type(float_id)->built_in = true; int_id = add_type(add_name("int")); get_type(int_id)->built_in = true; + uint_id = add_type(add_name("uint")); + get_type(uint_id)->built_in = true; { float2_id = add_type(add_name("float2")); @@ -340,6 +436,45 @@ void types_init(void) { permute(letters, (int)strlen(letters), 3, int4_found_int4); } + { + uint2_id = add_type(add_name("uint2")); + get_type(uint2_id)->built_in = true; + const char *letters = "xy"; + permute(letters, (int)strlen(letters), 1, uint2_found_uint); + permute(letters, (int)strlen(letters), 2, uint2_found_uint2); + letters = "rg"; + permute(letters, (int)strlen(letters), 1, uint2_found_uint); + permute(letters, (int)strlen(letters), 2, uint2_found_uint2); + } + + { + uint3_id = add_type(add_name("uint3")); + get_type(uint3_id)->built_in = true; + const char *letters = "xyz"; + permute(letters, (int)strlen(letters), 1, uint3_found_uint); + permute(letters, (int)strlen(letters), 2, uint3_found_uint2); + permute(letters, (int)strlen(letters), 3, uint3_found_uint3); + letters = "rgb"; + permute(letters, (int)strlen(letters), 1, uint3_found_uint); + permute(letters, (int)strlen(letters), 2, uint3_found_uint2); + permute(letters, (int)strlen(letters), 3, uint3_found_uint3); + } + + { + uint4_id = add_type(add_name("uint4")); + get_type(uint4_id)->built_in = true; + const char *letters = "xyzw"; + permute(letters, (int)strlen(letters), 1, uint4_found_uint); + permute(letters, (int)strlen(letters), 2, uint4_found_uint2); + permute(letters, (int)strlen(letters), 3, uint4_found_uint3); + permute(letters, (int)strlen(letters), 3, uint4_found_uint4); + letters = "rgba"; + permute(letters, (int)strlen(letters), 1, uint4_found_uint); + permute(letters, (int)strlen(letters), 2, uint4_found_uint2); + permute(letters, (int)strlen(letters), 3, uint4_found_uint3); + permute(letters, (int)strlen(letters), 3, uint4_found_uint4); + } + { float4x4_id = add_type(add_name("float4x4")); get_type(float4x4_id)->built_in = true; diff --git a/Sources/types.h b/Sources/types.h index b65a20d..c072fb7 100644 --- a/Sources/types.h +++ b/Sources/types.h @@ -87,6 +87,10 @@ extern type_id int_id; extern type_id int2_id; extern type_id int3_id; extern type_id int4_id; +extern type_id uint_id; +extern type_id uint2_id; +extern type_id uint3_id; +extern type_id uint4_id; extern type_id bool_id; extern type_id tex2d_type_id; extern type_id texcube_type_id; diff --git a/tests/in/test.kong b/tests/in/test.kong index ec36b72..9f9d7db 100644 --- a/tests/in/test.kong +++ b/tests/in/test.kong @@ -55,7 +55,13 @@ struct Payload { } fun sendrays(): void { + var idx: uint2 = ray_index().xy; + var size: float2 = ray_dimensions().xy; + var uv: float2 = idx / size; + var target: float3 = float3((uv.x * 2 - 1) * 1.8 * (size.x / size.y), + (1 - uv.y) * 4 - 2 + camera.y, + 0); } fun raymissed(payload: Payload): void {