/// <summary> /// Creates a compute shader from the given <see cref="ShaderDescription"/> containing SPIR-V bytecode or GLSL source /// code. /// </summary> /// <param name="factory">The <see cref="ResourceFactory"/> used to compile the translated shader code.</param> /// <param name="computeShaderDescription">The compute shader's description. /// <see cref="ShaderDescription.ShaderBytes"/> should contain SPIR-V bytecode or Vulkan-style GLSL source code which /// can be compiled to SPIR-V.</param> /// <param name="options">The <see cref="CrossCompileOptions"/> which will control the parameters used to translate the /// shaders from SPIR-V to the target language.</param> /// <returns>The compiled compute <see cref="Shader"/>.</returns> public static Shader CreateFromSpirv( this ResourceFactory factory, ShaderDescription computeShaderDescription, CrossCompileOptions options) { GraphicsBackend backend = factory.BackendType; if (backend == GraphicsBackend.Vulkan) { computeShaderDescription.ShaderBytes = EnsureSpirv(computeShaderDescription); return(factory.CreateShader(ref computeShaderDescription)); } CrossCompileTarget target = GetCompilationTarget(factory.BackendType); ComputeCompilationResult compilationResult = SpirvCompilation.CompileCompute( computeShaderDescription.ShaderBytes, target, options); string computeEntryPoint = (backend == GraphicsBackend.Metal && computeShaderDescription.EntryPoint == "main") ? "main0" : computeShaderDescription.EntryPoint; byte[] computeBytes = GetBytes(backend, compilationResult.ComputeShader); return(factory.CreateShader(new ShaderDescription( computeShaderDescription.Stage, computeBytes, computeEntryPoint))); }
private string[] CompileCompute(ShaderVariantDescription variant) { List <string> generatedFiles = new List <string>(); byte[] csBytes = CompileToSpirv(variant, variant.Shaders[0].FileName, ShaderStages.Compute); string spvPath = Path.Combine(_outputPath, $"{variant.Name}_{ShaderStages.Compute.ToString()}.spv"); File.WriteAllBytes(spvPath, csBytes); generatedFiles.Add(spvPath); List <Exception> compilationExceptions = new List <Exception>(); foreach (CrossCompileTarget target in variant.Targets) { try { ComputeCompilationResult result = SpirvCompilation.CompileCompute(csBytes, target, variant.CrossCompileOptions); string csPath = Path.Combine(_outputPath, $"{variant.Name}_Compute.{GetExtension(target)}"); File.WriteAllText(csPath, result.ComputeShader); generatedFiles.Add(csPath); string reflectionPath = Path.Combine(_outputPath, $"{variant.Name}_ReflectionInfo.json"); JsonSerializer serializer = new JsonSerializer(); serializer.Formatting = Formatting.Indented; StringEnumConverter enumConverter = new StringEnumConverter(); serializer.Converters.Add(enumConverter); using (StreamWriter sw = File.CreateText(reflectionPath)) using (JsonTextWriter jtw = new JsonTextWriter(sw)) { serializer.Serialize(jtw, result.Reflection); } generatedFiles.Add(reflectionPath); } catch (Exception e) { compilationExceptions.Add(e); } } if (compilationExceptions.Count > 0) { throw new AggregateException($"Errors were encountered when compiling shader variant(s).", compilationExceptions); } return(generatedFiles.ToArray()); }