//--------------------------------------------------------------------------
void VeRenderWindowD3D12::RecordScene(VeUInt32 u32Thread) noexcept
{
	for (auto& cam : m_kCameraList)
	{
		for (auto idx : cam.m_kStageList)
		{
			FrameCache& kFrame = m_akFrameCache[m_u32FrameIndex];
			ID3D12GraphicsCommandList* pkGCL = kFrame.m_kDirectCommandList[idx + u32Thread];
			VE_ASSERT_GE(pkGCL->Reset(kFrame.m_pkDirectAllocator, nullptr), S_OK);

			VE_ASSERT_GE(pkGCL->Close(), S_OK);
		}
	}
}
void* RenderAPI_D3D12::BeginModifyTexture(void* textureHandle, int textureWidth, int textureHeight, int* outRowPitch)
{
	ID3D12Fence* fence = s_D3D12->GetFrameFence();

	// Wait on the previous job (example only - simplifies resource management)
	if (fence->GetCompletedValue() < s_D3D12FenceValue)
	{
		fence->SetEventOnCompletion(s_D3D12FenceValue, s_D3D12Event);
		WaitForSingleObject(s_D3D12Event, INFINITE);
	}

	// Begin a command list
	s_D3D12CmdAlloc->Reset();
	s_D3D12CmdList->Reset(s_D3D12CmdAlloc, nullptr);

	// Fill data
	const UINT64 kDataSize = textureWidth * textureHeight * 4;
	ID3D12Resource* upload = GetUploadResource(kDataSize);
	void* mapped = NULL;
	upload->Map(0, NULL, &mapped);
	*outRowPitch = textureWidth * 4;
	return mapped;
}
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());
	}

}
Exemple #4
0
void TextureStore::loadTexture(wstring filename, string id)
{
	TextureLoadResult result;
	TextureInfo initialTexture;  // only use to initialize struct in texture store - do not access this after assignment to store
	vector<byte> file_buffer;

	initialTexture.id = id;
	textures[id] = initialTexture;
	TextureInfo *texture = &textures[id];

	// find texture file, look in pak file first:
	PakEntry *pakFileEntry = nullptr;
	pakFileEntry = xapp().findFileInPak(filename.c_str());
	// try file system if not found in pak:
	initialTexture.filename = filename; // TODO check: field not needed? only in this method? --> remove
	if (pakFileEntry == nullptr) {
		wstring binFile = xapp().findFile(filename.c_str(), XApp::TEXTURE);
		texture->filename = binFile;
		//initialTexture.filename = binFile;
		xapp().readFile(texture->filename.c_str(), file_buffer, XApp::FileCategory::TEXTURE);
	} else {
		xapp().readFile(pakFileEntry, file_buffer, XApp::FileCategory::TEXTURE);
	}


	ID3D12GraphicsCommandList *commandList = this->commandList.Get();
	//D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV
	// create heap - TODO adjust for one heap for multiple textures
	// Describe and create a shader resource view (SRV) heap for the texture.
	D3D12_DESCRIPTOR_HEAP_DESC srvHeapDesc = {};
	srvHeapDesc.NumDescriptors = 1;
	srvHeapDesc.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV;
	srvHeapDesc.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;
	ThrowIfFailed(xapp().device->CreateDescriptorHeap(&srvHeapDesc, IID_PPV_ARGS(&texture->m_srvHeap)));

	CD3DX12_CPU_DESCRIPTOR_HANDLE srvHandle(texture->m_srvHeap->GetCPUDescriptorHandleForHeapStart());
	//CD3DX12_CPU_DESCRIPTOR_HANDLE(D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV);

	CreateDDSTextureFromMemory(
		xapp().device.Get(),
		&file_buffer[0],
		file_buffer.size(),
		0,
		true,
		&texture->texSRV,
		srvHandle,
		result
	);
	//CreateDDSTextureFromFile(
	//	xapp().device.Get(),
	//	texture->filename.c_str(),
	//	0,
	//	true,
	//	&texture->texSRV,
	//	srvHandle,
	//	result
	//	);

	// upload texture to GPU:
	//ID3D12Resource* UploadBuffer;

	UINT64 uploadBufferSize = GetRequiredIntermediateSize(texture->texSRV.Get(), 0, result.NumSubresources);

	//CommandContext& InitContext = CommandContext::Begin();

	D3D12_HEAP_PROPERTIES HeapProps;
	HeapProps.Type = D3D12_HEAP_TYPE_UPLOAD;
	HeapProps.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
	HeapProps.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
	HeapProps.CreationNodeMask = 1;
	HeapProps.VisibleNodeMask = 1;

	D3D12_RESOURCE_DESC BufferDesc;
	BufferDesc.Dimension = D3D12_RESOURCE_DIMENSION_BUFFER;
	BufferDesc.Alignment = 0;
	BufferDesc.Width = uploadBufferSize;
	BufferDesc.Height = 1;
	BufferDesc.DepthOrArraySize = 1;
	BufferDesc.MipLevels = 1;
	BufferDesc.Format = DXGI_FORMAT_UNKNOWN;
	BufferDesc.SampleDesc.Count = 1;
	BufferDesc.SampleDesc.Quality = 0;
	BufferDesc.Layout = D3D12_TEXTURE_LAYOUT_ROW_MAJOR;
	BufferDesc.Flags = D3D12_RESOURCE_FLAG_NONE;

	ThrowIfFailed(xapp().device->CreateCommittedResource(&HeapProps, D3D12_HEAP_FLAG_NONE,
		&BufferDesc, D3D12_RESOURCE_STATE_GENERIC_READ,
		nullptr, IID_PPV_ARGS(&result.UploadBuffer)));

	// copy data to the intermediate upload heap and then schedule a copy from the upload heap to the default texture
	//InitContext.TransitionResource(Dest, D3D12_RESOURCE_STATE_COPY_DEST, true);
	commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(texture->texSRV.Get(), D3D12_RESOURCE_STATE_COMMON, D3D12_RESOURCE_STATE_COPY_DEST));
	UpdateSubresources(commandList, texture->texSRV.Get(), result.UploadBuffer, 0, 0, result.NumSubresources, result.initData.get());
	commandList->ResourceBarrier(1, &CD3DX12_RESOURCE_BARRIER::Transition(texture->texSRV.Get(), D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PIXEL_SHADER_RESOURCE));
	//InitContext.TransitionResource(Dest, D3D12_RESOURCE_STATE_GENERIC_READ, true);

	// Execute the command list and wait for it to finish so we can release the upload buffer
	//InitContext.CloseAndExecute(true);

	//UploadBuffer->Release();
	ThrowIfFailed(commandList->Close());
	ID3D12CommandList* ppCommandLists[] = { this->commandList.Get() };
	xapp().commandQueue->ExecuteCommandLists(_countof(ppCommandLists), ppCommandLists);

	// Create synchronization objects and wait until assets have been uploaded to the GPU.
	//Sleep(300);
	EffectBase::createSyncPoint(updateFrameData, xapp().commandQueue);
	EffectBase::waitForSyncPoint(updateFrameData);

	//auto &f = frameData[frameIndex];
	//createSyncPoint(f, xapp().commandQueue);
	//waitForSyncPoint(f);
	result.UploadBuffer->Release();
	ThrowIfFailed(commandList->Reset(commandAllocator.Get(), pipelineState.Get()));
}
//--------------------------------------------------------------------------
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);
}