@@ -273,7 +273,8 @@ core::smart_refctd_ptr<IGPUBufferView> ILogicalDevice::createBufferView(const as
273273 return createBufferView_impl (underlying,_fmt);
274274}
275275
276- core::smart_refctd_ptr<IGPUShader> ILogicalDevice::createShader (const SShaderCreationParameters& creationParams)
276+
277+ core::smart_refctd_ptr<asset::ICPUShader> ILogicalDevice::compileShader (const SShaderCreationParameters& creationParams)
277278{
278279 if (!creationParams.cpushader )
279280 {
@@ -291,92 +292,87 @@ core::smart_refctd_ptr<IGPUShader> ILogicalDevice::createShader(const SShaderCre
291292 // https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPipelineShaderStageCreateInfo.html#VUID-VkPipelineShaderStageCreateInfo-stage-00706
292293 switch (shaderStage)
293294 {
294- case IGPUShader::E_SHADER_STAGE::ESS_TESSELLATION_CONTROL: [[fallthrough]];
295- case IGPUShader::E_SHADER_STAGE::ESS_TESSELLATION_EVALUATION:
296- if (!features.tessellationShader )
297- {
298- NBL_LOG_ERROR (" Cannot create IGPUShader for %p, Tessellation Shader feature not enabled!" , creationParams.cpushader );
299- return nullptr ;
300- }
301- break ;
302- case IGPUShader::E_SHADER_STAGE::ESS_GEOMETRY:
303- if (!features.geometryShader )
304- {
305- NBL_LOG_ERROR (" Cannot create IGPUShader for %p, Geometry Shader feature not enabled!" , creationParams.cpushader );
306- return nullptr ;
307- }
308- break ;
309- case IGPUShader::E_SHADER_STAGE::ESS_ALL_OR_LIBRARY: [[fallthrough]];
310- case IGPUShader::E_SHADER_STAGE::ESS_VERTEX: [[fallthrough]];
311- case IGPUShader::E_SHADER_STAGE::ESS_FRAGMENT: [[fallthrough]];
312- case IGPUShader::E_SHADER_STAGE::ESS_COMPUTE:
313- break ;
314- // unsupported yet
315- case IGPUShader::E_SHADER_STAGE::ESS_TASK: [[fallthrough]];
316- case IGPUShader::E_SHADER_STAGE::ESS_MESH:
317- NBL_LOG_ERROR (" Unsupported (yet) shader stage" );
295+ case IGPUShader::E_SHADER_STAGE::ESS_TESSELLATION_CONTROL: [[fallthrough]];
296+ case IGPUShader::E_SHADER_STAGE::ESS_TESSELLATION_EVALUATION:
297+ if (!features.tessellationShader )
298+ {
299+ NBL_LOG_ERROR (" Cannot create IGPUShader for %p, Tessellation Shader feature not enabled!" , creationParams.cpushader );
318300 return nullptr ;
319- break ;
320- case IGPUShader::E_SHADER_STAGE::ESS_RAYGEN: [[fallthrough]];
321- case IGPUShader::E_SHADER_STAGE::ESS_ANY_HIT: [[fallthrough]];
322- case IGPUShader::E_SHADER_STAGE::ESS_CLOSEST_HIT: [[fallthrough]];
323- case IGPUShader::E_SHADER_STAGE::ESS_MISS: [[fallthrough]];
324- case IGPUShader::E_SHADER_STAGE::ESS_INTERSECTION: [[fallthrough]];
325- case IGPUShader::E_SHADER_STAGE::ESS_CALLABLE:
326- if (!features.rayTracingPipeline )
327- {
328- NBL_LOG_ERROR (" Cannot create IGPUShader for %p, Raytracing Pipeline feature not enabled!" , creationParams.cpushader );
329- return nullptr ;
330- }
331- break ;
332- default :
333- // Implicit unsupported stages or weird multi-bit stage enum values
334- NBL_LOG_ERROR (" Unknown Shader Stage %d" , shaderStage);
301+ }
302+ break ;
303+ case IGPUShader::E_SHADER_STAGE::ESS_GEOMETRY:
304+ if (!features.geometryShader )
305+ {
306+ NBL_LOG_ERROR (" Cannot create IGPUShader for %p, Geometry Shader feature not enabled!" , creationParams.cpushader );
335307 return nullptr ;
336- break ;
308+ }
309+ break ;
310+ case IGPUShader::E_SHADER_STAGE::ESS_ALL_OR_LIBRARY: [[fallthrough]];
311+ case IGPUShader::E_SHADER_STAGE::ESS_VERTEX: [[fallthrough]];
312+ case IGPUShader::E_SHADER_STAGE::ESS_FRAGMENT: [[fallthrough]];
313+ case IGPUShader::E_SHADER_STAGE::ESS_COMPUTE:
314+ break ;
315+ // unsupported yet
316+ case IGPUShader::E_SHADER_STAGE::ESS_TASK: [[fallthrough]];
317+ case IGPUShader::E_SHADER_STAGE::ESS_MESH:
318+ NBL_LOG_ERROR (" Unsupported (yet) shader stage" );
319+ return nullptr ;
320+ break ;
321+ case IGPUShader::E_SHADER_STAGE::ESS_RAYGEN: [[fallthrough]];
322+ case IGPUShader::E_SHADER_STAGE::ESS_ANY_HIT: [[fallthrough]];
323+ case IGPUShader::E_SHADER_STAGE::ESS_CLOSEST_HIT: [[fallthrough]];
324+ case IGPUShader::E_SHADER_STAGE::ESS_MISS: [[fallthrough]];
325+ case IGPUShader::E_SHADER_STAGE::ESS_INTERSECTION: [[fallthrough]];
326+ case IGPUShader::E_SHADER_STAGE::ESS_CALLABLE:
327+ if (!features.rayTracingPipeline )
328+ {
329+ NBL_LOG_ERROR (" Cannot create IGPUShader for %p, Raytracing Pipeline feature not enabled!" , creationParams.cpushader );
330+ return nullptr ;
331+ }
332+ break ;
333+ default :
334+ // Implicit unsupported stages or weird multi-bit stage enum values
335+ NBL_LOG_ERROR (" Unknown Shader Stage %d" , shaderStage);
336+ return nullptr ;
337+ break ;
337338 }
338339
339- core::smart_refctd_ptr<const asset::ICPUShader> spirvShader;
340- if (creationParams.cpushader ->getContentType ()==asset::ICPUShader::E_CONTENT_TYPE::ECT_SPIRV)
341- spirvShader = core::smart_refctd_ptr<const asset::ICPUShader>(creationParams.cpushader );
342- else
343- {
344- auto compiler = m_compilerSet->getShaderCompiler (creationParams.cpushader ->getContentType ());
340+ core::smart_refctd_ptr<asset::ICPUShader> spirvShader;
341+ auto compiler = m_compilerSet->getShaderCompiler (creationParams.cpushader ->getContentType ());
345342
346- asset::IShaderCompiler::SCompilerOptions commonCompileOptions = {};
343+ asset::IShaderCompiler::SCompilerOptions commonCompileOptions = {};
347344
348- commonCompileOptions.preprocessorOptions .logger = m_physicalDevice->getDebugCallback () ? m_physicalDevice->getDebugCallback ()->getLogger (): nullptr ;
349- commonCompileOptions.preprocessorOptions .includeFinder = compiler->getDefaultIncludeFinder (); // to resolve includes before compilation
350- commonCompileOptions.preprocessorOptions .sourceIdentifier = creationParams.cpushader ->getFilepathHint ().c_str ();
351- commonCompileOptions.preprocessorOptions .extraDefines = {};
345+ commonCompileOptions.preprocessorOptions .logger = m_physicalDevice->getDebugCallback () ? m_physicalDevice->getDebugCallback ()->getLogger () : nullptr ;
346+ commonCompileOptions.preprocessorOptions .includeFinder = compiler->getDefaultIncludeFinder (); // to resolve includes before compilation
347+ commonCompileOptions.preprocessorOptions .sourceIdentifier = creationParams.cpushader ->getFilepathHint ().c_str ();
348+ commonCompileOptions.preprocessorOptions .extraDefines = {};
352349
353- commonCompileOptions.stage = shaderStage;
354- commonCompileOptions.debugInfoFlags =
355- asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT |
356- asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT;
357- commonCompileOptions.spirvOptimizer = creationParams.optimizer ;
358- commonCompileOptions.targetSpirvVersion = m_physicalDevice->getLimits ().spirvVersion ;
350+ commonCompileOptions.stage = shaderStage;
351+ commonCompileOptions.debugInfoFlags =
352+ asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_SOURCE_BIT |
353+ asset::IShaderCompiler::E_DEBUG_INFO_FLAGS::EDIF_TOOL_BIT;
354+ commonCompileOptions.spirvOptimizer = creationParams.optimizer ;
355+ commonCompileOptions.targetSpirvVersion = m_physicalDevice->getLimits ().spirvVersion ;
359356
360- commonCompileOptions.readCache = creationParams.readCache ;
361- commonCompileOptions.writeCache = creationParams.writeCache ;
357+ commonCompileOptions.readCache = creationParams.readCache ;
358+ commonCompileOptions.writeCache = creationParams.writeCache ;
362359
363- if (creationParams.cpushader ->getContentType () == asset::ICPUShader::E_CONTENT_TYPE::ECT_HLSL)
364- {
365- // TODO: add specific HLSLCompiler::SOption params
366- spirvShader = m_compilerSet->compileToSPIRV (creationParams.cpushader , commonCompileOptions);
367- }
368- else if (creationParams.cpushader ->getContentType () == asset::ICPUShader::E_CONTENT_TYPE::ECT_GLSL)
369- {
370- spirvShader = m_compilerSet->compileToSPIRV (creationParams.cpushader , commonCompileOptions);
371- }
372- else
373- spirvShader = m_compilerSet->compileToSPIRV (creationParams.cpushader , commonCompileOptions);
360+ if (creationParams.cpushader ->getContentType () == asset::ICPUShader::E_CONTENT_TYPE::ECT_HLSL)
361+ {
362+ // TODO: add specific HLSLCompiler::SOption params
363+ spirvShader = m_compilerSet->compileToSPIRV (creationParams.cpushader , commonCompileOptions);
364+ }
365+ else if (creationParams.cpushader ->getContentType () == asset::ICPUShader::E_CONTENT_TYPE::ECT_GLSL)
366+ {
367+ spirvShader = m_compilerSet->compileToSPIRV (creationParams.cpushader , commonCompileOptions);
368+ }
369+ else
370+ spirvShader = m_compilerSet->compileToSPIRV (creationParams.cpushader , commonCompileOptions);
374371
375- if (!spirvShader)
376- {
377- NBL_LOG_ERROR (" SPIR-V Compilation from non SPIR-V shader %p failed" , creationParams.cpushader );
378- return nullptr ;
379- }
372+ if (!spirvShader)
373+ {
374+ NBL_LOG_ERROR (" SPIR-V Compilation from non SPIR-V shader %p failed" , creationParams.cpushader );
375+ return nullptr ;
380376 }
381377
382378 auto spirv = spirvShader->getContent ();
@@ -390,20 +386,29 @@ core::smart_refctd_ptr<IGPUShader> ILogicalDevice::createShader(const SShaderCre
390386 if constexpr (true )
391387 {
392388 system::ISystem::future_t <core::smart_refctd_ptr<system::IFile>> future;
393- m_physicalDevice->getSystem ()->createFile (future,system::path (creationParams.cpushader ->getFilepathHint ()).parent_path ()/ " compiled.spv" ,system::IFileBase::ECF_WRITE);
394- if (auto file= future.acquire (); file&& bool (*file))
389+ m_physicalDevice->getSystem ()->createFile (future, system::path (creationParams.cpushader ->getFilepathHint ()).parent_path () / " compiled.spv" , system::IFileBase::ECF_WRITE);
390+ if (auto file = future.acquire (); file && bool (*file))
395391 {
396392 system::IFile::success_t succ;
397- (*file)->write (succ,spirv->getPointer (),0 , spirv->getSize ());
393+ (*file)->write (succ, spirv->getPointer (), 0 , spirv->getSize ());
398394 succ.getBytesProcessed (true );
399395 }
400396 }
401397
402- auto retval = createShader_impl (spirvShader.get ());
398+ return spirvShader;
399+ }
400+
401+ core::smart_refctd_ptr<IGPUShader> ILogicalDevice::createShader (const SShaderCreationParameters& creationParams)
402+ {
403+ auto spirvShader = core::smart_refctd_ptr<const asset::ICPUShader>(creationParams.cpushader );
404+ if (creationParams.cpushader ->getContentType () != asset::ICPUShader::E_CONTENT_TYPE::ECT_SPIRV)
405+ spirvShader = compileShader (creationParams);
406+
407+ auto shader = createShader_impl (spirvShader.get ());
403408 const auto path = creationParams.cpushader ->getFilepathHint ();
404- if (retval && !path.empty ())
405- retval ->setObjectDebugName (path.c_str ());
406- return retval ;
409+ if (shader && !path.empty ())
410+ shader ->setObjectDebugName (path.c_str ());
411+ return shader ;
407412}
408413
409414core::smart_refctd_ptr<IGPUShader> ILogicalDevice::createShader (const asset::ICPUShader* cpushader, const asset::ISPIRVOptimizer* optimizer)
0 commit comments