Skip to content

Commit

Permalink
Supporting the BlendFactor in the D3D backend (#424)
Browse files Browse the repository at this point in the history
* Test on using the BlendFactor in a blend state.

* #424. Supporting the BlendFactor in the D3D backend.
  • Loading branch information
baSSiLL committed Jan 16, 2022
1 parent 0adacfa commit 1832620
Show file tree
Hide file tree
Showing 4 changed files with 121 additions and 3 deletions.
112 changes: 112 additions & 0 deletions src/Veldrid.Tests/RenderTests.cs
Expand Up @@ -1241,6 +1241,118 @@ public void WriteFragmentDepth()
}
GD.Unmap(readback);
}

[Fact]
public void UseBlendFactor()
{
const uint width = 512;
const uint height = 512;
using var output = RF.CreateTexture(
TextureDescription.Texture2D(width, height, 1, 1, PixelFormat.R32_G32_B32_A32_Float, TextureUsage.RenderTarget));
using var framebuffer = RF.CreateFramebuffer(new FramebufferDescription(null, output));

var yMod = GD.IsClipSpaceYInverted ? -1.0f : 1.0f;
var vertices = new[]
{
new ColoredVertex { Position = new Vector2(-1, 1 * yMod), Color = Vector4.One },
new ColoredVertex { Position = new Vector2(1, 1 * yMod), Color = Vector4.One },
new ColoredVertex { Position = new Vector2(-1, -1 * yMod), Color = Vector4.One },
new ColoredVertex { Position = new Vector2(1, -1 * yMod), Color = Vector4.One }
};
uint vertexSize = (uint)Unsafe.SizeOf<ColoredVertex>();
using var buffer = RF.CreateBuffer(new BufferDescription(
vertexSize * (uint)vertices.Length,
BufferUsage.StructuredBufferReadOnly,
vertexSize,
true));
GD.UpdateBuffer(buffer, 0, vertices);

using var graphicsLayout = RF.CreateResourceLayout(new ResourceLayoutDescription(
new ResourceLayoutElementDescription("InputVertices", ResourceKind.StructuredBufferReadOnly, ShaderStages.Vertex)));
using var graphicsSet = RF.CreateResourceSet(new ResourceSetDescription(graphicsLayout, buffer));

var blendDesc = new BlendStateDescription
{
BlendFactor = new RgbaFloat(0.25f, 0.5f, 0.75f, 1),
AttachmentStates = new[]
{
new BlendAttachmentDescription
{
BlendEnabled = true,
SourceColorFactor = BlendFactor.BlendFactor,
DestinationColorFactor = BlendFactor.Zero,
ColorFunction = BlendFunction.Add,
SourceAlphaFactor = BlendFactor.BlendFactor,
DestinationAlphaFactor = BlendFactor.Zero,
AlphaFunction = BlendFunction.Add
}
}
};
var pipelineDesc = new GraphicsPipelineDescription(
blendDesc,
DepthStencilStateDescription.Disabled,
RasterizerStateDescription.Default,
PrimitiveTopology.TriangleStrip,
new ShaderSetDescription(
Array.Empty<VertexLayoutDescription>(),
TestShaders.LoadVertexFragment(RF, "ColoredQuadRenderer")),
graphicsLayout,
framebuffer.OutputDescription);

using (var pipeline1 = RF.CreateGraphicsPipeline(pipelineDesc))
using (var cl = RF.CreateCommandList())
{
cl.Begin();
cl.SetFramebuffer(framebuffer);
cl.ClearColorTarget(0, RgbaFloat.Clear);
cl.SetPipeline(pipeline1);
cl.SetGraphicsResourceSet(0, graphicsSet);
cl.Draw((uint)vertices.Length);
cl.End();
GD.SubmitCommands(cl);
GD.WaitForIdle();
}

using (var readback = GetReadback(output))
{
var readView = GD.Map<RgbaFloat>(readback, MapMode.Read);
for (uint y = 0; y < height; y++)
for (uint x = 0; x < width; x++)
{
Assert.Equal(new RgbaFloat(0.25f, 0.5f, 0.75f, 1), readView[x, y]);
}
GD.Unmap(readback);
}

blendDesc.BlendFactor = new RgbaFloat(0, 1, 0.5f, 0);
blendDesc.AttachmentStates[0].DestinationColorFactor = BlendFactor.InverseBlendFactor;
blendDesc.AttachmentStates[0].DestinationAlphaFactor = BlendFactor.InverseBlendFactor;
pipelineDesc.BlendState = blendDesc;

using (var pipeline2 = RF.CreateGraphicsPipeline(pipelineDesc))
using (var cl = RF.CreateCommandList())
{
cl.Begin();
cl.SetFramebuffer(framebuffer);
cl.SetPipeline(pipeline2);
cl.SetGraphicsResourceSet(0, graphicsSet);
cl.Draw((uint)vertices.Length);
cl.End();
GD.SubmitCommands(cl);
GD.WaitForIdle();
}

using (var readback = GetReadback(output))
{
var readView = GD.Map<RgbaFloat>(readback, MapMode.Read);
for (uint y = 0; y < height; y++)
for (uint x = 0; x < width; x++)
{
Assert.Equal(new RgbaFloat(0.25f, 1, 0.875f, 1), readView[x, y]);
}
GD.Unmap(readback);
}
}
}

#if TEST_OPENGL
Expand Down
7 changes: 5 additions & 2 deletions src/Veldrid/D3D11/D3D11CommandList.cs
Expand Up @@ -35,6 +35,7 @@ internal class D3D11CommandList : CommandList
private DeviceBuffer _ib;
private uint _ibOffset;
private ID3D11BlendState _blendState;
private Color4 _blendFactor;
private ID3D11DepthStencilState _depthStencilState;
private uint _stencilReference;
private ID3D11RasterizerState _rasterizerState;
Expand Down Expand Up @@ -237,10 +238,12 @@ private protected override void SetPipelineCore(Pipeline pipeline)
Util.ClearArray(_invalidatedGraphicsResourceSets);

ID3D11BlendState blendState = d3dPipeline.BlendState;
if (_blendState != blendState)
Color4 blendFactor = d3dPipeline.BlendFactor;
if (_blendState != blendState || _blendFactor != blendFactor)
{
_blendState = blendState;
_context.OMSetBlendState(blendState);
_blendFactor = blendFactor;
_context.OMSetBlendState(blendState, blendFactor);
}

ID3D11DepthStencilState depthStencilState = d3dPipeline.DepthStencilState;
Expand Down
2 changes: 1 addition & 1 deletion src/Veldrid/D3D11/D3D11Formats.cs
Expand Up @@ -369,7 +369,7 @@ internal static Blend VdToD3D11Blend(BlendFactor factor)
case BlendFactor.BlendFactor:
return Blend.BlendFactor;
case BlendFactor.InverseBlendFactor:
return Blend.BlendFactor;
return Blend.InverseBlendFactor;
default:
throw Illegal.Value<BlendFactor>();
}
Expand Down
3 changes: 3 additions & 0 deletions src/Veldrid/D3D11/D3D11Pipeline.cs
@@ -1,6 +1,7 @@
using Vortice.Direct3D11;
using System.Diagnostics;
using System;
using Vortice.Mathematics;

namespace Veldrid.D3D11
{
Expand All @@ -10,6 +11,7 @@ internal class D3D11Pipeline : Pipeline
private bool _disposed;

public ID3D11BlendState BlendState { get; }
public Color4 BlendFactor { get; }
public ID3D11DepthStencilState DepthStencilState { get; }
public uint StencilReference { get; }
public ID3D11RasterizerState RasterizerState { get; }
Expand Down Expand Up @@ -74,6 +76,7 @@ public D3D11Pipeline(D3D11ResourceCache cache, ref GraphicsPipelineDescription d
out ID3D11InputLayout inputLayout);

BlendState = blendState;
BlendFactor = new Color4(description.BlendState.BlendFactor.ToVector4());
DepthStencilState = depthStencilState;
StencilReference = description.DepthStencilState.StencilReference;
RasterizerState = rasterizerState;
Expand Down

0 comments on commit 1832620

Please sign in to comment.