1 // Copyright 2017 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 #ifndef DAWNNATIVE_D3D12_DEVICED3D12_H_ 16 #define DAWNNATIVE_D3D12_DEVICED3D12_H_ 17 18 #include "common/SerialQueue.h" 19 #include "dawn_native/Device.h" 20 #include "dawn_native/d3d12/CommandRecordingContext.h" 21 #include "dawn_native/d3d12/D3D12Info.h" 22 #include "dawn_native/d3d12/Forward.h" 23 #include "dawn_native/d3d12/TextureD3D12.h" 24 25 namespace dawn_native { namespace d3d12 { 26 27 class CommandAllocatorManager; 28 class PlatformFunctions; 29 class ResidencyManager; 30 class ResourceAllocatorManager; 31 class SamplerHeapCache; 32 class ShaderVisibleDescriptorAllocator; 33 class StagingDescriptorAllocator; 34 35 #define ASSERT_SUCCESS(hr) \ 36 do { \ 37 HRESULT succeeded = hr; \ 38 ASSERT(SUCCEEDED(succeeded)); \ 39 } while (0) 40 41 // Definition of backend types 42 class Device final : public DeviceBase { 43 public: 44 static ResultOrError<Device*> Create(Adapter* adapter, 45 const DawnDeviceDescriptor* descriptor); 46 ~Device() override; 47 48 MaybeError Initialize(); 49 50 ResultOrError<Ref<CommandBufferBase>> CreateCommandBuffer( 51 CommandEncoder* encoder, 52 const CommandBufferDescriptor* descriptor) override; 53 54 MaybeError TickImpl() override; 55 56 ID3D12Device* GetD3D12Device() const; 57 ComPtr<ID3D12CommandQueue> GetCommandQueue() const; 58 ID3D12SharingContract* GetSharingContract() const; 59 60 ComPtr<ID3D12CommandSignature> GetDispatchIndirectSignature() const; 61 ComPtr<ID3D12CommandSignature> GetDrawIndirectSignature() const; 62 ComPtr<ID3D12CommandSignature> GetDrawIndexedIndirectSignature() const; 63 64 CommandAllocatorManager* GetCommandAllocatorManager() const; 65 ResidencyManager* GetResidencyManager() const; 66 67 const PlatformFunctions* GetFunctions() const; 68 ComPtr<IDXGIFactory4> GetFactory() const; 69 ComPtr<IDxcLibrary> GetDxcLibrary() const; 70 ComPtr<IDxcCompiler> GetDxcCompiler() const; 71 ComPtr<IDxcValidator> GetDxcValidator() const; 72 73 ResultOrError<CommandRecordingContext*> GetPendingCommandContext(); 74 75 MaybeError ClearBufferToZero(CommandRecordingContext* commandContext, 76 BufferBase* destination, 77 uint64_t destinationOffset, 78 uint64_t size); 79 80 const D3D12DeviceInfo& GetDeviceInfo() const; 81 82 MaybeError NextSerial(); 83 MaybeError WaitForSerial(ExecutionSerial serial); 84 85 void ReferenceUntilUnused(ComPtr<IUnknown> object); 86 87 MaybeError ExecutePendingCommandContext(); 88 89 ResultOrError<std::unique_ptr<StagingBufferBase>> CreateStagingBuffer(size_t size) override; 90 MaybeError CopyFromStagingToBuffer(StagingBufferBase* source, 91 uint64_t sourceOffset, 92 BufferBase* destination, 93 uint64_t destinationOffset, 94 uint64_t size) override; 95 96 void CopyFromStagingToBufferImpl(CommandRecordingContext* commandContext, 97 StagingBufferBase* source, 98 uint64_t sourceOffset, 99 BufferBase* destination, 100 uint64_t destinationOffset, 101 uint64_t size); 102 103 MaybeError CopyFromStagingToTexture(const StagingBufferBase* source, 104 const TextureDataLayout& src, 105 TextureCopy* dst, 106 const Extent3D& copySizePixels) override; 107 108 ResultOrError<ResourceHeapAllocation> AllocateMemory( 109 D3D12_HEAP_TYPE heapType, 110 const D3D12_RESOURCE_DESC& resourceDescriptor, 111 D3D12_RESOURCE_STATES initialUsage); 112 113 void DeallocateMemory(ResourceHeapAllocation& allocation); 114 115 ShaderVisibleDescriptorAllocator* GetViewShaderVisibleDescriptorAllocator() const; 116 ShaderVisibleDescriptorAllocator* GetSamplerShaderVisibleDescriptorAllocator() const; 117 118 // Returns nullptr when descriptor count is zero. 119 StagingDescriptorAllocator* GetViewStagingDescriptorAllocator( 120 uint32_t descriptorCount) const; 121 122 StagingDescriptorAllocator* GetSamplerStagingDescriptorAllocator( 123 uint32_t descriptorCount) const; 124 125 SamplerHeapCache* GetSamplerHeapCache(); 126 127 StagingDescriptorAllocator* GetRenderTargetViewAllocator() const; 128 129 StagingDescriptorAllocator* GetDepthStencilViewAllocator() const; 130 131 Ref<TextureBase> CreateExternalTexture(const TextureDescriptor* descriptor, 132 ComPtr<ID3D12Resource> d3d12Texture, 133 Ref<D3D11on12ResourceCacheEntry> d3d11on12Resource, 134 ExternalMutexSerial acquireMutexKey, 135 ExternalMutexSerial releaseMutexKey, 136 bool isSwapChainTexture, 137 bool isInitialized); 138 139 ComPtr<ID3D11On12Device> GetOrCreateD3D11on12Device(); 140 141 void InitTogglesFromDriver(); 142 143 uint32_t GetOptimalBytesPerRowAlignment() const override; 144 uint64_t GetOptimalBufferToTextureCopyOffsetAlignment() const override; 145 146 float GetTimestampPeriodInNS() const override; 147 148 bool ShouldDuplicateNumWorkgroupsForDispatchIndirect( 149 ComputePipelineBase* computePipeline) const override; 150 151 private: 152 using DeviceBase::DeviceBase; 153 154 ResultOrError<Ref<BindGroupBase>> CreateBindGroupImpl( 155 const BindGroupDescriptor* descriptor) override; 156 ResultOrError<Ref<BindGroupLayoutBase>> CreateBindGroupLayoutImpl( 157 const BindGroupLayoutDescriptor* descriptor, 158 PipelineCompatibilityToken pipelineCompatibilityToken) override; 159 ResultOrError<Ref<BufferBase>> CreateBufferImpl( 160 const BufferDescriptor* descriptor) override; 161 ResultOrError<Ref<PipelineLayoutBase>> CreatePipelineLayoutImpl( 162 const PipelineLayoutDescriptor* descriptor) override; 163 ResultOrError<Ref<QuerySetBase>> CreateQuerySetImpl( 164 const QuerySetDescriptor* descriptor) override; 165 ResultOrError<Ref<SamplerBase>> CreateSamplerImpl( 166 const SamplerDescriptor* descriptor) override; 167 ResultOrError<Ref<ShaderModuleBase>> CreateShaderModuleImpl( 168 const ShaderModuleDescriptor* descriptor, 169 ShaderModuleParseResult* parseResult) override; 170 ResultOrError<Ref<SwapChainBase>> CreateSwapChainImpl( 171 const SwapChainDescriptor* descriptor) override; 172 ResultOrError<Ref<NewSwapChainBase>> CreateSwapChainImpl( 173 Surface* surface, 174 NewSwapChainBase* previousSwapChain, 175 const SwapChainDescriptor* descriptor) override; 176 ResultOrError<Ref<TextureBase>> CreateTextureImpl( 177 const TextureDescriptor* descriptor) override; 178 ResultOrError<Ref<TextureViewBase>> CreateTextureViewImpl( 179 TextureBase* texture, 180 const TextureViewDescriptor* descriptor) override; 181 Ref<ComputePipelineBase> CreateUninitializedComputePipelineImpl( 182 const ComputePipelineDescriptor* descriptor) override; 183 Ref<RenderPipelineBase> CreateUninitializedRenderPipelineImpl( 184 const RenderPipelineDescriptor* descriptor) override; 185 void InitializeComputePipelineAsyncImpl(Ref<ComputePipelineBase> computePipeline, 186 WGPUCreateComputePipelineAsyncCallback callback, 187 void* userdata) override; 188 void InitializeRenderPipelineAsyncImpl(Ref<RenderPipelineBase> renderPipeline, 189 WGPUCreateRenderPipelineAsyncCallback callback, 190 void* userdata) override; 191 192 void DestroyImpl() override; 193 MaybeError WaitForIdleForDestruction() override; 194 195 MaybeError CheckDebugLayerAndGenerateErrors(); 196 197 MaybeError ApplyUseDxcToggle(); 198 199 MaybeError CreateZeroBuffer(); 200 201 ComPtr<ID3D12Fence> mFence; 202 HANDLE mFenceEvent = nullptr; 203 ResultOrError<ExecutionSerial> CheckAndUpdateCompletedSerials() override; 204 205 ComPtr<ID3D12Device> mD3d12Device; // Device is owned by adapter and will not be outlived. 206 ComPtr<ID3D12CommandQueue> mCommandQueue; 207 ComPtr<ID3D12SharingContract> mD3d12SharingContract; 208 209 // 11on12 device corresponding to mCommandQueue 210 ComPtr<ID3D11On12Device> mD3d11On12Device; 211 212 ComPtr<ID3D12CommandSignature> mDispatchIndirectSignature; 213 ComPtr<ID3D12CommandSignature> mDrawIndirectSignature; 214 ComPtr<ID3D12CommandSignature> mDrawIndexedIndirectSignature; 215 216 CommandRecordingContext mPendingCommands; 217 218 SerialQueue<ExecutionSerial, ComPtr<IUnknown>> mUsedComObjectRefs; 219 220 std::unique_ptr<CommandAllocatorManager> mCommandAllocatorManager; 221 std::unique_ptr<ResourceAllocatorManager> mResourceAllocatorManager; 222 std::unique_ptr<ResidencyManager> mResidencyManager; 223 224 static constexpr uint32_t kMaxSamplerDescriptorsPerBindGroup = 225 3 * kMaxSamplersPerShaderStage; 226 static constexpr uint32_t kMaxViewDescriptorsPerBindGroup = 227 kMaxBindingsPerPipelineLayout - kMaxSamplerDescriptorsPerBindGroup; 228 229 static constexpr uint32_t kNumSamplerDescriptorAllocators = 230 ConstexprLog2Ceil(kMaxSamplerDescriptorsPerBindGroup) + 1; 231 static constexpr uint32_t kNumViewDescriptorAllocators = 232 ConstexprLog2Ceil(kMaxViewDescriptorsPerBindGroup) + 1; 233 234 // Index corresponds to Log2Ceil(descriptorCount) where descriptorCount is in 235 // the range [0, kMaxSamplerDescriptorsPerBindGroup]. 236 std::array<std::unique_ptr<StagingDescriptorAllocator>, kNumViewDescriptorAllocators + 1> 237 mViewAllocators; 238 239 // Index corresponds to Log2Ceil(descriptorCount) where descriptorCount is in 240 // the range [0, kMaxViewDescriptorsPerBindGroup]. 241 std::array<std::unique_ptr<StagingDescriptorAllocator>, kNumSamplerDescriptorAllocators + 1> 242 mSamplerAllocators; 243 244 std::unique_ptr<StagingDescriptorAllocator> mRenderTargetViewAllocator; 245 246 std::unique_ptr<StagingDescriptorAllocator> mDepthStencilViewAllocator; 247 248 std::unique_ptr<ShaderVisibleDescriptorAllocator> mViewShaderVisibleDescriptorAllocator; 249 250 std::unique_ptr<ShaderVisibleDescriptorAllocator> mSamplerShaderVisibleDescriptorAllocator; 251 252 // Sampler cache needs to be destroyed before the CPU sampler allocator to ensure the final 253 // release is called. 254 std::unique_ptr<SamplerHeapCache> mSamplerHeapCache; 255 256 // A buffer filled with zeros that is used to copy into other buffers when they need to be 257 // cleared. 258 Ref<Buffer> mZeroBuffer; 259 260 // The number of nanoseconds required for a timestamp query to be incremented by 1 261 float mTimestampPeriod = 1.0f; 262 }; 263 264 }} // namespace dawn_native::d3d12 265 266 #endif // DAWNNATIVE_D3D12_DEVICED3D12_H_ 267