Git Product home page Git Product logo

d3d11on12's Introduction

D3D11On12

D3D11On12 is a mapping layer, which maps graphics commands from D3D11 to D3D12. D3D11On12 is not an implementation of the D3D11 API, but is instead an implementation of the D3D11 usermode DDI (device driver interface). That means it is not a binary named d3d11.dll, but is named d3d11on12.dll.

When an application creates a D3D11 device, they may choose for it to be a D3D11On12 device, rather than a native D3D11 device (see D3D11On12CreateDevice). When this happens, d3d11on12.dll is loaded by the D3D11 runtime and initialized. When the application calls rendering commands, D3D11 will validate those commands, optionally including the D3D11 debug layer for further validation, and then will convert those commands to the D3D11 DDI and send it to D3D11On12, just like any D3D11 driver. D3D11On12 will take these commands and convert them into D3D12 API calls, which are further validated by the D3D12 runtime, optionally including the D3D12 debug layer, which are then converted to the D3D12 DDI and sent to the D3D12 driver.

Note that D3D11On12 is an enlightened D3D11 driver, and there are several places where it receives additional information compared to a traditional D3D11 driver, either to enable it to provide API-level information to D3D12 rather than driver-level information (as is the case for shaders), or to enable interop scenarios. When a D3D11 device is created with D3D11On12, the device will expose an ID3D11On12Device interface which enables applications to submit work to both the D3D11 API and the D3D12 API with lightweight sharing and synchronization.

For more details about D3D11On12, see:

Make sure that you visit the DirectX Landing Page for more resources for DirectX developers.

How does it work?

The primary entrypoint to D3D11On12 is a custom version of the normal D3D11 driver OpenAdapter10_2 entrypoint, named OpenAdapter_D3D11On12, where D3D11 provides additional information to the mapping layer. In response to this, like a normal driver, D3D11On12 returns an adapter object, which exposes DDIs to create a device. The device is created like normal, but in addition to the normal DDI tables, it also exposes an ID3D11On12DDIDevice interface.

The device object internally uses an instance of the D3D12TranslationLayer immediate context, wrapped in a D3D12TranslationLayer batched context, to record commands. Similarly, most D3D11On12 objects are backed by an implementation from the D3D12TranslationLayer library. The code in this repository is largely a simple adaptor from the D3D11 DDI to the D3D12TranslationLayer library, where the real heavy lifting of converting to the D3D12 domain is done.

Building

In order to build D3D11On12, the WDK (Windows Driver Kit) must be installed, in order to provide d3d10umddi.h to D3D11On12, and in order to generate the D3D12TranslationLayer_WDK project, which hosts some code required to parse DXBC shaders and containers. The D3D12TranslationLayer and its subprojects, D3D12TranslationLayer_WDK and DXBCParser, will be fetched from GitHub when building with CMake if D3D12TranslationLayer_WDK isn't already included, such as by a parent CMakeLists.txt that has already entered that project. Assuming there was a top level CMakeLists.txt in a directory that included both D3D11On12 and D3D12TranslationLayer, you could achieve that like this:

cmake_minimum_required(VERSION 3.14)
include(FetchContent)

FetchContent_Declare(
    d3d12translationlayer
    SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/D3D12TranslationLayer
)
FetchContent_MakeAvailable(d3d12translationlayer)

add_subdirectory(D3D11On12)

At the time of publishing, the D3D11On12 and D3D12TranslationLayer require insider versions of the SDK and WDK. Those can be found here.

D3D11On12 requires C++17, and only supports building with MSVC at the moment.

Why open source?

The D3D11On12 mapping layer is included as an operating system component of Windows 10. Over the years and Windows 10 releases, it has grown in functionality, to the point where it is a complete and relatively performant implementation of a D3D11 driver. We are choosing to release the source to this component for two primary reasons:

  1. To enable the community to contribute bugfixes and further performance improvements, which will improve the stability and performance of Windows 10. See CONTRIBUTING.
  2. To serve as an example of how to use the D3D12TranslationLayer library.

What can you do with this?

There are minor differences between binaries built out of this repository and the versions that are included in the OS. To that end, shipping applications should not attempt to override the OS version of D3D11On12 with versions that they have built. We will not guarantee that newer versions of Windows will continue to support older versions of D3D11On12, since it is an OS component which may be revised together with D3D11. However, developers are welcome to override the Windows version of D3D11On12 for local testing and experimentation.

Compatibility

When possible, we will attempt to maintain compatibility between D3D11 and D3D11On12. One should expect that the tip of D3D11On12's master branch should work nicely with the latest release of Windows 10. Support for configurations other than that are not guaranteed to work.

Data Collection

The software may collect information about you and your use of the software and send it to Microsoft. Microsoft may use this information to provide services and improve our products and services. You may turn off the telemetry as described in the repository. There are also some features in the software that may enable you and Microsoft to collect data from users of your applications. If you use these features, you must comply with applicable law, including providing appropriate notices to users of your applications together with a copy of Microsoft's privacy statement. Our privacy statement is located at https://go.microsoft.com/fwlink/?LinkID=824704. You can learn more about data collection and use in the help documentation and our privacy statement. Your use of the software operates as your consent to these practices.

Note however that no data collection is performed when using your private builds.

d3d11on12's People

Contributors

jacquesvanrhynmsft avatar jenatali avatar microsoft-github-policy-service[bot] avatar randytiddmsft avatar randytiddmsft2 avatar sivileri avatar vdwtanner avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

d3d11on12's Issues

BUG when using 2D textures

My app uses the following technologies:

  1. wpf (directx 9 UI)
  2. directX 11 (simple rendering of textured quads and shapes)
  3. opencl (image processing, interoperability with directx 11 via AMD extentions)

hardware: AMD WX7100

The app does not create a swapchain. all rendering is preformed off-screen to a texture.

I replaced the D3D11 device creation code with d3d11on12 code: create a d3d12device and command queue, and call D3D11On12CreateDevice.

Other than that nothing was changed.

The problem I notice is that the textures are rendered incorrectly. It is as if their internal memory layout interpretation has somehow changed. I would guess that this is somehow related to their hardware dependent layout as the way it looks reminds me of the AMD micro-macro texture memory tiling.

Non-textured geometry seems to be rendered OK.

Here is a simple texture on a quad:

image

UpdateSubresource (Constant Buffer) + Draw pattern inhibits GPU parallelism

A common D3D11 pattern was to issue pairs of UpdateSubresource + Draw, where constant buffers were updated just-in-time before each draw.

This pattern, when translated to D3D12 is:

  1. ResourceBarrier (old state -> COPY_DEST)
  2. CopyBufferRegion
  3. ResourceBarrier (COPY_DEST -> VERTEX_AND_CONSTANT_BUFFER)
  4. Draw

That pattern means no draw overlaps with any other.

Some sort of 'rename' operation could occur, similar to the MAP_DISCARD behaviour from D3D11 to better allow GPU parallelism.

Support pulling D3D12TranslationLayer with FetchContent

Right now, the build is overly complex because it requires D3D12TranslationLayer and D3D11On12 to be siblings, both included by a (not-provided) top-level CMakeLists.txt. This is useful for us because we want to build D3D12TranslationLayer once, and share that .lib among multiple other mapping layers, but it would be way more convenient for anybody else building this layer to just grab this repo and have it pull dependencies automatically.

One time lag spike

I'm using D3D11on12 for interop with direct2d.

There is a one time 120 millisecond render where as the render work usually takes 1.5 milliseconds.

If the render work load is smaller it takes longer to happen. Seems something akin to when std::vector has to resize.

Do you know about this? Can you give any guidance?

translation layer failed to create PSO for VS + SO graphics pipeline

When runing wgf11draw Draw:1 with -11On12 option, the translation layer failed to create PSO because of invalid D3D12_GRAPHICS_PIPELINE_STATE_DESC argument.
This application only use Vertex Shader and StreamOut. It doesn't have Pixel Shader, render target and depth stencil buffer. And its Vertex Shader doesn't output a SV_POSITION value.
So in the D3D12_GRAPHICS_PIPELINE_STATE_DESC argument, the D3D12_STREAM_OUTPUT_DESC::RasterizedStream should be set to D3D12_SO_NO_RASTERIZED_STREAM, and the D3D12_DEPTH_STENCIL_DESC::DepthEnable, D3D12_DEPTH_STENCIL_DESC::StencilEnable should be set to false.
But the translation layer generates a D3D12_GRAPHICS_PIPELINE_STATE_DESC with D3D12_STREAM_OUTPUT_DESC::RasterizedStream set to 0 and D3D12_DEPTH_STENCIL_DESC::DepthEnable set to true. This result in an invalid argument error when creating PSO.
In D3D11On12::StreamOutShader::ProduceDesc, we may need to check if there is any output parameter has "SV_POSITION" semantic name. If not, we should set RasterizedStream to D3D12_SO_NO_RASTERIZED_STREAM and disable depth and stencil.

Header file "d3dx12.h" missing, and data definition "CD3DX12_RESOURCE_DESC1" missing.

Hi All,

Recently I've tried to compile the d3d11on12, but got lots of error. The first one is missing "d3dx12.h", which is included from the "external/d3d11on12.h". By searching on the internet it's found that the "d3dx12.h" is only a helper header file, which could be found inner another project, DirectX-Graphic-samples. I wonder if this header could be placed into the "external/" folder directly, instead of providing such a misleading error information.

What's more, after I copy the "d3dx12.h" and place it under the "external/" folder, the compiler complains that it could not find the definition of "CD3DX12_RESOURCE_DESC1", which is used in line 135 of "external/d3d11on12.h." I've checked the "d3dx12.h" with only CD3DX12_RESOURCE_DESC defined, Is this a typo for the tailing "1"?? Hope it could be confirmed.

Many thanks.

GPU shared memory usage grows unbounded using D3D11on12 device with Media Foundation source reader

Reproduced on two PCs:

  1. Windows 10 21H2 with AMD Radeon RX 5700 XT
  2. Windows 11 22H2 with Nvidia GeForce GTX 1660 Ti

When decoding video frames using an IMFSourceReader with a D3D11 device created with D3D11On12CreateDevice the GPU shared memory usage appears to grow unbounded. If there are enough frames to decode then it will reach the shared memory limit.

With the exact same code using a "real" D3D11 device the GPU shared memory usage remains flat. This is the expected result since each IMFSample is decoded and then immediately released.

Sample code

D3D11on12.cpp.txt

Test files

I can repro with any AVC or HEVC video in MP4 or MPEG-TS. But the video stream needs to be long enough before the memory usage can be observed. Decoding 1,000 frames should be enough to at least see a difference between D3D11 and D3D11on12.

Here's a sample file in case you need it. This is the 'main.ts' file referenced in the sample code.
main.ts MPEG-TS with 960x540 AVC (186 MB)

DxDiag

DxDiag-AMD.txt
DxDiag-Nvidia.txt

Decoding with a "real" D3D11 device:

       image

Video Codec is at 100% and memory usage is flat. This is the expected result.

Decoding with D3D11on12 device:

       image

The GPU shared memory usage grows linearly as soon as the decoding begins. Interestingly, there is also some Copy work going on that does not appear in the test above.

Results on Windows 11 with GTX 1660 Ti

The results are similar, though not identical, on a Windows 11 laptop with GTX 1660 Ti.

D3D11

image

D3D11on12

image

Question on Xbox Series X

Apologies if this isn't the best avenue to ask this, but was wondering if this project is something that is appropriate to use for conversion of DirectX versions in regard to the consoles, specifically from the Xbox One to Xbox Series X? Of course other API calls will need to be manually adjusted, but can this be included in an Xbox project or is this targeted for only Windows?

D3D12on11?

I'd have more interest for the opposite, making D3D12-only games work with D3D11 older hardware.

IDXGIOutputDuplication::AcquireNextFrame - DXGI_ERROR_ACCESS_LOST

When using D3D11on12, when using Desktop Duplication, calling IDXGIOutputDuplication::AcquireNextFrame results in DXGI_ERROR_ACCESS_LOST.

Tracing this as far as I can it seems to be caused by CGraphicsCommandQueue::AcquireKeyedMutex which calls D3DKMTAcquireKeyedMutex2 which returns 0x80 (WAIT_ABANDONED)

Note, this code is functioning perfectly on DX11 directly.

DXGI_ERROR_ACCESS_DENIED on SwapChainForComposition

I switched from a hwnd SwapChain to a composition SwapChain and started getting a semi non-reproducible device removal bug, which usually happens in the first few frames.

Debug output:

After Present
D3D12: Removing Device.
After MoveToNextFrame
D3D12 ERROR: ID3D12Device::RemoveDevice: Device removal has been triggered for the following reason (DXGI_ERROR_ACCESS_DENIED: The application attempted to use a resource it does not access to. This could be, for example, rendering to a texture while only having read access.). [ EXECUTION ERROR #232: DEVICE_REMOVAL_PROCESS_AT_FAULT]

The only resources I might not have access to are the swap chain buffers, so it seems like there is a bug. This doesn't happen if I comment out my D2D draw calls, but does still happen even if I am not rendering to the swap chain buffers but some secondary resource.

Also, could I get some guidance on how to recover? Present always returns 0, only on the next call to EndDraw do I get a non-zero hresult D2DERR_RECREATE_TARGET.

Use of occlusion queries around individual draws results in one ResolveQueryData per query

D3D11 gave no explicit control over batching query resolve operations, so it appears that 'EndQuery' is the place that ResolveQueryData operations are inserted.

The D3D11 pattern of:

  1. Begin(query)
  2. Draw
  3. End(query)

For tasks such as Occlusion Culling results in this pattern in D3D12:

  1. BeginQuery
  2. Draw
  3. EndQuery
  4. ResolveQueryData

This appears to inhibit draw-level parallelism as a ResolveQueryData operation sits between every draw. Some means (waves hands) of batching up Resolves into one operation before first use would help immeasurably!

DLL from repository doesn't work with the latest versions of windows.

Hi. I am trying to use this code as an example of usage of D3D12 translation layers.
I compiled successfully my version of d3d11on12.dll from the code from the repository, but I can not use it instead of the system one.

At the moment, my setup is: Windows 10 64 10.0.18363.836 (latest), Win SDK 10.0.19041.0 (latest or penultimate), WDK same as SDK, VS 2017.

While running the D3D1211On12 sample from the DirectX-Graphics-Samples (which works fine with system dll) I just put my d3d11on12.dll next to the file and every time I get this error "0x887a0004: The specified device interface or feature level is not supported on this system.".

I tried to use the d3d11.dll from different versions of Windows, but this did not work. I also tried to debug it, but as far as I can tell the problem inside the d3d11.dll, loading of my version of d3d11on12.dll goes fine and is further unloaded due to mismatches of some flags inside d3d11.dll.

What else could be wrong, are there any ideas?

Most of the code is understandable, but there are some things that are not obvious, and yet I want to have the ability to debug them.

Many thanks.

Using Windows.Graphics.Capture.Direct3D11CaptureFramePool with D3D11On12

I have implemented an Unreal Engine 4 module which allows one to use desktop windows as a texture with minimal overhead / latency. It works fine on DirectX11, but I would need to make it work for DirectX12 too. For this I am using the D3D11On12 APIs to get a ID3D11Device, which I can provide to the Direct3D11CaptureFramePool of WinRT on creation. Long story short: I got the D3D12 texture updated, but it only works until the capture frame pool fills up, as the frames are not closed and the FrameArrived event is not firing anymore.

To isolate the issue I have removed all rendering code besides creating the D3D11On12 device and the pool. It still does the same thing. It seems that when using a D3D11On12 device the frame pool fails. I am not experienced with DirectX 12 yet, I have tried issuing flush commands to the command queue etc. but the issue persists. I am assuming the D3D12CommandQueue I extracted from unreal engine gets executed, since otherwhile the D3D11 => D3D12 texture copies would never be performed, but they are. I am not sure how the capture frame pool works, but in theory it should be able to reuse frames after I close them.

I am doing something wrong here? Or is this a compatibility issue?

I guess my other option would be to create a D3D11 device and use shared resources with the D3D12 one, but that will have more overhead.

MediaFoundation / DirectX 12 interop

Hi,
I'm trying to enable direct mapping of decoded buffers from Media Foundation as DirectX 12 textures.
The problem is MediaFoundation doesn't support DirectX 12.
I tried two approaches:

  1. Create a DirectX 11 device. Use CreateSharedHandle to create a shared NT handle from the IMFDXGIBuffer. I get an error "Parameter is incorrect".
  2. Create a D3D11On12Device. Use CreateSharedHandle to create a shared NT handle from the IMFDXGIBuffer. I also get the same error "Parameter is incorrect".

My question is:
how do we enable interop between MediaFoundation and DirectX 12?
It seems that the IMFDXGIBuffer is not an NT handle while DirectX 12 requires an "NT handle"?

I also set MF_SA_D3D11_SHARED to true.
It doesn't seem that Media Foundation provides any option to allocate an "NT handle"?

Please advise.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.