void Draw() { mFrameCount++; int cmdIndex = mFrameCount % MaxFrameLatency; auto* cmdQueue = mCmdQueue.Get(); auto* cmdList = mCmdList.Get(); // Wait untill next queue be freed if (mFrameCount > MaxFrameLatency) { mFence->SetEventOnCompletion(mFrameCount - MaxFrameLatency, mFenceEveneHandle); DWORD wait = WaitForSingleObject(mFenceEveneHandle, 10000); if (wait != WAIT_OBJECT_0) throw runtime_error("Failed WaitForSingleObject()."); CHK(mCmdAlloc[cmdIndex]->Reset()); } CHK(cmdList->Reset(mCmdAlloc[cmdIndex].Get(), nullptr)); // Upload constant buffer { static float rot = 0.0f; rot += 1.0f; if (rot >= 360.0f) rot = 0.0f; XMMATRIX worldMat, viewMat, projMat; worldMat = XMMatrixRotationY(XMConvertToRadians(rot)); viewMat = XMMatrixLookAtLH({ 0, 1, -1.5f }, { 0, 0.5f, 0 }, { 0, 1, 0 }); projMat = XMMatrixPerspectiveFovLH(45, (float)mBufferWidth / mBufferHeight, 0.01f, 50.0f); auto mvpMat = XMMatrixTranspose(worldMat * viewMat * projMat); auto worldTransMat = XMMatrixTranspose(worldMat); // mCBUploadPtr is Write-Combine memory // Shift offset to guarantee that the pointer has not referred by executing command list. char* ptr = reinterpret_cast<char*>(mCBUploadPtr) + CB_SIZE * cmdIndex; memcpy_s(ptr, 64, &mvpMat, 64); memcpy_s(ptr + 64, 64, &worldTransMat, 64); } // Get current RTV descriptor auto descHandleRtvStep = mDev->GetDescriptorHandleIncrementSize(D3D12_DESCRIPTOR_HEAP_TYPE_RTV); D3D12_CPU_DESCRIPTOR_HANDLE descHandleRtv = mDescHeapRtv->GetCPUDescriptorHandleForHeapStart(); descHandleRtv.ptr += ((mFrameCount - 1) % BUFFER_COUNT) * descHandleRtvStep; // Get current swap chain ID3D12Resource* d3dBuffer = mD3DBuffer[(mFrameCount - 1) % BUFFER_COUNT].Get(); // Get DSV auto descHandleDsv = mDescHeapDsv->GetCPUDescriptorHandleForHeapStart(); // Barrier Present -> RenderTarget setResourceBarrier(mCmdList.Get(), d3dBuffer, D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET); // Viewport & Scissor D3D12_VIEWPORT viewport = {}; viewport.Width = (float)mBufferWidth; viewport.Height = (float)mBufferHeight; viewport.MinDepth = 0.0f; viewport.MaxDepth = 1.0f; cmdList->RSSetViewports(1, &viewport); D3D12_RECT scissor = {}; scissor.right = (LONG)mBufferWidth; scissor.bottom = (LONG)mBufferHeight; cmdList->RSSetScissorRects(1, &scissor); // Clear DepthTexture mCmdList->ClearDepthStencilView(descHandleDsv, D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr); // Clear { float clearColor[4] = { 0.1f, 0.2f, 0.3f, 1.0f }; mCmdList->ClearRenderTargetView(descHandleRtv, clearColor, 0, nullptr); } mCmdList->OMSetRenderTargets(1, &descHandleRtv, true, &descHandleDsv); // Draw cmdList->SetGraphicsRootSignature(mRootSignature.Get()); ID3D12DescriptorHeap* descHeaps[] = { mDescHeapCbvSrvUav[cmdIndex].Get() }; cmdList->SetDescriptorHeaps(ARRAYSIZE(descHeaps), descHeaps); { cmdList->SetGraphicsRootDescriptorTable(0, mDescHeapCbvSrvUav[cmdIndex]->GetGPUDescriptorHandleForHeapStart()); cmdList->SetPipelineState(mPso.Get()); cmdList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST); cmdList->IASetVertexBuffers(0, 1, &mVBView); cmdList->IASetIndexBuffer(&mIBView); cmdList->DrawIndexedInstanced(mIndexCount, 1, 0, 0, 0); } // Barrier RenderTarget -> Present //setResourceBarrier(mCmdList.Get(), d3dBuffer, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT); // Exec CHK(cmdList->Close()); ID3D12CommandList* const cmdLists = cmdList; //cmdQueue->ExecuteCommandLists(1, &cmdLists); CHK(cmdQueue->Signal(mFence.Get(), mFrameCount)); // Acquire RTV for D3D11 ID3D11Resource* backBuffer11 = mBackBuffer11Tex[(mFrameCount - 1) % BUFFER_COUNT].Get(); mDev11on12->AcquireWrappedResources(&backBuffer11, 1); // Draw auto* rtv11 = mBackBuffer11Rtv[(mFrameCount - 1) % BUFFER_COUNT].Get(); float color11[4] = {0.4f, 0.2f, 0.1f, 1.0f}; mDevCont11->ClearRenderTargetView(rtv11, color11); // Release RTV for D3D11 mDev11on12->ReleaseWrappedResources(&backBuffer11, 1); // Present CHK(mSwapChain->Present(1, 0)); }