[DirectX12][DXR] Imgui 적용과정에서 겪었던 버그와 해결과정

윤태웅·2023년 12월 14일
0

DirectX12

목록 보기
9/11
post-thumbnail

개요

https://velog.io/@15ywt/DirectX12DXR-%EB%A0%8C%EB%8D%94%EB%9F%AC%EC%97%90-Imgui-%EC%A0%81%EC%9A%A9%ED%95%98%EA%B8%B0
이전 글에서는 DirectX12 DXR프로젝트에 Imgui를 적용시킨 과정을 포스팅했었는데,
이번 글에서는 해당 과정에서 겪었던 버그들을 정리하고 어떻게 해결하였는지 적어보고자 한다.

문제상황


imgui에서 제공하는 파일들을 모두 프로젝트에 포함시키고 호출해야 하는 함수들을 적절하게 호출했는데, UI가 나오지 않았다.
Output창에는 어떠한 에러 로그도 뜨지 않았고,
VS디버거를 통해서 모든 함수들은 정상적으로 호출되고 있는 것도 확인하였다.

해결과정

문제 분석

일단 VS디버거로 모든 함수가 정상 호출됨을 확인한 시점에 GPU부분에서 문제가 발생했다는 것을 인식할 수 있었다. 그래서 GPU디버거인 PIX를 사용하기로 했다. PIX를 이용해서 문제가 발생한 내 렌더러와 정상동작하는 Imgui DX12 예제 렌더러를 모두 캡쳐해서 비교했다.


->Imgui가 출력안되는 내 렌더러 캡쳐


->Imgui가 잘 출력되는 예제 렌더러 캡쳐

분석결과

  1. DescriptorHeaps 칸에서 Imgui를 위한 별도의 SRVDescriptorHeap이 필요함을 인지함
  2. 내 렌더러에는 OM(Output Merger)스테이지에 렌더타겟이 GPU에 설정되어있지 않은 점을 확인함

이렇게 2가지 문제를 PIX를 통해 발견할 수 있었다.

문제 해결 코드작성

2가지 문제를 해결하는 코드를 추가해야 했다.

1번 문제 해결

1번 문제를 해결하기 위해서 Imgui만을 위한 별도의 SRVDescriptorHeap을 새로 만들었고 commandList에서 Imgui를 렌더링할때 DescriptorHeap을 설정하는 코드를 추가하였다.

{//imgui render
    ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), pCommandList.Get());
}

기존 코드

{//imgui render
    pCommandList->SetDescriptorHeaps(1,m_renderingResources.GetImguiDescriptorHeap().GetDescriptorHeap().GetAddressOf());
    ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), pCommandList.Get());
}

1번 문제 해결 코드

2번 문제 해결

2번 문제를 해결하기 위해서는 Imgui드로우콜 함수 호출전에 OMSetRenderTargets함수를 호출하였다.

{//imgui render
    pCommandList->SetDescriptorHeaps(1,m_renderingResources.GetImguiDescriptorHeap().GetDescriptorHeap().GetAddressOf());
    ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), pCommandList.Get());
}

기존코드

{//imgui render
    pCommandList->SetDescriptorHeaps(1,m_renderingResources.GetImguiDescriptorHeap().GetDescriptorHeap().GetAddressOf());
    D3D12_CPU_DESCRIPTOR_HANDLE rtvCPUHandle = m_renderingResources.GetRTVDescriptorHeap().GetRTVCPUHandle(m_renderingResources.GetFrameIndex());
    pCommandList->OMSetRenderTargets(1u,&rtvCPUHandle,FALSE,nullptr);
    ImGui_ImplDX12_RenderDrawData(ImGui::GetDrawData(), pCommandList.Get());
}

2번 문제 해결코드

결과


잘 나온다! Imgui를 처음 적용할때는 그냥 완전히 기존 렌더러와 디커플링되어서 따로 렌더링되는줄 알았지만, 이런 문제를 겪으면서 결국 렌더타겟을 연결하고 별도의 Imgui용 디스크립터힙을 만들어주는 과정을 프로그래머가 관리해야한다는 것을 알게되었다.

0개의 댓글