| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659 |
- // Copyright (C) 2009-present, Panagiotis Christopoulos Charitos and contributors.
- // All rights reserved.
- // Code licensed under the BSD License.
- // http://www.anki3d.org/LICENSE
- #include <AnKi/Gr/D3D/D3DGrManager.h>
- #include <AnKi/Gr/D3D/D3DDescriptor.h>
- #include <AnKi/Gr/D3D/D3DAccelerationStructure.h>
- #include <AnKi/Gr/D3D/D3DTexture.h>
- #include <AnKi/Gr/D3D/D3DCommandBuffer.h>
- #include <AnKi/Gr/D3D/D3DShader.h>
- #include <AnKi/Gr/D3D/D3DShaderProgram.h>
- #include <AnKi/Gr/D3D/D3DTexture.h>
- #include <AnKi/Gr/D3D/D3DPipelineQuery.h>
- #include <AnKi/Gr/D3D/D3DSampler.h>
- #include <AnKi/Gr/RenderGraph.h>
- #include <AnKi/Gr/D3D/D3DGrUpscaler.h>
- #include <AnKi/Gr/D3D/D3DTimestampQuery.h>
- #include <AnKi/ShaderCompiler/Common.h>
- #include <AnKi/Util/Tracer.h>
- #if ANKI_WINDOWING_SYSTEM_SDL
- # include <AnKi/Window/NativeWindowSdl.h>
- #endif
- // Use the Agility SDK
- extern "C" {
- __declspec(dllexport) extern const UINT D3D12SDKVersion = 616; // Number taken from the download page
- __declspec(dllexport) extern const char* D3D12SDKPath = ".\\"; // The D3D12Core.dll should be in the same dir as the .exe
- }
- namespace anki {
- static void NTAPI d3dDebugMessageCallback([[maybe_unused]] D3D12_MESSAGE_CATEGORY category, D3D12_MESSAGE_SEVERITY severity,
- [[maybe_unused]] D3D12_MESSAGE_ID id, LPCSTR pDescription, [[maybe_unused]] void* pContext)
- {
- if(id == D3D12_MESSAGE_ID_INVALID_BARRIER_ACCESS)
- {
- // Skip these for now
- return;
- }
- if(!Logger::isAllocated())
- {
- printf("d3dDebugMessageCallback : %s", pDescription);
- return;
- }
- else
- {
- switch(severity)
- {
- case D3D12_MESSAGE_SEVERITY_CORRUPTION:
- case D3D12_MESSAGE_SEVERITY_ERROR:
- ANKI_D3D_LOGE("%s", pDescription);
- break;
- case D3D12_MESSAGE_SEVERITY_WARNING:
- ANKI_D3D_LOGW("%s", pDescription);
- break;
- case D3D12_MESSAGE_SEVERITY_INFO:
- case D3D12_MESSAGE_SEVERITY_MESSAGE:
- ANKI_D3D_LOGI("%s", pDescription);
- break;
- }
- }
- }
- template<>
- template<>
- GrManager& MakeSingletonPtr<GrManager>::allocateSingleton<>()
- {
- ANKI_ASSERT(m_global == nullptr);
- m_global = new GrManagerImpl;
- #if ANKI_ASSERTIONS_ENABLED
- ++g_singletonsAllocated;
- #endif
- return *m_global;
- }
- template<>
- void MakeSingletonPtr<GrManager>::freeSingleton()
- {
- if(m_global)
- {
- delete static_cast<GrManagerImpl*>(m_global);
- m_global = nullptr;
- #if ANKI_ASSERTIONS_ENABLED
- --g_singletonsAllocated;
- #endif
- }
- }
- GrManager::GrManager()
- {
- }
- GrManager::~GrManager()
- {
- }
- PtrSize GrManager::getAccelerationStructureMemoryRequirement(const AccelerationStructureInitInfo& init) const
- {
- PtrSize asSize, unused;
- AccelerationStructureImpl::getMemoryRequirement(init, asSize, unused);
- return asSize;
- }
- Error GrManager::init(GrManagerInitInfo& inf)
- {
- ANKI_D3D_SELF(GrManagerImpl);
- return self.initInternal(inf);
- }
- void GrManager::beginFrame()
- {
- ANKI_D3D_SELF(GrManagerImpl);
- self.beginFrameInternal();
- }
- TexturePtr GrManager::acquireNextPresentableTexture()
- {
- ANKI_D3D_SELF(GrManagerImpl);
- return self.acquireNextPresentableTextureInternal();
- }
- void GrManager::endFrame()
- {
- ANKI_D3D_SELF(GrManagerImpl);
- self.endFrameInternal();
- }
- void GrManager::finish()
- {
- ANKI_D3D_SELF(GrManagerImpl);
- self.finishInternal();
- }
- void GrManager::submit(WeakArray<CommandBuffer*> cmdbs, WeakArray<Fence*> waitFences, FencePtr* signalFence)
- {
- ANKI_D3D_SELF(GrManagerImpl);
- self.submitInternal(cmdbs, waitFences, signalFence);
- }
- #define ANKI_NEW_GR_OBJECT(type) \
- type##Ptr GrManager::new##type(const type##InitInfo& init) \
- { \
- type##Ptr ptr(type::newInstance(init)); \
- if(!ptr.isCreated()) [[unlikely]] \
- { \
- ANKI_D3D_LOGF("Failed to create a " ANKI_STRINGIZE(type) " object"); \
- } \
- return ptr; \
- }
- #define ANKI_NEW_GR_OBJECT_NO_INIT_INFO(type) \
- type##Ptr GrManager::new##type() \
- { \
- type##Ptr ptr(type::newInstance()); \
- if(!ptr.isCreated()) [[unlikely]] \
- { \
- ANKI_D3D_LOGF("Failed to create a " ANKI_STRINGIZE(type) " object"); \
- } \
- return ptr; \
- }
- ANKI_NEW_GR_OBJECT(Buffer)
- ANKI_NEW_GR_OBJECT(Texture)
- ANKI_NEW_GR_OBJECT(Sampler)
- ANKI_NEW_GR_OBJECT(Shader)
- ANKI_NEW_GR_OBJECT(ShaderProgram)
- ANKI_NEW_GR_OBJECT(CommandBuffer)
- ANKI_NEW_GR_OBJECT_NO_INIT_INFO(TimestampQuery)
- ANKI_NEW_GR_OBJECT(PipelineQuery)
- ANKI_NEW_GR_OBJECT_NO_INIT_INFO(RenderGraph)
- ANKI_NEW_GR_OBJECT(AccelerationStructure)
- ANKI_NEW_GR_OBJECT(GrUpscaler)
- #undef ANKI_NEW_GR_OBJECT
- #undef ANKI_NEW_GR_OBJECT_NO_INIT_INFO
- GrManagerImpl::~GrManagerImpl()
- {
- destroy();
- }
- void GrManagerImpl::beginFrameInternal()
- {
- ANKI_TRACE_FUNCTION();
- LockGuard<Mutex> lock(m_globalMtx);
- // Do that at begin frame, ALWAYS
- m_crntFrame = (m_crntFrame + 1) % m_frames.getSize();
- PerFrame& frame = m_frames[m_crntFrame];
- // Wait for the oldest frame because we don't want to start the new one too early
- {
- ANKI_TRACE_SCOPED_EVENT(WaitFences);
- for(MicroFencePtr& fence : frame.m_fences)
- {
- if(fence)
- {
- const Bool signaled = fence->clientWait(kMaxSecond);
- if(!signaled)
- {
- ANKI_D3D_LOGF("Timeout detected");
- }
- }
- }
- }
- frame.m_fences.destroy();
- frame.m_queueWroteToSwapchainImage = GpuQueueType::kCount;
- // Clear garbage
- deleteObjectsMarkedForDeletion();
- }
- TexturePtr GrManagerImpl::acquireNextPresentableTextureInternal()
- {
- ANKI_TRACE_FUNCTION();
- m_crntSwapchain->m_backbufferIdx = m_crntSwapchain->m_swapchain->GetCurrentBackBufferIndex();
- Texture* tex = m_crntSwapchain->m_textures[m_crntSwapchain->m_backbufferIdx].get();
- return TexturePtr(tex);
- }
- void GrManagerImpl::endFrameInternal()
- {
- ANKI_TRACE_FUNCTION();
- m_crntSwapchain->m_swapchain->Present((g_cvarGrVsync) ? 1 : 0, (g_cvarGrVsync) ? 0 : DXGI_PRESENT_ALLOW_TEARING);
- MicroFencePtr presentFence = FenceFactory::getSingleton().newInstance("Present");
- presentFence->getImplementation().gpuSignal(GpuQueueType::kGeneral); // Only general can present
- LockGuard lock(m_globalMtx);
- auto& crntFrame = m_frames[m_crntFrame];
- crntFrame.m_fences.emplaceBack(presentFence);
- DescriptorFactory::getSingleton().endFrame();
- }
- void GrManagerImpl::submitInternal(WeakArray<CommandBuffer*> cmdbs, WeakArray<Fence*> waitFences, FencePtr* signalFence)
- {
- ANKI_TRACE_FUNCTION();
- // First thing, create a fence
- MicroFencePtr fence = FenceFactory::getSingleton().newInstance("Submit");
- // Gather command lists
- GrDynamicArray<ID3D12CommandList*> d3dCmdLists;
- d3dCmdLists.resizeStorage(cmdbs.getSize());
- GpuQueueType queueType = GpuQueueType::kCount;
- for(CommandBuffer* cmdb : cmdbs)
- {
- CommandBufferImpl& impl = static_cast<CommandBufferImpl&>(*cmdb);
- MicroCommandBuffer& mcmdb = impl.getMicroCommandBuffer();
- d3dCmdLists.emplaceBack(&mcmdb.getCmdList());
- if(queueType == GpuQueueType::kCount)
- {
- queueType = mcmdb.getQueueType();
- }
- else
- {
- ANKI_ASSERT(queueType == mcmdb.getQueueType());
- }
- impl.postSubmitWork(fence.get());
- }
- // Wait for fences
- for(Fence* fence : waitFences)
- {
- FenceImpl& impl = static_cast<FenceImpl&>(*fence);
- impl.m_fence->getImplementation().gpuWait(queueType);
- }
- // Submit command lists
- m_queues[queueType]->ExecuteCommandLists(d3dCmdLists.getSize(), d3dCmdLists.getBegin());
- // Signal fence
- fence->getImplementation().gpuSignal(queueType);
- if(signalFence)
- {
- FenceImpl* fenceImpl = anki::newInstance<FenceImpl>(GrMemoryPool::getSingleton(), "SignalFence");
- fenceImpl->m_fence = fence;
- signalFence->reset(fenceImpl);
- }
- LockGuard lock(m_globalMtx);
- m_frames[m_crntFrame].m_fences.emplaceBack(fence.get());
- }
- void GrManagerImpl::finishInternal()
- {
- LockGuard<Mutex> lock(m_globalMtx);
- // Queue wait
- if(FenceFactory::isAllocated())
- {
- for(GpuQueueType qType : EnumIterable<GpuQueueType>())
- {
- MicroFencePtr fence = FenceFactory::getSingleton().newInstance();
- fence->getImplementation().gpuSignal(qType);
- fence->clientWait(kMaxSecond);
- }
- }
- for(PerFrame& frame : m_frames)
- {
- for(MicroFencePtr& fence : frame.m_fences)
- {
- const Bool signaled = fence->clientWait(kMaxSecond);
- if(!signaled)
- {
- ANKI_D3D_LOGF("Timeout detected");
- }
- }
- frame.m_fences.destroy();
- }
- // Since we waited for the GPU do a cleanup as well
- const U8 oldFrame = m_crntFrame;
- for(U8 frame = 0; frame < m_frames.getSize(); ++frame)
- {
- m_crntFrame = frame;
- deleteObjectsMarkedForDeletion();
- }
- m_crntFrame = oldFrame;
- }
- Error GrManagerImpl::initInternal(const GrManagerInitInfo& init)
- {
- ANKI_D3D_LOGI("Initializing D3D backend");
- GrMemoryPool::allocateSingleton(init.m_allocCallback, init.m_allocCallbackUserData);
- // Validation
- UINT dxgiFactoryFlags = 0;
- if(g_cvarGrValidation || g_cvarGrGpuValidation)
- {
- ComPtr<ID3D12Debug> debugInterface;
- ANKI_D3D_CHECK(D3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)));
- debugInterface->EnableDebugLayer();
- dxgiFactoryFlags |= DXGI_CREATE_FACTORY_DEBUG;
- if(g_cvarGrGpuValidation)
- {
- ComPtr<ID3D12Debug1> debugInterface1;
- ANKI_D3D_CHECK(debugInterface->QueryInterface(IID_PPV_ARGS(&debugInterface1)));
- debugInterface1->SetEnableGPUBasedValidation(true);
- }
- ANKI_D3D_LOGI("Validation is enabled (GPU validation %s)", (g_cvarGrGpuValidation) ? "as well" : "no");
- }
- ComPtr<IDXGIFactory2> factory2;
- ANKI_D3D_CHECK(CreateDXGIFactory2(dxgiFactoryFlags, IID_PPV_ARGS(&factory2)));
- ComPtr<IDXGIFactory6> factory6;
- ANKI_D3D_CHECK(factory2->QueryInterface(IID_PPV_ARGS(&factory6)));
- // Get adapters
- struct Adapter
- {
- ComPtr<IDXGIAdapter1> m_adapter;
- DXGI_ADAPTER_DESC1 m_descr;
- };
- GrDynamicArray<Adapter> adapters;
- ComPtr<IDXGIAdapter1> pAdapter;
- UINT adapterIdx = 0;
- while(factory6->EnumAdapterByGpuPreference(adapterIdx, DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE, IID_PPV_ARGS(&pAdapter)) != DXGI_ERROR_NOT_FOUND)
- {
- Adapter& a = *adapters.emplaceBack();
- a.m_adapter = pAdapter;
- pAdapter->GetDesc1(&a.m_descr);
- ++adapterIdx;
- }
- const U32 chosenPhysDevIdx = min<U32>(g_cvarGrDevice, adapters.getSize() - 1);
- ANKI_D3D_LOGI("Physical devices:");
- for(U32 i = 0; i < adapters.getSize(); ++i)
- {
- ANKI_D3D_LOGI((i == chosenPhysDevIdx) ? "\t(Selected) %s" : "\t%s", ws2s(&adapters[i].m_descr.Description[0]).c_str());
- }
- // Find vendor
- switch(adapters[chosenPhysDevIdx].m_descr.VendorId)
- {
- case 0x13B5:
- m_capabilities.m_gpuVendor = GpuVendor::kArm;
- break;
- case 0x10DE:
- m_capabilities.m_gpuVendor = GpuVendor::kNvidia;
- break;
- case 0x1002:
- case 0x1022:
- m_capabilities.m_gpuVendor = GpuVendor::kAMD;
- break;
- case 0x8086:
- m_capabilities.m_gpuVendor = GpuVendor::kIntel;
- break;
- case 0x5143:
- m_capabilities.m_gpuVendor = GpuVendor::kQualcomm;
- break;
- default:
- m_capabilities.m_gpuVendor = GpuVendor::kUnknown;
- }
- ANKI_D3D_LOGI("Vendor identified as %s", &kGPUVendorStrings[m_capabilities.m_gpuVendor][0]);
- // Create device
- ComPtr<ID3D12Device> dev;
- ANKI_D3D_CHECK(D3D12CreateDevice(adapters[chosenPhysDevIdx].m_adapter.Get(), D3D_FEATURE_LEVEL_12_1, IID_PPV_ARGS(&dev)));
- ANKI_D3D_CHECK(dev->QueryInterface(IID_PPV_ARGS(&m_device)));
- if(g_cvarGrValidation)
- {
- ComPtr<ID3D12InfoQueue1> infoq;
- const HRESULT res = m_device->QueryInterface(IID_PPV_ARGS(&infoq));
- if(res == S_OK)
- {
- ANKI_D3D_CHECK(
- infoq->RegisterMessageCallback(d3dDebugMessageCallback, D3D12_MESSAGE_CALLBACK_FLAG_NONE, nullptr, &m_debugMessageCallbackCookie));
- }
- else
- {
- ANKI_D3D_LOGW("ID3D12InfoQueue1 not supported");
- // At least break when debugging
- if(IsDebuggerPresent())
- {
- ComPtr<ID3D12InfoQueue> infoq;
- const HRESULT res = m_device->QueryInterface(IID_PPV_ARGS(&infoq));
- if(res == S_OK)
- {
- infoq->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_ERROR, true);
- // infoq->SetBreakOnSeverity(D3D12_MESSAGE_SEVERITY_WARNING, true);
- }
- }
- }
- }
- if(g_cvarGrDred)
- {
- ComPtr<ID3D12DeviceRemovedExtendedDataSettings> dredSettings;
- ANKI_D3D_CHECK(D3D12GetDebugInterface(IID_PPV_ARGS(&dredSettings)));
- // Turn on AutoBreadcrumbs and Page Fault reporting
- dredSettings->SetAutoBreadcrumbsEnablement(D3D12_DRED_ENABLEMENT_FORCED_ON);
- dredSettings->SetPageFaultEnablement(D3D12_DRED_ENABLEMENT_FORCED_ON);
- ANKI_D3D_LOGI("DRED is enabled");
- m_canInvokeDred = true;
- }
- // Create queues
- {
- D3D12_COMMAND_QUEUE_DESC queueDesc = {};
- queueDesc.Flags = D3D12_COMMAND_QUEUE_FLAG_NONE;
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
- ANKI_D3D_CHECK(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_queues[GpuQueueType::kGeneral])));
- queueDesc.Type = D3D12_COMMAND_LIST_TYPE_COMPUTE;
- ANKI_D3D_CHECK(m_device->CreateCommandQueue(&queueDesc, IID_PPV_ARGS(&m_queues[GpuQueueType::kCompute])));
- ANKI_D3D_CHECK(m_queues[GpuQueueType::kGeneral]->GetTimestampFrequency(&m_timestampFrequency));
- }
- // Set device capabilities (taken from mesa's dozen driver)
- {
- D3D12_FEATURE_DATA_D3D12_OPTIONS1 options1;
- ANKI_D3D_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS1, &options1, sizeof(options1)));
- D3D12_FEATURE_DATA_D3D12_OPTIONS5 options5;
- ANKI_D3D_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS5, &options5, sizeof(options5)));
- D3D12_FEATURE_DATA_D3D12_OPTIONS16 options16;
- ANKI_D3D_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS16, &options16, sizeof(options16)));
- D3D12_FEATURE_DATA_ARCHITECTURE architecture = {.NodeIndex = 0};
- ANKI_D3D_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_ARCHITECTURE, &architecture, sizeof(architecture)));
- D3D12_FEATURE_DATA_D3D12_OPTIONS21 options21;
- ANKI_D3D_CHECK(m_device->CheckFeatureSupport(D3D12_FEATURE_D3D12_OPTIONS21, &options21, sizeof(options21)));
- if(g_cvarGrWorkGraphcs && options21.WorkGraphsTier == D3D12_WORK_GRAPHS_TIER_NOT_SUPPORTED)
- {
- ANKI_D3D_LOGW("WorkGraphs can't be enabled. They not supported");
- }
- else if(g_cvarGrWorkGraphcs && options21.WorkGraphsTier != D3D12_WORK_GRAPHS_TIER_NOT_SUPPORTED)
- {
- ANKI_D3D_LOGV("WorkGraphs supported");
- m_capabilities.m_workGraphs = true;
- }
- m_d3dCapabilities.m_rebar = options16.GPUUploadHeapSupported;
- if(!m_d3dCapabilities.m_rebar)
- {
- ANKI_D3D_LOGW("ReBAR not supported");
- }
- if(g_cvarGrRayTracing && options5.RaytracingTier != D3D12_RAYTRACING_TIER_1_1)
- {
- ANKI_D3D_LOGW("Raytracing can't be enabled. Not supported");
- m_capabilities.m_rayTracingEnabled = false;
- }
- else if(g_cvarGrRayTracing && options5.RaytracingTier == D3D12_RAYTRACING_TIER_1_1)
- {
- ANKI_D3D_LOGV("Raytracing supported");
- m_capabilities.m_rayTracingEnabled = true;
- }
- else
- {
- m_capabilities.m_rayTracingEnabled = false;
- }
- m_capabilities.m_minWaveSize = options1.WaveLaneCountMin;
- m_capabilities.m_maxWaveSize = options1.WaveLaneCountMax;
- m_capabilities.m_constantBufferBindOffsetAlignment = D3D12_CONSTANT_BUFFER_DATA_PLACEMENT_ALIGNMENT;
- m_capabilities.m_structuredBufferBindOffsetAlignment = 0; // Not for DX
- m_capabilities.m_structuredBufferNaturalAlignment = true;
- m_capabilities.m_texelBufferBindOffsetAlignment = 32;
- m_capabilities.m_fastConstantsSize = kMaxFastConstantsSize;
- m_capabilities.m_computeSharedMemorySize = D3D12_CS_TGSM_REGISTER_COUNT * sizeof(F32);
- m_capabilities.m_sbtRecordAlignment = 32; // ?
- m_capabilities.m_maxDrawIndirectCount = kMaxU32;
- m_capabilities.m_discreteGpu = !architecture.UMA;
- m_capabilities.m_majorApiVersion = 12;
- m_capabilities.m_vrs = g_cvarGrVrs;
- m_capabilities.m_unalignedBbpTextureFormats = false;
- m_capabilities.m_dlss = false;
- m_capabilities.m_meshShaders = g_cvarGrMeshShaders;
- m_capabilities.m_pipelineQuery = true;
- m_capabilities.m_barycentrics = true;
- m_capabilities.m_shaderGroupHandleSize = D3D12_SHADER_IDENTIFIER_SIZE_IN_BYTES;
- // It should be D3D12_RAYTRACING_SHADER_RECORD_BYTE_ALIGNMENT but anki uses a single SBT for raygen, miss and hit groups so the non raygen
- // groups should be aligned to the SBT buffer itself
- m_capabilities.m_sbtRecordAlignment = D3D12_RAYTRACING_SHADER_TABLE_BYTE_ALIGNMENT;
- }
- // Other systems
- DescriptorFactory::allocateSingleton();
- ANKI_CHECK(DescriptorFactory::getSingleton().init());
- SwapchainFactory::allocateSingleton();
- m_crntSwapchain = SwapchainFactory::getSingleton().newInstance();
- RootSignatureFactory::allocateSingleton();
- FenceFactory::allocateSingleton();
- CommandBufferFactory::allocateSingleton();
- IndirectCommandSignatureFactory::allocateSingleton();
- ANKI_CHECK(IndirectCommandSignatureFactory::getSingleton().init());
- TimestampQueryFactory::allocateSingleton();
- PrimitivesPassedClippingFactory::allocateSingleton();
- {
- BufferInitInfo buffInit("ZeroBuffer");
- buffInit.m_mapAccess = BufferMapAccessBit::kWrite;
- buffInit.m_size = 1_KB;
- buffInit.m_usage = BufferUsageBit::kCopySource;
- m_zeroBuffer = newBuffer(buffInit);
- void* mapped = m_zeroBuffer->map(0, kMaxPtrSize, BufferMapAccessBit::kWrite);
- memset(mapped, 0, buffInit.m_size);
- m_zeroBuffer->unmap();
- }
- return Error::kNone;
- }
- void GrManagerImpl::destroy()
- {
- ANKI_D3D_LOGI("Destroying D3D backend");
- finishInternal();
- // Destroy everything that has a reference to GrObjects.
- m_zeroBuffer.reset(nullptr);
- m_crntSwapchain.reset(nullptr);
- SwapchainFactory::freeSingleton();
- for(U8 frame = 0; frame < m_frames.getSize(); ++frame)
- {
- m_crntFrame = frame;
- deleteObjectsMarkedForDeletion();
- }
- // Destroy systems
- PrimitivesPassedClippingFactory::freeSingleton();
- TimestampQueryFactory::freeSingleton();
- CommandBufferFactory::freeSingleton();
- RootSignatureFactory::freeSingleton();
- DescriptorFactory::freeSingleton();
- IndirectCommandSignatureFactory::freeSingleton();
- FenceFactory::freeSingleton();
- safeRelease(m_queues[GpuQueueType::kGeneral]);
- safeRelease(m_queues[GpuQueueType::kCompute]);
- safeRelease(m_device);
- // Report objects that didn't cleaned up
- {
- ComPtr<IDXGIDebug1> dxgiDebug;
- if(SUCCEEDED(DXGIGetDebugInterface1(0, IID_PPV_ARGS(&dxgiDebug))))
- {
- dxgiDebug->ReportLiveObjects(DXGI_DEBUG_ALL, DXGI_DEBUG_RLO_FLAGS(DXGI_DEBUG_RLO_SUMMARY | DXGI_DEBUG_RLO_IGNORE_INTERNAL));
- }
- }
- GrMemoryPool::freeSingleton();
- }
- void GrManagerImpl::invokeDred() const
- {
- Bool error = false;
- do
- {
- if(m_canInvokeDred)
- {
- ComPtr<ID3D12DeviceRemovedExtendedData> pDred;
- if(!SUCCEEDED(m_device->QueryInterface(IID_PPV_ARGS(&pDred))))
- {
- error = true;
- break;
- }
- D3D12_DRED_AUTO_BREADCRUMBS_OUTPUT dredAutoBreadcrumbsOutput;
- if(!SUCCEEDED(pDred->GetAutoBreadcrumbsOutput(&dredAutoBreadcrumbsOutput)))
- {
- error = true;
- break;
- }
- D3D12_DRED_PAGE_FAULT_OUTPUT dredPageFaultOutput;
- if(!SUCCEEDED(pDred->GetPageFaultAllocationOutput(&dredPageFaultOutput)))
- {
- error = true;
- break;
- }
- }
- } while(false);
- }
- } // end namespace anki
|