NVRHI (NVIDIA Rendering Hardware Interface) is a library that implements a common abstraction layer over multiple graphics APIs

Related tags

Graphics nvrhi
Overview

NVRHI

Build Status

Introduction

NVRHI (NVIDIA Rendering Hardware Interface) is a library that implements a common abstraction layer over multiple graphics APIs (GAPIs): Direct3D 11, Direct3D 12, and Vulkan 1.2. It works on Windows (x64 only) and Linux (x64 and ARM64).

Key features:

  • Automatic tracking of resource states and barrier placement (optional).
  • Automatic tracking of resource usage and lifetime, deferred and safe resource destruction.
  • Convenient and efficient resource binding model with little runtime overhead.
  • Easy direct interaction with the underlying GAPI when necessary.
  • Easy portability of the rendering code between the supported GAPIs.
  • Hidden sub-allocation of upload buffers and versioning of constant buffers.
  • Parallel command list recording and multi-queue rendering.
  • Supports all types of pipelines: Graphics, Compute, Ray Tracing, and Meshlet.
  • Validation layer and resource reflection for easy debugging.

Various early versions of NVRHI have been used in various projects created at NVIDIA, including:

Requirements

  • Windows or Linux (x64 or ARM64)
  • CMake 3.10
  • A C++ 17 compiler (Visual Studio 2019, GCC 8 or Clang 6)
  • Windows SDK version 10.0.19041.0 or later for DX12 support

Building NVRHI

NVRHI can be configured to be used a set of static libraries in CMake-based projects, or as a single dynamic library.

To include NVRHI into a CMake project as static libraries:

  1. Add this repository as a submodule.
  2. Add a add_subdirectory(nvrhi) directive to the parent CMakeLists.txt.
  3. Add dependencies to the necessary targets:
    • nvrhi for the interface headers, common utilities, and validation;
    • nvrhi_d3d11 for DX11 (enabled when NVRHI_WITH_DX11 is ON);
    • nvrhi_d3d12 for DX12 (enabled when NVRHI_WITH_DX12 is ON); and
    • nvrhi_vk for Vulkan (enabled when NVRHI_WITH_VULKAN is ON).

To build NVRHI as a shared library (DLL or .so):

  1. Clone this repository recursively (including submodules).
  2. Generate the project with CMake:
    • Set the NVRHI_BUILD_SHARED variable to ON.
    • Make sure to set the target platform to a 64-bit one. 32-bit builds are not supported.
  3. Build and install as normal.

Using NVRHI in Applications

See the programming guide and the tutorial.

Shader Compiler

NVRHI includes an optional tool for compiling shaders and generating shader permutations. The shader compiler is normally built together with NVRHI when the NVRHI_WITH_SHADER_COMPILER variable is ON. It can be used from CMake rules by its target name shaderCompiler or directly from its install location using the executable name nvrhi-scomp.

The NVRHI shader compiler is just a front-end for DXC, it does not implement any shader language processing itself.

For the list of command line options, run nvrhi-scomp --help.

The shader compiler is driven by a configuration file that lists shaders, their targets and permutations. The file has one shader source per line, for example:

Shaders.hlsl -T vs_5_0 -E main_vs
Shaders.hlsl -T ps_5_0 -E main_ps -D ENABLE_SOMETHING={0,1}

The above configuration will compile 3 shaders total: one vertex shader main_vs and two permutations of pixel shader main_ps with different values of the ENABLE_SOMETHING define. The pixel shader permutations will be combined into a single permutation blob. Permutation blobs can be parsed using functions declared in .

NVAPI Support

NVRHI includes optional support for certain DX11 and DX12 extensions available through the NVAPI library. The library is not distributed with NVRHI but is available separately here.

To enable NVAPI support, extract the NVAPI SDK into the nvapi subfolder of your main project and set the NVRHI_WITH_NVAPI CMake variable to ON.

The following extensions are supported:

  • Fast Geometry Shader with optional coordinate swizzling (Maxwell+)
  • Single Pass Stereo (Pascal+)
  • HLSL Extensions through a fake UAV slot (see this blog post)

RTXMU Integration

NVRHI includes an optional integration of the RTXMU library. The library is included as a git submodule, and can be enabled with the NVRHI_WITH_RTXMU CMake variable.

When RTXMU integration is enabled, all bottom-level ray tracing acceleration structures (BLAS'es) are managed by that library. All built BLAS'es that have the AllowCompaction flag set are automatically compacted when ICommandList::compactBottomLevelAccelStructs method is called. No other configuration is necessary.

License

NVRHI is licensed under the MIT License.

Comments
  • Use DirectX-Headers

    Use DirectX-Headers

    Using DirectX-Headers would allow to be not dependent on the installed windows SDK for newer DX-SDK features. The DirectX-Headers are only used in private source files which should not affect when this library is consumed. The DirectX-Headers submodule is pinned to the latest stable release v1.602.0. I also changed one static_assert which was missing the error message.

    opened by Zwingling 6
  • Adding shared flags for D3D11 and 12 resources.

    Adding shared flags for D3D11 and 12 resources.

    This change adds 'isSharedAcrossDevice' and 'isSharedAcrossAdapter' to TextureDesc and BufferDesc. In D3D11 and 12, applying these flags will result in applying shared resource flags. In VK, applying this flag will produce an error because it's too different the way to share resource against D3Ds. VK needs information about the other hand's API to apply sharing flags.

    I have read the CLA Document and I hereby sign the CLA

    opened by tksgmsy 5
  • Fix invalid argument for DX12 CreateHeap

    Fix invalid argument for DX12 CreateHeap

    This adds a heap tier check because the D3D12_HEAP_FLAG_ALLOW_ALL_BUFFERS_AND_TEXTURES flag is not supported for heap tier 1. I tested this on Windows 10 SDK 10.0.19041.0 and 10.0.20348.0.

    opened by stephenap07 4
  • Incomplete Vulkan HPP Initialization in DLL Builds

    Incomplete Vulkan HPP Initialization in DLL Builds

    I found a problem in the Vulkan backend while attempting to follow the tutorial. I built NVRHI for win64 from a fresh clone of the main branch like so:

    cmake -D NVRHI_BUILD_SHARED=ON -D NVRHI_WITH_VULKAN=ON -D NVRHI_WITH_DX11=OFF -D NVRHI_WITH_DX12=OFF -D NVRHI_WITH_SHADER_COMPILER=OFF ..
    

    The problem is, when I call nvrhi::vulkan::createDevice only calls the first of the three required VULKAN_HPP_DEFAULT_DISPATCHER.init variants, which means only vkCreateInstance, vkEnumerateInstanceExtensionProperties, vkEnumerateInstanceLayerProperties, and vkEnumerateInstanceVersion are initialized. NVRHI then proceeds to behave as if the full initialization had been performed, and then immediately crashes when it tries to call VULKAN_HPP_DEFAULT_DISPATCHER::createSemaphore via vk::Device::createSemaphore, which is still null.

    When NVRHI_SHARED_LIBRARY_BUILD is set, as is the case in my build, NVRHI defines VULKAN_HPP_DEFAULT_DISPATCH_LOADER_DYNAMIC_STORAGE but not VULKAN_HPP_STORAGE_SHARED or VULKAN_HPP_STORAGE_SHARED_EXPORT. According to the vulkan-hpp docs, this means I can't just finish up the initialization in my own application.

    So I think to fix this correctly, VULKAN_HPP_STORAGE_SHARED and VULKAN_HPP_STORAGE_SHARED_EXPORT need to be define for the build config or so, and nvrhi::vulkan::createDevice needs to be updated to initialize like so:

        DeviceHandle createDevice(const DeviceDesc& desc)
        {
    #if defined(NVRHI_SHARED_LIBRARY_BUILD)
            const vk::DynamicLoader dl;
            const PFN_vkGetInstanceProcAddr vkGetInstanceProcAddr =   // NOLINT(misc-misplaced-const)
                dl.getProcAddress<PFN_vkGetInstanceProcAddr>("vkGetInstanceProcAddr");
            VULKAN_HPP_DEFAULT_DISPATCHER.init(vkGetInstanceProcAddr);
            VULKAN_HPP_DEFAULT_DISPATCHER.init(desc.instance);
            VULKAN_HPP_DEFAULT_DISPATCHER.init(desc.device);
    #endif
    
    opened by Aeva 3
  • Added MemoryAllocateFlagsInfo for device address enabled buffers in VK

    Added MemoryAllocateFlagsInfo for device address enabled buffers in VK

    When enabling device address in VK, vk::MemoryAllocateFlagsInfo is required in pNext chain when allocating VRAM. Without this, VK validation layer produce an error message.

    opened by tksgmsy 2
  • Use vulkan-hpp will definitely kill almost all performace of C++ compiling.

    Use vulkan-hpp will definitely kill almost all performace of C++ compiling.

    Vulkan-hpp is definitely a bad practise to manipulate vulkan API which abuse template usage so as to kill C++ compiling performace.

    When just including <vulkan.hpp> in any of emty source, compiling duration can take quater of a hour. This dependency will definitely make your work useless.

    opened by HuazyYang 1
  • Recursive locking of a non-recursive mutex can occur in StaticDescriptorHeap

    Recursive locking of a non-recursive mutex can occur in StaticDescriptorHeap

    On entry, StaticDescriptorHeap::allocateDescriptors() locks m_Mutex for the scope of the function, and on descriptor exhaustion (or heavy fragmentation) it calls Grow() which also tries to lock m_Mutex. However, m_Mutex is a std::mutex, for which locking multiple times on the same thread is undefined behavior. On Windows Debug builds this generally results in a std::system_error being thrown on the second locking attempt, possibly crashing the whole process.

    To be fair, I discovered this while writing a buggy app that didn't correctly clean up after itself and would eventually overflow the default RTV heap size of 1024. But still probably worth switching to std::recursive_mutex for correctness at least.

    opened by itabashki 1
  • This fixes NVRHI_BUILD_SHARED and linking RTXMU

    This fixes NVRHI_BUILD_SHARED and linking RTXMU

    This fixes: /usr/bin/ld: rtxmu/librtxmu.a(VkAccelStructManager.cpp.o): relocation R_X86_64_PC32 against symbol `_ZN5rtxmu7VkBlock10m_instanceE' can not be used when making a shared object; recompile with -fPIC

    I assume I need to sign the CLA somehow?

    Cheers

    opened by boberfly 1
  • Extend existing drawIndirect by drawCount

    Extend existing drawIndirect by drawCount

    DrawIndirect seems to be not really usable right now as it does not allow to set a drawCount. This PR adds drawCount to the drawIndirect method. This will be DX12 and Vulkan only. For convenience I added the DrawIndirectArguments struct which matches the VkDrawIndirectCommand and D3D12_DRAW_ARGUMENTS.

    This is a breaking API change as the drawIndirect signature changed but I think this is not used currently?

    opened by Zwingling 0
  • PSO recreation on frame buffer resize

    PSO recreation on frame buffer resize

    I'm confused why the validation layer enforces PSO framebuffer sizes to match a framebuffer binding. The rest of the member checks are correct, but I don't believe size needs to be the same. Recreating PSOs due to a window resize can be a very expensive operation. The documentation mentions:

    "Following the Vulkan API for creating graphics pipelines, NVRHI has a concept of a framebuffer. A framebuffer is a collection of render targets, up to 8, and a depth target, each with its subresource set. Framebuffers hold strong references to their textures and are immutable.

    A valid framebuffer is necessary to create a graphics or meshlet pipeline. A pipeline created with a certain framebuffer can then be used with the same framebuffer, or with any other framebuffer which is compatible. Two framebuffers are considered compatible when they have the same number and formats of the render targets, and the width and height of the render targets."

    I believe this is meant to follow Vulkan render pass compatibility (note render pass, not framebuffer). The Vulkan docs don't mention the size (width and height) in the compatibility requirements: https://registry.khronos.org/vulkan/specs/1.2-extensions/html/chap8.html#renderpass-compatibility

    Removing this validation and reusing PSOs with a resized framebuffer doesn't trigger any validation issues on d3d12 or VK. If I'm incorrect can you point me to the relevant documentation for d3d12 or VK?

    Thanks!

    opened by vancerm 0
  • Tiled resource support

    Tiled resource support

    opened by HuazyYang 0
  • Vulkan validation layer bufferDeviceAddress warning

    Vulkan validation layer bufferDeviceAddress warning

    VK validation layer reports:

    WARNING: [Vulkan: location=0xfffffffff972dfbf code=0, layerPrefix='Validation'] Validation Error: [ VUID-VkMemoryAllocateInfo-flags-03331 ] Object 0: handle = 0x12f05f5af50, type = VK_OBJECT_TYPE_DEVICE; | MessageID = 0xf972dfbf | If VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT is set, bufferDeviceAddress must be enabled. The Vulkan spec states: If VkMemoryAllocateFlagsInfo::flags includes VK_MEMORY_ALLOCATE_DEVICE_ADDRESS_BIT, the bufferDeviceAddress feature must be enabled (https://vulkan.lunarg.com/doc/view/1.3.224.1/windows/1.3-extensions/vkspec.html#VUID-VkMemoryAllocateInfo-flags-03331)
    

    Adding .setBufferDeviceAddress(bufferAddressSupported) to vulkan12features in DeviceManager_VK.cpp fixed the problem.

    opened by aleieng 0
  • clearBufferUInt does not work on raw UAV buffers under DX11

    clearBufferUInt does not work on raw UAV buffers under DX11

    It fails on d3d11-buffer.cpp line 360 "assert(format != Format::UNKNOWN);", since in clearBufferUInt function, the viewType is incorrectly assigned as TypedBuffer_UAV. This function does not expect a raw UAV buffer.

    I added the following lines to clearBufferUInt (d3d11-buffer.cpp) line 170 as a WAR to make it work.

            if (bufferDesc.canHaveRawViews && bufferDesc.format == Format::UNKNOWN)
            {
                viewType = ResourceType::RawBuffer_UAV;
            }
    
    opened by aleieng 0
Owner
NVIDIA GameWorks
NVIDIA Technologies for game and application developers
NVIDIA GameWorks
Legion Low Level Rendering Interface provides a graphics API agnostic rendering interface with minimal CPU overhead and low level access to verbose GPU operations.

Legion-LLRI Legion-LLRI, or “Legion Low Level Rendering Interface” is a rendering API that aims to provide a graphics API agnostic approach to graphic

Rythe Interactive 26 Aug 13, 2022
Direct3D to OpenGL abstraction layer

TOGL Direct3D -> OpenGL translation layer. Taken directly from the DOTA2 source tree; supports: Limited subset of Direct3D 9.0c Bytecode-level HLSL ->

Valve Software 2k Nov 19, 2022
Implementing Nvidia DXR tutorial with Microsoft DXR Fallback Layer

DXRNvTutorial Implemented the Nvidia DXR tutorial with Microsoft DXR Fallback Layer, tested on Nvidia GTX 980Ti (AMD won't work). Extended nv_helpers_

Phil Guo 2 Sep 21, 2019
Source Code for "Ray Tracing Gems: High-Quality and Real-Time Rendering with DXR and Other APIs" by Eric Haines and Tomas Akenine-Möller

Apress Source Code This repository accompanies Ray Tracing Gems: High-Quality and Real-Time Rendering with DXR and Other APIs by Eric Haines and Tomas

Apress 851 Nov 21, 2022
Cross-platform, graphics API agnostic, "Bring Your Own Engine/Framework" style rendering library.

bgfx - Cross-platform rendering library GitHub Discussions Discord Chat What is it? Cross-platform, graphics API agnostic, "Bring Your Own Engine/Fram

Бранимир Караџић 12.4k Nov 27, 2022
A modern cross-platform low-level graphics library and rendering framework

Diligent Engine A Modern Cross-Platform Low-Level 3D Graphics Library Diligent Engine is a lightweight cross-platform graphics API abstraction library

Diligent Graphics 2.6k Nov 28, 2022
ORE (OpenGL Rendering Engine) is a rendering engine developed for my college minor project assessment.

ORE (OPENGL RENDERING ENGINE) What is ORE? ORE(OpenGL Rendering Engine) is a rendering engine with great and easy to use UI that allows the user to lo

HARSHIT BARGUJAR 3 Sep 23, 2022
A terminal-based graphics library for both 2D and 3D graphics.

TermGL A terminal-based graphics library for both 2D and 3D graphics. Written in C, created for terminals supporting ANSI escape codes. Table of Conte

null 211 Oct 31, 2022
Vire is a C++ voxel rendering engine. It is written in C++14 and uses OpenGL for graphics.

Vire Vire is a C++ voxel rendering engine. It is written in C++14 and uses OpenGL for graphics. Downloads If you'd just like to just download and try,

null 35 Jul 27, 2022
kaun is a replacement for löve's built-in love.graphics module intended for 3D graphics

kaun kaun is a replacement for löve's built-in love.graphics module intended for 3D graphics. It is a Lua module you can require from a shared library

Joel Schumacher 4 Apr 5, 2021
This repo contains the DirectX Graphics samples that demonstrate how to build graphics intensive applications on Windows.

DirectX-Graphics-Samples This repo contains the DirectX 12 Graphics samples that demonstrate how to build graphics intensive applications for Windows

Microsoft 4.9k Nov 24, 2022
Metal-cpp is a low-overhead C++ interface for Metal that helps developers add Metal functionality to graphics apps, games, and game engines that are written in C++.

About metal-cpp is a low overhead and header only C++ interface for Metal that helps developers add Metal functionality to graphics applications that

Бранимир Караџић 163 Nov 29, 2022
A basic 3D scene implemented with various engines, frameworks or APIs.

Here be dragons Hic sunt dracones. This repository contains multiple implementations of the same 3D scene, using different APIs and frameworks on vari

Simon Rodriguez 1.7k Nov 14, 2022
C++ (with python bindings) library for easily reading/writing/manipulating common animation particle formats such as PDB, BGEO, PTC. See the discussion group @ http://groups.google.com/group/partio-discuss

Partio - A library for particle IO and manipulation This is the initial source code release of partio a tool we used for particle reading/writing. It

Walt Disney Animation Studios 411 Nov 23, 2022
Implementation of Peter Shirley's Ray Tracing In One Weekend book using Vulkan and NVIDIA's RTX extension.

Ray Tracing In Vulkan My implementation of Peter Shirley's Ray Tracing in One Weekend books using Vulkan and NVIDIA's RTX extension (formerly VK_NV_ra

Tanguy Fautre 839 Nov 20, 2022
This is a openGL cube demo program. It was made as a tech demo using PVR_PSP2 Driver layer GPU libraries.

OpenGL Cube Demo using PVR_PSP2 Driver layer GPU libraries This is a openGL cube demo program. It was made as a tech demo using PVR_PSP2 Driver layer

David Cantu 5 Oct 31, 2021
A fork of Microsoft's D3D12 Raytracing Fallback Layer

D3D12 Raytracing Fallback Layer The D3D12 Raytracing Fallback Layer is a library that emulates the DirectX Raytracing (DXR) API on devices without nat

Phil Guo 9 Sep 13, 2022
Open source Altium Database Library with over 147,000 high quality components and full 3d models.

Open source Altium Database Library with over 147,000 high quality components and full 3d models.

Mark 1.3k Nov 20, 2022