diff options
| author | skallweitNV <64953474+skallweitNV@users.noreply.github.com> | 2022-11-03 16:58:49 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-11-03 11:58:49 -0400 |
| commit | 8f9d58416934cbf850f0f01e5fefbdfe1b02d4d6 (patch) | |
| tree | 3d376e772dcaeb7d0ef55d091fe49e33a6f57fb1 | |
| parent | 203b5d7a5014d7f140345567e065cbf57b57b819 (diff) | |
Add gfxGetAdapters function (currently implemented for D3D12/Vulkan) (#2486)
* Add gfxGetAdapters function (currently implemented for D3D12/Vulkan)
* Extend to handle DirectX11 and CUDA
* Use blob to return adapter list and add AdapterList helper
* Replace strncpy with memcpy
Co-authored-by: jsmall-nvidia <jsmall@nvidia.com>
| -rw-r--r-- | slang-gfx.h | 49 | ||||
| -rw-r--r-- | tools/gfx/cuda/cuda-helper-functions.cpp | 23 | ||||
| -rw-r--r-- | tools/gfx/cuda/cuda-helper-functions.h | 5 | ||||
| -rw-r--r-- | tools/gfx/d3d11/d3d11-helper-functions.cpp | 21 | ||||
| -rw-r--r-- | tools/gfx/d3d11/d3d11-helper-functions.h | 3 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-helper-functions.cpp | 21 | ||||
| -rw-r--r-- | tools/gfx/d3d12/d3d12-helper-functions.h | 3 | ||||
| -rw-r--r-- | tools/gfx/render.cpp | 48 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-helper-functions.cpp | 39 | ||||
| -rw-r--r-- | tools/gfx/vulkan/vk-helper-functions.h | 2 |
10 files changed, 207 insertions, 7 deletions
diff --git a/slang-gfx.h b/slang-gfx.h index 6b06b6375..5decc9010 100644 --- a/slang-gfx.h +++ b/slang-gfx.h @@ -98,7 +98,7 @@ enum class DeviceType enum class ProjectionStyle { Unknown, - OpenGl, + OpenGl, DirectX, Vulkan, CountOf, @@ -415,7 +415,7 @@ enum class Format // TODO: Width/Height/Depth/whatever should not be used. We should use extentX, extentY, etc. struct FormatInfo { - GfxCount channelCount; ///< The amount of channels in the format. Only set if the channelType is set + GfxCount channelCount; ///< The amount of channels in the format. Only set if the channelType is set uint8_t channelType; ///< One of SlangScalarType None if type isn't made up of elements of type. TODO: Change to uint32_t? Size blockSizeInBytes; ///< The size of a block in bytes. @@ -588,7 +588,7 @@ public: virtual SLANG_NO_THROW Type SLANG_MCALL getType() = 0; virtual SLANG_NO_THROW Result SLANG_MCALL getNativeResourceHandle(InteropHandle* outHandle) = 0; virtual SLANG_NO_THROW Result SLANG_MCALL getSharedHandle(InteropHandle* outHandle) = 0; - + virtual SLANG_NO_THROW Result SLANG_MCALL setDebugName(const char* name) = 0; virtual SLANG_NO_THROW const char* SLANG_MCALL getDebugName() = 0; @@ -2071,6 +2071,32 @@ public: 0x8eccc8ec, 0x5c04, 0x4a51, { 0x99, 0x75, 0x13, 0xf8, 0xfe, 0xa1, 0x59, 0xf3 } \ } +struct AdapterInfo +{ + char name[128]; + uint32_t vendorID; + uint32_t deviceID; +}; + +class AdapterList +{ +public: + AdapterList(ISlangBlob* blob) : m_blob(blob) {} + + const AdapterInfo* getAdapters() const + { + return reinterpret_cast<const AdapterInfo*>(m_blob ? m_blob->getBufferPointer() : nullptr); + } + + GfxCount getCount() const + { + return (GfxCount)(m_blob ? m_blob->getBufferSize() / sizeof(AdapterInfo) : 0); + } + +private: + ComPtr<ISlangBlob> m_blob; +}; + struct DeviceInfo { DeviceType deviceType; @@ -2394,7 +2420,7 @@ public: slang::TypeReflection* type, ShaderObjectContainerType container, IShaderObject** outObject) = 0; - + virtual SLANG_NO_THROW Result SLANG_MCALL createShaderObjectFromTypeLayout( slang::TypeLayoutReflection* typeLayout, IShaderObject** outObject) = 0; @@ -2472,7 +2498,7 @@ public: virtual SLANG_NO_THROW Result SLANG_MCALL createQueryPool( const IQueryPool::Desc& desc, IQueryPool** outPool) = 0; - + virtual SLANG_NO_THROW Result SLANG_MCALL getAccelerationStructurePrebuildInfo( const IAccelerationStructure::BuildInputs& buildInputs, IAccelerationStructure::PrebuildInfo* outPrebuildInfo) = 0; @@ -2538,9 +2564,12 @@ extern "C" /// Checks if format is typeless SLANG_GFX_API bool SLANG_MCALL gfxIsTypelessFormat(Format format); - /// Gets information about the format + /// Gets information about the format SLANG_GFX_API SlangResult SLANG_MCALL gfxGetFormatInfo(Format format, FormatInfo* outInfo); + /// Gets a list of available adapters for a given device type + SLANG_GFX_API SlangResult SLANG_MCALL gfxGetAdapters(DeviceType type, ISlangBlob** outAdaptersBlob); + /// Given a type returns a function that can construct it, or nullptr if there isn't one SLANG_GFX_API SlangResult SLANG_MCALL gfxCreateDevice(const IDevice::Desc* desc, IDevice** outDevice); @@ -2557,6 +2586,14 @@ extern "C" SLANG_GFX_API const char* SLANG_MCALL gfxGetDeviceTypeName(DeviceType type); } +/// Gets a list of available adapters for a given device type +inline AdapterList gfxGetAdapters(DeviceType type) +{ + ComPtr<ISlangBlob> blob; + gfxGetAdapters(type, blob.writeRef()); + return AdapterList(blob); +} + // Extended descs. struct D3D12ExperimentalFeaturesDesc { diff --git a/tools/gfx/cuda/cuda-helper-functions.cpp b/tools/gfx/cuda/cuda-helper-functions.cpp index 6325d9fc6..702caf253 100644 --- a/tools/gfx/cuda/cuda-helper-functions.cpp +++ b/tools/gfx/cuda/cuda-helper-functions.cpp @@ -72,6 +72,22 @@ void _optixLogCallback(unsigned int level, const char* tag, const char* message, # endif } // namespace cuda +Result SLANG_MCALL getCUDAAdapters(List<AdapterInfo>& outAdapters) +{ + int count; + cudaGetDeviceCount(&count); + for (int i = 0; i < count; i++) + { + cudaDeviceProp prop; + cudaGetDeviceProperties(&prop, i); + AdapterInfo info = {}; + memcpy(info.name, prop.name, Math::Min(strlen(prop.name), sizeof(AdapterInfo::name) - 1)); + outAdapters.add(info); + } + + return SLANG_OK; +} + Result SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice) { RefPtr<cuda::DeviceImpl> result = new cuda::DeviceImpl(); @@ -80,6 +96,13 @@ returnComPtr(outDevice, result); return SLANG_OK; } #else + +Result SLANG_MCALL getCUDAAdapters(List<AdapterInfo>& outAdapters) +{ + SLANG_UNUSED(outAdapters); + return SLANG_FAIL; +} + Result SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice) { SLANG_UNUSED(desc); diff --git a/tools/gfx/cuda/cuda-helper-functions.h b/tools/gfx/cuda/cuda-helper-functions.h index 001e3946a..92ac4f4ed 100644 --- a/tools/gfx/cuda/cuda-helper-functions.h +++ b/tools/gfx/cuda/cuda-helper-functions.h @@ -3,12 +3,13 @@ #include "slang-gfx.h" #include "cuda-base.h" +#include "../../../source/core/slang-list.h" namespace gfx { -#ifdef GFX_ENABLE_CUDA using namespace Slang; +#ifdef GFX_ENABLE_CUDA namespace cuda { SLANG_FORCE_INLINE bool _isError(CUresult result) { return result != 0; } @@ -101,6 +102,8 @@ void _optixLogCallback(unsigned int level, const char* tag, const char* message, } // namespace cuda #endif +Result SLANG_MCALL getCUDAAdapters(List<AdapterInfo>& outAdapters); + Result SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice); } // namespace gfx diff --git a/tools/gfx/d3d11/d3d11-helper-functions.cpp b/tools/gfx/d3d11/d3d11-helper-functions.cpp index c797979ce..93065077a 100644 --- a/tools/gfx/d3d11/d3d11-helper-functions.cpp +++ b/tools/gfx/d3d11/d3d11-helper-functions.cpp @@ -345,6 +345,27 @@ namespace d3d11 } } // namespace d3d11 +Result SLANG_MCALL getD3D11Adapters(List<AdapterInfo>& outAdapters) +{ + List<ComPtr<IDXGIAdapter>> dxgiAdapters; + DeviceCheckFlags flags = DeviceCheckFlag::UseHardwareDevice; + SLANG_RETURN_ON_FAIL(D3DUtil::findAdapters(flags, UnownedStringSlice(), dxgiAdapters)); + + outAdapters.clear(); + for (const auto& dxgiAdapter : dxgiAdapters) + { + DXGI_ADAPTER_DESC desc; + dxgiAdapter->GetDesc(&desc); + AdapterInfo info = {}; + auto name = String::fromWString(desc.Description); + memcpy(info.name, name.getBuffer(), Math::Min(name.getLength(), (Index)sizeof(AdapterInfo::name) - 1)); + info.vendorID = desc.VendorId; + info.deviceID = desc.DeviceId; + outAdapters.add(info); + } + return SLANG_OK; +} + Result SLANG_MCALL createD3D11Device(const IDevice::Desc* desc, IDevice** outDevice) { RefPtr<d3d11::DeviceImpl> result = new d3d11::DeviceImpl(); diff --git a/tools/gfx/d3d11/d3d11-helper-functions.h b/tools/gfx/d3d11/d3d11-helper-functions.h index 266ba0973..9f115d88d 100644 --- a/tools/gfx/d3d11/d3d11-helper-functions.h +++ b/tools/gfx/d3d11/d3d11-helper-functions.h @@ -3,6 +3,7 @@ #include "slang-gfx.h" #include "d3d11-base.h" +#include "../../../source/core/slang-list.h" namespace gfx { @@ -281,6 +282,8 @@ namespace d3d11 D3D11_SHADER_RESOURCE_VIEW_DESC& descOut); } // namespace d3d11 +Result SLANG_MCALL getD3D11Adapters(List<AdapterInfo>& outAdapters); + Result SLANG_MCALL createD3D11Device(const IDevice::Desc* desc, IDevice** outDevice); } // namespace gfx diff --git a/tools/gfx/d3d12/d3d12-helper-functions.cpp b/tools/gfx/d3d12/d3d12-helper-functions.cpp index 5f9102d0c..34efa8401 100644 --- a/tools/gfx/d3d12/d3d12-helper-functions.cpp +++ b/tools/gfx/d3d12/d3d12-helper-functions.cpp @@ -613,6 +613,27 @@ void translatePostBuildInfoDescs( } // namespace d3d12 +Result SLANG_MCALL getD3D12Adapters(List<AdapterInfo>& outAdapters) +{ + List<ComPtr<IDXGIAdapter>> dxgiAdapters; + DeviceCheckFlags flags = DeviceCheckFlag::UseHardwareDevice; + SLANG_RETURN_ON_FAIL(D3DUtil::findAdapters(flags, UnownedStringSlice(), dxgiAdapters)); + + outAdapters.clear(); + for (const auto& dxgiAdapter : dxgiAdapters) + { + DXGI_ADAPTER_DESC desc; + dxgiAdapter->GetDesc(&desc); + AdapterInfo info = {}; + auto name = String::fromWString(desc.Description); + memcpy(info.name, name.getBuffer(), Math::Min(name.getLength(), (Index)sizeof(AdapterInfo::name) - 1)); + info.vendorID = desc.VendorId; + info.deviceID = desc.DeviceId; + outAdapters.add(info); + } + return SLANG_OK; +} + Result SLANG_MCALL createD3D12Device(const IDevice::Desc* desc, IDevice** outDevice) { RefPtr<d3d12::DeviceImpl> result = new d3d12::DeviceImpl(); diff --git a/tools/gfx/d3d12/d3d12-helper-functions.h b/tools/gfx/d3d12/d3d12-helper-functions.h index 97f75a654..52b587529 100644 --- a/tools/gfx/d3d12/d3d12-helper-functions.h +++ b/tools/gfx/d3d12/d3d12-helper-functions.h @@ -6,6 +6,7 @@ #include "d3d12-shader-object-layout.h" #include "d3d12-submitter.h" #include "../../../source/core/slang-short-list.h" +#include "../../../source/core/slang-list.h" #ifndef __ID3D12GraphicsCommandList1_FWD_DEFINED__ // If can't find a definition of CommandList1, just use an empty definition @@ -84,6 +85,8 @@ void translatePostBuildInfoDescs( } // namespace d3d12 +Result SLANG_MCALL getD3D12Adapters(List<AdapterInfo>& outAdapters); + Result SLANG_MCALL createD3D12Device(const IDevice::Desc* desc, IDevice** outDevice); } // namespace gfx diff --git a/tools/gfx/render.cpp b/tools/gfx/render.cpp index b19824671..84f537705 100644 --- a/tools/gfx/render.cpp +++ b/tools/gfx/render.cpp @@ -1,6 +1,7 @@ // render.cpp #include "renderer-shared.h" #include "../../source/core/slang-math.h" +#include "../../source/core/slang-blob.h" #include "open-gl/render-gl.h" #include "debug-layer/debug-device.h" @@ -15,6 +16,11 @@ Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outDevice Result SLANG_MCALL createCUDADevice(const IDevice::Desc* desc, IDevice** outDevice); Result SLANG_MCALL createCPUDevice(const IDevice::Desc* desc, IDevice** outDevice); +Result SLANG_MCALL getD3D11Adapters(List<AdapterInfo>& outAdapters); +Result SLANG_MCALL getD3D12Adapters(List<AdapterInfo>& outAdapters); +Result SLANG_MCALL getVKAdapters(List<AdapterInfo>& outAdapters); +Result SLANG_MCALL getCUDAAdapters(List<AdapterInfo>& outAdapters); + static bool debugLayerEnabled = false; bool isGfxDebugLayerEnabled() { return debugLayerEnabled; } @@ -233,6 +239,48 @@ extern "C" return SLANG_OK; } + SLANG_GFX_API SlangResult SLANG_MCALL gfxGetAdapters(DeviceType type, ISlangBlob** outAdaptersBlob) + { + List<AdapterInfo> adapters; + + switch (type) + { +#if SLANG_WINDOWS_FAMILY + case DeviceType::DirectX11: + SLANG_RETURN_ON_FAIL(getD3D11Adapters(adapters)); + break; + case DeviceType::DirectX12: + SLANG_RETURN_ON_FAIL(getD3D12Adapters(adapters)); + break; + case DeviceType::OpenGl: + return SLANG_E_NOT_IMPLEMENTED; + case DeviceType::Vulkan: + SLANG_RETURN_ON_FAIL(getVKAdapters(adapters)); + break; + case DeviceType::CUDA: + SLANG_RETURN_ON_FAIL(getCUDAAdapters(adapters)); + break; +#elif SLANG_LINUX_FAMILY && !defined(__CYGWIN__) + case DeviceType::Vulkan: + SLANG_RETURN_ON_FAIL(getVKAdapters(adapters)); + break; + case DeviceType::CUDA: + SLANG_RETURN_ON_FAIL(getCUDAAdapters(adapters)); + break; +#endif + case DeviceType::CPU: + return SLANG_E_NOT_IMPLEMENTED; + default: + return SLANG_E_INVALID_ARG; + } + + auto adaptersBlob = RawBlob::create(adapters.getBuffer(), adapters.getCount() * sizeof(AdapterInfo)); + if (outAdaptersBlob) + returnComPtr(outAdaptersBlob, adaptersBlob); + + return SLANG_OK; + } + SlangResult _createDevice(const IDevice::Desc* desc, IDevice** outDevice) { switch (desc->deviceType) diff --git a/tools/gfx/vulkan/vk-helper-functions.cpp b/tools/gfx/vulkan/vk-helper-functions.cpp index aa6c42ec5..da2b55fd2 100644 --- a/tools/gfx/vulkan/vk-helper-functions.cpp +++ b/tools/gfx/vulkan/vk-helper-functions.cpp @@ -2,6 +2,7 @@ #include "vk-helper-functions.h" #include "vk-device.h" +#include "vk-util.h" namespace gfx { @@ -451,6 +452,44 @@ VkImageAspectFlags getAspectMaskFromFormat(VkFormat format) } // namespace vk +Result SLANG_MCALL getVKAdapters(List<AdapterInfo>& outAdapters) +{ + VulkanModule module; + SLANG_RETURN_ON_FAIL(module.init(false)); + VulkanApi api; + SLANG_RETURN_ON_FAIL(api.initGlobalProcs(module)); + + VkInstanceCreateInfo instanceCreateInfo = { VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO }; + VkInstance instance; + SLANG_VK_RETURN_ON_FAIL(api.vkCreateInstance(&instanceCreateInfo, nullptr, &instance)); + + // This will fail due to not loading any extensions. + api.initInstanceProcs(instance); + // Make sure required functions for enumerating physical devices were loaded. + if (!api.vkEnumeratePhysicalDevices || !api.vkGetPhysicalDeviceProperties) + return SLANG_FAIL; + + uint32_t numPhysicalDevices = 0; + SLANG_VK_RETURN_ON_FAIL(api.vkEnumeratePhysicalDevices(instance, &numPhysicalDevices, nullptr)); + + List<VkPhysicalDevice> physicalDevices; + physicalDevices.setCount(numPhysicalDevices); + SLANG_VK_RETURN_ON_FAIL(api.vkEnumeratePhysicalDevices(instance, &numPhysicalDevices, physicalDevices.getBuffer())); + + for (const auto& physicalDevice : physicalDevices) + { + VkPhysicalDeviceProperties props; + api.vkGetPhysicalDeviceProperties(physicalDevice, &props); + AdapterInfo info = {}; + memcpy(info.name, props.deviceName, Math::Min(strlen(props.deviceName), sizeof(AdapterInfo::name) - 1)); + info.vendorID = props.vendorID; + info.deviceID = props.deviceID; + outAdapters.add(info); + } + + return SLANG_OK; +} + Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outRenderer) { RefPtr<vk::DeviceImpl> result = new vk::DeviceImpl(); diff --git a/tools/gfx/vulkan/vk-helper-functions.h b/tools/gfx/vulkan/vk-helper-functions.h index 86233027c..cc80cde40 100644 --- a/tools/gfx/vulkan/vk-helper-functions.h +++ b/tools/gfx/vulkan/vk-helper-functions.h @@ -177,6 +177,8 @@ VkImageAspectFlags getAspectMaskFromFormat(VkFormat format); } // namespace vk +Result SLANG_MCALL getVKAdapters(List<AdapterInfo>& outAdapters); + Result SLANG_MCALL createVKDevice(const IDevice::Desc* desc, IDevice** outRenderer); } // namespace gfx |
