Skip to content

Commit

Permalink
v1.116
Browse files Browse the repository at this point in the history
HIGHLIGHTS:

- fixes and improvements
- merged PRs from users

DETAILS:

NRI: retrieve adapter desc as early as possible to improve message reporting
NRI: fixed "GetDisplayDesc" behavior if a window is outside of all displays
NRI: improved error reporting
VK: added missing forward declaration in wrapper ext
VK: improved memory type selection
VK: fixed wrapper compatibility with C interface
  • Loading branch information
dzhdanNV committed Jan 29, 2024
1 parent 63e18b8 commit a746a1e
Show file tree
Hide file tree
Showing 9 changed files with 189 additions and 156 deletions.
2 changes: 1 addition & 1 deletion Include/Extensions/NRISwapChain.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ NRI_STRUCT(SwapChainInterface)
NRI_NAME(Texture)* const* (NRI_CALL *GetSwapChainTextures)(const NRI_NAME_REF(SwapChain) swapChain, uint32_t NRI_REF textureNum);
uint32_t (NRI_CALL *AcquireNextSwapChainTexture)(NRI_NAME_REF(SwapChain) swapChain); // IMPORTANT: return OUT_OF_DATE index to indicate "out of date" swap chain status (VK only)
NRI_NAME(Result) (NRI_CALL *SwapChainPresent)(NRI_NAME_REF(SwapChain) swapChain);
NRI_NAME(Result) (NRI_CALL *GetDisplayDesc)(NRI_NAME_REF(SwapChain) swapChain, NRI_NAME_REF(DisplayDesc) displayDesc);
NRI_NAME(Result) (NRI_CALL *GetDisplayDesc)(NRI_NAME_REF(SwapChain) swapChain, NRI_NAME_REF(DisplayDesc) displayDesc); // returns FAILURE if window is outside of all monitors
};

NRI_NAMESPACE_END
2 changes: 0 additions & 2 deletions Include/Extensions/NRIWrapperVK.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

#include "NRIDeviceCreation.h"

NRI_FORWARD_STRUCT(VkImageSubresourceRange);

NRI_NAMESPACE_BEGIN

NRI_FORWARD_STRUCT(AccelerationStructure);
Expand Down
4 changes: 2 additions & 2 deletions Include/NRI.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
#include <stddef.h>

#define NRI_VERSION_MAJOR 1
#define NRI_VERSION_MINOR 115
#define NRI_VERSION_DATE "25 January 2024"
#define NRI_VERSION_MINOR 116
#define NRI_VERSION_DATE "29 January 2024"

#ifdef _WIN32
#define NRI_CALL __fastcall
Expand Down
2 changes: 1 addition & 1 deletion Resources/Version.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Versioning rules:
*/

#define VERSION_MAJOR 1
#define VERSION_MINOR 115
#define VERSION_MINOR 116
#define VERSION_BUILD 0
#define VERSION_REVISION 0

Expand Down
15 changes: 15 additions & 0 deletions Source/D3D11/DeviceD3D11.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -269,18 +269,33 @@ void DeviceD3D11::FillDesc(bool isValidationEnabled)
{
D3D11_FEATURE_DATA_D3D11_OPTIONS options = {};
HRESULT hr = m_Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &options, sizeof(options));
if (FAILED(hr))
REPORT_WARNING(this, "ID3D11Device::CheckFeatureSupport(options) failed, result = 0x%08X!", hr);

D3D11_FEATURE_DATA_D3D11_OPTIONS1 options1 = {};
hr = m_Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS1, &options1, sizeof(options1));
if (FAILED(hr))
REPORT_WARNING(this, "ID3D11Device::CheckFeatureSupport(options1) failed, result = 0x%08X!", hr);

D3D11_FEATURE_DATA_D3D11_OPTIONS2 options2 = {};
hr = m_Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS2, &options2, sizeof(options2));
if (FAILED(hr))
REPORT_WARNING(this, "ID3D11Device::CheckFeatureSupport(options2) failed, result = 0x%08X!", hr);

D3D11_FEATURE_DATA_D3D11_OPTIONS3 options3 = {};
hr = m_Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS3, &options3, sizeof(options3));
if (FAILED(hr))
REPORT_WARNING(this, "ID3D11Device::CheckFeatureSupport(options3) failed, result = 0x%08X!", hr);

D3D11_FEATURE_DATA_D3D11_OPTIONS4 options4 = {};
hr = m_Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS4, &options4, sizeof(options4));
if (FAILED(hr))
REPORT_WARNING(this, "ID3D11Device::CheckFeatureSupport(options4) failed, result = 0x%08X!", hr);

D3D11_FEATURE_DATA_D3D11_OPTIONS5 options5 = {};
hr = m_Device->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS5, &options5, sizeof(options5));
if (FAILED(hr))
REPORT_WARNING(this, "ID3D11Device::CheckFeatureSupport(options4) failed, result = 0x%08X!", hr);

uint64_t timestampFrequency = 0;
{
Expand Down
153 changes: 90 additions & 63 deletions Source/D3D12/DeviceD3D12.cpp

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions Source/Shared/SharedExternal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -348,6 +348,9 @@ nri::Result DisplayDescHelper::GetDisplayDesc(void* hwnd, nri::DisplayDesc& disp
i++;
}

if (!bestOutput)
return nri::Result::FAILURE;

// Having determined the output (display) upon which the app is primarily being
// rendered, retrieve the HDR capabilities of that display by checking the color space.

Expand Down
160 changes: 76 additions & 84 deletions Source/VK/DeviceVK.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,59 @@ DeviceVK::~DeviceVK()
UnloadSharedLibrary(*m_Loader);
}

void DeviceVK::GetAdapterDesc()
{
VkPhysicalDeviceIDProperties deviceIDProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
VkPhysicalDeviceProperties2 props = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &deviceIDProps };
m_VK.GetPhysicalDeviceProperties2(m_PhysicalDevices.front(), &props);

#ifdef _WIN32
static_assert(sizeof(LUID) == VK_LUID_SIZE, "invalid sizeof");

ComPtr<IDXGIFactory4> dxgiFactory;
HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgiFactory));
if (FAILED(hr))
REPORT_WARNING(this, "CreateDXGIFactory2() failed, result = 0x%08X!", hr);

ComPtr<IDXGIAdapter> adapter;
LUID luid = *(LUID*)&deviceIDProps.deviceLUID[0];
hr = dxgiFactory->EnumAdapterByLuid(luid, IID_PPV_ARGS(&adapter));
if (FAILED(hr))
REPORT_WARNING(this, "IDXGIFactory4::EnumAdapterByLuid() failed, result = 0x%08X!", hr);

DXGI_ADAPTER_DESC desc = {};
hr = adapter->GetDesc(&desc);
if (FAILED(hr))
REPORT_WARNING(this, "IDXGIAdapter::GetDesc() failed, result = 0x%08X!", hr);
else
{
wcstombs(m_Desc.adapterDesc.description, desc.Description, GetCountOf(m_Desc.adapterDesc.description) - 1);
m_Desc.adapterDesc.luid = *(uint64_t*)&desc.AdapterLuid;
m_Desc.adapterDesc.videoMemorySize = desc.DedicatedVideoMemory;
m_Desc.adapterDesc.systemMemorySize = desc.DedicatedSystemMemory + desc.SharedSystemMemory;
m_Desc.adapterDesc.deviceId = desc.DeviceId;
m_Desc.adapterDesc.vendor = GetVendorFromID(desc.VendorId);
}
#else
strncpy(m_Desc.adapterDesc.description, props.properties.deviceName, sizeof(m_Desc.adapterDesc.description));
m_Desc.adapterDesc.luid = *(uint64_t*)&deviceIDProps.deviceLUID[0];
m_Desc.adapterDesc.deviceId = props.properties.deviceID;
m_Desc.adapterDesc.vendor = GetVendorFromID(props.properties.vendorID);

/* THIS IS AWFUL!
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceMemoryProperties.html
In a unified memory architecture (UMA) system there is often only a single memory heap which is considered to
be equally "local" to the host and to the device, and such an implementation must advertise the heap as device-local. */
for (uint32_t k = 0; k < m_MemoryProps.memoryHeapCount; k++)
{
if (m_MemoryProps.memoryHeaps[k].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
m_Desc.adapterDesc.videoMemorySize += m_MemoryProps.memoryHeaps[k].size;
else
m_Desc.adapterDesc.systemMemorySize += m_MemoryProps.memoryHeaps[k].size;
}
#endif
}

Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc)
{
m_OwnsNativeObjects = true;
Expand Down Expand Up @@ -198,18 +251,23 @@ Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc)
if (res != Result::SUCCESS)
return res;

// Create device
res = ResolveInstanceDispatchTable();
if (res != Result::SUCCESS)
return res;

// Find physical device
res = FindPhysicalDeviceGroup(deviceCreationDesc.adapterDesc, deviceCreationDesc.enableMGPU);
if (res != Result::SUCCESS)
return res;

m_VK.GetPhysicalDeviceMemoryProperties(m_PhysicalDevices.front(), &m_MemoryProps);

FillFamilyIndices(false, nullptr, 0);

// Get adapter
GetAdapterDesc();

// Create device
res = CreateLogicalDevice(deviceCreationDesc);
if (res != Result::SUCCESS)
return res;
Expand All @@ -224,23 +282,6 @@ Result DeviceVK::Create(const DeviceCreationDesc& deviceCreationDesc)
for (uint32_t i = 0; i < groupSize; i++)
std::fill(begin + i * groupSize, begin + (i + 1) * groupSize, i);

// Get adapter
#ifdef _WIN32
VkPhysicalDeviceIDProperties deviceIDProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
VkPhysicalDeviceProperties2 props = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &deviceIDProps };
m_VK.GetPhysicalDeviceProperties2(m_PhysicalDevices.front(), &props);

static_assert(sizeof(LUID) == VK_LUID_SIZE, "invalid sizeof");

ComPtr<IDXGIFactory4> dxgiFactory;
HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgiFactory));
RETURN_ON_BAD_HRESULT(this, hr, "CreateDXGIFactory2()");

LUID luid = *(LUID*)&deviceIDProps.deviceLUID[0];
hr = dxgiFactory->EnumAdapterByLuid(luid, IID_PPV_ARGS(&m_Adapter));
RETURN_ON_BAD_HRESULT(this, hr, "IDXGIFactory4::EnumAdapterByLuid()");
#endif

// Finalize
CreateCommandQueues();
FillDesc(deviceCreationDesc.enableAPIValidation);
Expand All @@ -256,10 +297,6 @@ Result DeviceVK::Create(const DeviceCreationVKDesc& deviceCreationVKDesc)
m_OwnsNativeObjects = false;
m_SPIRVBindingOffsets = deviceCreationVKDesc.spirvBindingOffsets;

// TODO: physical device indices?
const VkPhysicalDevice* physicalDevices = (VkPhysicalDevice*)deviceCreationVKDesc.vkPhysicalDevices;
m_PhysicalDevices.insert(m_PhysicalDevices.begin(), physicalDevices, physicalDevices + deviceCreationVKDesc.deviceGroupSize);

const char* loaderPath = deviceCreationVKDesc.vulkanLoaderPath ? deviceCreationVKDesc.vulkanLoaderPath : VULKAN_LOADER_NAME;
m_Loader = LoadSharedLibrary(loaderPath);
if (!m_Loader)
Expand All @@ -275,23 +312,29 @@ Result DeviceVK::Create(const DeviceCreationVKDesc& deviceCreationVKDesc)

m_Instance = (VkInstance)deviceCreationVKDesc.vkInstance;

// Create device
res = ResolveInstanceDispatchTable();
if (res != Result::SUCCESS)
return res;

// Find physical device
const VkPhysicalDevice* physicalDevices = (VkPhysicalDevice*)deviceCreationVKDesc.vkPhysicalDevices; // TODO: physical device indices?
m_PhysicalDevices.insert(m_PhysicalDevices.begin(), physicalDevices, physicalDevices + deviceCreationVKDesc.deviceGroupSize);

m_VK.GetPhysicalDeviceMemoryProperties(m_PhysicalDevices.front(), &m_MemoryProps);

FillFamilyIndices(true, deviceCreationVKDesc.queueFamilyIndices, deviceCreationVKDesc.queueFamilyIndexNum);

// Get adapter
GetAdapterDesc();

// Create device
m_Device = (VkDevice)deviceCreationVKDesc.vkDevice;

res = ResolveDispatchTable();
if (res != Result::SUCCESS)
return res;

m_VK.GetPhysicalDeviceMemoryProperties(m_PhysicalDevices.front(), &m_MemoryProps);

FillFamilyIndices(true, deviceCreationVKDesc.queueFamilyIndices, deviceCreationVKDesc.queueFamilyIndexNum);

// Instance extensions
{
{ // Instance extensions
uint32_t extensionNum = 0;
m_VK.EnumerateInstanceExtensionProperties(nullptr, &extensionNum, nullptr);

Expand All @@ -301,9 +344,8 @@ Result DeviceVK::Create(const DeviceCreationVKDesc& deviceCreationVKDesc)
if (IsExtensionSupported(VK_EXT_DEBUG_UTILS_EXTENSION_NAME, supportedExts))
supportedFeatures.debugUtils = true;
}

// Device extensions
{

{ // Device extensions
uint32_t extensionNum = 0;
m_VK.EnumerateDeviceExtensionProperties(m_PhysicalDevices.front(), nullptr, &extensionNum, nullptr);

Expand All @@ -326,23 +368,6 @@ Result DeviceVK::Create(const DeviceCreationVKDesc& deviceCreationVKDesc)
supportedFeatures.meshShader = true;
}

// Get adapter
#ifdef _WIN32
VkPhysicalDeviceIDProperties deviceIDProps = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_ID_PROPERTIES };
VkPhysicalDeviceProperties2 props = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &deviceIDProps };
m_VK.GetPhysicalDeviceProperties2(m_PhysicalDevices.front(), &props);

static_assert(sizeof(LUID) == VK_LUID_SIZE, "invalid sizeof");

ComPtr<IDXGIFactory4> dxgiFactory;
HRESULT hr = CreateDXGIFactory2(0, IID_PPV_ARGS(&dxgiFactory));
RETURN_ON_BAD_HRESULT(this, hr, "CreateDXGIFactory2()");

LUID luid = *(LUID*)&deviceIDProps.deviceLUID[0];
hr = dxgiFactory->EnumAdapterByLuid(luid, IID_PPV_ARGS(&m_Adapter));
RETURN_ON_BAD_HRESULT(this, hr, "IDXGIFactory4::EnumAdapterByLuid()");
#endif

// Finalize
CreateCommandQueues();
FillDesc(false);
Expand All @@ -365,12 +390,13 @@ bool DeviceVK::GetMemoryType(MemoryLocation memoryLocation, uint32_t memoryTypeM
{
neededFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
desiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
undesiredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
}
else
{
neededFlags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT;
undesiredFlags = VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT;
desiredFlags = VK_MEMORY_PROPERTY_HOST_CACHED_BIT;
desiredFlags = memoryLocation == MemoryLocation::HOST_READBACK ? VK_MEMORY_PROPERTY_HOST_CACHED_BIT : 0;
}

// Phase 1: needed, undesired and desired
Expand Down Expand Up @@ -825,45 +851,11 @@ void DeviceVK::FillDesc(bool enableValidation)
VkPhysicalDeviceFeatures2 features2 = { VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2, &features12 };
m_VK.GetPhysicalDeviceFeatures2(m_PhysicalDevices.front(), &features2);

VkPhysicalDeviceMemoryProperties memoryProperties = {};
m_VK.GetPhysicalDeviceMemoryProperties(m_PhysicalDevices.front(), &memoryProperties);

supportedFeatures.descriptorIndexing = features12.descriptorIndexing ? true : false;
supportedFeatures.bufferDeviceAddress = features12.bufferDeviceAddress ? true : false;

static_assert(VK_LUID_SIZE == sizeof(uint64_t), "invalid sizeof");

#ifdef _WIN32
DXGI_ADAPTER_DESC desc = {};
HRESULT hr = m_Adapter->GetDesc(&desc);
if (SUCCEEDED(hr))
{
wcstombs(m_Desc.adapterDesc.description, desc.Description, GetCountOf(m_Desc.adapterDesc.description) - 1);
m_Desc.adapterDesc.luid = *(uint64_t*)&desc.AdapterLuid;
m_Desc.adapterDesc.videoMemorySize = desc.DedicatedVideoMemory;
m_Desc.adapterDesc.systemMemorySize = desc.DedicatedSystemMemory + desc.SharedSystemMemory;
m_Desc.adapterDesc.deviceId = desc.DeviceId;
m_Desc.adapterDesc.vendor = GetVendorFromID(desc.VendorId);
}
#else
strncpy(m_Desc.adapterDesc.description, props.properties.deviceName, sizeof(m_Desc.adapterDesc.description));
m_Desc.adapterDesc.luid = *(uint64_t*)&deviceIDProps.deviceLUID[0];
m_Desc.adapterDesc.deviceId = props.properties.deviceID;
m_Desc.adapterDesc.vendor = GetVendorFromID(props.properties.vendorID);

/* THIS IS AWFUL!
https://registry.khronos.org/vulkan/specs/1.3-extensions/man/html/VkPhysicalDeviceMemoryProperties.html
In a unified memory architecture (UMA) system there is often only a single memory heap which is considered to
be equally "local" to the host and to the device, and such an implementation must advertise the heap as device-local. */
for (uint32_t k = 0; k < memoryProperties.memoryHeapCount; k++)
{
if (memoryProperties.memoryHeaps[k].flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT)
m_Desc.adapterDesc.videoMemorySize += memoryProperties.memoryHeaps[k].size;
else
m_Desc.adapterDesc.systemMemorySize += memoryProperties.memoryHeaps[k].size;
}
#endif

const VkPhysicalDeviceLimits& limits = props.properties.limits;

m_Desc.viewportMaxNum = limits.maxViewports;
Expand Down
4 changes: 1 addition & 3 deletions Source/VK/DeviceVK.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ struct DeviceVK final : public DeviceBase
Result ResolveDispatchTable();
void FilterInstanceLayers(Vector<const char*>& layers);
void ReportDeviceGroupInfo();
void GetAdapterDesc();

template< typename Implementation, typename Interface, typename ... Args >
Result CreateImplementation(Interface*& entity, const Args&... args);
Expand Down Expand Up @@ -173,9 +174,6 @@ struct DeviceVK final : public DeviceBase
VkInstance m_Instance = VK_NULL_HANDLE;
VkAllocationCallbacks* m_AllocationCallbackPtr = nullptr;
VkDebugUtilsMessengerEXT m_Messenger = VK_NULL_HANDLE;
#ifdef _WIN32
ComPtr<IDXGIAdapter> m_Adapter;
#endif
bool m_OwnsNativeObjects = false;
Lock m_Lock;
};
Expand Down

0 comments on commit a746a1e

Please sign in to comment.