Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrect GLSL logic about the reuse variables and countbits function #50

Open
xlincuts opened this issue Dec 29, 2020 · 0 comments
Open

Comments

@xlincuts
Copy link

Hi,

I found 2 issues in the generated GLSL logic

The HLSL source:

cbuffer csInput_CB : register(b0)
{
    uint g_MaskDefault;
    uint g_MaskX;
    uint g_MaskY;
};

RWBuffer<uint> csOutput : register(u0);
// ------------------------------------------------------------------------------

void CalculateMask(inout uint mask, in uint index, in uint maskComponent)
{
    uint curBit = 1;
    mask = g_MaskDefault;

    [loop]
    for (uint i = 0; i < index; ++i)
    {
        [flatten]
        if ((index & 1) && (maskComponent & 1))
        {
            mask = curBit;
            break;
        }
        curBit <<= 1;
    }
}

// ------------------------------------------------------------------------------
[numthreads(1, 1, 1)]
void main(uint3 threadID : SV_DispatchThreadID)
{
    uint2 masks = 0;
    uint outputOffset = (threadID.x << 1);
    uint checkIndex = threadID.x + 1;

    CalculateMask(masks.x, checkIndex, g_MaskX);
    CalculateMask(masks.y, checkIndex, g_MaskY);

    uint count = countbits(masks.x) + countbits(masks.y);

    if (count > 0)
    {
        csOutput[outputOffset + 0] = masks.x;
        csOutput[outputOffset + 1] = masks.y;
    }
}

The generated GLSL source:

#version 430
#extension GL_ARB_shading_language_420pack : require

layout(location = 0) uniform 	uint g_MaskDefault;
uniform 	uint g_MaskX;
uniform 	uint g_MaskY;
writeonly layout(binding=0) uniform uimageBuffer csOutput;
ivec3 u_xlati0;
uint u_xlatu0;
uint u_xlatu1;
ivec3 u_xlati2;
uvec3 u_xlatu2;
bvec3 u_xlatb2;
uint u_xlatu3;
int u_xlati4;
int u_xlati5;
uint u_xlatu5;
bool u_xlatb5;
layout(local_size_x = 1, local_size_y = 1, local_size_z = 1) in;
void main()
{
    u_xlatu0 = gl_GlobalInvocationID.x + 1u;
    u_xlati2.x = int(u_xlatu0 & 1u);
    u_xlati2.yz = ivec2(csInput_CBCS.uvec2(g_MaskX, g_MaskY) & uvec2(1u, 1u));
    u_xlatb2.xyz = notEqual(u_xlati2.xyzz, ivec4(0, 0, 0, 0)).xyz;
    u_xlatb2.x = u_xlatb2.y && u_xlatb2.x; 
    u_xlatb2.y = u_xlatb2.z && u_xlatb2.x;Incorrect
    u_xlatu2.z = csInput_CBCS.g_MaskDefault;
    u_xlatu1 = uint(1u);
    for(uint u_xlatu_loop_1 = uint(0u) ; u_xlatu_loop_1<u_xlatu0 ; u_xlatu_loop_1++)
    {
        u_xlatu5 = (u_xlatb2.x) ? u_xlatu1 : u_xlatu2.z;
        u_xlatu2.z = u_xlatu5;
        u_xlati5 = int(u_xlatb2.x);
        if(u_xlati5 != 0) {break;}
        u_xlatu1 = u_xlatu1 << 1u;
    }
    u_xlatu2.x = csInput_CBCS.g_MaskDefault;
    u_xlatu1 = uint(1u);
    for(uint u_xlatu_loop_2 = uint(0u) ; u_xlatu_loop_2<u_xlatu0 ; u_xlatu_loop_2++)
    {
        u_xlatu5 = (u_xlatb2.y) ? u_xlatu1 : u_xlatu2.x;
        u_xlatu2.x = u_xlatu5;
        u_xlati5 = int(u_xlatb2.y);
        if(u_xlati5 != 0) {break;}
        u_xlatu1 = u_xlatu1 << 1u;
    }
    u_xlati0.xz = bitCount(ivec4(u_xlatu2.zzxz));
    u_xlati0.x = u_xlati0.z + u_xlati0.x;
    if(u_xlati0.x != 0) {
        u_xlati0.x = int(gl_GlobalInvocationID.x) << 1;
        imageStore(csOutput, u_xlati0.x, u_xlatu2.zzzz);
        u_xlati4 = int(gl_GlobalInvocationID.x) * 2 + 1;
        imageStore(csOutput, int(u_xlati4), u_xlatu2.xxxx);
    //ENDIF
    }
    return;
}

Issue1: Incorrect reuse variables

'u_xlatb2.y' will get an incorrect result, as 'u_xlatb2.x' in the previous step has been changed.
So the next logics which're using 'x_xlatb2.y', will get the error results

u_xlatu0 = gl_GlobalInvocationID.x + 1u; // u_xlatu0 --> checkIndex (in HLSL)
u_xlatb2.xyz = notEqual(u_xlati2.xyzz, ivec4(0, 0, 0, 0)).xyz; //  x --> (checkIndex&1), y --> (g_MaskX&1), z --> (g_MaskY&1)
u_xlatb2.x = u_xlatb2.y && u_xlatb2.x;  // u_xlatb2.x --> (checkIndex&1) && (g_MaskX&1)
u_xlatb2.y = u_xlatb2.z && u_xlatb2.x; // Error: u_xlatb2.y --> (checkIndex&1) && (g_MaskX&1) && (g_MaskY&1),
                                       // it should be (checkIndex&1) && (g_MaskY&1)

Issue2: countbits function convert

The bitCount argument is incorrect, when 'z' is 0 and 'x' greater 0, the 'u_xlati0' will get an incorrect result.

u_xlati0.xz = bitCount(ivec4(u_xlatu2.zzxz));

For the detail compilation information, please check Here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant