오늘은 크러시가 나는 부분을 고치고,
그 뒤에 새로운 문제를 직면하고 이를 고치다가 뛰쳐나갈것만 같은 정신을 붙잡고 있습니다.

 

우선 크러시 부분.

이 코드를 짜면서 몇몇 Class는 상위버전이 나와서 이를 가져다 썼는데, 그 중 하나가 SwapChain이었습니다.

하지만 이 부분이 문제임은 알겠는데 새로 나온 SwapChain1이 어떻게 하면 정상적으로 사용할 수 있는지
알 수 없어 그냥 SwapChain으로 원상복구했습니다.

 

대부분의 문제들은 오타들로 인한 것이거나, 이처럼 최신 코드를 사용하는 방법을 알지 못해서 발생했습니다.

답답한건 라이브러리 코드 구현체를 보면 대충 어느부분을 주의해야하는지 감이 잡히는데.

DirectX12는 특정 헤더만 열려있고 구현체는 닫혀있어 구현체를 알 수가 없습니다.

 

다음 문제가 이런 종류였습니다.

이제 크러시는 나지 않는데, DXError가 발생하면서 Model Shading이 출력되지 않고 있습니다.

에로 코드는 다음과 같습니다.

 

D3D12 ERROR: ID3D12CommandQueue::ExecuteCommandLists: 
Using ClearDepthStencilView on Command List (0x0A75BC28:'Unnamed ID3D12GraphicsCommandList Object'): 
Resource state (0x0: D3D12_RESOURCE_STATE_[COMMON|PRESENT]) of resource (0x0A6DE398:'Unnamed ID3D12Resource Object') (subresource: 1) 
is invalid for use as a depth buffer.  

Expected State Bits (all): 0x10: D3D12_RESOURCE_STATE_DEPTH_WRITE, 
\Actual State: 0x0: D3D12_RESOURCE_STATE_[COMMON|PRESENT], 
Missing State: 0x10: D3D12_RESOURCE_STATE_DEPTH_WRITE. 
[ EXECUTION ERROR #538: INVALID_SUBRESOURCE_STATE]

즉 CommandLists에 담겨있는 Comaand 중 ClearDepthStencilView를 호출하면서 사용하는 resource의
Resource State의 값이 적절치 못하다는 것입니다.

 

여기서 좀 머리가 복잡해졌습니다. 우선 문제가 발생된다고 예상되는 코드 부분을 발췌했습니다.

void BoxApp::Draw(const GameTimer& gt)
{
	ThrowIfFailed(mDirectCmdListAlloc->Reset());
	ThrowIfFailed(mCommandList->Reset(mDirectCmdListAlloc.Get(), mPSO.Get()));

	// Set CommandList
	mCommandList->RSSetViewports(1, &mScreenViewport);
	mCommandList->RSSetScissorRects(1, &mScissorRect);

	// Set CommandList - not problem
	D3D12_RESOURCE_BARRIER BeforeBarrier;
	ZeroMemory(&BeforeBarrier, sizeof(BeforeBarrier));
	BeforeBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
	BeforeBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
	BeforeBarrier.Transition.pResource = CurrentBackBuffer();
	BeforeBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
	BeforeBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
	BeforeBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;

	mCommandList->ResourceBarrier(1, &BeforeBarrier);

	mCommandList->ClearRenderTargetView(CurrentBackBufferView(), Colors::LightSteelBlue, 0, nullptr);
	mCommandList->ClearDepthStencilView(DepthStencilView(), D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr);

	// Specify the buffers we are going to render to.
	// Set CommandList
	mCommandList->OMSetRenderTargets(1, &CurrentBackBufferView(), true, &DepthStencilView());

	ID3D12DescriptorHeap* descriptorHeaps[] = { mCbvHeap.Get() };
	mCommandList->SetDescriptorHeaps(_countof(descriptorHeaps), descriptorHeaps);

	// Set CommandList
	mCommandList->SetGraphicsRootSignature(mRootSignature.Get());

	// Set CommandList
	mCommandList->IASetVertexBuffers(0, 1, &mBoxGeo->VertexBufferView());
	mCommandList->IASetIndexBuffer(&mBoxGeo->IndexBufferView());
	mCommandList->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLELIST);

	// Set CommandList
	mCommandList->SetGraphicsRootDescriptorTable(0, mCbvHeap->GetGPUDescriptorHandleForHeapStart());

	mCommandList->DrawIndexedInstanced(mBoxGeo->DrawArgs["box"].IndexCount, 1, 0, 0, 0);

	// Set CommandList - not problem
	D3D12_RESOURCE_BARRIER AfterBarrier;
	ZeroMemory(&AfterBarrier, sizeof(AfterBarrier));
	AfterBarrier.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
	AfterBarrier.Flags = D3D12_RESOURCE_BARRIER_FLAG_NONE;
	AfterBarrier.Transition.pResource = CurrentBackBuffer();
	AfterBarrier.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
	AfterBarrier.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
	AfterBarrier.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
	
	mCommandList->ResourceBarrier(1, &AfterBarrier);
	ThrowIfFailed(mCommandList->Close());

	ID3D12CommandList* cmdsLists[] = { mCommandList.Get() };
	mCommandQueue->ExecuteCommandLists(_countof(cmdsLists), cmdsLists);

	ThrowIfFailed(mSwapChain->Present(0, 0));
	mCurrentBackBuffer = (mCurrentBackBuffer + 1) % SwapChainBufferCount;

	FlushCommandQueue();
}

 

1. Resource State를 가져다 쓰는 것은 Resource_Barrier 선언 두번 뿐입니다.
둘의 StateBefore와 StateAfter가 대칭인 것으로 보아 아마 고친다면 둘 다 고쳐야 할것입니다.

2. 로그에 찍힌대로만 하면 Resource_State_Present를 Resource_State_Depth_Write로 고치면 될 것입니다. 
하지만 그렇게 되면 그 사이 함수들 부분에서 에러가 발생합니다.

3. 로그에 찍힌 또 다른 요소인 ClearDepthStencilView 부분을 직접 수정해야 하나
원래 코드와 다른 부분이 없어 무엇이 문제인지 파악할 수 없습니다.

 

이 상태에서 Resource_Barrier 사이에 선언된 모든 함수나 파라미터를 건드려 보았으나
유의미한 성과를 얻지 못했습니다.

 

 

정말 참... 정신 나갈 것 같습니다.

거의 문제 하나를 일주일동안 붙들고 있으니 진행도 안되고 미쳐버릴 것 같습니다.

빨리 빌드를 완성했으면 좋겠습니다.

그래야 코드 하나하나 뜯어서 구조를 머릿속에 박아넣을텐데...

'내용정리 > DirectX12' 카테고리의 다른 글

20.08.25 개발일지  (0) 2020.08.25
20.08.21 개발일지  (0) 2020.08.21
20.08.14 일지  (0) 2020.08.14
20.08.07 개발일지  (0) 2020.08.07
20.08.04 일지  (0) 2020.08.04

+ Recent posts