diff --git a/Codegen.jai b/Codegen.jai index 54010ab..3ff3b9b 100644 --- a/Codegen.jai +++ b/Codegen.jai @@ -1,6 +1,7 @@ Output_Language :: enum { HLSL; - GLSL; + GLSL; // @Incomplete + MLSL; // @Incomplete } Codegen_State :: struct { @@ -28,10 +29,11 @@ Codegen_Result :: struct { } init_codegen_state :: (state : *Codegen_State, root : *AST_Node, checker_result : Semantic_Check_Result, output_language : Output_Language) { - state.root = root; - state.scope_stack = checker_result.scope_stack; - state.type_variables = checker_result.type_variables; - state.current_scope = cast(Scope_Handle)1; + state.root = root; + state.scope_stack = checker_result.scope_stack; + state.type_variables = checker_result.type_variables; + state.current_scope = cast(Scope_Handle)1; + state.output_language = output_language; init_string_builder(*state.builder); } @@ -48,6 +50,14 @@ emit_field :: (state : *Codegen_State, node : *AST_Node, indentation : int) { print_to_builder(*state.builder, "% ", type_to_string(field)); print_to_builder(*state.builder, "%", node.name); + if field.type == .Sampler { + print_to_builder(*state.builder, " : register(s%)", field.resource_index); + } + + if field.type == .Texture2D { + print_to_builder(*state.builder, " : register(t%)", field.resource_index); + } + for i :0..node.children.count - 1 { child := node.children[i]; @@ -133,26 +143,40 @@ emit_properties :: (state : *Codegen_State, node : *AST_Node, indentation : int) variable := h2tv(state.type_variables, find_result.type_variable); - print_to_builder(*state.builder, "cbuffer __PROPERTIES : register(b%) \n{\n", variable.buffer_index); + print_to_builder(*state.builder, "cbuffer __PROPERTIES : register(b%) \n{\n", variable.resource_index); previous_scope := state.current_scope; state.current_scope = variable.scope; + resources : Static_Array(*AST_Node, 8); + for child : node.children { if child.kind == .FieldList { for field : child.children { + tv := h2tv(state.type_variables, field.type_variable); + if tv.type == .Sampler || tv.type == .Texture2D { + array_add(*resources, field); + continue; + } emit_node(state, field, 1); append(*state.builder, ";\n"); } - } - } - state.current_scope = previous_scope; - append(*state.builder, "}\n\n"); + + for i : 0..resources.count - 1 { + resource := resources[i]; + emit_node(state, resource, 0); + + append(*state.builder, ";\n"); + } + + append(*state.builder, "\n"); + + state.current_scope = previous_scope; } emit_function :: (state : *Codegen_State, node : *AST_Node, indentation : int, emit_body := true) { @@ -372,7 +396,7 @@ emit_struct :: (state : *Codegen_State, node : *AST_Node, indentation : int) { emit_cbuffer :: (state : *Codegen_State, node : *AST_Node, indentation : int) { variable := h2tv(state.type_variables, node.type_variable); - print_to_builder(*state.builder, "cbuffer % : register(b%)", variable.name, variable.buffer_index); + print_to_builder(*state.builder, "cbuffer % : register(b%)", variable.name, variable.resource_index); current_scope := state.current_scope; state.current_scope = h2tv(state.type_variables, node.type_variable).scope; diff --git a/Semantic_Analysis.jai b/Semantic_Analysis.jai index 1b329ea..4d6151e 100644 --- a/Semantic_Analysis.jai +++ b/Semantic_Analysis.jai @@ -77,7 +77,7 @@ Type_Variable :: struct { child_count : int; //@Note(niels): For constant buffers - buffer_index : u32; + resource_index : u32; uf_parent : Type_Variable_Handle; @@ -198,6 +198,10 @@ Semantic_Checker :: struct { // type_variables : [..]Type_Variable; constraints : [..]Type_Constraint; + current_buffer_index : u32 = 0; + current_sampler_index : u32 = 0; + current_texture_index : u32 = 0; + result : Semantic_Check_Result; } @@ -926,8 +930,6 @@ declare_struct :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variab return declare_struct(checker, node, node.name); } -current_buffer_index : u32 = 0; - declare_properties :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable_Handle { name := ifx node.name.count == 0 then "properties" else node.name; @@ -938,8 +940,8 @@ declare_properties :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Va var := h2tv(checker, type_var); var.type = .Properties; var.typename = "properties"; - var.buffer_index = current_buffer_index; - current_buffer_index += 1; + var.resource_index = checker.current_buffer_index; + checker.current_buffer_index += 1; return type_var; } @@ -947,8 +949,8 @@ declare_cbuffer :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Varia type_var := declare_struct(checker, node); var := h2tv(checker, type_var); var.type = .CBuffer; - var.buffer_index = current_buffer_index; - current_buffer_index += 1; + var.resource_index = checker.current_buffer_index; + checker.current_buffer_index += 1; array_add(*checker.result.constant_buffers, type_var); return type_var; } @@ -1252,6 +1254,17 @@ create_field :: (checker : *Semantic_Checker, node : *AST_Node) -> Type_Variable variable.name = node.name; typename : string; variable.type = get_type_from_identifier(checker, checker.current_scope, node, *typename); + + if variable.kind == .Declaration && variable.type == .Sampler { + variable.resource_index = checker.current_sampler_index; + checker.current_sampler_index += 1; + } + + if variable.kind == .Declaration && variable.type == .Texture2D { + variable.resource_index = checker.current_texture_index; + checker.current_texture_index += 1; + } + variable.typename = typename; variable.source_node = node; variable.scope = checker.current_scope; @@ -1761,7 +1774,9 @@ type_check :: (checker : *Semantic_Checker, root : *AST_Node) { } check :: (checker : *Semantic_Checker, root : *AST_Node) -> Semantic_Check_Result { - current_buffer_index = 0; + checker.current_buffer_index = 0; + checker.current_sampler_index = 0; + checker.current_texture_index = 0; array_reserve(*checker.result.messages, 16); array_reserve(*checker.constraints, 1024); add_hlsl_builtins(checker); @@ -2037,6 +2052,7 @@ print_type_variable :: (builder : *String_Builder, variable : Type_Variable, che } case .Function; #through; case .Struct; #through; + case .CBuffer; #through; case .Field; { if variable.struct_field_parent { print_to_builder(builder, "%.", variable.struct_field_parent.name); diff --git a/module.jai b/module.jai index b655690..27bfbc0 100644 --- a/module.jai +++ b/module.jai @@ -72,6 +72,7 @@ Field :: struct { name : string; type : Field_Type; + resource_index : u32; hints : [..]Field_Hint; } @@ -240,9 +241,13 @@ type_variable_to_field :: (checker : *Semantic_Checker, variable : *Type_Variabl } case .Texture2D; { type.kind = Field_Kind.Texture2D; + + field.resource_index = variable.resource_index; } case .Sampler; { type.kind = Field_Kind.Sampler; + + field.resource_index = variable.resource_index; } case .Struct; { type.kind = Field_Kind.Struct; @@ -374,11 +379,11 @@ compile_file :: (compiler : *Shader_Compiler, path : string) -> Compilation_Resu for i : 0..variable.child_count - 1 { child := variable.children[i]; field : Property_Field; - field.base_field = type_variable_to_field(*checker, h2tv(*checker, child));; + field.base_field = type_variable_to_field(*checker, h2tv(*checker, child));; array_add(*cb.fields, field); } - cb.buffer_index = variable.buffer_index; + cb.buffer_index = variable.resource_index; } find_result := find_symbol(*check_result.scope_stack, check_result.property_name, xx 1); @@ -392,7 +397,7 @@ compile_file :: (compiler : *Shader_Compiler, path : string) -> Compilation_Resu prop_field.base_field = field; array_add(*result.collection.properties.fields, prop_field); } - result.collection.properties.buffer_index = property_variable.buffer_index; + result.collection.properties.buffer_index = property_variable.resource_index; } if checker.result.pixel_entry_point { diff --git a/test/codegen/texture_sample.golden b/test/codegen/texture_sample.golden new file mode 100644 index 0000000..ba7961b --- /dev/null +++ b/test/codegen/texture_sample.golden @@ -0,0 +1,29 @@ +struct PS_Input; + +cbuffer __PROPERTIES : register(b0) +{ +} + +Texture2D texture : register(t0); +Sampler sampler : register(s0); + +struct PS_Input +{ + float2 uv; + float4 pos : POSITION; +} + +PS_Input vs_main(float4 pos : POSITION, float2 uv) +{ + PS_Input result; + result.uv = uv; + result.pos = pos; + return result; +} + +float4 ps_main(PS_Input input) : SV_TARGET +{ + float4 color = texture.sample(input.uv, sampler); + return color; +} + diff --git a/test/semant/constant_buffer.golden b/test/semant/constant_buffer.golden new file mode 100644 index 0000000..1f36c81 --- /dev/null +++ b/test/semant/constant_buffer.golden @@ -0,0 +1,15 @@ +scope (global) [ + [pixel__ps_main] : () -> float4 + [vertex__vs_main] : (pos : float4) -> float4 + [camera] : {projection : float4x4, view : float4x4} + scope (camera) [ + [projection] : float4x4 + [view] : float4x4 + ] + scope (vertex__vs_main) [ + [pos] : float4 + [mv] : float4 + [mvp] : float4 + ] + scope (pixel__ps_main) [] +]