Restrictions d’utilisation de l’interface

Le matériel GPU actuel ne prend pas en charge les informations d’emplacement variables au moment de l’exécution du nuanceur. Par conséquent, les références d’interface ne peuvent pas être modifiées dans une expression conditionnelle telle qu’une instruction if ou switch.

Le code de nuanceur suivant indique quand cette restriction se produira et une autre approche possible.

Compte tenu des déclarations d’interface suivantes :

interface A
{
    float GetRatio();
    bool IsGood();
};

interface B
{
    float GetValue();
};

A arrayA[6];
B arrayB[6];

Compte tenu des déclarations de classe suivantes :

class C1 : A
{
    float var;
    float GetRatio() { return 1.0f; }
    bool IsGood() { return true; }
};

class C2 : C1, B
{
    float GetRatio() { return C1::GetRatio() * 0.33f; }
    float GetValue() { return 5.0f; }
    bool IsGood() { return false; }
};

class C3 : B
{
    float var;
    float GetValue() { return -1.0f; }
};

class C4 : A, B
{
    float var;
    float GetRatio() { return var; }
    float GetValue() { return var * 2.0f; }
    bool IsGood() { return var > 0.0f; }
};

Impossible de modifier une référence d’interface dans l’expression conditionnelle (instruction if) :

float main() : wicked
{
    float rev;
    {
        A a = arrayA[0];
        for( uint i = 0; i < 6; ++i )
        {
            if( arrayA[i].IsGood() )
            {
                // This forces the loop to be unrolled, 
                // since the slot information is changing.
                a = arrayA[i]; 
                rev -= arrayA[i-2].GetRatio();
            }
            else
            {
                // This causes an error since the compiler is
                // unable to determine the interface slot
                rev += arrayB[i].GetValue() + a.GetRatio(); 
            }
        }
    }
    return rev;
}

Étant donné les mêmes déclarations d’interface et de classe, vous pouvez utiliser un index pour fournir les mêmes fonctionnalités et éviter le déroulement forcé de la boucle.

float main() : wicked
{
    float rev;
    {
        uint index = 0;
        for( uint i = 0; i < 6; ++i )
        {
            if( arrayA[i].IsGood() )
            {
                index = i;
                rev -= arrayA[i-2].GetRatio();
            }
            else
            {
                rev += arrayB[i].GetValue() + arrayA[index].GetRatio();
            }
        }
    }
    return rev;
}

Liaison dynamique