Skip to content
Permalink
Browse files

Add output merger UAV binding. (#478)

  • Loading branch information
WhyPenguins authored and xen2 committed Aug 29, 2019
1 parent b7451e4 commit a503e9013938388024b26a0efbab2da54a2f73b4
Showing with 53 additions and 4 deletions.
  1. +53 −4 sources/engine/Xenko.Graphics/Direct3D/CommandList.Direct3D.cs
@@ -26,6 +26,8 @@ public partial class CommandList
private SharpDX.Direct3D11.OutputMergerStage outputMerger;

private readonly SharpDX.Direct3D11.RenderTargetView[] currentRenderTargetViews = new SharpDX.Direct3D11.RenderTargetView[SimultaneousRenderTargetCount];
private int currentRenderTargetViewsActiveCount = 0;
private readonly SharpDX.Direct3D11.UnorderedAccessView[] currentUARenderTargetViews = new SharpDX.Direct3D11.UnorderedAccessView[SimultaneousRenderTargetCount];
private readonly SharpDX.Direct3D11.CommonShaderStage[] shaderStages = new SharpDX.Direct3D11.CommonShaderStage[StageCount];
private readonly Buffer[] constantBuffers = new Buffer[StageCount * ConstantBufferCount];
private readonly SamplerState[] samplerStates = new SamplerState[StageCount * SamplerStateCount];
@@ -89,6 +91,8 @@ private void ClearStateImpl()
unorderedAccessViews[i] = null;
for (int i = 0; i < currentRenderTargetViews.Length; i++)
currentRenderTargetViews[i] = null;
for (int i = 0; i < currentUARenderTargetViews.Length; i++)
currentUARenderTargetViews[i] = null;

// Since nothing can be drawn in default state, no need to set anything (another SetPipelineState should happen before)
currentPipelineState = GraphicsDevice.DefaultPipelineState;
@@ -101,6 +105,8 @@ private void ResetTargetsImpl()
{
for (int i = 0; i < currentRenderTargetViews.Length; i++)
currentRenderTargetViews[i] = null;
for (int i = 0; i < currentUARenderTargetViews.Length; i++)
currentUARenderTargetViews[i] = null;
outputMerger.ResetTargets();
}

@@ -113,6 +119,8 @@ private void ResetTargetsImpl()
/// <exception cref="System.ArgumentNullException">renderTargetViews</exception>
private void SetRenderTargetsImpl(Texture depthStencilBuffer, int renderTargetCount, Texture[] renderTargets)
{
currentRenderTargetViewsActiveCount = renderTargetCount;

for (int i = 0; i < renderTargetCount; i++)
currentRenderTargetViews[i] = renderTargets[i].NativeRenderTargetView;

@@ -255,6 +263,30 @@ internal void SetShaderResourceView(ShaderStage stage, int slot, GraphicsResourc
shaderStages[(int)stage - 1].SetShaderResource(slot, shaderResourceView != null ? shaderResourceView.NativeShaderResourceView : null);
}

/// <summary>
/// Sets an unordered access view to the shader pipeline, without affecting ones that are already set.
/// </summary>
/// <param name="slot">The binding slot.</param>
/// <param name="shaderResourceView">The shader resource view.</param>
/// <param name="view">The native unordered access view.</param>
/// <param name="uavInitialOffset">The Append/Consume buffer offset. See SetUnorderedAccessView for more details.</param>
internal void OMSetSingleUnorderedAccessView(int slot, SharpDX.Direct3D11.UnorderedAccessView view, int uavInitialOffset)
{
currentUARenderTargetViews[slot] = view;

int remainingSlots = currentUARenderTargetViews.Length - currentRenderTargetViewsActiveCount;

var uavs = new SharpDX.Direct3D11.UnorderedAccessView[remainingSlots];
Array.Copy(currentUARenderTargetViews, currentRenderTargetViewsActiveCount, uavs, 0, remainingSlots);

var uavInitialCounts = new int[remainingSlots];
for (int i = 0; i < remainingSlots; i++)
uavInitialCounts[i] = -1;
uavInitialCounts[slot - currentRenderTargetViewsActiveCount] = uavInitialOffset;

outputMerger.SetUnorderedAccessViews(currentRenderTargetViewsActiveCount, uavs, uavInitialCounts);
}

/// <summary>
/// Sets an unordered access view to the shader pipeline.
/// </summary>
@@ -268,14 +300,24 @@ internal void SetShaderResourceView(ShaderStage stage, int slot, GraphicsResourc
/// <exception cref="System.ArgumentException">Invalid stage.;stage</exception>
internal void SetUnorderedAccessView(ShaderStage stage, int slot, GraphicsResource unorderedAccessView, int uavInitialOffset)
{
if (stage != ShaderStage.Compute)
if (stage != ShaderStage.Compute && stage != ShaderStage.Pixel)
throw new ArgumentException("Invalid stage.", "stage");

var view = unorderedAccessView?.NativeUnorderedAccessView;
if (unorderedAccessViews[slot] != view)
if (stage == ShaderStage.Compute)
{
unorderedAccessViews[slot] = view;
NativeDeviceContext.ComputeShader.SetUnorderedAccessView(slot, view, uavInitialOffset);
if (unorderedAccessViews[slot] != view)
{
unorderedAccessViews[slot] = view;
NativeDeviceContext.ComputeShader.SetUnorderedAccessView(slot, view, uavInitialOffset);
}
}
else
{
if (currentUARenderTargetViews[slot] != view)
{
OMSetSingleUnorderedAccessView(slot, view, uavInitialOffset);
}
}
}

@@ -297,6 +339,13 @@ internal void UnsetUnorderedAccessView(GraphicsResource unorderedAccessView)
NativeDeviceContext.ComputeShader.SetUnorderedAccessView(slot, null);
}
}
for (int slot = 0; slot < SimultaneousRenderTargetCount; slot++)
{
if (currentUARenderTargetViews[slot] == view)
{
OMSetSingleUnorderedAccessView(slot, null, -1);
}
}
}

/// <summary>

0 comments on commit a503e90

Please sign in to comment.
You can’t perform that action at this time.