yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
43d0c2100
master
1#if 0 2// Duplicated: This test is identical to slang-rhi\tests\test-precompiled-module-cache.cpp 3// TODO_TESTING port 4 5#include "core/slang-basic.h" 6#include "core/slang-blob.h" 7#include "core/slang-io.h" 8#include "core/slang-memory-file-system.h" 9#include "gfx-test-util.h" 10#include "slang-rhi.h" 11#include "slang-rhi/shader-cursor.h" 12#include "unit-test/slang-unit-test.h" 13 14using namespace rhi ; 15 16namespace gfx_test 17{ 18// Test that mixing precompiled and non-precompiled modules is working. 19 20static Slang ::Result precompileProgram ( 21 rhi::IDevice * device , 22ISlangMutableFileSystem * fileSys , 23const char * shaderModuleName , 24PrecompilationMode precompilationMode ) 25{ 26Slang ::ComPtr < slang::ISession > slangSession ; 27SLANG_RETURN_ON_FAIL (device -> getSlangSession (slangSession .writeRef ())); 28 slang::SessionDesc sessionDesc = {}; 29auto searchPaths = getSlangSearchPaths (); 30sessionDesc .searchPathCount = searchPaths .getCount (); 31sessionDesc .searchPaths = searchPaths .getBuffer (); 32auto globalSession = slangSession -> getGlobalSession (); 33globalSession -> createSession (sessionDesc ,slangSession .writeRef ()); 34 35 slang::IModule * module ; 36 { 37Slang ::ComPtr < slang::IBlob > diagnosticsBlob ; 38module = slangSession -> loadModule (shaderModuleName ,diagnosticsBlob .writeRef ()); 39diagnoseIfNeeded (diagnosticsBlob ); 40 } 41if (!module ) 42return SLANG_FAIL ; 43 44if (precompilationMode == PrecompilationMode ::InternalLink || 45precompilationMode == PrecompilationMode ::ExternalLink ) 46 { 47SlangCompileTarget target ; 48switch (device -> getInfo ().deviceType ) 49 { 50case rhi::DeviceType ::D3D12 : 51target = SLANG_DXIL ; 52break ; 53case rhi::DeviceType ::Vulkan : 54target = SLANG_SPIRV ; 55break ; 56default : 57return SLANG_FAIL ; 58 } 59 60ComPtr < slang::IModulePrecompileService_Experimental > precompileService ; 61if (module -> queryInterface ( 62 slang::SLANG_UUID_IModulePrecompileService_Experimental , 63 (void ** )precompileService .writeRef ())== SLANG_OK ) 64 { 65Slang ::ComPtr < slang::IBlob > diagnosticsBlob ; 66auto res = precompileService -> precompileForTarget (target ,diagnosticsBlob .writeRef ()); 67diagnoseIfNeeded (diagnosticsBlob ); 68SLANG_RETURN_ON_FAIL (res ); 69 70// compile a second time to check for driver bugs. 71diagnosticsBlob = nullptr ; 72res = precompileService -> precompileForTarget (target ,diagnosticsBlob .writeRef ()); 73diagnoseIfNeeded (diagnosticsBlob ); 74SLANG_RETURN_ON_FAIL (res ); 75 } 76 } 77 78// Write loaded modules to file system. 79for (SlangInt i = 0 ;i < slangSession -> getLoadedModuleCount ();i ++ ) 80 { 81auto module = slangSession -> getLoadedModule (i ); 82auto path = module -> getFilePath (); 83if (path ) 84 { 85auto name = module -> getName (); 86ComPtr < ISlangBlob > outBlob ; 87module -> serialize (outBlob .writeRef ()); 88fileSys -> saveFileBlob ((Slang ::String (name )+ ".slang-module" ).getBuffer (),outBlob ); 89 } 90 } 91return SLANG_OK ; 92} 93 94void precompiledModule2TestImplCommon ( 95IDevice * device , 96UnitTestContext * context , 97PrecompilationMode precompilationMode ) 98{ 99// First, load and compile the slang source. 100ComPtr < ISlangMutableFileSystem > memoryFileSystem = 101ComPtr < ISlangMutableFileSystem > (new Slang ::MemoryFileSystem ()); 102 103ComPtr < IShaderProgram > shaderProgram ; 104 slang::ProgramLayout * slangReflection ; 105GFX_CHECK_CALL_ABORT (precompileProgram ( 106device , 107memoryFileSystem .get (), 108"precompiled-module-imported" , 109precompilationMode )); 110 111// Next, load the precompiled slang program. 112Slang ::ComPtr < slang::ISession > slangSession ; 113device -> getSlangSession (slangSession .writeRef ()); 114 slang::SessionDesc sessionDesc = {}; 115sessionDesc .targetCount = 1 ; 116 slang::TargetDesc targetDesc = {}; 117switch (device -> getInfo ().deviceType ) 118 { 119case rhi::DeviceType ::D3D12 : 120targetDesc .format = SLANG_DXIL ; 121targetDesc .profile = device -> getSlangSession ()-> getGlobalSession ()-> findProfile ("sm_6_6" ); 122break ; 123case rhi::DeviceType ::Vulkan : 124targetDesc .format = SLANG_SPIRV ; 125targetDesc .profile = device -> getSlangSession ()-> getGlobalSession ()-> findProfile ("GLSL_460" ); 126break ; 127 } 128sessionDesc .targets = & targetDesc ; 129sessionDesc .fileSystem = memoryFileSystem .get (); 130 131Slang ::List < slang::CompilerOptionEntry > options ; 132 slang::CompilerOptionEntry skipDownstreamLinkingOption ; 133skipDownstreamLinkingOption .name = slang::CompilerOptionName ::SkipDownstreamLinking ; 134skipDownstreamLinkingOption .value .kind = slang::CompilerOptionValueKind ::Int ; 135skipDownstreamLinkingOption .value .intValue0 = 136precompilationMode == PrecompilationMode ::ExternalLink ; 137options .add (skipDownstreamLinkingOption ); 138 139sessionDesc .compilerOptionEntries = options .getBuffer (); 140sessionDesc .compilerOptionEntryCount = options .getCount (); 141auto globalSession = slangSession -> getGlobalSession (); 142globalSession -> createSession (sessionDesc ,slangSession .writeRef ()); 143 144const char * moduleSrc = R"( 145import "precompiled-module-imported"; 146 147// Main entry-point. 148 149using namespace ns; 150 151[shader("compute")] 152[numthreads(4, 1, 1)] 153void computeMain( 154uint3 sv_dispatchThreadID : SV_DispatchThreadID, 155uniform RWStructuredBuffer <float> buffer) 156{ 157buffer[sv_dispatchThreadID.x] = helperFunc() + helperFunc1(); 158} 159)" ; 160memoryFileSystem -> saveFile ("precompiled-module.slang" ,moduleSrc ,strlen (moduleSrc )); 161GFX_CHECK_CALL_ABORT (loadComputeProgram ( 162device , 163slangSession , 164shaderProgram , 165"precompiled-module" , 166"computeMain" , 167slangReflection , 168precompilationMode )); 169 170ComputePipelineDesc pipelineDesc = {}; 171pipelineDesc .program = shaderProgram .get (); 172ComPtr < rhi::IComputePipeline > pipeline = device -> createComputePipeline (pipelineDesc ); 173const int numberCount = 4 ; 174float initialData []= {0.0f ,0.0f ,0.0f ,0.0f }; 175BufferDesc bufferDesc = {}; 176bufferDesc .size = numberCount * sizeof (float ); 177bufferDesc .format = rhi::Format ::Undefined ; 178bufferDesc .elementSize = sizeof (float ); 179bufferDesc .defaultState = ResourceState ::UnorderedAccess ; 180bufferDesc .memoryType = MemoryType ::DeviceLocal ; 181 182ComPtr < IBuffer > numbersBuffer ; 183GFX_CHECK_CALL_ABORT ( 184device -> createBuffer (bufferDesc , (void * )initialData ,numbersBuffer .writeRef ())); 185 186// We have done all the set up work, now it is time to start recording a command buffer for 187// GPU execution. 188 { 189auto queue = device -> getQueue (QueueType ::Graphics ); 190 191auto commandBuffer = queue -> createCommandEncoder (); 192auto encoder = commandBuffer -> beginComputePass (); 193 194auto rootObject = encoder -> bindPipeline (pipeline ); 195 196ShaderCursor entryPointCursor ( 197rootObject -> getEntryPoint (0 ));// get a cursor the the first entry-point. 198// Bind buffer view to the entry point. 199entryPointCursor .getPath ("buffer" ).setBinding (numbersBuffer ); 200 201encoder -> dispatchCompute (1 ,1 ,1 ); 202encoder -> end (); 203queue -> submit (commandBuffer -> finish ()); 204queue -> waitOnHost (); 205 } 206 207compareComputeResult (device ,numbersBuffer , std::array {3.0f ,3.0f ,3.0f ,3.0f }); 208} 209 210void precompiledModule2TestImpl (IDevice * device ,UnitTestContext * context ) 211{ 212precompiledModule2TestImplCommon (device ,context ,PrecompilationMode ::SlangIR ); 213} 214 215void precompiledTargetModule2InternalLinkTestImpl (IDevice * device ,UnitTestContext * context ) 216{ 217precompiledModule2TestImplCommon (device ,context ,PrecompilationMode ::InternalLink ); 218} 219 220void precompiledTargetModule2ExternalLinkTestImpl (IDevice * device ,UnitTestContext * context ) 221{ 222precompiledModule2TestImplCommon (device ,context ,PrecompilationMode ::ExternalLink ); 223} 224 225SLANG_UNIT_TEST (precompiledModule2D3D12 ) 226{ 227runTestImpl (precompiledModule2TestImpl ,unitTestContext ,DeviceType ::D3D12 ); 228} 229 230SLANG_UNIT_TEST (precompiledTargetModuleInternalLink2D3D12 ) 231{ 232runTestImpl ( 233precompiledTargetModule2InternalLinkTestImpl , 234unitTestContext , 235DeviceType ::D3D12 ); 236} 237 238/* 239// Unavailable on D3D12/DXIL currently 240SLANG_UNIT_TEST(precompiledTargetModuleExternalLink2D3D12) 241{ 242runTestImpl(precompiledTargetModule2ExternalLinkTestImpl, unitTestContext, 243DeviceType::D3D12); 244} 245*/ 246 247SLANG_UNIT_TEST (precompiledModule2Vulkan ) 248{ 249runTestImpl (precompiledModule2TestImpl ,unitTestContext ,DeviceType ::Vulkan ); 250} 251 252SLANG_UNIT_TEST (precompiledTargetModule2InternalLinkVulkan ) 253{ 254runTestImpl ( 255precompiledTargetModule2InternalLinkTestImpl , 256unitTestContext , 257DeviceType ::Vulkan ); 258} 259 260SLANG_UNIT_TEST (precompiledTargetModule2ExternalLinkVulkan ) 261{ 262runTestImpl ( 263precompiledTargetModule2ExternalLinkTestImpl , 264unitTestContext , 265DeviceType ::Vulkan ); 266} 267 268}// namespace gfx_test 269 270#endif