public static void ShaderSetAutoDiscovery()
        {
            ToolChain toolChain = ToolChain.Get(ToolFeatures.ToCompiled);

            if (toolChain == null)
            {
                throw new RequiredToolFeatureMissingException("No tool chain supporting compilation was found!");
            }

            Compilation                        compilation      = TestUtil.GetCompilation();
            LanguageBackend                    backend          = toolChain.CreateBackend(compilation);
            ShaderGenerator                    sg               = new ShaderGenerator(compilation, backend);
            ShaderGenerationResult             generationResult = sg.GenerateShaders();
            IReadOnlyList <GeneratedShaderSet> hlslSets         = generationResult.GetOutput(backend);

            Assert.Equal(4, hlslSets.Count);
            GeneratedShaderSet set = hlslSets[0];

            Assert.Equal("VertexAndFragment", set.Name);

            CompileResult result = toolChain.Compile(set.VertexShaderCode, Stage.Vertex, "VS");

            Assert.False(result.HasError, result.ToString());

            result = toolChain.Compile(set.FragmentShaderCode, Stage.Fragment, "FS");
            Assert.False(result.HasError, result.ToString());
        }
Beispiel #2
0
        private void TestCompile(GraphicsBackend graphicsBackend, string vsName, string fsName, string csName = null)
        {
            Compilation compilation = TestUtil.GetCompilation();
            ToolChain   toolChain   = ToolChain.Require(ToolFeatures.ToCompiled, graphicsBackend);

            LanguageBackend backend = toolChain.CreateBackend(compilation);
            ShaderGenerator sg      = new ShaderGenerator(compilation, backend, vsName, fsName, csName);

            ShaderGenerationResult generationResult = sg.GenerateShaders();

            IReadOnlyList <GeneratedShaderSet> sets = generationResult.GetOutput(backend);

            Assert.Equal(1, sets.Count);
            GeneratedShaderSet set         = sets[0];
            ShaderModel        shaderModel = set.Model;

            List <CompileResult> results = new List <CompileResult>();

            if (!string.IsNullOrWhiteSpace(vsName))
            {
                ShaderFunction vsFunction = shaderModel.GetFunction(vsName);
                string         vsCode     = set.VertexShaderCode;

                results.Add(toolChain.Compile(vsCode, Stage.Vertex, vsFunction.Name));
            }
            if (!string.IsNullOrWhiteSpace(fsName))
            {
                ShaderFunction fsFunction = shaderModel.GetFunction(fsName);
                string         fsCode     = set.FragmentShaderCode;
                results.Add(toolChain.Compile(fsCode, Stage.Fragment, fsFunction.Name));
            }
            if (!string.IsNullOrWhiteSpace(csName))
            {
                ShaderFunction csFunction = shaderModel.GetFunction(csName);
                string         csCode     = set.ComputeShaderCode;
                results.Add(toolChain.Compile(csCode, Stage.Compute, csFunction.Name));
            }

            // Collate results
            StringBuilder builder = new StringBuilder();

            foreach (CompileResult result in results)
            {
                if (result.HasError)
                {
                    builder.AppendLine(result.ToString());
                }
            }

            Assert.True(builder.Length < 1, builder.ToString());
        }
Beispiel #3
0
        public void PartialFiles()
        {
            ToolChain toolChain = ToolChain.Get(ToolFeatures.ToCompiled);

            if (toolChain == null)
            {
                throw new RequiredToolFeatureMissingException("No tool chain supporting compilation was found!");
            }

            Compilation     compilation = TestUtil.GetCompilation();
            LanguageBackend backend     = toolChain.CreateBackend(compilation);
            ShaderGenerator sg          = new ShaderGenerator(compilation, backend, "TestShaders.PartialVertex.VertexShaderFunc");

            ShaderGenerationResult             genResult = sg.GenerateShaders();
            IReadOnlyList <GeneratedShaderSet> sets      = genResult.GetOutput(backend);

            Assert.Equal(1, sets.Count);
            GeneratedShaderSet set         = sets[0];
            ShaderModel        shaderModel = set.Model;
            string             vsCode      = set.VertexShaderCode;
            CompileResult      result      = toolChain.Compile(vsCode, Stage.Vertex, "VertexShaderFunc");

            Assert.False(result.HasError, result.ToString());
        }
Beispiel #4
0
        /// <summary>
        /// Executes the specified test.
        /// </summary>
        /// <param name="generationResult">The generation result.</param>
        /// <param name="csFunctionName">Name of the cs function.</param>
        /// <param name="output">The output.</param>
        public void Execute(
            ShaderGenerationResult generationResult,
            string csFunctionName,
            ITestOutputHelper output)
        {
            if (Executed)
            {
                output.WriteLine(
                    $"The {Name} tests have already been executed!");
                return;
            }

            TestSets testSets = TestSets;
            Mappings mappings = testSets.Mappings;

            if (ToolChain == null)
            {
                /*
                 * Generate the test data and the result set data for the CPU.
                 */
                AllocateResults(output);
                using (new TestTimer(output,
                                     $"Running {testSets.TestLoops} iterations on the {Name} backend"))
                {
                    for (int test = 0; test < testSets.TestLoops; test++)
                    {
                        foreach (MethodMap method in mappings.MethodMaps)
                        {
                            method.ExecuteCPU(TestSets.TestData, Results, test);
                        }
                    }

                    return;
                }
            }

            GeneratedShaderSet set;
            CompileResult      compilationResult;

            // Compile shader for this backend.
            using (new TestTimer(output, $"Compiling Compute Shader for {ToolChain.GraphicsBackend}"))
            {
                set = generationResult.GetOutput(Backend).Single();
                compilationResult =
                    ToolChain.Compile(set.ComputeShaderCode, Stage.Compute, set.ComputeFunction.Name);
            }

            if (compilationResult.HasError)
            {
                output.WriteLine($"Failed to compile Compute Shader from set \"{set.Name}\"!");
                output.WriteLine(compilationResult.ToString());
                return;
            }

            Assert.NotNull(compilationResult.CompiledOutput);

            using (GraphicsDevice graphicsDevice = ToolChain.CreateHeadless())
            {
                if (!graphicsDevice.Features.ComputeShader)
                {
                    output.WriteLine(
                        $"The {ToolChain.GraphicsBackend} backend does not support compute shaders, skipping!");
                    return;
                }

                ResourceFactory factory = graphicsDevice.ResourceFactory;
                using (DeviceBuffer inOutBuffer = factory.CreateBuffer(
                           new BufferDescription(
                               (uint)mappings.BufferSize,
                               BufferUsage.StructuredBufferReadWrite,
                               (uint)mappings.StructSize)))

                    using (Shader computeShader = factory.CreateShader(
                               new ShaderDescription(
                                   ShaderStages.Compute,
                                   compilationResult.CompiledOutput,
                                   csFunctionName)))

                        using (ResourceLayout inOutStorageLayout = factory.CreateResourceLayout(
                                   new ResourceLayoutDescription(
                                       new ResourceLayoutElementDescription("InOutBuffer", ResourceKind.StructuredBufferReadWrite,
                                                                            ShaderStages.Compute))))

                            using (Pipeline computePipeline = factory.CreateComputePipeline(new ComputePipelineDescription(
                                                                                                computeShader,
                                                                                                new[] { inOutStorageLayout },
                                                                                                1, 1, 1)))


                                using (ResourceSet computeResourceSet = factory.CreateResourceSet(
                                           new ResourceSetDescription(inOutStorageLayout, inOutBuffer)))

                                    using (CommandList commandList = factory.CreateCommandList())
                                    {
                                        // Ensure the headless graphics device is the backend we expect.
                                        Assert.Equal(ToolChain.GraphicsBackend, graphicsDevice.BackendType);

                                        output.WriteLine($"Created compute pipeline for {Name} backend.");

                                        // Allocate the results buffer
                                        AllocateResults(output);

                                        using (new TestTimer(output,
                                                             $"Running {testSets.TestLoops} iterations on the {Name} backend"))
                                        {
                                            // Loop for each test
                                            for (int test = 0; test < testSets.TestLoops; test++)
                                            {
                                                // Update parameter buffer
                                                graphicsDevice.UpdateBuffer(
                                                    inOutBuffer,
                                                    0,
                                                    // Get the portion of test data for the current test loop
                                                    Marshal.UnsafeAddrOfPinnedArrayElement(testSets.TestData, mappings.BufferSize * test),
                                                    (uint)mappings.BufferSize);
                                                graphicsDevice.WaitForIdle();

                                                // Execute compute shaders
                                                commandList.Begin();
                                                commandList.SetPipeline(computePipeline);
                                                commandList.SetComputeResourceSet(0, computeResourceSet);
                                                commandList.Dispatch((uint)mappings.Methods, 1, 1);
                                                commandList.End();

                                                graphicsDevice.SubmitCommands(commandList);
                                                graphicsDevice.WaitForIdle();

                                                // Read back parameters using a staging buffer
                                                using (DeviceBuffer stagingBuffer =
                                                           factory.CreateBuffer(
                                                               new BufferDescription(inOutBuffer.SizeInBytes, BufferUsage.Staging)))
                                                {
                                                    commandList.Begin();
                                                    commandList.CopyBuffer(inOutBuffer, 0, stagingBuffer, 0, stagingBuffer.SizeInBytes);
                                                    commandList.End();
                                                    graphicsDevice.SubmitCommands(commandList);
                                                    graphicsDevice.WaitForIdle();

                                                    // Read back test results
                                                    MappedResource map = graphicsDevice.Map(stagingBuffer, MapMode.Read);

                                                    mappings.SetResults(map.Data, Results, test);
                                                    graphicsDevice.Unmap(stagingBuffer);
                                                }
                                            }
                                        }
                                    }
            }
        }
Beispiel #5
0
        public void AllSetsCompile()
        {
            Compilation compilation = TestUtil.GetCompilation();

            // Get all available tool chains.
            LanguageBackend[] backends = TestUtil.GetAllBackends(compilation, ToolFeatures.ToCompiled);

            ShaderGenerator        sg = new ShaderGenerator(compilation, backends);
            ShaderGenerationResult generationResult = sg.GenerateShaders();

            string spacer1 = new string('=', 80);
            string spacer2 = new string('-', 80);

            bool failed = false;

            foreach (LanguageBackend backend in backends)
            {
                ToolChain toolChain = ToolChain.Get(backend);
                IReadOnlyList <GeneratedShaderSet> sets = generationResult.GetOutput(backend);
                _output.WriteLine(spacer1);
                _output.WriteLine($"Generated shader sets for {toolChain.Name} backend.");

                foreach (GeneratedShaderSet set in sets)
                {
                    _output.WriteLine(string.Empty);
                    _output.WriteLine(spacer2);
                    _output.WriteLine(string.Empty);
                    CompileResult result;

                    if (set.VertexShaderCode != null)
                    {
                        result = toolChain.Compile(set.VertexShaderCode, Stage.Vertex, set.VertexFunction.Name);
                        if (result.HasError)
                        {
                            _output.WriteLine($"Failed to compile Vertex Shader from set \"{set.Name}\"!");
                            _output.WriteLine(result.ToString());
                            failed = true;
                        }
                        else
                        {
                            _output.WriteLine($"Compiled Vertex Shader from set \"{set.Name}\"!");
                        }
                    }

                    if (set.FragmentFunction != null)
                    {
                        result = toolChain.Compile(set.FragmentShaderCode, Stage.Fragment, set.FragmentFunction.Name);
                        if (result.HasError)
                        {
                            _output.WriteLine($"Failed to compile Fragment Shader from set \"{set.Name}\"!");
                            _output.WriteLine(result.ToString());
                            failed = true;
                        }
                        else
                        {
                            _output.WriteLine($"Compiled Fragment Shader from set \"{set.Name}\"!");
                        }
                    }

                    if (set.ComputeFunction != null)
                    {
                        // TODO The skipped shaders are not included in the auto discovered shaders, leaving this here for completeness.
                        if (backend is GlslEs300Backend)
                        {
                            string fullname = set.ComputeFunction.DeclaringType + "." + set.ComputeFunction.Name + "_";
                            if (s_glslesSkippedShaders.Contains(fullname))
                            {
                                continue;
                            }
                        }

                        result = toolChain.Compile(set.ComputeShaderCode, Stage.Compute, set.ComputeFunction.Name);
                        if (result.HasError)
                        {
                            _output.WriteLine($"Failed to compile Compute Shader from set \"{set.Name}\"!");
                            _output.WriteLine(result.ToString());
                            failed = true;
                        }
                        else
                        {
                            _output.WriteLine($"Compiled Compute Shader from set \"{set.Name}\"!");
                        }
                    }
                }

                _output.WriteLine(string.Empty);
            }

            Assert.False(failed);
        }