안녕하세요. 다렉12 ms sample 보면서 공부중입니다.
정점 3개 위치랑 색깔 넣어서 삼각형 띄우는건 성공해서 텍스쳐를 입혀보려고 하는데 궁금한게 생겼습니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | // Render the scene. void D3D12HelloTexture::OnRender() { // Record all the commands we need to render the scene into the command list. PopulateCommandList(); // Execute the command list. ID3D12CommandList* ppCommandLists[] = { m_commandList.Get() }; m_commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists); // Present the frame. ThrowIfFailed(m_swapChain->Present(1, 0)); WaitForPreviousFrame(); } void D3D12HelloTexture::PopulateCommandList() { // Command list allocators can only be reset when the associated // command lists have finished execution on the GPU; apps should use // fences to determine GPU execution progress. ThrowIfFailed(m_commandAllocator->Reset()); // However, when ExecuteCommandList() is called on a particular command // list, that command list can then be reset at any time and must be before // re-recording. ThrowIfFailed(m_commandList->Reset(m_commandAllocator.Get(), m_pipelineState.Get())); // Set necessary state. m_commandList->SetGraphicsRootSignature(m_rootSignature.Get()); ID3D12DescriptorHeap* ppHeaps[] = { m_srvHeap.Get() }; m_commandList->SetDescriptorHeaps(_countof(ppHeaps), ppHeaps); m_commandList->SetGraphicsRootDescriptorTable(0, m_srvHeap->GetGPUDescriptorHandleForHeapStart()); m_commandList->RSSetViewports(1, &m_viewport); m_commandList->RSSetScissorRects(1, &m_scissorRect); // Indicate that the back buffer will be used as a render target. m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET)); CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(m_rtvHeap->GetCPUDescriptorHandleForHeapStart(), m_frameIndex, m_rtvDescriptorSize); m_commandList->OMSetRenderTargets(1, &rtvHandle, FALSE, nullptr); // Record commands. const float clearColor[] = { 0.0f, 0.2f, 0.4f, 1.0f }; m_commandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr); m_commandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); m_commandList->IASetVertexBuffers(0, 1, &m_vertexBufferView); m_commandList->DrawInstanced(3, 1, 0, 0); // Indicate that the back buffer will now be used to present. m_commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(m_renderTargets[m_frameIndex].Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT)); ThrowIfFailed(m_commandList->Close()); } | cs |
이게 MS sample 코드 HelloTexture!의 렌더 부분인데요. 궁금한게 있습니다.
지금은 텍스쳐를 입힌 삼각형만 띄우면 되기 때문에 필요한 descriptorHeap만 set 해주면 되는데
나중에 게임을 만들든 뭘 만들든 하면, 저 순간에 어떤걸 렌더링할지 모르잖아요.
그런데 그 순간에 필요한 descriptorHeap을 어떻게 선택해야할 지 모르겠습니다.
정리하자면,
1. 매 순간마다 렌더링 해야하는게 다르다.
2. 따라서 매 순간마다 필요한 디스크립터가 다르다. 어느 때는 srv가 필요할 수도 있지만 필요하지 않을 수도 있음.
3. 그러면 커맨드리스트에 디스크립터 힙을 넣을때, 넣을 힙과 안넣을 힙을 어떻게 구분해야하는가... ㅠ
너무 뉴비라 고급 갤에 수준낮은 질문 남기는거 죄송합니다...
바인딩 되는 게 다르면 디스크립터 힙도 바뀌어야지 그럼 뭐 어찌함?
넣을 힙과 안 넣을 힙을 어떻게 구분하냐면, 프로그래머가 구분해주면 됨
그러라고 D3D12가 있는 거임
좀 더 공부해야겠네요. 감사합니다.
처음하는거면 그냥 11하세요
저도 DX12 부터 공부 해왔음. 이런식으로 분석해보고 코드 카피해보고 하면 2~3 개월 안에 구상이 잡힐 거임. 그리고 님이 고민하시는 "그래픽스 파이프라인에 바인딩 된 디스크립터를 상황에 따라 어떻게 바꾸나요?"는 DX12에서는 그냥 단순하게 해결 된다. 만일 3가지 종류의 그래픽스 파이프라인을 필요로 한다면 그래픽스 파이프라인을 3개 만들어서 상황에 따라 command list에 원하는 파이프라인을 바인딩 하면 됨.
그래서 렌더타겟, 디스크립터 셋, 블랜딩 옵션, 테셀레이션 사용 여부 등등 여러가지 옵션의 경우의 수 들을 모두 곱한 값 만큼 파이프라인을 생성하게 됨. 그래픽스 파이프라인 종류가 100개가 넘는 경우도 수두룩함.
이거 이제야 보네요 ㅋㅋㅋㅋㅋ 감사합니다!