directx11 计算着色器中的某些赋值将被跳过,即使稍后会使用赋值也是如此

Some of the assignment operations in the directx11 compute shader are getting skipped, even though the assigned values are used later

提问人:ThisAccountIsForGameDev 提问时间:10/28/2023 更新时间:10/28/2023 访问量:18

问:

我正在我的计算着色器上实现一种名为 Fast3x3 SVD 的算法。但是,当我在 RenderDoc 中调试我的计算着色器时,我注意到一些赋值运算符被完全跳过了。

void SortSingularValues(inout float3x3 B, inout float3x3 V)
{
    float rho1 = DistSquared(float3(B[0][0], B[1][0], B[2][0]));
    float rho2 = DistSquared(float3(B[0][1], B[1][1], B[2][1]));
    float rho3 = DistSquared(float3(B[0][2], B[1][2], B[2][2]));

    bool c = rho1 < rho2;
    float z = -B[0][0];
    B[0][0] = c ? B[0][1]: B[0][0];
    B[0][1] = c ? z : B[0][1];
    
    z = -B[1][0];
    B[1][0] = c ? B[1][1]: B[1][0];
    B[1][1] = c ? z : B[1][1];
    
    z = -B[2][0];
    B[2][0] = c ? B[2][1] : B[2][0];
    B[2][1] = c ? z : B[2][1];
    
    z = -V[0][0];
    V[0][0] = c ? V[0][1] : V[0][0];
    V[0][1] = c ? z : V[0][1];
    
    z = -V[1][0];
    V[1][0] = c ? V[1][1] : V[1][0];
    V[1][1] = c ? z : V[1][1];
    
    z = -V[2][0];
    V[2][0] = c ? V[2][1] : V[2][0];
    V[2][1] = c ? z : V[2][1];
    CondSwap(c, rho1, rho2);

    c = rho1 < rho3;
    z = -B[0][0];
    B[0][0] = c ? B[0][2] : B[0][0];
    B[0][2] = c ? z : B[0][2];
    
    z = -B[1][0];
    B[1][0] = c ? B[1][2] : B[1][0];
    B[1][2] = c ? z : B[1][2];
    
    z = -B[2][0];
    B[2][0] = c ? B[2][2] : B[2][0];
    B[2][2] = c ? z : B[2][2];
    
    z = -V[0][0];
    V[0][0] = c ? V[0][2] : V[0][0];
    V[0][2] = c ? z : V[0][2];
    
    z = -V[1][0];
    V[1][0] = c ? V[1][2] : V[1][0];
    V[1][2] = c ? z : V[1][2];
    
    z = -V[2][0];
    V[2][0] = c ? V[2][2] : V[2][0];
    V[2][2] = c ? z : V[2][2];
    CondSwap(c, rho1, rho3);

    /*-----------This is where the skipping happens!-------------------*/
    c = rho2 < rho3;
    z = -B[0][1]; // <- Skipped
    B[0][1] = c ? B[0][2] : B[0][1];
    B[0][2] = c ? z : B[0][2]; // <- Skipped
    
    z = -B[1][1]; // <- Skipped
    B[1][1] = c ? B[1][2] : B[1][1];
    B[1][2] = c ? z : B[1][2]; // <- Skipped
    
    z = -B[2][1]; // <- Skipped
    B[2][1] = c ? B[2][2] : B[2][1];
    B[2][2] = c ? z : B[2][2]; // <- Skipped
    
    //Everything else get hit from here...
    z = -V[0][1];
    V[0][1] = c ? V[0][2] : V[0][1];
    V[0][2] = c ? z : V[0][2];
    
    z = -V[1][1];
    V[1][1] = c ? V[1][2] : V[1][1];
    V[1][2] = c ? z : V[1][2];
    
    z = -V[2][1];
    V[2][1] = c ? V[2][2] : V[2][1];
    V[2][2] = c ? z : V[2][2];
}

我按如下方式调用上面的函数......

void FastSVD(in float3x3 A, out float3x3 U, out float3x3 S, out float3x3 V)
{
    float3x3 At = GetTranspose(A);
    float3x3 AtA = mul(At, A);

    float4 qV;
    qV.x = 0.0;
    qV.y = 0.0;
    qV.z = 0.0;
    qV.w = 1.0;
    JacobiEigenAnalysis(
        AtA[0][0], AtA[1][0], AtA[1][1], AtA[2][0], AtA[2][1], AtA[2][2], qV
    );
    
    V = GetMat3x3FromQuat(qV);

    float3x3 B = mul(A, V);

    SortSingularValues(V, B);
    QRDecomposition(B, U, S);
}

我什至查看了相应跳过行的反汇编代码,但它们在反汇编级别不存在。我很困惑为什么着色器编译器甚至不会为这些行生成反汇编代码......更令人困惑的是,所有代码都适用于 V 矩阵,但不适用于 B 矩阵。任何关于为什么会发生这种情况的线索将不胜感激!

DirectX-11 HLSL 计算着色器 渲染文档

评论


答: 暂无答案