首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >亲爱的IMGUI和DirectX 12覆盖(DXGI_ERROR_INVALID_CALL)

亲爱的IMGUI和DirectX 12覆盖(DXGI_ERROR_INVALID_CALL)
EN

Stack Overflow用户
提问于 2020-08-27 12:07:26
回答 1查看 2.9K关注 0票数 1

我试图做一个简单的框架计数器为DirectX 12游戏使用亲爱的IMGUI。我只是想覆盖一个小的透明窗口,以显示游戏期间帧的顺序。要做到这一点,我要挂钩Present(),这样我就可以获得SwapChain,并计算调用该方法的次数(帧计数)。这不是为了作弊。,我不是为游戏写作弊,我只是想记录帧数,以便于分析。

我已经在DirectX 11中成功地使用了这里提供的ShowExampleAppSimpleOverlay()示例:demo.cpp

下面是一个图像示例,显示DX 11游戏中的帧计数器。

我现在也在DirectX 12上做同样的工作,连接Present()不是问题。

使用这里提供的示例代码:directx12 12/main.cpp

我再次尝试使用ShowExampleAppSimpleOverlay()方法,但是在我对d3d12CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&d3d12CommandList);的调用(用于呈现覆盖)的代码中,它会导致一个错误表示(0x887A0001: DXGI_ERROR_INVALID_CALL)。这是下面提供的代码示例中的最后一行代码:

我不知道该怎么做。有什么想法吗?

编辑:我忘了提到,我也是挂钩和获取游戏命令que。因此,d3d12CommandQueue是直接从游戏中获得的。它不返回NULL,所以我假设它是正确的对象。但我可能错了..。

对于当前()的每个调用,请执行以下操作:

代码语言:javascript
运行
复制
//iterate frame
Frame_Number = Frame_Number + 1;

//Get Device, using IDXGISwapChain3
ID3D12Device* device;
HRESULT gd = pSwapChain->GetDevice(__uuidof(ID3D12Device), (void**)&device);
assert(gd == S_OK);

//Get window handle from swapchain for IMGUI
DXGI_SWAP_CHAIN_DESC sd;
pSwapChain->GetDesc(&sd);
window = sd.OutputWindow;

//Get backbuffers
buffersCounts = sd.BufferCount;
frameContext = new FrameContext[buffersCounts];

D3D12_DESCRIPTOR_HEAP_DESC descriptorImGuiRender = {};
descriptorImGuiRender.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
descriptorImGuiRender.NumDescriptors = buffersCounts;
descriptorImGuiRender.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;

// Create Descriptor Heap IMGUI render
if (device->CreateDescriptorHeap(&descriptorImGuiRender, IID_PPV_ARGS(&d3d12DescriptorHeapImGuiRender)) != S_OK)
    return false;

//Create Command Allocator
ID3D12CommandAllocator* allocator;
if (device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_DIRECT, IID_PPV_ARGS(&allocator)) != S_OK)
    return false;

for (size_t i = 0; i < buffersCounts; i++) {
    frameContext[i].commandAllocator = allocator;
}

if (device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_DIRECT, allocator, NULL, IID_PPV_ARGS(&d3d12CommandList)) != S_OK ||
    d3d12CommandList->Close() != S_OK)
    return false;

//create descriptor heap, describe and create a render target view (RTV) descriptor heap.
D3D12_DESCRIPTOR_HEAP_DESC descriptorBackBuffers;
descriptorBackBuffers.Type = D3D12_DESCRIPTOR_HEAP_TYPE_RTV;
descriptorBackBuffers.NumDescriptors = buffersCounts;
descriptorBackBuffers.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
descriptorBackBuffers.NodeMask = 1;

if (device->CreateDescriptorHeap(&descriptorBackBuffers, IID_PPV_ARGS(&d3d12DescriptorHeapBackBuffers)) != S_OK)
    return false;
const auto rtvDescriptorSize = device->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV);

// Create frame resources.
D3D12_CPU_DESCRIPTOR_HANDLE rtvHandle = d3d12DescriptorHeapBackBuffers->GetCPUDescriptorHandleForHeapStart();

// Create a RTV for each frame.
for (size_t i = 0; i < buffersCounts; i++) {
    ID3D12Resource* pBackBuffer = nullptr;

    frameContext[i].main_render_target_descriptor = rtvHandle;
    pSwapChain->GetBuffer(i, IID_PPV_ARGS(&pBackBuffer));
    device->CreateRenderTargetView(pBackBuffer, nullptr, rtvHandle);
    frameContext[i].main_render_target_resource = pBackBuffer;
    rtvHandle.ptr += rtvDescriptorSize;
}

// Setup Platform/Renderer bindings dor IMGUI
ImGui_ImplWin32_Init(window);
ImGui_ImplDX12_Init(device, buffersCounts,
    DXGI_FORMAT_R8G8B8A8_UNORM, d3d12DescriptorHeapImGuiRender,
    d3d12DescriptorHeapImGuiRender->GetCPUDescriptorHandleForHeapStart(),
    d3d12DescriptorHeapImGuiRender->GetGPUDescriptorHandleForHeapStart());
ImGui::GetIO().ImeWindowHandle = window;

// Start the Dear ImGui frame
ImGui_ImplDX12_NewFrame();
ImGui_ImplWin32_NewFrame();
ImGui::NewFrame();

//call imgui menues here
bool bShow = true;
ShowExampleAppSimpleOverlay(&bShow);

// Rendering (imgui)
FrameContext& currentFrameContext = frameContext[pSwapChain->GetCurrentBackBufferIndex()];
currentFrameContext.commandAllocator->Reset();

D3D12_RESOURCE_BARRIER barrier;
barrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
barrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
barrier.Transition.pResource = currentFrameContext.main_render_target_resource;
barrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;

d3d12CommandList->Reset(currentFrameContext.commandAllocator, nullptr);
d3d12CommandList->ResourceBarrier(1, &barrier);
d3d12CommandList->OMSetRenderTargets(1, &currentFrameContext.main_render_target_descriptor, FALSE, nullptr);

d3d12CommandList->SetDescriptorHeaps(1, &d3d12DescriptorHeapImGuiRender);

ImGui::Render();
ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), d3d12CommandList);

barrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
barrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;

d3d12CommandList->ResourceBarrier(1, &barrier);
d3d12CommandList->Close();

d3d12CommandQueue->ExecuteCommandLists(1, (ID3D12CommandList* const*)&d3d12CommandList);
EN

回答 1

Stack Overflow用户

发布于 2020-09-21 10:55:50

DXGI_ERROR_INVALID_CALL告诉列表中的一个命令无效,但哪个命令无效。

在创建命令列表时,您需要使用d3d12调试层进行运行时检查。调试层还会告诉您其无效的原因。

有关更多信息,请参见msdn

您可以使用以下代码对其进行aktivate,但是在设备创建之前需要调用它

代码语言:javascript
运行
复制
ID3D12Debug* debugInterface;
if (SUCCEEDED(D3D12GetDebugInterface(IID_PPV_ARGS(&debugInterface)))) {
    debugInterface->EnableDebugLayer();
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/63615630

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档