예제 #1
0
        public async Task <PipelineState> CreateGraphicsPipelineStateAsync()
        {
            if (MaterialDescriptor is null)
            {
                throw new InvalidOperationException("The current material descriptor cannot be null when creating a pipeline state.");
            }

            InputElementDescription[] inputElements = new[]
            {
                new InputElementDescription("Position", 0, (Format)PixelFormat.R32G32B32_Float, 0),
                new InputElementDescription("Normal", 0, (Format)PixelFormat.R32G32B32_Float, 1),
                new InputElementDescription("Tangent", 0, (Format)PixelFormat.R32G32B32A32_Float, 2),
                new InputElementDescription("TexCoord", 0, (Format)PixelFormat.R32G32_Float, 3)
            };

            CompiledShader compiledShader = new CompiledShader();

            string shaderCachePath = Path.Combine("Log", "ShaderCache");

            string filePath = Path.Combine(shaderCachePath, $"Shader_{MaterialDescriptor.Id}");

            if (!await Content.ExistsAsync(filePath))
            {
                ShaderGenerator       shaderGenerator = new ShaderGenerator(MaterialDescriptor.Attributes);
                ShaderGeneratorResult result          = shaderGenerator.GenerateShader();

                CompiledShaderAsset shaderAsset = new CompiledShaderAsset();

                foreach (var entryPoint in result.EntryPoints)
                {
                    compiledShader.Shaders[entryPoint.Key]    = ShaderCompiler.Compile(GetShaderStage(entryPoint.Key), result.ShaderSource, entryPoint.Value);
                    shaderAsset.ShaderSources[entryPoint.Key] = Path.Combine(shaderCachePath, $"{entryPoint.Key}_{MaterialDescriptor.Id}.cso");

                    using Stream stream = await Content.FileProvider.OpenStreamAsync(shaderAsset.ShaderSources[entryPoint.Key], FileMode.Create, FileAccess.ReadWrite);

                    await stream.WriteAsync(compiledShader.Shaders[entryPoint.Key], 0, compiledShader.Shaders[entryPoint.Key].Length);
                }

                await Content.SaveAsync(filePath, shaderAsset);
            }
            else
            {
                compiledShader = await Content.LoadAsync <CompiledShader>(filePath);
            }

            ID3D12RootSignature rootSignature = CreateRootSignature();

            return(new PipelineState(GraphicsDevice, inputElements, rootSignature,
                                     compiledShader.Shaders["vertex"],
                                     compiledShader.Shaders["pixel"],
                                     compiledShader.Shaders.ContainsKey("geometry") ? compiledShader.Shaders["geometry"] : null,
                                     compiledShader.Shaders.ContainsKey("hull") ? compiledShader.Shaders["hull"] : null,
                                     compiledShader.Shaders.ContainsKey("domain") ? compiledShader.Shaders["domain"] : null));
        }
        public async Task <PipelineState> CreateGraphicsPipelineStateAsync()
        {
            if (MaterialDescriptor is null)
            {
                throw new InvalidOperationException("The current material descriptor cannot be null when creating a pipeline state.");
            }

            InputElementDescription[] inputElements = new[]
            {
                new InputElementDescription("Position", 0, (Format)PixelFormat.R32G32B32_Float, 0),
                new InputElementDescription("Normal", 0, (Format)PixelFormat.R32G32B32_Float, 1),
                new InputElementDescription("Tangent", 0, (Format)PixelFormat.R32G32B32A32_Float, 2),
                new InputElementDescription("TexCoord", 0, (Format)PixelFormat.R32G32_Float, 3)
            };

            CompiledShader compiledShader = new CompiledShader();

            string fileName = $"Shader_{MaterialDescriptor.Id}";

            if (!await Content.ExistsAsync(fileName))
            {
                ShaderGenerator       shaderGenerator = new ShaderGenerator(MaterialDescriptor.Attributes);
                ShaderGeneratorResult result          = shaderGenerator.GenerateShader();

                CompiledShaderAsset shaderAsset = new CompiledShaderAsset();

                foreach (var entryPoint in result.EntryPoints)
                {
                    compiledShader.Shaders[entryPoint.Key]    = ShaderCompiler.Compile(GetShaderStage(entryPoint.Key), result.ShaderSource, entryPoint.Value);
                    shaderAsset.ShaderSources[entryPoint.Key] = $"{entryPoint.Key}_{MaterialDescriptor.Id}.cso";
                    await FileIO.WriteBytesAsync(await Content.RootFolder !.CreateFileAsync(shaderAsset.ShaderSources[entryPoint.Key], CreationCollisionOption.ReplaceExisting), compiledShader.Shaders[entryPoint.Key]);
                }

                await Content.SaveAsync(fileName, shaderAsset);
            }
            else
            {
                compiledShader = await Content.LoadAsync <CompiledShader>(fileName);
            }

            ID3D12RootSignature rootSignature = CreateRootSignature();

            return(new PipelineState(GraphicsDevice, inputElements, rootSignature,
                                     compiledShader.Shaders["vertex"],
                                     compiledShader.Shaders["pixel"],
                                     compiledShader.Shaders.ContainsKey("geometry") ? compiledShader.Shaders["geometry"] : null,
                                     compiledShader.Shaders.ContainsKey("hull") ? compiledShader.Shaders["hull"] : null,
                                     compiledShader.Shaders.ContainsKey("domain") ? compiledShader.Shaders["domain"] : null));
        }
        public override async Task <CompiledShader> CreateShaderAsync()
        {
            if (MaterialDescriptor is null)
            {
                throw new InvalidOperationException("The current material descriptor cannot be null when creating a pipeline state.");
            }
            if (Shader is null)
            {
                throw new InvalidOperationException();
            }

            CompiledShader compiledShader = new CompiledShader();

            string shaderCachePath = Path.Combine("Log", "ShaderCache");
            string filePath        = Path.Combine(shaderCachePath, $"Shader_{MaterialDescriptor.Id}");

            if (!await Content.ExistsAsync(filePath))
            {
                ShaderGenerator       shaderGenerator = new ShaderGenerator(Shader, Settings);
                ShaderGeneratorResult result          = shaderGenerator.GenerateShader();

                CompiledShaderAsset shaderAsset = new CompiledShaderAsset();

                foreach (var entryPoint in result.EntryPoints)
                {
                    compiledShader.Shaders[entryPoint.Key]    = ShaderCompiler.Compile(GetShaderStage(entryPoint.Key), result.ShaderSource, entryPoint.Value);
                    shaderAsset.ShaderSources[entryPoint.Key] = Path.Combine(shaderCachePath, $"{entryPoint.Key}_{MaterialDescriptor.Id}.cso");

                    using Stream stream = await Content.FileProvider.OpenStreamAsync(shaderAsset.ShaderSources[entryPoint.Key], FileMode.Create, FileAccess.ReadWrite);

                    await stream.WriteAsync(compiledShader.Shaders[entryPoint.Key], 0, compiledShader.Shaders[entryPoint.Key].Length);
                }

                await Content.SaveAsync(filePath, shaderAsset);
            }
            else
            {
                compiledShader = await Content.LoadAsync <CompiledShader>(filePath);
            }

            return(compiledShader);
        }