Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

#ActualHodgman

Posted 16 January 2012 - 06:30 AM

I can understand your point of view but in both cases I see some potential problems, but maybe you have a way around those.
(1) If I specify the CBuffers in the FX, how do you know what shader type and permutation actually require that particular buffer?
(2) Or, if you specify them only in the shader code, how can you ensure there will always be the ability to do reflection?

Yeah, being explicit (repeating yourself) can sometimes be a good thing. For example, it's common to have some variables that only show up when in an editor like Maya, but aren't "officially" part of the shader, so you could omit them from the [FX] part.
For (1), seeing you're writing your own syntax here, you could add a property to your FX description that explicitly states this, e.g.
cbuffer cbPerObjectVS : register( vs_b0 ){ ... };

For (2), you can write a full-blown HLSL parser yourself, and convert your HLSL source into an abstract-syntax-tree, which you can reflect over yourself. That's of course quite a bit more complex than the alternative of producing HLSL from your 'reflection' format though ;)
This is what we do at work, and the high investment cost to write your own parser/translater pays off by allowing you to use any kind of custom syntax that you like, to translate your code into multiple output languages, and to do things like converting if/for statements into permutations, etc...

I'm not sure how to specify which shader type and in what permutation actually requires a particular CBuffer so it can be inserted into the shader code and compiled. I'd probably need a more complex FX section which specifies that link/mask which is what I gather your Lua FX section does?

At the moment, my shader format at home is still fairly primitive, so I output all [fx] cbuffers into both the VS and PS. This has the effect of artificially limiting the number of constant registers available to me -- e.g. if a vertex shader cbuffer is bound to c0-c200, then those registers are unusable for ps variables for no good reason.
I'll probably remedy this by adding an explicit description like (1) above, where the [fx] section can say which shader-types should include the cbuffer (but still output the cbuffer for every permutation, for simplicity's sake)

This sort of stems from the same issue I described earlier, but in your system how do you determine what shader type a CBuffer is linked to so you can know what Set*ShaderConstantF function to call?

There's three different situations here:
1) The engine/game code is binding a known cbuffer structure -- the person writing that code can hard-code either a SetPsCBuffer/SetVsCBuffer/etc command, because they know which shader they want to set the data to.
2) The content tools are compiling an artist's material -- all shader uniforms (which have been annotated with a "should appear in DCC GUI"-type tag) are available to be set by the artists when they author a model/material. When their models are imported, the content tools will take these uniform values, and search through every cbuffer (for every shader type) for a variable who's name matches.
When a match is found, an instance of that cbuffer is instantiated (or the existing instance grabbed) and the default value is overwritten with the artist's value.
If that name only shows up in a PS cbuffer, then only a PS cbuffer will be instantiated, and only a PS binding command generated.
3) The engine/game code is binding some cbuffer values, but the structure of the cbuffer isn't hard-coded. In this case, they can use the reflection API to iterate every cbuffer for each shader type, and find which cbuffers (and shader types) contain the variable they're trying to set, and then create the appropriate buffer instances and binding commands. If this is something that was going to happen every frame, you'd instantiate the relevant cbuffers/binding commands once, and store the relevant offsets into those cbuffers where your dynamic data will be written. N.B. in most cases, use-case #1 can be used instead of this #3 use-case.

#5Hodgman

Posted 16 January 2012 - 02:39 AM

I can understand your point of view but in both cases I see some potential problems, but maybe you have a way around those.
(1) If I specify the CBuffers in the FX, how do you know what shader type and permutation actually require that particular buffer?
(2) Or, if you specify them only in the shader code, how can you ensure there will always be the ability to do reflection?

Yeah, being explicit (repeating yourself) can sometimes be a good thing. For example, it's common to have some variables that only show up when in an editor like Maya, but aren't "officially" part of the shader, so you could omit them from the [FX] part.
For (1), seeing you're writing your own syntax here, you could add a property to your FX description that explicitly states this, e.g.
cbuffer cbPerObjectVS : register( vs_b0 ){ ... };

For (2), you can write a full-blown HLSL parser yourself, and convert your HLSL source into an abstract-syntax-tree, which you can reflect over yourself. That's of course quite a bit more complex than the alternative of producing HLSL from your 'reflection' format though ;)
This is what we do at work, and the high investment cost to write your own parser/translater pays off by allowing you to use any kind of custom syntax that you like, to translate your code into multiple output languages, and to do things like converting if/for statements into permutations, etc...

I'm not sure how to specify which shader type and in what permutation actually requires a particular CBuffer so it can be inserted into the shader code and compiled. I'd probably need a more complex FX section which specifies that link/mask which is what I gather your Lua FX section does?

At the moment, my shader format at home is still fairly primitive, so I output all [fx] cbuffers into both the VS and PS. This has the effect of artificially limiting the number of constant registers available to me -- e.g. if a vertex shader cbuffer is bound to c0-c200, then those registers are unusable for ps variables for no good reason.
I'll probably remedy this by adding an explicit description like (1) above, where the [fx] section can say which shader-types should include the cbuffer (but still output the cbuffer for every permutation, for simplicity's sake)

This sort of stems from the same issue I described earlier, but in your system how do you determine what shader type a CBuffer is linked to so you can know what Set*ShaderConstantF function to call?

There's three different situations here:
1) The engine/game code is binding a known cbuffer structure -- the person writing that code can hard-code either a SetPsCBuffer/SetVsCBuffer/etc command, because they know which shader they want to set the data to.
2) The content tools are compiling an artist's material -- all shader uniforms (which have been annotated with a "should appear in DCC GUI"-type tag) are available to be set by the artists when they author a model/material. When their models are imported, the content tools will take these uniform values, and search through every cbuffer (for every shader type) for a variable who's name matches.
When a match is found, an instance of that cbuffer is instantiated (or the existing instance grabbed) and the default value is overwritten with the artist's value.
If that name only shows up in a PS cbuffer, then only a PS cbuffer will be instantiated, and only a PS binding command generated.
3) The engine/game code is binding some cbuffer values, but the structure of the cbuffer isn't hard-coded. In this case, they can use the reflection API to iterate every cbuffer for each shader type, and find which cbuffers (and shader types) contain the variable they're trying to set, and then create the appropriate buffer instances and binding commands.

#4Hodgman

Posted 16 January 2012 - 02:37 AM

I can understand your point of view but in both cases I see some potential problems, but maybe you have a way around those.
(1) If I specify the CBuffers in the FX, how do you know what shader type and permutation actually require that particular buffer?
(2) Or, if you specify them only in the shader code, how can you ensure there will always be the ability to do reflection?

Yeah, being explicit (repeating yourself) can sometimes be a good thing. For example, it's common to have some variables that only show up when in an editor like Maya, but aren't "officially" part of the shader, so you could omit them from the [FX] part.
For (1), seeing you're writing your own syntax here, you could add a property to your FX description that explicitly states this, e.g.
cbuffer cbPerObjectVS : register( vs_b0 ){ ... };

For (2), you can write a full-blown HLSL parser yourself, and convert your HLSL source into an abstract-syntax-tree, which you can reflect over yourself. That's of course quite a bit more complex than the alternative of producing HLSL from your 'reflection' format though ;)
This is what we do at work, and the high investment cost to write your own parser/translater pays off by allowing you to use any kind of custom syntax that you like, to translate your code into multiple output languages, and to do things like converting if/for statements into permutations, etc...

I'm not sure how to specify which shader type and in what permutation actually requires a particular CBuffer so it can be inserted into the shader code and compiled. I'd probably need a more complex FX section which specifies that link/mask which is what I gather your Lua FX section does?

At the moment, my shader format at home is still fairly primitive, so I output all [fx] cbuffers into both the VS and PS. This has the effect of artificially limiting the number of constant registers available to me -- e.g. if a vertex shader cbuffer is bound to c0-c200, then those registers are unusable for ps variables for no good reason.
I'll probably remedy this by adding an explicit description like (1) above, where the [fx] section can say which shader-types should include the cbuffer (but still output the cbuffer for every permutation, for simplicity's sake)

This sort of stems from the same issue I described earlier, but in your system how do you determine what shader type a CBuffer is linked to so you can know what Set*ShaderConstantF function to call?

There's three different situations here:
1) The engine/game code is binding a known cbuffer structure -- the person writing that code can hard-code either a SetPsCBuffer/SetVsCBuffer/etc command, because they know which shader they want to set the data to.
2) The content tools are compiling an artist's material -- all shader uniforms (which have been annotated with a "should appear in DCC GUI"-type tag) are available to be set by the artists when they author a model/material. When their models are imported, the content tools will take these uniform values, and search through every cbuffer (for every shader type) for a variable who's name matches.
When a match is found, an instance of that cbuffer is instantiated (or the existing instance grabbed) and the default value is overwritten with the artist's value.
If that name only shows up in a PS cbuffer, then only a PS cbuffer will be instantiated, and only a PS binding command generated.
3) The engine/game code is binding some cbuffer values, but the structure of the cbuffer isn't hard-coded. In this case, they can use the reflection API to iterate every cbuffer for each shader type, and find which cbuffers (and shader types) contain the variable they're trying to set.

#3Hodgman

Posted 16 January 2012 - 02:35 AM

I can understand your point of view but in both cases I see some potential problems, but maybe you have a way around those.
(1) If I specify the CBuffers in the FX, how do you know what shader type and permutation actually require that particular buffer?
(2) Or, if you specify them only in the shader code, how can you ensure there will always be the ability to do reflection?

Yeah, being explicit (repeating yourself) can sometimes be a good thing. For example, it's common to have some variables that only show up when in an editor like Maya, but aren't "officially" part of the shader, so you could omit them from the [FX] part.
For (1), seeing you're writing your own syntax here, you could add a property to your FX description that explicitly states this, e.g.
cbuffer cbPerObjectVS : register( vs_b0 ){ ... };

For (2), you can write a full-blown HLSL parser yourself, and convert your HLSL source into an abstract-syntax-tree, which you can reflect over yourself. That's of course quite a bit more complex than the alternative of producing HLSL from your 'reflection' format though ;)
This is what we do at work, and the high investment cost to write your own parser/translater pays off by allowing you to use any kind of custom syntax that you like, to translate your code into multiple output languages, and to do things like converting if/for statements into permutations, etc...

I'm not sure how to specify which shader type and in what permutation actually requires a particular CBuffer so it can be inserted into the shader code and compiled. I'd probably need a more complex FX section which specifies that link/mask which is what I gather your Lua FX section does?

At the moment, my shader format at home is still fairly primitive, so I output all [fx] cbuffers into both the VS and PS. This has the effect of artificially limiting the number of constant registers available to me -- e.g. if a vertex shader cbuffer is bound to c0-c200, then those registers are unusable for ps variables for no good reason.
I'll probably remedy this by adding an explicit description like (1) above, where the [fx] section can say which shader-types should include the cbuffer (but still output the cbuffer for every permutation, for simplicity's sake)

This sort of stems from the same issue I described earlier, but in your system how do you determine what shader type a CBuffer is linked to so you can know what Set*ShaderConstantF function to call?

There's three different situations here:
1) The engine/game code is binding a known cbuffer structure -- the person writing that code can hard-code either a SetPsCBuffer/SetVsCBuffer/etc command, because they know which shader they want to set the data to.
2) The content tools are compiling an artist's material -- all shader uniforms (which have been tagged as "should appear in DCC GUI") are available to be set by the artists when they author a model/material. When their models are imported, the content tools will take these uniform values, and search through every cbuffer (for every shader type) for a variable who's name matches.
When a match is found, an instance of that cbuffer is instantiated (or the existing instance grabbed) and the default value is overwritten with the artist's value.
If that name only shows up in a PS cbuffer, then only a PS cbuffer will be instantiated, and only a PS binding command generated.
3) The engine/game code is binding some cbuffer values, but the structure of the cbuffer isn't hard-coded. In this case, they can use the reflection API to iterate every cbuffer for each shader type, and find which cbuffers (and shader types) contain the variable they're trying to set.

#2Hodgman

Posted 16 January 2012 - 02:33 AM

I can understand your point of view but in both cases I see some potential problems, but maybe you have a way around those.
(1) If I specify the CBuffers in the FX, how do you know what shader type and permutation actually require that particular buffer?
(2) Or, if you specify them only in the shader code, how can you ensure there will always be the ability to do reflection?

Yeah, being explicit (repeating yourself) can sometimes be a good thing. For example, it's common to have some variables that only show up when in an editor like Maya, but aren't "officially" part of the shader, so you could omit them from the [FX] part.
For (1), seeing you're writing your own syntax here, you could add a property to your FX description that explicitly states this, e.g.
cbuffer cbPerObjectVS : register( vs_b0 ){ ... };

For (2), you can write a full-blown HLSL parser yourself, and convert your HLSL source into an abstract-syntax-tree, which you can reflect over yourself. That's of course quite a bit more complex than the alternative of producing HLSL from your 'reflection' format though ;)
This is what we do at work, and the high investment cost to write your own parser/translater pays off by allowing you to use any kind of custom syntax that you like, to translate your code into multiple output languages, and to do things like converting if/for statements into permutations, etc...

I'm not sure how to specify which shader type and in what permutation actually requires a particular CBuffer so it can be inserted into the shader code and compiled. I'd probably need a more complex FX section which specifies that link/mask which is what I gather your Lua FX section does?

At the moment, my shader format at home is still fairly primitive, so I output all [fx] cbuffers into both the VS and PS. This has the effect of artificially limiting the number of constant registers available to me -- e.g. if a vertex shader cbuffer is bound to c0-c200, then those registers are unusable for ps variables for no good reason.
I'll probably remedy this by adding an explicit description like above, where the [fx] section can say which shader-types should include the cbuffer.

This sort of stems from the same issue I described earlier, but in your system how do you determine what shader type a CBuffer is linked to so you can know what Set*ShaderConstantF function to call?

There's three different situations here:
1) The engine/game code is binding a known cbuffer structure -- the person writing that code can hard-code either a SetPsCBuffer/SetVsCBuffer/etc command, because they know which shader they want to set the data to.
2) The content tools are compiling an artist's material -- all shader uniforms (which have been tagged as "should appear in DCC GUI") are available to be set by the artists when they author a model/material. When their models are imported, the content tools will take these uniform values, and search through every cbuffer (for every shader type) for a variable who's name matches.
When a match is found, an instance of that cbuffer is instantiated (or the existing instance grabbed) and the default value is overwritten with the artist's value.
If that name only shows up in a PS cbuffer, then only a PS cbuffer will be instantiated, and only a PS binding command generated.
3) The engine/game code is binding some cbuffer values, but the structure of the cbuffer isn't hard-coded. In this case, they can use the reflection API to iterate every cbuffer for each shader type, and find which cbuffers (and shader types) contain the variable they're trying to set.

#1Hodgman

Posted 16 January 2012 - 02:28 AM

I can understand your point of view but in both cases I see some potential problems, but maybe you have a way around those.
(1) If I specify the CBuffers in the FX, how do you know what shader type and permutation actually require that particular buffer?
(2) Or, if you specify them only in the shader code, how can you ensure there will always be the ability to do reflection?

Yeah, being explicit (repeating yourself) can sometimes be a good thing. For example, it's common to have some variables that only show up when in an editor like Maya, but aren't "officially" part of the shader, so you could omit them from the [FX] part.
For (1), seeing you're writing your own syntax here, you could add a property to your FX description that explicitly states this, e.g.
cbuffer cbPerObjectVS : register( vs_b0 ){ ... };

For (2), you can write a full-blown HLSL parser yourself, and convert your HLSL source into an abstract-syntax-tree, which you can reflect over yourself. That's quite a bit more complex than the alternative of producing HLSL from your 'reflection' format though ;)

I'm not sure how to specify which shader type and in what permutation actually requires a particular CBuffer so it can be inserted into the shader code and compiled. I'd probably need a more complex FX section which specifies that link/mask which is what I gather your Lua FX section does?

At the moment, my shader format at home is still fairly primitive, so I output all [fx] cbuffers into both the VS and PS. This has the effect of artificially limiting the number of constant registers available to me -- e.g. if a vertex shader cbuffer is bound to c0-c200, then those registers are unusable for ps variables for no good reason.
I'll probably remedy this by adding an explicit description like above, where the [fx] section can say which shader-types should include the cbuffer.

This sort of stems from the same issue I described earlier, but in your system how do you determine what shader type a CBuffer is linked to so you can know what Set*ShaderConstantF function to call?

There's three different situations here:
1) The engine/game code is binding a known cbuffer structure -- the person writing that code can hard-code either a SetPsCBuffer/SetVsCBuffer/etc command, because they know which shader they want to set the data to.
2) The content tools are compiling an artist's material -- all shader uniforms (which have been tagged as "should appear in DCC GUI") are available to be set by the artists when they author a model/material. When their models are imported, the content tools will take these uniform values, and search through every cbuffer (for every shader type) for a variable who's name matches.
When a match is found, an instance of that cbuffer is instantiated (or the existing instance grabbed) and the default value is overwritten with the artist's value.
If that name only shows up in a PS cbuffer, then only a PS cbuffer will be instantiated, and only a PS binding command generated.
3) The engine/game code is binding some cbuffer values, but the structure of the cbuffer isn't hard-coded. In this case, they can use the reflection API to iterate every cbuffer for each shader type, and find which cbuffers (and shader types) contain the variable they're trying to set.

PARTNERS