void D3D12RenderState::ApplyState(ID3D12GraphicsCommandList *cmd) const { if(pipe != ResourceId()) cmd->SetPipelineState(GetResourceManager()->GetCurrentAs<ID3D12PipelineState>(pipe)); if(!views.empty()) cmd->RSSetViewports((UINT)views.size(), &views[0]); if(!scissors.empty()) cmd->RSSetScissorRects((UINT)scissors.size(), &scissors[0]); if(topo != D3D_PRIMITIVE_TOPOLOGY_UNDEFINED) cmd->IASetPrimitiveTopology(topo); cmd->OMSetStencilRef(stencilRef); cmd->OMSetBlendFactor(blendFactor); if(ibuffer.buf != ResourceId()) { D3D12_INDEX_BUFFER_VIEW ib; ID3D12Resource *res = GetResourceManager()->GetCurrentAs<ID3D12Resource>(ibuffer.buf); if(res) ib.BufferLocation = res->GetGPUVirtualAddress() + ibuffer.offs; else ib.BufferLocation = 0; ib.Format = (ibuffer.bytewidth == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT); ib.SizeInBytes = ibuffer.size; cmd->IASetIndexBuffer(&ib); } for(size_t i = 0; i < vbuffers.size(); i++) { D3D12_VERTEX_BUFFER_VIEW vb; ID3D12Resource *res = GetResourceManager()->GetCurrentAs<ID3D12Resource>(vbuffers[i].buf); if(res) vb.BufferLocation = res->GetGPUVirtualAddress() + vbuffers[i].offs; else vb.BufferLocation = 0; vb.StrideInBytes = vbuffers[i].stride; vb.SizeInBytes = vbuffers[i].size; cmd->IASetVertexBuffers((UINT)i, 1, &vb); } std::vector<ID3D12DescriptorHeap *> descHeaps; descHeaps.resize(heaps.size()); for(size_t i = 0; i < heaps.size(); i++) descHeaps[i] = GetResourceManager()->GetCurrentAs<ID3D12DescriptorHeap>(heaps[i]); if(!descHeaps.empty()) cmd->SetDescriptorHeaps((UINT)descHeaps.size(), &descHeaps[0]); if(!rts.empty() || dsv.heap != ResourceId()) { D3D12_CPU_DESCRIPTOR_HANDLE rtHandles[8]; D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = CPUHandleFromPortableHandle(GetResourceManager(), dsv); UINT rtCount = (UINT)rts.size(); UINT numActualHandles = rtSingle ? RDCMIN(1U, rtCount) : rtCount; for(UINT i = 0; i < numActualHandles; i++) rtHandles[i] = CPUHandleFromPortableHandle(GetResourceManager(), rts[i]); // need to unwrap here, as FromPortableHandle unwraps too. Unwrap(cmd)->OMSetRenderTargets((UINT)rts.size(), rtHandles, rtSingle ? TRUE : FALSE, dsv.heap != ResourceId() ? &dsvHandle : NULL); } if(graphics.rootsig != ResourceId()) { cmd->SetGraphicsRootSignature( GetResourceManager()->GetCurrentAs<ID3D12RootSignature>(graphics.rootsig)); ApplyGraphicsRootElements(cmd); } if(compute.rootsig != ResourceId()) { cmd->SetComputeRootSignature( GetResourceManager()->GetCurrentAs<ID3D12RootSignature>(compute.rootsig)); ApplyComputeRootElements(cmd); } }
void D3D12RenderState::ApplyState(ID3D12GraphicsCommandList *cmd) { if(pipe != ResourceId()) cmd->SetPipelineState(GetResourceManager()->GetCurrentAs<ID3D12PipelineState>(pipe)); if(!views.empty()) cmd->RSSetViewports((UINT)views.size(), &views[0]); if(!scissors.empty()) cmd->RSSetScissorRects((UINT)scissors.size(), &scissors[0]); if(topo != D3D_PRIMITIVE_TOPOLOGY_UNDEFINED) cmd->IASetPrimitiveTopology(topo); cmd->OMSetStencilRef(stencilRef); cmd->OMSetBlendFactor(blendFactor); if(ibuffer.buf != ResourceId()) { D3D12_INDEX_BUFFER_VIEW ib; ID3D12Resource *res = GetResourceManager()->GetCurrentAs<ID3D12Resource>(ibuffer.buf); if(res) ib.BufferLocation = res->GetGPUVirtualAddress() + ibuffer.offs; else ib.BufferLocation = 0; ib.Format = (ibuffer.bytewidth == 2 ? DXGI_FORMAT_R16_UINT : DXGI_FORMAT_R32_UINT); ib.SizeInBytes = ibuffer.size; cmd->IASetIndexBuffer(&ib); } for(size_t i = 0; i < vbuffers.size(); i++) { D3D12_VERTEX_BUFFER_VIEW vb; ID3D12Resource *res = GetResourceManager()->GetCurrentAs<ID3D12Resource>(vbuffers[i].buf); if(res) vb.BufferLocation = res->GetGPUVirtualAddress() + vbuffers[i].offs; else vb.BufferLocation = 0; vb.StrideInBytes = vbuffers[i].stride; vb.SizeInBytes = vbuffers[i].size; cmd->IASetVertexBuffers((UINT)i, 1, &vb); } std::vector<ID3D12DescriptorHeap *> descHeaps; descHeaps.resize(heaps.size()); for(size_t i = 0; i < heaps.size(); i++) descHeaps[i] = GetResourceManager()->GetCurrentAs<ID3D12DescriptorHeap>(heaps[i]); if(!descHeaps.empty()) cmd->SetDescriptorHeaps((UINT)descHeaps.size(), &descHeaps[0]); if(!rts.empty() || dsv.heap != ResourceId()) { D3D12_CPU_DESCRIPTOR_HANDLE rtHandles[8]; D3D12_CPU_DESCRIPTOR_HANDLE dsvHandle = CPUHandleFromPortableHandle(GetResourceManager(), dsv); UINT numActualHandles = rtSingle ? 1 : (UINT)rts.size(); for(UINT i = 0; i < numActualHandles; i++) rtHandles[i] = CPUHandleFromPortableHandle(GetResourceManager(), rts[i]); // need to unwrap here, as FromPortableHandle unwraps too. Unwrap(cmd)->OMSetRenderTargets((UINT)rts.size(), rtHandles, rtSingle ? TRUE : FALSE, dsv.heap != ResourceId() ? &dsvHandle : NULL); } if(graphics.rootsig != ResourceId()) { cmd->SetGraphicsRootSignature( GetResourceManager()->GetCurrentAs<ID3D12RootSignature>(graphics.rootsig)); for(size_t i = 0; i < graphics.sigelems.size(); i++) { // just don't set tables that aren't in the descriptor heaps, since it's invalid and can crash // and is probably just from stale bindings that aren't going to be used if(graphics.sigelems[i].type == eRootTable || std::find(heaps.begin(), heaps.end(), graphics.sigelems[i].id) != heaps.end()) { graphics.sigelems[i].SetToGraphics(GetResourceManager(), cmd, (UINT)i); } else { RDCDEBUG("Skipping setting possibly stale graphics root table referring to heap %llu", graphics.sigelems[i].id); } } } if(compute.rootsig != ResourceId()) { cmd->SetComputeRootSignature( GetResourceManager()->GetCurrentAs<ID3D12RootSignature>(compute.rootsig)); for(size_t i = 0; i < compute.sigelems.size(); i++) { // just don't set tables that aren't in the descriptor heaps, since it's invalid and can crash // and is probably just from stale bindings that aren't going to be used if(compute.sigelems[i].type != eRootTable || std::find(heaps.begin(), heaps.end(), compute.sigelems[i].id) != heaps.end()) { compute.sigelems[i].SetToCompute(GetResourceManager(), cmd, (UINT)i); } else { RDCDEBUG("Skipping setting possibly stale compute root table referring to heap %llu", compute.sigelems[i].id); } } } }