yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
0d16228ae
master
1// slang-artifact-associated-impl.cpp 2#include "slang-artifact-associated-impl.h" 3 4#include "../core/slang-array-view.h" 5#include "../core/slang-char-util.h" 6#include "../core/slang-file-system.h" 7#include "../core/slang-io.h" 8#include "../core/slang-type-text-util.h" 9#include "slang-artifact-diagnostic-util.h" 10 11namespace Slang 12{ 13 14/* !!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactDiagnostics !!!!!!!!!!!!!!!!!!!!!!!!!!! */ 15 16ArtifactDiagnostics ::ArtifactDiagnostics (const ThisType & rhs ) 17 :ComBaseObject () 18 ,m_result (rhs .m_result ) 19 ,m_diagnostics (rhs .m_diagnostics ) 20 ,m_raw (rhs .m_raw .getLength ()+ 1 ) 21{ 22// We need to be careful with raw, we want a new *copy* not a non atomic ref counting 23// In initialization we should have enough space 24m_raw .append (rhs .m_raw .getUnownedSlice ()); 25 26// Reallocate all the strings 27for (auto & diagnostic :m_diagnostics ) 28 { 29diagnostic .filePath = m_allocator .allocate (diagnostic .filePath ); 30diagnostic .code = m_allocator .allocate (diagnostic .code ); 31diagnostic .text = m_allocator .allocate (diagnostic .text ); 32 } 33} 34 35void * ArtifactDiagnostics ::clone (const Guid & guid ) 36{ 37ThisType * copy = new ThisType (* this ); 38if (auto ptr = copy -> castAs (guid )) 39 { 40return ptr ; 41 } 42// If the cast fails, we delete the item. 43delete copy ; 44return nullptr ; 45} 46 47void * ArtifactDiagnostics ::getInterface (const Guid & guid ) 48{ 49if (guid == ISlangUnknown ::getTypeGuid ()|| guid == ICastable ::getTypeGuid ()|| 50guid == IClonable ::getTypeGuid ()|| guid == IArtifactDiagnostics ::getTypeGuid ()) 51 { 52return static_cast < IArtifactDiagnostics *> (this ); 53 } 54return nullptr ; 55} 56 57void * ArtifactDiagnostics ::getObject (const Guid & guid ) 58{ 59SLANG_UNUSED (guid ); 60return nullptr ; 61} 62 63void * ArtifactDiagnostics ::castAs (const Guid & guid ) 64{ 65if (auto intf = getInterface (guid )) 66 { 67return intf ; 68 } 69return getObject (guid ); 70} 71 72void ArtifactDiagnostics ::reset () 73{ 74m_diagnostics .clear (); 75m_raw .clear (); 76m_result = SLANG_OK ; 77 78m_allocator .deallocateAll (); 79} 80 81void ArtifactDiagnostics ::add (const Diagnostic & inDiagnostic ) 82{ 83Diagnostic diagnostic (inDiagnostic ); 84 85diagnostic .text = m_allocator .allocate (inDiagnostic .text ); 86diagnostic .code = m_allocator .allocate (inDiagnostic .code ); 87diagnostic .filePath = m_allocator .allocate (inDiagnostic .filePath ); 88 89m_diagnostics .add (diagnostic ); 90} 91 92void ArtifactDiagnostics ::setRaw (const CharSlice & slice ) 93{ 94m_raw .clear (); 95m_raw <<asStringSlice (slice ); 96} 97 98void ArtifactDiagnostics ::appendRaw (const CharSlice & slice ) 99{ 100if (m_raw .getLength ()&& m_raw [m_raw .getLength ()- 1 ]!= '\n' ) 101 { 102m_raw .appendChar ('\n' ); 103 } 104m_raw <<asStringSlice (slice ); 105} 106 107Count ArtifactDiagnostics ::getCountAtLeastSeverity (Diagnostic ::Severity severity ) 108{ 109Index count = 0 ; 110for (const auto & msg :m_diagnostics ) 111 { 112count += Index (Index (msg .severity ) >=Index (severity )); 113 } 114return count ; 115} 116 117Count ArtifactDiagnostics ::getCountBySeverity (Diagnostic ::Severity severity ) 118{ 119Index count = 0 ; 120for (const auto & msg :m_diagnostics ) 121 { 122count += Index (msg .severity == severity ); 123 } 124return count ; 125} 126 127bool ArtifactDiagnostics ::hasOfAtLeastSeverity (Diagnostic ::Severity severity ) 128{ 129for (const auto & msg :m_diagnostics ) 130 { 131if (Index (msg .severity ) >=Index (severity )) 132 { 133return true; 134 } 135 } 136return false; 137} 138 139Count ArtifactDiagnostics ::getCountByStage ( 140Diagnostic ::Stage stage , 141Count outCounts [Int (Diagnostic ::Severity ::CountOf )]) 142{ 143Int count = 0 ; 144 ::memset (outCounts ,0 ,sizeof (Index )* Int (Diagnostic ::Severity ::CountOf )); 145for (const auto & diagnostic :m_diagnostics ) 146 { 147if (diagnostic .stage == stage ) 148 { 149count ++ ; 150outCounts [Index (diagnostic .severity )]++ ; 151 } 152 } 153return count ++ ; 154} 155 156void ArtifactDiagnostics ::removeBySeverity (Diagnostic ::Severity severity ) 157{ 158Index count = m_diagnostics .getCount (); 159for (Index i = 0 ;i < count ;++ i ) 160 { 161if (m_diagnostics [i ].severity == severity ) 162 { 163m_diagnostics .removeAt (i ); 164i -- ; 165count -- ; 166 } 167 } 168} 169 170void ArtifactDiagnostics ::maybeAddNote (const CharSlice & in ) 171{ 172ArtifactDiagnosticUtil ::maybeAddNote (asStringSlice (in ),this ); 173} 174 175void ArtifactDiagnostics ::requireErrorDiagnostic () 176{ 177// If we find an error, we don't need to add a generic diagnostic 178for (const auto & msg :m_diagnostics ) 179 { 180if (Index (msg .severity ) >=Index (Diagnostic ::Severity ::Error )) 181 { 182return ; 183 } 184 } 185 186Diagnostic diagnostic ; 187diagnostic .severity = Diagnostic ::Severity ::Error ; 188diagnostic .text = m_allocator .allocate (m_raw ); 189 190// Add the diagnostic 191m_diagnostics .add (diagnostic ); 192} 193 194/* static */ UnownedStringSlice _getSeverityText (ArtifactDiagnostic ::Severity severity ) 195{ 196typedef ArtifactDiagnostic ::Severity Severity ; 197switch (severity ) 198 { 199default : 200return UnownedStringSlice ::fromLiteral ("Unknown" ); 201case Severity ::Info : 202return UnownedStringSlice ::fromLiteral ("Info" ); 203case Severity ::Warning : 204return UnownedStringSlice ::fromLiteral ("Warning" ); 205case Severity ::Error : 206return UnownedStringSlice ::fromLiteral ("Error" ); 207 } 208} 209 210static void _appendCounts ( 211const Index counts [Int (ArtifactDiagnostic ::Severity ::CountOf )], 212StringBuilder & out ) 213{ 214typedef ArtifactDiagnostic ::Severity Severity ; 215 216for (Index i = 0 ;i < Int (Severity ::CountOf );i ++ ) 217 { 218if (counts [i ]> 0 ) 219 { 220out <<_getSeverityText (Severity (i )) <<"(" <<counts [i ] <<") " ; 221 } 222 } 223} 224 225static void _appendSimplified ( 226const Index counts [Int (ArtifactDiagnostic ::Severity ::CountOf )], 227StringBuilder & out ) 228{ 229typedef ArtifactDiagnostic ::Severity Severity ; 230for (Index i = 0 ;i < Int (Severity ::CountOf );i ++ ) 231 { 232if (counts [i ]> 0 ) 233 { 234out <<_getSeverityText (Severity (i )) <<" " ; 235 } 236 } 237} 238 239void ArtifactDiagnostics ::calcSummary (ISlangBlob ** outBlob ) 240{ 241StringBuilder buf ; 242 243Index counts [Int (Diagnostic ::Severity ::CountOf )]; 244if (getCountByStage (Diagnostic ::Stage ::Compile ,counts )> 0 ) 245 { 246buf <<"Compile: " ; 247_appendCounts (counts ,buf ); 248buf <<"\n" ; 249 } 250if (getCountByStage (Diagnostic ::Stage ::Link ,counts )> 0 ) 251 { 252buf <<"Link: " ; 253_appendCounts (counts ,buf ); 254buf <<"\n" ; 255 } 256 257* outBlob = StringBlob ::moveCreate (buf ).detach (); 258} 259 260void ArtifactDiagnostics ::calcSimplifiedSummary (ISlangBlob ** outBlob ) 261{ 262StringBuilder buf ; 263 264Index counts [Int (Diagnostic ::Severity ::CountOf )]; 265if (getCountByStage (Diagnostic ::Stage ::Compile ,counts )> 0 ) 266 { 267buf <<"Compile: " ; 268_appendSimplified (counts ,buf ); 269buf <<"\n" ; 270 } 271if (getCountByStage (Diagnostic ::Stage ::Link ,counts )> 0 ) 272 { 273buf <<"Link: " ; 274_appendSimplified (counts ,buf ); 275buf <<"\n" ; 276 } 277 278* outBlob = StringBlob ::moveCreate (buf ).detach (); 279} 280 281/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ArtifactPostEmitMetadata !!!!!!!!!!!!!!!!!!!!!!!!!!! */ 282 283void * ArtifactPostEmitMetadata ::getInterface (const Guid & guid ) 284{ 285if (guid == ISlangUnknown ::getTypeGuid ()|| guid == ICastable ::getTypeGuid ()|| 286guid == IArtifactPostEmitMetadata ::getTypeGuid ()) 287 { 288return static_cast < IArtifactPostEmitMetadata *> (this ); 289 } 290return nullptr ; 291} 292 293void * ArtifactPostEmitMetadata ::getObject (const Guid & uuid ) 294{ 295if (uuid == getTypeGuid ()) 296 { 297return this ; 298 } 299return nullptr ; 300} 301 302void * ArtifactPostEmitMetadata ::castAs (const Guid & guid ) 303{ 304if (auto ptr = getInterface (guid )) 305 { 306return ptr ; 307 } 308return getObject (guid ); 309} 310 311Slice < ShaderBindingRange > ArtifactPostEmitMetadata ::getUsedBindingRanges () 312{ 313return Slice < ShaderBindingRange > (m_usedBindings .getBuffer (),m_usedBindings .getCount ()); 314} 315 316Slice < String > ArtifactPostEmitMetadata ::getExportedFunctionMangledNames () 317{ 318return Slice < String > ( 319m_exportedFunctionMangledNames .getBuffer (), 320m_exportedFunctionMangledNames .getCount ()); 321} 322 323SlangResult ArtifactPostEmitMetadata ::isParameterLocationUsed ( 324SlangParameterCategory category , 325SlangUInt spaceIndex , 326SlangUInt registerIndex , 327bool & outUsed ) 328{ 329for (const auto & range :getUsedBindingRanges ()) 330 { 331if (range .containsBinding ((slang::ParameterCategory )category ,spaceIndex ,registerIndex )) 332 { 333outUsed = true; 334return SLANG_OK ; 335 } 336 } 337 338outUsed = false; 339return SLANG_OK ; 340} 341 342const char * ArtifactPostEmitMetadata ::getDebugBuildIdentifier () 343{ 344return m_debugBuildIdentifier .getBuffer (); 345} 346 347 348}// namespace Slang