src/ComputeSharp.Shaders/ShaderRunner{T}.cs
/// <summary>
/// Compiles and runs the input shader on a target <see cref="GraphicsDevice"/> instance, with the specified parameters
/// </summary>
/// <param name="device">The <see cref="GraphicsDevice"/> to use to run the shader</param>
/// <param name="x">The number of iterations to run on the X axis</param>
/// <param name="y">The number of iterations to run on the Y axis</param>
/// <param name="z">The number of iterations to run on the Z axis</param>
/// <param name="threadsX">The number of threads in each thread group for the X axis</param>
/// <param name="threadsY">The number of threads in each thread group for the Y axis</param>
/// <param name="threadsZ">The number of threads in each thread group for the Z axis</param>
/// <param name="shader">The input <typeparamref name="T"/> instance representing the compute shader to run</param>
Compiles and runs the input shader on a target  instance, with the specified parameters
Compiles and runs the input shader on a target instance with the specified parameters
public static void Run(
            GraphicsDevice device,
            int x, int y, int z,
            int threadsX, int threadsY, int threadsZ,
            in T shader)
        {
            CachedShader<T> shaderData;
            lock (ShadersCache)
            {
                var key = new ShaderKey(ShaderHashCodeProvider.GetHashCode(shader), threadsX, threadsY, threadsZ);
                if (!ShadersCache.TryGetValue(key, out shaderData))
                {
                    ShaderLoader<T> shaderLoader = ShaderLoader<T>.Load(shader);
                    ShaderInfo shaderInfo = new ShaderInfo
                    {
                        BuffersList = shaderLoader.BuffersList,
                        FieldsList = shaderLoader.FieldsList,
                        NumThreadsX = threadsX,
                        NumThreadsY = threadsY,
                        NumThreadsZ = threadsZ,
                        ThreadsIdsVariableName = shaderLoader.ThreadsIdsVariableName,
                        ShaderBody = shaderLoader.MethodBody,
                        FunctionsList = shaderLoader.FunctionsList,
                        LocalFunctionsList = shaderLoader.LocalFunctionsList
                    };
                    string shaderSource = ShaderRenderer.Instance.Render(shaderInfo);
                    ShaderBytecode shaderBytecode = ShaderCompiler.CompileShader(shaderSource);
                    ShadersCache.GetOrAddValueRef(key) = shaderData = new CachedShader<T>(shaderLoader, shaderBytecode);
                }
            }
            VersionedRootSignatureDescription rootSignatureDescription = new VersionedRootSignatureDescription(new RootSignatureDescription1(RootSignatureFlags.None, shaderData.Loader.RootParameters));
            ID3D12RootSignature rootSignature = device.CreateRootSignature(rootSignatureDescription);
            PipelineState pipelineState = new PipelineState(device, rootSignature, shaderData.Bytecode);
            using CommandList commandList = new CommandList(device, CommandListType.Compute);
            commandList.SetPipelineState(pipelineState);
            using DispatchData dispatchData = shaderData.Loader.GetDispatchData(shader, x, y, z);
            Span<GraphicsResource> resources = dispatchData.Resources;
            for (int i = 0; i < resources.Length; i++)
            {
                commandList.SetComputeRootDescriptorTable(i + 1, resources[i]);
            }
            Span<Int4> variables = dispatchData.Variables;
            using GraphicsResource variablesBuffer = device.AllocateConstantBuffer(variables);
            commandList.SetComputeRootDescriptorTable(0, variablesBuffer);
            int
                groupsX = x / threadsX + (x % threadsX == 0 ? 0 : 1),
                groupsY = y / threadsY + (y % threadsY == 0 ? 0 : 1),
                groupsZ = z / threadsZ + (z % threadsZ == 0 ? 0 : 1);
            commandList.Dispatch(groupsX, groupsY, groupsZ);
            commandList.ExecuteAndWaitForCompletion();
        }
public static void Run ( GraphicsDevice device , int x , int y , int z , int threadsX , int threadsY , int threadsZ , in T shader ) { CachedShader < T > shaderData ; lock ( ShadersCache ) { var key = new ShaderKey ( ShaderHashCodeProvider . GetHashCode ( shader ) , threadsX , threadsY , threadsZ ) ; if ( ! ShadersCache . TryGetValue ( key , out shaderData ) ) { ShaderLoader < T > shaderLoader = ShaderLoader < T > . Load ( shader ) ; ShaderInfo shaderInfo = new ShaderInfo { BuffersList = shaderLoader . BuffersList , FieldsList = shaderLoader . FieldsList , NumThreadsX = threadsX , NumThreadsY = threadsY , NumThreadsZ = threadsZ , ThreadsIdsVariableName = shaderLoader . ThreadsIdsVariableName , ShaderBody = shaderLoader . MethodBody , FunctionsList = shaderLoader . FunctionsList , LocalFunctionsList = shaderLoader . LocalFunctionsList } ; string shaderSource = ShaderRenderer . Instance . Render ( shaderInfo ) ; ShaderBytecode shaderBytecode = ShaderCompiler . CompileShader ( shaderSource ) ; ShadersCache . GetOrAddValueRef ( key ) = shaderData = new CachedShader < T > ( shaderLoader , shaderBytecode ) ; } } VersionedRootSignatureDescription rootSignatureDescription = new VersionedRootSignatureDescription ( new RootSignatureDescription1 ( RootSignatureFlags . None , shaderData . Loader . RootParameters ) ) ; ID3D12RootSignature rootSignature = device . CreateRootSignature ( rootSignatureDescription ) ; PipelineState pipelineState = new PipelineState ( device , rootSignature , shaderData . Bytecode ) ; using CommandList commandList = new CommandList ( device , CommandListType . Compute ) ; commandList . SetPipelineState ( pipelineState ) ; using DispatchData dispatchData = shaderData . Loader . GetDispatchData ( shader , x , y , z ) ; Span < GraphicsResource > resources = dispatchData . Resources ; for ( int i = 0 ; i < resources . Length ; i ++ ) { commandList . SetComputeRootDescriptorTable ( i + 1 , resources [ i ] ) ; } Span < Int4 > variables = dispatchData . Variables ; using GraphicsResource variablesBuffer = device . AllocateConstantBuffer ( variables ) ; commandList . SetComputeRootDescriptorTable ( 0 , variablesBuffer ) ; int groupsX = x / threadsX + ( x % threadsX == 0 ? 0 : 1 ) , groupsY = y / threadsY + ( y % threadsY == 0 ? 0 : 1 ) , groupsZ = z / threadsZ + ( z % threadsZ == 0 ? 0 : 1 ) ; commandList . Dispatch ( groupsX , groupsY , groupsZ ) ; commandList . ExecuteAndWaitForCompletion ( ) ; }
Compiles and runs the input shader on a target  instance, with the specified parameters
Compiles and runs the input shader on a target instance with the specified parameters
// Try to get the cache shader // Load the input shader // Render the loaded shader // Compile the loaded shader to HLSL bytecode // Cache for later use // Create the root signature for the pipeline and get the pipeline state // Create the commands list and set the pipeline state // Extract the dispatch data for the shader invocation // Load the captured buffers // Initialize the loop targets // Calculate the dispatch values // Dispatch and wait for completion
device
GraphicsDevice
The  to use to run the shader
The to use to run the shader
x
int
The number of iterations to run on the X axis
The number of iterations to run on the X axis
y
int
The number of iterations to run on the Y axis
The number of iterations to run on the Y axis
z
int
The number of iterations to run on the Z axis
The number of iterations to run on the Z axis
threadsX
int
The number of threads in each thread group for the X axis
The number of threads in each thread group for the X axis
threadsY
int
The number of threads in each thread group for the Y axis
The number of threads in each thread group for the Y axis
threadsZ
int
The number of threads in each thread group for the Z axis
The number of threads in each thread group for the Z axis
T
in
shader
The input  instance representing the compute shader to run
The input instance representing the compute shader to run