Rasagar/Library/PackageCache/com.unity.rendering.light-transport/Runtime/UnifiedRayTracing/Compute/ComputeRayTracingShader.cs

121 lines
5.4 KiB
C#
Raw Normal View History

2024-08-26 13:07:20 -07:00
using Unity.Mathematics;
using UnityEngine.Assertions;
namespace UnityEngine.Rendering.UnifiedRayTracing
{
internal class ComputeRayTracingShader : IRayTracingShader
{
ComputeShader m_Shader;
int m_KernelIndex;
uint3 m_ThreadGroupSizes;
private GraphicsBuffer m_DispatchBuffer; // This is a buffer to hold dispatch arguments when using non indirect dispatch
internal ComputeRayTracingShader(ComputeShader shader, string dispatchFuncName, GraphicsBuffer dispatchBuffer)
{
m_Shader = shader;
m_KernelIndex = m_Shader.FindKernel(dispatchFuncName);
m_Shader.GetKernelThreadGroupSizes(m_KernelIndex,
out m_ThreadGroupSizes.x, out m_ThreadGroupSizes.y, out m_ThreadGroupSizes.z);
m_DispatchBuffer = dispatchBuffer;
}
public uint3 GetThreadGroupSizes()
{
return m_ThreadGroupSizes;
}
public void PopulateDispatchDimensionBuffer(CommandBuffer cmd, GraphicsBuffer dispatchDimensionsBuffer, uint3 dimensions)
{
Assert.IsTrue((dispatchDimensionsBuffer.target & GraphicsBuffer.Target.IndirectArguments) != 0);
Assert.IsTrue((dispatchDimensionsBuffer.target & GraphicsBuffer.Target.Structured) != 0);
Assert.IsTrue(dispatchDimensionsBuffer.count * dispatchDimensionsBuffer.stride == 24);
uint3 workgroups = GraphicsHelpers.DivUp(dimensions, m_ThreadGroupSizes);
cmd.SetBufferData(dispatchDimensionsBuffer, new uint[] { dimensions.x, dimensions.y, dimensions.z, workgroups.x, workgroups.y, workgroups.z });
}
public void SetAccelerationStructure(CommandBuffer cmd, string name, IRayTracingAccelStruct accelStruct)
{
var computeAccelStruct = accelStruct as ComputeRayTracingAccelStruct;
Assert.IsNotNull(computeAccelStruct);
computeAccelStruct.Bind(cmd, name, this);
}
public void SetIntParam(CommandBuffer cmd, int nameID, int val)
{
cmd.SetComputeIntParam(m_Shader, nameID, val);
}
public void SetFloatParam(CommandBuffer cmd, int nameID, float val)
{
cmd.SetComputeFloatParam(m_Shader, nameID, val);
}
public void SetVectorParam(CommandBuffer cmd, int nameID, Vector4 val)
{
cmd.SetComputeVectorParam(m_Shader, nameID, val);
}
public void SetMatrixParam(CommandBuffer cmd, int nameID, Matrix4x4 val)
{
cmd.SetComputeMatrixParam(m_Shader, nameID, val);
}
public void SetTextureParam(CommandBuffer cmd, int nameID, RenderTargetIdentifier rt)
{
cmd.SetComputeTextureParam(m_Shader, m_KernelIndex, nameID, rt);
}
public void SetBufferParam(CommandBuffer cmd, int nameID, GraphicsBuffer buffer)
{
cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, nameID, buffer);
}
public void SetBufferParam(CommandBuffer cmd, int nameID, ComputeBuffer buffer)
{
cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, nameID, buffer);
}
public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, uint width, uint height, uint depth)
{
var requiredScratchSize = GetTraceScratchBufferRequiredSizeInBytes(width, height, depth);
if (requiredScratchSize > 0 && (scratchBuffer == null || ((ulong)(scratchBuffer.count * scratchBuffer.stride) < requiredScratchSize)))
{
throw new System.ArgumentException("scratchBuffer size is too small");
}
if (requiredScratchSize > 0 && scratchBuffer.stride != 4)
{
throw new System.ArgumentException("scratchBuffer stride must be 4");
}
cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, RadeonRays.SID.g_stack, scratchBuffer);
uint workgroupsX = (uint)GraphicsHelpers.DivUp((int)width, m_ThreadGroupSizes.x);
uint workgroupsY = (uint)GraphicsHelpers.DivUp((int)height, m_ThreadGroupSizes.y);
uint workgroupsZ = (uint)GraphicsHelpers.DivUp((int)depth, m_ThreadGroupSizes.z);
PopulateDispatchDimensionBuffer(cmd, m_DispatchBuffer, new uint3(width, height, depth));
SetBufferParam(cmd, RadeonRays.SID.g_dispatch_dimensions, m_DispatchBuffer);
cmd.DispatchCompute(m_Shader, m_KernelIndex, (int)workgroupsX, (int)workgroupsY, (int)workgroupsZ);
}
public ulong GetTraceScratchBufferRequiredSizeInBytes(uint width, uint height, uint depth)
{
uint rayCount = width * height * depth;
return (RadeonRays.RadeonRaysAPI.GetTraceMemoryRequirements(rayCount) * 4);
}
public void Dispatch(CommandBuffer cmd, GraphicsBuffer scratchBuffer, GraphicsBuffer argsBuffer)
{
Assert.IsTrue((argsBuffer.target & GraphicsBuffer.Target.IndirectArguments) != 0);
Assert.IsTrue((argsBuffer.target & GraphicsBuffer.Target.Structured) != 0);
Assert.IsTrue(argsBuffer.count * argsBuffer.stride == 24);
cmd.SetComputeBufferParam(m_Shader, m_KernelIndex, RadeonRays.SID.g_stack, scratchBuffer);
SetBufferParam(cmd, RadeonRays.SID.g_dispatch_dimensions, argsBuffer);
cmd.DispatchCompute(m_Shader, m_KernelIndex, argsBuffer, RayTracingHelper.k_GroupSizeByteOffset);
}
}
}