D3D12 – 옵티머스 장비에서의 문제점

옵티머스,엔듀로 이런게 평소에는 내장 gpu를 사용하다가 필요할때 dGPU를 쓰는 기술이다. 엔듀로는 요새 많이 안쓰는거 같고 요새 나오는 GPU특화된 대부분의 노트북들은 옵티머스 기술이 적용되어있다.

이 빌.어.먹.을 옵티머스가 DirectX 9/11세대에서도 많은 문제를 일으켜왔는데 DirectX 12에선 진짜 꽤 치명적인 문제를 안고 있고 아직 해결되지 않고 있다.

우선 Windows 10의 현재 정식빌드인 th2(10586)에서 Present()를 호출하면 간헐적으로 에러를 발생시킨다. 옵티머스 장비의 경우 3D렌더링은 dGPU가 처리하지만, 마지막에 화면을 Blt해주는건 내장 GPU가 수행한다. 여기서 문제가 생긴다. Fence를 걸고 모든 렌더링 작업이 끝나기를 기다리고 있는데도 사용중인 리소스의 상태가 바뀌었다는 에러가 발생한다.
물론 에러를 무시하고 진행할 수는 있다. 한 200프레임 넘게 나오면 화면이 간헐적으로 찢어진다.

그리고 Windoww 10의 차기 빌드인 Redstone(14328)에서 Present()를 호출하는 경우 비슷한 에러를 발생시킨다. 차이점은 ‘항상’ 에러가 발생한다. Present()후에 RenderTarget을 설정했던 텍스쳐 리소스의 D3D12_RESOURCE_STATE가 D3D12_RESOURCE_STATE_COPY_SOURCE로 바뀌어버린다.

ISwapChain 내부에서 Blt작업을 하기 위해서 바꿨다고 생각한다. 문제는 바꿔놨으면 돌려놔야할거 아냐…
Present가 완료된 후에도 그 상태 그대로 D3D12_RESOURCE_STATE_COPY_SOURCE 상태를 유지하고 있다. 진짜 문제는 이걸 프로그래머가 api를 사용해서 바꾸지 못한다. COMMAND_LIST_TYPE이 다르다고 거부된다.

더블버퍼링을 위해 2개 이상의 백버퍼를 사용하는데 처음 Present 한번은 성공하고 Present후에는 상태가 D3D12_RESOURCE_STATE_COPY_SOURCE로 바뀌어서 고정되므로 이후에 렌더타겟으로 쓸 수 없다. 2개의 버퍼 모두 Present한번씩 거치고나면 D3D12_RESOURCE_STATE_COPY_SOURCE로 바뀌어서 고정된다. 3개의 버퍼를 사용하거나 4개의 버퍼를 사용해도 마찬가지다. 3개든 4개든 모두 D3D12_RESOURCE_STATE_COPY_SOURCE로 바뀌어서 고정된다.
즉 Present()한번 하고 나면 사용했던 RenderTaget 버퍼는 아무짝에도 쓰지 못하는 상태가 되는 것이다.

물론 데스크탑 gpu나, 아예 인텔 내장 gpu에서만 돌리면 아무 문제 없다.
옵티머스로 돌릴때만 나타난다.

내가 뭘 잘못했다고? 아니 MS의 모든 샘플도 다 똑같은 증상을 보인다. 화면에 삼각형 한개 그리는 MS샘플도 똑같다.

혹시라도 레드스톤에서 문제가 해결됐을까 싶어서 서피스북을 레드스톤으로 올린거였는데 문제가 더 심긱해졌네.

대체 이건 누구 잘못인가. MS? intel? nvidia? 아니면 셋 다?
이 현상은 너무 쉽게 나오기 때문에 모를리가 없다. 아 누구든 문제좀 해결해달란 말이다.


댓글 남기기