yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
43d0c2100
master
1#if 0 2// Duplicated: This is identical to slang-rhi\tests\test-texture-shared.cpp 3 4#include "core/slang-basic.h" 5#include "gfx-test-util.h" 6#include "slang-gfx.h" 7#include "slang-rhi/shader-cursor.h" 8#include "unit-test/slang-unit-test.h" 9 10using namespace gfx ; 11 12namespace gfx_test 13{ 14void setUpAndRunShader ( 15IDevice * device , 16ComPtr < ITextureResource > tex , 17ComPtr < IResourceView > texView , 18ComPtr < IResourceView > bufferView , 19const char * entryPoint , 20ComPtr < ISamplerState > sampler = nullptr ) 21{ 22Slang ::ComPtr < ITransientResourceHeap > transientHeap ; 23ITransientResourceHeap ::Desc transientHeapDesc = {}; 24transientHeapDesc .constantBufferSize = 4096 ; 25GFX_CHECK_CALL_ABORT ( 26device -> createTransientResourceHeap (transientHeapDesc ,transientHeap .writeRef ())); 27 28ComPtr < IShaderProgram > shaderProgram ; 29 slang::ProgramLayout * slangReflection ; 30GFX_CHECK_CALL_ABORT ( 31loadComputeProgram (device ,shaderProgram ,"trivial-copy" ,entryPoint ,slangReflection )); 32 33ComputePipelineStateDesc pipelineDesc = {}; 34pipelineDesc .program = shaderProgram .get (); 35ComPtr < gfx::IPipelineState > pipelineState ; 36GFX_CHECK_CALL_ABORT ( 37device -> createComputePipelineState (pipelineDesc ,pipelineState .writeRef ())); 38 39// We have done all the set up work, now it is time to start recording a command buffer for 40// GPU execution. 41 { 42ICommandQueue ::Desc queueDesc = {ICommandQueue ::QueueType ::Graphics }; 43auto queue = device -> createCommandQueue (queueDesc ); 44 45auto commandBuffer = transientHeap -> createCommandBuffer (); 46auto encoder = commandBuffer -> encodeComputeCommands (); 47 48auto rootObject = encoder -> bindPipeline (pipelineState ); 49 50ShaderCursor entryPointCursor ( 51rootObject -> getEntryPoint (0 ));// get a cursor the the first entry-point. 52 53auto & desc = * tex -> getDesc (); 54entryPointCursor ["width" ].setData (desc .size .width ); 55entryPointCursor ["height" ].setData (desc .size .height ); 56 57// Bind texture view to the entry point 58entryPointCursor ["tex" ].setResource (texView ); 59 60if (sampler ) 61entryPointCursor ["sampler" ].setSampler (sampler ); 62 63// Bind buffer view to the entry point. 64entryPointCursor ["buffer" ].setResource (bufferView ); 65 66encoder -> dispatchCompute (1 ,1 ,1 ); 67encoder -> endEncoding (); 68commandBuffer -> close (); 69queue -> executeCommandBuffer (commandBuffer ); 70queue -> waitOnHost (); 71 } 72} 73 74ComPtr < ITextureResource > createTexture ( 75IDevice * device , 76ITextureResource ::Extents extents , 77 gfx::Format format , 78ITextureResource ::SubresourceData * initialData ) 79{ 80ITextureResource ::Desc texDesc = {}; 81texDesc .type = IResource ::Type ::Texture2D ; 82texDesc .numMipLevels = 1 ; 83texDesc .arraySize = 1 ; 84texDesc .size = extents ; 85texDesc .defaultState = ResourceState ::UnorderedAccess ; 86texDesc .allowedStates = ResourceStateSet ( 87ResourceState ::ShaderResource , 88ResourceState ::UnorderedAccess , 89ResourceState ::CopyDestination , 90ResourceState ::CopySource ); 91texDesc .format = format ; 92texDesc .isShared = true; 93 94ComPtr < ITextureResource > inTex ; 95GFX_CHECK_CALL_ABORT (device -> createTextureResource (texDesc ,initialData ,inTex .writeRef ())); 96return inTex ; 97} 98 99ComPtr < IResourceView > createTexView (IDevice * device ,ComPtr < ITextureResource > inTexture ) 100{ 101ComPtr < IResourceView > texView ; 102IResourceView ::Desc texViewDesc = {}; 103texViewDesc .type = IResourceView ::Type ::UnorderedAccess ; 104texViewDesc .format = 105inTexture -> getDesc ()-> format ;// TODO: Handle typeless formats - gfxIsTypelessFormat(format) 106// ? convertTypelessFormat(format) : format; 107GFX_CHECK_CALL_ABORT (device -> createTextureView (inTexture ,texViewDesc ,texView .writeRef ())); 108return texView ; 109} 110 111template < typename T > 112ComPtr < IBufferResource > createBuffer (IDevice * device ,int size ,void * initialData ) 113{ 114IBufferResource ::Desc bufferDesc = {}; 115bufferDesc .sizeInBytes = size * sizeof (T ); 116bufferDesc .format = gfx::Format ::Unknown ; 117bufferDesc .elementSize = sizeof (T ); 118bufferDesc .allowedStates = ResourceStateSet ( 119ResourceState ::ShaderResource , 120ResourceState ::UnorderedAccess , 121ResourceState ::CopyDestination , 122ResourceState ::CopySource ); 123bufferDesc .defaultState = ResourceState ::UnorderedAccess ; 124bufferDesc .memoryType = MemoryType ::DeviceLocal ; 125 126ComPtr < IBufferResource > outBuffer ; 127GFX_CHECK_CALL_ABORT ( 128device -> createBufferResource (bufferDesc ,initialData ,outBuffer .writeRef ())); 129return outBuffer ; 130} 131 132ComPtr < IResourceView > createOutBufferView (IDevice * device ,ComPtr < IBufferResource > outBuffer ) 133{ 134ComPtr < IResourceView > bufferView ; 135IResourceView ::Desc viewDesc = {}; 136viewDesc .type = IResourceView ::Type ::UnorderedAccess ; 137viewDesc .format = Format ::Unknown ; 138GFX_CHECK_CALL_ABORT ( 139device -> createBufferView (outBuffer ,nullptr ,viewDesc ,bufferView .writeRef ())); 140return bufferView ; 141} 142 143void sharedTextureTestImpl (IDevice * srcDevice ,IDevice * dstDevice ,UnitTestContext * context ) 144{ 145ISamplerState ::Desc samplerDesc ; 146auto sampler = dstDevice -> createSamplerState (samplerDesc ); 147 148float initFloatData [16 ]= {0.0f }; 149auto floatResults = createBuffer < float > (dstDevice ,16 ,initFloatData ); 150auto floatBufferView = createOutBufferView (dstDevice ,floatResults ); 151 152uint32_t initUintData [16 ]= {0u }; 153auto uintResults = createBuffer < uint32_t > (dstDevice ,16 ,initUintData ); 154auto uintBufferView = createOutBufferView (dstDevice ,uintResults ); 155 156int32_t initIntData [16 ]= {0 }; 157auto intResults = createBuffer < uint32_t > (dstDevice ,16 ,initIntData ); 158auto intBufferView = createOutBufferView (dstDevice ,intResults ); 159 160ITextureResource ::Extents size = {}; 161size .width = 2 ; 162size .height = 2 ; 163size .depth = 1 ; 164 165ITextureResource ::Extents bcSize = {}; 166bcSize .width = 4 ; 167bcSize .height = 4 ; 168bcSize .depth = 1 ; 169 170 { 171float texData []= { 1721.0f , 1730.0f , 1740.0f , 1751.0f , 1760.0f , 1771.0f , 1780.0f , 1791.0f , 1800.0f , 1810.0f , 1821.0f , 1831.0f , 1840.5f , 1850.5f , 1860.5f , 1871.0f }; 188ITextureResource ::SubresourceData subData = {(void * )texData ,32 ,0 }; 189 190// Create a shareable texture using srcDevice, get its handle, then create a texture using 191// the handle using dstDevice. Read back the texture and check that its contents are 192// correct. 193auto srcTexture = createTexture (srcDevice ,size , gfx::Format ::R32G32B32A32_FLOAT ,& subData ); 194 195InteropHandle sharedHandle ; 196GFX_CHECK_CALL_ABORT (srcTexture -> getSharedHandle (& sharedHandle )); 197ComPtr < ITextureResource > dstTexture ; 198size_t sizeInBytes = 0 ; 199size_t alignment = 0 ; 200GFX_CHECK_CALL_ABORT (srcDevice -> getTextureAllocationInfo ( 201* (srcTexture -> getDesc ()), 202& sizeInBytes , 203& alignment )); 204GFX_CHECK_CALL_ABORT (dstDevice -> createTextureFromSharedHandle ( 205sharedHandle , 206* (srcTexture -> getDesc ()), 207sizeInBytes , 208dstTexture .writeRef ())); 209// Reading back the buffer from srcDevice to make sure it's been filled in before reading 210// anything back from dstDevice 211// TODO: Implement actual synchronization (and not this hacky solution) 212compareComputeResult (dstDevice ,dstTexture ,ResourceState ::ShaderResource ,texData ,32 ,2 ); 213 214auto texView = createTexView (dstDevice ,dstTexture ); 215setUpAndRunShader (dstDevice ,dstTexture ,texView ,floatBufferView ,"copyTexFloat4" ); 216compareComputeResult ( 217dstDevice , 218floatResults , 219Slang ::makeArray < float > ( 2201.0f , 2210.0f , 2220.0f , 2231.0f , 2240.0f , 2251.0f , 2260.0f , 2271.0f , 2280.0f , 2290.0f , 2301.0f , 2311.0f , 2320.5f , 2330.5f , 2340.5f , 2351.0f )); 236 } 237} 238 239void sharedTextureTestAPI ( 240UnitTestContext * context , 241Slang ::RenderApiFlag ::Enum srcApi , 242Slang ::RenderApiFlag ::Enum dstApi ) 243{ 244auto srcDevice = createTestingDevice (context ,srcApi ); 245auto dstDevice = createTestingDevice (context ,dstApi ); 246if (!srcDevice || !dstDevice ) 247 { 248SLANG_IGNORE_TEST ; 249 } 250 251sharedTextureTestImpl (srcDevice ,dstDevice ,context ); 252} 253#if SLANG_WIN64 254SLANG_UNIT_TEST (sharedTextureD3D12ToCUDA ) 255{ 256sharedTextureTestAPI (unitTestContext ,Slang ::RenderApiFlag ::D3D12 ,Slang ::RenderApiFlag ::CUDA ); 257} 258 259SLANG_UNIT_TEST (sharedTextureVulkanToCUDA ) 260{ 261sharedTextureTestAPI (unitTestContext ,Slang ::RenderApiFlag ::Vulkan ,Slang ::RenderApiFlag ::CUDA ); 262} 263#endif 264}// namespace gfx_test 265 266#endif