HLSL: receiving a handle to a struct

Hi! I'm having trouble receiving a handle to a structure in a hlsl file.

This is the structure:

struct VS_SIMPLE_INPUT

{

float4 pos : POSITION;

float3 normal : NORMAL;

};

And I try to receive the handle like this:

pEffect->GetParameterByName( NULL, "VS_SIMPLE_INPUT" );

It doesn't work, I get a NULL ptr. Can anybody help me



Answer this question

HLSL: receiving a handle to a struct

  • e-u-l-o-g-y

    Does anybody know how to receive the shader function pointer needed for D3DXGetShaderInputSemantics(CONST DWORD* pFunction, ...)

    I tried using effect->GetVertexShader( D3DXHANDLE hParameter, LPDIRECT3DVERTEXSHADER9* ppVShader ), but I haven't succeeded getting the necessary handle of the shader function. Or isn't "hParameter" the handle of the shader function

    Or do I have to compile the effect using ID3DXEffectCompiler->CompileShader() But then again, what handle to pass in


  • Vorn

    Yesterday I found this function...maybe this could help

    Use D3DXGetShaderInputSemantics to return a list of input semantics required by the shader. This is the way to find out what the input vertex format is for a high-level shader language (HLSL) shader. If the shader has additional inputs that your vertex declaration is missing, you could create an extra vertex stream that has a stride of 0 that has the missing components with default values. For instance, this technique could be used to provide default vertex color for models that do not specify it.

    http://msdn.microsoft.com/library/default.asp url=/library/en-us/directx9_c/D3DXGetShaderInputSemantics.asp


  • stevencbk

    The problem is that you have only defined a struct type, which can then be used to define variables or parameters to functions. You need to define a global variable, which you will then be able to access as an effect parameter. For example, follow up that code in the effect file with:

    VS_SIMPLE_INPUT myStruct;

    You should then be able to access the parameter like this:

    DXHANDLE structHandle=pEffect->GetParameterByName(NULL,"myStruct");

    From that point, you can get a description of the parameter like this:

    D3DXPARAMTER_DESC structDesc;
    pEffect->GetParameterDesc(structHandle,&structDesc);

    There are a couple of elements in the description that will help you further evaluate the structure. First, you can verify that the parameter is indeed a structure by checking that structDesc.Class is equal to D3DXPC_STRUCT. You can then check the structDesc.StructMembers to find out how many members there are, and then retrieve these and get their individual descriptions as well:

    if (structDesc.Class==D3DXPC_STRUCT&&structDesc.StructMembers>0) {
    for (int i=0;i<structDesc.StructMemebers;i++) {
    D3DXHANDLE memberHandle=pEffect->GetParameterElement(structHandle,i);
    if (memberHandle) {
    D3DXPARAMETER_DESC memberDesc;
    pEffect->GetParameterDesc(memberHandle,&memberDesc);
    // process member information.....
    }
    }
    }

    Robert Dunlop
    Microsoft DirectX MVP
    www.directxzone.org


  • syedasad

    Thanks Robert and Etienne!

    I had the same idea Robert suggests, but declaring a variable which isn't actually used in the shader seems a bit like a workaround though.

    Using D3DXGetShaderInputSemantics seems a good way to do what I like to do, but only the USAGE type and index for each vertex element is received. So I need to use a fixed vertex element size for each semantic. Will think about it... ;-)


  • Dedy Susanto

    Well, I just noted it seems not possible what I'm trying to do. A handle to a structure seems not possible.

    What I'm trying to do is to receive information about a vertex shader input structure from the fx file, to automatically create a fitting vertex declaration. But right now I don't see a way of getting the necessary information from the fx file. Any ideas


  • B-RETT

    fx file are what the programmer use to make sure it can make an effect and have many fallback technique in case the hardware of the client don't support all possibility

    fx file is known to the programmer it's not a document that you read
    you would know what parameters to send

    But if you still want to read it like you didn't know what's in it

    you can try to find the source code of the Mesh Viewer in the SDK and see how they managed to read this

    I think the new mesh viewer can read this info (not sure)
    it's in the utility directory, it's not a sample

    Mesh viewer who are design to read fx that they don't know will use SAS to connect
    the parameters, that don't include the Vertex Buffer format...but all other variables are in SAS format so the viewer can connect to them





  • TheRealTaz

    Are you by any chance using the D3DXFX_NOT_CLONEABLE flag when loading your effect According to the docs for this flag, it will cause the effect object not to store a local copy of the effect function, in order to save memory (about 50% of the effect object's usage, according to docs). In this case, null pointers will be returned for both the vertex and pixel shaders when retrieving the description of a pass.

    Robert Dunlop
    Microsoft DirectX MVP
    www.directxzone.com


  • john_jps

    Well, the first suggestion works, but using GetPassDesc() which is more handy doesn't.

    This is my code using GetPassDesc() :

    D3DXHANDLE hPass = pEffect->GetPassByName( hTechnique, strPassName );

    D3DXPASS_DESC desc;

    pEffect->GetPassDesc( hPass, &desc );

    D3DXSEMANTIC semantics[MAXD3DDECLLENGTH];

    UINT semanticsCount;

    D3DXGetShaderInputSemantics( desc.pVertexShaderFunction, semantics, &semanticsCount );

    desc.pVertexShaderFunction and desc.pPixelShaderFunction are simply not set.

     

    Just in case anybody will try the same some time, here the working implementation of Robert's first idea:

    IDirect3DDevice9* pD3DDevice = DXUTGetD3DDevice();

    IDirect3DVertexShader9* pVS;

    UINT cPasses;

    pEffect->SetTechnique( hTechnique );

    pEffect->Begin( &cPasses, 0 );

    pEffect->BeginPass( 0 );

    pD3DDevice->GetVertexShader( &pVS );

    pEffect->EndPass();

    pEffect->End();

    UINT shaderSize;

    pVS->GetFunction( NULL, &shaderSize );

    BYTE* shaderFunc = new BYTE[shaderSize];

    pVS->GetFunction( shaderFunc, &shaderSize );

    D3DXGetShaderInputSemantics( (DWORD*)shaderFunc, semantics, &semanticsCount );

    delete [] shaderFunc;

    pVS->Release();

    Noteworthy is that vertex elements which are specified in the HLSL vs input struct but which are not used inside the shader are not added to the semantics array. Which is logical actually, because D3DXGetShaderInputSemantics works on the compiled shaders. Anyway it confused me at first... ;-)


  • TCVMZhen

    Thanks! :) Will try that.
  • Snyper_10

    I'm not sure what handle it is looking for there, the docs aren't real specific are they I can see a couple of other ways to get to the array of DWORD tokens for the shaders, though:

    1. If you are executing an effect pass, you could call the device's GetPixelShader function to get a pointer to the pixel shader interface, then use the shader's GetFunction method to get the DWORD*. When done with the pixel shader interface be sure to release it.
    2. Get the handle of a pass and call the effect's GetPassDesc using this handle to fill a D3DXPASS_DESC structure, which will have the DWORD* pointers for both the pixel and vertex shader usesd in that pass.

    Robert Dunlop
    Microsoft DirectX MVP
    www.directxzone.org


  • R3dD0g

    Thanks! Probably that was the problem because I was using D3DXFX_NOT_CLONEABLE. I will test.
  • Rob Sherrard

    Thanks for your idea with the mesh viewer, I will have a look into it! ;-)

    The reason for reading the vertex format is simply convenience. I don't like to always have to manually type in the vertex format structure whenever I use a new shader with different parameters. Also I don't like all these structures "hang around" in my code.. ;-).

    I don't really get what you mean with your SAS comment. AFAIK SAS is a standardized way of doing annotations in fx files. But a vertex format struct cannot be annotated, only techniques, passes and top level parameters...

    So maybe I could also put the vertex info in a big annotation to the technique. But that is probably not a nice solution, because that would involve typing in detailed annotation which will mess up the fx file.


  • HLSL: receiving a handle to a struct