浏览代码

Added viewport copy for GPUCopy

/main
Frédéric Vauchelles 7 年前
当前提交
ab299efc
共有 3 个文件被更改,包括 174 次插入30 次删除
  1. 15
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.compute
  2. 81
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.cs
  3. 108
      ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopyAsset.cs

15
ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.compute


#include "../ShaderLibrary/Common.hlsl"
#pragma only_renderers d3d11 ps4 xboxone vulkan metal
CBUFFER_START (UnityCBuffer)
uint2 _RectOffset;
CBUFFER_END
#pragma kernel KSampleCopy4_1_x
[numthreads(8, 8, 1)]
void KSampleCopy4_1_x(uint2 dispatchThreadId : SV_DispatchThreadID)
#pragma kernel KSampleCopy4_1_x_8 KERNEL_NAME=KSampleCopy4_1_x_8 KERNEL_SIZE=8
#pragma kernel KSampleCopy4_1_x_1 KERNEL_NAME=KSampleCopy4_1_x_1 KERNEL_SIZE=1
[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)]
void KERNEL_NAME(uint2 dispatchThreadId : SV_DispatchThreadID)
_Result1[dispatchThreadId] = LOAD_TEXTURE2D(_Source4, dispatchThreadId).x;
_Result1[_RectOffset + dispatchThreadId] = LOAD_TEXTURE2D(_Source4, _RectOffset + dispatchThreadId).x;
}

81
ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopy.cs


public class GPUCopy
{
ComputeShader m_Shader;
int k_SampleKernel_xyzw2x;
int k_SampleKernel_xyzw2x_8;
int k_SampleKernel_xyzw2x_1;
k_SampleKernel_xyzw2x = m_Shader.FindKernel("KSampleCopy4_1_x");
k_SampleKernel_xyzw2x_8 = m_Shader.FindKernel("KSampleCopy4_1_x_8");
k_SampleKernel_xyzw2x_1 = m_Shader.FindKernel("KSampleCopy4_1_x_1");
static readonly int _RectOffset = Shader.PropertyToID("_RectOffset");
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Vector2 size)
void SampleCopyChannel(
CommandBuffer cmd,
RectInt rect,
int _source,
RenderTargetIdentifier source,
int _target,
RenderTargetIdentifier target,
int kernel8,
int kernel1)
{
RectInt main, topRow, rightCol, topRight;
unsafe
cmd.SetComputeTextureParam(m_Shader, k_SampleKernel_xyzw2x, _Source4, source);
cmd.SetComputeTextureParam(m_Shader, k_SampleKernel_xyzw2x, _Result1, target);
cmd.DispatchCompute(m_Shader, k_SampleKernel_xyzw2x, (int)Mathf.Max((size.x) / 8, 1), (int)Mathf.Max((size.y) / 8, 1), 1);
RectInt* dispatch1Rects = stackalloc RectInt[3];
int dispatch1RectCount = 0;
RectInt dispatch8Rect = RectInt.zero;
if (TileLayoutUtils.TryLayoutByTiles(
rect,
8,
out main,
out topRow,
out rightCol,
out topRight))
{
if (topRow.width > 0 && topRow.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRow;
++dispatch1RectCount;
}
if (rightCol.width > 0 && rightCol.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rightCol;
++dispatch1RectCount;
}
if (topRight.width > 0 && topRight.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRight;
++dispatch1RectCount;
}
dispatch8Rect = main;
}
else if (rect.width > 0 && rect.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rect;
++dispatch1RectCount;
}
cmd.SetComputeTextureParam(m_Shader, kernel8, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel1, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel8, _target, target);
cmd.SetComputeTextureParam(m_Shader, kernel1, _target, target);
if (dispatch8Rect.width > 0 && dispatch8Rect.height > 0)
{
var r = dispatch8Rect;
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel8, (int)Mathf.Max(r.width / 8, 1), (int)Mathf.Max(r.height / 8, 1), 1);
}
for (int i = 0, c = dispatch1RectCount; i < c; ++i)
{
var r = dispatch1Rects[i];
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel1, (int)Mathf.Max(r.width, 1), (int)Mathf.Max(r.height, 1), 1);
}
}
public void SampleCopyChannel_xyzw2x(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, RectInt rect)
{
SampleCopyChannel(cmd, rect, _Source4, source, _Result1, target, k_SampleKernel_xyzw2x_8, k_SampleKernel_xyzw2x_1);
}
}
}

108
ScriptableRenderPipeline/Core/CoreRP/CoreResources/GPUCopyAsset.cs


}
ccp.AppendLine();
ccp.AppendLine("CBUFFER_START (UnityCBuffer)");
ccp.AppendLine(" uint2 _RectOffset;");
ccp.AppendLine("CBUFFER_END");
ccp.AppendLine();
csm.AppendLine(" static readonly int _RectOffset = Shader.PropertyToID(\"_RectOffset\");");
ccp.AppendLine();
ccp.AppendLine();
csm.AppendLine(@" void SampleCopyChannel(
CommandBuffer cmd,
RectInt rect,
int _source,
RenderTargetIdentifier source,
int _target,
RenderTargetIdentifier target,
int kernel8,
int kernel1)
{
RectInt main, topRow, rightCol, topRight;
unsafe
{
RectInt* dispatch1Rects = stackalloc RectInt[3];
int dispatch1RectCount = 0;
RectInt dispatch8Rect = RectInt.zero;
if (TileLayoutUtils.TryLayoutByTiles(
rect,
8,
out main,
out topRow,
out rightCol,
out topRight))
{
if (topRow.width > 0 && topRow.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRow;
++dispatch1RectCount;
}
if (rightCol.width > 0 && rightCol.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rightCol;
++dispatch1RectCount;
}
if (topRight.width > 0 && topRight.height > 0)
{
dispatch1Rects[dispatch1RectCount] = topRight;
++dispatch1RectCount;
}
dispatch8Rect = main;
}
else if (rect.width > 0 && rect.height > 0)
{
dispatch1Rects[dispatch1RectCount] = rect;
++dispatch1RectCount;
}
cmd.SetComputeTextureParam(m_Shader, kernel8, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel1, _source, source);
cmd.SetComputeTextureParam(m_Shader, kernel8, _target, target);
cmd.SetComputeTextureParam(m_Shader, kernel1, _target, target);
if (dispatch8Rect.width > 0 && dispatch8Rect.height > 0)
{
var r = dispatch8Rect;
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel8, (int)Mathf.Max(r.width / 8, 1), (int)Mathf.Max(r.height / 8, 1), 1);
}
for (int i = 0, c = dispatch1RectCount; i < c; ++i)
{
var r = dispatch1Rects[i];
cmd.SetComputeIntParams(m_Shader, _RectOffset, (int)r.x, (int)r.y);
cmd.DispatchCompute(m_Shader, kernel1, (int)Mathf.Max(r.width, 1), (int)Mathf.Max(r.height, 1), 1);
}
}
}");
csc.AppendLine(" public GPUCopy(ComputeShader shader)");
csc.AppendLine(" {");

var o = operations[i];
// Compute kernel
var kernelName = string.Format("KSampleCopy{0}_{1}_{2}", o.sourceChannel.ToString(), o.targetChannel.ToString(), o.subscript);
cck.AppendLine(string.Format("#pragma kernel {0}", kernelName));
cck.AppendLine(string.Format(@"[numthreads({0}, {0}, 1)]",
k_KernelSize.ToString(), k_KernelSize.ToString()));
cck.AppendLine(string.Format(@"void {0}(uint2 dispatchThreadId : SV_DispatchThreadID)", kernelName));
var kernelName8 = string.Format("KSampleCopy{0}_{1}_{2}_8", o.sourceChannel.ToString(), o.targetChannel.ToString(), o.subscript);
var kernelName1 = string.Format("KSampleCopy{0}_{1}_{2}_1", o.sourceChannel.ToString(), o.targetChannel.ToString(), o.subscript);
cck.AppendLine(string.Format("#pragma kernel {0} KERNEL_NAME={0} KERNEL_SIZE=8", kernelName8));
cck.AppendLine(string.Format("#pragma kernel {0} KERNEL_NAME={0} KERNEL_SIZE=1", kernelName1));
cck.AppendLine(@"[numthreads(KERNEL_SIZE, KERNEL_SIZE, 1)]");
cck.AppendLine(@"void KERNEL_NAME(uint2 dispatchThreadId : SV_DispatchThreadID)");
cck.AppendLine(string.Format(" _Result{0}[dispatchThreadId] = LOAD_TEXTURE2D(_Source{1}, dispatchThreadId).{2};",
cck.AppendLine(string.Format(" _Result{0}[_RectOffset + dispatchThreadId] = LOAD_TEXTURE2D(_Source{1}, _RectOffset + dispatchThreadId).{2};",
o.targetChannel.ToString(), o.sourceChannel.ToString(), o.subscript));
cck.AppendLine("}");
cck.AppendLine();

var kernelIndexName = string.Format("k_SampleKernel_{0}2{1}", channelName, o.subscript);
csp.AppendLine(string.Format(" int {0};", kernelIndexName));
var kernelIndexName8 = string.Format("k_SampleKernel_{0}2{1}_8", channelName, o.subscript);
var kernelIndexName1 = string.Format("k_SampleKernel_{0}2{1}_1", channelName, o.subscript);
csp.AppendLine(string.Format(" int {0};", kernelIndexName8));
csp.AppendLine(string.Format(" int {0};", kernelIndexName1));
csc.AppendLine(string.Format(" {0} = m_Shader.FindKernel(\"{1}\");", kernelIndexName, kernelName));
csc.AppendLine(string.Format(" {0} = m_Shader.FindKernel(\"{1}\");", kernelIndexName8, kernelName8));
csc.AppendLine(string.Format(" {0} = m_Shader.FindKernel(\"{1}\");", kernelIndexName1, kernelName1));
csm.AppendLine(string.Format(@" public void SampleCopyChannel_{0}2{1}(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, Vector2 size)", channelName, o.subscript));
csm.AppendLine(" {");
csm.AppendLine(string.Format(" cmd.SetComputeTextureParam(m_Shader, {0}, _Source{1}, source);", kernelIndexName, o.sourceChannel.ToString()));
csm.AppendLine(string.Format(" cmd.SetComputeTextureParam(m_Shader, {0}, _Result{1}, target);", kernelIndexName, o.targetChannel.ToString()));
csm.AppendLine(string.Format(" cmd.DispatchCompute(m_Shader, {0}, (int)Mathf.Max((size.x) / {1}, 1), (int)Mathf.Max((size.y) / {1}, 1), 1);", kernelIndexName, k_KernelSize.ToString()));
csm.AppendLine(" }");
csm.AppendLine(string.Format(@" public void SampleCopyChannel_{0}2{1}(CommandBuffer cmd, RenderTargetIdentifier source, RenderTargetIdentifier target, RectInt rect)", channelName, o.subscript));
csm.AppendLine (" {");
csm.AppendLine(string.Format(" SampleCopyChannel(cmd, rect, _Source{0}, source, _Result{1}, target, {2}, {3});", o.sourceChannel.ToString(), o.targetChannel.ToString(), kernelIndexName8, kernelIndexName1));
csm.AppendLine (" }");
}
csc.AppendLine(" }");

正在加载...
取消
保存