Compute shaders
-
- OGRE Contributor
- Posts: 267
- Joined: Wed Apr 23, 2014 3:49 pm
- Location: Bologna, Italy
- x 75
Compute shaders
Hi,
I've begun to play with compute shaders and I have two quick questions.
What's the purpouse of inform_shader_of_texture_data_change? I've seen that in every *.material.json file that declares a compute shader is set to true. But reading the HlmsComputeJob::setInformHlmsOfTextureData documentation it seems that is it should be left as it is to false (unless you know what you're doing).
Correct me if I'm wrong, but at the moment there's no way to set preprocessor definitions of a compute shader, right? Would it be hard to add this feature? I'm asking this because I have some 3rd party compute shaders that enable/disable features by defines. I'd like to keep them as they are to simplify the merge/update process in the future.
I've begun to play with compute shaders and I have two quick questions.
What's the purpouse of inform_shader_of_texture_data_change? I've seen that in every *.material.json file that declares a compute shader is set to true. But reading the HlmsComputeJob::setInformHlmsOfTextureData documentation it seems that is it should be left as it is to false (unless you know what you're doing).
Correct me if I'm wrong, but at the moment there's no way to set preprocessor definitions of a compute shader, right? Would it be hard to add this feature? I'm asking this because I have some 3rd party compute shaders that enable/disable features by defines. I'd like to keep them as they are to simplify the merge/update process in the future.
Senior programmer at 505 Games; former senior engine programmer at Sandbox Games
Worked on: Racecraft Esport — Racecraft Coin-Op, Victory: The Age of Racing
-
- OGRE Team Member
- Posts: 5511
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1379
Re: Compute shaders
There are several properties that are only set when inform_shader_of_texture_data_change is true.
These properties are in HlmsComputeJob::setTextureProperties
The most important one is probably uav0_pf_type, which is why inform_shader_of_texture_data_change is often true.
Regular textures can switch formats dynamically. e.g. you declare in HLSL:
And you can later bind a texture with format PFG_RG8_UNORM and myTex.Sample().xy will return the valid values, while .zw will return 0.
Everything works.
UAVs however don't. You must declare the proper format. If you expect to bind PFG_RG8_UNORM, then you must declare:
Even the 'unorm' part is mandatory.
If you know beforehand which format you expect to bind, then you can hardcode it and leave inform_shader_of_texture_data_change as false (assuming you also don't use any of the other properties that are only defined with this setting)
But otherwise, you can use the Hlms to dynamically define the format:
And that's why inform_shader_of_texture_data_change is often true.
If a ComputeJob keeps switching textures or uavs very often, there is a performance overhead as we must reset the texture properties, and then:
These properties are in HlmsComputeJob::setTextureProperties
The most important one is probably uav0_pf_type, which is why inform_shader_of_texture_data_change is often true.
Regular textures can switch formats dynamically. e.g. you declare in HLSL:
Code: Select all
Texture<float4> myTex;
Everything works.
UAVs however don't. You must declare the proper format. If you expect to bind PFG_RG8_UNORM, then you must declare:
Code: Select all
RWTexture<unorm float2> myUav;
If you know beforehand which format you expect to bind, then you can hardcode it and leave inform_shader_of_texture_data_change as false (assuming you also don't use any of the other properties that are only defined with this setting)
But otherwise, you can use the Hlms to dynamically define the format:
Code: Select all
RWTexture3D<@insertpiece(uav0_pf_type)> outLightHigherMip0 : register(u0);
If a ComputeJob keeps switching textures or uavs very often, there is a performance overhead as we must reset the texture properties, and then:
- We see if a shader with the exact same properties is already in the cache.
- If it's not, then we must generate the new shader code by running the Hlms parser.
- Then we see if the generated shader is already cached (because two jobs with different properties may end up producing the same output if e.g. you don't use those the key properties that changed).
This isn't slow, but it can take its time: for example the shaders based on GaussianBlurBase_cs use a lot of @foreach, and the parser takes noticeable time (specially on Debug) - If the generated output is not in the cache, we compile the HLSL/GLSL/Metal code (and that can be super slow)
-
- OGRE Team Member
- Posts: 5511
- Joined: Sat Jul 21, 2007 4:55 pm
- Location: Buenos Aires, Argentina
- x 1379
Re: Compute shaders
We don't have that feature at the moment. You can workaround it by setting them at the start with Hlms properties:TaaTT4 wrote: Mon Oct 14, 2019 11:47 am Correct me if I'm wrong, but at the moment there's no way to set preprocessor definitions of a compute shader, right?
Code: Select all
@property( MY_DEFINE )#define MY_DEFINE @value( MY_DEFINE )@end
Code: Select all
// C++ code:
const char *definitions =
"#define PARAM_A\n
#define PARAM_B";
computeJob->setPiece( "my_custom_definitions", definitions );
// Shader code at the top:
@insertpiece( my_custom_definitions )
I don't think it's very hard.TaaTT4 wrote: Mon Oct 14, 2019 11:47 amWould it be hard to add this feature? I'm asking this because I have some 3rd party compute shaders that enable/disable features by defines. I'd like to keep them as they are to simplify the merge/update process in the future.
The shaders already support custom definitions via:
Code: Select all
gp->setParameter( "preprocessor_defines", "..." );
However since we perform very extensive and complicated multi-level caching, the easiest way to play nice with caching would be to store the definitions as a piece:
Code: Select all
HlmsComputeJob::setDefinitions( const String &definitions )
{
this->setPiece( "__internal_definitions", definitions );
}
This should be easy for you to implement if you want to contribute.
Cheers
Matias