DispatchRays not working.

Hey,

I’m trying to figure out how to debug an issue I’m having implementing DXR into my project. Here is the code for reference(it’s basically just a copy and paste from the Microsoft DXR example project). The issue is simple: I’m getting all black in the render target. It’s my understanding that the miss shader should be called, even if the rays don’t hit any geometry. In that case I should be getting a blue color buffer. Any ideas on what I might be doing wrong, or ways I can debug this issue?

void DXR_DoRaytracing(int width, int height, DXRMesh &mesh, D3DBuffer &m_indexBuffer, SceneConstantBuffer &m_sceneCB)
{
	auto commandList = m_deviceResources->GetCommandList();
	auto frameIndex = m_deviceResources->GetCurrentFrameIndex();

	auto DispatchRays = [&](auto* commandList, auto* stateObject, auto* dispatchDesc)
	{
		// Since each shader table has only one shader record, the stride is same as the size.
		dispatchDesc->HitGroupTable.StartAddress = d3d12CoreState->m_hitGroupShaderTable->GetGPUVirtualAddress();
		dispatchDesc->HitGroupTable.SizeInBytes = d3d12CoreState->m_hitGroupShaderTable->GetDesc().Width;
		dispatchDesc->HitGroupTable.StrideInBytes = dispatchDesc->HitGroupTable.SizeInBytes;
		dispatchDesc->MissShaderTable.StartAddress = d3d12CoreState->m_missShaderTable->GetGPUVirtualAddress();
		dispatchDesc->MissShaderTable.SizeInBytes = d3d12CoreState->m_missShaderTable->GetDesc().Width;
		dispatchDesc->MissShaderTable.StrideInBytes = dispatchDesc->MissShaderTable.SizeInBytes;
		dispatchDesc->RayGenerationShaderRecord.StartAddress = d3d12CoreState->m_rayGenShaderTable->GetGPUVirtualAddress();
		dispatchDesc->RayGenerationShaderRecord.SizeInBytes = d3d12CoreState->m_rayGenShaderTable->GetDesc().Width;
		dispatchDesc->Width = width;
		dispatchDesc->Height = height;
		commandList->DispatchRays(stateObject, dispatchDesc);
	};

	auto SetCommonPipelineState = [&](auto* descriptorSetCommandList)
	{
		descriptorSetCommandList->SetDescriptorHeaps(1, d3d12CoreState->m_descriptorHeap.GetAddressOf());
		// Set index and successive vertex buffer decriptor tables
		commandList->SetComputeRootDescriptorTable(GlobalRootSignatureParams::VertexBuffersSlot, m_indexBuffer.gpuDescriptorHandle);
		commandList->SetComputeRootDescriptorTable(GlobalRootSignatureParams::OutputViewSlot, d3d12CoreState->m_raytracingOutputResourceUAVGpuDescriptor);
	};

	commandList->SetComputeRootSignature(d3d12CoreState->m_raytracingGlobalRootSignature.Get());

	// Copy the updated scene constant buffer to GPU.
	memcpy(&d3d12CoreState->m_mappedConstantData[frameIndex].constants, &m_sceneCB, sizeof(m_sceneCB));
	auto cbGpuAddress = d3d12CoreState->m_perFrameConstants->GetGPUVirtualAddress() + frameIndex * sizeof(d3d12CoreState->m_mappedConstantData[0]);
	commandList->SetComputeRootConstantBufferView(GlobalRootSignatureParams::SceneConstantSlot, cbGpuAddress);

	{
		D3D12_DISPATCH_RAYS_DESC dispatchDesc = {};
		SetCommonPipelineState(commandList);
		commandList->SetComputeRootShaderResourceView(GlobalRootSignatureParams::AccelerationStructureSlot, mesh.m_topLevelAccelerationStructure->GetGPUVirtualAddress());
		DispatchRays(d3d12CoreState->m_dxrCommandList.Get(), d3d12CoreState->m_dxrStateObject.Get(), &dispatchDesc);
	}

	{
		auto commandList = m_deviceResources->GetCommandList();
		auto renderTarget = m_deviceResources->GetRenderTarget();

		D3D12_RESOURCE_BARRIER preCopyBarriers[2];
		preCopyBarriers[0] = CD3DX12_RESOURCE_BARRIER::Transition(renderTarget, D3D12_RESOURCE_STATE_RENDER_TARGET, D3D12_RESOURCE_STATE_COPY_DEST);
		preCopyBarriers[1] = CD3DX12_RESOURCE_BARRIER::Transition(d3d12CoreState->m_raytracingOutput.Get(), D3D12_RESOURCE_STATE_UNORDERED_ACCESS, D3D12_RESOURCE_STATE_COPY_SOURCE);
		commandList->ResourceBarrier(ARRAYSIZE(preCopyBarriers), preCopyBarriers);

		commandList->CopyResource(renderTarget, d3d12CoreState->m_raytracingOutput.Get());

		D3D12_RESOURCE_BARRIER postCopyBarriers[2];
		postCopyBarriers[0] = CD3DX12_RESOURCE_BARRIER::Transition(renderTarget, D3D12_RESOURCE_STATE_COPY_DEST, D3D12_RESOURCE_STATE_PRESENT);
		postCopyBarriers[1] = CD3DX12_RESOURCE_BARRIER::Transition(d3d12CoreState->m_raytracingOutput.Get(), D3D12_RESOURCE_STATE_COPY_SOURCE, D3D12_RESOURCE_STATE_UNORDERED_ACCESS);

		commandList->ResourceBarrier(ARRAYSIZE(postCopyBarriers), postCopyBarriers);
	}
}

Have you tried writing into your Render Target directly from inside the Ray Generation Shader, before/without calling TraceRay()? For instance, setting all of the pixels to white or something, to make sure that the resource bindings and stuff are good to go right from the start of the shader pipeline.

Once you figure that out, you could start to work your way forward to figure out what is amiss.