@@ -59,6 +59,12 @@ pub(super) struct WrappedMatCx2 {
59
59
pub ( super ) columns : crate :: VectorSize ,
60
60
}
61
61
62
+
63
+ #[ derive( Clone , Copy , Debug , Hash , Eq , Ord , PartialEq , PartialOrd ) ]
64
+ pub ( super ) struct WrappedZeroValue {
65
+ pub ( super ) ty : Handle < crate :: Type > ,
66
+ }
67
+
62
68
/// HLSL backend requires its own `ImageQuery` enum.
63
69
///
64
70
/// It is used inside `WrappedImageQuery` and should be unique per ImageQuery function.
@@ -348,7 +354,7 @@ impl<'a, W: Write> super::Writer<'a, W> {
348
354
}
349
355
350
356
/// Helper function that write wrapped function for `Expression::Compose` for structures.
351
- pub ( super ) fn write_wrapped_constructor_function (
357
+ fn write_wrapped_constructor_function (
352
358
& mut self ,
353
359
module : & crate :: Module ,
354
360
constructor : WrappedConstructor ,
@@ -856,13 +862,33 @@ impl<'a, W: Write> super::Writer<'a, W> {
856
862
Ok ( ( ) )
857
863
}
858
864
865
+ // TODO: we could merge this with iteration in write_wrapped_compose_functions...
866
+ //
867
+ /// Helper function that writes zero value wrapped functions
868
+ pub ( super ) fn write_wrapped_zero_value_functions (
869
+ & mut self ,
870
+ module : & crate :: Module ,
871
+ expressions : & crate :: Arena < crate :: Expression > ,
872
+ ) -> BackendResult {
873
+ for ( handle, _) in expressions. iter ( ) {
874
+ if let crate :: Expression :: ZeroValue ( ty) = expressions[ handle] {
875
+ let zero_value = WrappedZeroValue { ty } ;
876
+ if self . wrapped . zero_values . insert ( zero_value) {
877
+ self . write_wrapped_zero_value_function ( module, zero_value) ?;
878
+ }
879
+ }
880
+ }
881
+ Ok ( ( ) )
882
+ }
883
+
859
884
/// Helper function that writes various wrapped functions
860
885
pub ( super ) fn write_wrapped_functions (
861
886
& mut self ,
862
887
module : & crate :: Module ,
863
888
func_ctx : & FunctionCtx ,
864
889
) -> BackendResult {
865
890
self . write_wrapped_compose_functions ( module, func_ctx. expressions ) ?;
891
+ self . write_wrapped_zero_value_functions ( module, func_ctx. expressions ) ?;
866
892
867
893
for ( handle, _) in func_ctx. expressions . iter ( ) {
868
894
match func_ctx. expressions [ handle] {
@@ -1140,4 +1166,71 @@ impl<'a, W: Write> super::Writer<'a, W> {
1140
1166
1141
1167
Ok ( ( ) )
1142
1168
}
1169
+
1170
+ pub ( super ) fn write_wrapped_zero_value_function_name (
1171
+ & mut self ,
1172
+ module : & crate :: Module ,
1173
+ zero_value : WrappedZeroValue ,
1174
+ ) -> BackendResult {
1175
+ let name = crate :: TypeInner :: hlsl_type_id ( zero_value. ty , module. to_ctx ( ) , & self . names ) ?;
1176
+ write ! ( self . out, "ZeroValue{name}" ) ?;
1177
+ Ok ( ( ) )
1178
+ }
1179
+
1180
+ /// Helper function that write wrapped function for `Expression::ZeroValue`
1181
+ ///
1182
+ /// This is necessary since we might have a member access after the zero value expression, e.g.
1183
+ /// `.y` (in practice this can come up when consuming SPIRV that's been produced by glslc).
1184
+ ///
1185
+ /// So we can't just write `(float4)0` since `(float4)0.y` won't parse correctly.
1186
+ ///
1187
+ /// Parenthesizing the expression like `((float4)0).y` would work... except DXC can't handle
1188
+ /// cases like:
1189
+ ///
1190
+ /// ```ignore
1191
+ /// tests\out\hlsl\access.hlsl:183:41: error: cannot compile this l-value expression yet
1192
+ /// t_1.am = (__mat4x2[2])((float4x2[2])0);
1193
+ /// ^
1194
+ /// ```
1195
+ fn write_wrapped_zero_value_function (
1196
+ & mut self ,
1197
+ module : & crate :: Module ,
1198
+ zero_value : WrappedZeroValue ,
1199
+ ) -> BackendResult {
1200
+ use crate :: back:: INDENT ;
1201
+
1202
+ const RETURN_VARIABLE_NAME : & str = "ret" ;
1203
+
1204
+ // Write function return type and name
1205
+ if let crate :: TypeInner :: Array { base, size, .. } = module. types [ zero_value. ty ] . inner {
1206
+ write ! ( self . out, "typedef " ) ?;
1207
+ self . write_type ( module, zero_value. ty ) ?;
1208
+ write ! ( self . out, " ret_" ) ?;
1209
+ self . write_wrapped_zero_value_function_name ( module, zero_value) ?;
1210
+ self . write_array_size ( module, base, size) ?;
1211
+ writeln ! ( self . out, ";" ) ?;
1212
+
1213
+ write ! ( self . out, "ret_" ) ?;
1214
+ self . write_wrapped_zero_value_function_name ( module, zero_value) ?;
1215
+ } else {
1216
+ self . write_type ( module, zero_value. ty ) ?;
1217
+ }
1218
+ write ! ( self . out, " " ) ?;
1219
+ self . write_wrapped_zero_value_function_name ( module, zero_value) ?;
1220
+
1221
+ // Write function parameters (none) and start function body
1222
+ writeln ! ( self . out, "() {{" ) ?;
1223
+
1224
+ // Write `ZeroValue` function.
1225
+ write ! ( self . out, "{INDENT}return " ) ?;
1226
+ self . write_default_init ( module, zero_value. ty ) ?;
1227
+ writeln ! ( self . out, ";" ) ?;
1228
+
1229
+ // End of function body
1230
+ writeln ! ( self . out, "}}" ) ?;
1231
+ // Write extra new line
1232
+ writeln ! ( self . out) ?;
1233
+
1234
+ Ok ( ( ) )
1235
+ }
1143
1236
}
0 commit comments