yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
9ec6b9168
master
1//TEST(compute):COMPARE_COMPUTE_EX:-slang -compute -shaderobj -output-using-type 2//TEST(compute):COMPARE_COMPUTE_EX:-vk -slang -compute -shaderobj -output-using-type 3 4//TEST_INPUT:ubuffer(data=[0 0 0], stride=4):out,name=outputBuffer 5RWStructuredBuffer<float> outputBuffer; 6 7struct HitInfo 8{ 9 float val; 10 float getVal() { return val; } 11} 12struct PathInfo 13{ 14 HitInfo hit; 15 [mutating] 16 void setVal(float x) 17 { 18 hit.val = x; 19 } 20} 21 22void someOp(HitInfo hitInfo) 23{ 24 outputBuffer[0] = hitInfo.val; 25} 26 27void func(int x) 28{ 29 PathInfo path = {}; 30 int i = 0; 31 if (x < 10) 32 { 33 // The `elementAddr(path, hit)` is first defined in this block. 34 // Note that this block dominates all remaining blocks in this 35 // function, so all future references to path.hit will use 36 // `elementAddr` inst defined here. 37 // 38 // The bug here is that when we emit code, the emit logic will 39 // find that the elementAddr inst is not in a valid region for 40 // future use and will try to create a local var for it. This will 41 // result a pointer typed var being created, and leads to invalid 42 // hlsl/glsl code. 43 // 44 // The fix is to hoist all always-fold insts to earliest point 45 // in the program instead of creating a var for it. 46 // 47 someOp(path.hit); 48 } 49 else 50 { 51 // This return makes the true block dominate the rest of the blocks 52 // from a region that does not "dominate" the rest code regions. 53 return; 54 } 55 56 while (i < 3) 57 { 58 if (i < 2) 59 { 60 path.setVal(1); 61 } 62 else 63 { 64 path.setVal(2); 65 } 66 67 // This is the point where we are using path.hit again. 68 outputBuffer[i] = path.hit.getVal(); 69 i++; 70 } 71} 72 73[numthreads(1, 1, 1)] 74void computeMain(uint3 dispatchThreadID: SV_DispatchThreadID) 75{ 76 func(4); 77}