void GraphicsContext::SetRenderTargets( UINT NumRTVs, ITextureViewD3D12** ppRTVs, ITextureViewD3D12* pDSV )
{
    D3D12_CPU_DESCRIPTOR_HANDLE RTVHandles[8]; // Do not waste time initializing array to zero

	for (UINT i = 0; i < NumRTVs; ++i)
	{
        auto *pRTV = ppRTVs[i];
        if( pRTV )
        {
            auto *pTexture = ValidatedCast<TextureD3D12Impl>( pRTV->GetTexture() );
	        TransitionResource(pTexture, D3D12_RESOURCE_STATE_RENDER_TARGET);
		    RTVHandles[i] = pRTV->GetCPUDescriptorHandle();
        }
	}

	if (pDSV)
	{
        auto *pTexture = ValidatedCast<TextureD3D12Impl>( pDSV->GetTexture() );
		//if (bReadOnlyDepth)
		//{
		//	TransitionResource(*pTexture, D3D12_RESOURCE_STATE_DEPTH_READ);
		//	m_pCommandList->OMSetRenderTargets( NumRTVs, RTVHandles, FALSE, &DSV->GetDSV_DepthReadOnly() );
		//}
		//else
		{
			TransitionResource(pTexture, D3D12_RESOURCE_STATE_DEPTH_WRITE);
            auto DSVHandle = pDSV->GetCPUDescriptorHandle();
			m_pCommandList->OMSetRenderTargets( NumRTVs, RTVHandles, FALSE, &DSVHandle );
		}
	}
	else
	{
		m_pCommandList->OMSetRenderTargets( NumRTVs, RTVHandles, FALSE, nullptr );
	}
}
void CommandContext::BeginResourceTransition(GpuResource& Resource, D3D12_RESOURCE_STATES NewState, bool FlushImmediate)
{
	// If it's already transitioning, finish that transition
	if (Resource.m_TransitioningState != (D3D12_RESOURCE_STATES)-1)
		TransitionResource(Resource, Resource.m_TransitioningState);

	D3D12_RESOURCE_STATES OldState = Resource.m_UsageState;

	if (OldState != NewState)
	{
		ASSERT(m_NumBarriersToFlush < 16, "Exceeded arbitrary limit on buffered barriers");
		D3D12_RESOURCE_BARRIER& BarrierDesc = m_ResourceBarrierBuffer[m_NumBarriersToFlush++];

		BarrierDesc.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
		BarrierDesc.Transition.pResource = Resource.GetResource();
		BarrierDesc.Transition.Subresource = D3D12_RESOURCE_BARRIER_ALL_SUBRESOURCES;
		BarrierDesc.Transition.StateBefore = OldState;
		BarrierDesc.Transition.StateAfter = NewState;

		BarrierDesc.Flags = D3D12_RESOURCE_BARRIER_FLAG_BEGIN_ONLY;

		Resource.m_TransitioningState = NewState;
	}

	if (FlushImmediate || m_NumBarriersToFlush == 16)
	{
		m_pCommandList->ResourceBarrier(m_NumBarriersToFlush, m_ResourceBarrierBuffer);
		m_NumBarriersToFlush = 0;
	}
}
void CommandContext::ClearUAVFloat( ITextureViewD3D12 *pTexView, const float* Color )
{
    auto *pTexture = ValidatedCast<TextureD3D12Impl>( pTexView->GetTexture() );
	TransitionResource(pTexture, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, true);

	// After binding a UAV, we can get a GPU handle that is required to clear it as a UAV (because it essentially runs
	// a shader to set all of the values).
    UNSUPPORTED("Not yet implemented");
    D3D12_GPU_DESCRIPTOR_HANDLE GpuVisibleHandle = {};//m_DynamicDescriptorHeap.UploadDirect(Target.GetUAV());
	m_pCommandList->ClearUnorderedAccessViewFloat(GpuVisibleHandle, pTexView->GetCPUDescriptorHandle(), pTexture->GetD3D12Resource(), Color, 0, nullptr);
}
Ejemplo n.º 4
0
//---------------------------------------------------------------------------//
  void RenderContextDX12::ApplyRenderTargets()
  {
    if (!myRenderTargetsDirty)
      return;

    myRenderTargetsDirty = false;

    D3D12_CPU_DESCRIPTOR_HANDLE rtDescriptors[Rendering::Constants::kMaxNumRenderTargets];
    GpuResource* rtResources[Rendering::Constants::kMaxNumRenderTargets];
    uint32 numRtsToSet = 0u;

    for (uint32 i = 0u; i < Rendering::Constants::kMaxNumRenderTargets; ++i)
    {
      Texture* rt = myRenderTargets[i];

      if (rt != nullptr)
      {
        rtResources[numRtsToSet] = rt;
        rtDescriptors[numRtsToSet] = rt->GetRtv().myCpuHandle;
        ++numRtsToSet;
      }
    }

    for (uint32 i = 0u; i < numRtsToSet; ++i)
    {
      TransitionResource(rtResources[i], D3D12_RESOURCE_STATE_RENDER_TARGET);
    }

    if (myDepthStencilTarget)
      TransitionResource(myDepthStencilTarget, D3D12_RESOURCE_STATE_DEPTH_WRITE);

    KickoffResourceBarriers();

    if (myDepthStencilTarget) 
      myCommandList->OMSetRenderTargets(numRtsToSet, rtDescriptors, false, &myDepthStencilTarget->GetDsv().myCpuHandle); 
    else 
      myCommandList->OMSetRenderTargets(numRtsToSet, rtDescriptors, false, nullptr);
  }
void CommandContext::CopySubresource(GpuResource& Dest, UINT DestSubIndex, GpuResource& Src, UINT SrcSubIndex)
{
	// TODO:  Add a TransitionSubresource()?
	TransitionResource(Dest, D3D12_RESOURCE_STATE_COPY_DEST);
	TransitionResource(Src, D3D12_RESOURCE_STATE_COPY_SOURCE);
	FlushResourceBarriers();

	D3D12_TEXTURE_COPY_LOCATION DestLocation =
	{
		Dest.GetResource(),
		D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
		DestSubIndex
	};

	D3D12_TEXTURE_COPY_LOCATION SrcLocation =
	{
		Src.GetResource(),
		D3D12_TEXTURE_COPY_TYPE_SUBRESOURCE_INDEX,
		SrcSubIndex
	};

	m_pCommandList->CopyTextureRegion(&DestLocation, 0, 0, 0, &SrcLocation, nullptr);
}
void CommandContext::ClearUAVUint( ITextureViewD3D12 *pTexView, const UINT *Color  )
{
    auto *pTexture = ValidatedCast<TextureD3D12Impl>( pTexView->GetTexture() );
	TransitionResource(pTexture, D3D12_RESOURCE_STATE_UNORDERED_ACCESS, true);

	// After binding a UAV, we can get a GPU handle that is required to clear it as a UAV (because it essentially runs
	// a shader to set all of the values).
    UNSUPPORTED("Not yet implemented");
    D3D12_GPU_DESCRIPTOR_HANDLE GpuVisibleHandle = {};//m_DynamicDescriptorHeap.UploadDirect(Target.GetUAV());
	//CD3DX12_RECT ClearRect(0, 0, (LONG)Target.GetWidth(), (LONG)Target.GetHeight());

	//TODO: My Nvidia card is not clearing UAVs with either Float or Uint variants.
	m_pCommandList->ClearUnorderedAccessViewUint(GpuVisibleHandle, pTexView->GetCPUDescriptorHandle(), pTexture->GetD3D12Resource(), Color, 0, nullptr/*1, &ClearRect*/);
}
void CommandContext::TransitionResource(IBufferD3D12 *pBuffer, D3D12_RESOURCE_STATES NewState, bool FlushImmediate)
{
    VERIFY_EXPR( pBuffer != nullptr );
    auto *pBuffD3D12 = ValidatedCast<BufferD3D12Impl>(pBuffer);

#ifdef _DEBUG
    // Dynamic buffers are suballocated in the upload heap when Map() is called 
    // and must always be in D3D12_RESOURCE_STATE_GENERIC_READ state
    if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC)
    {
        VERIFY(pBuffD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to always be in D3D12_RESOURCE_STATE_GENERIC_READ state")
        VERIFY( (NewState & D3D12_RESOURCE_STATE_GENERIC_READ) == NewState, "Dynamic buffers can only transition to one of D3D12_RESOURCE_STATE_GENERIC_READ states")
    }
#endif

    TransitionResource(*pBuffD3D12, *pBuffD3D12, NewState, FlushImmediate);

#ifdef _DEBUG
    if(pBuffD3D12->GetDesc().Usage == USAGE_DYNAMIC)
        VERIFY(pBuffD3D12->GetState() == D3D12_RESOURCE_STATE_GENERIC_READ, "Dynamic buffers are expected to never transition from D3D12_RESOURCE_STATE_GENERIC_READ state")
#endif
}
void CommandContext::TransitionResource(ITextureD3D12 *pTexture, D3D12_RESOURCE_STATES NewState, bool FlushImmediate)
{
    VERIFY_EXPR( pTexture != nullptr );
    auto *pTexD3D12 = ValidatedCast<TextureD3D12Impl>(pTexture);
    TransitionResource(*pTexD3D12, *pTexD3D12, NewState, FlushImmediate);
}
void GraphicsContext::ClearDepthStencil( ITextureViewD3D12 *pDSV, D3D12_CLEAR_FLAGS ClearFlags, float Depth, UINT8 Stencil )
{
    auto *pTexture = ValidatedCast<TextureD3D12Impl>( pDSV->GetTexture() );
	TransitionResource( pTexture, D3D12_RESOURCE_STATE_DEPTH_WRITE, true);
	m_pCommandList->ClearDepthStencilView(pDSV->GetCPUDescriptorHandle(), ClearFlags, Depth, Stencil, 0, nullptr);
}
void GraphicsContext::ClearRenderTarget( ITextureViewD3D12 *pRTV, const float *Color )
{
    auto *pTexture = ValidatedCast<TextureD3D12Impl>( pRTV->GetTexture() );
	TransitionResource(pTexture, D3D12_RESOURCE_STATE_RENDER_TARGET, true);
	m_pCommandList->ClearRenderTargetView(pRTV->GetCPUDescriptorHandle(), Color, 0, nullptr);
}