Sign in to follow this  
Darkneon

Usage of Annotations in HLSL

Recommended Posts

Hi guys, I don't quite get the concept of annotations. I looked over the internet, but no one has a clear explanation. All they say is "user-added information". They don't really explain how/why/when to use them and their effects. Thanks Darkneon

Share this post


Link to post
Share on other sites
Hi there Darkneon,
How are you doing?

[What are Annotations?]
"Annotations are user-specific data that can be attached to any technique, pass, or parameter. An annotation is a flexible way to add information to individual parameters. The information can be read back and used any way the application chooses. An annotation can be of any data type and can be added dynamically. Annotation declarations are delimited by angle brackets."

[What do they contain?]
An annotation contains:
A data type.
A variable name.
An equals sign (=).
The data value.
A ending semicolon (;).

[How do I use them?]
[source lang = c++]
texture Tex0 < string name = "tiger.bmp"; >;



"The annotation is attached to the texture object and specifies the texture file that should be used to initialize the texture object. The annotation does not initialize the texture object, it is simply a piece of user information that is attached to the variable. An application can read the annotation with either ID3DXEffect::GetAnnotation or ID3DXEffect::GetAnnotationByName to return the string. Annotations can also be added by the application."

If you look at the EffectEdit utility in the SDK you will see how they use Annotations to set textures and meshes within the shader.

I think this explains it pretty well and how to use them.
If you have any more questions a little more specific. Please do not hesitate to ask.

Share this post


Link to post
Share on other sites
Hi Armadon.
I'm doing great, how about yourself?

I like the example you have chosen; that's the one I had in mind. But I don't see how the texture is loaded--the annotation 'name' is never used in the effect file. Now thinking about it, I would guess that when we declare the effect file in the source code, we also retrive the annotation name. Then we assign that value to the filename, am I right?

But, but, but, if you look at the effect file, a little down below you have those lines.

string XFile = "tiger\\tiger.x"; // Model to load
string BIMG = "misc\\lake.bmp"; // Background image


And they are not declared as annotations, and I don't see them any where in the effect code! Can you explain me the difference here, how is the background and the kitty loaded if they are not annotations. Why aren't they annotations? Why is the texture an annotation?

I just want to add that I really hate that book :)

Thanks
Darkneon

[Edited by - Darkneon on August 3, 2005 11:35:45 PM]

Share this post


Link to post
Share on other sites
Hi there Darkneon,
How are you doing?

As far as I know Annotations are just used to add pieces of information to your effect file.
[Annotation Example]
[source lang = c++]
texture Tex0 < string name = "tiger.bmp"; >;



"The annotation is attached to the texture object and specifies the texture file that should be used to initialize the texture object"
How to retrieve it:
ID3DXEffect::GetAnnotationByName(....,"name");

[Parameter Example]
[source lang = c++]
string XFile = "tiger\\tiger.x"; // Model to load
string BIMG = "misc\\lake.bmp"; // Background image



Those are just shader level variables.
How to retrieve it:
ID3DXEffect::GetParameterByName(..., "XFile");

It explains it pretty clearly :)

Share this post


Link to post
Share on other sites
Hi Armadon again.

It's only clear once you understand it, but I think I do so now.

You cannot do this:
texture Tex0 = "tiger.bmp"; //Doesn't make sense

You can always do this:
texture Tex0;
string name = "tiger.bmp";

but using an annotation makes it more clear to read.

Now, about those two:
string XFile = "tiger\\tiger.x"; // Model to load
string BIMG = "misc\\lake.bmp"; // Background image


Here you cannot use annotation because there is no Mesh or Bitmap objects in HLSL (I'm assuming here). So you just use global (external) variables.

Cool, I got it :)

OK, I'm off learing more HLSL.
Darkneon

Share this post


Link to post
Share on other sites
Annotations can be interpreted by the host application to provide additional information what a parameter means and/or how it is used. Semantics are there for the same reason, though.

E.g., if a host application finds this parameter


texture myTex <
string filename = "mytex.dds";
>;


and it knows that the filename-annotation means "which texture to load", it can load mytex.dds and assign this texture to the myTex parameter.

Another example (using semantics)

float4x4 wvp : WORLDVIEWPROJECTION;

If the application knows the WORLDVIEWPROJECTION semantic it can assign the current world*view*projection matrix to the parameter wvp.

You can add semantics and annotations almost arbitrarily (there are some fixed semantics for shader in/output). However, to provide a nice workflow between content creation tools and the gameengine, it is usefull to have a standard set of annotations. Microsoft is working on a standard (SAS = standard annotations and semantics) to let different content creation software and engines talk with each other. Unfortunately, little information is available about these standards yet (look at "DirectX Standard Annotations and Semantics Reference" in the D3D docs). There seems to be another (older?) standard which e.g. fx composer uses. In FX Composer goto Help->Semantics & Annotations. This is a bit confusing. I cannot find much information on this topic :(

Regards,
Andre

Share this post


Link to post
Share on other sites
Is it correct to assume that in order to take advantage of these annotation, you would have to build a little parser, otherwise that kind of information will be lost.. Right?

I was wondering if anyone knows if Microsoft is working on a sort of "default parser" to be included in the D3DX library maybe..

Share this post


Link to post
Share on other sites
The effect compiler parses the fx file for you. You can access the annotations per parameter through GetAnnotation/GetAnnotationByName as mentioned above. Then use GetParameterDesc with the handle you got to get information on the annotation.

Here an example how to loop through all parameters and annotations (again C#, but you'll get the point):


// iterate through all parameters
for( int i = 0; i < fx.Description.Parameters; ++i ) {
EffectHandle handle = fx.GetParameter( null, i );
if( handle != null ) {
// get parameter description
ParameterDescription desc = fx.GetParameterDescription( handle );
Console.WriteLine( "Parameter {0}", desc.Name );

// iterate through all associated annotations
for( int a = 0; a < desc.Annotations; ++a ) {
EffectHandle anno = fx.GetAnnotation( handle, a );

// get annotation description (contains the name of the annotation)
// (left side of =)
ParameterDescription annoDesc = fx.GetParameterDescription( anno );
string value = string.Empty;

// get value of annotation (right side of =)
// this depends on the type of the annotation
switch( annoDesc.Type ) {
case ParameterType.String:
value = fx.GetValueString( anno );
break;
case ParameterType.Integer:
value = fx.GetValueInteger( anno ).ToString();
break;
case ParameterType.Float:
value = fx.GetValueFloat( anno ).ToString();
break;
case ParameterType.Boolean:
value = fx.GetValueBoolean( anno ).ToString();
break;
}
Console.WriteLine( " Annotation {0} = {1}", annoDesc.Name, value );
}
}
}



Your application has to interpret the annotation name/value pairs in any way it needs to.

Regards,
Andre

Share this post


Link to post
Share on other sites
Annotations are meta data for the shaders, read by the application.

I helped a bit in defining the dx9 .fx file format, based on my experiences doing the ShaderFX system at nvidia.

My goal was to have a way for an application to load a shader it had never seen before, and have the shader

1) work properly, with all textures, geometry, and constants set up based on what the shader wanted

or

2) fail gracefully, and tell you what its missing

So, the mesh file example isn't a realistic example for a production game. A better example would be texture info, like the format the texture is expected in, etc.

The idea is to provide info from the shader author to the application shader loader so it can determine what the shader requires. This applies to both semantics and annotations.

Additionally, the annotations provide a way to have the application put up gui elements to allow things to be artist tweakable.

Share this post


Link to post
Share on other sites
SimmerD, do you have any further information on the SAS specifications? Sorry for hijacking this thread, but that's the topic I'm busy with atm.

Regards,
Andre

Share this post


Link to post
Share on other sites
A million thanks to you centipede.

That link is great! All the examples use C# and MDX.
Now I won't be able to sleep for 3 days because I will be too busy dissecting all this . Thank you very much centipede :)

Darkneon

Share this post


Link to post
Share on other sites
Just some quick observations.

It seems that there is no GetAnnotationByName() in C#. However, the GetAnnotation(handle, name) overload seems similar. Are they indeed the same, or is C# missing something?

Also, I was looking how nVidia's programmer(s) handle this. In the following code, is it me or the annotationHandle object can never be null?


public static bool FindAnnotationString(Effect effect, EffectHandle parameterHandle, string name, ref string ret)
{
ParameterDescription paramDesc = effect.GetParameterDescription(parameterHandle);
for(int i = 0; i < paramDesc.Annotations; i++)
{
EffectHandle annotationHandle = effect.GetAnnotation(parameterHandle, i);
if (annotationHandle != null) /* <-- Here, is this possible? */
{
ParameterDescription annotationDesc = effect.GetParameterDescription(annotationHandle);
if (annotationDesc.Type == ParameterType.String &&
string.Compare(annotationDesc.Name, name, true) == 0)
{
ret = effect.GetValueString(annotationHandle);
return true;
}
}
}
return false;
}






Darkneon

Share this post


Link to post
Share on other sites
You are right, this handle should never be null because the index is always valid.

In the native COM-Version there is GetAnnotation and GetAnnotationByName. They had to choose different names because COM does not allow overloading of functions.

GetAnnotation is called by BaseEffect.GetAnnotation(EffectHandle, int),
GetAnnotationByName is called by BaseEffect.GetAnnotation(EffectHandle, string).

Nothing's missing!

Regards,
Andre

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this