From 9a3a4b08c8817905c2f608549c0e57216f8068c5 Mon Sep 17 00:00:00 2001 From: jsmall-nvidia Date: Thu, 3 Nov 2022 14:31:51 -0400 Subject: Shader Execution Reordering without HLSL2021 (#2489) * #include an absolute path didn't work - because paths were taken to always be relative. * Disable SER tests and enabling HLSL2021 by default. * Small typos fix. Improve SER coverage in testing. * Fix typo. --- source/slang/hlsl.meta.slang | 116 ++++- source/slang/slang-emit-hlsl.cpp | 5 + .../hit-object-make-hit.slang | 18 +- .../hit-object-make-hit.slang.expected | 380 +++++++++------- .../hit-object-make-nop.slang | 21 + .../hit-object-make-nop.slang.expected | 131 ++++++ .../hit-object-reorder-thread.slang | 29 +- .../hit-object-reorder-thread.slang.expected | 479 +++++++++++++++------ .../hit-object-trace-ray.slang | 2 +- .../hit-object-trace-ray.slang.expected | 28 +- 10 files changed, 891 insertions(+), 318 deletions(-) create mode 100644 tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang create mode 100644 tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-nop.slang.expected diff --git a/source/slang/hlsl.meta.slang b/source/slang/hlsl.meta.slang index 238739fcd..ec2e6de95 100644 --- a/source/slang/hlsl.meta.slang +++ b/source/slang/hlsl.meta.slang @@ -5421,6 +5421,7 @@ struct VkSubpassInputMS T SubpassLoad(int sampleIndex); } + /// /// Shader Execution Reordering (SER) /// @@ -5445,8 +5446,7 @@ struct HitObject { /// Executes ray traversal (including anyhit and intersection shaders) like TraceRay, but returns the /// resulting hit information as a HitObject and does not trigger closesthit or miss shaders. - __target_intrinsic(hlsl, "NvTraceRayHitObject") - [__requiresNVAPI] + __specialized_for_target(hlsl) static HitObject TraceRay( RaytracingAccelerationStructure AccelerationStructure, uint RayFlags, @@ -5455,7 +5455,21 @@ struct HitObject uint MultiplierForGeometryContributionToHitGroupIndex, uint MissShaderIndex, RayDesc Ray, - inout payload_t Payload); + inout payload_t Payload) + { + HitObject hitObj; + __traceRay( + AccelerationStructure, + RayFlags, + InstanceInclusionMask, + RayContributionToHitGroupIndex, + MultiplierForGeometryContributionToHitGroupIndex, + MissShaderIndex, + Ray, + Payload, + hitObj); + return hitObj; + } /// Creates a HitObject representing a hit based on values explicitly passed as arguments, without /// tracing a ray. The primitive specified by AccelerationStructure, InstanceIndex, GeometryIndex, @@ -5463,8 +5477,7 @@ struct HitObject /// TraceRay. The computed index must reference a valid hit group record in the shader table. The /// Attributes parameter must either be an attribute struct, such as /// BuiltInTriangleIntersectionAttributes, or another HitObject to copy the attributes from. - __target_intrinsic(hlsl, "NvMakeHit") - [__requiresNVAPI] + __specialized_for_target(hlsl) static HitObject MakeHit( RaytracingAccelerationStructure AccelerationStructure, uint InstanceIndex, @@ -5474,7 +5487,22 @@ struct HitObject uint RayContributionToHitGroupIndex, uint MultiplierForGeometryContributionToHitGroupIndex, RayDesc Ray, - attr_t attributes); + attr_t attributes) + { + HitObject hitObj; + __makeHit( + AccelerationStructure, + InstanceIndex, + GeometryIndex, + PrimitiveIndex, + HitKind, + RayContributionToHitGroupIndex, + MultiplierForGeometryContributionToHitGroupIndex, + Ray, + attributes, + hitObj); + return hitObj; + } /// Creates a HitObject representing a hit based on values explicitly passed as arguments, without /// tracing a ray. The primitive specified by AccelerationStructure, InstanceIndex, GeometryIndex, @@ -5483,8 +5511,7 @@ struct HitObject /// reference a valid hit group record in the shader table. The Attributes parameter must either be an /// attribute struct, such as BuiltInTriangleIntersectionAttributes, or another HitObject to copy the /// attributes from. - __target_intrinsic(hlsl, "NvMakeHitWithRecordIndex") - [__requiresNVAPI] + __specialized_for_target(hlsl) static HitObject MakeHit( uint HitGroupRecordIndex, RaytracingAccelerationStructure AccelerationStructure, @@ -5493,7 +5520,21 @@ struct HitObject uint PrimitiveIndex, uint HitKind, RayDesc Ray, - attr_t attributes); + attr_t attributes) + { + HitObject hitObj; + __makeHitWithRecordIndex( + HitGroupRecordIndex, + AccelerationStructure, + InstanceIndex, + GeometryIndex, + PrimitiveIndex, + HitKind, + Ray, + attributes, + hitObj); + return hitObj; + } /// Creates a HitObject representing a miss based on values explicitly passed as arguments, without /// tracing a ray. The provided shader table index must reference a valid miss record in the shader @@ -5573,17 +5614,66 @@ struct HitObject uint GetHitKind(); /// Returns the attributes of a hit. Valid if the hit object represents a hit or a miss. - __target_intrinsic(hlsl, "$0.GetAttributes<$G0>()") - [__requiresNVAPI] - attr_t GetAttributes(); + __specialized_for_target(hlsl) + attr_t GetAttributes() + { + attr_t v; + __getAttributesFromHitObject(v); + return v; + } /// Loads a root constant from the local root table referenced by the hit object. Valid if the hit object /// represents a hit or a miss. RootConstantOffsetInBytes must be a multiple of 4. __target_intrinsic(hlsl) [__requiresNVAPI] uint LoadLocalRootTableConstant(uint RootConstantOffsetInBytes); -}; + /// + /// !!!! Internal impl. Do not use! + /// + + __target_intrinsic(hlsl, "NvGetAttributesFromHitObject($0, $1)") + [__requiresNVAPI] + void __getAttributesFromHitObject(out T t); + + __target_intrinsic(hlsl, "NvMakeHitWithRecordIndex") + [__requiresNVAPI] + static void __makeHitWithRecordIndex(uint HitGroupRecordIndex, + RaytracingAccelerationStructure AccelerationStructure, + uint InstanceIndex, + uint GeometryIndex, + uint PrimitiveIndex, + uint HitKind, + RayDesc Ray, + attr_t attributes, + out HitObject hitObj); + + __target_intrinsic(hlsl, "NvMakeHit") + [__requiresNVAPI] + static void __makeHit(RaytracingAccelerationStructure AccelerationStructure, + uint InstanceIndex, + uint GeometryIndex, + uint PrimitiveIndex, + uint HitKind, + uint RayContributionToHitGroupIndex, + uint MultiplierForGeometryContributionToHitGroupIndex, + RayDesc Ray, + attr_t attributes, + out HitObject hitObj); + + __target_intrinsic(hlsl, "NvTraceRayHitObject") + [__requiresNVAPI] + static void __traceRay( + RaytracingAccelerationStructure AccelerationStructure, + uint RayFlags, + uint InstanceInclusionMask, + uint RayContributionToHitGroupIndex, + uint MultiplierForGeometryContributionToHitGroupIndex, + uint MissShaderIndex, + RayDesc Ray, + inout payload_t Payload, + out HitObject hitObj); +}; /// Reorders threads based on a coherence hint value. NumCoherenceHintBits indicates how many of /// the least significant bits of CoherenceHint should be considered during reordering (max: 16). diff --git a/source/slang/slang-emit-hlsl.cpp b/source/slang/slang-emit-hlsl.cpp index 93b501ae0..187115232 100644 --- a/source/slang/slang-emit-hlsl.cpp +++ b/source/slang/slang-emit-hlsl.cpp @@ -1153,6 +1153,11 @@ void HLSLSourceEmitter::emitFrontMatterImpl(TargetRequest* targetReq) // m_writer->emit("#define SLANG_HLSL_ENABLE_NVAPI 1\n"); + // TODO(JS): For now when using NVAPI for generated code we do not want to + // use HLSL2021 features, that are typically used for Shader Execution Reordering + // so we turn on the 'macro' based interface by default + m_writer->emit(toSlice("#define NV_HITOBJECT_USE_MACRO_API 1\n")); + // In addition, if the user has informed the Slang compiler of // the register/space that it wants to use for NVAPI, then we // need to pass along that information to prelude in the diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang index 242faa7c4..9ba631c9f 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang @@ -21,21 +21,33 @@ uint calcValue(HitObject hit) { uint r = 0; - if (!hit.IsMiss()) + if (hit.IsHit()) { uint instanceIndex = hit.GetInstanceIndex(); uint instanceID = hit.GetInstanceID(); uint geometryIndex = hit.GetGeometryIndex(); uint primitiveIndex = hit.GetPrimitiveIndex(); - - SomeValues objSomeValues = hit.GetAttributes(); + uint hitKind = hit.GetHitKind(); + r += hitKind; r += instanceIndex; r += instanceID; r += geometryIndex; r += primitiveIndex; + + RayDesc ray = hit.GetRayDesc(); + + r += uint(ray.TMin > 0); + r += uint(ray.TMax < ray.TMin); + + SomeValues objSomeValues = hit.GetAttributes(); + r += objSomeValues.a; } + else if (hit.IsMiss()) + { + r += 1; + } return r; } diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.expected index f481d22f3..323762360 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.expected @@ -6,7 +6,7 @@ standard output = { ; Note: shader requires additional functionality: ; UAVs at every shader stage ; -; shader hash: 98c6f18c569b635938f62584ccf64bbf +; shader hash: 74e3ebb1057bef29c64dd2b1aede2893 ; ; Buffer Definitions: ; @@ -59,10 +59,7 @@ target triple = "dxil-ms-dx" %struct.RaytracingAccelerationStructure = type { i32 } %"class.RWStructuredBuffer" = type { i32 } %struct.SomeValues_0 = type { i32, float } -%struct.AttrWrapper.0 = type { %struct.SomeValues_0 } -%struct.DummyPayload.1 = type { i32 } -%struct.AttrWrapper = type { %struct.SomeValues_0 } -%struct.DummyPayload = type { i32 } +%struct.NvHitObjectMacroDummyPayloadType = type { i32 } %dx.types.Handle = type { i8* } @"\01?g_NvidiaExt@@3V?$RWStructuredBuffer@UNvShaderExtnStruct@@@@A" = external constant %"class.RWStructuredBuffer", align 4 @@ -75,54 +72,54 @@ define void @"\01?rayGenerationMain@@YAXXZ"() #0 { %2 = load %"class.RWStructuredBuffer", %"class.RWStructuredBuffer"* @"\01?outputBuffer_0@@3V?$RWStructuredBuffer@I@@A", align 4 %3 = load %"class.RWStructuredBuffer", %"class.RWStructuredBuffer"* @"\01?g_NvidiaExt@@3V?$RWStructuredBuffer@UNvShaderExtnStruct@@@@A", align 4, !noalias !21 %4 = alloca %struct.SomeValues_0, align 8 - %5 = alloca %struct.AttrWrapper.0, align 4 - %6 = alloca %struct.DummyPayload.1, align 4 + %5 = alloca %struct.SomeValues_0, align 8 + %6 = alloca %struct.NvHitObjectMacroDummyPayloadType, align 4 %7 = alloca %struct.SomeValues_0, align 8 - %8 = alloca %struct.AttrWrapper, align 4 - %9 = alloca %struct.DummyPayload, align 4 + %8 = alloca %struct.SomeValues_0, align 8 + %9 = alloca %struct.NvHitObjectMacroDummyPayloadType, align 4 %10 = call i32 @dx.op.dispatchRaysIndex.i32(i32 145, i8 0) ; DispatchRaysIndex(col) %11 = sitofp i32 %10 to float %12 = fmul fast float %11, 2.000000e+00 %13 = sitofp i32 %10 to float %14 = mul nsw i32 %10, 3 %15 = shl nsw i32 %10, 1 - %16 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %17 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %16, i8 1) ; BufferUpdateCounter(uav,inc) + %16 = getelementptr inbounds %struct.SomeValues_0, %struct.SomeValues_0* %8, i32 0, i32 0 + store i32 %10, i32* %16, align 8 + %17 = getelementptr inbounds %struct.SomeValues_0, %struct.SomeValues_0* %8, i32 0, i32 1 + store float %12, float* %17, align 4 %18 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %18, i32 %17, i32 0, i32 69, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) - %19 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %19, i32 %17, i32 144, i32 2, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + %19 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %18, i8 1) ; BufferUpdateCounter(uav,inc) %20 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %20, i32 %17, i32 76, i32 %10, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %20, i32 %19, i32 0, i32 69, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %21 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %21, i32 %17, i32 80, i32 %15, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %21, i32 %19, i32 144, i32 2, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %22 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %22, i32 %17, i32 84, i32 %14, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %22, i32 %19, i32 76, i32 %10, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %23 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %23, i32 %17, i32 88, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %23, i32 %19, i32 80, i32 %15, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %24 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %24, i32 %17, i32 92, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %24, i32 %19, i32 84, i32 %14, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %25 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - %26 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %25, i8 1) ; BufferUpdateCounter(uav,inc) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %25, i32 %19, i32 88, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + %26 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %26, i32 %19, i32 92, i32 0, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %27 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) %28 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %27, i8 1) ; BufferUpdateCounter(uav,inc) - %29 = getelementptr inbounds %struct.AttrWrapper, %struct.AttrWrapper* %8, i32 0, i32 0, i32 0 - store i32 %10, i32* %29, align 4 - %30 = getelementptr inbounds %struct.AttrWrapper, %struct.AttrWrapper* %8, i32 0, i32 0, i32 1 - store float %12, float* %30, align 4 - call void @dx.op.callShader.struct.AttrWrapper(i32 159, i32 %28, %struct.AttrWrapper* nonnull %8) ; CallShader(ShaderIndex,Parameter) + %29 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) + %30 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %29, i8 1) ; BufferUpdateCounter(uav,inc) + call void @dx.op.callShader.struct.SomeValues_0(i32 159, i32 %30, %struct.SomeValues_0* nonnull %8) ; CallShader(ShaderIndex,Parameter) %31 = call %dx.types.Handle @dx.op.createHandleForLib.struct.RaytracingAccelerationStructure(i32 160, %struct.RaytracingAccelerationStructure %1) ; CreateHandleForLib(Resource) - call void @dx.op.traceRay.struct.DummyPayload(i32 157, %dx.types.Handle %31, i32 0, i32 0, i32 0, i32 0, i32 %28, float %13, float 0.000000e+00, float 0.000000e+00, float 0x3F847AE140000000, float 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+04, %struct.DummyPayload* nonnull %9) ; TraceRay(AccelerationStructure,RayFlags,InstanceInclusionMask,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToShaderIndex,MissShaderIndex,Origin_X,Origin_Y,Origin_Z,TMin,Direction_X,Direction_Y,Direction_Z,TMax,payload) + call void @dx.op.traceRay.struct.NvHitObjectMacroDummyPayloadType(i32 157, %dx.types.Handle %31, i32 0, i32 0, i32 0, i32 0, i32 %30, float %13, float 0.000000e+00, float 0.000000e+00, float 0x3F847AE140000000, float 0.000000e+00, float 1.000000e+00, float 0.000000e+00, float 1.000000e+04, %struct.NvHitObjectMacroDummyPayloadType* nonnull %9) ; TraceRay(AccelerationStructure,RayFlags,InstanceInclusionMask,RayContributionToHitGroupIndex,MultiplierForGeometryContributionToShaderIndex,MissShaderIndex,Origin_X,Origin_Y,Origin_Z,TMin,Direction_X,Direction_Y,Direction_Z,TMax,payload) %32 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) %33 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %32, i8 1) ; BufferUpdateCounter(uav,inc) %34 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %34, i32 %33, i32 0, i32 73, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %34, i32 %33, i32 0, i32 83, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %35 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) - call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %35, i32 %33, i32 76, i32 %26, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) + call void @dx.op.rawBufferStore.i32(i32 140, %dx.types.Handle %35, i32 %33, i32 76, i32 %28, i32 undef, i32 undef, i32 undef, i8 1, i32 4) ; RawBufferStore(uav,index,elementOffset,value0,value1,value2,value3,mask,alignment) %36 = call %dx.types.Handle @"dx.op.createHandleForLib.class.RWStructuredBuffer"(i32 160, %"class.RWStructuredBuffer" %3) ; CreateHandleForLib(Resource) %37 = call i32 @dx.op.bufferUpdateCounter(i32 70, %dx.types.Handle %36, i8 1) ; BufferUpdateCounter(uav,inc) %38 = icmp eq i32 %37, 0 - br i1 %38, label %39, label %76 + br i1 %38, label %111, label %39 ;