yum-mirror/slang
Making it easier to work with shaders
git clone https://git.yummers.dev/yum-mirror/slang
b118451e3
master
1// d3d11-helper-functions.cpp 2#include "d3d11-helper-functions.h" 3 4#include "d3d11-device.h" 5 6namespace gfx 7{ 8 9using namespace Slang ; 10 11namespace d3d11 12{ 13bool isSupportedNVAPIOp (IUnknown * dev ,uint32_t op ) 14{ 15#ifdef GFX_NVAPI 16 { 17bool isSupported ; 18NvAPI_Status status = 19NvAPI_D3D11_IsNvShaderExtnOpCodeSupported (dev ,NvU32 (op ),& isSupported ); 20return status == NVAPI_OK && isSupported ; 21 } 22#else 23return false; 24#endif 25} 26 27D3D11_BIND_FLAG calcResourceFlag (ResourceState state ) 28{ 29switch (state ) 30 { 31case ResourceState ::VertexBuffer : 32return D3D11_BIND_VERTEX_BUFFER ; 33case ResourceState ::IndexBuffer : 34return D3D11_BIND_INDEX_BUFFER ; 35case ResourceState ::ConstantBuffer : 36return D3D11_BIND_CONSTANT_BUFFER ; 37case ResourceState ::StreamOutput : 38return D3D11_BIND_STREAM_OUTPUT ; 39case ResourceState ::RenderTarget : 40return D3D11_BIND_RENDER_TARGET ; 41case ResourceState ::DepthRead : 42case ResourceState ::DepthWrite : 43return D3D11_BIND_DEPTH_STENCIL ; 44case ResourceState ::UnorderedAccess : 45return D3D11_BIND_UNORDERED_ACCESS ; 46case ResourceState ::ShaderResource : 47case ResourceState ::PixelShaderResource : 48case ResourceState ::NonPixelShaderResource : 49return D3D11_BIND_SHADER_RESOURCE ; 50default : 51return D3D11_BIND_FLAG (0 ); 52 } 53} 54 55int _calcResourceBindFlags (ResourceStateSet allowedStates ) 56{ 57int dstFlags = 0 ; 58for (uint32_t i = 0 ;i < (uint32_t )ResourceState ::_Count ;i ++ ) 59 { 60auto state = (ResourceState )i ; 61if (allowedStates .contains (state )) 62dstFlags |=calcResourceFlag (state ); 63 } 64return dstFlags ; 65} 66 67int _calcResourceAccessFlags (MemoryType memType ) 68{ 69switch (memType ) 70 { 71case MemoryType ::DeviceLocal : 72return 0 ; 73case MemoryType ::ReadBack : 74return D3D11_CPU_ACCESS_READ ; 75case MemoryType ::Upload : 76return D3D11_CPU_ACCESS_WRITE ; 77default : 78assert (!"Invalid flags" ); 79return 0 ; 80 } 81} 82 83D3D11_FILTER_TYPE translateFilterMode (TextureFilteringMode mode ) 84{ 85switch (mode ) 86 { 87default : 88return D3D11_FILTER_TYPE (0 ); 89 90#define CASE (SRC ,DST ) \ 91 case TextureFilteringMode::SRC: \ 92 return D3D11_FILTER_TYPE_##DST 93 94CASE (Point ,POINT ); 95CASE (Linear ,LINEAR ); 96 97#undef CASE 98 } 99} 100 101D3D11_FILTER_REDUCTION_TYPE translateFilterReduction (TextureReductionOp op ) 102{ 103switch (op ) 104 { 105default : 106return D3D11_FILTER_REDUCTION_TYPE (0 ); 107 108#define CASE (SRC ,DST ) \ 109 case TextureReductionOp::SRC: \ 110 return D3D11_FILTER_REDUCTION_TYPE_##DST 111 112CASE (Average ,STANDARD ); 113CASE (Comparison ,COMPARISON ); 114CASE (Minimum ,MINIMUM ); 115CASE (Maximum ,MAXIMUM ); 116 117#undef CASE 118 } 119} 120 121D3D11_TEXTURE_ADDRESS_MODE translateAddressingMode (TextureAddressingMode mode ) 122{ 123switch (mode ) 124 { 125default : 126return D3D11_TEXTURE_ADDRESS_MODE (0 ); 127 128#define CASE (SRC ,DST ) \ 129 case TextureAddressingMode::SRC: \ 130 return D3D11_TEXTURE_ADDRESS_##DST 131 132CASE (Wrap ,WRAP ); 133CASE (ClampToEdge ,CLAMP ); 134CASE (ClampToBorder ,BORDER ); 135CASE (MirrorRepeat ,MIRROR ); 136CASE (MirrorOnce ,MIRROR_ONCE ); 137 138#undef CASE 139 } 140} 141 142D3D11_COMPARISON_FUNC translateComparisonFunc (ComparisonFunc func ) 143{ 144switch (func ) 145 { 146default : 147// TODO: need to report failures 148return D3D11_COMPARISON_ALWAYS ; 149 150#define CASE (FROM ,TO ) \ 151 case ComparisonFunc::FROM: \ 152 return D3D11_COMPARISON_##TO 153 154CASE (Never ,NEVER ); 155CASE (Less ,LESS ); 156CASE (Equal ,EQUAL ); 157CASE (LessEqual ,LESS_EQUAL ); 158CASE (Greater ,GREATER ); 159CASE (NotEqual ,NOT_EQUAL ); 160CASE (GreaterEqual ,GREATER_EQUAL ); 161CASE (Always ,ALWAYS ); 162#undef CASE 163 } 164} 165 166D3D11_STENCIL_OP translateStencilOp (StencilOp op ) 167{ 168switch (op ) 169 { 170default : 171// TODO: need to report failures 172return D3D11_STENCIL_OP_KEEP ; 173 174#define CASE (FROM ,TO ) \ 175 case StencilOp::FROM: \ 176 return D3D11_STENCIL_OP_##TO 177 178CASE (Keep ,KEEP ); 179CASE (Zero ,ZERO ); 180CASE (Replace ,REPLACE ); 181CASE (IncrementSaturate ,INCR_SAT ); 182CASE (DecrementSaturate ,DECR_SAT ); 183CASE (Invert ,INVERT ); 184CASE (IncrementWrap ,INCR ); 185CASE (DecrementWrap ,DECR ); 186#undef CASE 187 } 188} 189 190D3D11_FILL_MODE translateFillMode (FillMode mode ) 191{ 192switch (mode ) 193 { 194default : 195// TODO: need to report failures 196return D3D11_FILL_SOLID ; 197 198case FillMode ::Solid : 199return D3D11_FILL_SOLID ; 200case FillMode ::Wireframe : 201return D3D11_FILL_WIREFRAME ; 202 } 203} 204 205D3D11_CULL_MODE translateCullMode (CullMode mode ) 206{ 207switch (mode ) 208 { 209default : 210// TODO: need to report failures 211return D3D11_CULL_NONE ; 212 213case CullMode ::None : 214return D3D11_CULL_NONE ; 215case CullMode ::Back : 216return D3D11_CULL_BACK ; 217case CullMode ::Front : 218return D3D11_CULL_FRONT ; 219 } 220} 221 222bool isBlendDisabled (AspectBlendDesc const & desc ) 223{ 224return desc .op == BlendOp ::Add && desc .srcFactor == BlendFactor ::One && 225desc .dstFactor == BlendFactor ::Zero ; 226} 227 228 229bool isBlendDisabled (TargetBlendDesc const & desc ) 230{ 231return isBlendDisabled (desc .color )&& isBlendDisabled (desc .alpha ); 232} 233 234D3D11_BLEND_OP translateBlendOp (BlendOp op ) 235{ 236switch (op ) 237 { 238default : 239assert (!"unimplemented" ); 240return (D3D11_BLEND_OP )- 1 ; 241 242#define CASE (FROM ,TO ) \ 243 case BlendOp::FROM: \ 244 return D3D11_BLEND_OP_##TO 245CASE (Add ,ADD ); 246CASE (Subtract ,SUBTRACT ); 247CASE (ReverseSubtract ,REV_SUBTRACT ); 248CASE (Min ,MIN ); 249CASE (Max ,MAX ); 250#undef CASE 251 } 252} 253 254D3D11_BLEND translateBlendFactor (BlendFactor factor ) 255{ 256switch (factor ) 257 { 258default : 259assert (!"unimplemented" ); 260return (D3D11_BLEND )- 1 ; 261 262#define CASE (FROM ,TO ) \ 263 case BlendFactor::FROM: \ 264 return D3D11_BLEND_##TO 265CASE (Zero ,ZERO ); 266CASE (One ,ONE ); 267CASE (SrcColor ,SRC_COLOR ); 268CASE (InvSrcColor ,INV_SRC_COLOR ); 269CASE (SrcAlpha ,SRC_ALPHA ); 270CASE (InvSrcAlpha ,INV_SRC_ALPHA ); 271CASE (DestAlpha ,DEST_ALPHA ); 272CASE (InvDestAlpha ,INV_DEST_ALPHA ); 273CASE (DestColor ,DEST_COLOR ); 274CASE (InvDestColor ,INV_DEST_ALPHA ); 275CASE (SrcAlphaSaturate ,SRC_ALPHA_SAT ); 276CASE (BlendColor ,BLEND_FACTOR ); 277CASE (InvBlendColor ,INV_BLEND_FACTOR ); 278CASE (SecondarySrcColor ,SRC1_COLOR ); 279CASE (InvSecondarySrcColor ,INV_SRC1_COLOR ); 280CASE (SecondarySrcAlpha ,SRC1_ALPHA ); 281CASE (InvSecondarySrcAlpha ,INV_SRC1_ALPHA ); 282#undef CASE 283 } 284} 285 286D3D11_COLOR_WRITE_ENABLE translateRenderTargetWriteMask (RenderTargetWriteMaskT mask ) 287{ 288UINT result = 0 ; 289#define CASE (FROM ,TO ) \ 290 if (mask & RenderTargetWriteMask::Enable##FROM) \ 291 result |= D3D11_COLOR_WRITE_ENABLE_##TO 292 293CASE (Red ,RED ); 294CASE (Green ,GREEN ); 295CASE (Blue ,BLUE ); 296CASE (Alpha ,ALPHA ); 297 298#undef CASE 299return D3D11_COLOR_WRITE_ENABLE (result ); 300} 301 302void initSrvDesc ( 303IResource ::Type resourceType , 304const ITextureResource ::Desc & textureDesc , 305DXGI_FORMAT pixelFormat , 306D3D11_SHADER_RESOURCE_VIEW_DESC & descOut ) 307{ 308// create SRV 309descOut = D3D11_SHADER_RESOURCE_VIEW_DESC (); 310 311descOut .Format = 312 (pixelFormat == DXGI_FORMAT_UNKNOWN ) 313 ?D3DUtil ::calcFormat (D3DUtil ::USAGE_SRV ,D3DUtil ::getMapFormat (textureDesc .format )) 314 :pixelFormat ; 315const int arraySize = calcEffectiveArraySize (textureDesc ); 316if (arraySize <=1 ) 317 { 318switch (textureDesc .type ) 319 { 320case IResource ::Type ::Texture1D : 321descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1D ; 322break ; 323case IResource ::Type ::Texture2D : 324descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D ; 325break ; 326case IResource ::Type ::Texture3D : 327descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D ; 328break ; 329default : 330assert (!"Unknown dimension" ); 331 } 332 333descOut .Texture2D .MipLevels = textureDesc .numMipLevels ; 334descOut .Texture2D .MostDetailedMip = 0 ; 335 } 336else if (resourceType == IResource ::Type ::TextureCube ) 337 { 338if (textureDesc .arraySize > 1 ) 339 { 340descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBEARRAY ; 341 342descOut .TextureCubeArray .NumCubes = textureDesc .arraySize ; 343descOut .TextureCubeArray .First2DArrayFace = 0 ; 344descOut .TextureCubeArray .MipLevels = textureDesc .numMipLevels ; 345descOut .TextureCubeArray .MostDetailedMip = 0 ; 346 } 347else 348 { 349descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURECUBE ; 350 351descOut .TextureCube .MipLevels = textureDesc .numMipLevels ; 352descOut .TextureCube .MostDetailedMip = 0 ; 353 } 354 } 355else 356 { 357assert (textureDesc .size .depth > 1 || arraySize > 1 ); 358 359switch (textureDesc .type ) 360 { 361case IResource ::Type ::Texture1D : 362descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE1DARRAY ; 363break ; 364case IResource ::Type ::Texture2D : 365descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2DARRAY ; 366break ; 367case IResource ::Type ::Texture3D : 368descOut .ViewDimension = D3D11_SRV_DIMENSION_TEXTURE3D ; 369break ; 370 371default : 372assert (!"Unknown dimension" ); 373 } 374 375descOut .Texture2DArray .ArraySize = std::max (textureDesc .size .depth ,arraySize ); 376descOut .Texture2DArray .MostDetailedMip = 0 ; 377descOut .Texture2DArray .MipLevels = textureDesc .numMipLevels ; 378descOut .Texture2DArray .FirstArraySlice = 0 ; 379 } 380} 381}// namespace d3d11 382 383Result SLANG_MCALL getD3D11Adapters (List < AdapterInfo >& outAdapters ) 384{ 385List < ComPtr < IDXGIAdapter >> dxgiAdapters ; 386SLANG_RETURN_ON_FAIL ( 387D3DUtil ::findAdapters (DeviceCheckFlag ::UseHardwareDevice ,nullptr ,dxgiAdapters )); 388 389outAdapters .clear (); 390for (const auto & dxgiAdapter :dxgiAdapters ) 391 { 392DXGI_ADAPTER_DESC desc ; 393dxgiAdapter -> GetDesc (& desc ); 394AdapterInfo info = {}; 395auto name = String ::fromWString (desc .Description ); 396memcpy ( 397info .name , 398name .getBuffer (), 399Math ::Min (name .getLength (), (Index )sizeof (AdapterInfo ::name )- 1 )); 400info .vendorID = desc .VendorId ; 401info .deviceID = desc .DeviceId ; 402info .luid = D3DUtil ::getAdapterLUID (dxgiAdapter ); 403outAdapters .add (info ); 404 } 405return SLANG_OK ; 406} 407 408Result SLANG_MCALL createD3D11Device (const IDevice ::Desc * desc ,IDevice ** outDevice ) 409{ 410RefPtr < d3d11::DeviceImpl > result = new d3d11::DeviceImpl (); 411SLANG_RETURN_ON_FAIL (result -> initialize (* desc )); 412returnComPtr (outDevice ,result ); 413return SLANG_OK ; 414} 415 416}// namespace gfx