• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Dawn Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 // D3D12Backend.cpp: contains the definition of symbols exported by D3D12Backend.h so that they
16 // can be compiled twice: once export (shared library), once not exported (static library)
17 
18 #include "dawn_native/D3D12Backend.h"
19 
20 #include "common/Log.h"
21 #include "common/Math.h"
22 #include "common/SwapChainUtils.h"
23 #include "dawn_native/d3d12/D3D11on12Util.h"
24 #include "dawn_native/d3d12/DeviceD3D12.h"
25 #include "dawn_native/d3d12/NativeSwapChainImplD3D12.h"
26 #include "dawn_native/d3d12/ResidencyManagerD3D12.h"
27 #include "dawn_native/d3d12/TextureD3D12.h"
28 
29 namespace dawn_native { namespace d3d12 {
30 
GetD3D12Device(WGPUDevice device)31     ComPtr<ID3D12Device> GetD3D12Device(WGPUDevice device) {
32         return ToBackend(FromAPI(device))->GetD3D12Device();
33     }
34 
CreateNativeSwapChainImpl(WGPUDevice device,HWND window)35     DawnSwapChainImplementation CreateNativeSwapChainImpl(WGPUDevice device, HWND window) {
36         Device* backendDevice = ToBackend(FromAPI(device));
37 
38         DawnSwapChainImplementation impl;
39         impl = CreateSwapChainImplementation(new NativeSwapChainImpl(backendDevice, window));
40         impl.textureUsage = WGPUTextureUsage_Present;
41 
42         return impl;
43     }
44 
GetNativeSwapChainPreferredFormat(const DawnSwapChainImplementation * swapChain)45     WGPUTextureFormat GetNativeSwapChainPreferredFormat(
46         const DawnSwapChainImplementation* swapChain) {
47         NativeSwapChainImpl* impl = reinterpret_cast<NativeSwapChainImpl*>(swapChain->userData);
48         return static_cast<WGPUTextureFormat>(impl->GetPreferredFormat());
49     }
50 
ExternalImageDescriptorDXGISharedHandle()51     ExternalImageDescriptorDXGISharedHandle::ExternalImageDescriptorDXGISharedHandle()
52         : ExternalImageDescriptor(ExternalImageType::DXGISharedHandle) {
53     }
54 
ExternalImageDXGI(ComPtr<ID3D12Resource> d3d12Resource,const WGPUTextureDescriptor * descriptor)55     ExternalImageDXGI::ExternalImageDXGI(ComPtr<ID3D12Resource> d3d12Resource,
56                                          const WGPUTextureDescriptor* descriptor)
57         : mD3D12Resource(std::move(d3d12Resource)),
58           mUsage(descriptor->usage),
59           mDimension(descriptor->dimension),
60           mSize(descriptor->size),
61           mFormat(descriptor->format),
62           mMipLevelCount(descriptor->mipLevelCount),
63           mSampleCount(descriptor->sampleCount) {
64         ASSERT(!descriptor->nextInChain ||
65                descriptor->nextInChain->sType == WGPUSType_DawnTextureInternalUsageDescriptor);
66         if (descriptor->nextInChain) {
67             mUsageInternal = reinterpret_cast<const WGPUDawnTextureInternalUsageDescriptor*>(
68                                  descriptor->nextInChain)
69                                  ->internalUsage;
70         }
71         mD3D11on12ResourceCache = std::make_unique<D3D11on12ResourceCache>();
72     }
73 
74     ExternalImageDXGI::~ExternalImageDXGI() = default;
75 
ProduceTexture(WGPUDevice device,const ExternalImageAccessDescriptorDXGIKeyedMutex * descriptor)76     WGPUTexture ExternalImageDXGI::ProduceTexture(
77         WGPUDevice device,
78         const ExternalImageAccessDescriptorDXGIKeyedMutex* descriptor) {
79         Device* backendDevice = ToBackend(FromAPI(device));
80 
81         // Ensure the texture usage is allowed
82         if (!IsSubset(descriptor->usage, mUsage)) {
83             dawn::ErrorLog() << "Texture usage is not valid for external image";
84             return nullptr;
85         }
86 
87         TextureDescriptor textureDescriptor = {};
88         textureDescriptor.usage = static_cast<wgpu::TextureUsage>(descriptor->usage);
89         textureDescriptor.dimension = static_cast<wgpu::TextureDimension>(mDimension);
90         textureDescriptor.size = {mSize.width, mSize.height, mSize.depthOrArrayLayers};
91         textureDescriptor.format = static_cast<wgpu::TextureFormat>(mFormat);
92         textureDescriptor.mipLevelCount = mMipLevelCount;
93         textureDescriptor.sampleCount = mSampleCount;
94 
95         DawnTextureInternalUsageDescriptor internalDesc = {};
96         if (mUsageInternal) {
97             textureDescriptor.nextInChain = &internalDesc;
98             internalDesc.internalUsage = static_cast<wgpu::TextureUsage>(mUsageInternal);
99             internalDesc.sType = wgpu::SType::DawnTextureInternalUsageDescriptor;
100         }
101 
102         Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource =
103             mD3D11on12ResourceCache->GetOrCreateD3D11on12Resource(device, mD3D12Resource.Get());
104         if (d3d11on12Resource == nullptr) {
105             dawn::ErrorLog() << "Unable to create 11on12 resource for external image";
106             return nullptr;
107         }
108 
109         Ref<TextureBase> texture = backendDevice->CreateExternalTexture(
110             &textureDescriptor, mD3D12Resource, std::move(d3d11on12Resource),
111             ExternalMutexSerial(descriptor->acquireMutexKey),
112             ExternalMutexSerial(descriptor->releaseMutexKey), descriptor->isSwapChainTexture,
113             descriptor->isInitialized);
114 
115         return ToAPI(texture.Detach());
116     }
117 
118     // static
Create(WGPUDevice device,const ExternalImageDescriptorDXGISharedHandle * descriptor)119     std::unique_ptr<ExternalImageDXGI> ExternalImageDXGI::Create(
120         WGPUDevice device,
121         const ExternalImageDescriptorDXGISharedHandle* descriptor) {
122         Device* backendDevice = ToBackend(FromAPI(device));
123 
124         Microsoft::WRL::ComPtr<ID3D12Resource> d3d12Resource;
125         if (FAILED(backendDevice->GetD3D12Device()->OpenSharedHandle(
126                 descriptor->sharedHandle, IID_PPV_ARGS(&d3d12Resource)))) {
127             return nullptr;
128         }
129 
130         const TextureDescriptor* textureDescriptor = FromAPI(descriptor->cTextureDescriptor);
131 
132         if (backendDevice->ConsumedError(
133                 ValidateTextureDescriptor(backendDevice, textureDescriptor))) {
134             return nullptr;
135         }
136 
137         if (backendDevice->ConsumedError(
138                 ValidateTextureDescriptorCanBeWrapped(textureDescriptor),
139                 "validating that a D3D12 external image can be wrapped with %s",
140                 textureDescriptor)) {
141             return nullptr;
142         }
143 
144         if (backendDevice->ConsumedError(
145                 ValidateD3D12TextureCanBeWrapped(d3d12Resource.Get(), textureDescriptor))) {
146             return nullptr;
147         }
148 
149         // Shared handle is assumed to support resource sharing capability. The resource
150         // shared capability tier must agree to share resources between D3D devices.
151         const Format* format =
152             backendDevice->GetInternalFormat(textureDescriptor->format).AcquireSuccess();
153         if (format->IsMultiPlanar()) {
154             if (backendDevice->ConsumedError(ValidateD3D12VideoTextureCanBeShared(
155                     backendDevice, D3D12TextureFormat(textureDescriptor->format)))) {
156                 return nullptr;
157             }
158         }
159 
160         std::unique_ptr<ExternalImageDXGI> result(
161             new ExternalImageDXGI(std::move(d3d12Resource), descriptor->cTextureDescriptor));
162         return result;
163     }
164 
SetExternalMemoryReservation(WGPUDevice device,uint64_t requestedReservationSize,MemorySegment memorySegment)165     uint64_t SetExternalMemoryReservation(WGPUDevice device,
166                                           uint64_t requestedReservationSize,
167                                           MemorySegment memorySegment) {
168         Device* backendDevice = ToBackend(FromAPI(device));
169 
170         return backendDevice->GetResidencyManager()->SetExternalMemoryReservation(
171             memorySegment, requestedReservationSize);
172     }
173 
AdapterDiscoveryOptions()174     AdapterDiscoveryOptions::AdapterDiscoveryOptions()
175         : AdapterDiscoveryOptionsBase(WGPUBackendType_D3D12), dxgiAdapter(nullptr) {
176     }
177 
AdapterDiscoveryOptions(ComPtr<IDXGIAdapter> adapter)178     AdapterDiscoveryOptions::AdapterDiscoveryOptions(ComPtr<IDXGIAdapter> adapter)
179         : AdapterDiscoveryOptionsBase(WGPUBackendType_D3D12), dxgiAdapter(std::move(adapter)) {
180     }
181 }}  // namespace dawn_native::d3d12
182