Exemplo n.º 1
0
void AppTest::InitBundles()
{
	CHK(Device->CreateCommandAllocator(D3D12_COMMAND_LIST_TYPE_BUNDLE, IID_PPV_ARGS(CommandBundleAllocator.GetAddressOf())));

	for (unsigned int i = 0; i < BundleCount; i++)
	{
		const unsigned int bundlesPerThread = BundleCount / ThreadCount;
		const unsigned int threadID = i / bundlesPerThread;

		CHK(Device->CreateCommandList(0, D3D12_COMMAND_LIST_TYPE_BUNDLE, CommandBundleAllocator.Get(), PSO.Get(), IID_PPV_ARGS(CommandBundleArray[i].GetAddressOf())));

		ID3D12GraphicsCommandList* commandBundle = CommandBundleArray[i].Get();

		const unsigned int offset = ObjectsPerBundle * i;

		commandBundle->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLELIST);
		commandBundle->SetGraphicsRootSignature(RootSignature.Get());

		if (UseRootLevelCBV)
		{
			for (unsigned int command = 0; command < ObjectsPerBundle; command++)
			{
				commandBundle->SetGraphicsRootConstantBufferView(0, PerObjectConstantBuffers.GetGPUHandle(offset + command));
				commandBundle->DrawIndexedInstanced(IndexCount, 1, 0, 0, 0);
			}
		}
		else
		{
			D3D12_GPU_DESCRIPTOR_HANDLE descriptorHandle;

			ID3D12DescriptorHeap* descriptorHeap = ConstantBufferDescriptorHeap->GetBaseHeap();
			commandBundle->SetDescriptorHeaps(1, &descriptorHeap);

			for (unsigned int command = 0; command < ObjectsPerBundle; command++)
			{
				descriptorHandle.ptr = ConstantBufferDescriptorHeap->GetDescriptorGPUHandle(offset + command);
				commandBundle->SetGraphicsRootDescriptorTable(0, descriptorHandle);
				commandBundle->DrawIndexedInstanced(IndexCount, 1, 0, 0, 0);
			}
		}

		commandBundle->Close();
	}
}
void DXMultiAdapterRenderer::PopulateCommandLists()
{
	// Primary rendering command list
	{
		ComPtr<ID3D12Resource> curPrimaryRenderTarget = mDXDevices[Device_Primary]->mRenderTargets[mCurrentFrameIndex];

		// Reset allocator and command list for current render target
		ThrowIfFailed(mDXDevices[Device_Primary]->mCommandAllocator->Reset()); // Only do this when all command lists have finished executing
		ID3D12GraphicsCommandList* primaryCommandList = mCommandLists[Primary_CommandList_Scene].Get();
		ThrowIfFailed(primaryCommandList->Reset(mDXDevices[Device_Primary]->mCommandAllocator.Get(), nullptr));

		primaryCommandList->RSSetViewports(1, &mViewport);
		primaryCommandList->RSSetScissorRects(1, &mScissorRect);

		ID3D12DescriptorHeap* descHeaps[] = { mDXDevices[Device_Primary]->mCbvSrvUavHeap.Get() };
		primaryCommandList->SetDescriptorHeaps(_countof(descHeaps), descHeaps);

		// Allow for rending to current render target
		primaryCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(curPrimaryRenderTarget.Get(), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));

		CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mDXDevices[Device_Primary]->mRtvHeap->GetCPUDescriptorHandleForHeapStart(), mCurrentFrameIndex, mDXDevices[Device_Primary]->mRtvDescriptorSize);
		primaryCommandList->OMSetRenderTargets(1, &rtvHandle, true, nullptr);
		primaryCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
		primaryCommandList->IASetVertexBuffers(0, 1, mVertexBufferViews[Primary_Quad_Top]);

		// Render top portion of scene on primary GPU
		primaryCommandList->SetGraphicsRootSignature(mRootSignatures[Primary_RootSignature_Scene].Get());
		primaryCommandList->SetGraphicsRootDescriptorTable(0, mTimePrimaryCbvHandle);
		primaryCommandList->SetPipelineState(mPipelineStates[Primary_PipelineState_Scene].Get());
		primaryCommandList->DrawInstanced(4, 1, 0, 0);

		// Indicate that render target will be used for copy 
		primaryCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(curPrimaryRenderTarget.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_SOURCE));

		ThrowIfFailed(mCommandLists[Primary_CommandList_Scene]->Close());
	}

	// Copy command list - in DXCrossAdapterResources object
	{
		mCrossAdapterResources->PopulateCommandList(mCurrentFrameIndex);
	}

	// Reset command allocator for secondary device - used by all following command lists	
	ThrowIfFailed(mDXDevices[Device_Secondary]->mCommandAllocator->Reset()); // Only do this when all command lists have finished executing

	// Secondary rendering command list
	{
		ID3D12GraphicsCommandList* secondaryCommandList = mCommandLists[Secondary_CommandList_Scene].Get();
		ThrowIfFailed(secondaryCommandList->Reset(mDXDevices[Device_Secondary]->mCommandAllocator.Get(), nullptr));

		secondaryCommandList->RSSetViewports(1, &mViewport);
		secondaryCommandList->RSSetScissorRects(1, &mScissorRect);

		ID3D12DescriptorHeap* descHeaps[] = { mDXDevices[Device_Secondary]->mCbvSrvUavHeap.Get() };
		secondaryCommandList->SetDescriptorHeaps(_countof(descHeaps), descHeaps);

		secondaryCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mTexture.Get(), D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE, D3D12_RESOURCE_STATE_RENDER_TARGET));

		secondaryCommandList->OMSetRenderTargets(1, &mTextureRtvHandle, true, nullptr);
		secondaryCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
		secondaryCommandList->IASetVertexBuffers(0, 1, mVertexBufferViews[Secondary_Quad_Bottom]); // Quad geometry

		// Render bottom portion of scene on secondary GPU
		secondaryCommandList->SetGraphicsRootSignature(mRootSignatures[Secondary_RootSignature_Scene].Get());
		secondaryCommandList->SetGraphicsRootDescriptorTable(0, mTimeSecondaryCbvHandle);
		secondaryCommandList->SetPipelineState(mPipelineStates[Secondary_PipelineState_Scene].Get());
		secondaryCommandList->DrawInstanced(4, 1, 0, 0); 

		secondaryCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(mTexture.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));

		ThrowIfFailed(mCommandLists[Secondary_CommandList_Scene]->Close());
	}

	// Overlay Command List
	{
		ID3D12GraphicsCommandList* overlayCommandList = mCommandLists[Secondary_CommandList_Combine_Scene].Get();
		ComPtr<ID3D12Resource> curSecondaryRenderTarget = mDXDevices[Device_Secondary]->mRenderTargets[mCurrentFrameIndex]; // Get secondary render target for current frame
		ThrowIfFailed(overlayCommandList->Reset(mDXDevices[Device_Secondary]->mCommandAllocator.Get(), nullptr));

		overlayCommandList->RSSetViewports(1, &mViewport);
		overlayCommandList->RSSetScissorRects(1, &mScissorRect);

		ID3D12DescriptorHeap* descHeaps[] = { mDXDevices[Device_Secondary]->mCbvSrvUavHeap.Get() };
		overlayCommandList->SetDescriptorHeaps(_countof(descHeaps), descHeaps);

		overlayCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(curSecondaryRenderTarget.Get(), D3D12_RESOURCE_STATE_PRESENT, D3D12_RESOURCE_STATE_RENDER_TARGET));

		CD3DX12_CPU_DESCRIPTOR_HANDLE rtvHandle(mDXDevices[Device_Secondary]->mRtvHeap->GetCPUDescriptorHandleForHeapStart(), mCurrentFrameIndex, mDXDevices[Device_Secondary]->mRtvDescriptorSize);
		overlayCommandList->OMSetRenderTargets(1, &rtvHandle, true, nullptr);
		static const float clearColor[4] = { 0.0f, 1.0f, 0.0f, 1.0f };
		overlayCommandList->ClearRenderTargetView(rtvHandle, clearColor, 0, nullptr);
		overlayCommandList->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);

		// Render top quad with cross-adapter texture
		overlayCommandList->IASetVertexBuffers(0, 1, mVertexBufferViews[Secondary_Quad_Combine_Top]); // Quad geometry
		CD3DX12_GPU_DESCRIPTOR_HANDLE crossAdapterSrvHandle(mDXDevices[Device_Secondary]->mCbvSrvUavHeap->GetGPUDescriptorHandleForHeapStart(), mCurrentFrameIndex, mDXDevices[Device_Secondary]->mCbvSrvUavDescriptorSize);
		overlayCommandList->SetGraphicsRootSignature(mRootSignatures[Secondary_RootSignature_CrossAdapter].Get());
		overlayCommandList->SetPipelineState(mPipelineStates[Secondary_PipelineState_CrossAdapter].Get());
		overlayCommandList->SetGraphicsRootDescriptorTable(0, mTransformTopCbvHandle);
		overlayCommandList->SetGraphicsRootDescriptorTable(1, crossAdapterSrvHandle);
		// Scale and translate quad to top of screen
		mConstantBufferTransformTopData.modelViewProjection = DirectX::XMMatrixIdentity();
		mConstantBufferTransformTopData.modelViewProjection *= DirectX::XMMatrixTranslation(0.0, ((1.0f / mSharePercentage) - 1.0f) + 0.015f, 0.0);
		mConstantBufferTransformTopData.modelViewProjection *= DirectX::XMMatrixScaling(1.0, mSharePercentage, 1.0);
		UpdateConstantBuffer(mConstantBufferTransformTop, &mConstantBufferTransformTopData, sizeof(mConstantBufferTransformTopData));
		overlayCommandList->DrawInstanced(4, 1, 0, 0);  

		// Render bottom quad with texture from secondary GPU
		overlayCommandList->IASetVertexBuffers(0, 1, mVertexBufferViews[Secondary_Quad_Combine_Bottom]); // Quad geometry
		overlayCommandList->SetGraphicsRootDescriptorTable(0, mTransformBottomCbvHandle);
		overlayCommandList->SetGraphicsRootDescriptorTable(1, mTextureSrvHandle);
		// Scale and translate quad to bottom of screen
		mConstantBufferTransformBottomData.modelViewProjection = DirectX::XMMatrixIdentity();
		mConstantBufferTransformBottomData.modelViewProjection *= DirectX::XMMatrixTranslation(0.0, -((1.0f / (1.0f - mSharePercentage)) - 1.0f) - 0.015f, 0.0);
		mConstantBufferTransformBottomData.modelViewProjection *= DirectX::XMMatrixScaling(1.0, (1.0f - mSharePercentage), 1.0);
		UpdateConstantBuffer(mConstantBufferTransformBottom, &mConstantBufferTransformBottomData, sizeof(mConstantBufferTransformBottomData));
		overlayCommandList->DrawInstanced(4, 1, 0, 0); 

		overlayCommandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(curSecondaryRenderTarget.Get(), D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_PRESENT));

		ThrowIfFailed(mCommandLists[Secondary_CommandList_Combine_Scene]->Close());
	}

}
Exemplo n.º 3
0
//--------------------------------------------------------------------------
void VeRenderWindowD3D12::Record(VeUInt32 u32Index) noexcept
{
	VeRendererD3D12& kRenderer = *VeMemberCast(
		&VeRendererD3D12::m_kRenderWindowList, m_kNode.get_list());

	VE_ASSERT(u32Index < m_kRecorderList.size());
	Recorder& kRecorder = m_kRecorderList[u32Index];
	FrameCache& kFrame = m_akFrameCache[m_u32FrameIndex];
	ID3D12GraphicsCommandList* pkGCL = kFrame.m_kDirectCommandList[kRecorder.m_u32CommandIndex];
	VE_ASSERT_GE(pkGCL->Reset(kFrame.m_pkDirectAllocator, nullptr), S_OK);
	ID3D12DescriptorHeap* ppHeaps[] = { kRenderer.m_kSRVHeap.Get() };
	pkGCL->SetDescriptorHeaps(1, ppHeaps);
	for (auto& task : kRecorder.m_kTaskList)
	{
		switch (task->m_eType)
		{
		case REC_BARRIER:
		{
			auto& list = ((RecordBarrier*)task)->m_akBarrierList[m_u32FrameIndex];
			pkGCL->ResourceBarrier((VeUInt32)list.size(), &list.front());
		}
		break;
		case REC_CLEAR_RTV:
		{
			RecordClearRTV& rec = *((RecordClearRTV*)task);
			pkGCL->ClearRenderTargetView(rec.m_ahHandle[m_u32FrameIndex],
				(const FLOAT*)&(rec.m_kColor), 0, nullptr);
		}
		break;
		case REC_CLEAR_DSV:
		{
			RecordClearDSV& rec = *((RecordClearDSV*)task);
			pkGCL->ClearDepthStencilView(rec.m_ahHandle[m_u32FrameIndex],
				rec.m_eFlags, rec.m_f32Depth, rec.m_u8Stencil, 0, nullptr);
		}
		break;
		case REC_RENDER_TARGET:
		{
			RecordRenderTarget& rec = *((RecordRenderTarget*)task);
			pkGCL->OMSetRenderTargets((VeUInt32)rec.m_akRTVList[m_u32FrameIndex].size(),
				&rec.m_akRTVList[m_u32FrameIndex].front(), FALSE,
				rec.m_ahDSV[m_u32FrameIndex].ptr ? &rec.m_ahDSV[m_u32FrameIndex] : nullptr);
		}
		break;
		case REC_VIEWPORT:
		{
			RecordViewport& rec = *((RecordViewport*)task);
			pkGCL->RSSetViewports((VeUInt32)rec.m_kViewportList.size(), &rec.m_kViewportList.front());
		}
		break;
		case REC_SCISSOR_RECT:
		{
			RecordScissorRect& rec = *((RecordScissorRect*)task);
			pkGCL->RSSetScissorRects((VeUInt32)rec.m_kScissorRectList.size(), &rec.m_kScissorRectList.front());
		}
		break;
		case REC_RENDER_QUAD:
		{
			RecordRenderQuad& rec = *((RecordRenderQuad*)task);
			pkGCL->SetPipelineState(rec.m_pkPipelineState);
			pkGCL->SetGraphicsRootSignature(rec.m_pkRootSignature);
			for (auto& itTab : rec.m_kTable)
			{
				pkGCL->SetGraphicsRootDescriptorTable(itTab.first, itTab.second);
			}
			pkGCL->IASetPrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP);
			pkGCL->IASetVertexBuffers(0, 1, &kRenderer.m_kQuadVBV);
			pkGCL->DrawInstanced(4, 1, 0, 0);
		}
		break;
		default:
			break;
		}

	}
	VE_ASSERT_GE(pkGCL->Close(), S_OK);
}