yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
5b9931456
master
1// main.cpp 2 3#include "slang-com-helper.h" 4#include "slang-com-ptr.h" 5#include "slang.h" 6 7#include <stdio.h> 8 9// This includes a useful small function for setting up the prelude (described more further below). 10#include "../../source/core/slang-test-tool-util.h" 11#include "examples/example-base/example-base.h" 12 13// Slang namespace is used for elements support code (like core) which we use here 14// for ComPtr<> and TestToolUtil 15using namespace Slang ; 16 17static const ExampleResources resourceBase ("cpu-com-example" ); 18 19// For the moment we have to explicitly write the Slang COM interface in C++ code. It *MUST* match 20// the interface in the slang source 21// As it stands all interfaces need to derive from ISlangUnknown (or IUnknown). 22class IDoThings :public ISlangUnknown 23{ 24public : 25virtual SLANG_NO_THROW int SLANG_MCALL doThing (int a ,int b )= 0 ; 26virtual SLANG_NO_THROW int SLANG_MCALL calcHash (const char * in )= 0 ; 27virtual SLANG_NO_THROW void SLANG_MCALL printMessage (const char * in )= 0 ; 28}; 29 30static int _calcHash (const char * in ) 31{ 32int hash = 0 ; 33for (;* in ;++ in ) 34 { 35// A very poor hash function 36hash = hash * 13 + * in ; 37 } 38return hash ; 39} 40 41class DoThings :public IDoThings 42{ 43public : 44// We don't need queryInterface for this impl, or ref counting 45virtual SLANG_NO_THROW SlangResult SLANG_MCALL 46queryInterface (SlangUUID const & uuid ,void ** outObject )SLANG_OVERRIDE 47 { 48return SLANG_E_NOT_IMPLEMENTED ; 49 } 50virtual SLANG_NO_THROW uint32_t SLANG_MCALL addRef ()SLANG_OVERRIDE {return 1 ; } 51virtual SLANG_NO_THROW uint32_t SLANG_MCALL release ()SLANG_OVERRIDE {return 1 ; } 52 53// IDoThings 54virtual SLANG_NO_THROW int SLANG_MCALL doThing (int a ,int b )SLANG_OVERRIDE 55 { 56return a + b + 1 ; 57 } 58virtual SLANG_NO_THROW int SLANG_MCALL calcHash (const char * in )SLANG_OVERRIDE 59 { 60return (int )_calcHash (in ); 61 } 62virtual SLANG_NO_THROW void SLANG_MCALL printMessage (const char * in )SLANG_OVERRIDE 63 { 64printf ("%s\n" ,in ); 65 } 66}; 67 68static SlangResult _innerMain (int argc ,char ** argv ) 69{ 70// NOTE! This example only works if `slang-llvm` or a C++ compiler that Slang supports is 71// available. 72 73// Create the session 74ComPtr < slang::IGlobalSession > slangSession ; 75slangSession .attach (spCreateSession (NULL )); 76 77// Set up the prelude 78// NOTE: This isn't strictly necessary, as preludes are embedded in the binary. 79TestToolUtil ::setSessionDefaultPreludeFromExePath (argv [0 ],slangSession ); 80 81// Create a compile request 82Slang ::ComPtr < slang::ICompileRequest > request ; 83SLANG_ALLOW_DEPRECATED_BEGIN 84SLANG_RETURN_ON_FAIL (slangSession -> createCompileRequest (request .writeRef ())); 85SLANG_ALLOW_DEPRECATED_END 86 87// We want to compile to 'HOST_CALLABLE' here such that we can execute the Slang code. 88// 89// Note that it is possible to use HOST_HOST_CALLABLE, but this currently only works with 90// 'regular' C++ compilers not with `slang-llvm`. 91const int targetIndex = request -> addCodeGenTarget (SLANG_SHADER_HOST_CALLABLE ); 92 93// Set the target flag to indicate that we want to compile all into a library. 94request -> setTargetFlags (targetIndex ,SLANG_TARGET_FLAG_GENERATE_WHOLE_PROGRAM ); 95 96// Add the translation unit 97const int translationUnitIndex = 98request -> addTranslationUnit (SLANG_SOURCE_LANGUAGE_SLANG ,nullptr ); 99 100// Set the source file for the translation unit 101Slang ::String path = resourceBase .resolveResource ("shader.slang" ); 102request -> addTranslationUnitSourceFile (translationUnitIndex ,path .getBuffer ()); 103 104const SlangResult compileRes = request -> compile (); 105 106// Even if there were no errors that forced compilation to fail, the 107// compiler may have produced "diagnostic" output such as warnings. 108// We will go ahead and print that output here. 109// 110if (auto diagnostics = request -> getDiagnosticOutput ()) 111 { 112printf ("%s" ,diagnostics ); 113 } 114 115// Get the 'shared library' (note that this doesn't necessarily have to be implemented as a 116// shared library it's just an interface to executable code). 117ComPtr < ISlangSharedLibrary > sharedLibrary ; 118SLANG_RETURN_ON_FAIL (request -> getTargetHostCallable (0 ,sharedLibrary .writeRef ())); 119 120DoThings doThings ; 121 122 { 123auto doThingsPtr = (IDoThings ** )sharedLibrary -> findSymbolAddressByName ("globalDoThings" ); 124if (!doThingsPtr ) 125 { 126return SLANG_FAIL ; 127 } 128// Set the global interface 129* doThingsPtr = & doThings ; 130 } 131 132// Test a free function 133 { 134typedef const char * (* Func )(const char * ); 135Func func = (Func )sharedLibrary -> findFuncByName ("getString" ); 136 137if (!func ) 138 { 139return SLANG_FAIL ; 140 } 141 142String text = "Hello World!" ; 143String returnedText = func (text .getBuffer ()); 144 145SLANG_ASSERT (text == returnedText ); 146 } 147 148// Test hash 149 { 150typedef int (* Func )(const char * text ); 151Func func = (Func )sharedLibrary -> findFuncByName ("calcHash" ); 152if (!func ) 153 { 154return SLANG_FAIL ; 155 } 156 157String text ("Hello" ); 158const int hash = func (text .getBuffer ()); 159SLANG_ASSERT (hash == _calcHash (text .getBuffer ())); 160 } 161 162// Test printing 163 { 164typedef void (* Func )(const char * text ); 165 166Func func = (Func )sharedLibrary -> findFuncByName ("printMessage" ); 167 168if (!func ) 169 { 170return SLANG_FAIL ; 171 } 172func ("Hello World!" ); 173 } 174 175return SLANG_OK ; 176} 177 178int exampleMain (int argc ,char ** argv ) 179{ 180return SLANG_SUCCEEDED (_innerMain (argc ,argv )) ?0 :-1 ; 181}