diff --git a/Sources/backends/cstyle.c b/Sources/backends/cstyle.c index 38e50d4..4ab5ba1 100644 --- a/Sources/backends/cstyle.c +++ b/Sources/backends/cstyle.c @@ -89,10 +89,15 @@ void cstyle_write_opcode(char *code, size_t *offset, opcode *o, type_string_func break; } break; - case OPCODE_LOAD_CONSTANT: + case OPCODE_LOAD_FLOAT_CONSTANT: indent(code, offset, *indentation); - *offset += sprintf(&code[*offset], "%s _%" PRIu64 " = %f;\n", type_string(o->op_load_constant.to.type.type), o->op_load_constant.to.index, - o->op_load_constant.number); + *offset += sprintf(&code[*offset], "%s _%" PRIu64 " = %f;\n", type_string(o->op_load_float_constant.to.type.type), o->op_load_float_constant.to.index, + o->op_load_float_constant.number); + break; + case OPCODE_LOAD_BOOL_CONSTANT: + indent(code, offset, *indentation); + *offset += sprintf(&code[*offset], "%s _%" PRIu64 " = %s;\n", type_string(o->op_load_bool_constant.to.type.type), o->op_load_bool_constant.to.index, + o->op_load_bool_constant.boolean ? "true" : "false"); break; case OPCODE_ADD: { indent(code, offset, *indentation); diff --git a/Sources/backends/hlsl.c b/Sources/backends/hlsl.c index 668517b..838d23d 100644 --- a/Sources/backends/hlsl.c +++ b/Sources/backends/hlsl.c @@ -603,6 +603,10 @@ 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 " = SV_GroupIndex;\n", type_string(o->op_call.var.type.type), o->op_call.var.index); } + else if (o->op_call.func == add_name("world_ray_direction")) { + 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 { *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/backends/spirv.c b/Sources/backends/spirv.c index 4a40f6c..058b7ca 100644 --- a/Sources/backends/spirv.c +++ b/Sources/backends/spirv.c @@ -533,6 +533,11 @@ static spirv_id write_constant_float(instructions_buffer *instructions, spirv_id return write_constant(instructions, spirv_float_type, value_id, uint32_value); } +static spirv_id write_constant_bool(instructions_buffer *instructions, spirv_id value_id, bool value) { + uint32_t uint32_value = *(uint32_t *)&value; + return write_constant(instructions, spirv_bool_type, value_id, uint32_value); +} + static void write_vertex_output_decorations(instructions_buffer *instructions, spirv_id output_struct) { { uint32_t operands[] = {output_struct.id, 0, (uint32_t)DECORATION_BUILTIN, (uint32_t)BUILTIN_POSITION}; @@ -629,6 +634,20 @@ static spirv_id get_float_constant(float value) { return index; } +static struct { + bool key; + spirv_id value; +} *bool_constants = NULL; + +static spirv_id get_bool_constant(bool value) { + spirv_id index = hmget(bool_constants, value); + if (index.id == 0) { + index = allocate_index(); + hmput(bool_constants, value, index); + } + return index; +} + static spirv_id write_op_access_chain(instructions_buffer *instructions, spirv_id result_type, spirv_id base, int *indices, uint16_t indices_size) { spirv_id pointer = allocate_index(); @@ -819,9 +838,14 @@ static void write_function(instructions_buffer *instructions, function *f, spirv break; } - case OPCODE_LOAD_CONSTANT: { - spirv_id id = get_float_constant(o->op_load_constant.number); - hmput(index_map, o->op_load_constant.to.index, id); + case OPCODE_LOAD_FLOAT_CONSTANT: { + spirv_id id = get_float_constant(o->op_load_float_constant.number); + hmput(index_map, o->op_load_float_constant.to.index, id); + break; + } + case OPCODE_LOAD_BOOL_CONSTANT: { + spirv_id id = get_bool_constant(o->op_load_bool_constant.boolean); + hmput(index_map, o->op_load_bool_constant.to.index, id); break; } case OPCODE_CALL: { @@ -1046,6 +1070,11 @@ static void write_constants(instructions_buffer *instructions) { for (size_t i = 0; i < size; ++i) { write_constant_float(instructions, float_constants[i].value, float_constants[i].key); } + + size = hmlenu(bool_constants); + for (size_t i = 0; i < size; ++i) { + write_constant_bool(instructions, bool_constants[i].value, bool_constants[i].key); + } } static void init_index_map(void) { diff --git a/Sources/backends/wgsl.c b/Sources/backends/wgsl.c index 38c5a28..3acbb37 100644 --- a/Sources/backends/wgsl.c +++ b/Sources/backends/wgsl.c @@ -566,10 +566,15 @@ static void write_functions(char *code, size_t *offset) { type_string(o->op_binary.result.type.type), o->op_binary.left.index, o->op_binary.right.index); break; } - case OPCODE_LOAD_CONSTANT: + case OPCODE_LOAD_FLOAT_CONSTANT: indent(code, offset, indentation); - *offset += sprintf(&code[*offset], "var _%" PRIu64 ": %s = %f;\n", o->op_load_constant.to.index, - type_string(o->op_load_constant.to.type.type), o->op_load_constant.number); + *offset += sprintf(&code[*offset], "var _%" PRIu64 ": %s = %f;\n", o->op_load_float_constant.to.index, + type_string(o->op_load_float_constant.to.type.type), o->op_load_float_constant.number); + break; + case OPCODE_LOAD_BOOL_CONSTANT: + indent(code, offset, indentation); + *offset += sprintf(&code[*offset], "var _%" PRIu64 ": %s = %s;\n", o->op_load_bool_constant.to.index, + type_string(o->op_load_bool_constant.to.type.type), o->op_load_bool_constant.boolean ? "true" : "false"); break; case OPCODE_CALL: { debug_context context = {0}; diff --git a/Sources/compiler.c b/Sources/compiler.c index 8ac4817..34f4d87 100644 --- a/Sources/compiler.c +++ b/Sources/compiler.c @@ -399,8 +399,19 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { } } case EXPRESSION_BOOLEAN: { - debug_context context = {0}; - error(context, "not implemented"); + type_ref t; + init_type_ref(&t, NO_NAME); + t.type = float_id; + variable v = allocate_variable(t, VARIABLE_LOCAL); + + opcode o; + o.type = OPCODE_LOAD_BOOL_CONSTANT; + o.size = OP_SIZE(o, op_load_bool_constant); + o.op_load_bool_constant.boolean = e->boolean; + o.op_load_bool_constant.to = v; + emit_op(code, &o); + + return v; } case EXPRESSION_NUMBER: { type_ref t; @@ -409,10 +420,10 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { variable v = allocate_variable(t, VARIABLE_LOCAL); opcode o; - o.type = OPCODE_LOAD_CONSTANT; - o.size = OP_SIZE(o, op_load_constant); - o.op_load_constant.number = (float)e->number; - o.op_load_constant.to = v; + o.type = OPCODE_LOAD_FLOAT_CONSTANT; + o.size = OP_SIZE(o, op_load_float_constant); + o.op_load_float_constant.number = (float)e->number; + o.op_load_float_constant.to = v; emit_op(code, &o); return v; @@ -457,9 +468,12 @@ variable emit_expression(opcodes *code, block *parent, expression *e) { o.size = OP_SIZE(o, op_load_member); debug_context context = {0}; - check(e->member.left->kind == EXPRESSION_VARIABLE, context, "Misformed member construct"); - - o.op_load_member.from = find_variable(parent, e->member.left->variable); + if (e->member.left->kind == EXPRESSION_VARIABLE) { + o.op_load_member.from = find_variable(parent, e->member.left->variable); + } + else { + o.op_load_member.from = emit_expression(code, parent, e->member.left); + } check(o.op_load_member.from.index != 0, context, "Load var is broken"); o.op_load_member.to = v; diff --git a/Sources/compiler.h b/Sources/compiler.h index b46bebd..ea274de 100644 --- a/Sources/compiler.h +++ b/Sources/compiler.h @@ -28,7 +28,8 @@ typedef struct opcode { OPCODE_ADD_AND_STORE_MEMBER, OPCODE_DIVIDE_AND_STORE_MEMBER, OPCODE_MULTIPLY_AND_STORE_MEMBER, - OPCODE_LOAD_CONSTANT, + OPCODE_LOAD_FLOAT_CONSTANT, + OPCODE_LOAD_BOOL_CONSTANT, OPCODE_LOAD_MEMBER, OPCODE_RETURN, OPCODE_CALL, @@ -77,7 +78,11 @@ typedef struct opcode { struct { float number; variable to; - } op_load_constant; + } op_load_float_constant; + struct { + bool boolean; + variable to; + } op_load_bool_constant; struct { variable from; variable to; diff --git a/Sources/functions.c b/Sources/functions.c index 3a98209..1e70a9c 100644 --- a/Sources/functions.c +++ b/Sources/functions.c @@ -49,6 +49,18 @@ static void add_func_float3(char *name) { f->block = NULL; } +static void add_func_float_float(char *name) { + function_id func = add_function(add_name(name)); + function *f = get_function(func); + init_type_ref(&f->return_type, add_name("float")); + f->return_type.type = find_type_by_ref(&f->return_type); + f->parameter_names[0] = add_name("a"); + init_type_ref(&f->parameter_types[0], add_name("float")); + f->parameter_types[0].type = find_type_by_ref(&f->parameter_types[0]); + f->parameters_size = 1; + f->block = NULL; +} + static void add_func_float3_float3(char *name) { function_id func = add_function(add_name(name)); function *f = get_function(func); @@ -136,6 +148,7 @@ void functions_init(void) { add_func_float3_float_float_float("lerp"); add_func_float3("world_ray_direction"); add_func_float3_float3("normalize"); + add_func_float_float("saturate"); } static void grow_if_needed(uint64_t size) { diff --git a/tests/in/test.kong b/tests/in/test.kong index ed28b65..ec36b72 100644 --- a/tests/in/test.kong +++ b/tests/in/test.kong @@ -1,4 +1,4 @@ -struct VertexIn { +/*struct VertexIn { position: float3; } @@ -19,10 +19,14 @@ fun pos(input: VertexIn): FragmentIn { #[fragment] fun pixel(input: FragmentIn): float4 { var color: float4; - color.r = 1.0; - color.g = 0.0; + color.r = 0.0; + color.g = 1.0; color.b = 0.0; color.a = 1.0; + + var a: int = 3; + a += 2; + return color; } @@ -32,4 +36,43 @@ struct Pipe { fragment = pixel; } -// https://shader-playground.timjones.io/9daab221a76e1fe6fe3fbad510c436c1 +#[compute, threads(32, 1, 1)] +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; +} + +fun sendrays(): void { + +} + +fun raymissed(payload: Payload): void { + var slope: float = normalize(world_ray_direction()).y; + var t: float = saturate(slope * 5 + 0.5); + payload.color = lerp(skyBottom, skyTop, t); + + payload.missed = true; +} + +fun closesthit(payload: Payload, uv: float2): void { + +} + +#[raypipe] +struct RayPipe { + gen = sendrays; + miss = raymissed; + closest = closesthit; +}