@@ -50,12 +50,13 @@ class codegen_glsl final : public codegen
5050 void write_result (module &s) const override
5151 {
5252 s.hlsl +=
53- " vec2 hlsl_fmod(vec2 x, vec2 y) { return x - y * trunc(x / y); }"
54- " vec3 hlsl_fmod(vec3 x, vec3 y) { return x - y * trunc(x / y); }"
55- " vec4 hlsl_fmod(vec4 x, vec4 y) { return x - y * trunc(x / y); }"
56- " mat2 hlsl_fmod(mat2 x, mat2 y) { return x - matrixCompMult(y, mat2(trunc(x[0] / y[0]), trunc(x[1] / y[1]))); }"
57- " mat3 hlsl_fmod(mat3 x, mat3 y) { return x - matrixCompMult(y, mat3(trunc(x[0] / y[0]), trunc(x[1] / y[1]), trunc(x[2] / y[2]))); }"
58- " mat4 hlsl_fmod(mat4 x, mat4 y) { return x - matrixCompMult(y, mat4(trunc(x[0] / y[0]), trunc(x[1] / y[1]), trunc(x[2] / y[2]), trunc(x[3] / y[3]))); }\n " ;
53+ " float hlsl_fmod(float x, float y) { return x - y * trunc(x / y); }\n "
54+ " vec2 hlsl_fmod( vec2 x, vec2 y) { return x - y * trunc(x / y); }\n "
55+ " vec3 hlsl_fmod( vec3 x, vec3 y) { return x - y * trunc(x / y); }\n "
56+ " vec4 hlsl_fmod( vec4 x, vec4 y) { return x - y * trunc(x / y); }\n "
57+ " mat2 hlsl_fmod( mat2 x, mat2 y) { return x - matrixCompMult(y, mat2(trunc(x[0] / y[0]), trunc(x[1] / y[1]))); }\n "
58+ " mat3 hlsl_fmod( mat3 x, mat3 y) { return x - matrixCompMult(y, mat3(trunc(x[0] / y[0]), trunc(x[1] / y[1]), trunc(x[2] / y[2]))); }\n "
59+ " mat4 hlsl_fmod( mat4 x, mat4 y) { return x - matrixCompMult(y, mat4(trunc(x[0] / y[0]), trunc(x[1] / y[1]), trunc(x[2] / y[2]), trunc(x[3] / y[3]))); }\n " ;
5960
6061 if (_blocks.count (_cbuffer_type_id))
6162 s.hlsl += " layout(std140, binding = 0) uniform _Globals {\n " + _blocks.at (_cbuffer_type_id) + " };\n " ;
@@ -151,15 +152,21 @@ class codegen_glsl final : public codegen
151152
152153 if (type.is_array ())
153154 {
154- s += " { " ;
155-
156155 struct type elem_type = type;
157156 elem_type.array_length = 0 ;
158157
159- for (size_t i = 0 ; i < data.array_data .size (); ++i)
160- s += write_constant (elem_type, data.array_data [i]) + " , " ;
158+ s += write_type (elem_type) + " [](" ;
159+
160+ for (int i = 0 ; i < type.array_length ; ++i)
161+ {
162+ s += write_constant (elem_type, i < static_cast <int >(data.array_data .size ()) ? data.array_data [i] : constant ());
163+
164+ if (i < type.array_length - 1 )
165+ s += " , " ;
166+ }
167+
168+ s += ' )' ;
161169
162- s += " }" ;
163170 return s;
164171 }
165172
@@ -173,29 +180,26 @@ class codegen_glsl final : public codegen
173180
174181 s += ' (' ;
175182
176- if ( type.is_numeric () )
183+ for ( unsigned int i = 0 , components = type.components (); i < components; ++i )
177184 {
178- for ( unsigned int i = 0 , components = type.components (); i < components; ++i )
185+ switch ( type.base )
179186 {
180- switch (type.base )
181- {
182- case type::t_bool:
183- s += data.as_uint [i] ? " true" : " false" ;
184- break ;
185- case type::t_int:
186- s += std::to_string (data.as_int [i]);
187- break ;
188- case type::t_uint:
189- s += std::to_string (data.as_uint [i]);
190- break ;
191- case type::t_float:
192- s += std::to_string (data.as_float [i]);
193- break ;
194- }
195-
196- if (i < components - 1 )
197- s += " , " ;
187+ case type::t_bool:
188+ s += data.as_uint [i] ? " true" : " false" ;
189+ break ;
190+ case type::t_int:
191+ s += std::to_string (data.as_int [i]);
192+ break ;
193+ case type::t_uint:
194+ s += std::to_string (data.as_uint [i]);
195+ break ;
196+ case type::t_float:
197+ s += std::to_string (data.as_float [i]);
198+ break ;
198199 }
200+
201+ if (i < components - 1 )
202+ s += " , " ;
199203 }
200204
201205 if (!type.is_scalar ())
@@ -364,6 +368,9 @@ class codegen_glsl final : public codegen
364368
365369 code () += ' \n ' + write_location (param.location ) + ' \t ' + write_type (param.type , true ) + ' ' + param.name ;
366370
371+ if (param.type .is_array ())
372+ code () += ' [' + std::to_string (param.type .array_length ) + ' ]' ;
373+
367374 if (i < num_params - 1 )
368375 code () += ' ,' ;
369376 }
@@ -457,12 +464,16 @@ class codegen_glsl final : public codegen
457464 {
458465 for (int i = 0 , array_length = std::max (1 , param.type .array_length ); i < array_length; i++)
459466 {
467+ // Build struct from separate member input variables
460468 if (param.type .is_struct ())
461469 {
462- code () += write_type (param.type ) + " _param_" + param.name + std::to_string (i) + " = " + write_type (param.type ) + ' (' ;
470+ code () += write_type (param.type ) + " _param_" + param.name ;
471+ if (param.type .is_array ())
472+ code () += std::to_string (i);
473+ code () += " = " + write_type (param.type ) + ' (' ;
463474
464475 for (const auto &member : find_struct (param.type .definition ).member_list )
465- code () += escape_name_with_builtins (" _param_" + param.name + ' _' + member.name + std::to_string (i), member.semantic ) + " , " ;
476+ code () += escape_name_with_builtins (" _param_" + param.name + ' _' + member.name + (param. type . is_array () ? std::to_string (i) : std::string () ), member.semantic ) + " , " ;
466477
467478 code ().pop_back ();
468479 code ().pop_back ();
@@ -489,7 +500,7 @@ class codegen_glsl final : public codegen
489500 code () += write_scope ();
490501 // Structs cannot be output variables, so have to write to a temporary first and then output each member separately
491502 if (func.return_type .is_struct ())
492- code () += write_type (func.return_type ) + " ret = " ;
503+ code () += write_type (func.return_type ) + " _return = " ;
493504 // All other output types can write to the output variable directly
494505 else if (!func.return_type .is_void ())
495506 code () += " _return = " ;
@@ -546,6 +557,8 @@ class codegen_glsl final : public codegen
546557 // Can refer to l-values without access chain directly
547558 if (chain.is_lvalue && chain.ops .empty ())
548559 return chain.base ;
560+ else if (chain.is_constant )
561+ return emit_constant (chain.type , chain.constant );
549562
550563 const id res = make_id ();
551564
@@ -556,39 +569,32 @@ class codegen_glsl final : public codegen
556569
557570 code () += " = " ;
558571
559- if (chain.is_constant )
560- {
561- code () += write_constant (chain.type , chain.constant );
562- }
563- else
564- {
565- std::string newcode = id_to_name (chain.base );
572+ std::string newcode = id_to_name (chain.base );
566573
567- for (const auto &op : chain.ops )
574+ for (const auto &op : chain.ops )
575+ {
576+ switch (op.type )
568577 {
569- switch (op.type )
570- {
571- case expression::operation::op_cast:
572- newcode = write_type (op.to ) + ' (' + newcode + ' )' ;
573- break ;
574- case expression::operation::op_index:
575- newcode += ' [' + id_to_name (op.index ) + ' ]' ;
576- break ;
577- case expression::operation::op_member:
578- newcode += op.from .definition == _cbuffer_type_id ? ' _' : ' .' ;
579- newcode += find_struct (op.from .definition ).member_list [op.index ].name ;
580- break ;
581- case expression::operation::op_swizzle:
582- newcode += ' .' ;
583- for (unsigned int i = 0 ; i < 4 && op.swizzle [i] >= 0 ; ++i)
584- newcode += " xyzw" [op.swizzle [i]];
585- break ;
586- }
578+ case expression::operation::op_cast:
579+ newcode = write_type (op.to ) + ' (' + newcode + ' )' ;
580+ break ;
581+ case expression::operation::op_index:
582+ newcode += ' [' + id_to_name (op.index ) + ' ]' ;
583+ break ;
584+ case expression::operation::op_member:
585+ newcode += op.from .definition == _cbuffer_type_id ? ' _' : ' .' ;
586+ newcode += find_struct (op.from .definition ).member_list [op.index ].name ;
587+ break ;
588+ case expression::operation::op_swizzle:
589+ newcode += ' .' ;
590+ for (unsigned int i = 0 ; i < 4 && op.swizzle [i] >= 0 ; ++i)
591+ newcode += " xyzw" [op.swizzle [i]];
592+ break ;
587593 }
588-
589- code () += newcode;
590594 }
591595
596+ code () += newcode;
597+
592598 code () += " ;\n " ;
593599
594600 return res;
@@ -630,6 +636,13 @@ class codegen_glsl final : public codegen
630636 {
631637 const id res = make_id ();
632638
639+ // Struct initialization is not supported right now
640+ if (type.is_struct ())
641+ {
642+ code () += write_scope () + ' ' + write_type (type) + ' ' + id_to_name (res) + " ;\n " ;
643+ return res;
644+ }
645+
633646 code () += write_scope () + " const " + write_type (type) + ' ' + id_to_name (res);
634647
635648 if (type.is_array ())
@@ -1044,6 +1057,10 @@ class codegen_glsl final : public codegen
10441057 if (!is_in_block ())
10451058 return 0 ;
10461059
1060+ // Skip implicit return statement
1061+ if (!_functions.back ()->return_type .is_void () && value == 0 )
1062+ return set_block (0 );
1063+
10471064 code () += write_scope () + " return" ;
10481065
10491066 if (value != 0 )
0 commit comments