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

SPIR-V: Support new SM6.0 Wave ops.. #645

Closed
oscarbg opened this issue Sep 23, 2017 · 7 comments
Closed

SPIR-V: Support new SM6.0 Wave ops.. #645

oscarbg opened this issue Sep 23, 2017 · 7 comments
Assignees
Labels
spirv Work related to SPIR-V

Comments

@oscarbg
Copy link

oscarbg commented Sep 23, 2017

compling wave.hlsl to SPIR-V of this sample:

https://github.com/Microsoft/DirectX-Graphics-Samples/tree/master/Samples/Desktop/D3D12SM6WaveIntrinsics
dxc /D_WAVE_OP /Zi /E"PSMain" /Vn"g_Wave_PS" /Tps_6_0 /Fh"wave_ps.hlsl.h" /nologo wave.hlsl -spirv

fails with (removing duplicated errors):

error: Intrinsic function 'WaveGetLaneIndex' not yet implemented.
error: Intrinsic function 'WaveIsFirstLane' not yet implemented.
error: Intrinsic function 'WaveActiveMax' not yet implemented.
error: Intrinsic function 'WaveActiveBallot' not yet implemented.
error: Intrinsic function 'countbits' not yet implemented.
error: Intrinsic function 'WaveReadLaneFirst' not yet implemented.
error: Intrinsic function 'WaveActiveSum' not yet implemented.
error: Intrinsic function 'WavePrefixSum' not yet implemented.
error: Intrinsic function 'QuadReadAcrossX' not yet implemented.
error: Intrinsic function 'QuadReadAcrossY' not yet implemented.
error: Intrinsic function 'smoothstep' not yet implemented.
@oscarbg
Copy link
Author

oscarbg commented Sep 23, 2017

forgot that should be mappable to SPV_KHR_shader_ballot && others may need SPV_AMD_shader_ballot..
AMD provides mapping table here:
https://gpuopen.com/gcn-shader-extensions-for-direct3d-and-vulkan/

@antiagainst
Copy link
Contributor

Thanks for reporting! Yes, supporting wave ops is planned.

@antiagainst antiagainst self-assigned this Jan 5, 2018
@antiagainst
Copy link
Contributor

#1118 implements support for SM 6.0 wave ops.

@oscarbg
Copy link
Author

oscarbg commented Mar 11, 2018

Hi @antiagainst,
good news!
unfortunately I must be in bad luck because testing the original wave.hlsl (I put below)
and used minimum arguments I see no output:
dxc /E"PSMain" /Tps_6_0 wave2.hlsl -spirv
I even run with -O0 -Vd
dxc /E"PSMain" /Tps_6_0 wave2.hlsl -spirv -O0 -Vd
(I use both -O0 -Vd to disable optimizations and SPIR-V validation which seemed to help with SPIRV-Tools bugs in my min16float test which any way should have been fixed by now)..

I tested both builds of the pull request:
https://ci.appveyor.com/project/marcelolr/directxshadercompiler/build/1.0.2032
https://ci.appveyor.com/project/marcelolr/directxshadercompiler/build/1.0.2037
maybe because this builds still not include updated SPIRV 1.3 tools ([spirv] Refresh external projects for SPIR-V 1.3 pull request)?

thanks..

/*
*  Note that SM6 is not supported in the integrated shader compiling functionality in Viusal Studio 2017.
*  In the VS project file, we specify the shaders will be built via a custom build script, CompileShader_SM6.bat.
*  Please refer to CompileShader_SM6.bat to see compiling commands. 
*  
*  You may need to modify the SDK paths in CompileShader_SM6.bat to match the installed SDK. By default the path is pointing to 15063 SDK.
*/

cbuffer SceneConstantBuffer : register(b0)
{
    float4x4 orthProjMatrix;
    float2 mousePosition;
    float2 resolution;
    float time;
    uint renderMode;
    uint laneSize;
    uint padding;
};

struct PSInput
{
	float4 position : SV_POSITION;
	float4 color : COLOR;
};

PSInput VSMain(float4 position : POSITION, float4 color : COLOR)
{
	PSInput result;

	result.position = mul(position, orthProjMatrix);
	result.color = color;

	return result;
}


// use this to generate grid-like texture
float texPattern(float2 position)
{
    float scale = 0.13;
    float t = sin(position.x * scale) + cos(position.y * scale);
    float c = smoothstep(0.0, 0.2, t*t);
    
    return c;
}


float4 PSMain(PSInput input) : SV_TARGET
{
    float4 outputColor;

    // Add grid-like texture pattern on top of the color
    float texP = texPattern(input.position.xy );
    outputColor = texP * input.color;

    switch (renderMode)
    {
        case 1:
        {
            // Just pass through the color we generate before
            break;
        }
        case 2:
        {
            // Example of query intrinsics: WaveGetLaneIndex
            // Gradiently color the wave block by their lane id. Black for the smallest lane id and White for the largest lane id.
            outputColor = WaveGetLaneIndex() / float(laneSize);
            break;
        }
        case 3:
        {
            // Example of query intrinsics: WaveIsFirstLane
            // Mark the first lane as white pixel
            if (WaveIsFirstLane())
                outputColor = float4(1., 1., 1., 1.);
            break;
        }
        case 4:
        {
            // Example of query intrinsics: WaveIsFirstLane
            // Mark the first active lane as white pixel. Mark the last active lane as red pixel.
            if (WaveIsFirstLane())
                outputColor = float4(1., 1., 1., 1.);
            if (WaveGetLaneIndex() == WaveActiveMax(WaveGetLaneIndex()))
                outputColor = float4(1., 0., 0., 1.);
            break;
        }
        case 5:
        {
            // Example of vote intrinsics: WaveActiveBallot
            // Active lanes ratios (# of total activelanes / # of total lanes).
            uint4 activeLaneMask = WaveActiveBallot(true);
            uint numActiveLanes = countbits(activeLaneMask.x) + countbits(activeLaneMask.y) + countbits(activeLaneMask.z) + countbits(activeLaneMask.w);
            float activeRatio = (float)numActiveLanes / float(laneSize);
            outputColor = float4(activeRatio, activeRatio, activeRatio, 1.0);
            break;
        }
        case 6:
        {
            // Example of wave broadcast intrinsics: WaveReadLaneFirst
            // Broadcast the color in first lan to the wave.
            outputColor = WaveReadLaneFirst(outputColor);
            break;
        }

        case 7:
        {
            // Example of wave reduction intrinsics: WaveActiveSum
            // Paint the wave with the averaged color inside the wave.
            uint4 activeLaneMask = WaveActiveBallot(true);
            uint numActiveLanes = countbits(activeLaneMask.x) + countbits(activeLaneMask.y) + countbits(activeLaneMask.z) + countbits(activeLaneMask.w);
            float4 avgColor = WaveActiveSum(outputColor) / float(numActiveLanes);
            outputColor = avgColor;
            break;
        }

        case 8:
        {
            // Example of wave scan intrinsics: WavePrefixSum
            // First, compute the prefix sum of distance each lane to first lane.
            // Then, use the prefix sum value to color each pixel.
            float4 basePos = WaveReadLaneFirst(input.position);
            float4 prefixSumPos = WavePrefixSum(input.position - basePos);
            
            // Get the number of total active lanes.
            uint4 activeLaneMask = WaveActiveBallot(true);
            uint numActiveLanes = countbits(activeLaneMask.x) + countbits(activeLaneMask.y) + countbits(activeLaneMask.z) + countbits(activeLaneMask.w);
            
            outputColor = prefixSumPos/numActiveLanes;

            break;
        }

        case 9:
        {
            // Example of Quad-Wide shuffle intrinsics: QuadReadAcrossX and QuadReadAcrossY
            // Color pixels based on their quad id:
            //  q0 -> red
            //  q1 -> green
            //  q2 -> blue
            //  q3 -> white
            //
            //   -------------> x
            //  |   [0] [1]
            //  |   [2] [3]
            //  V
            //  Y
            //
            float dx = QuadReadAcrossX(input.position.x)-input.position.x;
            float dy = QuadReadAcrossY(input.position.y)-input.position.y;

            
            // q0
            if (dx > 0 && dy > 0)
                outputColor = float4(1, 0, 0, 1);
            // q1
            else if (dx <0 && dy > 0)
                outputColor = float4(0, 1, 0, 1);
            // q2
            else if (dx > 0 && dy < 0)
                outputColor = float4(0, 0, 1, 1);
            // q3
            else if (dx < 0 && dy < 0)
                outputColor = float4(1, 1, 1, 1);
            else
                outputColor = float4(0, 0, 0, 1);

            break;
        }

        default:
        {
            break;
        }
    }
    
    return outputColor;
}

@antiagainst
Copy link
Contributor

@oscarbg: Thanks for testing it out! Yes, you are right. There was a bug in semantic duplication check. I've pushed a new commit (4d14835) into #1118 to fix it. Tested that the above code can compile successfully with the fix.

@oscarbg
Copy link
Author

oscarbg commented Mar 12, 2018

thanks @antiagainst,
now looks good!

@antiagainst
Copy link
Contributor

#1118 is landed. I'll close this.

@antiagainst antiagainst added the spirv Work related to SPIR-V label Mar 17, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
spirv Work related to SPIR-V
Projects
None yet
Development

No branches or pull requests

2 participants