Welcome, Guest.
Username: Password: Remember me

TOPIC: Any plans to use cbuffer instead of #defines?

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #1

  • OtisInf
  • OtisInf's Avatar
  • Offline
  • Posts: 122
  • Thank you received: 51
Hi,

Today, the shaders used in reshade are using #defines to define the parameter values they're operate with stored in .cfg files. When you want to create the perfect screenshot, this often requires one to tinker with the values in .cfg files, save the file, reshade picks up the change, recompiles the HLSL, and you see the effect of the change you made. This has the following downsides:

- it's slow, as changing a parameter could take 2-3 seconds at least to see the effect
- and more importantly: it works with files and recompiling of shaders, this means there's no real-time UI possible.

So this got me thinking: why not do the following? Use a cbuffer / constant buffer instead: using variables in a cbuffer struct, the HLSL compiler will compile that into a tight buffer which is updatable in real-time. The shaders no longer use the #defined constants in their code but the (albeit global) variables in the cbuffer.

The big advantage of this is that a real-time UI to change the values and immediately see the effect of that change is no longer hard: the UI (e.g. created with ImGui github.com/ocornut/imgui ) can offer controls to the user which, when their values are changed, immediately update the cbuffer which is then pushed to the shaders again, and the effect of the change is seen immediately.

This is the same system ENB uses: it saves the values used at runtime in separate, simple ini files. You could, for backwards compatibility, use the current cfg files as initial values for the variables, so people can download presets as-is, but don't have to alter the cfg files anymore, they can do that through the UI.

Am I delusional or is this a possibility? :) Thanks for listening.
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #2

  • Ganossa
  • Ganossa's Avatar
  • Offline
  • 최정장군
  • Posts: 790
  • Thank you received: 838
You will miss out optimization opportunities if you change all #defines with variable cbuffer values.
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #3

  • OtisInf
  • OtisInf's Avatar
  • Offline
  • Posts: 122
  • Thank you received: 51
And how much difference does that make, have you measured it with a profiler? I never noticed much difference when using hardcoded values or a variable with e.g. ENB shaders. And as long as the current shaders have code like this:
float GetFocalDepth(float2 focalpoint)
{ 
 	float depthsum = 0;
 	float fcRadius = 0.00;

	[unroll]
	for(int r=0;r<6;r++)
	{ 
 		float t = (float)r; 
 		t *= 3.1415*2/6;                    
 		float2 coord = float2(cos(t),sin(t)); 
 		coord.y *= ScreenSize.z; 
 		coord *= fcRadius;              // A
 		float depth = GetLinearDepth(tex2Dlod(RFX_depthColor,float4(coord+focalpoint,0,0)).x); 
 		depthsum+=depth; 
 	}

	depthsum = depthsum/6;

#if(DOF_MANUALFOCUS == 1)
	depthsum = DOF_MANUALFOCUSDEPTH;                       // B
#endif

	return depthsum; 
}
I wouldn't worry about perf loss due to variables instead of hard-coded constants. ;)

(hint: at line A, you're multiplying with 0, as fcRadius is never updated, at line B you're overwriting the work you've done above the code, which can be made more optimal by including the loop in the #ifdef so it's only done when manual focus depth is 0 ;))
Last Edit: 1 year 1 month ago by OtisInf.
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #4

  • crosire
  • crosire's Avatar
  • Offline
  • Posts: 2437
  • Thank you received: 1385
ReShade (in theory) supports this already. There even is a GUI system to edit uniforms in-game implemented since ReShade 1.0, but it's currently disabled, because not yet finished. But if they are used and how is still up to the shader developers.
Cheers, crosire =)
Last Edit: 1 year 1 month ago by crosire.
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #5

  • Ganossa
  • Ganossa's Avatar
  • Offline
  • 최정장군
  • Posts: 790
  • Thank you received: 838
Since we cannot "un-define" uniforms and they are (currently!) not encapsulated within namespaces, it is (currently!) not advisable to introduce a bigger amount of them in this shared project.

@Crosire, any change to the loaded files will re-compile the shader currently? So even though they are internally cbuffer variables, they would still cause the re-compilations, is that correct or would you need to define the actual values in that experimental GUI that you mentioned?
Last Edit: 1 year 1 month ago by Ganossa.
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #6

  • crosire
  • crosire's Avatar
  • Offline
  • Posts: 2437
  • Thank you received: 1385
LuciferHawk wrote:
@Crosire, any change to the loaded files will re-compile the shader currently? So even though they are internally cbuffer variables, they would still cause the re-compilations, is that correct or would you need to define the actual values in that experimental GUI that you mentioned?
Of course. Uniforms are there to be changed at runtime, not to be changed in the source code.
When ReShade compiles a shader it stores a list of all uniforms it came across, creates a constant buffer and populates it with those uniforms. Later the GUI I'm talking about loops over all uniforms, adds some slider or similar to the in-game overlay and waits for user input. If the user changes one of those sliders, ReShade knows which offset in the constant buffer that value is stored at and replaces it in GPU memory.

Uniforms should be used carefully and only when useful. Example: Changing between different DOF types, which changes the actual code is something one would do with preprocessor macros, because it reduces the amount of code that needs to be executed. Something like the DOF near and far plane constants however could be implemented with uniforms, because those are simple variable values without any payload attached to them.
Cheers, crosire =)
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #7

  • OtisInf
  • OtisInf's Avatar
  • Offline
  • Posts: 122
  • Thank you received: 51
That's great news :) Looking forward to trying out this UI! keep up the good work
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #8

  • Ganossa
  • Ganossa's Avatar
  • Offline
  • 최정장군
  • Posts: 790
  • Thank you received: 838
Just to explain where I was going with my question, and maybe thats a helpful one for you:
If its supposed to be how you are saying, then (currently!) I am missing some step here in the plan :P Where (and maybe also When) will the settings for uniforms ultimately be stored persistently if not in the setting files so the user does not have to set them up each time he runs a game or to share presets?

Unless there is a clause for preset uniforms in the re-compilation on file change and another language extension to change/set this value, I see it not really being an alternative to preprocessor defines. (But maybe it was just too early in its actual development to answer those question that however need to be answered in the end I believe ;))
Last Edit: 1 year 1 month ago by Ganossa.
The administrator has disabled public write access.

Any plans to use cbuffer instead of #defines? 1 year 1 month ago #9

  • crosire
  • crosire's Avatar
  • Offline
  • Posts: 2437
  • Thank you received: 1385
LuciferHawk wrote:
Where (and maybe also When) will the settings for uniforms ultimately be stored persistently if not in the setting files so the user does not have to set them up each time he runs a game or to share presets?
They do have a default value:
uniform float myValue = 1337.0f;
But apart from that, nowhere. They aren't made for preset editing. They can be used for faster development, because one can very quickly try out various values or a value range without waiting hours on the compiler to finish. Once an appropiate value is found, it's best to replace the uniform variable with a constant variable or a preprocessor define for possible optimization and thus performance improvement:

Constant (is evaluated by the compiler):
static const float myValue = 1337.0f;
Preprocessor Macro (is a simple text replacement in the source code done by the preprocessor, so before the compiler is executed):
#define myValue 1337.0f
Cheers, crosire =)
The administrator has disabled public write access.
The following user(s) said Thank You: Ganossa