1
\$\begingroup\$

I am working with SharpDX, i thinking to try using (uniform) global variables for HLSL constants instead of constant buffers.

But, in my code SharpDX's Effect class is not used: i use PixelShader and VertexShader classes instead - constructed directly from bytecode blobs (i just don't use techniques/passes, i compile shaders separately).

With Effect class, i can assign new value to any constant in HLSL program by its name, as DirectX allows that, in any time. Example (i haven't tested this; yes, its ugly here):

SharpDX.Direct3D11.Effect fx = //
fx.GetVariableByName("someOption").AsVector().Set<Vector3>(newVectorValue);//nice

But i don't use Effect class. How can i set global HLSL variable using Vertex/PixelShader class instance? If it is not possible, shame on SharpDX dev then, in native DirectX it is much easier.

\$\endgroup\$
2
  • \$\begingroup\$ Are you using D3D9, 10, or 11? I assume 10-11 because you mentioned constant buffers. \$\endgroup\$ – Nathan Reed Mar 1 '14 at 2:22
  • \$\begingroup\$ I use SharpDX.Direct3D11 of course. It is strange to use DX9/10 nowadays. Yes and i use DX wrapper, not SharpDX.Toolkit. \$\endgroup\$ – Croll Mar 1 '14 at 3:06
1
\$\begingroup\$

In D3D11, there is no such thing as a global variable that's not in a constant buffer. Even if you declare variables outside of a constant buffer, the HLSL compiler will put them in a default constant buffer for you.

In C++, I usually just create a struct that matches the layout of a constant buffer in the shader. That might be harder to get working in C# (not sure); but you can also query for the location of individual variables in constant buffers of a compile shader using the ShaderReflection interface, and assemble constant buffers in a data-driven form.

To use a constant buffer outside the effect framework, you have to:

  1. Create a Buffer object to hold the contents of the constant buffer. It should be created with dynamic usage, the constant buffer bind flag, write access from the CPU, and its size has to be a multiple of 16 bytes. If your constant buffer isn't a multiple of 16 bytes, just round up to the next one.
  2. To update the constant buffer, map it (using one of the DeviceContext.MapSubresource methods) using the WriteDiscard map mode, copy your data into it and then unmap it. This can be done as many times per frame as you need (constant buffers are designed to be updated many times per frame).
  3. To provide it to the shader, use the DeviceContext.VertexShader.SetConstantBuffer and DeviceContext.PixelShader.SetConstantBuffer methods. You have to know which slot the constant buffer is assigned to in the shader, which can also be retrieved through the reflection interface, or assigned explicitly in the shader using register(b0) syntax.
\$\endgroup\$
5
  • \$\begingroup\$ I already use constant buffer, in C# it's mapped with struct defintion, with StructLayout attribute(LayoutKind.Sequental, Pack=16). \$\endgroup\$ – Croll Mar 1 '14 at 3:14
  • \$\begingroup\$ Unfortunately, as you say, it is not possible to push SINGLE variable value to shader. But it is possible with Effect class, this means SharpDX missing this important feature (as i don't like that some variables are copied to GPU each Draw() but they are not changed). But maybe it is not so bad... \$\endgroup\$ – Croll Mar 1 '14 at 3:18
  • \$\begingroup\$ @DmitrijA SharpDX isn't missing a feature. The effect framework simulates the ability to set a single variable, but under the hood it's just updating constant buffers and setting them. BTW, you can organize variables into different constant buffers to be updated at different frequencies, such as one per frame, one per material, one per draw, to reduce the amount of data being updated per draw. \$\endgroup\$ – Nathan Reed Mar 1 '14 at 3:38
  • \$\begingroup\$ currently i am looking to SharpDX.Direct3D11.Effects.dll assembly in .NET reflector, and i cannot proof that... i see that new value is being PUSHED to some caculated pointer (SetRawValue), without any mentions of 'constant buffer' \$\endgroup\$ – Croll Mar 1 '14 at 3:50
  • \$\begingroup\$ This is stupid. I think you're right anyway. Thanks. \$\endgroup\$ – Croll Mar 1 '14 at 4:06

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.