yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
8f20632a0
master
1// render.cpp 2#include "../../source/core/slang-blob.h" 3#include "../../source/core/slang-math.h" 4#include "debug-layer/debug-device.h" 5#include "open-gl/render-gl.h" 6#include "renderer-shared.h" 7 8#include <cstring> 9 10namespace gfx 11{ 12using namespace Slang ; 13 14Result SLANG_MCALL createD3D11Device (const IDevice ::Desc * desc ,IDevice ** outDevice ); 15Result SLANG_MCALL createD3D12Device (const IDevice ::Desc * desc ,IDevice ** outDevice ); 16Result SLANG_MCALL createVKDevice (const IDevice ::Desc * desc ,IDevice ** outDevice ); 17Result SLANG_MCALL createMetalDevice (const IDevice ::Desc * desc ,IDevice ** outDevice ); 18Result SLANG_MCALL createCUDADevice (const IDevice ::Desc * desc ,IDevice ** outDevice ); 19Result SLANG_MCALL createCPUDevice (const IDevice ::Desc * desc ,IDevice ** outDevice ); 20 21Result SLANG_MCALL getD3D11Adapters (List < AdapterInfo >& outAdapters ); 22Result SLANG_MCALL getD3D12Adapters (List < AdapterInfo >& outAdapters ); 23Result SLANG_MCALL getVKAdapters (List < AdapterInfo >& outAdapters ); 24Result SLANG_MCALL getMetalAdapters (List < AdapterInfo >& outAdapters ); 25Result SLANG_MCALL getCUDAAdapters (List < AdapterInfo >& outAdapters ); 26 27Result SLANG_MCALL reportD3DLiveObjects (); 28 29// Enable debug layer (validation layer) by default for DEBUG build 30#if _DEBUG 31static bool debugLayerEnabled = true; 32#else 33static bool debugLayerEnabled = false; 34#endif 35 36bool isGfxDebugLayerEnabled () 37{ 38return debugLayerEnabled ; 39} 40 41/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Global Renderer Functions !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ 42 43#define GFX_FORMAT_SIZE (name ,blockSizeInBytes ,pixelsPerBlock ) {blockSizeInBytes, pixelsPerBlock}, 44 45static const uint32_t s_formatSizeInfo [][2 ]= {GFX_FORMAT (GFX_FORMAT_SIZE )}; 46 47static bool _checkFormat () 48{ 49Index value = 0 ; 50Index count = 0 ; 51 52// Check the values are in the same order 53#define GFX_FORMAT_CHECK (name ,blockSizeInBytes ,pixelsPerblock ) \ 54 count += Index(Index(Format::name) == value++); 55GFX_FORMAT (GFX_FORMAT_CHECK ) 56 57const bool r = (count == Index (Format ::_Count )); 58SLANG_ASSERT (r ); 59return r ; 60} 61 62// We don't make static because we will get a warning that it's unused 63static const bool _checkFormatResult = _checkFormat (); 64 65struct FormatInfoMap 66{ 67FormatInfoMap () 68 { 69// Set all to nothing initially 70for (auto & info :m_infos ) 71 { 72info .channelCount = 0 ; 73info .channelType = SLANG_SCALAR_TYPE_NONE ; 74 } 75 76set (Format ::R32G32B32A32_TYPELESS ,SLANG_SCALAR_TYPE_UINT32 ,4 ); 77set (Format ::R32G32B32_TYPELESS ,SLANG_SCALAR_TYPE_UINT32 ,3 ); 78set (Format ::R32G32_TYPELESS ,SLANG_SCALAR_TYPE_UINT32 ,2 ); 79set (Format ::R32_TYPELESS ,SLANG_SCALAR_TYPE_UINT32 ,1 ); 80 81set (Format ::R16G16B16A16_TYPELESS ,SLANG_SCALAR_TYPE_UINT16 ,4 ); 82set (Format ::R16G16_TYPELESS ,SLANG_SCALAR_TYPE_UINT16 ,2 ); 83set (Format ::R16_TYPELESS ,SLANG_SCALAR_TYPE_UINT16 ,1 ); 84 85set (Format ::R8G8B8A8_TYPELESS ,SLANG_SCALAR_TYPE_UINT8 ,4 ); 86set (Format ::R8G8_TYPELESS ,SLANG_SCALAR_TYPE_UINT8 ,2 ); 87set (Format ::R8_TYPELESS ,SLANG_SCALAR_TYPE_UINT8 ,1 ); 88set (Format ::B8G8R8A8_TYPELESS ,SLANG_SCALAR_TYPE_UINT8 ,4 ); 89 90set (Format ::R32G32B32A32_FLOAT ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 91set (Format ::R32G32B32_FLOAT ,SLANG_SCALAR_TYPE_FLOAT32 ,3 ); 92set (Format ::R32G32_FLOAT ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 93set (Format ::R32_FLOAT ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 94 95set (Format ::R16G16B16A16_FLOAT ,SLANG_SCALAR_TYPE_FLOAT16 ,4 ); 96set (Format ::R16G16_FLOAT ,SLANG_SCALAR_TYPE_FLOAT16 ,2 ); 97set (Format ::R16_FLOAT ,SLANG_SCALAR_TYPE_FLOAT16 ,1 ); 98 99set (Format ::R64_UINT ,SLANG_SCALAR_TYPE_UINT64 ,1 ); 100 101set (Format ::R32G32B32A32_UINT ,SLANG_SCALAR_TYPE_UINT32 ,4 ); 102set (Format ::R32G32B32_UINT ,SLANG_SCALAR_TYPE_UINT32 ,3 ); 103set (Format ::R32G32_UINT ,SLANG_SCALAR_TYPE_UINT32 ,2 ); 104set (Format ::R32_UINT ,SLANG_SCALAR_TYPE_UINT32 ,1 ); 105 106set (Format ::R16G16B16A16_UINT ,SLANG_SCALAR_TYPE_UINT16 ,4 ); 107set (Format ::R16G16_UINT ,SLANG_SCALAR_TYPE_UINT16 ,2 ); 108set (Format ::R16_UINT ,SLANG_SCALAR_TYPE_UINT16 ,1 ); 109 110set (Format ::R8G8B8A8_UINT ,SLANG_SCALAR_TYPE_UINT8 ,4 ); 111set (Format ::R8G8_UINT ,SLANG_SCALAR_TYPE_UINT8 ,2 ); 112set (Format ::R8_UINT ,SLANG_SCALAR_TYPE_UINT8 ,1 ); 113 114set (Format ::R64_SINT ,SLANG_SCALAR_TYPE_INT64 ,1 ); 115 116set (Format ::R32G32B32A32_SINT ,SLANG_SCALAR_TYPE_INT32 ,4 ); 117set (Format ::R32G32B32_SINT ,SLANG_SCALAR_TYPE_INT32 ,3 ); 118set (Format ::R32G32_SINT ,SLANG_SCALAR_TYPE_INT32 ,2 ); 119set (Format ::R32_SINT ,SLANG_SCALAR_TYPE_INT32 ,1 ); 120 121set (Format ::R16G16B16A16_SINT ,SLANG_SCALAR_TYPE_INT16 ,4 ); 122set (Format ::R16G16_SINT ,SLANG_SCALAR_TYPE_INT16 ,2 ); 123set (Format ::R16_SINT ,SLANG_SCALAR_TYPE_INT16 ,1 ); 124 125set (Format ::R8G8B8A8_SINT ,SLANG_SCALAR_TYPE_INT8 ,4 ); 126set (Format ::R8G8_SINT ,SLANG_SCALAR_TYPE_INT8 ,2 ); 127set (Format ::R8_SINT ,SLANG_SCALAR_TYPE_INT8 ,1 ); 128 129set (Format ::R16G16B16A16_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 130set (Format ::R16G16_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 131set (Format ::R16_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 132 133set (Format ::R8G8B8A8_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 134set (Format ::R8G8B8A8_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 135set (Format ::R8G8_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 136set (Format ::R8_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 137set (Format ::B8G8R8A8_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 138set (Format ::B8G8R8A8_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 139set (Format ::B8G8R8X8_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 140set (Format ::B8G8R8X8_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 141 142set (Format ::R16G16B16A16_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 143set (Format ::R16G16_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 144set (Format ::R16_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 145 146set (Format ::R8G8B8A8_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 147set (Format ::R8G8_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 148set (Format ::R8_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 149 150set (Format ::D32_FLOAT ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 151set (Format ::D16_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ); 152set (Format ::D32_FLOAT_S8_UINT ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 153set (Format ::R32_FLOAT_X32_TYPELESS ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ); 154 155set (Format ::B4G4R4A4_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 156set (Format ::B5G6R5_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,3 ); 157set (Format ::B5G5R5A1_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 158 159set (Format ::R9G9B9E5_SHAREDEXP ,SLANG_SCALAR_TYPE_FLOAT32 ,3 ); 160set (Format ::R10G10B10A2_TYPELESS ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 161set (Format ::R10G10B10A2_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ); 162set (Format ::R10G10B10A2_UINT ,SLANG_SCALAR_TYPE_UINT32 ,4 ); 163set (Format ::R11G11B10_FLOAT ,SLANG_SCALAR_TYPE_FLOAT32 ,3 ); 164 165set (Format ::BC1_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 166set (Format ::BC1_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 167set (Format ::BC2_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 168set (Format ::BC2_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 169set (Format ::BC3_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 170set (Format ::BC3_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 171set (Format ::BC4_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ,4 ,4 ); 172set (Format ::BC4_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,1 ,4 ,4 ); 173set (Format ::BC5_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ,4 ,4 ); 174set (Format ::BC5_SNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,2 ,4 ,4 ); 175set (Format ::BC6H_UF16 ,SLANG_SCALAR_TYPE_FLOAT32 ,3 ,4 ,4 ); 176set (Format ::BC6H_SF16 ,SLANG_SCALAR_TYPE_FLOAT32 ,3 ,4 ,4 ); 177set (Format ::BC7_UNORM ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 178set (Format ::BC7_UNORM_SRGB ,SLANG_SCALAR_TYPE_FLOAT32 ,4 ,4 ,4 ); 179 } 180 181void set ( 182Format format , 183SlangScalarType type , 184Index channelCount , 185uint32_t blockWidth = 1 , 186uint32_t blockHeight = 1 ) 187 { 188FormatInfo & info = m_infos [Index (format )]; 189info .channelCount = uint8_t (channelCount ); 190info .channelType = uint8_t (type ); 191 192auto sizeInfo = s_formatSizeInfo [Index (format )]; 193info .blockSizeInBytes = sizeInfo [0 ]; 194info .pixelsPerBlock = sizeInfo [1 ]; 195info .blockWidth = blockWidth ; 196info .blockHeight = blockHeight ; 197 } 198 199const FormatInfo & get (Format format )const {return m_infos [Index (format )]; } 200 201FormatInfo m_infos [Index (Format ::_Count )]; 202}; 203 204static const FormatInfoMap s_formatInfoMap ; 205 206static void _compileTimeAsserts () 207{ 208SLANG_COMPILE_TIME_ASSERT (SLANG_COUNT_OF (s_formatSizeInfo )== int (Format ::_Count )); 209} 210 211extern "C" 212{ 213SLANG_GFX_API bool SLANG_MCALL gfxIsCompressedFormat (Format format ) 214 { 215switch (format ) 216 { 217case Format ::BC1_UNORM : 218case Format ::BC1_UNORM_SRGB : 219case Format ::BC2_UNORM : 220case Format ::BC2_UNORM_SRGB : 221case Format ::BC3_UNORM : 222case Format ::BC3_UNORM_SRGB : 223case Format ::BC4_UNORM : 224case Format ::BC4_SNORM : 225case Format ::BC5_UNORM : 226case Format ::BC5_SNORM : 227case Format ::BC6H_UF16 : 228case Format ::BC6H_SF16 : 229case Format ::BC7_UNORM : 230case Format ::BC7_UNORM_SRGB : 231return true; 232default : 233return false; 234 } 235 } 236 237SLANG_GFX_API bool SLANG_MCALL gfxIsTypelessFormat (Format format ) 238 { 239switch (format ) 240 { 241case Format ::R32G32B32A32_TYPELESS : 242case Format ::R32G32B32_TYPELESS : 243case Format ::R32G32_TYPELESS : 244case Format ::R32_TYPELESS : 245case Format ::R16G16B16A16_TYPELESS : 246case Format ::R16G16_TYPELESS : 247case Format ::R16_TYPELESS : 248case Format ::R8G8B8A8_TYPELESS : 249case Format ::R8G8_TYPELESS : 250case Format ::R8_TYPELESS : 251case Format ::B8G8R8A8_TYPELESS : 252case Format ::R10G10B10A2_TYPELESS : 253return true; 254default : 255return false; 256 } 257 } 258 259SLANG_GFX_API SlangResult SLANG_MCALL gfxGetFormatInfo (Format format ,FormatInfo * outInfo ) 260 { 261* outInfo = s_formatInfoMap .get (format ); 262return SLANG_OK ; 263 } 264 265SLANG_GFX_API SlangResult SLANG_MCALL 266gfxGetAdapters (DeviceType type ,ISlangBlob ** outAdaptersBlob ) 267 { 268List < AdapterInfo > adapters ; 269 270switch (type ) 271 { 272#if SLANG_ENABLE_DIRECTX 273case DeviceType ::DirectX11 : 274SLANG_RETURN_ON_FAIL (getD3D11Adapters (adapters )); 275break ; 276case DeviceType ::DirectX12 : 277SLANG_RETURN_ON_FAIL (getD3D12Adapters (adapters )); 278break ; 279#endif 280#if SLANG_WINDOWS_FAMILY 281case DeviceType ::OpenGl : 282return SLANG_E_NOT_IMPLEMENTED ; 283#endif 284#if SLANG_WINDOWS_FAMILY || SLANG_LINUX_FAMILY 285// Assume no Vulkan or CUDA on MacOS or Cygwin 286case DeviceType ::Vulkan : 287SLANG_RETURN_ON_FAIL (getVKAdapters (adapters )); 288break ; 289case DeviceType ::CUDA : 290SLANG_RETURN_ON_FAIL (getCUDAAdapters (adapters )); 291break ; 292#endif 293#if SLANG_APPLE_FAMILY 294case DeviceType ::Vulkan : 295SLANG_RETURN_ON_FAIL (getVKAdapters (adapters )); 296break ; 297case DeviceType ::Metal : 298SLANG_RETURN_ON_FAIL (getMetalAdapters (adapters )); 299break ; 300#endif 301case DeviceType ::CPU : 302return SLANG_E_NOT_IMPLEMENTED ; 303default : 304return SLANG_E_INVALID_ARG ; 305 } 306 307auto adaptersBlob = 308RawBlob ::create (adapters .getBuffer (),adapters .getCount ()* sizeof (AdapterInfo )); 309if (outAdaptersBlob ) 310returnComPtr (outAdaptersBlob ,adaptersBlob ); 311 312return SLANG_OK ; 313 } 314 315SlangResult _createDevice (const IDevice ::Desc * desc ,IDevice ** outDevice ) 316 { 317switch (desc -> deviceType ) 318 { 319#if SLANG_ENABLE_DIRECTX 320case DeviceType ::DirectX11 : 321 { 322return createD3D11Device (desc ,outDevice ); 323 } 324case DeviceType ::DirectX12 : 325 { 326return createD3D12Device (desc ,outDevice ); 327 } 328#endif 329#if SLANG_WINDOWS_FAMILY 330case DeviceType ::OpenGl : 331 { 332return createGLDevice (desc ,outDevice ); 333 } 334case DeviceType ::Vulkan : 335 { 336return createVKDevice (desc ,outDevice ); 337 } 338case DeviceType ::Default : 339 { 340IDevice ::Desc newDesc = * desc ; 341newDesc .deviceType = DeviceType ::DirectX12 ; 342if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 343return SLANG_OK ; 344newDesc .deviceType = DeviceType ::Vulkan ; 345if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 346return SLANG_OK ; 347newDesc .deviceType = DeviceType ::DirectX11 ; 348if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 349return SLANG_OK ; 350newDesc .deviceType = DeviceType ::OpenGl ; 351if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 352return SLANG_OK ; 353return SLANG_FAIL ; 354 } 355break ; 356#elif SLANG_APPLE_FAMILY 357case DeviceType ::Vulkan : 358 { 359return createVKDevice (desc ,outDevice ); 360 } 361case DeviceType ::Metal : 362 { 363return createMetalDevice (desc ,outDevice ); 364 } 365case DeviceType ::Default : 366 { 367IDevice ::Desc newDesc = * desc ; 368newDesc .deviceType = DeviceType ::Metal ; 369if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 370return SLANG_OK ; 371newDesc .deviceType = DeviceType ::Vulkan ; 372if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 373return SLANG_OK ; 374return SLANG_FAIL ; 375 } 376#elif SLANG_LINUX_FAMILY && !defined(__CYGWIN__ ) 377case DeviceType ::Vulkan : 378 { 379return createVKDevice (desc ,outDevice ); 380 } 381case DeviceType ::Default : 382 { 383IDevice ::Desc newDesc = * desc ; 384newDesc .deviceType = DeviceType ::Vulkan ; 385if (_createDevice (& newDesc ,outDevice )== SLANG_OK ) 386return SLANG_OK ; 387return SLANG_FAIL ; 388 } 389#endif 390case DeviceType ::CUDA : 391 { 392return createCUDADevice (desc ,outDevice ); 393 } 394case DeviceType ::CPU : 395 { 396return createCPUDevice (desc ,outDevice ); 397 } 398break ; 399 400default : 401return SLANG_FAIL ; 402 } 403 } 404 405SLANG_GFX_API SlangResult SLANG_MCALL 406gfxCreateDevice (const IDevice ::Desc * desc ,IDevice ** outDevice ) 407 { 408ComPtr < IDevice > innerDevice ; 409auto resultCode = _createDevice (desc ,innerDevice .writeRef ()); 410if (SLANG_FAILED (resultCode )) 411return resultCode ; 412if (!debugLayerEnabled ) 413 { 414returnComPtr (outDevice ,innerDevice ); 415return resultCode ; 416 } 417RefPtr < debug::DebugDevice > debugDevice = new debug::DebugDevice (); 418debugDevice -> baseObject = innerDevice ; 419returnComPtr (outDevice ,debugDevice ); 420return resultCode ; 421 } 422 423SLANG_GFX_API SlangResult SLANG_MCALL gfxReportLiveObjects () 424 { 425#if SLANG_ENABLE_DIRECTX 426SLANG_RETURN_ON_FAIL (reportD3DLiveObjects ()); 427#endif 428return SLANG_OK ; 429 } 430 431SLANG_GFX_API SlangResult SLANG_MCALL gfxSetDebugCallback (IDebugCallback * callback ) 432 { 433_getDebugCallback ()= callback ; 434return SLANG_OK ; 435 } 436 437SLANG_GFX_API void SLANG_MCALL gfxEnableDebugLayer (bool enable ) 438 { 439debugLayerEnabled = enable ; 440 } 441 442const char * SLANG_MCALL gfxGetDeviceTypeName (DeviceType type ) 443 { 444switch (type ) 445 { 446case gfx::DeviceType ::Unknown : 447return "Unknown" ; 448case gfx::DeviceType ::Default : 449return "Default" ; 450case gfx::DeviceType ::DirectX11 : 451return "DirectX11" ; 452case gfx::DeviceType ::DirectX12 : 453return "DirectX12" ; 454case gfx::DeviceType ::OpenGl : 455return "OpenGL" ; 456case gfx::DeviceType ::Vulkan : 457return "Vulkan" ; 458case gfx::DeviceType ::Metal : 459return "Metal" ; 460case gfx::DeviceType ::CPU : 461return "CPU" ; 462case gfx::DeviceType ::CUDA : 463return "CUDA" ; 464default : 465return "?" ; 466 } 467 } 468 469 470void SLANG_MCALL gfxGetIdentityProjection (ProjectionStyle style ,float projMatrix [16 ]) 471 { 472switch (style ) 473 { 474case ProjectionStyle ::DirectX : 475case ProjectionStyle ::OpenGl : 476 { 477static const float kIdentity []= {1 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1 }; 478 ::memcpy (projMatrix ,kIdentity ,sizeof (kIdentity )); 479break ; 480 } 481case ProjectionStyle ::Vulkan : 482 { 483static const float kIdentity []= {1 ,0 ,0 ,0 ,0 ,-1 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,1 }; 484 ::memcpy (projMatrix ,kIdentity ,sizeof (kIdentity )); 485break ; 486 } 487default : 488 { 489assert (!"Not handled" ); 490 } 491 } 492 } 493} 494 495}// namespace gfx