yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
1ea2ab1b6
master
1// unit-test-ptr-layout.cpp 2 3#include "slang-com-ptr.h" 4#include "slang.h" 5#include "unit-test/slang-unit-test.h" 6 7#include <stdlib.h> 8 9using namespace Slang ; 10 11SLANG_UNIT_TEST (metalConstantBufferInParameterBlockLayout ) 12{ 13const char * testSource = R"( 14struct T 15{ 16float4 m0; 17float m1; 18float3 m2; 19}; 20 21ParameterBlock<ConstantBuffer<T>> params; 22)" ; 23 24ComPtr < slang::IGlobalSession > globalSession ; 25SLANG_CHECK (slang_createGlobalSession (SLANG_API_VERSION ,globalSession .writeRef ())== SLANG_OK ); 26 27 slang::TargetDesc targetDesc = {}; 28targetDesc .format = SLANG_METAL ; 29targetDesc .profile = globalSession -> findProfile ("metal" ); 30 31 slang::SessionDesc sessionDesc = {}; 32sessionDesc .targetCount = 1 ; 33sessionDesc .targets = & targetDesc ; 34 35ComPtr < slang::ISession > session ; 36SLANG_CHECK (globalSession -> createSession (sessionDesc ,session .writeRef ())== SLANG_OK ); 37 38ComPtr < slang::IBlob > diagnosticBlob ; 39auto module = session -> loadModuleFromSourceString ( 40"test" , 41"test.slang" , 42testSource , 43diagnosticBlob .writeRef ()); 44SLANG_CHECK (module != nullptr ); 45 46auto testBody = [& ]() 47 { 48auto reflection = module -> getLayout (); 49 50// Collect our layouts 51auto paramBlockType = reflection -> findTypeByName ("ParameterBlock<ConstantBuffer<T>>" ); 52SLANG_CHECK (paramBlockType != nullptr ); 53auto paramBlockLayout = reflection -> getTypeLayout (paramBlockType ); 54SLANG_CHECK (paramBlockLayout != nullptr ); 55auto cbufferLayout = paramBlockLayout -> getElementTypeLayout (); 56SLANG_CHECK (cbufferLayout != nullptr ); 57auto structLayout = cbufferLayout -> getElementTypeLayout (); 58SLANG_CHECK (structLayout != nullptr ); 59 60// Check offsets follow constant buffer rules (uniform alignment) 61// m0 : float4 should be at offset 0 62// m1 : float should be at offset 16 (after float4) 63// m2 : float3 should be at offset 32 (aligned to 16-byte boundary) 64SLANG_CHECK (structLayout -> getFieldCount ()== 3 ); 65SLANG_CHECK (structLayout -> getFieldByIndex (0 )-> getOffset ()== 0 ); 66SLANG_CHECK (structLayout -> getFieldByIndex (1 )-> getOffset ()== 16 ); 67SLANG_CHECK (structLayout -> getFieldByIndex (2 )-> getOffset ()== 32 ); 68 }; 69 70testBody (); 71} 72 73SLANG_UNIT_TEST (metalArgumentBufferLayout ) 74{ 75const char * testSource = R"( 76struct T 77{ 78float4 m0; 79float m1; 80float3 m2; 81}; 82 83// Using ParameterBlock directly without ConstantBuffer wrapper 84ParameterBlock<T> params; 85)" ; 86 87ComPtr < slang::IGlobalSession > globalSession ; 88SLANG_CHECK (slang_createGlobalSession (SLANG_API_VERSION ,globalSession .writeRef ())== SLANG_OK ); 89 90 slang::TargetDesc targetDesc = {}; 91targetDesc .format = SLANG_METAL ; 92targetDesc .profile = globalSession -> findProfile ("metal" ); 93 94 slang::SessionDesc sessionDesc = {}; 95sessionDesc .targetCount = 1 ; 96sessionDesc .targets = & targetDesc ; 97 98ComPtr < slang::ISession > session ; 99SLANG_CHECK (globalSession -> createSession (sessionDesc ,session .writeRef ())== SLANG_OK ); 100 101ComPtr < slang::IBlob > diagnosticBlob ; 102auto module = session -> loadModuleFromSourceString ( 103"test" , 104"test.slang" , 105testSource , 106diagnosticBlob .writeRef ()); 107SLANG_CHECK (module != nullptr ); 108 109auto testBody = [& ]() 110 { 111auto reflection = module -> getLayout (); 112 113// Collect our layouts 114auto paramBlockType = reflection -> findTypeByName ("ParameterBlock<T>" ); 115SLANG_CHECK (paramBlockType != nullptr ); 116auto paramBlockLayout = reflection -> getTypeLayout (paramBlockType ); 117SLANG_CHECK (paramBlockLayout != nullptr ); 118auto structLayout = paramBlockLayout -> getElementTypeLayout (); 119SLANG_CHECK (structLayout != nullptr ); 120 121// Check that offsets follow Metal argument buffer rules 122// Fields should have 0 offset and meaningful binding indices 123SLANG_CHECK (structLayout -> getFieldCount ()== 3 ); 124SLANG_CHECK (structLayout -> getFieldByIndex (0 )-> getOffset ()== 0 ); 125SLANG_CHECK (structLayout -> getFieldByIndex (1 )-> getOffset ()== 0 ); 126SLANG_CHECK (structLayout -> getFieldByIndex (2 )-> getOffset ()== 0 ); 127SLANG_CHECK (structLayout -> getFieldByIndex (0 )-> getBindingIndex ()== 0 ); 128SLANG_CHECK (structLayout -> getFieldByIndex (1 )-> getBindingIndex ()== 1 ); 129SLANG_CHECK (structLayout -> getFieldByIndex (2 )-> getBindingIndex ()== 2 ); 130 }; 131 132testBody (); 133}