Jump to content
  • Advertisement
Panokrieger

DX12 Shadow-Mapping with DirectX 12

Recommended Posts

Hi,

I have to implement depth-shadow-mapping whith DirectX 12. It would be no problem for me to implement it in DX11, but in DX12 many things are quite new and puzzeling.

Under normal conditions, I wouldn't waist your precious time, but there exist no literature or websites which makes the things clearer for me.

I only found the book of Frank Luna: "Introduction to 3D Game Programming with DirectX 12", which is very good, but doesn't go deeper into DX12.

Especially I have no idea, how to pass the information of the depth buffer of the first shadowmapping renderpass to the shadowmap-texture of the second main renderpass.

I thought, I have to create a depth buffer resource with a dsv and take the same resource to make a srv for the second main renderpass. But it doesn't seem to work, for the scene doesn't cast any shadow.  

Here I added the pieces of my code, which are relevant for my problem, to make the things easier to read, the variable name includes the complete type mame in small cases:

I would really appreciate help from an directx12 expert. Many thanks in advance!



	// Initialisation method of the depth dhadowmapping-renderpass, uxShadowMap and uyShadowMap are the resolution of the shadowmap:
	void CDirectX12Basic::InitShadowRenderpass(unsigned int uxShadowMap, unsigned int uyShadowMap) 
	{
		HRESULT hresult;

		m_viewportShadow.MinDepth = 0.0f;
		m_viewportShadow.MaxDepth = 1.0f;
		m_viewportShadow.Width = (FLOAT)uxShadowMap;
		m_viewportShadow.Height = (FLOAT)uyShadowMap;

		m_rectScissorShadow.bottom = 0;
		m_rectScissorShadow.left = 0;
		m_rectScissorShadow.right = uxShadowMap;
		m_rectScissorShadow.bottom = uyShadowMap;

		// ---------------------------------------------------
		// Creating Depth/Stencil Buffers for the Shadow-Pass:
		// --------------------------------------------------

		D3D12_DEPTH_STENCIL_DESC depthstencildesc;
		depthstencildesc.DepthEnable = true; 
		depthstencildesc.DepthWriteMask = D3D12_DEPTH_WRITE_MASK_ALL; 
		depthstencildesc.DepthFunc = D3D12_COMPARISON_FUNC_LESS;  
		depthstencildesc.StencilEnable = false; 
		depthstencildesc.StencilReadMask = D3D12_DEFAULT_STENCIL_READ_MASK;
		depthstencildesc.StencilWriteMask = D3D12_DEFAULT_STENCIL_WRITE_MASK;
		depthstencildesc.FrontFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
		depthstencildesc.FrontFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP;
		depthstencildesc.FrontFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
		depthstencildesc.FrontFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;
		depthstencildesc.BackFace.StencilFailOp = D3D12_STENCIL_OP_KEEP;
		depthstencildesc.BackFace.StencilDepthFailOp = D3D12_STENCIL_OP_KEEP; 
		depthstencildesc.BackFace.StencilPassOp = D3D12_STENCIL_OP_KEEP;
		depthstencildesc.BackFace.StencilFunc = D3D12_COMPARISON_FUNC_ALWAYS;

		D3D12_DEPTH_STENCIL_VIEW_DESC depthstencilviewdesc = {};
		depthstencilviewdesc.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; 	// From the example in the book of Frank-Luna, is the stencil-buffer really necessary? 
		depthstencilviewdesc.ViewDimension = D3D12_DSV_DIMENSION_TEXTURE2D;
		depthstencilviewdesc.Flags = D3D12_DSV_FLAG_READ_ONLY_DEPTH;
		depthstencilviewdesc.Texture2D.MipSlice = 0;

		m_clearvalueShadow.Format = DXGI_FORMAT_D24_UNORM_S8_UINT; // From the example in the book of Frank-Luna
		m_clearvalueShadow.DepthStencil.Depth = 1.0f; 
		m_clearvalueShadow.DepthStencil.Stencil = 0;
 
		D3D12_RESOURCE_DESC resourcedescDepthStencil = {};
		resourcedescDepthStencil.Format = DXGI_FORMAT_R24G8_TYPELESS; // laut Luna-Buch
		resourcedescDepthStencil.Width = (UINT64)uxShadowMap;
		resourcedescDepthStencil.Height = uyShadowMap; 
		resourcedescDepthStencil.DepthOrArraySize = 1; 
		resourcedescDepthStencil.MipLevels = 0; 
		resourcedescDepthStencil.SampleDesc.Count = 1;
		resourcedescDepthStencil.SampleDesc.Quality = 0;
		resourcedescDepthStencil.Flags = D3D12_RESOURCE_FLAG_ALLOW_DEPTH_STENCIL; 		
		resourcedescDepthStencil.Layout = D3D12_TEXTURE_LAYOUT_UNKNOWN; 
		resourcedescDepthStencil.Alignment = 0;
		resourcedescDepthStencil.Dimension = D3D12_RESOURCE_DIMENSION_TEXTURE2D;

		D3D12_HEAP_PROPERTIES heappropertiesDepthStencil = {};
		heappropertiesDepthStencil.Type = D3D12_HEAP_TYPE_DEFAULT;
		heappropertiesDepthStencil.CPUPageProperty = D3D12_CPU_PAGE_PROPERTY_UNKNOWN;
		heappropertiesDepthStencil.MemoryPoolPreference = D3D12_MEMORY_POOL_UNKNOWN;
		heappropertiesDepthStencil.CreationNodeMask = 1;
		heappropertiesDepthStencil.VisibleNodeMask = 1;

		D3D12_DESCRIPTOR_HEAP_DESC descriptorheapdescDepthStencil = {};
		descriptorheapdescDepthStencil.NumDescriptors = 1;
		descriptorheapdescDepthStencil.Type = D3D12_DESCRIPTOR_HEAP_TYPE_DSV; 
		descriptorheapdescDepthStencil.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_NONE;
		
		hresult = m_pdevice->CreateDescriptorHeap(&descriptorheapdescDepthStencil, IID_PPV_ARGS(&m_pdescriptorheapDepthStencilShadow));
		CHECK_N_DRECK(hresult, "CreateDescriptorHeap for Shadow-Depth-Stencil");

		D3D12_DESCRIPTOR_HEAP_DESC descriptorheapdescDepthStencil2Pass = {};
		descriptorheapdescDepthStencil2Pass.NumDescriptors = 1;
		descriptorheapdescDepthStencil2Pass.Type = D3D12_DESCRIPTOR_HEAP_TYPE_CBV_SRV_UAV; 
		descriptorheapdescDepthStencil2Pass.Flags = D3D12_DESCRIPTOR_HEAP_FLAG_SHADER_VISIBLE;

		hresult = m_pdevice->CreateDescriptorHeap(&descriptorheapdescDepthStencil2Pass, IID_PPV_ARGS(&m_pdescriptorheapDepthStencilShadow2Pass));
		CHECK_N_DRECK(hresult, "CreateDescriptorHeap second Pass for Shadow-Depth-Stencil");


		hresult = m_pdevice->CreateCommittedResource(
			&heappropertiesDepthStencil,
			D3D12_HEAP_FLAG_NONE,
			&resourcedescDepthStencil,
			D3D12_RESOURCE_STATE_GENERIC_READ,
			&m_clearvalueShadow,
			IID_PPV_ARGS(&m_pressourceDepthStencilShadow)
		);
		CHECK_N_DRECK(hresult, "CreateCommittedResource for Shadow-Depth-Stencil-Buffer");

		m_cpudescriptorhandleShadowDSV = m_pdescriptorheapDepthStencilShadow->GetCPUDescriptorHandleForHeapStart();

		m_pdevice->CreateDepthStencilView(m_pressourceDepthStencilShadow, &depthstencilviewdesc, m_cpudescriptorhandleShadowDSV);


		D3D12_INPUT_ELEMENT_DESC ainputelementdesc[] =
		{
			{ "POSITION", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 0, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
			{ "NORMAL", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 16, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
			{ "TANGENT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 32, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
			{ "BITANGENT", 0, DXGI_FORMAT_R32G32B32A32_FLOAT, 0, 48, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 },
			{ "TEXCOORD", 0, DXGI_FORMAT_R32G32_FLOAT, 0, 64, D3D12_INPUT_CLASSIFICATION_PER_VERTEX_DATA, 0 }
		};

		D3D12_INPUT_LAYOUT_DESC inputlayoutdesc;
		inputlayoutdesc.pInputElementDescs = ainputelementdesc;
		inputlayoutdesc.NumElements = 5; // Pos + Normal + Tangent + Bitangent + Texcood = 5 Params !!! (getestet!) 

#ifdef _DEBUG
		UINT uCompilerflags = D3DCOMPILE_DEBUG | D3DCOMPILE_OPTIMIZATION_LEVEL3;
#else
		UINT uCompilerflags = D3DCOMPILE_FLAGS2_FORCE_ROOT_SIGNATURE_LATEST | D3DCOMPILE_PARTIAL_PRECISION | D3DCOMPILE_SKIP_VALIDATION | D3DCOMPILE_OPTIMIZATION_LEVEL3;
#endif

		ID3DBlob * pblobVertexShader;
		hresult = D3DCompileFromFile(L"shaders\\Source\\DirectX12_ShadowVertexshader.hlsl", 0, 0, "main", "vs_5_1", uCompilerflags, 0, &pblobVertexShader, 0);
		CHECK_N_DRECK(hresult, "D3DCompileFromFile (ShadowMap Vertex Shader)");

		ID3DBlob * pblobPixelShader;
		hresult = D3DCompileFromFile(L"shaders\\Source\\DirectX12_ShadowPixelshader.hlsl", 0, 0, "main", "ps_5_1", uCompilerflags, 0, &pblobPixelShader, 0);
		CHECK_N_DRECK(hresult, "D3DCompileFromFile (ShadowMap Pixel Shader)");

		// ---------------------------------------------
		// Creating Constant Buffers of the Shadow-Pass:
		// ---------------------------------------------

		ZeroMemory(&m_arootparameterShadow, sizeof(D3D12_ROOT_PARAMETER) * NR_OF_ROOT_PARAMETERS);

		unsigned int uRootParameter = 0;
		unsigned int uRegisterConstant = 4; 

		m_uRootParameterWorldViewProjShadow = uRootParameter;
		m_uRegisterWorldViewProjShadow = uRegisterConstant;

		m_bufferconstantWorldViewProjShadow.InitPSO(m_pdevice, sizeof(SBufferCpuWorldViewProjShadow),
			m_arootparameterShadow, D3D12_SHADER_VISIBILITY_VERTEX, uRootParameter++, uRegisterConstant++); 

		//---------------------------------------------
		// creating Root Signature for the Shadow-Pass:
		//---------------------------------------------

		D3D12_ROOT_SIGNATURE_DESC rootsignaturedesc;
		ZeroMemory(&rootsignaturedesc, sizeof(rootsignaturedesc));
		rootsignaturedesc.NumParameters = uRootParameter; // Aazahl der Ruudparameda
		rootsignaturedesc.pParameters = &m_arootparameterShadow[0];
		rootsignaturedesc.Flags =
			D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT |
			D3D12_ROOT_SIGNATURE_FLAG_DENY_DOMAIN_SHADER_ROOT_ACCESS |  
			D3D12_ROOT_SIGNATURE_FLAG_DENY_HULL_SHADER_ROOT_ACCESS |
			D3D12_ROOT_SIGNATURE_FLAG_DENY_GEOMETRY_SHADER_ROOT_ACCESS;
			D3D12_ROOT_SIGNATURE_FLAG_DENY_PIXEL_SHADER_ROOT_ACCESS;

		ID3DBlob * pblobRootSignature = NULL;
		ID3DBlob * pblobRootSignatureError = NULL; 		
		hresult = D3D12SerializeRootSignature(&rootsignaturedesc, D3D_ROOT_SIGNATURE_VERSION_1, &pblobRootSignature, &pblobRootSignatureError);
		CHECK_N_DRECK(hresult, "D3D12SerializeRootSignature for Shadow Map");

		hresult = m_pdevice->CreateRootSignature(0, pblobRootSignature->GetBufferPointer(), pblobRootSignature->GetBufferSize(), IID_PPV_ARGS(&m_prootsignatureShadow));
		CHECK_N_DRECK(hresult, "CreateRootSignature for Shadow Map");

		//--------------------------------------------
		// Creating PipelineStateDesc for Shadow-Pass:
		//--------------------------------------------

		D3D12_GRAPHICS_PIPELINE_STATE_DESC pipelinestatedesc = { 0 };
		pipelinestatedesc.VS.pShaderBytecode = pblobVertexShader->GetBufferPointer();
		pipelinestatedesc.VS.BytecodeLength = pblobVertexShader->GetBufferSize();
		pipelinestatedesc.PS.pShaderBytecode = pblobPixelShader->GetBufferPointer();
		pipelinestatedesc.PS.BytecodeLength = pblobPixelShader->GetBufferSize();
		pipelinestatedesc.pRootSignature = m_prootsignatureShadow;
		pipelinestatedesc.BlendState.AlphaToCoverageEnable = FALSE;
		pipelinestatedesc.BlendState.IndependentBlendEnable = FALSE;
		for (int i = 0; i < 8; i++)
		{
			pipelinestatedesc.BlendState.RenderTarget[i].BlendEnable = TRUE;
			pipelinestatedesc.BlendState.RenderTarget[i].LogicOpEnable = FALSE;
			pipelinestatedesc.BlendState.RenderTarget[i].SrcBlend = D3D12_BLEND_SRC_ALPHA;
			pipelinestatedesc.BlendState.RenderTarget[i].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
			pipelinestatedesc.BlendState.RenderTarget[i].BlendOp = D3D12_BLEND_OP_ADD;
			pipelinestatedesc.BlendState.RenderTarget[i].SrcBlendAlpha = D3D12_BLEND_ONE;
			pipelinestatedesc.BlendState.RenderTarget[i].DestBlendAlpha = D3D12_BLEND_ZERO;
			pipelinestatedesc.BlendState.RenderTarget[i].BlendOpAlpha = D3D12_BLEND_OP_ADD;
			pipelinestatedesc.BlendState.RenderTarget[i].LogicOp = D3D12_LOGIC_OP_NOOP;
			pipelinestatedesc.BlendState.RenderTarget[i].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
		}
		pipelinestatedesc.RasterizerState.FillMode = D3D12_FILL_MODE_SOLID;
		pipelinestatedesc.RasterizerState.CullMode = D3D12_CULL_MODE_BACK;
		pipelinestatedesc.RasterizerState.FrontCounterClockwise = TRUE;
		pipelinestatedesc.RasterizerState.DepthClipEnable = TRUE; 
		pipelinestatedesc.RasterizerState.DepthBias = 0; // In the Frank Luna-example 10000, but make this realy sense?
		pipelinestatedesc.RasterizerState.DepthBiasClamp = 0.0f; // example of Frank Luna
		pipelinestatedesc.RasterizerState.SlopeScaledDepthBias = 1.0f; // example of Frank Luna
		pipelinestatedesc.RasterizerState.MultisampleEnable = FALSE;
		pipelinestatedesc.RasterizerState.AntialiasedLineEnable = FALSE;
		pipelinestatedesc.RasterizerState.ForcedSampleCount = 0;
		pipelinestatedesc.RasterizerState.ConservativeRaster = D3D12_CONSERVATIVE_RASTERIZATION_MODE_OFF;

		pipelinestatedesc.SampleMask = UINT_MAX;
		pipelinestatedesc.PrimitiveTopologyType = D3D12_PRIMITIVE_TOPOLOGY_TYPE_TRIANGLE;
		// A Shadow Pass has no RenderTargets!: 
		pipelinestatedesc.NumRenderTargets = 0; 
		pipelinestatedesc.RTVFormats[0] = DXGI_FORMAT_UNKNOWN; /
		pipelinestatedesc.DSVFormat = resourcedescDepthStencil.Format;
		pipelinestatedesc.SampleDesc.Count = 1;
		pipelinestatedesc.DepthStencilState = depthstencildesc;
		// Hier gehen die Infos für den Input Assembler rein:
		pipelinestatedesc.InputLayout = inputlayoutdesc;

		hresult = m_pdevice->CreateGraphicsPipelineState(&pipelinestatedesc, IID_PPV_ARGS(&m_ppipelinestateShadow));
		CHECK_N_DRECK(hresult, "CreateGraphicsPipelineState for ShadowMap");

		// -----------------------------------------
		// Configuriering of Schadow-Render Targets:
		// -----------------------------------------

		// Die Größe eines Descriptiors variiert von Grafikkarte zu Grafikkarte und Hersteller zu Hersteller (Intel, NVIDEA, AMD), 
		// Daher muss sie abgefragt werden. RTV steht für Render Target View:
		for (int iFrame = 0; iFrame < FRAMES; iFrame++)
		{
			m_abufferrendertargetShadow[iFrame].InitShadow(m_pdevice, m_pressourceDepthStencilShadow, m_commandqueuedesc.Type, m_cpudescriptorhandleShadowDSV, m_ppipelinestateShadow);
		}

		// ------------------------------------------------------------
		// Creating the Shadow-Map-View for the second main Renderpass: 
		// ------------------------------------------------------------

		D3D12_SHADER_RESOURCE_VIEW_DESC shaderresourceviewdesc = {};
		ZeroMemory(&shaderresourceviewdesc, sizeof(shaderresourceviewdesc));
		shaderresourceviewdesc.Shader4ComponentMapping = D3D12_DEFAULT_SHADER_4_COMPONENT_MAPPING;
		shaderresourceviewdesc.Format = DXGI_FORMAT_R24_UNORM_X8_TYPELESS;
		shaderresourceviewdesc.ViewDimension = D3D12_SRV_DIMENSION_TEXTURE2D;
		shaderresourceviewdesc.Texture2D.MipLevels = 1;
		shaderresourceviewdesc.Texture2D.MostDetailedMip = 0;
		shaderresourceviewdesc.Texture2D.ResourceMinLODClamp = 0.0f;
		shaderresourceviewdesc.Texture2D.PlaneSlice = 0;

		m_cpudescriptorhandleShadowSRV = m_pdescriptorheapDepthStencilShadow2Pass->GetCPUDescriptorHandleForHeapStart();
		m_pdevice->CreateShaderResourceView(m_pressourceDepthStencilShadow, &shaderresourceviewdesc, m_cpudescriptorhandleShadowSRV);

		m_aheapShadowMap[0] = m_pdescriptorheapDepthStencilShadow2Pass;
		m_gpudescriptorhandleShadow = m_pdescriptorheapDepthStencilShadow2Pass->GetGPUDescriptorHandleForHeapStart();

	}

 ...

	// Main render method, the parameters are for the model-view-projection of the second renderpass:
	void CDirectX12Basic::RenderViewport(CHMat & mProjection, CHMat & mView, CHVector & vCamPos, CViewport &viewport)
	{
		WaitForPreviousFrame();
		UINT uFrame = m_pswapchain->GetCurrentBackBufferIndex();

		// ------------------------
		// First shadow-renderpass:
		// ------------------------

		m_abufferrendertargetShadow[uFrame].Open(m_apcommandlistShadow[uFrame]); 
		
		m_apcommandlistShadow[uFrame]->RSSetViewports(1, &m_viewportShadow);		
		m_apcommandlistShadow[uFrame]->RSSetScissorRects(1, &m_rectScissorShadow);
		m_apcommandlistShadow[uFrame]->SetGraphicsRootSignature(m_prootsignatureShadow);
		m_apcommandlistShadow[uFrame]->SetPipelineState(m_ppipelinestateShadow);

		// ...
		// Here: Drawing the relvant geometry for shadow casting 
		// ...

		m_abufferrendertargetShadow[uFrame].Close(m_apcommandlistShadow[uFrame]);

		ID3D12CommandList * pcommandlistsShadow[] = { m_abufferrendertargetShadow[uFrame].m_pcommandlist }; 

		m_pcommandqueue->ExecuteCommandLists(1, pcommandlistsShadow); // Param1: Anzahl der CommandLists

		// -----------------------
		// Second main renderpass:
		// -----------------------

		m_abufferrendertarget[uFrame].Open(m_apcommandlist[uFrame]); 

		m_apcommandlist[uFrame]->RSSetViewports(1, &m_viewport);
		m_apcommandlist[uFrame]->RSSetScissorRects(1, &m_rectScissor);

		m_apcommandlist[uFrame]->SetGraphicsRootSignature(m_prootsignature);

		m_apcommandlist[uFrame]->SetPipelineState(m_ppipelinestate);
		m_buffersampler.Draw(m_apcommandlist[uFrame]);
		
		// -------------------------------------------------------------------------------------------------------
		// The Binding of the depth-Buffer of the first Renderpass to the shadowe-msap-texture of the second pass:  
		// I suppose, that I'm doing here sdomething wrong: 
		// -------------------------------------------------------------------------------------------------------

		m_apcommandlist[uFrame]->SetDescriptorHeaps(1, m_aheapShadowMap);
		m_apcommandlist[uFrame]->SetGraphicsRootDescriptorTable(m_uRootParameterShadowMap, m_gpudescriptorhandleShadow);

		m_lights.FillBufferCpuLight(m_abuffercpulight);
		m_buffersrtructuredLights.Tick(m_apcommandlist[uFrame], m_abuffercpulight);

		CHMat mProj;
		mProj = mProjection;
		mProj.Transpose();

		CHMat mViewProj = mProj* mView; // I'm doing a precompiling of the View-Projection to speed up, it's not done in the vertex shader, is this a good idea? 

		// The Method DrawGeos passes the relvant geometry to the main vertex shader, it works fine: 
		DrawGeos(m_apcommandlist[uFrame], mViewProj, vCamPos);

		m_abufferrendertarget[uFrame].Close(m_apcommandlist[uFrame]);

		ID3D12CommandList * pcommandlists[] = { m_abufferrendertarget[uFrame].m_pcommandlist }; 

		m_pcommandqueue->ExecuteCommandLists(1, pcommandlists); 
	}

 

Share this post


Link to post
Share on other sites
Advertisement

Do you have a ResourceBarrier call to transition your depth buffer from depth usage to SRV usage? I don't see one in the code you posted.

Share this post


Link to post
Share on other sites

Hi Soldier of Light!

Thank you for Your quick reply!  

Yes I do have installed ressource barriers, but they are hidden in the methods "Init" "Open" and "Close" of the class "CBufferRenderTarget", I call the method "Open" at the very beginning of a renderpass, and the method "Close" at the end of it (see code before). For the instance of the shadow render pass I switched the boolean flag "bShadowRenderPass" to "true".  Here is the cpp-Code of the 3 methods:

void CDirectX12BufferRenderTarget::Init(..., bool bShadowRenderPass)
{

	m_bShadowRenderPass = bShadowRenderPass;
	//...
	if(bShadowRenderPass)
	{
		m_resourcebarrierOpen.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
		m_resourcebarrierOpen.Transition.pResource = presource;
		m_resourcebarrierOpen.Transition.StateBefore = D3D12_RESOURCE_STATE_GENERIC_READ;
		m_resourcebarrierOpen.Transition.StateAfter = D3D12_RESOURCE_STATE_DEPTH_WRITE;
		m_resourcebarrierOpen.Transition.Subresource = 0;

		m_resourcebarrierClose.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
		m_resourcebarrierClose.Transition.pResource = presource;
		m_resourcebarrierClose.Transition.StateBefore = D3D12_RESOURCE_STATE_DEPTH_WRITE;
		m_resourcebarrierClose.Transition.StateAfter = D3D12_RESOURCE_STATE_GENERIC_READ;
		m_resourcebarrierClose.Transition.Subresource = 0;

		m_pdevice->CreateRenderTargetView(presource, 0, m_cpudescriptorhandle);
		// ...
	}
	else
	{
		m_resourcebarrierOpen.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
		m_resourcebarrierOpen.Transition.pResource = presource;
		m_resourcebarrierOpen.Transition.StateBefore = D3D12_RESOURCE_STATE_PRESENT;
		m_resourcebarrierOpen.Transition.StateAfter = D3D12_RESOURCE_STATE_RENDER_TARGET;
		m_resourcebarrierOpen.Transition.Subresource = 0;

		m_resourcebarrierClose.Type = D3D12_RESOURCE_BARRIER_TYPE_TRANSITION;
		m_resourcebarrierClose.Transition.pResource = presource;
		m_resourcebarrierClose.Transition.StateBefore = D3D12_RESOURCE_STATE_RENDER_TARGET;
		m_resourcebarrierClose.Transition.StateAfter = D3D12_RESOURCE_STATE_PRESENT;
		m_resourcebarrierClose.Transition.Subresource = 0;
		// ...
	}

}


void CDirectX12BufferRenderTarget::Open(ID3D12GraphicsCommandList* & pcommandlist)
{
	HRESULT hresult;

	pcommandlist = m_pcommandlist;

	hresult = pcommandlist->Reset(m_pcommandallocator, m_ppipelinestate);
	CHECK_N_DRECK(hresult, "Reset for Render Target Bufffer");

  	// Here it is ...: 
	pcommandlist->ResourceBarrier(1, &m_resourcebarrierOpen);

	if (m_bShadowRenderPass)
	{
		// Set	a null render target because we	are only going to draw to the depth buffer:		
		pcommandlist->OMSetRenderTargets(0, nullptr, false, &m_cpudescriptorhandleDepthStencil);
		pcommandlist->ClearDepthStencilView(m_cpudescriptorhandleDepthStencil, D3D12_CLEAR_FLAG_DEPTH | D3D12_CLEAR_FLAG_STENCIL, 1.0f, 0, 0, nullptr);
	}
	else
	{

		pcommandlist->OMSetRenderTargets(1, &m_cpudescriptorhandle, false, &m_cpudescriptorhandleDepthStencil); 
		pcommandlist->ClearRenderTargetView(m_cpudescriptorhandle, m_afClearColor, 0, 0);
		pcommandlist->ClearDepthStencilView(m_cpudescriptorhandleDepthStencil,D3D12_CLEAR_FLAG_DEPTH, 1.0f, 0, 0, nullptr);
	}


void CDirectX12BufferRenderTarget::Close(ID3D12GraphicsCommandList* & pcommandlist)
{
  	// ... and here: 
	pcommandlist->ResourceBarrier(1, &m_resourcebarrierClose);
	pcommandlist->Close();

}

 

Share this post


Link to post
Share on other sites

Looks like you want to pass information between render passes. Why not have a RootConstant that you write to in one render pass and read in another render pass. I am still learning but this is how would have tried, if I had the problem you are facing.

Share this post


Link to post
Share on other sites

Hi RitzMax72!

Thank you very much for Your suggestion! You are right, under normal conditions your attempt would work fine, but I think, in this case it's a little bit more tricky, because the information I want to pass between the renderpasses resides only in the depth buffer of the first renderpass and have to be passed to a Texture2D of the second renderpass.   

As far as I know, you can only write to RootConstants by calculating something in a shader. But in my case the pixelshader is empty, for no shading is necessary.

Share this post


Link to post
Share on other sites

Hi Panokrieger, You logic to use SRV for sampling in second pass seems correct to me. As SolierOfLight pointed out about D3D12_RESOURCE_BARRIER::TRANSITION is important here. You design may be correct and still if you not reading correct values from SRV, you probably would have missed a step in copying values from one resource to another. You can try using ID3D12Resource::Map function and reinterpret casting the returned pointer and try to interpret the depth values that you expect to be in depth stencil buffer, again after copying to SRV resource, Map that resource too to verify same depth values are present or not.  All of these in debugger. Hope this helps. Good work!

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!