30#include <vulkan/vulkan.hpp>
87 namespace Preprocessor
117 static char*
Input(
char* buffer,
const int size,
void* userData )
noexcept
126 if ( ch ==
'\n' || i == size )
139 static_cast<WorkData*
>(userData)->_output +=
static_cast<char>(ch);
142 static char*
Scratch(
const std::string_view fileName )
145 strncpy( result, fileName.data(),fileName.size() );
151 static void Error(
void* userData,
const char* format, va_list args )
156 const size_t length =
to_size(vsnprintf(
nullptr, 0, format, args ) + 1);
157 message.resize( length );
158 vsnprintf( message.data(), length, format, args );
167 if ( !message.empty() )
180 const auto setTag = [](
const int tag,
void* value )
187 const auto setFlag = [](
const int tag,
bool flag )
189 static bool data =
true;
192 g_tagHead->data = (flag ? &data :
nullptr);
196 setFlag( FPPTAG_KEEPCOMMENTS,
true );
197 setFlag( FPPTAG_IGNORE_NONFATAL,
false );
198 setFlag( FPPTAG_IGNORE_CPLUSPLUS,
false );
199 setFlag( FPPTAG_LINE,
false );
200 setFlag( FPPTAG_WARNILLEGALCPP,
false );
201 setFlag( FPPTAG_OUTPUTLINE,
false );
202 setFlag( FPPTAG_IGNOREVERSION,
false );
203 setFlag( FPPTAG_OUTPUTINCLUDES,
false );
204 setFlag( FPPTAG_OUTPUTBALANCE,
true );
205 setFlag( FPPTAG_OUTPUTSPACE,
true );
206 setFlag( FPPTAG_NESTED_COMMENTS,
true );
207 setFlag( FPPTAG_WARN_NESTED_COMMENTS,
false );
208 setFlag( FPPTAG_WARNMISSINCLUDE,
false );
209 setFlag( FPPTAG_RIGHTCONCAT,
true );
210 setFlag( FPPTAG_DISPLAYFUNCTIONS,
false );
211 setFlag( FPPTAG_WEBMODE,
false );
224 if ( sourceInOut.empty() )
236 tagptr->tag = FPPTAG_INPUT_NAME;
240 tagptr->tag = FPPTAG_END;
241 tagptr->data =
nullptr;
245 if ( fppPreProcess(
g_tags ) == 0 )
276 return (
s_targetVulkan ? Paths::Shaders::g_cacheLocationVK : Paths::Shaders::g_cacheLocationGL);
281 return Paths::Shaders::g_cacheLocation / Paths::g_buildTypeLocation;
306 return ResourcePath{ fileName +
"." + Paths::Shaders::g_SPIRVExt.c_str() };
311 return ResourcePath { fileName +
"." + Paths::Shaders::g_ReflectionExt.c_str() };
325 U64 lastWriteTime = 0u, lastWriteTimeCache = 0u;
326 const ResourcePath sourceShaderFullPath = Paths::Shaders::GLSL::g_GLSLShaderLoc / sourceFileName;
327 if (
fileLastWriteTime( sourceShaderFullPath, lastWriteTime ) != FileError::NONE )
342 lastWriteTimeCache < lastWriteTime ||
353 FileError err = FileError::NONE;
362 return err == FileError::NONE || err == FileError::FILE_NOT_FOUND;
384 const auto AppendToShaderHeader = [](
const ShaderType type,
const string&
entry )
389 const auto AppendResourceBindingSlots = [&AppendToShaderHeader](
const bool targetOpenGL )
394 const auto ApplyDescriptorSetDefines = [&AppendToShaderHeader](
const DescriptorSetUsage setUsage )
410 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE(SET, BINDING) layout(binding = CONCATENATE(SET, BINDING))" );
411 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE_OFFSET(SET, BINDING, OFFSET) layout(binding = CONCATENATE(SET, BINDING), offset = OFFSET)" );
412 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE_LAYOUT(SET, BINDING, LAYOUT) layout(binding = CONCATENATE(SET, BINDING), LAYOUT)" );
413 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE_OFFSET_LAYOUT(SET, BINDING, OFFSET, LAYOUT) layout(binding = CONCATENATE(SET, BINDING), offset = OFFSET, LAYOUT)" );
421 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE(SET, BINDING) layout(set = SET, binding = BINDING)" );
422 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE_OFFSET(SET, BINDING, OFFSET) layout(set = SET, binding = BINDING, offset = OFFSET)" );
423 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE_LAYOUT(SET, BINDING, LAYOUT) layout(set = SET, binding = BINDING, LAYOUT)" );
424 AppendToShaderHeader(
ShaderType::COUNT,
"#define DESCRIPTOR_SET_RESOURCE_OFFSET_LAYOUT(SET, BINDING, OFFSET, LAYOUT) layout(set = SET, binding = BINDING, offset = OFFSET, LAYOUT)" );
428 constexpr std::pair<const char*, const char*> shaderVaryings[] =
430 {
"vec4" ,
"_vertexW"},
431 {
"vec4" ,
"_vertexWV"},
432 {
"vec3" ,
"_normalWV"},
433 {
"vec2" ,
"_texCoord"},
434 {
"flat uvec4" ,
"_indirectionIDs"},
435 {
"flat uint" ,
"_LoDLevel"},
438 constexpr const char* crossTypeGLSLHLSL =
"#define float2 vec2\n"
439 "#define float3 vec3\n"
440 "#define float4 vec4\n"
441 "#define int2 ivec2\n"
442 "#define int3 ivec3\n"
443 "#define int4 ivec4\n"
444 "#define float2x2 mat2\n"
445 "#define float3x3 mat3\n"
446 "#define float4x4 mat4\n"
449 const auto getPassData = [&](
const ShaderType type ) ->
string
451 string baseString =
" _out.{} = _in[index].{};";
454 baseString =
" _out[gl_InvocationID].{} = _in[index].{};";
457 string passData(
"void PassData(in int index) {" );
458 passData.append(
"\n" );
459 for (
const auto& [varType, name] : shaderVaryings )
462 passData.append(
"\n" );
465 passData.append(
"#if defined(HAS_VELOCITY)\n" );
466 passData.append(
Util::StringFormat( baseString.c_str(),
"_prevVertexWVP",
"_prevVertexWVP" ) );
467 passData.append(
"\n#endif //HAS_VELOCITY\n" );
469 passData.append(
"#if defined(ENABLE_TBN)\n" );
471 passData.append(
"\n#endif //ENABLE_TBN\n" );
473 passData.append(
"}\n" );
478 const auto addVaryings = [&](
const ShaderType type )
480 for (
const auto& [varType, name] : shaderVaryings )
484 AppendToShaderHeader( type,
"#if defined(HAS_VELOCITY)" );
485 AppendToShaderHeader( type,
" vec4 _prevVertexWVP;" );
486 AppendToShaderHeader( type,
"#endif //HAS_VELOCITY" );
488 AppendToShaderHeader( type,
"#if defined(ENABLE_TBN)" );
489 AppendToShaderHeader( type,
" mat3 _tbnWV;" );
490 AppendToShaderHeader( type,
"#endif //ENABLE_TBN" );
510 AppendToShaderHeader(
ShaderType::COUNT,
"/*Copyright 2009-2022 DIVIDE-Studio*/" );
516 AppendToShaderHeader(
ShaderType::COUNT,
"#define dvd_VertexIndex gl_VertexID" );
517 AppendToShaderHeader(
ShaderType::COUNT,
"#define dvd_InstanceIndex gl_InstanceID" );
518 AppendToShaderHeader(
ShaderType::COUNT,
"#define DVD_GL_BASE_INSTANCE gl_BaseInstance" );
519 AppendToShaderHeader(
ShaderType::COUNT,
"#define DVD_GL_BASE_VERTEX gl_BaseVertex" );
524 AppendToShaderHeader(
ShaderType::COUNT,
"#extension GL_ARB_shader_draw_parameters : require" );
526 AppendToShaderHeader(
ShaderType::COUNT,
"#define dvd_VertexIndex gl_VertexIndex" );
527 AppendToShaderHeader(
ShaderType::COUNT,
"#define dvd_InstanceIndex gl_InstanceIndex" );
528 AppendToShaderHeader(
ShaderType::COUNT,
"#define DVD_GL_BASE_INSTANCE gl_BaseInstanceARB" );
529 AppendToShaderHeader(
ShaderType::COUNT,
"#define DVD_GL_BASE_VERTEX gl_BaseVertexARB" );
530 AppendToShaderHeader(
ShaderType::COUNT,
"#define DVD_GL_DRAW_ID gl_DrawIDARB" );
548 AppendToShaderHeader(
ShaderType::COUNT,
"#define CONCATENATE_IMPL(s1, s2) s1 ## _ ## s2" );
549 AppendToShaderHeader(
ShaderType::COUNT,
"#define CONCATENATE(s1, s2) CONCATENATE_IMPL(s1, s2)" );
562 constexpr float Z_TEST_SIGMA = 0.00001f;
607 AppendToShaderHeader(
ShaderType::COUNT,
"#define M_PI 3.14159265358979323846" );
608 AppendToShaderHeader(
ShaderType::COUNT,
"#define M_PI_DIV_2 1.57079632679489661923" );
609 AppendToShaderHeader(
ShaderType::COUNT,
"#define INV_M_PI 0.31830988618379067153" );
610 AppendToShaderHeader(
ShaderType::COUNT,
"#define TWO_M_PI 6.28318530717958647692" );
611 AppendToShaderHeader(
ShaderType::COUNT,
"#define EULER_CONST 2.71828182845904523536" );
664 const string interfaceLocationString =
"layout(location = 0) ";
680 AppendToShaderHeader(
ShaderType::COUNT,
"#if defined(PRE_PASS) || defined(SHADOW_PASS)" );
684 AppendToShaderHeader(
ShaderType::COUNT,
"#if defined(COMPUTE_TBN) && !defined(ENABLE_TBN)" );
686 AppendToShaderHeader(
ShaderType::COUNT,
"#endif //COMPUTE_TBN && !ENABLE_TBN" );
752 return glswState == 1;
762 , _addPrefix( addPrefix )
767 : _sourceFile( file ), _variant( variant ), _moduleType( type )
783 bool expected =
true;
826 return it->second.get();
836 , _generation( generation )
851 if ( it->getGUID() ==
parent->getGUID() )
865 const I64 targetGUID =
parent->getGUID();
870 return it->
getGUID() == targetGUID;
885 , _highPriority( descriptor.flag() )
886 , _descriptor( descriptor._propertyDescriptor )
888 if ( assetName().empty() )
890 assetName( resourceName() );
893 if ( assetLocation().empty() )
895 assetLocation( Paths::g_shadersLocation );
986 if (
entry._queueDelay > 0u )
1002 if ( !
entry._program->recompile() )
1009 entry._queueDelayHighWaterMark += 1u;
1010 entry._queueDelay =
entry._queueDelayHighWaterMark;
1041 const string shaderName{ program->resourceName().c_str() };
1043 if ( shaderName.find( name ) !=
Str<256>::npos || shaderName.compare( name ) == 0 )
1062 RefreshBindingSlots();
1108 if ( s_useShaderCache )
1115 for (
const FileEntry& it : list )
1117 s_newestShaderAtomWriteTime = std::max( s_newestShaderAtomWriteTime, it._lastWriteTime );
1161 bindings.fill( {} );
1170 return s_bindingsPerSet[
to_base( usage )][slot]._glBinding;
1178 for (
U8 j = 0u; j < bindings.size(); ++j )
1180 if ( bindings[j]._glBinding == binding && bindings[j]._type == type )
1201 bindingData.
_type = type;
1249 if ( binding._type == type )
1269 totalUniformBufferSize = 0u;
1290 if ( program ==
nullptr )
1292 program = shaderProgram;
1307 if ( program !=
nullptr && program->getGUID() == guid)
1330 if ( atomLocations.empty() )
1333 atomLocations.emplace_back( Paths::g_shadersLocation );
1335 atomLocations.emplace_back( Paths::Shaders::GLSL::g_GLSLShaderLoc );
1337 atomLocations.emplace_back( Paths::Shaders::GLSL::g_comnAtomLoc );
1339 atomLocations.emplace_back( Paths::Shaders::GLSL::g_compAtomLoc );
1341 atomLocations.emplace_back( Paths::Shaders::GLSL::g_fragAtomLoc );
1343 atomLocations.emplace_back( Paths::Shaders::GLSL::g_geomAtomLoc );
1345 atomLocations.emplace_back( Paths::Shaders::GLSL::g_tescAtomLoc );
1347 atomLocations.emplace_back( Paths::Shaders::GLSL::g_teseAtomLoc );
1349 atomLocations.emplace_back( Paths::Shaders::GLSL::g_vertAtomLoc );
1352 return atomLocations;
1362 string& sourceInOut,
1364 eastl::set<U64>& foundAtomIDsInOut,
1372 size_t lineNumber = 1;
1375 string output, includeString;
1376 output.reserve(sourceInOut.size());
1382 const std::string_view directive = !line.empty() ? std::string_view{ line }.substr( 1 ) :
"";
1397 if (
auto m = ctre::match<Paths::g_includePattern>( line ) )
1401 const auto includeFile =
Util::Trim( m.get<1>().str() );
1403 foundAtomIDsInOut.insert(
_ID( includeFile.c_str() ) );
1420 bool wasParsed =
false;
1429 if ( includeString.empty() )
1438 output.append( includeString );
1444 output.append( line.c_str() );
1447 output.append(
"\n" );
1451 sourceInOut = output;
1457 const U64 atomNameHash =
_ID( atomName );
1459 const AtomMap::iterator it =
s_atoms.find( atomNameHash );
1462 if ( it != std::cend(
s_atoms ) )
1465 for (
const auto& atom : atoms )
1467 foundAtomIDsInOut.insert( atom );
1475 assert( !filePath.
empty() );
1478 string& output =
s_atoms[atomNameHash];
1493 for (
const auto& atom : atoms )
1495 foundAtomIDsInOut.insert( atom );
1507 FileError err = FileError::FILE_EMPTY;
1522 if ( err != FileError::NONE )
1542 if ( err != FileError::NONE )
1566 if ( !DeleteCacheLocked( cache, dataIn.
_shaderName ) )
1577 if ( !s_useShaderCache )
1585 if ( !DeleteCacheLocked( cache, dataInOut.
_shaderName ) )
1593 FileError err = FileError::FILE_EMPTY;
1598 err =
readFile( TxtCacheLocation(),
1602 return err == FileError::NONE;
1606 std::ifstream tempData;
1608 err =
readFile( SpvCacheLocation(),
1614 if ( err == FileError::NONE )
1616 tempData.seekg(0, std::ios::end);
1620 while (!tempData.eof())
1623 tempData.read((
char *)&inWord,
sizeof(inWord));
1624 if (!tempData.eof())
1627 if (tempData.fail())
1657 glswSetPath(( Paths::Shaders::GLSL::g_GLSLShaderLoc.
string() + Paths::g_pathSeparator).c_str(),
".glsl" );
1664 fileData[fileHash]._modules.push_back( shaderDescriptor );
1670 U8 blockOffset = 0u;
1675 _setUsage.fill(
false );
1677 for (
auto& [fileHash, loadDataPerFile] : fileData )
1710 if ( !loadDataPerFile._programName.empty() )
1712 loadDataPerFile._programName.append(
"-" );
1714 loadDataPerFile._programName.append( stageData.
_shaderName.c_str() );
1738 for (
const LoadData& stageData : programLoadData )
1755 SetVisibility( binding, image );
1779 SetVisibility( binding, buffer );
1799 for (
const LoadData& stageData : programLoadData )
1808 if ( uniformBlock !=
nullptr )
1814 if ( uploaderBlock.
_bindingSet != stageData._reflectionData._uniformBlockBindingSet ||
1815 uploaderBlock.
_bindingSlot != stageData._reflectionData._uniformBlockBindingIndex )
1840 blockBuffer.uploadUniformData( data );
1842 if ( blockBuffer.commit( set, memCmdInOut ) )
1858 eastl::set<U64> atomIDs;
1860 bool needGLSL = !s_targetVulkan;
1861 if ( reloadExisting )
1885 loadAndParseGLSL( defines, loadDataInOut, previousUniformsInOut, blockIndexInOut, atomIDs );
1943 _usedAtomIDs.insert( begin( atomIDs ), end( atomIDs ) );
1953 U8& blockIndexInOut,
1954 eastl::set<U64>& atomIDsInOut )
1957 glslCodeOut.resize( 0 );
1962 if ( sourceCodeStr !=
nullptr )
1964 glslCodeOut.append( sourceCodeStr );
1968 if ( !glslCodeOut.empty() )
1972 for (
const auto& [defineString, appendPrefix] : defines )
1975 if ( defineString ==
"DEFINE_PLACEHOLDER" )
1981 header.append( (appendPrefix ?
"#define " :
"") + defineString +
'\n' );
1984 for (
const auto& [defineString, appendPrefix] : defines )
1987 if ( !appendPrefix || defineString ==
"DEFINE_PLACEHOLDER" )
1994 header.append(
"/*Engine define: [ " + defineString +
" ]*/\n" );
2011 if ( !previousUniformsInOut.empty() && previousUniformsInOut != loadDataInOut.
_uniforms )
2015 DIVIDE_ASSERT(blockIndexInOut < 2,
"ShaderProgram::load: We only support 2 uniform blocks per shader program at the moment. Batch uniforms from different stages together to reduce usage!");
2022 uniformBlock =
"layout( ";
2027 uniformBlock.append(
"binding = {}, std140 ) uniform {} {{" );
2033 uniformBlock.append(
"\n}} ");
2038 const string rawName = uniform.
_name.substr( 0, uniform.
_name.find_first_of(
"[" ) ).c_str();
2049 previousUniformsInOut = loadDataInOut.
_uniforms;
2052 string pushConstantCodeBlock{};
2055 pushConstantCodeBlock =
2056 "layout( push_constant ) uniform constants\n"
2060 "} PushConstants;\n"
2061 "#define PushData0 PushConstants.data0\n"
2062 "#define PushData1 PushConstants.data1";
2066 pushConstantCodeBlock =
2067 "layout(location = 18) uniform mat4 PushConstantData[2];\n"
2068 "#define PushData0 PushConstantData[0]\n"
2069 "#define PushData1 PushConstantData[1]";
2086 eastl::fixed_vector<U64, 128, true> queuedDeletion;
2092 if ( it->first == atomHash)
2098 if ( it->second.find( atomHash ) != it->second.cend() )
2101 queuedDeletion.push_back( it->first );
2106 for (
const U64 atom : queuedDeletion )
2123 const U64 atomNameHash =
_ID(
string{ atomName }.c_str() );
2132 for (
const U64 atomID : program->_usedAtomIDs )
2134 if ( atomID == atomNameHash )
#define PROFILE_SCOPE_AUTO(CATEGORY)
virtual bool load(PlatformContext &context)
Loading and unloading interface.
static void deallocateWatcher(I64 fileWatcherGUID)
static FileWatcher & allocateWatcher()
Rough around the edges Adapter pattern abstracting the actual rendering API and access to the GPU.
static U64 FrameCount() noexcept
PerformanceMetrics & getPerformanceMetrics() noexcept
Utility class that adds basic GUID management to objects.
FORCE_INLINE I64 getGUID() const noexcept
GFXDevice & context() const noexcept
static constexpr F32 MAX_SHININESS
PlatformContext & context() noexcept
Configuration & config() noexcept
ResourceState getState() const noexcept
static U16 SkyProbeLayerIndex() noexcept
virtual ~ShaderModule() override
void deregisterParent(ShaderProgram *parent)
static constexpr U32 MAX_FRAME_LIFETIME
static void Idle(bool fast)
eastl::fixed_vector< ShaderProgram *, 4, true > _parents
static void DestroyStaticData()
static ShaderModule * GetShader(const std::string_view name)
Returns a reference to an already loaded shader, null otherwise.
static void InitStaticData()
static ShaderModule * GetShaderLocked(const std::string_view name)
hashMap< U64, ShaderModule_uptr > ShaderMap
ShaderModule(GFXDevice &context, const std::string_view name, U32 generation)
void registerParent(ShaderProgram *parent)
static std::atomic_bool s_modulesRemoved
Shader cache.
static SharedMutex s_shaderNameLock
static ShaderMap s_shaderNameMap
static const string & ShaderFileReadLocked(const ResourcePath &filePath, std::string_view atomName, bool recurse, eastl::set< U64 > &foundAtomIDsInOut, bool &wasParsed)
Open the file found at 'filePath' matching 'atomName' and return it's source code.
static void OnEndFrame(GFXDevice &gfx)
std::array< BindingsPerSetArray, to_base(DescriptorSetUsage::COUNT)> BindingSetData
virtual ShaderResult validatePreBind(bool rebind=true)
bool loadSourceCode(const ModuleDefines &defines, bool reloadExisting, LoadData &loadDataInOut, Reflection::UniformsSet &previousUniformsInOut, U8 &blockIndexInOut)
static void EraseAtom(const U64 atomHash)
void initDrawDescriptorSetLayout(const PerFileShaderData &loadData)
static U64 shaderAtomExtensionHash[to_base(ShaderType::COUNT)+1]
void loadAndParseGLSL(const ModuleDefines &defines, LoadData &loadDataInOut, Reflection::UniformsSet &previousUniformsInOut, U8 &blockIndexInOut, eastl::set< U64 > &atomIDsInOut)
static ResourcePath shaderAtomLocationPrefix[to_base(ShaderType::COUNT)+1]
static std::pair< DescriptorSetUsage, U8 > GetDescriptorSlotForGLBinding(U8 binding, DescriptorSetBindingType type) noexcept
static SharedMutex s_programLock
static Str< 8 > shaderAtomExtensionName[to_base(ShaderType::COUNT)+1]
static void OnBeginFrame(GFXDevice &gfx)
static void DestroyStaticData()
static void RebuildAllShaders()
static U8 k_commandBufferID
static const string & ShaderFileRead(const ResourcePath &filePath, std::string_view atomName, bool recurse, eastl::set< U64 > &foundAtomIDsInOut, bool &wasParsed)
static void RegisterShaderProgram(ShaderProgram *shaderProgram)
Add a shaderProgram to the program cache.
static U8 GetGLBindingForDescriptorSlot(DescriptorSetUsage usage, U8 slot) noexcept
static std::atomic_int s_shaderCount
static bool UnregisterShaderProgram(ShaderProgram *shaderProgram)
Remove a shaderProgram from the program cache.
virtual bool loadInternal(hashMap< U64, PerFileShaderData > &fileData, bool overwrite)
std::array< BindingsPerSet, MAX_BINDINGS_PER_DESCRIPTOR_SET > BindingsPerSetArray
bool uploadUniformData(const UniformData &data, DescriptorSet &set, GFX::MemoryBarrierCommand &memCmdInOut)
bool load(PlatformContext &context) override
Loading and unloading interface.
static ShaderQueue s_recompileQueue
static Mutex s_atomLock
Shaders loaded from files are kept as atoms.
eastl::stack< ShaderQueueEntry, vector< ShaderQueueEntry > > ShaderQueue
static constexpr const char * UNIFORM_BLOCK_NAME
ShaderProgram(PlatformContext &context, const ResourceDescriptor< ShaderProgram > &descriptor)
static void PreprocessIncludes(std::string_view name, string &sourceInOut, I32 level, eastl::set< U64 > &foundAtomIDsInOut, bool lock)
static ShaderProgramMap s_shaderPrograms
Shader program cache.
static LastRequestedShader s_lastRequestedShaderProgram
std::array< LoadData, to_base(ShaderType::COUNT)> ShaderLoadData
static eastl::fixed_vector< ShaderProgram *, U16_MAX, false > s_usedShaderPrograms
static ShaderQueue s_recompileFailedQueue
static void RegisterSetLayoutBinding(DescriptorSetUsage usage, U8 slot, DescriptorSetBindingType type, ShaderStageVisibility visibility)
static vector< ResourcePath > GetAllAtomLocations()
static AtomInclusionMap s_atomIncludes
static BindingSetData & GetBindingSetData() noexcept
const ShaderProgramDescriptor _descriptor
static void OnAtomChange(std::string_view atomName, FileUpdateEvent evt)
static void Idle(PlatformContext &platformContext, bool fast)
static ErrorCode OnStartup(PlatformContext &context)
static void EraseAtomLocked(const U64 atomHash)
static bool LoadFromCache(LoadData::ShaderCacheType cache, LoadData &dataInOut, eastl::set< U64 > &atomIDsOut)
static U32 GetBindingCount(DescriptorSetUsage usage, DescriptorSetBindingType type)
hashMap< U64, string > AtomMap
static BindingSetData s_bindingsPerSet
static void InitStaticData()
hashMap< U64, eastl::set< U64 > > AtomInclusionMap
eastl::fixed_vector< ShaderProgram *, U16_MAX, true > ShaderProgramMap
void initUniformUploader(const PerFileShaderData &loadData)
static I64 s_shaderFileWatcherID
static bool RecompileShaderProgram(const std::string_view name)
Queue a shaderProgram recompile request.
static ErrorCode SubmitSetLayouts(GFXDevice &gfx)
~ShaderProgram() override
vector< UniformBlockUploader > _uniformBlockBuffers
static void OnThreadCreated(const GFXDevice &gfx, const std::thread::id &threadID, bool isMainRenderThread)
static bool SaveToCache(LoadData::ShaderCacheType cache, const LoadData &dataIn, const eastl::set< U64 > &atomIDsIn)
eastl::set< U64 > _usedAtomIDs
static constexpr U8 WORLD_AO_LAYER_INDEX
void addIgnoredEndCharacter(char character)
void addIgnoredExtension(const char *extension)
int glswSetPath(const char *pathPrefix, const char *pathSuffix)
const char * glswGetShader(const char *pEffectKey)
int glswAddDirectiveToken(const char *token, const char *directive)
glswContext * glswGetCurrentContext()
void glswClearCurrentContext()
constexpr bool IS_SHIPPING_BUILD
constexpr bool IS_DEBUG_BUILD
constexpr bool IS_PROFILE_BUILD
constexpr U8 CLUSTERS_Y_THREADS
constexpr U8 CLUSTERS_X_THREADS
constexpr U8 CLUSTERS_Z_THREADS
constexpr U8 CLUSTERS_X
Controls compute shader dispatch. e.g. Dispatch Z count = CLUSTERS_Z / CLUSTERS_Z_THREADS.
constexpr U8 MAX_SHADOW_CASTING_POINT_LIGHTS
constexpr U8 MAX_SHADOW_CASTING_SPOT_LIGHTS
constexpr U16 MAX_ACTIVE_LIGHTS_PER_FRAME
Maximum number of lights we process per frame. We need this upper bound for pre-allocating arrays and...
constexpr U8 MAX_SHADOW_CASTING_LIGHTS
Maximum number of shadow casting lights processed per frame.
constexpr U8 MAX_CSM_SPLITS_PER_LIGHT
Used for CSM or PSSM to determine the maximum number of frustum splits.
constexpr U8 MAX_SHADOW_CASTING_DIRECTIONAL_LIGHTS
How many lights (in order as passed to the shader for the node) should cast shadows.
constexpr U16 TARGET_FRAME_RATE
Application desired framerate for physics and input simulations.
constexpr U16 MAX_CONCURRENT_MATERIALS
Estimated maximum number of materials used in a single frame by all passes combined.
constexpr U8 MAX_CULL_DISTANCES
constexpr U16 MAX_BONE_COUNT_PER_NODE
Maximum number of bones available per node.
constexpr float ALPHA_DISCARD_THRESHOLD
constexpr U16 MAX_VISIBLE_NODES
Estimated maximum number of visible objects per render pass (this includes debug primitives)
constexpr U8 MAX_CLIP_DISTANCES
static constexpr const char * shaderTypes[]
static constexpr const char * descriptorSetUsage[]
static void Error(void *userData, const char *format, va_list args)
static char * Input(char *buffer, const int size, void *userData) noexcept
static char * Scratch(const std::string_view fileName)
FORCE_INLINE void Output(const int ch, void *userData)
FORCE_INLINE void AddDependency(const char *file, void *userData)
NO_DESTROY static thread_local WorkData g_workData
static void OnThreadCreated()
constexpr U8 g_maxTagCount
NO_DESTROY static thread_local fppTag g_tags[g_maxTagCount]
static bool PreProcessMacros(const std::string_view fileName, string &sourceInOut)
NO_DESTROY static thread_local fppTag * g_tagHead
constexpr Optick::Category::Type Streaming
constexpr Optick::Category::Type Graphics
static constexpr U8 INVALID_BINDING_INDEX
void PreProcessUniforms(string &sourceInOut, UniformsSet &foundUniforms)
eastl::set< UniformDeclaration, UniformCompare > UniformsSet
bool SaveReflectionData(const ResourcePath &path, const ResourcePath &file, const Data &reflectionDataIn, const eastl::set< U64 > &atomIDsIn)
const Reflection::BufferEntry * FindUniformBlock(const Reflection::Data &data)
bool LoadReflectionData(const ResourcePath &path, const ResourcePath &file, Data &reflectionDataOut, eastl::set< U64 > &atomIDsOut)
DescriptorSetUsage StringToDescriptorSetUsage(const string &name)
const char * DescriptorSetUsageToString(DescriptorSetUsage setUsage) noexcept
const char * ShadingModeToString(ShadingMode shadingMode) noexcept
const char * MaterialDebugFlagToString(const MaterialDebugFlag unitType) noexcept
const char * TextureOperationToString(TextureOperation textureOp) noexcept
bool GetLine(istringstream &input, T_str &line, char delimiter='\n')
Str StringFormat(const char *fmt, Args &&...args)
string to_string(GET_PASS_TYPE< T > value)
bool BeginsWith(std::string_view input, std::string_view compare, bool ignoreWhitespace)
bool ReplaceStringInPlace(T_str &subject, std::span< const std::string_view > search, std::string_view replace, bool recursive=false)
T_str GetTrailingCharacters(const T_str &input, size_t count)
ResourcePath ShaderBuildCacheLocation()
ResourcePath SpvCacheLocation()
bool DeleteCache(const ShaderProgram::LoadData::ShaderCacheType type, const Str< 256 > &fileName)
ResourcePath TxtCacheLocation()
ResourcePath ReflTargetName(const Str< 256 > &fileName)
ResourcePath ShaderAPILocation()
ResourcePath SpvTargetName(const Str< 256 > &fileName)
ResourcePath ReflCacheLocation()
bool ValidateCacheLocked(const ShaderProgram::LoadData::ShaderCacheType type, const Str< 256 > &sourceFileName, const Str< 256 > &fileName)
bool DeleteCacheLocked(const ShaderProgram::LoadData::ShaderCacheType type, const Str< 256 > &fileName)
void RefreshBindingSlots()
ResourcePath ShaderParentCacheLocation()
U64 s_newestShaderAtomWriteTime
Used to detect modified shader atoms to validate/invalidate shader cache.
Handle console commands that start with a forward slash.
std::lock_guard< mutex > LockGuard
constexpr U32 nextPOW2(U32 n) noexcept
constexpr U32 to_U32(const T value)
FileError writeFile(const ResourcePath &filePath, const std::string_view fileName, const char *content, const size_t length, const FileType fileType)
FileError readFile(const ResourcePath &filePath, std::string_view fileName, FileType fileType, std::ifstream &sreamOut)
static const vec3< F32 > WORLD_X_AXIS
constexpr U16 to_U16(const T value)
constexpr U8 MAX_BINDINGS_PER_DESCRIPTOR_SET
@ RES_LOADED
The resource is available for usage.
static const vec3< F32 > WORLD_Z_AXIS
static bool InitGLSW(const RenderAPI renderingAPI, const Configuration &config)
vector< ModuleDefine > ModuleDefines
std::shared_mutex SharedMutex
size_t DefinesHash(const ModuleDefines &defines) noexcept
TextureOperation
How should each texture be added.
constexpr I8 s_maxHeaderRecursionLevel
FileError createDirectory(const ResourcePath &path)
eastl::vector< Type > vector
hashAlg::unordered_map< K, V, HashFun, Predicate > hashMap
std::shared_lock< mutex > SharedLock
bool getAllFilesInDirectory(const ResourcePath &filePath, FileList &listInOut, const char *extensionNoDot)
constexpr U64 _ID(const char *const str, const U64 value=val_64_const) noexcept
constexpr U16 GLOBAL_PROBE_COUNT
std::basic_istringstream< char, std::char_traits< char >, dvd_allocator< char > > istringstream
@ Vulkan
not supported yet
void efficient_clear(eastl::fixed_vector< T, nodeCount, bEnableOverflow, OverflowAllocator > &fixed_vector)
constexpr U8 to_U8(const T value)
::value constexpr T CLAMPED(T n, T min, T max) noexcept
constexpr size_t to_size(const T value)
ShaderType
Available shader stages.
std::basic_string< char, std::char_traits< char >, dvd_allocator< char > > string
FileError deleteFile(const ResourcePath &filePath, const std::string_view fileName)
constexpr U8 GLOBAL_WATER_BODIES_COUNT
static NO_DESTROY UpdateListener g_sFileWatcherListener([](const std::string_view atomName, const FileUpdateEvent evt) { ShaderProgram::OnAtomChange(atomName, evt);})
bool dvd_erase_if(eastl::vector< T, A > &vec, Predicate &&pred)
Project const SceneEntry & entry
FileError fileLastWriteTime(const ResourcePath &filePathAndName, U64 &timeOutSec)
static const vec3< F32 > WORLD_Y_AXIS
constexpr auto to_base(const Type value) -> Type
struct Divide::Configuration::Debug::Cache cache
U16 reflectionProbeResolution
struct Divide::Configuration::Rendering rendering
struct Divide::Configuration::Debug debug
static NO_INLINE void d_printfn(const char *format, T &&... args)
static NO_INLINE void errorfn(const char *format, T &&... args)
static NO_INLINE void warnfn(const char *format, T &&... args)
static constexpr RTColourAttachmentSlot ALBEDO
static constexpr RTColourAttachmentSlot NORMALS
static constexpr RTColourAttachmentSlot MODULATE
static constexpr RTColourAttachmentSlot VELOCITY
static constexpr RTColourAttachmentSlot ACCUMULATION
static constexpr RTColourAttachmentSlot REVEALAGE
ShaderProgram::ShaderLoadData _loadData
std::string_view _fileName
std::array< char, 16<< 10 > _scratch
vector< ShaderModuleDescriptor > _modules
ModuleDefines _globalDefines
vector< BufferEntry > _buffers
U8 _uniformBlockBindingIndex
U8 _uniformBlockBindingSet
vector< ImageEntry > _images
std::array< bool, to_base(RTColourAttachmentSlot::COUNT)> _fragmentOutputs
bool _combinedImageSampler
StringReturnType< N > string() const noexcept
bool empty() const noexcept
ShaderModuleDescriptor()=default
BaseType< ShaderStageVisibility > _visibility
DescriptorSetBindingType _type
Reflection::UniformsSet _uniforms
Reflection::Data _reflectionData
std::vector< SpvWord > _sourceCodeSpirV
static bool BuildReflectionData(Divide::ShaderType shader_type, const std::vector< unsigned int > &spirv, bool targetVulkan, Divide::Reflection::Data &reflectionDataInOut)
static bool GLSLtoSPV(Divide::ShaderType shader_type, const char *pshader, std::vector< unsigned int > &spirv, const bool targetVulkan)