diff options
25 files changed, 514 insertions, 400 deletions
diff --git a/.github/workflows/windows-selfhosted.yml b/.github/workflows/windows-selfhosted.yml index 08f079537..bc059ad0a 100644 --- a/.github/workflows/windows-selfhosted.yml +++ b/.github/workflows/windows-selfhosted.yml @@ -41,11 +41,11 @@ jobs: run: | $ErrorActionPreference = "SilentlyContinue" $env:Path += ';.\external\slang-binaries\spirv-tools\windows-${{matrix.testPlatform}}\bin\' - .\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\slang-test.exe tests/ -use-test-server -emit-spirv-directly -expected-failure-list tests/expected-failure.txt -api vk + .\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\slang-test.exe tests/ -use-test-server -server-count 8 -emit-spirv-directly -expected-failure-list tests/expected-failure.txt -api vk - name: test run: | $ErrorActionPreference = "SilentlyContinue" $env:Path += ';.\external\slang-binaries\spirv-tools\windows-${{matrix.testPlatform}}\bin\' - .\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\slang-test.exe -use-test-server -api all-cpu + .\bin\windows-${{matrix.testPlatform}}\${{matrix.configuration}}\slang-test.exe -use-test-server -server-count 8 -api all-cpu diff --git a/deps/target-deps.json b/deps/target-deps.json index 1266d4a81..6c0880c78 100644 --- a/deps/target-deps.json +++ b/deps/target-deps.json @@ -4,14 +4,14 @@ "dependencies" : [ { "name" : "slang-llvm", - "baseUrl" : "https://github.com/shader-slang/slang-llvm/releases/download/v13.x-39/", + "baseUrl" : "https://github.com/shader-slang/slang-llvm/releases/download/v13.x-41/", "optional" : true, "packages" : { - "windows-x86_64" : { "type" : "url", "path" : "slang-llvm-13.x-39-win64.zip" }, - "windows-x86" : { "type": "url", "path" : "slang-llvm-13.x-39-win32.zip" }, - "linux-x86_64" : { "type": "url", "path" : "slang-llvm-v13.x-39-linux-x86_64-release.zip" }, - "macosx-x86_64" : { "type": "url", "path" : "slang-llvm-v13.x-39-macosx-x86_64-release.zip" } + "windows-x86_64" : { "type" : "url", "path" : "slang-llvm-13.x-41-win64.zip" }, + "windows-x86" : { "type": "url", "path" : "slang-llvm-13.x-41-win32.zip" }, + "linux-x86_64" : { "type": "url", "path" : "slang-llvm-v13.x-41-linux-x86_64-release.zip" }, + "macosx-x86_64" : { "type": "url", "path" : "slang-llvm-v13.x-41-macosx-x86_64-release.zip" } } }, { diff --git a/github_test.sh b/github_test.sh index 3ce8f8314..6f6e18abe 100644 --- a/github_test.sh +++ b/github_test.sh @@ -37,4 +37,5 @@ fi SLANG_TEST=${OUTPUTDIR}slang-test export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OUTPUTDIR +export PATH=$PATH:${OUTPUTDIR} ${SLANG_TEST} -bindir ${OUTPUTDIR} -travis -category ${SLANG_TEST_CATEGORY} ${SLANG_TEST_FLAGS} -api all-vk diff --git a/source/core/slang-process.h b/source/core/slang-process.h index 0beb78c06..c36064ac3 100644 --- a/source/core/slang-process.h +++ b/source/core/slang-process.h @@ -73,6 +73,8 @@ public: /// Get the clock tick. static uint64_t getClockTick(); + static uint32_t getId(); + protected: int32_t m_returnValue = 0; ///< Value returned if process terminated RefPtr<Stream> m_streams[Index(StdStreamType::CountOf)]; ///< Streams to communicate with the process diff --git a/source/core/unix/slang-unix-process.cpp b/source/core/unix/slang-unix-process.cpp index 428bef874..3ab113d83 100644 --- a/source/core/unix/slang-unix-process.cpp +++ b/source/core/unix/slang-unix-process.cpp @@ -649,4 +649,9 @@ closePipes: return SLANG_OK; } +uint32_t Process::getId() +{ + return getpid(); +} + } // namespace Slang diff --git a/source/core/windows/slang-win-process.cpp b/source/core/windows/slang-win-process.cpp index e577da0fa..38f733015 100644 --- a/source/core/windows/slang-win-process.cpp +++ b/source/core/windows/slang-win-process.cpp @@ -561,4 +561,10 @@ static const uint64_t g_frequency = _getClockFrequency(); return counter.QuadPart; } +uint32_t Process::getId() +{ + return _getpid(); +} + + } // namespace Slang diff --git a/source/slang/slang-check-decl.cpp b/source/slang/slang-check-decl.cpp index f25821dac..76ab8655a 100644 --- a/source/slang/slang-check-decl.cpp +++ b/source/slang/slang-check-decl.cpp @@ -5615,6 +5615,39 @@ namespace Slang paramDecl->type = typeExpr; checkMeshOutputDecl(paramDecl); } + + if (auto declRefType = as<DeclRefType>(paramDecl->type.type)) + { + if (declRefType->getDeclRef().getDecl()->findModifier<NonCopyableTypeAttribute>()) + { + // Always pass a non-copyable type by reference. + // Remove all existing direction modifiers, and replace them with a single Ref modifier. + List<Modifier*> newModifiers; + bool hasRefModifier = false; + for (auto modifier : paramDecl->modifiers) + { + if (as<InModifier>(modifier) || as<InOutModifier>(modifier) || as<OutModifier>(modifier)) + { + continue; + } + if (as<RefModifier>(modifier)) + { + hasRefModifier = true; + } + newModifiers.add(modifier); + } + if (!hasRefModifier) + newModifiers.add(this->getASTBuilder()->create<RefModifier>()); + paramDecl->modifiers.first = newModifiers.getFirst(); + for (Index i = 0; i < newModifiers.getCount(); i++) + { + if (i < newModifiers.getCount() - 1) + newModifiers[i]->next = newModifiers[i + 1]; + else + newModifiers[i]->next = nullptr; + } + } + } } // This checks that the declaration is marked as "out" and changes the hlsl diff --git a/source/slang/slang-check-overload.cpp b/source/slang/slang-check-overload.cpp index c13e74f69..50da2d3eb 100644 --- a/source/slang/slang-check-overload.cpp +++ b/source/slang/slang-check-overload.cpp @@ -508,10 +508,11 @@ namespace Slang return nullptr; } - if (paramDeclRef.getDecl()->findModifier<OutModifier>()) + if (paramDeclRef.getDecl()->findModifier<OutModifier>() || + paramDeclRef.getDecl()->findModifier<RefModifier>()) { // Function parameters marked with `out`, `inout`, - // or `in out` are all mutable in a way where + // `in out` or `ref` are all mutable in a way where // the result of mutations will be visible to the // caller. // diff --git a/source/slang/slang-emit-glsl.cpp b/source/slang/slang-emit-glsl.cpp index 3cde9f467..c651c8735 100644 --- a/source/slang/slang-emit-glsl.cpp +++ b/source/slang/slang-emit-glsl.cpp @@ -2204,6 +2204,7 @@ void GLSLSourceEmitter::emitTypeImpl(IRType* type, const StringSliceLoc* nameAnd { if (auto refType = as<IRRefType>(type)) { + _requireGLSLExtension(UnownedStringSlice("GL_EXT_spirv_intrinsics")); m_writer->emit("spirv_by_reference "); type = refType->getValueType(); } @@ -2214,11 +2215,13 @@ void GLSLSourceEmitter::emitParamTypeImpl(IRType* type, String const& name) { if (auto refType = as<IRRefType>(type)) { + _requireGLSLExtension(UnownedStringSlice("GL_EXT_spirv_intrinsics")); m_writer->emit("spirv_by_reference "); type = refType->getValueType(); } else if (auto spirvLiteralType = as<IRSPIRVLiteralType>(type)) { + _requireGLSLExtension(UnownedStringSlice("GL_EXT_spirv_intrinsics")); m_writer->emit("spirv_literal "); type = spirvLiteralType->getValueType(); } diff --git a/source/slang/slang-ir-inline.cpp b/source/slang/slang-ir-inline.cpp index fd9ec495b..5479a98ff 100644 --- a/source/slang/slang-ir-inline.cpp +++ b/source/slang/slang-ir-inline.cpp @@ -861,8 +861,6 @@ struct GLSLResourceReturnFunctionInliningPass : InliningPassBase auto outValueType = outType->getValueType(); if (isResourceType(outValueType)) return true; - if (isIllegalGLSLParameterType(outValueType)) - return true; } return false; } diff --git a/source/slang/slang-ir-lower-buffer-element-type.cpp b/source/slang/slang-ir-lower-buffer-element-type.cpp index bc8e47e91..af25cacd0 100644 --- a/source/slang/slang-ir-lower-buffer-element-type.cpp +++ b/source/slang/slang-ir-lower-buffer-element-type.cpp @@ -403,43 +403,46 @@ namespace Slang return info; } - switch (target->getTarget()) + if (target->shouldEmitSPIRVDirectly()) { - case CodeGenTarget::SPIRV: - case CodeGenTarget::SPIRVAssembly: - if (as<IRBoolType>(type)) + switch (target->getTarget()) { - // Bool is an abstract type in SPIRV, so we need to lower them into an int. - info.loweredType = builder.getIntType(); - // Create unpack func. + case CodeGenTarget::SPIRV: + case CodeGenTarget::SPIRVAssembly: + if (as<IRBoolType>(type)) { - builder.setInsertAfter(type); - info.convertLoweredToOriginal = builder.createFunc(); - builder.setInsertInto(info.convertLoweredToOriginal); - builder.addNameHintDecoration(info.convertLoweredToOriginal, UnownedStringSlice("unpackStorage")); - info.convertLoweredToOriginal->setFullType(builder.getFuncType(1, (IRType**)&info.loweredType, type)); - builder.emitBlock(); - auto loweredParam = builder.emitParam(info.loweredType); - auto result = builder.emitCast(type, loweredParam); - builder.emitReturn(result); - } + // Bool is an abstract type in SPIRV, so we need to lower them into an int. + info.loweredType = builder.getIntType(); + // Create unpack func. + { + builder.setInsertAfter(type); + info.convertLoweredToOriginal = builder.createFunc(); + builder.setInsertInto(info.convertLoweredToOriginal); + builder.addNameHintDecoration(info.convertLoweredToOriginal, UnownedStringSlice("unpackStorage")); + info.convertLoweredToOriginal->setFullType(builder.getFuncType(1, (IRType**)&info.loweredType, type)); + builder.emitBlock(); + auto loweredParam = builder.emitParam(info.loweredType); + auto result = builder.emitCast(type, loweredParam); + builder.emitReturn(result); + } - // Create pack func. - { - builder.setInsertAfter(info.convertLoweredToOriginal); - info.convertOriginalToLowered = builder.createFunc(); - builder.setInsertInto(info.convertOriginalToLowered); - builder.addNameHintDecoration(info.convertOriginalToLowered, UnownedStringSlice("packStorage")); - info.convertOriginalToLowered->setFullType(builder.getFuncType(1, (IRType**)&type, info.loweredType)); - builder.emitBlock(); - auto param = builder.emitParam(type); - auto result = builder.emitCast(info.loweredType, param); - builder.emitReturn(result); + // Create pack func. + { + builder.setInsertAfter(info.convertLoweredToOriginal); + info.convertOriginalToLowered = builder.createFunc(); + builder.setInsertInto(info.convertOriginalToLowered); + builder.addNameHintDecoration(info.convertOriginalToLowered, UnownedStringSlice("packStorage")); + info.convertOriginalToLowered->setFullType(builder.getFuncType(1, (IRType**)&type, info.loweredType)); + builder.emitBlock(); + auto param = builder.emitParam(type); + auto result = builder.emitCast(info.loweredType, param); + builder.emitReturn(result); + } } + break; + default: + break; } - break; - default: - break; } info.loweredType = type; diff --git a/source/slang/slang-ir-specialize-resources.cpp b/source/slang/slang-ir-specialize-resources.cpp index 839e5e08e..620c4e508 100644 --- a/source/slang/slang-ir-specialize-resources.cpp +++ b/source/slang/slang-ir-specialize-resources.cpp @@ -1228,10 +1228,6 @@ bool isIllegalGLSLParameterType(IRType* type) } if (as<IRMeshOutputType>(type)) return true; - if (as<IRRayQueryType>(type)) - return true; - if (as<IRHitObjectType>(type)) - return true; return false; } diff --git a/tests/bugs/ray-query-in-generic.slang b/tests/bugs/ray-query-in-generic.slang index 3de92b775..62cbf11b6 100644 --- a/tests/bugs/ray-query-in-generic.slang +++ b/tests/bugs/ray-query-in-generic.slang @@ -38,6 +38,11 @@ struct Ray RaytracingAccelerationStructure sceneBVH; +uint getCommittedStatus<let Flags : int>(RayQuery<Flags> q) +{ + return q.CommittedStatus(); +} + bool traceSceneVisibilityRayImpl<let Flags : int>(const bool useAlphaTest, inout RayQuery<Flags> q, const Ray ray, uint rayFlags, uint instanceInclusionMask) { var rayDesc = ray.toRayDesc(); @@ -47,7 +52,7 @@ bool traceSceneVisibilityRayImpl<let Flags : int>(const bool useAlphaTest, inout 0xff, rayDesc); q.Proceed(); - if (q.CommittedStatus() == COMMITTED_TRIANGLE_HIT) + if (getCommittedStatus(q) == COMMITTED_TRIANGLE_HIT) { q.CommittedRayT(); return true; diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected index 9c4f57b68..9d4f4e5fb 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-make-hit.slang.1.expected @@ -5,6 +5,7 @@ standard output = { #version 460 #extension GL_EXT_ray_tracing : require #extension GL_NV_shader_invocation_reorder : require +#extension GL_EXT_spirv_intrinsics : require layout(row_major) uniform; layout(row_major) buffer; layout(binding = 0) @@ -31,48 +32,43 @@ struct RayDesc_0 float TMax_0; }; -void main() +RayDesc_0 HitObject_GetRayDesc_0(hitObjectNV this_0) { - uvec3 _S1 = ((gl_LaunchIDEXT)); - ivec2 launchID_0 = ivec2(_S1.xy); - uvec3 _S2 = ((gl_LaunchSizeEXT)); - int idx_0 = launchID_0.x; - RayDesc_0 ray_0; - ray_0.Origin_0 = vec3(float(idx_0), 0.0, 0.0); - ray_0.TMin_0 = 0.00999999977648258209; - ray_0.Direction_0 = vec3(0.0, 1.0, 0.0); - ray_0.TMax_0 = 10000.0; - uint _S3 = uint(idx_0); - uint _S4 = uint(idx_0 * 2); - uint _S5 = uint(idx_0 * 3); - RayDesc_0 _S6 = ray_0; - hitObjectNV hitObj_0; - int _S7 = int(_S3); - int _S8 = int(_S4); - int _S9 = int(_S5); - hitObjectRecordHitWithIndexNV(hitObj_0, scene_0, _S7, _S8, _S9, 0U, 0U, _S6.Origin_0, _S6.TMin_0, _S6.Direction_0, _S6.TMax_0, (0)); - bool _S10 = (hitObjectIsHitNV((hitObj_0))); + vec3 _S1 = (hitObjectGetWorldRayOriginNV((this_0))); + float _S2 = (hitObjectGetRayTMinNV((this_0))); + vec3 _S3 = (hitObjectGetObjectRayDirectionNV((this_0))); + float _S4 = (hitObjectGetRayTMaxNV((this_0))); + RayDesc_0 ray_0 = { _S1, _S2, _S3, _S4 }; + return ray_0; +} + +SomeValues_0 HitObject_GetAttributes_0(hitObjectNV this_1) +{ + hitObjectGetAttributesNV((this_1), ((0))); + return t_0; +} + +uint calcValue_0(spirv_by_reference hitObjectNV hit_0) +{ + bool _S5 = (hitObjectIsHitNV((hit_0))); uint r_0; - if(_S10) + if(_S5) { - uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_0 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - uint hitKind_0 = (hitObjectGetHitKindNV((hitObj_0))); + uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hit_0))); + uint instanceID_0 = (hitObjectGetInstanceIdNV((hit_0))); + uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0))); + uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0))); + uint hitKind_0 = (hitObjectGetHitKindNV((hit_0))); uint r_1 = hitKind_0 + instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0; - vec3 _S11 = (hitObjectGetWorldRayOriginNV((hitObj_0))); - float _S12 = (hitObjectGetRayTMinNV((hitObj_0))); - vec3 _S13 = (hitObjectGetObjectRayDirectionNV((hitObj_0))); - float _S14 = (hitObjectGetRayTMaxNV((hitObj_0))); - uint r_2 = r_1 + uint(_S12 > 0.0) + uint(_S14 < _S12); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_0 = uint(int(r_2) + t_0.a_0); + RayDesc_0 ray_1 = HitObject_GetRayDesc_0(hit_0); + uint r_2 = r_1 + uint(ray_1.TMin_0 > 0.0) + uint(ray_1.TMax_0 < ray_1.TMin_0); + SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0); + r_0 = uint(int(r_2) + objSomeValues_0.a_0); } else { - bool _S15 = (hitObjectIsMissNV((hitObj_0))); - if(_S15) + bool _S6 = (hitObjectIsMissNV((hit_0))); + if(_S6) { r_0 = 1U; } @@ -81,40 +77,37 @@ void main() r_0 = 0U; } } - RayDesc_0 _S16 = ray_0; + return r_0; +} + +void main() +{ + uvec3 _S7 = ((gl_LaunchIDEXT)); + ivec2 launchID_0 = ivec2(_S7.xy); + uvec3 _S8 = ((gl_LaunchSizeEXT)); + int idx_0 = launchID_0.x; + RayDesc_0 ray_2; + ray_2.Origin_0 = vec3(float(idx_0), 0.0, 0.0); + ray_2.TMin_0 = 0.00999999977648258209; + ray_2.Direction_0 = vec3(0.0, 1.0, 0.0); + ray_2.TMax_0 = 10000.0; + uint _S9 = uint(idx_0); + uint _S10 = uint(idx_0 * 2); + uint _S11 = uint(idx_0 * 3); + RayDesc_0 _S12 = ray_2; + hitObjectNV hitObj_0; + int _S13 = int(_S9); + int _S14 = int(_S10); + int _S15 = int(_S11); + hitObjectRecordHitWithIndexNV(hitObj_0, scene_0, _S13, _S14, _S15, 0U, 0U, _S12.Origin_0, _S12.TMin_0, _S12.Direction_0, _S12.TMax_0, (0)); + hitObjectNV hit_1 = hitObj_0; + uint r_3 = calcValue_0(hit_1); + RayDesc_0 _S16 = ray_2; hitObjectNV hitObj_1; - hitObjectRecordHitNV(hitObj_1, scene_0, _S7, _S9, _S8, 0U, 0U, 4U, _S16.Origin_0, _S16.TMin_0, _S16.Direction_0, _S16.TMax_0, (0)); - bool _S17 = (hitObjectIsHitNV((hitObj_1))); - uint r_3; - if(_S17) - { - uint instanceIndex_1 = (hitObjectGetInstanceCustomIndexNV((hitObj_1))); - uint instanceID_1 = (hitObjectGetInstanceIdNV((hitObj_1))); - uint geometryIndex_1 = (hitObjectGetGeometryIndexNV((hitObj_1))); - uint primitiveIndex_1 = (hitObjectGetPrimitiveIndexNV((hitObj_1))); - uint hitKind_1 = (hitObjectGetHitKindNV((hitObj_1))); - uint r_4 = hitKind_1 + instanceIndex_1 + instanceID_1 + geometryIndex_1 + primitiveIndex_1; - vec3 _S18 = (hitObjectGetWorldRayOriginNV((hitObj_1))); - float _S19 = (hitObjectGetRayTMinNV((hitObj_1))); - vec3 _S20 = (hitObjectGetObjectRayDirectionNV((hitObj_1))); - float _S21 = (hitObjectGetRayTMaxNV((hitObj_1))); - uint r_5 = r_4 + uint(_S19 > 0.0) + uint(_S21 < _S19); - hitObjectGetAttributesNV((hitObj_1), ((0))); - r_3 = uint(int(r_5) + t_0.a_0); - } - else - { - bool _S22 = (hitObjectIsMissNV((hitObj_1))); - if(_S22) - { - r_3 = 1U; - } - else - { - r_3 = 0U; - } - } - outputBuffer_0._data[_S3] = r_0 + r_3; + hitObjectRecordHitNV(hitObj_1, scene_0, _S13, _S15, _S14, 0U, 0U, 4U, _S16.Origin_0, _S16.TMin_0, _S16.Direction_0, _S16.TMax_0, (0)); + hitObjectNV hit_2 = hitObj_1; + uint _S17 = calcValue_0(hit_2); + outputBuffer_0._data[_S9] = r_3 + _S17; return; } diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected index 0eb445ba5..778aa0e58 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-output.slang.1.expected @@ -5,6 +5,7 @@ standard output = { #version 460 #extension GL_EXT_ray_tracing : require #extension GL_NV_shader_invocation_reorder : require +#extension GL_EXT_spirv_intrinsics : require layout(row_major) uniform; layout(row_major) buffer; layout(binding = 0) @@ -58,58 +59,54 @@ hitObjectNV myTraceRay_0(uint idx_1) return hitObj_0; } -void main() +MyAttributes_0 HitObject_GetAttributes_0(hitObjectNV this_0) { - uvec3 _S1 = ((gl_LaunchIDEXT)); - uint idx_2 = _S1.x; - bool _S2 = (hitObjectIsHitNV((myTraceRay_0(idx_2)))); - uint r_0; - if(_S2) - { - hitObjectGetAttributesNV((myTraceRay_0(idx_2)), ((0))); - r_0 = 16U + t_0.value_0; - } - else - { - r_0 = 0U; - } - uint r_1 = r_0 * 256U; - bool _S3 = (hitObjectIsHitNV((myTraceRay_0(idx_2)))); - if(_S3) - { - hitObjectGetAttributesNV((myTraceRay_0(idx_2)), ((0))); - r_0 = r_1 + (16U + t_0.value_0); - } - else + hitObjectGetAttributesNV((this_0), ((0))); + return t_0; +} + +void accumulate_0(inout uint value_2, spirv_by_reference hitObjectNV hit_0) +{ + value_2 = value_2 * 256U; + bool _S1 = (hitObjectIsHitNV((hit_0))); + if(_S1) { - r_0 = r_1; + MyAttributes_0 _S2 = HitObject_GetAttributes_0(hit_0); + value_2 = value_2 + (16U + _S2.value_0); } + return; +} + +void copyHitObjectHandle_0(spirv_by_reference hitObjectNV dst_0, spirv_by_reference hitObjectNV src_0) +{ + dst_0 = src_0; + return; +} + +void myMakeMiss_0(uint idx_2, spirv_by_reference hitObjectNV h_0) +{ RayDesc_0 ray_2 = makeRay_0(idx_2, 1U); hitObjectNV hitObj_1; hitObjectRecordMissNV(hitObj_1, idx_2, ray_2.Origin_0, ray_2.TMin_0, ray_2.Direction_0, ray_2.TMax_0); - uint r_2 = r_0 * 256U; - bool _S4 = (hitObjectIsHitNV((hitObj_1))); - if(_S4) - { - hitObjectGetAttributesNV((hitObj_1), ((0))); - r_0 = r_2 + (16U + t_0.value_0); - } - else - { - r_0 = r_2; - } - uint r_3 = r_0 * 256U; - bool _S5 = (hitObjectIsHitNV((myTraceRay_0(idx_2)))); - if(_S5) - { - hitObjectGetAttributesNV((myTraceRay_0(idx_2)), ((0))); - r_0 = r_3 + (16U + t_0.value_0); - } - else - { - r_0 = r_3; - } - outputBuffer_0._data[idx_2] = r_0; + h_0 = hitObj_1; + return; +} + +void main() +{ + uvec3 _S3 = ((gl_LaunchIDEXT)); + uint idx_3 = _S3.x; + uint r_0 = 0U; + hitObjectNV hit_1 = myTraceRay_0(idx_3); + accumulate_0(r_0, hit_1); + hitObjectNV hit2_0; + copyHitObjectHandle_0(hit2_0, hit_1); + accumulate_0(r_0, hit2_0); + hitObjectNV hitBackup_0 = hit_1; + myMakeMiss_0(idx_3, hit_1); + accumulate_0(r_0, hit_1); + accumulate_0(r_0, hitBackup_0); + outputBuffer_0._data[idx_3] = r_0; return; } diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected index 29fee14ab..167d27514 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-reorder-thread.slang.1.expected @@ -5,6 +5,7 @@ standard output = { #version 460 #extension GL_EXT_ray_tracing : require #extension GL_NV_shader_invocation_reorder : require +#extension GL_EXT_spirv_intrinsics : require layout(row_major) uniform; layout(row_major) buffer; layout(binding = 0) @@ -31,6 +32,40 @@ layout(location = 1) rayPayloadEXT SomeValues_0 p_1; +SomeValues_0 HitObject_GetAttributes_0(hitObjectNV this_0) +{ + hitObjectGetAttributesNV((this_0), ((0))); + return t_0; +} + +uint calcValue_0(spirv_by_reference hitObjectNV hit_0) +{ + bool _S1 = (hitObjectIsHitNV((hit_0))); + uint r_0; + if(_S1) + { + uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hit_0))); + uint instanceID_0 = (hitObjectGetInstanceIdNV((hit_0))); + uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0))); + uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0))); + SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0); + r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + objSomeValues_0.a_0); + } + else + { + r_0 = 0U; + } + return r_0; +} + +void HitObject_Invoke_0(accelerationStructureEXT AccelerationStructure_0, spirv_by_reference hitObjectNV HitOrMiss_0, inout SomeValues_0 Payload_0) +{ + p_0 = Payload_0; + hitObjectExecuteShaderNV(HitOrMiss_0, (0)); + Payload_0 = p_0; + return; +} + struct RayDesc_0 { vec3 Origin_0; @@ -41,104 +76,46 @@ struct RayDesc_0 void main() { - uvec3 _S1 = ((gl_LaunchIDEXT)); - ivec2 launchID_0 = ivec2(_S1.xy); - uvec3 _S2 = ((gl_LaunchSizeEXT)); + uvec3 _S2 = ((gl_LaunchIDEXT)); + ivec2 launchID_0 = ivec2(_S2.xy); + uvec3 _S3 = ((gl_LaunchSizeEXT)); int idx_0 = launchID_0.x; - float _S3 = float(idx_0); - float _S4 = _S3 * 2.0; + float _S4 = float(idx_0); + float _S5 = _S4 * 2.0; RayDesc_0 ray_0; - ray_0.Origin_0 = vec3(_S3, 0.0, 0.0); + ray_0.Origin_0 = vec3(_S4, 0.0, 0.0); ray_0.TMin_0 = 0.00999999977648258209; ray_0.Direction_0 = vec3(0.0, 1.0, 0.0); ray_0.TMax_0 = 10000.0; - RayDesc_0 _S5 = ray_0; + RayDesc_0 _S6 = ray_0; hitObjectNV hitObj_0; p_1.a_0 = idx_0; - p_1.b_0 = _S4; - hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S5.Origin_0, _S5.TMin_0, _S5.Direction_0, _S5.TMax_0, (1)); - int _S6 = idx_0 * -1; - float _S7 = _S3 * 4.0; - uint _S8 = uint(idx_0 & 3); - int _S9 = idx_0 * -2; - float _S10 = _S3 * 8.0; - uint _S11 = uint(idx_0 & 1); - int _S12 = idx_0 * -4; - float _S13 = _S3 * 16.0; - uint _S14 = uint(idx_0); - bool _S15 = (hitObjectIsHitNV((hitObj_0))); - uint r_0; - if(_S15) - { - uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_0 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + t_0.a_0); - } - else - { - r_0 = 0U; - } - reorderThreadNV(hitObj_0); - p_0.a_0 = _S6; - p_0.b_0 = _S7; - hitObjectExecuteShaderNV(hitObj_0, (0)); - bool _S16 = (hitObjectIsHitNV((hitObj_0))); - uint r_1; - if(_S16) - { - uint instanceIndex_1 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_1 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_1 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_1 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_1 = uint(int(instanceIndex_1 + instanceID_1 + geometryIndex_1 + primitiveIndex_1) + t_0.a_0); - } - else - { - r_1 = 0U; - } - uint r_2 = r_0 + r_1; - reorderThreadNV(hitObj_0, _S8, 2U); - p_0.a_0 = _S9; - p_0.b_0 = _S10; - hitObjectExecuteShaderNV(hitObj_0, (0)); - bool _S17 = (hitObjectIsHitNV((hitObj_0))); - if(_S17) - { - uint instanceIndex_2 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_2 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_2 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_2 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_0 = uint(int(instanceIndex_2 + instanceID_2 + geometryIndex_2 + primitiveIndex_2) + t_0.a_0); - } - else - { - r_0 = 0U; - } - uint r_3 = r_2 + r_0; - reorderThreadNV(_S11, 1U); - p_0.a_0 = _S12; - p_0.b_0 = _S13; - hitObjectExecuteShaderNV(hitObj_0, (0)); - bool _S18 = (hitObjectIsHitNV((hitObj_0))); - if(_S18) - { - uint instanceIndex_3 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_3 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_3 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_3 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_0 = uint(int(instanceIndex_3 + instanceID_3 + geometryIndex_3 + primitiveIndex_3) + t_0.a_0); - } - else - { - r_0 = 0U; - } - outputBuffer_0._data[_S14] = r_3 + r_0; + p_1.b_0 = _S5; + hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S6.Origin_0, _S6.TMin_0, _S6.Direction_0, _S6.TMax_0, (1)); + hitObjectNV hit_1 = hitObj_0; + uint r_1 = calcValue_0(hit_1); + reorderThreadNV(hit_1); + float _S7 = _S4 * 4.0; + SomeValues_0 otherValues_0; + otherValues_0.a_0 = idx_0 * -1; + otherValues_0.b_0 = _S7; + HitObject_Invoke_0(scene_0, hit_1, otherValues_0); + uint _S8 = calcValue_0(hit_1); + uint r_2 = r_1 + _S8; + reorderThreadNV(hit_1, uint(idx_0 & 3), 2U); + float _S9 = _S4 * 8.0; + otherValues_0.a_0 = idx_0 * -2; + otherValues_0.b_0 = _S9; + HitObject_Invoke_0(scene_0, hit_1, otherValues_0); + uint _S10 = calcValue_0(hit_1); + uint r_3 = r_2 + _S10; + reorderThreadNV(uint(idx_0 & 1), 1U); + float _S11 = _S4 * 16.0; + otherValues_0.a_0 = idx_0 * -4; + otherValues_0.b_0 = _S11; + HitObject_Invoke_0(scene_0, hit_1, otherValues_0); + uint _S12 = calcValue_0(hit_1); + outputBuffer_0._data[uint(idx_0)] = r_3 + _S12; return; } diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected index 2b86e9613..298edfa02 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-motion-ray.slang.1.expected @@ -4,8 +4,9 @@ standard error = { standard output = { #version 460 #extension GL_EXT_ray_tracing : require -#extension GL_NV_ray_tracing_motion_blur : require #extension GL_NV_shader_invocation_reorder : require +#extension GL_EXT_spirv_intrinsics : require +#extension GL_NV_ray_tracing_motion_blur : require layout(row_major) uniform; layout(row_major) buffer; layout(binding = 0) @@ -28,6 +29,32 @@ layout(location = 0) rayPayloadEXT SomeValues_0 p_0; +SomeValues_0 HitObject_GetAttributes_0(hitObjectNV this_0) +{ + hitObjectGetAttributesNV((this_0), ((0))); + return t_0; +} + +uint calcValue_0(spirv_by_reference hitObjectNV hit_0) +{ + bool _S1 = (hitObjectIsHitNV((hit_0))); + uint r_0; + if(_S1) + { + uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hit_0))); + uint instanceID_0 = (hitObjectGetInstanceIdNV((hit_0))); + uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0))); + uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0))); + SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0); + r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + objSomeValues_0.a_0); + } + else + { + r_0 = 0U; + } + return r_0; +} + struct RayDesc_0 { vec3 Origin_0; @@ -38,40 +65,27 @@ struct RayDesc_0 void main() { - uvec3 _S1 = ((gl_LaunchIDEXT)); - ivec2 launchID_0 = ivec2(_S1.xy); - uvec3 _S2 = ((gl_LaunchSizeEXT)); + uvec3 _S2 = ((gl_LaunchIDEXT)); + ivec2 launchID_0 = ivec2(_S2.xy); + uvec3 _S3 = ((gl_LaunchSizeEXT)); int idx_0 = launchID_0.x; float currentTime_0 = float(idx_0 / 4); - float _S3 = float(idx_0); - float _S4 = _S3 * 2.0; + float _S4 = float(idx_0); + float _S5 = _S4 * 2.0; RayDesc_0 ray_0; - ray_0.Origin_0 = vec3(_S3, 0.0, 0.0); + ray_0.Origin_0 = vec3(_S4, 0.0, 0.0); ray_0.TMin_0 = 0.00999999977648258209; ray_0.Direction_0 = vec3(0.0, 1.0, 0.0); ray_0.TMax_0 = 10000.0; - RayDesc_0 _S5 = ray_0; + RayDesc_0 _S6 = ray_0; hitObjectNV hitObj_0; p_0.a_0 = idx_0; - p_0.b_0 = _S4; - hitObjectTraceRayMotionNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S5.Origin_0, _S5.TMin_0, _S5.Direction_0, _S5.TMax_0, currentTime_0, (0)); - uint _S6 = uint(idx_0); - bool _S7 = (hitObjectIsHitNV((hitObj_0))); - uint r_0; - if(_S7) - { - uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_0 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + t_0.a_0); - } - else - { - r_0 = 0U; - } - outputBuffer_0._data[_S6] = r_0; + p_0.b_0 = _S5; + hitObjectTraceRayMotionNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S6.Origin_0, _S6.TMin_0, _S6.Direction_0, _S6.TMax_0, currentTime_0, (0)); + hitObjectNV hit_1 = hitObj_0; + uint _S7 = uint(idx_0); + uint _S8 = calcValue_0(hit_1); + outputBuffer_0._data[_S7] = _S8; return; } diff --git a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected index 8e89ec1c5..e6091a555 100644 --- a/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected +++ b/tests/hlsl-intrinsic/shader-execution-reordering/hit-object-trace-ray.slang.1.expected @@ -5,6 +5,7 @@ standard output = { #version 460 #extension GL_EXT_ray_tracing : require #extension GL_NV_shader_invocation_reorder : require +#extension GL_EXT_spirv_intrinsics : require layout(row_major) uniform; layout(row_major) buffer; layout(binding = 0) @@ -27,6 +28,32 @@ layout(location = 0) rayPayloadEXT SomeValues_0 p_0; +SomeValues_0 HitObject_GetAttributes_0(hitObjectNV this_0) +{ + hitObjectGetAttributesNV((this_0), ((0))); + return t_0; +} + +uint calcValue_0(spirv_by_reference hitObjectNV hit_0) +{ + bool _S1 = (hitObjectIsHitNV((hit_0))); + uint r_0; + if(_S1) + { + uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hit_0))); + uint instanceID_0 = (hitObjectGetInstanceIdNV((hit_0))); + uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hit_0))); + uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hit_0))); + SomeValues_0 objSomeValues_0 = HitObject_GetAttributes_0(hit_0); + r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + objSomeValues_0.a_0); + } + else + { + r_0 = 0U; + } + return r_0; +} + struct RayDesc_0 { vec3 Origin_0; @@ -37,39 +64,26 @@ struct RayDesc_0 void main() { - uvec3 _S1 = ((gl_LaunchIDEXT)); - ivec2 launchID_0 = ivec2(_S1.xy); - uvec3 _S2 = ((gl_LaunchSizeEXT)); + uvec3 _S2 = ((gl_LaunchIDEXT)); + ivec2 launchID_0 = ivec2(_S2.xy); + uvec3 _S3 = ((gl_LaunchSizeEXT)); int idx_0 = launchID_0.x; - float _S3 = float(idx_0); - float _S4 = _S3 * 2.0; + float _S4 = float(idx_0); + float _S5 = _S4 * 2.0; RayDesc_0 ray_0; - ray_0.Origin_0 = vec3(_S3, 0.0, 0.0); + ray_0.Origin_0 = vec3(_S4, 0.0, 0.0); ray_0.TMin_0 = 0.00999999977648258209; ray_0.Direction_0 = vec3(0.0, 1.0, 0.0); ray_0.TMax_0 = 10000.0; - RayDesc_0 _S5 = ray_0; + RayDesc_0 _S6 = ray_0; hitObjectNV hitObj_0; p_0.a_0 = idx_0; - p_0.b_0 = _S4; - hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S5.Origin_0, _S5.TMin_0, _S5.Direction_0, _S5.TMax_0, (0)); - uint _S6 = uint(idx_0); - bool _S7 = (hitObjectIsHitNV((hitObj_0))); - uint r_0; - if(_S7) - { - uint instanceIndex_0 = (hitObjectGetInstanceCustomIndexNV((hitObj_0))); - uint instanceID_0 = (hitObjectGetInstanceIdNV((hitObj_0))); - uint geometryIndex_0 = (hitObjectGetGeometryIndexNV((hitObj_0))); - uint primitiveIndex_0 = (hitObjectGetPrimitiveIndexNV((hitObj_0))); - hitObjectGetAttributesNV((hitObj_0), ((0))); - r_0 = uint(int(instanceIndex_0 + instanceID_0 + geometryIndex_0 + primitiveIndex_0) + t_0.a_0); - } - else - { - r_0 = 0U; - } - outputBuffer_0._data[_S6] = r_0; + p_0.b_0 = _S5; + hitObjectTraceRayNV(hitObj_0, scene_0, 20U, 255U, 0U, 4U, 0U, _S6.Origin_0, _S6.TMin_0, _S6.Direction_0, _S6.TMax_0, (0)); + hitObjectNV hit_1 = hitObj_0; + uint _S7 = uint(idx_0); + uint _S8 = calcValue_0(hit_1); + outputBuffer_0._data[_S7] = _S8; return; } diff --git a/tools/gfx-unit-test/copy-texture-tests.cpp b/tools/gfx-unit-test/copy-texture-tests.cpp index 0129dd818..68ca193ae 100644 --- a/tools/gfx-unit-test/copy-texture-tests.cpp +++ b/tools/gfx-unit-test/copy-texture-tests.cpp @@ -749,20 +749,20 @@ namespace gfx_test // Skip Type::Unknown and Type::Buffer as well as Format::Unknown // TODO: Add support for TextureCube + Format formats[] = { Format::R8G8B8A8_UNORM, Format::R16_FLOAT, Format::R16G16_FLOAT, Format::R10G10B10A2_UNORM, Format::B5G5R5A1_UNORM }; for (uint32_t i = 2; i < (uint32_t)ITextureResource::Type::_Count - 1; ++i) { - for (uint32_t j = 1; j < (uint32_t)Format::_Count; ++j) + for (auto format : formats) { // Fails validation VUID-VkImageCreateInfo-imageCreateMaxMipLevels-02251 - if(isVkd3d && ((Format)j == Format::R32G32B32_TYPELESS || - (Format)j == Format::R32G32B32_FLOAT || - (Format)j == Format::R32G32B32_UINT || - (Format)j == Format::R32G32B32_SINT)) + if(isVkd3d && (format == Format::R32G32B32_TYPELESS || + format == Format::R32G32B32_FLOAT || + format == Format::R32G32B32_UINT || + format == Format::R32G32B32_SINT)) { continue; } auto type = (ITextureResource::Type)i; - auto format = (Format)j; auto validationFormat = getValidationTextureFormat(format); if (!validationFormat) continue; diff --git a/tools/gfx-unit-test/shader-cache-tests.cpp b/tools/gfx-unit-test/shader-cache-tests.cpp index de699c2d6..3879fd630 100644 --- a/tools/gfx-unit-test/shader-cache-tests.cpp +++ b/tools/gfx-unit-test/shader-cache-tests.cpp @@ -7,7 +7,7 @@ #include "source/core/slang-string-util.h" #include "source/core/slang-io.h" #include "source/core/slang-file-system.h" - +#include "source/core/slang-process.h" #include "gfx-test-texture-util.h" using namespace gfx; @@ -112,9 +112,8 @@ namespace gfx_test { this->context = context; this->api = api; - - testDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/shader-cache-test"); - cacheDirectory = Path::simplify(testDirectory + "/cache"); + testDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/shader-cache-test" + String(Process::getId())); + cacheDirectory = Path::simplify(testDirectory + "/cache" + String(Process::getId())); // Cleanup if there are stale files from a previously aborted test. removeDirectory(cacheDirectory); diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index c910d83cc..b726caea3 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -879,7 +879,11 @@ static Result _executeRPC(TestContext* context, SpawnType spawnType, const Unown } // Execute - SLANG_RETURN_ON_FAIL(rpcConnection->sendCall(method, rttiInfo, args)); + if (SLANG_FAILED(rpcConnection->sendCall(method, rttiInfo, args))) + { + context->destroyRPCConnection(); + return SLANG_FAIL; + } // Wait for the result rpcConnection->waitForResult(context->connectionTimeOutInMs); @@ -893,12 +897,17 @@ static Result _executeRPC(TestContext* context, SpawnType spawnType, const Unown if (rpcConnection->getMessageType() != JSONRPCMessageType::Result) { + context->destroyRPCConnection(); return SLANG_FAIL; } // Get the result TestServerProtocol::ExecutionResult exeRes; - SLANG_RETURN_ON_FAIL(rpcConnection->getMessage(&exeRes)); + if (SLANG_FAILED(rpcConnection->getMessage(&exeRes))) + { + context->destroyRPCConnection(); + return SLANG_FAIL; + } outRes.resultCode = exeRes.returnCode; outRes.standardError = exeRes.stdError; @@ -1648,7 +1657,10 @@ TestResult runExecutableTest(TestContext* context, TestInput& input) // Just use shared library now, TestServer spawn mode seems to cause slangc to fail to find its own // executable path, and thus failed to find the `gfx.slang` file sitting along side `slangc.exe`. // We need to figure out what happened to `Path::getExecutablePath()` inside test-server. - TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, SpawnType::UseSharedLibrary, cmdLine, exeRes)); + SpawnType slangcSpawnType = input.spawnType; + if (slangcSpawnType == SpawnType::UseTestServer) + slangcSpawnType = SpawnType::UseExe; + TEST_RETURN_ON_DONE(spawnAndWait(context, outputStem, slangcSpawnType, cmdLine, exeRes)); String actualOutput; @@ -1702,6 +1714,9 @@ TestResult runExecutableTest(TestContext* context, TestInput& input) TestResult runLanguageServerTest(TestContext* context, TestInput& input) { + // We don't support running language server tests in parallel yet. + std::lock_guard lock(context->mutex); + if (!context->m_languageServerConnection) { if (SLANG_FAILED(context->createLanguageServerJSONRPCConnection(context->m_languageServerConnection))) @@ -4072,6 +4087,42 @@ void getFilesInDirectory(String directoryPath, List<String>& files) } } +template<typename F> +void runTestsInParallel(TestContext* context, int count, const F& f) +{ + auto originalReporter = context->getTestReporter(); + std::atomic<int> consumePtr; + consumePtr = 0; + auto threadFunc = [&](int threadId) + { + TestReporter reporter; + reporter.init(context->options.outputMode, context->options.expectedFailureList, true); + TestReporter::SuiteScope suiteScope(&reporter, "tests"); + context->setThreadIndex(threadId); + context->setTestReporter(&reporter); + do + { + int index = consumePtr.fetch_add(1); + if (index >= count) + break; + f(index); + } while (true); + { + std::lock_guard<std::mutex> lock(context->mutex); + originalReporter->consolidateWith(&reporter); + } + context->setTestReporter(nullptr); + }; + List<std::thread> threads; + for (int threadId = 0; threadId < context->options.serverCount; threadId++) + { + threads.add(std::thread(threadFunc, threadId)); + } + for (auto& t : threads) + t.join(); + context->setTestReporter(originalReporter); +} + void runTestsInDirectory( TestContext* context, String directoryPath) @@ -4119,37 +4170,10 @@ void runTestsInDirectory( } else { - auto originalReporter = context->getTestReporter(); - std::atomic<int> consumePtr; - consumePtr = 0; - auto threadFunc = [&](int threadId) - { - TestReporter reporter; - reporter.init(context->options.outputMode, context->options.expectedFailureList, true); - TestReporter::SuiteScope suiteScope(&reporter, "tests"); - context->setThreadIndex(threadId); - context->setTestReporter(&reporter); - do + runTestsInParallel(context, (int)files.getCount(), [&](int index) { - int index = consumePtr.fetch_add(1); - if (index >= (int)files.getCount()) - break; processFile(files[index]); - } while (true); - { - std::lock_guard<std::mutex> lock(context->mutex); - originalReporter->consolidateWith(&reporter); - } - context->setTestReporter(nullptr); - }; - List<std::thread> threads; - for (int threadId = 0; threadId < context->options.serverCount; threadId++) - { - threads.add(std::thread(threadFunc, threadId)); - } - for (auto& t : threads) - t.join(); - context->setTestReporter(originalReporter); + }); } } @@ -4205,10 +4229,6 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti if (!testModule) return SLANG_FAIL; - auto reporter = TestReporter::get(); - - testModule->setTestReporter(reporter); - UnitTestContext unitTestContext; unitTestContext.slangGlobalSession = context->getSession(); unitTestContext.workDirectory = ""; @@ -4217,6 +4237,16 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti auto testCount = testModule->getTestCount(); + struct TestItem + { + UnitTestFunc testFunc; + String testName; + String command; + }; + + List<TestItem> tests; + + // Discover all tests first. for (SlangInt i = 0; i < testCount; i++) { auto testFunc = testModule->getTestFunc(i); @@ -4224,59 +4254,94 @@ static SlangResult runUnitTestModule(TestContext* context, TestOptions& testOpti StringBuilder filePath; filePath << moduleName << "/" << testName << ".internal"; + auto command = filePath.produceString(); - testOptions.command = filePath; - - if (shouldRunTest(context, testOptions.command)) + if (shouldRunTest(context, command)) { if (testPassesCategoryMask(context, testOptions)) { - if (spawnType == SpawnType::UseTestServer || - spawnType == SpawnType::UseFullyIsolatedTestServer) - { - TestServerProtocol::ExecuteUnitTestArgs args; - args.enabledApis = context->options.enabledApis; - args.moduleName = moduleName; - args.testName = testName; + tests.add(TestItem{ testFunc, testName, command }); + } + } + } - { - TestReporter::TestScope scopeTest(reporter, testOptions.command); - ExecuteResult exeRes; + auto runUnitTest = [&](TestItem test) + { + auto reporter = context->getTestReporter(); + TestOptions options = testOptions; + options.command = test.command; - SlangResult rpcRes = _executeRPC(context, spawnType, TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes); - const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode)); + if (spawnType == SpawnType::UseTestServer || + spawnType == SpawnType::UseFullyIsolatedTestServer) + { + TestServerProtocol::ExecuteUnitTestArgs args; + args.enabledApis = context->options.enabledApis; + args.moduleName = moduleName; + args.testName = test.testName; - // If the test fails, output any output - which might give information about individual tests that have failed. - if (SLANG_FAILED(rpcRes) || testResult == TestResult::Fail) - { - String output = getOutput(exeRes); - reporter->message(TestMessageType::TestFailure, output.getBuffer()); - } + { + TestReporter::TestScope scopeTest(reporter, options.command); + ExecuteResult exeRes; - reporter->addResult(testResult); - } - } - else + SlangResult rpcRes = _executeRPC(context, spawnType, TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes); + const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode)); + + // If the test fails, output any output - which might give information about individual tests that have failed. + if (SLANG_FAILED(rpcRes) || testResult == TestResult::Fail) { - TestReporter::TestScope scopeTest(reporter, testOptions.command); + String output = getOutput(exeRes); + reporter->message(TestMessageType::TestFailure, output.getBuffer()); + } - // TODO(JS): Problem here could be exception not handled properly across - // shared library boundary. + reporter->addResult(testResult); + } + } + else + { + TestReporter::TestScope scopeTest(reporter, options.command); - try - { - testFunc(&unitTestContext); - } - catch (...) - { - reporter->message(TestMessageType::TestFailure, "Exception was thrown during execution"); - reporter->addResult(TestResult::Fail); - } - } + // TODO(JS): Problem here could be exception not handled properly across + // shared library boundary. + testModule->setTestReporter(reporter); + try + { + test.testFunc(&unitTestContext); } + catch (...) + { + reporter->message(TestMessageType::TestFailure, "Exception was thrown during execution"); + reporter->addResult(TestResult::Fail); + } + } + }; + + bool useMultiThread = false; + if (spawnType == SpawnType::UseTestServer || + spawnType == SpawnType::UseFullyIsolatedTestServer) + { + if (context->options.serverCount > 1) + { + useMultiThread = true; } } + if (useMultiThread) + { + runTestsInParallel(context, (int)tests.getCount(), [&](int index) + { + runUnitTest(tests[index]); + }); + } + else + { + auto reporter = TestReporter::get(); + + testModule->setTestReporter(reporter); + + for (auto t : tests) + runUnitTest(t); + } + testModule->destroy(); return SLANG_OK; } diff --git a/tools/slang-test/test-context.h b/tools/slang-test/test-context.h index 00aad5888..ad8a45042 100644 --- a/tools/slang-test/test-context.h +++ b/tools/slang-test/test-context.h @@ -159,8 +159,8 @@ class TestContext /// TODO(JS): We could split the stdlib compilation from other actions, and have timeout specific for /// that. To do this we could have a 'compileStdLib' RPC method. /// - /// Current default is 2 mins. - Slang::Int connectionTimeOutInMs = 2 * 60 * 1000; + /// Current default is 20 seconds. + Slang::Int connectionTimeOutInMs = 20 * 1000; void setThreadIndex(int index); void setMaxTestRunnerThreadCount(int count); diff --git a/tools/slang-unit-test/unit-test-lock-file.cpp b/tools/slang-unit-test/unit-test-lock-file.cpp index be767a5ee..4915770fe 100644 --- a/tools/slang-unit-test/unit-test-lock-file.cpp +++ b/tools/slang-unit-test/unit-test-lock-file.cpp @@ -2,6 +2,7 @@ #include "tools/unit-test/slang-unit-test.h" #include "../../source/core/slang-io.h" +#include "../../source/core/slang-process.h" #include <atomic> #include <future> @@ -10,7 +11,7 @@ using namespace Slang; -static const String fileName = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/test_lock_file"); +static const String fileName = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/test_lock_file" + String(Process::getId())); SLANG_UNIT_TEST(lockFileOpenClose) { diff --git a/tools/slang-unit-test/unit-test-persistent-cache.cpp b/tools/slang-unit-test/unit-test-persistent-cache.cpp index d2d8aeb25..cb7ebcab2 100644 --- a/tools/slang-unit-test/unit-test-persistent-cache.cpp +++ b/tools/slang-unit-test/unit-test-persistent-cache.cpp @@ -5,6 +5,7 @@ #include "../../source/core/slang-io.h" #include "../../source/core/slang-file-system.h" #include "../../source/core/slang-random-generator.h" +#include "../../source/core/slang-process.h" #include <chrono> #include <thread> @@ -86,7 +87,7 @@ struct PersistentCacheTest PersistentCacheTest(Count maxEntryCount = 0) { osFileSystem = OSFileSystem::getMutableSingleton(); - cacheDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/persistent-cache-test"); + cacheDirectory = Path::simplify(Path::getParentDirectory(Path::getExecutablePath()) + "/persistent-cache-test" + String(Process::getId())); removeCacheFiles(); diff --git a/tools/slang-unit-test/unit-test-translation-unit-import.cpp b/tools/slang-unit-test/unit-test-translation-unit-import.cpp index 9e79831e5..3a0a98e17 100644 --- a/tools/slang-unit-test/unit-test-translation-unit-import.cpp +++ b/tools/slang-unit-test/unit-test-translation-unit-import.cpp @@ -8,6 +8,7 @@ #include "tools/unit-test/slang-unit-test.h" #include "../../slang-com-ptr.h" #include "../../source/core/slang-io.h" +#include "../../source/core/slang-process.h" using namespace Slang; @@ -31,8 +32,7 @@ SLANG_UNIT_TEST(translationUnitImport) )"; // Source for a module that transitively uses the generated source via a file. - const char* userSource = R"( - import moduleG; + const char* userSourceBody = R"( [shader("compute")] [numthreads(4,1,1)] void computeMain( @@ -42,11 +42,12 @@ SLANG_UNIT_TEST(translationUnitImport) buffer[sv_dispatchThreadID.x] = g(); })"; - + auto moduleName = "moduleG" + String(Process::getId()); + String userSource = "import " + moduleName + ";\n" + userSourceBody; auto session = spCreateSession(); auto request = spCreateCompileRequest(session); - File::writeAllText("moduleG.slang", fileSource); + File::writeAllText(moduleName + ".slang", fileSource); spAddCodeGenTarget(request, SLANG_HLSL); int generatedTranslationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "generatedUnit"); @@ -55,7 +56,7 @@ SLANG_UNIT_TEST(translationUnitImport) int entryPointTranslationUnitIndex = spAddTranslationUnit(request, SLANG_SOURCE_LANGUAGE_SLANG, "userUnit"); spAddTranslationUnitSourceString( - request, entryPointTranslationUnitIndex, "userFile", userSource); + request, entryPointTranslationUnitIndex, "userFile", userSource.getUnownedSlice().begin()); spAddEntryPoint(request, entryPointTranslationUnitIndex, "computeMain", SLANG_STAGE_COMPUTE); auto compileResult = spCompile(request); @@ -67,7 +68,6 @@ SLANG_UNIT_TEST(translationUnitImport) spDestroyCompileRequest(request); spDestroySession(session); - - File::remove("moduleG.slang"); + File::remove(moduleName + ".slang"); } |
