yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
9d47a3529
master
1// unit-test-unit-test-conditional-vertex-input.cpp 2 3#include "../../source/core/slang-io.h" 4#include "../../source/core/slang-process.h" 5#include "slang-com-ptr.h" 6#include "slang.h" 7#include "unit-test/slang-unit-test.h" 8 9#include <stdio.h> 10#include <stdlib.h> 11 12using namespace Slang ; 13 14// Test the compilation API for compiling an entrypoint that uses `Conditional<T>` to 15// represent conditional vertex attribute input that can be specialized away. 16 17SLANG_UNIT_TEST (conditionalVertexInput ) 18{ 19const char * userSourceBody = R"( 20struct Vertex<bool hasColor> { 21float3 pos : POSITION; 22Conditional<float3, hasColor> color : COLOR; 23float3 normal : NORMAL; 24} 25 26extern static const bool vertexHasColor = true; 27 28[shader("vertex")] 29float4 vertMain(Vertex<vertexHasColor> o) { 30if (let color = o.color.get()) 31{ 32// If `vertexHasColor` is true, we can use `color`. 33return float4(o.pos + color + o.normal, 1); 34} 35return float4(o.pos + o.normal, 1); 36} 37)" ; 38const char * userSourceBodyNoColor = R"(export static const bool vertexHasColor = false;)" ; 39 40ComPtr < slang::IGlobalSession > globalSession ; 41SLANG_CHECK (slang_createGlobalSession (SLANG_API_VERSION ,globalSession .writeRef ())== SLANG_OK ); 42 slang::TargetDesc targetDesc = {}; 43targetDesc .format = SLANG_GLSL ; 44 slang::SessionDesc sessionDesc = {}; 45sessionDesc .targetCount = 1 ; 46sessionDesc .targets = & targetDesc ; 47ComPtr < slang::ISession > session ; 48SLANG_CHECK (globalSession -> createSession (sessionDesc ,session .writeRef ())== SLANG_OK ); 49 50ComPtr < slang::IBlob > diagnosticBlob ; 51auto module = session -> loadModuleFromSourceString ( 52"m" , 53"m.slang" , 54userSourceBody , 55diagnosticBlob .writeRef ()); 56SLANG_CHECK (module != nullptr ); 57 58ComPtr < slang::IEntryPoint > entryPoint ; 59module -> findAndCheckEntryPoint ( 60"vertMain" , 61SLANG_STAGE_VERTEX , 62entryPoint .writeRef (), 63diagnosticBlob .writeRef ()); 64 65// Check the program with `vertexHasColor = true`. 66 { 67 slang::IComponentType * componentTypes [2 ]= {module ,entryPoint .get ()}; 68ComPtr < slang::IComponentType > composedProgram ; 69session -> createCompositeComponentType ( 70componentTypes , 712 , 72composedProgram .writeRef (), 73diagnosticBlob .writeRef ()); 74 75ComPtr < slang::IComponentType > linkedProgram ; 76composedProgram -> link (linkedProgram .writeRef (),diagnosticBlob .writeRef ()); 77 78auto paramLayout = linkedProgram -> getLayout () 79-> getEntryPointByIndex (0 ) 80-> getParameterByIndex (0 ) 81-> getTypeLayout (); 82 83// Total number of varying inputs should be 3. (pos, color and normal) 84SLANG_CHECK (paramLayout -> getSize (slang::ParameterCategory ::VaryingInput )== 3 ); 85 86// Offset of `normal` should be 2. 87SLANG_CHECK ( 88paramLayout 89-> getFieldByIndex (2 )// `o.normal` 90-> getOffset (slang::ParameterCategory ::VaryingInput )== 2 ); 91ComPtr < slang::IBlob > code ; 92SLANG_CHECK ( 93linkedProgram -> getEntryPointCode (0 ,0 ,code .writeRef (),diagnosticBlob .writeRef ())== 94SLANG_OK ); 95auto codeStr = Slang ::UnownedStringSlice ((const char * )code -> getBufferPointer ()); 96SLANG_CHECK (codeStr .indexOf (toSlice ("layout(location = 0)" ))!= -1 ); 97SLANG_CHECK (codeStr .indexOf (toSlice ("layout(location = 1)" ))!= -1 ); 98SLANG_CHECK (codeStr .indexOf (toSlice ("layout(location = 2)" ))!= -1 ); 99 } 100 101// Check the program with `vertexHashColor = false`. 102 { 103auto configModule = session -> loadModuleFromSourceString ( 104"config" , 105"config.slang" , 106userSourceBodyNoColor , 107diagnosticBlob .writeRef ()); 108SLANG_CHECK (module != nullptr ); 109 110 slang::IComponentType * componentTypes [3 ]= {module ,entryPoint .get (),configModule }; 111ComPtr < slang::IComponentType > composedProgram ; 112session -> createCompositeComponentType ( 113componentTypes , 1143 , 115composedProgram .writeRef (), 116diagnosticBlob .writeRef ()); 117 118ComPtr < slang::IComponentType > linkedProgram ; 119composedProgram -> link (linkedProgram .writeRef (),diagnosticBlob .writeRef ()); 120 121auto paramLayout = linkedProgram -> getLayout () 122-> getEntryPointByIndex (0 ) 123-> getParameterByIndex (0 ) 124-> getTypeLayout (); 125 126// Total number of varying inputs should be 2. (pos and normal) 127SLANG_CHECK (paramLayout -> getSize (slang::ParameterCategory ::VaryingInput )== 2 ); 128 129// Offset of `normal` should be 1. 130SLANG_CHECK ( 131paramLayout 132-> getFieldByIndex (2 )// `o.normal` 133-> getOffset (slang::ParameterCategory ::VaryingInput )== 1 ); 134ComPtr < slang::IBlob > code ; 135SLANG_CHECK ( 136linkedProgram -> getEntryPointCode (0 ,0 ,code .writeRef (),diagnosticBlob .writeRef ())== 137SLANG_OK ); 138 139auto codeStr = Slang ::UnownedStringSlice ((const char * )code -> getBufferPointer ()); 140 141SLANG_CHECK (codeStr .indexOf (toSlice ("layout(location = 0)" ))!= -1 ); 142SLANG_CHECK (codeStr .indexOf (toSlice ("layout(location = 1)" ))!= -1 ); 143// Resulting code should not contain `layout(location = 1)` since `color` is not used. 144SLANG_CHECK (codeStr .indexOf (toSlice ("layout(location = 2)" ))== -1 ); 145 } 146}