summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorskallweitNV <64953474+skallweitNV@users.noreply.github.com>2022-11-03 16:58:49 +0100
committerGitHub <noreply@github.com>2022-11-03 11:58:49 -0400
commit8f9d58416934cbf850f0f01e5fefbdfe1b02d4d6 (patch)
tree3d376e772dcaeb7d0ef55d091fe49e33a6f57fb1
parent203b5d7a5014d7f140345567e065cbf57b57b819 (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.h49
-rw-r--r--tools/gfx/cuda/cuda-helper-functions.cpp23
-rw-r--r--tools/gfx/cuda/cuda-helper-functions.h5
-rw-r--r--tools/gfx/d3d11/d3d11-helper-functions.cpp21
-rw-r--r--tools/gfx/d3d11/d3d11-helper-functions.h3
-rw-r--r--tools/gfx/d3d12/d3d12-helper-functions.cpp21
-rw-r--r--tools/gfx/d3d12/d3d12-helper-functions.h3
-rw-r--r--tools/gfx/render.cpp48
-rw-r--r--tools/gfx/vulkan/vk-helper-functions.cpp39
-rw-r--r--tools/gfx/vulkan/vk-helper-functions.h2
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