From d5d39dda2ec02c1dd21ba34a89f74b27092efcdd Mon Sep 17 00:00:00 2001 From: ArielG-NV <159081215+ArielG-NV@users.noreply.github.com> Date: Tue, 16 Apr 2024 13:06:23 -0400 Subject: Init expressions for struct fields support, #3738 (#3907) * Init expressions for struct members Following commit handles init expressions of struct's. The general implementation follows C++ init expression rules for classes & inherited classes. The logic was implemented after type resolution (`SemanticsDeclAttributesVisitor`): 1. Create a default constructor if missing. 2. Check all member variables (`this` and `super`) for if a member has an init expression, continue to *3* if found. 3. For each constructor, insert a member variable's init expression at the beginning of a constructor. This is to follow how C++ does construction of objects. Some important notes about implementation: * We must handle the scenario that there is inheritance. To handle the inheritance information processing `findLevelsOfInheritance` was created. * If a user manually sets overload rank's of constructor expression's we have no way to assume new default constructor overload ranks. * address feedback - moved all scope bound variables into if statment initializers - added indent - changed logic for overloadRank to be centered around positive numbers rather than negative * Inheritance fixes universally & for struct field init 1. reimplemented struct field logic 2. implemented inheritance through calling a "super->init()" inisde a constructor for each "this". 3. implemented support for multi level inheritance (4+) and accessing members without a crash. * add a way to ignore Forward declared constructors. * a test and fix for a falcor failiure the following case was not handled: creating an default Ctor due to a non L-Value struct field. Having an empty Ctor causes a warning. * remove texture/sampler from test since it will break glsl * get inheritance info using existing lookup logic modified Facet lookups to store relative depth rather than arbitrary ::Self or' ::Direct for inheritance (which was 'wong' since depth 2 is not Direct, but was considered a Direct inheritance) * cleanup unused * cleanup unused functions and whitespace * fix compile warning * clean up, reorder, addressed language server fail changed logic to safeguard bad code --> no longer breaks language server if code is incomplete. remove the "semi-ordering" logic because caused a crash (and this code does nothing functionally, just thought it would be nice to add if '0 cost'). Remove rank setting for constructors, in place use an addition to the overload system: "this" expressions have calling priority over "super" expressions. * undo all inheritance depth checks & code added to the inheritance checking algorithm Reorder default ctor creation and auto-generation of constructor body. * Handle same struct types during overload resolution Changed overload resolution logic to properly handle same struct types; added test to check for multi-param same type function overload. * remove unused ast object Used unused object in an incorrect way. This caused the compiler to not flag a warning. * extension support for default constructors specialization is not supported with default constructors yet. * fix bugs Fix bug in override/overload logic with type comparisons. used wrong type for ctor list construction Specialization has not been added yet * disallow default ctor inside extension * adjust comment, add new tests * add explicit types to invoke, use faster default ctor lookup. * adjust syntax & naming as recomended --- .../overload-different-param-count.slang | 59 +++++++++++++++++++ ...t-field-initializer-extension-inheritance.slang | 59 +++++++++++++++++++ .../struct-field-initializer-extension.slang | 45 +++++++++++++++ .../struct-field-initializer-import-target.slang | 9 +++ .../struct-field-initializer-import.slang | 26 +++++++++ .../struct-field-initializer-inherited-chain.slang | 53 +++++++++++++++++ .../struct-field-initializer-inherited.slang | 66 ++++++++++++++++++++++ ...itializer-init-extension-init-non-default.slang | 32 +++++++++++ ...nitializer-init-inheritance-write-to-same.slang | 32 +++++++++++ .../struct-field-initializer-init-parameter.slang | 28 +++++++++ .../struct-field-initializer-static.slang | 32 +++++++++++ .../struct-field-initializer.slang | 60 ++++++++++++++++++++ ...struct-field-no-initializer-complex-types.slang | 40 +++++++++++++ 13 files changed, 541 insertions(+) create mode 100644 tests/language-feature/higher-order-functions/overload-different-param-count.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-extension.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-import-target.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-import.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-inherited.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-init-extension-init-non-default.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-init-parameter.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-initializer.slang create mode 100644 tests/language-feature/struct-field-initializers/struct-field-no-initializer-complex-types.slang (limited to 'tests') diff --git a/tests/language-feature/higher-order-functions/overload-different-param-count.slang b/tests/language-feature/higher-order-functions/overload-different-param-count.slang new file mode 100644 index 000000000..1af1b6706 --- /dev/null +++ b/tests/language-feature/higher-order-functions/overload-different-param-count.slang @@ -0,0 +1,59 @@ +//TEST:SIMPLE(filecheck=CHECK): -target glsl -entry computeMain -stage compute +// CHECK: main( +struct DiffMaterialData : IDifferentiable +{ + static const uint kMaterialParamCount = 20; + + // Material parameters. + float data[kMaterialParamCount]; + + [Differentiable] + __init() + { + [ForceUnroll] + for (uint i = 0; i < kMaterialParamCount; i++) + data[i] = 0.f; + } + + [Differentiable] + float read(inout uint offset) { return data[offset++]; } + + [Differentiable] + void read(out vector value, inout uint offset) + { + [ForceUnroll] + for (uint i = 0; i < N; i++) + value[i] = read(offset); + } + + [Differentiable] + vector read(inout uint offset) + { + vector value; + this.read(value, offset); + return value; + } + + [mutating] + [Differentiable] + void write(float value, inout uint offset) { data[offset++] = value; } + + [mutating] + [Differentiable] + void write(vector value, inout uint offset) + { + [ForceUnroll] + for (uint i = 0; i < N; i++) + this.write(value[i], offset); + } +}; + +RWStructuredBuffer outputBuffer; + +[numthreads(1,1,1)] +void computeMain() +{ + DiffMaterialData diffData; + uint offset = 0; + outputBuffer[0] = diffData.read<3>(offset); +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang new file mode 100644 index 000000000..4af5f2847 --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-extension-inheritance.slang @@ -0,0 +1,59 @@ +//TEST:SIMPLE(filecheck=CHECK): -target hlsl -stage compute -entry computeMain +RWStructuredBuffer outputBuffer; + +//CHECK: error 30851 + +struct DefaultStructNoInit_base +{ + int data0 = 2; + int data1 = 2; +}; +extension DefaultStructNoInit_base +{ + __init(int indata) + { + //unused + } +} +struct DefaultStructNoInit : DefaultStructNoInit_base +{ + int dataInherit = 2; +}; + +struct DefaultStructWithInit_base +{ + int data0; + int data1 = 3; +}; +extension DefaultStructWithInit_base +{ + __init(int indata) + { + //unused + } + __init() + { + data0 = 3; + } +} +struct DefaultStructWithInit : DefaultStructWithInit_base +{ + int dataInherit = 3; +}; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructNoInit noInit = DefaultStructNoInit(); + DefaultStructWithInit withInit = DefaultStructWithInit(); + // BUF: 1 + outputBuffer[0] = true + && noInit.data0 == 2 + && noInit.data1 == 2 + && noInit.dataInherit == 2 + + && withInit.data0 == 3 + && withInit.data1 == 3 + && withInit.dataInherit == 3 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-extension.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-extension.slang new file mode 100644 index 000000000..1acfeeba7 --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-extension.slang @@ -0,0 +1,45 @@ +//TEST:SIMPLE(filecheck=CHECK): -target hlsl -stage compute -entry computeMain +RWStructuredBuffer outputBuffer; + +//CHECK: error 30851 + +struct DefaultStructNoInit +{ + int data0 = 2; + int data1 = 2; + +}; +extension DefaultStructNoInit +{ +} + +struct DefaultStructWithInit +{ + int data0; + int data1 = 3; + int data2; +}; +extension DefaultStructWithInit +{ + __init() + { + data0 = 3; + data2 = 3; + } +} + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructNoInit noInit = DefaultStructNoInit(); + DefaultStructWithInit withInit = DefaultStructWithInit(); + // BUF: 1 + outputBuffer[0] = true + && noInit.data0 == 2 + && noInit.data1 == 2 + + && withInit.data0 == 3 + && withInit.data1 == 3 + && withInit.data2 == 3 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-import-target.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-import-target.slang new file mode 100644 index 000000000..23d1e3844 --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-import-target.slang @@ -0,0 +1,9 @@ +// tested import struct for struct-field-initializer-import.slang +struct DefaultStructNoInit +{ + int data0 = 2; +}; +struct DefaultStructNoInit2 +{ + int data0; +}; \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-import.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-import.slang new file mode 100644 index 000000000..6c8b6fee1 --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-import.slang @@ -0,0 +1,26 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer +import struct_field_initializer_import_target; +RWStructuredBuffer outputBuffer; + +void modifyOut(out DefaultStructNoInit2 noInit2) +{ + noInit2.data0 = 2; +} + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructNoInit noInit; + DefaultStructNoInit2 noInit2; + modifyOut(noInit2); + // BUF: 1 + outputBuffer[0] = true + && noInit.data0 == 2 + && noInit2.data0 == 2 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang new file mode 100644 index 000000000..ef21a452f --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited-chain.slang @@ -0,0 +1,53 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +static int myTwo = 2; +static int myThree = 1+2; + +struct DefaultStruct_bottom +{ + int data0 = 1; +}; +struct DefaultStruct_middle1 : DefaultStruct_bottom +{ + int data1 = 1; +}; +struct DefaultStruct_middle2 : DefaultStruct_middle1 +{ + int data2 = 1; +}; +struct DefaultStruct_top : DefaultStruct_middle2 +{ + int data3 = 1; +}; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStruct_bottom s1; + DefaultStruct_middle1 s2; + DefaultStruct_middle2 s3; + DefaultStruct_top s4; + + // BUF: 1 + outputBuffer[0] = true + && s1.data0 == 1 + + && s2.data0 == 1 + && s2.data1 == 1 + + && s3.data0 == 1 + && s3.data1 == 1 + && s3.data2 == 1 + + && s4.data0 == 1 + && s4.data1 == 1 + && s4.data2 == 1 + && s4.data3 == 1 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited.slang new file mode 100644 index 000000000..8edb98447 --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-inherited.slang @@ -0,0 +1,66 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +static int myTwo = 2; +static int myThree = 1+2; + +struct DefaultStruct_base +{ + int data0 = 1; + int data1; + + __init() + { + data1 = 1; + } +}; +struct DefaultStruct1 : DefaultStruct_base +{ + int data2 = 1; +}; +struct DefaultStruct2 : DefaultStruct_base +{ + int data2 = 1; + __init() + { + if (data0 != 1) + { + data2 = 0; + } + } +}; +struct DefaultStruct3 : DefaultStruct_base +{ + __init() + { + } +}; +struct DefaultStruct4 : DefaultStruct_base +{ +}; +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStruct1 s1; + DefaultStruct2 s2; + DefaultStruct3 s3; + DefaultStruct4 s4; + // BUF: 1 + outputBuffer[0] = true + && s1.data0 == 1 + && s1.data1 == 1 + && s1.data2 == 1 + && s2.data0 == 1 + && s2.data1 == 1 + && s2.data2 == 1 + && s3.data0 == 1 + && s3.data1 == 1 + && s4.data0 == 1 + && s4.data1 == 1 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-init-extension-init-non-default.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-extension-init-non-default.slang new file mode 100644 index 000000000..2c6cfefac --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-extension-init-non-default.slang @@ -0,0 +1,32 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +struct DefaultStructWithInit +{ + int data0 = 3; + int data1 = 0; +}; +extension DefaultStructWithInit +{ + [mutating] + __init(int inData) + { + data1 = 3; + } +} + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructWithInit withInit = DefaultStructWithInit(5); + // BUF: 1 + outputBuffer[0] = true + && withInit.data0 == 3 + && withInit.data1 == 3 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang new file mode 100644 index 000000000..eff3595f1 --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-inheritance-write-to-same.slang @@ -0,0 +1,32 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +struct DefaultStructWithInit_base +{ + int data0 = 3; + int data1 = 0; +}; + +struct DefaultStructWithInit : DefaultStructWithInit_base +{ + __init() + { + data1 = 3; + } +}; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructWithInit withInit = DefaultStructWithInit(); + // BUF: 1 + outputBuffer[0] = true + && withInit.data0 == 3 + && withInit.data1 == 3 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-init-parameter.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-parameter.slang new file mode 100644 index 000000000..02773c9fa --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-init-parameter.slang @@ -0,0 +1,28 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +struct DefaultStructWithInit +{ + int data0 = 3; + int data1 = 0; + __init(int inData) + { + data1 = 3; + } +}; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructWithInit withInit = DefaultStructWithInit(5); + // BUF: 1 + outputBuffer[0] = true + && withInit.data0 == 3 + && withInit.data1 == 3 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang new file mode 100644 index 000000000..7f0b0577f --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer-static.slang @@ -0,0 +1,32 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +struct DefaultStructNoInit_base +{ + static const int data0 = 2; + static int data1 = 2; + int data2 = 2; +}; + +struct DefaultStructNoInit : DefaultStructNoInit_base +{ + int data3 = 2; +}; + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructNoInit noInit; + // BUF: 1 + outputBuffer[0] = true + && noInit.data0 == 2 + && noInit.data1 == 2 + && noInit.data2 == 2 + && noInit.data3 == 2 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-initializer.slang b/tests/language-feature/struct-field-initializers/struct-field-initializer.slang new file mode 100644 index 000000000..0a03644aa --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-initializer.slang @@ -0,0 +1,60 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +static int myTwo = 2; +static int myThree = 1+2; + +struct DefaultStructNoInit +{ + int data0; + int data1 = myTwo; + int data2 = 2; +}; +struct DefaultStructWithInit +{ + int data0 = 3; + int data1 = myThree; + int data2; + __init() + { + data2 = 3; + } +}; +struct DefaultStructWithInit2 +{ + int data0 = 4; + int data1 = 1; + int data2 = 1; + __init() + { + data1 = 4; + data2 = 4; + } +}; +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultStructNoInit noInit = DefaultStructNoInit(); + noInit.data0 = 2; + DefaultStructWithInit withInit = DefaultStructWithInit(); + DefaultStructWithInit2 withInit2 = DefaultStructWithInit2(); + // BUF: 1 + outputBuffer[0] = true + && noInit.data0 == 2 + && noInit.data1 == 2 + && noInit.data2 == 2 + + && withInit.data0 == 3 + && withInit.data1 == 3 + && withInit.data2 == 3 + + && withInit2.data0 == 4 + && withInit2.data1 == 4 + && withInit2.data2 == 4 + ; +} \ No newline at end of file diff --git a/tests/language-feature/struct-field-initializers/struct-field-no-initializer-complex-types.slang b/tests/language-feature/struct-field-initializers/struct-field-no-initializer-complex-types.slang new file mode 100644 index 000000000..a55c4725d --- /dev/null +++ b/tests/language-feature/struct-field-initializers/struct-field-no-initializer-complex-types.slang @@ -0,0 +1,40 @@ +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-vk -compute -entry computeMain -emit-spirv-directly +//TEST(compute, vulkan):COMPARE_COMPUTE(filecheck-buffer=BUF):-cpu -compute -entry computeMain +//TEST(smoke,compute):COMPARE_COMPUTE(filecheck-buffer=BUF):-dx12 -use-dxil -compute -entry computeMain + +//TEST_INPUT:ubuffer(data=[0 0], stride=4):out,name=outputBuffer +RWStructuredBuffer outputBuffer; + +struct DefaultData +{ + static const int2 val = int2(0, 1); + float2 size; + float scale; + float bias; +}; + +extension DefaultData +{ + int someGet() + { + return val.x; + } +} + +int loadDefaultData(inout DefaultData noInit) +{ + outputBuffer[1] = 1; + return noInit.someGet(); +} + +[numthreads(1, 1, 1)] +void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) +{ + DefaultData noInit; + outputBuffer[0] = true + && loadDefaultData(noInit) == 0; + ; + // BUF: 1 + // BUF-NEXT: 1 +} \ No newline at end of file -- cgit v1.2.3