2

We have a project that currently uses DirectX11 SlimDX and would like to move it to SharpDX. However, this project uses the Effect framework from SlimDX which I understand is no longer properly supported in DirectX11. However I can't find definitive information about how I should transition the effects.

The effects in use are relatively simple pixels shaders, contained in .fx files.

Should I move away from .fx files? What to? To plain .hlsl files? Or should I use the SharpDX Toolkit? Does this use a different format from .fx files?

I can't find any documentation on this. Is there anyone who has made this transition who could give me some advice, or any documentation on the SharpDX Toolkit effects framework?

Grokys
  • 16,228
  • 14
  • 69
  • 101
  • I would recommend using plain hlsl files, as this is the direction that has been chosen for DirectX 11 as well. fx is not supported anymore – thumbmunkeys Jun 12 '14 at 13:34
  • @thumbmunkeys: Thanks for the reply. Could you point me to any documentation that tells me how to do that? – Grokys Jun 12 '14 at 17:32
  • Why do you need to move to SharpDX? Your code will work as long as Direct3D11 is working on the machine, even if Effects is no longer updated – xoofx Jun 12 '14 at 21:59
  • @xoofx: mainly because we're concerned about relying on a library that is no longer maintained. – Grokys Jun 17 '14 at 19:57
  • @xoofx: and also: I want to know how to do it! – Grokys Jun 17 '14 at 19:57

1 Answers1

4

The move to SharpDX is pretty simple, there's a couple of changes in naming, and resource description, but apart the fact that it's relatively cumbersome (depending on the size of your code base), there's nothing too complex.

About effects framework, you have the library SharpDX.Direct3D11.Effects that wraps it, so you have it of course supported. It's pretty much the same as per SlimDX counterpart, so you should not have any major issues moving from it.

If you want to transition away from fx framework to more plain hlsl, you can keep the same fx file, compilation steps will change, instead on compiling the whole file you need to compile each shader separately.

So for example, to compile and create a VertexShader:

CompilationResult result = ShaderBytecode.Compile(content, "VS", "vs_5_0", flags, EffectFlags.None, null, null);

VertexShader shader = new VertexShader(device, result.Bytecode);

Also you need to be careful with all constantbuffers/resource registers, it's generally good to set them explicitely, for example:

cbuffer cbData : register(b0)
{
float4x4 tW;
    float4x4 tColor;
float4 cAmb;
};

You of course don't have anymore all the EffectVariable, Get by name/semantic, so instead you need to map your cBuffer to a struct in c# (you can also use datastream directly), and create Constant buffer resources.

[StructLayout(LayoutKind.Sequential,Pack=16)]
public struct cbData
{
    public Matrix tW;
    public Matrix tColor;
    public Vector4 cAmb;
}

BufferDescription bd = new BufferDescription()
{
   BindFlags = BindFlags.ConstantBuffer,
   CpuAccessFlags = CpuAccessFlags.Write,
   OptionFlags = ResourceOptionFlags.None,
   SizeInBytes = 144, //Matches the struct
   Usage = ResourceUsage.Dynamic
};

var cbuffer = new SharpDX.Direct3D11.Buffer(device, bd);

Use either UpdateSubResource or MapSubresource to update data, and deviceContext.VertexShader.SetConstantBuffer to bind to pipeline.

If you need to inspect shader with reflection, this is done this way (please note that's actually what the effects framework does, it's just a layer on top of d3dcompiler):

ShaderReflection refl = new ShaderReflection(result.Bytecode);

You then need to set up all API calls manually (which is what Effects does for you when you call EffectPass.Apply ).

Also since you compile shaders individually, there is no more layout validation between stages (effects compiler giving you : No valid VertexShader-PixelShader combination....). So you need to be careful setting your pipeline with non matching shaders (you can use reflection data to validate manually, or watch a black screen with debug runtime spamming your output window in visual studio).

So transitioning can be a bit tedious, but can also be beneficial since it's easier to minimize pipeline state changes (In my use case this is not a concern, so effects framework does just fine, but if you have a high number of draw calls that can become significant).

mrvux
  • 8,523
  • 1
  • 27
  • 61
  • My `VertexShader shader = new VertexShader(device, result.Bytecode);` -> `result.Bytecode` doesn't returns a `Byte[]`, it returns a `DataStream`. So i cannot use it as parameter of the `VertexShader` constructor. Any ideas? – Jeroen van Langen Nov 11 '16 at 11:42
  • @JeroenvanLangen Which version of SharpDX? just checked on 3 and it passes a byte[]. Also it has an implicit converter, so new VertexShader(device, result); should also work straight away – mrvux Nov 22 '16 at 15:25
  • @catflier thanks for your reaction. Seen many reactions you gave are usefull. For me I got it solved by referencing another sharpdx assembly. – Jeroen van Langen Nov 23 '16 at 08:11