yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
f65d756bf
master
1// cpu-device.cpp 2#include "cpu-device.h" 3 4#include "cpu-buffer.h" 5#include "cpu-pipeline-state.h" 6#include "cpu-query.h" 7#include "cpu-resource-views.h" 8#include "cpu-shader-object.h" 9#include "cpu-shader-program.h" 10#include "cpu-texture.h" 11 12#include <chrono> 13 14namespace gfx 15{ 16using namespace Slang ; 17 18namespace cpu 19{ 20DeviceImpl ::~DeviceImpl () 21{ 22m_currentPipeline = nullptr ; 23m_currentRootObject = nullptr ; 24} 25 26SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::initialize (const Desc & desc ) 27{ 28SLANG_RETURN_ON_FAIL (slangContext .initialize ( 29desc .slang , 30desc .extendedDescCount , 31desc .extendedDescs , 32SLANG_SHADER_HOST_CALLABLE , 33"sm_5_1" , 34makeArray (slang::PreprocessorMacroDesc {"__CPU__" ,"1" }).getView ())); 35 36SLANG_RETURN_ON_FAIL (RendererBase ::initialize (desc )); 37 38// Initialize DeviceInfo 39 { 40m_info .deviceType = DeviceType ::CPU ; 41m_info .bindingStyle = BindingStyle ::CUDA ; 42m_info .projectionStyle = ProjectionStyle ::DirectX ; 43m_info .apiName = "CPU" ; 44static const float kIdentity []= {1 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1 }; 45 ::memcpy (m_info .identityProjectionMatrix ,kIdentity ,sizeof (kIdentity )); 46m_info .adapterName = "CPU" ; 47m_info .timestampFrequency = 1000000000 ; 48 } 49 50// Can support pointers (or something akin to that) 51 { 52m_features .add ("has-ptr" ); 53 } 54 55return SLANG_OK ; 56} 57 58SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::createTextureResource ( 59const ITextureResource ::Desc & desc , 60const ITextureResource ::SubresourceData * initData , 61ITextureResource ** outResource ) 62{ 63TextureResource ::Desc srcDesc = fixupTextureDesc (desc ); 64 65RefPtr < TextureResourceImpl > texture = new TextureResourceImpl (srcDesc ); 66 67SLANG_RETURN_ON_FAIL (texture -> init (initData )); 68 69returnComPtr (outResource ,texture ); 70return SLANG_OK ; 71} 72 73SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::createBufferResource ( 74const IBufferResource ::Desc & descIn , 75const void * initData , 76IBufferResource ** outResource ) 77{ 78auto desc = fixupBufferDesc (descIn ); 79RefPtr < BufferResourceImpl > resource = new BufferResourceImpl (desc ); 80SLANG_RETURN_ON_FAIL (resource -> init ()); 81if (initData ) 82 { 83SLANG_RETURN_ON_FAIL (resource -> setData (0 ,desc .sizeInBytes ,initData )); 84 } 85returnComPtr (outResource ,resource ); 86return SLANG_OK ; 87} 88 89SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::createTextureView ( 90ITextureResource * inTexture , 91IResourceView ::Desc const & desc , 92IResourceView ** outView ) 93{ 94auto texture = static_cast < TextureResourceImpl *> (inTexture ); 95RefPtr < TextureResourceViewImpl > view = new TextureResourceViewImpl (desc ,texture ); 96returnComPtr (outView ,view ); 97return SLANG_OK ; 98} 99 100SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::createBufferView ( 101IBufferResource * inBuffer , 102IBufferResource * counterBuffer , 103IResourceView ::Desc const & desc , 104IResourceView ** outView ) 105{ 106auto buffer = static_cast < BufferResourceImpl *> (inBuffer ); 107RefPtr < BufferResourceViewImpl > view = new BufferResourceViewImpl (desc ,buffer ); 108returnComPtr (outView ,view ); 109return SLANG_OK ; 110} 111 112Result DeviceImpl ::createShaderObjectLayout ( 113 slang::ISession * session , 114 slang::TypeLayoutReflection * typeLayout , 115ShaderObjectLayoutBase ** outLayout ) 116{ 117RefPtr < ShaderObjectLayoutImpl > cpuLayout = 118new ShaderObjectLayoutImpl (this ,session ,typeLayout ); 119returnRefPtrMove (outLayout ,cpuLayout ); 120 121return SLANG_OK ; 122} 123 124Result DeviceImpl ::createShaderObject (ShaderObjectLayoutBase * layout ,IShaderObject ** outObject ) 125{ 126auto cpuLayout = static_cast < ShaderObjectLayoutImpl *> (layout ); 127 128RefPtr < ShaderObjectImpl > result = new ShaderObjectImpl (); 129SLANG_RETURN_ON_FAIL (result -> init (this ,cpuLayout )); 130returnComPtr (outObject ,result ); 131 132return SLANG_OK ; 133} 134 135Result DeviceImpl ::createMutableShaderObject ( 136ShaderObjectLayoutBase * layout , 137IShaderObject ** outObject ) 138{ 139auto cpuLayout = static_cast < ShaderObjectLayoutImpl *> (layout ); 140 141RefPtr < MutableShaderObjectImpl > result = new MutableShaderObjectImpl (); 142SLANG_RETURN_ON_FAIL (result -> init (this ,cpuLayout )); 143returnComPtr (outObject ,result ); 144 145return SLANG_OK ; 146} 147 148Result DeviceImpl ::createRootShaderObject (IShaderProgram * program ,ShaderObjectBase ** outObject ) 149{ 150auto cpuProgram = static_cast < ShaderProgramImpl *> (program ); 151auto cpuProgramLayout = cpuProgram -> layout ; 152 153RefPtr < RootShaderObjectImpl > result = new RootShaderObjectImpl (); 154SLANG_RETURN_ON_FAIL (result -> init (this ,cpuProgramLayout )); 155returnRefPtrMove (outObject ,result ); 156return SLANG_OK ; 157} 158 159SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::createProgram ( 160const IShaderProgram ::Desc & desc , 161IShaderProgram ** outProgram , 162ISlangBlob ** outDiagnosticBlob ) 163{ 164RefPtr < ShaderProgramImpl > cpuProgram = new ShaderProgramImpl (); 165cpuProgram -> init (desc ); 166auto slangGlobalScope = cpuProgram -> linkedProgram ; 167if (slangGlobalScope ) 168 { 169auto slangProgramLayout = slangGlobalScope -> getLayout (); 170if (!slangProgramLayout ) 171return SLANG_FAIL ; 172 173RefPtr < RootShaderObjectLayoutImpl > cpuProgramLayout = new RootShaderObjectLayoutImpl ( 174this , 175slangGlobalScope -> getSession (), 176slangProgramLayout ); 177cpuProgramLayout -> m_programLayout = slangProgramLayout ; 178 179cpuProgram -> layout = cpuProgramLayout ; 180 } 181 182returnComPtr (outProgram ,cpuProgram ); 183return SLANG_OK ; 184} 185 186SLANG_NO_THROW Result SLANG_MCALL DeviceImpl ::createComputePipelineState ( 187const ComputePipelineStateDesc & desc , 188IPipelineState ** outState ) 189{ 190RefPtr < PipelineStateImpl > state = new PipelineStateImpl (); 191state -> init (desc ); 192returnComPtr (outState ,state ); 193return Result (); 194} 195 196SLANG_NO_THROW Result SLANG_MCALL 197DeviceImpl ::createQueryPool (const IQueryPool ::Desc & desc ,IQueryPool ** outPool ) 198{ 199RefPtr < QueryPoolImpl > pool = new QueryPoolImpl (); 200pool -> init (desc ); 201returnComPtr (outPool ,pool ); 202return SLANG_OK ; 203} 204 205void DeviceImpl ::writeTimestamp (IQueryPool * pool ,GfxIndex index ) 206{ 207static_cast < QueryPoolImpl *> (pool )-> m_queries [index ]= 208 std::chrono::high_resolution_clock::now ().time_since_epoch ().count (); 209} 210 211SLANG_NO_THROW const DeviceInfo & SLANG_MCALL DeviceImpl ::getDeviceInfo ()const 212{ 213return m_info ; 214} 215 216SLANG_NO_THROW Result SLANG_MCALL 217DeviceImpl ::createSamplerState (ISamplerState ::Desc const & desc ,ISamplerState ** outSampler ) 218{ 219SLANG_UNUSED (desc ); 220* outSampler = nullptr ; 221return SLANG_OK ; 222} 223 224void * DeviceImpl ::map (IBufferResource * buffer ,MapFlavor flavor ) 225{ 226SLANG_UNUSED (flavor ); 227auto bufferImpl = static_cast < BufferResourceImpl *> (buffer ); 228return bufferImpl -> m_data ; 229} 230void DeviceImpl ::unmap (IBufferResource * buffer ,size_t offsetWritten ,size_t sizeWritten ) 231{ 232SLANG_UNUSED (buffer ); 233SLANG_UNUSED (offsetWritten ); 234SLANG_UNUSED (sizeWritten ); 235} 236 237void DeviceImpl ::setPipelineState (IPipelineState * state ) 238{ 239m_currentPipeline = static_cast < PipelineStateImpl *> (state ); 240} 241 242void DeviceImpl ::bindRootShaderObject (IShaderObject * object ) 243{ 244m_currentRootObject = static_cast < RootShaderObjectImpl *> (object ); 245} 246 247void DeviceImpl ::dispatchCompute (int x ,int y ,int z ) 248{ 249int entryPointIndex = 0 ; 250int targetIndex = 0 ; 251 252// Specialize the compute kernel based on the shader object bindings. 253RefPtr < PipelineStateBase > newPipeline ; 254maybeSpecializePipeline (m_currentPipeline ,m_currentRootObject ,newPipeline ); 255m_currentPipeline = static_cast < PipelineStateImpl *> (newPipeline .Ptr ()); 256 257auto program = m_currentPipeline -> getProgram (); 258auto entryPointLayout = m_currentRootObject -> getLayout ()-> getEntryPoint (entryPointIndex ); 259auto entryPointName = entryPointLayout -> getEntryPointName (); 260 261auto entryPointObject = m_currentRootObject -> getEntryPoint (entryPointIndex ); 262 263ComPtr < ISlangSharedLibrary > sharedLibrary ; 264ComPtr < ISlangBlob > diagnostics ; 265auto compileResult = program -> slangGlobalScope -> getEntryPointHostCallable ( 266entryPointIndex , 267targetIndex , 268sharedLibrary .writeRef (), 269diagnostics .writeRef ()); 270if (diagnostics ) 271 { 272getDebugCallback ()-> handleMessage ( 273compileResult == SLANG_OK ?DebugMessageType ::Warning :DebugMessageType ::Error , 274DebugMessageSource ::Slang , 275 (char * )diagnostics -> getBufferPointer ()); 276 } 277if (SLANG_FAILED (compileResult )) 278return ; 279 280auto func = (slang_prelude::ComputeFunc )sharedLibrary -> findSymbolAddressByName (entryPointName ); 281 282 slang_prelude::ComputeVaryingInput varyingInput ; 283varyingInput .startGroupID .x = 0 ; 284varyingInput .startGroupID .y = 0 ; 285varyingInput .startGroupID .z = 0 ; 286varyingInput .endGroupID .x = x ; 287varyingInput .endGroupID .y = y ; 288varyingInput .endGroupID .z = z ; 289 290auto globalParamsData = m_currentRootObject -> getDataBuffer (); 291auto entryPointParamsData = entryPointObject -> getDataBuffer (); 292func (& varyingInput ,entryPointParamsData ,globalParamsData ); 293} 294 295void DeviceImpl ::copyBuffer ( 296IBufferResource * dst , 297size_t dstOffset , 298IBufferResource * src , 299size_t srcOffset , 300size_t size ) 301{ 302auto dstImpl = static_cast < BufferResourceImpl *> (dst ); 303auto srcImpl = static_cast < BufferResourceImpl *> (src ); 304memcpy ((uint8_t * )dstImpl -> m_data + dstOffset , (uint8_t * )srcImpl -> m_data + srcOffset ,size ); 305} 306 307}// namespace cpu 308 309Result SLANG_MCALL createCPUDevice (const IDevice ::Desc * desc ,IDevice ** outDevice ) 310{ 311RefPtr < cpu::DeviceImpl > result = new cpu::DeviceImpl (); 312SLANG_RETURN_ON_FAIL (result -> initialize (* desc )); 313returnComPtr (outDevice ,result ); 314return SLANG_OK ; 315} 316 317}// namespace gfx