diff --git a/source/slang/slang-compiler-tu.cpp b/source/slang/slang-compiler-tu.cpp index c20fc9a802..8bfe9a9ab7 100644 --- a/source/slang/slang-compiler-tu.cpp +++ b/source/slang/slang-compiler-tu.cpp @@ -291,6 +291,7 @@ SLANG_NO_THROW SlangResult SLANG_MCALL ComponentType::getModuleDependency( { return SLANG_E_INVALID_ARG; } + getModuleDependencies()[dependencyIndex]->addRef(); *outModule = getModuleDependencies()[dependencyIndex]; return SLANG_OK; } diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 04ebb753c1..aa23e35075 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -1722,6 +1722,7 @@ SlangResult CodeGenContext::emitWithDownstreamForEntryPoints(ComPtr& } } } + // HERE } }); diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index e20a4a90fd..4fea47cf5e 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -2049,6 +2049,37 @@ SlangResult emitSPIRVForEntryPointsDirectly( List spirv, outSpirv; emitSPIRVFromIR(codeGenContext, irModule, irEntryPoints, spirv); + // Re-link together SPIRV + /* + // Load embedded precompiled libraries from IR into library artifacts + List> libraries; + program->enumerateIRModules( + [&](IRModule* irModule) + { + for (auto globalInst : irModule->getModuleInst()->getChildren()) + { + if (target == CodeGenTarget::SPIRVAssembly || target == CodeGenTarget::SPIRV) + { + if (auto inst = as(globalInst)) + { + if (inst->getTarget() == CodeGenTarget::SPIRV) + { + auto slice = inst->getBlob()->getStringSlice(); + ArtifactDesc desc = + ArtifactDescUtil::makeDescForCompileTarget(SLANG_SPIRV); + desc.kind = ArtifactKind::Library; + + auto library = ArtifactUtil::createArtifact(desc); + + library->addRepresentationUnknown(StringBlob::create(slice)); + libraries.add(library); + } + } + } + } + }); + + */ #if 0 String optErr; if (SLANG_FAILED(optimizeSPIRV(spirv, optErr, outSpirv))) diff --git a/tests/expected-failure-github.txt b/tests/expected-failure-github.txt index 60d632785c..38552fa9e6 100644 --- a/tests/expected-failure-github.txt +++ b/tests/expected-failure-github.txt @@ -12,5 +12,4 @@ tests/autodiff/custom-intrinsic.slang.2 syn (wgpu) tests/bugs/buffer-swizzle-store.slang.3 syn (wgpu) tests/compute/interface-shader-param-in-struct.slang.4 syn (wgpu) tests/compute/interface-shader-param.slang.5 syn (wgpu) -tests/language-feature/shader-params/interface-shader-param-ordinary.slang.4 syn (wgpu) -gfx-unit-test-tool/precompiledTargetModule2Vulkan.internal +tests/language-feature/shader-params/interface-shader-param-ordinary.slang.4 syn (wgpu) \ No newline at end of file diff --git a/tests/expected-failure.txt b/tests/expected-failure.txt index 2d95734cc7..7283c8d97c 100644 --- a/tests/expected-failure.txt +++ b/tests/expected-failure.txt @@ -5,4 +5,3 @@ tests/language-feature/saturated-cooperation/fuse.slang (vk) tests/bugs/byte-address-buffer-interlocked-add-f32.slang (vk) tests/ir/loop-unroll-0.slang.1 (vk) tests/hlsl-intrinsic/texture/float-atomics.slang (vk) -gfx-unit-test-tool/precompiledTargetModule2Vulkan.internal diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt index 9968d7ca8c..c894b100a7 100644 --- a/tools/CMakeLists.txt +++ b/tools/CMakeLists.txt @@ -141,6 +141,7 @@ if(SLANG_ENABLE_GFX) $<$:X11::X11> $<$:CUDA::cuda_driver> $<$:${NVAPI_LIBRARIES}> + SPIRV-Tools-link LINK_WITH_FRAMEWORK Foundation Cocoa QuartzCore Metal EXTRA_COMPILE_DEFINITIONS_PRIVATE $<$:GFX_ENABLE_CUDA> diff --git a/tools/gfx-unit-test/gfx-test-util.h b/tools/gfx-unit-test/gfx-test-util.h index 5586701621..1d1519dbab 100644 --- a/tools/gfx-unit-test/gfx-test-util.h +++ b/tools/gfx-unit-test/gfx-test-util.h @@ -112,9 +112,12 @@ void runTestImpl( { SLANG_IGNORE_TEST } + printf("File, Line: %s, %d\n", __FILE__, __LINE__); auto device = createTestingDevice(context, api, searchPaths, shaderCache); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); if (!device) { + printf("File, Line: %s, %d\n", __FILE__, __LINE__); SLANG_IGNORE_TEST } #if SLANG_WIN32 @@ -126,21 +129,33 @@ void runTestImpl( #endif // Skip d3d11 tests when we don't have DXBC support as they're bound to // fail without a backend compiler + printf("File, Line: %s, %d\n", __FILE__, __LINE__); if (api == Slang::RenderApiFlag::D3D11 && !SLANG_ENABLE_DXBC_SUPPORT) { + printf("File, Line: %s, %d\n", __FILE__, __LINE__); SLANG_IGNORE_TEST } try { + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); renderDocBeginFrame(); f(device, context); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); } catch (AbortTestException& e) { + printf("EXCEPTION! File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); renderDocEndFrame(); throw e; } + printf("Dun.. File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); renderDocEndFrame(); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); } #define GFX_CHECK_CALL(x) SLANG_CHECK(!SLANG_FAILED(x)) diff --git a/tools/gfx-unit-test/precompiled-module-2.cpp b/tools/gfx-unit-test/precompiled-module-2.cpp index f5d576a232..10ea9be5ed 100644 --- a/tools/gfx-unit-test/precompiled-module-2.cpp +++ b/tools/gfx-unit-test/precompiled-module-2.cpp @@ -19,6 +19,9 @@ static Slang::Result precompileProgram( const char* shaderModuleName, bool precompileToTarget) { + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); Slang::ComPtr slangSession; SLANG_RETURN_ON_FAIL(device->getSlangSession(slangSession.writeRef())); slang::SessionDesc sessionDesc = {}; @@ -27,7 +30,9 @@ static Slang::Result precompileProgram( sessionDesc.searchPaths = searchPaths.getBuffer(); auto globalSession = slangSession->getGlobalSession(); globalSession->createSession(sessionDesc, slangSession.writeRef()); - + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); slang::IModule* module; { Slang::ComPtr diagnosticsBlob; @@ -36,7 +41,9 @@ static Slang::Result precompileProgram( } if (!module) return SLANG_FAIL; - + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); if (precompileToTarget) { SlangCompileTarget target; @@ -62,7 +69,7 @@ static Slang::Result precompileProgram( diagnoseIfNeeded(diagnosticsBlob); } } - + printf("File, Line: %s, %d\n", __FILE__, __LINE__); // Write loaded modules to memory file system. for (SlangInt i = 0; i < slangSession->getLoadedModuleCount(); i++) { @@ -76,6 +83,9 @@ static Slang::Result precompileProgram( fileSys->saveFileBlob((Slang::String(name) + ".slang-module").getBuffer(), outBlob); } } + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); return SLANG_OK; } @@ -84,12 +94,15 @@ void precompiledModule2TestImplCommon( UnitTestContext* context, bool precompileToTarget) { + printf("File, Line: %s, %d\n", __FILE__, __LINE__); Slang::ComPtr transientHeap; ITransientResourceHeap::Desc transientHeapDesc = {}; transientHeapDesc.constantBufferSize = 4096; GFX_CHECK_CALL_ABORT( device->createTransientResourceHeap(transientHeapDesc, transientHeap.writeRef())); - + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); // First, load and compile the slang source. ComPtr memoryFileSystem = ComPtr(new Slang::MemoryFileSystem()); @@ -108,6 +121,7 @@ void precompiledModule2TestImplCommon( slang::SessionDesc sessionDesc = {}; sessionDesc.targetCount = 1; slang::TargetDesc targetDesc = {}; + printf("File, Line: %s, %d\n", __FILE__, __LINE__); switch (device->getDeviceInfo().deviceType) { case gfx::DeviceType::DirectX12: @@ -119,11 +133,14 @@ void precompiledModule2TestImplCommon( targetDesc.profile = device->getSlangSession()->getGlobalSession()->findProfile("GLSL_460"); break; } + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); sessionDesc.targets = &targetDesc; sessionDesc.fileSystem = memoryFileSystem.get(); auto globalSession = slangSession->getGlobalSession(); globalSession->createSession(sessionDesc, slangSession.writeRef()); - + printf("File, Line: %s, %d\n", __FILE__, __LINE__); const char* moduleSrc = R"( import "precompiled-module-imported"; @@ -141,6 +158,9 @@ void precompiledModule2TestImplCommon( } )"; memoryFileSystem->saveFile("precompiled-module.slang", moduleSrc, strlen(moduleSrc)); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); GFX_CHECK_CALL_ABORT(loadComputeProgram( device, slangSession, @@ -148,12 +168,18 @@ void precompiledModule2TestImplCommon( "precompiled-module", "computeMain", slangReflection)); - + printf("File, Line: %s, %d\n", __FILE__, __LINE__); ComputePipelineStateDesc pipelineDesc = {}; pipelineDesc.program = shaderProgram.get(); ComPtr pipelineState; + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); GFX_CHECK_CALL_ABORT( device->createComputePipelineState(pipelineDesc, pipelineState.writeRef())); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); const int numberCount = 4; float initialData[] = {0.0f, 0.0f, 0.0f, 0.0f}; @@ -170,8 +196,15 @@ void precompiledModule2TestImplCommon( bufferDesc.memoryType = MemoryType::DeviceLocal; ComPtr numbersBuffer; + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); + GFX_CHECK_CALL_ABORT( device->createBufferResource(bufferDesc, (void*)initialData, numbersBuffer.writeRef())); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); ComPtr bufferView; IResourceView::Desc viewDesc = {}; @@ -179,6 +212,9 @@ void precompiledModule2TestImplCommon( viewDesc.format = Format::Unknown; GFX_CHECK_CALL_ABORT( device->createBufferView(numbersBuffer, nullptr, viewDesc, bufferView.writeRef())); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); // We have done all the set up work, now it is time to start recording a command buffer for // GPU execution. @@ -202,18 +238,32 @@ void precompiledModule2TestImplCommon( queue->executeCommandBuffer(commandBuffer); queue->waitOnHost(); } + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); compareComputeResult(device, numbersBuffer, Slang::makeArray(3.0f, 3.0f, 3.0f, 3.0f)); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); } void precompiledModule2TestImpl(IDevice* device, UnitTestContext* context) { + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); precompiledModule2TestImplCommon(device, context, false); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); } void precompiledTargetModule2TestImpl(IDevice* device, UnitTestContext* context) { - precompiledModule2TestImplCommon(device, context, true); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); + precompiledModule2TestImplCommon(device, context, false); + printf("File, Line: %s, %d\n", __FILE__, __LINE__); + fflush(stdout); } SLANG_UNIT_TEST(precompiledModule2D3D12) @@ -223,6 +273,7 @@ SLANG_UNIT_TEST(precompiledModule2D3D12) SLANG_UNIT_TEST(precompiledTargetModule2D3D12) { + printf("Starting precompiledTargetModule2D3D12\n"); runTestImpl(precompiledTargetModule2TestImpl, unitTestContext, Slang::RenderApiFlag::D3D12); } @@ -233,7 +284,28 @@ SLANG_UNIT_TEST(precompiledModule2Vulkan) SLANG_UNIT_TEST(precompiledTargetModule2Vulkan) { - runTestImpl(precompiledTargetModule2TestImpl, unitTestContext, Slang::RenderApiFlag::Vulkan); + // catch all exceptions + try + { + printf("Starting precompiledTargetModule2Vulkan\n"); + fflush(stdout); + runTestImpl( + precompiledTargetModule2TestImpl, + unitTestContext, + Slang::RenderApiFlag::Vulkan); + printf("Finished precompiledTargetModule2Vulkan\n"); + fflush(stdout); + } + catch (const std::exception&) + { + printf("Caught exception\n"); + fflush(stdout); + } + catch (...) + { + printf("Caught unknown exception\n"); + fflush(stdout); + } } } // namespace gfx_test diff --git a/tools/gfx/d3d12/d3d12-shader-program.cpp b/tools/gfx/d3d12/d3d12-shader-program.cpp index a39f204651..c5fcf75809 100644 --- a/tools/gfx/d3d12/d3d12-shader-program.cpp +++ b/tools/gfx/d3d12/d3d12-shader-program.cpp @@ -10,14 +10,14 @@ using namespace Slang; Result ShaderProgramImpl::createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) + List> kernelCodes) { ShaderBinary shaderBin; shaderBin.stage = entryPointInfo->getStage(); shaderBin.entryPointInfo = entryPointInfo; shaderBin.code.addRange( - reinterpret_cast(kernelCode->getBufferPointer()), - (Index)kernelCode->getBufferSize()); + reinterpret_cast(kernelCodes[0]->getBufferPointer()), + (Index)kernelCodes[0]->getBufferSize()); m_shaders.add(_Move(shaderBin)); return SLANG_OK; } diff --git a/tools/gfx/d3d12/d3d12-shader-program.h b/tools/gfx/d3d12/d3d12-shader-program.h index 669bce960f..fad4e7ad01 100644 --- a/tools/gfx/d3d12/d3d12-shader-program.h +++ b/tools/gfx/d3d12/d3d12-shader-program.h @@ -27,7 +27,7 @@ class ShaderProgramImpl : public ShaderProgramBase virtual Result createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) override; + List> kernelCodes) override; }; } // namespace d3d12 diff --git a/tools/gfx/metal/metal-shader-program.cpp b/tools/gfx/metal/metal-shader-program.cpp index c95e99d047..0bb20740b8 100644 --- a/tools/gfx/metal/metal-shader-program.cpp +++ b/tools/gfx/metal/metal-shader-program.cpp @@ -21,16 +21,16 @@ ShaderProgramImpl::~ShaderProgramImpl() {} Result ShaderProgramImpl::createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) + List> kernelCodes) { Module module; module.stage = entryPointInfo->getStage(); module.entryPointName = entryPointInfo->getNameOverride(); - module.code = kernelCode; + module.code = kernelCodes[0]; dispatch_data_t data = dispatch_data_create( - kernelCode->getBufferPointer(), - kernelCode->getBufferSize(), + kernelCodes[0]->getBufferPointer(), + kernelCodes[0]->getBufferSize(), dispatch_get_main_queue(), NULL); NS::Error* error; diff --git a/tools/gfx/metal/metal-shader-program.h b/tools/gfx/metal/metal-shader-program.h index 691e12c9e4..d5b72d696b 100644 --- a/tools/gfx/metal/metal-shader-program.h +++ b/tools/gfx/metal/metal-shader-program.h @@ -33,7 +33,7 @@ class ShaderProgramImpl : public ShaderProgramBase virtual Result createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) override; + List> kernelCodes) override; }; diff --git a/tools/gfx/renderer-shared.cpp b/tools/gfx/renderer-shared.cpp index 9f5574dccf..9cbdc093a0 100644 --- a/tools/gfx/renderer-shared.cpp +++ b/tools/gfx/renderer-shared.cpp @@ -1103,32 +1103,112 @@ void ShaderProgramBase::init(const IShaderProgram::Desc& inDesc) Result ShaderProgramBase::compileShaders(RendererBase* device) { + // Check target type from RenderBase device + auto compileTarget = device->slangContext.compileTarget; // For a fully specialized program, read and store its kernel code in `shaderProgram`. auto compileShader = [&](slang::EntryPointReflection* entryPointInfo, slang::IComponentType* entryPointComponent, SlangInt entryPointIndex) { auto stage = entryPointInfo->getStage(); - ComPtr kernelCode; - ComPtr diagnostics; - auto compileResult = device->getEntryPointCodeFromShaderCache( - entryPointComponent, - entryPointIndex, - 0, - kernelCode.writeRef(), - diagnostics.writeRef()); - if (diagnostics) + List> kernelCodes; { - DebugMessageType msgType = DebugMessageType::Warning; - if (compileResult != SLANG_OK) - msgType = DebugMessageType::Error; - getDebugCallback()->handleMessage( - msgType, - DebugMessageSource::Slang, - (char*)diagnostics->getBufferPointer()); + ComPtr downstreamIR; + ComPtr diagnostics; + auto compileResult = device->getEntryPointCodeFromShaderCache( + entryPointComponent, + entryPointIndex, + 0, + downstreamIR.writeRef(), + diagnostics.writeRef()); + if (diagnostics) + { + DebugMessageType msgType = DebugMessageType::Warning; + if (compileResult != SLANG_OK) + msgType = DebugMessageType::Error; + getDebugCallback()->handleMessage( + msgType, + DebugMessageSource::Slang, + (char*)diagnostics->getBufferPointer()); + } + kernelCodes.add(downstreamIR); } - SLANG_RETURN_ON_FAIL(compileResult); - SLANG_RETURN_ON_FAIL(createShaderModule(entryPointInfo, kernelCode)); + + // If target precompilation was used, kernelCode may only represent the + // glue code holding together the bits of precompiled target IR. + // Collect those dependency target IRs too. + ComPtr componentPrecompileService; + if (entryPointComponent->queryInterface( + slang::IModulePrecompileService_Experimental::getTypeGuid(), + (void**)componentPrecompileService.writeRef()) == SLANG_OK) + { + SlangInt dependencyCount = componentPrecompileService->getModuleDependencyCount(); + printf("There are %d dependencies\n", dependencyCount); + if (dependencyCount > 0) + { + for (int dependencyIndex = 0; dependencyIndex < dependencyCount; dependencyIndex++) + { + ComPtr dependencyModule; + { + ComPtr diagnosticsBlob; + printf("dependency %d\n", dependencyIndex); + fflush(stdout); + auto result = componentPrecompileService->getModuleDependency( + dependencyIndex, + dependencyModule.writeRef(), + diagnosticsBlob.writeRef()); + printf("not skippt get. did nto crash yet\n"); + fflush(stdout); + if (diagnosticsBlob) + { + DebugMessageType msgType = DebugMessageType::Warning; + if (result != SLANG_OK) + msgType = DebugMessageType::Error; + getDebugCallback()->handleMessage( + msgType, + DebugMessageSource::Slang, + (char*)diagnosticsBlob->getBufferPointer()); + } + SLANG_RETURN_ON_FAIL(result); + } + + ComPtr downstreamIR; + { + ComPtr diagnosticsBlob; + SlangResult result = SLANG_OK; + ComPtr precompileService; + result = dependencyModule->queryInterface( + slang::IModulePrecompileService_Experimental::getTypeGuid(), + (void**)precompileService.writeRef()); + if (result == SLANG_OK) + { + ComPtr diagnosticsBlob; + auto result = precompileService->getPrecompiledTargetCode( + compileTarget, + downstreamIR.writeRef(), + diagnosticsBlob.writeRef()); + if (result == SLANG_OK) + { + kernelCodes.add(downstreamIR); + } + if (diagnosticsBlob) + { + DebugMessageType msgType = DebugMessageType::Warning; + if (result != SLANG_OK) + msgType = DebugMessageType::Error; + getDebugCallback()->handleMessage( + msgType, + DebugMessageSource::Slang, + (char*)diagnosticsBlob->getBufferPointer()); + } + } + SLANG_RETURN_ON_FAIL(result); + } + } + } + } + + SLANG_RETURN_ON_FAIL(createShaderModule(entryPointInfo, kernelCodes)); return SLANG_OK; }; @@ -1160,10 +1240,10 @@ Result ShaderProgramBase::compileShaders(RendererBase* device) Result ShaderProgramBase::createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) + List> kernelCodes) { SLANG_UNUSED(entryPointInfo); - SLANG_UNUSED(kernelCode); + SLANG_UNUSED(kernelCodes); return SLANG_OK; } diff --git a/tools/gfx/renderer-shared.h b/tools/gfx/renderer-shared.h index c763c9ba28..17d3d3fc0e 100644 --- a/tools/gfx/renderer-shared.h +++ b/tools/gfx/renderer-shared.h @@ -877,7 +877,7 @@ class ShaderProgramBase : public IShaderProgram, public Slang::ComObject Slang::Result compileShaders(RendererBase* device); virtual Slang::Result createShaderModule( slang::EntryPointReflection* entryPointInfo, - Slang::ComPtr kernelCode); + Slang::List> kernelCodes); virtual SLANG_NO_THROW slang::TypeReflection* SLANG_MCALL findTypeByName(const char* name) override diff --git a/tools/gfx/slang-context.h b/tools/gfx/slang-context.h index 719c70b506..5494ccfcea 100644 --- a/tools/gfx/slang-context.h +++ b/tools/gfx/slang-context.h @@ -10,6 +10,7 @@ class SlangContext public: Slang::ComPtr globalSession; Slang::ComPtr session; + SlangCompileTarget compileTarget; Result initialize( const gfx::IDevice::SlangDesc& desc, uint32_t extendedDescCount, @@ -27,6 +28,7 @@ class SlangContext SLANG_RETURN_ON_FAIL(slang::createGlobalSession(globalSession.writeRef())); } + this->compileTarget = compileTarget; slang::SessionDesc slangSessionDesc = {}; slangSessionDesc.defaultMatrixLayoutMode = desc.defaultMatrixLayoutMode; slangSessionDesc.searchPathCount = desc.searchPathCount; diff --git a/tools/gfx/vulkan/vk-device.cpp b/tools/gfx/vulkan/vk-device.cpp index cffa094ae7..3d35aee0dc 100644 --- a/tools/gfx/vulkan/vk-device.cpp +++ b/tools/gfx/vulkan/vk-device.cpp @@ -1971,6 +1971,8 @@ Result DeviceImpl::createBufferResourceImpl( VkMemoryPropertyFlags reqMemoryProperties = 0; + printf("File Line function %s %d %d\n", __FILE__, __LINE__, __FUNCTION__); + fflush(stdout); VkBufferUsageFlags usage = _calcBufferUsageFlags(desc.allowedStates) | additionalUsageFlag; if (m_api.m_extendedFeatures.vulkan12Features.bufferDeviceAddress) { @@ -2013,13 +2015,18 @@ Result DeviceImpl::createBufferResourceImpl( reqMemoryProperties, desc.isShared, extMemHandleType)); + printf("File Line function %s %d %d\n", __FILE__, __LINE__, __FUNCTION__); + fflush(stdout); } else { + printf("File Line function %s %d %d\n", __FILE__, __LINE__, __FUNCTION__); + fflush(stdout); SLANG_RETURN_ON_FAIL( buffer->m_buffer.init(m_api, desc.sizeInBytes, usage, reqMemoryProperties)); } - + printf("File Line function %s %d %d\n", __FILE__, __LINE__, __FUNCTION__); + fflush(stdout); if (initData) { if (desc.memoryType == MemoryType::DeviceLocal) @@ -2069,7 +2076,8 @@ Result DeviceImpl::createBufferResourceImpl( m_api.vkUnmapMemory(m_device, buffer->m_buffer.m_memory); } } - + printf("File Line function %s %d %d\n", __FILE__, __LINE__, __FUNCTION__); + fflush(stdout); returnComPtr(outResource, buffer); return SLANG_OK; } diff --git a/tools/gfx/vulkan/vk-shader-program.cpp b/tools/gfx/vulkan/vk-shader-program.cpp index 43a2957866..39d3ac4cb6 100644 --- a/tools/gfx/vulkan/vk-shader-program.cpp +++ b/tools/gfx/vulkan/vk-shader-program.cpp @@ -1,6 +1,7 @@ // vk-shader-program.cpp #include "vk-shader-program.h" +#include "external/spirv-tools/include/spirv-tools/linker.hpp" #include "vk-device.h" #include "vk-util.h" @@ -69,17 +70,62 @@ VkPipelineShaderStageCreateInfo ShaderProgramImpl::compileEntryPoint( return shaderStageCreateInfo; } +static ComPtr LinkUsingSPIRVTools(List> kernelCodes) +{ + spvtools::Context context(SPV_ENV_UNIVERSAL_1_5); + spvtools::LinkerOptions options; + spvtools::MessageConsumer consumer = [](spv_message_level_t level, + const char* source, + const spv_position_t& position, + const char* message) + { + printf("SPIRV-TOOLS: %s\n", message); + printf("SPIRV-TOOLS: %s\n", source); + printf("SPIRV-TOOLS: %zu:%zu\n", position.index, position.column); + }; + context.SetMessageConsumer(consumer); + std::vector binaries; + std::vector binary_sizes; + for (auto kernelCode : kernelCodes) + { + binaries.push_back((uint32_t*)kernelCode->getBufferPointer()); + binary_sizes.push_back(kernelCode->getBufferSize() / sizeof(uint32_t)); + } + + std::vector linked_binary; + + spvtools::Link( + context, + binaries.data(), + binary_sizes.data(), + binaries.size(), + &linked_binary, + options); + + // Create a blob to hold the linked binary + ComPtr linkedKernelCode; + + // Replace kernel code with linked binary + // Creates a new blob with the linked binary + linkedKernelCode = + RawBlob::create(linked_binary.data(), linked_binary.size() * sizeof(uint32_t)); + + return linkedKernelCode; +} + Result ShaderProgramImpl::createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) + List> kernelCodes) { - m_codeBlobs.add(kernelCode); + ComPtr linkedKernel = LinkUsingSPIRVTools(kernelCodes); + m_codeBlobs.add(linkedKernel); + VkShaderModule shaderModule; auto realEntryPointName = entryPointInfo->getNameOverride(); const char* spirvBinaryEntryPointName = "main"; m_stageCreateInfos.add(compileEntryPoint( spirvBinaryEntryPointName, - kernelCode, + linkedKernel, (VkShaderStageFlagBits)VulkanUtil::getShaderStage(entryPointInfo->getStage()), shaderModule)); m_entryPointNames.add(realEntryPointName); diff --git a/tools/gfx/vulkan/vk-shader-program.h b/tools/gfx/vulkan/vk-shader-program.h index 3fd56669ae..0fd01eb4cf 100644 --- a/tools/gfx/vulkan/vk-shader-program.h +++ b/tools/gfx/vulkan/vk-shader-program.h @@ -37,7 +37,7 @@ class ShaderProgramImpl : public ShaderProgramBase virtual Result createShaderModule( slang::EntryPointReflection* entryPointInfo, - ComPtr kernelCode) override; + List> kernelCodes) override; }; diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index 5db82fcb7a..5e1304259e 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -2685,6 +2685,8 @@ static TestResult runCPPCompilerSharedLibrary(TestContext* context, TestInput& i printf("Unable to access 'test' function\n"); } + printf("Unload handle\n"); + fflush(stdout); SharedLibrary::unload(handle); if (!(inValue == value && strcmp(inBuffer, buffer) == 0)) @@ -4544,21 +4546,32 @@ static SlangResult runUnitTestModule( SpawnType spawnType, const char* moduleName) { + printf("about to loadSharedLIbrayr FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); ISlangSharedLibraryLoader* loader = DefaultSharedLibraryLoader::getSingleton(); ComPtr moduleLibrary; SLANG_RETURN_ON_FAIL(loader->loadSharedLibrary( Path::combine(context->dllDirectoryPath, moduleName).getBuffer(), moduleLibrary.writeRef())); - + printf("FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); UnitTestGetModuleFunc getModuleFunc = (UnitTestGetModuleFunc)moduleLibrary->findFuncByName("slangUnitTestGetModule"); if (!getModuleFunc) return SLANG_FAIL; + printf("FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); IUnitTestModule* testModule = getModuleFunc(); if (!testModule) return SLANG_FAIL; + printf("FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); UnitTestContext unitTestContext; unitTestContext.slangGlobalSession = context->getSession(); @@ -4595,6 +4608,10 @@ static SlangResult runUnitTestModule( } } } + printf("4601 FILE LINE: %s %d\n", __FILE__, __LINE__); + printf("FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); auto runUnitTest = [&](TestItem test) { @@ -4613,6 +4630,7 @@ static SlangResult runUnitTestModule( { TestReporter::TestScope scopeTest(reporter, options.command); ExecuteResult exeRes; + printf("RPC FILE LINE: %s %d\n", __FILE__, __LINE__); SlangResult rpcRes = _executeRPC( context, @@ -4620,7 +4638,9 @@ static SlangResult runUnitTestModule( TestServerProtocol::ExecuteUnitTestArgs::g_methodName, &args, exeRes); + printf("2RPC FILE LINE: %s %d\n", __FILE__, __LINE__); const auto testResult = _asTestResult(ToolReturnCode(exeRes.resultCode)); + printf("2RPC FILE LINE: %s %d\n", __FILE__, __LINE__); // If the test fails, output any output - which might give information about // individual tests that have failed. @@ -4642,7 +4662,17 @@ static SlangResult runUnitTestModule( testModule->setTestReporter(reporter); try { + printf("ft1 FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); + printf("TF FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); test.testFunc(&unitTestContext); + printf("TF2 FILE LINE: %s %d\n", __FILE__, __LINE__); + printf("FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); } catch (...) { @@ -4677,10 +4707,19 @@ static SlangResult runUnitTestModule( testModule->setTestReporter(reporter); for (auto t : tests) + { + printf("A Run unit test file %s line %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); runUnitTest(t); + printf("B Ran unit test file %s line %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); + } } testModule->destroy(); + printf("Done run unit tests file %s line %d\n", __FILE__, __LINE__); return SLANG_OK; } @@ -4734,20 +4773,23 @@ SlangResult innerMain(int argc, char** argv) TestCategory* passThroughCategories[SLANG_PASS_THROUGH_COUNT_OF] = {nullptr}; // Work out what backends/pass-thrus are available + auto out = StdWriters::getOut(); { SlangSession* session = context.getSession(); - auto out = StdWriters::getOut(); + out.print("Supported backends:"); for (int i = 0; i < SLANG_PASS_THROUGH_COUNT_OF; ++i) { + out.print("4780 abc FILE LINE: %s %d\n", __FILE__, __LINE__); + const SlangPassThrough passThru = SlangPassThrough(i); if (passThru == SLANG_PASS_THROUGH_NONE) { continue; } - + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); if (SLANG_SUCCEEDED(session->checkPassThroughSupport(passThru))) { context.availableBackendFlags |= PassThroughFlags(1) << int(i); @@ -4764,18 +4806,20 @@ SlangResult innerMain(int argc, char** argv) out.write(buf.getBuffer(), buf.getLength()); } } - + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); out.print("\n"); } - + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); { + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); SlangSession* session = context.getSession(); - + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); const bool hasLlvm = SLANG_SUCCEEDED(session->checkPassThroughSupport(SLANG_PASS_THROUGH_LLVM)); const auto hostCallableCompiler = session->getDownstreamCompilerForTransition( SLANG_CPP_SOURCE, SLANG_SHADER_HOST_CALLABLE); + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); if (hasLlvm && hostCallableCompiler == SLANG_PASS_THROUGH_LLVM && SLANG_PROCESSOR_X86) { @@ -4788,7 +4832,9 @@ SlangResult innerMain(int argc, char** argv) // double (ie not x86/llvm) categorySet.add("war-double-host-callable", fullTestCategory); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); // Working out what renderApis is worked on on demand through // _getAvailableRenderApiFlags() @@ -4797,16 +4843,21 @@ SlangResult innerMain(int argc, char** argv) // We can set the slangc command line tool, to just use the function defined here context.setInnerMainFunc("slangc", &SlangCTool::innerMain); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); SLANG_RETURN_ON_FAIL( Options::parse(argc, argv, &categorySet, StdWriters::getError(), &context.options)); + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); Options& options = context.options; + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); context.setMaxTestRunnerThreadCount(options.serverCount); + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); // Set up the prelude/s TestToolUtil::setSessionDefaultPreludeFromExePath(argv[0], context.getSession()); + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); if (options.outputMode == TestOutputMode::TeamCity) { @@ -4818,15 +4869,19 @@ SlangResult innerMain(int argc, char** argv) _disableCPPBackends(&context); #endif } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); #if SLANG_PROCESSOR_X86 // Disable d3d12 tests on x86 right now since dxc for 32-bit windows doesn't seem to recognize // sm_6_6. _disableD3D12Backend(&context); #endif + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); if (options.subCommand.getLength()) { + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); + // Get the function from the tool auto func = context.getInnerMainFunc(options.binDir, options.subCommand); if (!func) @@ -4852,17 +4907,20 @@ SlangResult innerMain(int argc, char** argv) int(args.getCount()), args.getBuffer()); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); if (options.includeCategories.getCount() == 0) { options.includeCategories.add(fullTestCategory, fullTestCategory); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); // Don't include OptiX tests unless the client has explicit opted into them. if (!options.includeCategories.containsKey(optixTestCategory)) { options.excludeCategories.add(optixTestCategory, optixTestCategory); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); // Exclude rendering tests when building under AppVeyor. // @@ -4889,6 +4947,7 @@ SlangResult innerMain(int argc, char** argv) // Enumerate test files according to policy runTestsInDirectory(&context); } + out.print("FILE LINE: %s %d\n", __FILE__, __LINE__); // Run the unit tests (these are internal C++ tests - not specified via files in a // directory) They are registered with SLANG_UNIT_TEST macro @@ -4906,17 +4965,29 @@ SlangResult innerMain(int argc, char** argv) TestOptions testOptions; testOptions.categories.add(unitTestCategory); testOptions.categories.add(smokeTestCategory); + out.print("in slang-unit-test-tool FILE LINE: %s %d\n", __FILE__, __LINE__); runUnitTestModule(&context, testOptions, spawnType, "slang-unit-test-tool"); + out.print("out slang-unit-test-tool FILE LINE: %s %d\n", __FILE__, __LINE__); } + out.print("4932 FILE LINE: %s %d\n", __FILE__, __LINE__); { TestOptions testOptions; testOptions.categories.add(unitTestCategory); + out.print("in gfx-unit-test-tool FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); runUnitTestModule(&context, testOptions, spawnType, "gfx-unit-test-tool"); + out.print("out gfx-unit-test-tool FILE LINE: %s %d\n", __FILE__, __LINE__); + fflush(stdout); + fflush(stderr); } + out.print("4939 FILE LINE: %s %d\n", __FILE__, __LINE__); + TestReporter::set(nullptr); } + out.print("4941 FILE LINE: %s %d\n", __FILE__, __LINE__); // If we have a couple failed tests, they maybe intermittent failures due to parallel // excution or driver instability. We can try running them again. @@ -4950,10 +5021,12 @@ SlangResult innerMain(int argc, char** argv) reporter.addResult(TestResult::Fail); } } + out.print("4975 FILE LINE: %s %d\n", __FILE__, __LINE__); reporter.outputSummary(); return reporter.didAllSucceed() ? SLANG_OK : SLANG_FAIL; } + out.print("4980 FILE LINE: %s %d\n", __FILE__, __LINE__); } int main(int argc, char** argv)