diff options
| -rw-r--r-- | source/slang/lower-to-ir.cpp | 82 | ||||
| -rw-r--r-- | tests/compute/initializer-list.slang | 30 | ||||
| -rw-r--r-- | tests/compute/initializer-list.slang.expected.txt | 4 |
3 files changed, 114 insertions, 2 deletions
diff --git a/source/slang/lower-to-ir.cpp b/source/slang/lower-to-ir.cpp index b395d2a95..9e58d908b 100644 --- a/source/slang/lower-to-ir.cpp +++ b/source/slang/lower-to-ir.cpp @@ -1107,9 +1107,87 @@ struct ExprLoweringVisitorBase : ExprVisitor<Derived, LoweredValInfo> return lowerSubExpr(expr->base); } - LoweredValInfo visitInitializerListExpr(InitializerListExpr* /*expr*/) + LoweredValInfo visitInitializerListExpr(InitializerListExpr* expr) { - SLANG_UNIMPLEMENTED_X("codegen for initializer list expression"); + // Allocate a temporary of the given type + RefPtr<Type> type = lowerSimpleType(context, expr->type); + LoweredValInfo val = createVar(context, type); + + UInt argCount = expr->args.Count(); + + // Now for each argument in the initializer list, + // fill in the appropriate field of the result + if (auto arrayType = type->As<ArrayExpressionType>()) + { + UInt elementCount = (UInt) GetIntVal(arrayType->ArrayLength); + auto elementType = lowerType(context, arrayType->baseType); + for (UInt ee = 0; ee < elementCount; ++ee) + { + IRValue* indexVal = context->irBuilder->getIntValue( + getIntType(context), + ee); + LoweredValInfo elemVal = subscriptValue( + elementType, + val, + indexVal); + + if (ee < argCount) + { + auto argExpr = expr->args[ee]; + LoweredValInfo argVal = lowerRValueExpr(context, argExpr); + + assign(context, elemVal, argVal); + } + else + { + SLANG_UNEXPECTED("need to default-initialize array elements"); + } + } + } + else if (auto declRefType = type->As<DeclRefType>()) + { + DeclRef<Decl> declRef = declRefType->declRef; + if (auto aggTypeDeclRef = declRef.As<AggTypeDecl>()) + { + UInt argCounter = 0; + for (auto ff : getMembersOfType<StructField>(aggTypeDeclRef)) + { + if (ff.getDecl()->HasModifier<HLSLStaticModifier>()) + continue; + + auto loweredFieldType = lowerType( + context, + GetType(ff)); + LoweredValInfo fieldVal = extractField( + loweredFieldType, + val, + ff); + + UInt argIndex = argCounter++; + if (argIndex < argCount) + { + auto argExpr = expr->args[argIndex]; + LoweredValInfo argVal = lowerRValueExpr(context, argExpr); + assign(context, fieldVal, argVal); + } + else + { + SLANG_UNEXPECTED("need to default-initialize struct fields"); + } + } + } + else + { + SLANG_UNEXPECTED("not sure how to initialize this type"); + } + } + else + { + SLANG_UNEXPECTED("not sure how to initialize this type"); + } + + + return val; } LoweredValInfo visitConstantExpr(ConstantExpr* expr) diff --git a/tests/compute/initializer-list.slang b/tests/compute/initializer-list.slang new file mode 100644 index 000000000..24ff4b037 --- /dev/null +++ b/tests/compute/initializer-list.slang @@ -0,0 +1,30 @@ +//TEST(compute):COMPARE_COMPUTE:-xslang -use-ir + +//TEST_INPUT: ubuffer(data=[0 0 0 0], stride=4):dxbinding(0),glbinding(0),out + +struct Test +{ + float4 a; + uint b; + float c; +}; + + +uint test(uint val) +{ + Test t = { float4(1.0f), 16, 99.0f }; + return val + t.b; +} + +RWStructuredBuffer<uint> outputBuffer; + +[numthreads(4, 1, 1)] +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +{ + uint tid = dispatchThreadID.x; + + uint inVal = tid; + uint outVal = test(inVal); + + outputBuffer[tid] = outVal; +}
\ No newline at end of file diff --git a/tests/compute/initializer-list.slang.expected.txt b/tests/compute/initializer-list.slang.expected.txt new file mode 100644 index 000000000..a0d427709 --- /dev/null +++ b/tests/compute/initializer-list.slang.expected.txt @@ -0,0 +1,4 @@ +10 +11 +12 +13 |
