public static void TestConstantsStructMatchesShader <Material, ConstantsStruct>(string shaderName, string bufferName)
    {
        var fields   = typeof(ConstantsStruct).GetFields();
        var bytecode = ShaderCache.LoadBytesFromResource <Material>(shaderName + ShaderCache.PixelShaderExtension);

        using (var reflection = new ShaderReflection(bytecode))
            using (var buffer = reflection.GetConstantBuffer(bufferName)) {
                int variableCount = buffer.Description.VariableCount;
                Assert.AreEqual(buffer.Description.Size, Marshal.SizeOf <ConstantsStruct>(), "struct size mismatch");
                Assert.AreEqual(variableCount, fields.Length, "field count mismatch");

                for (int i = 0; i < variableCount; ++i)
                {
                    FieldInfo field = fields[i];

                    using (var variable = buffer.GetVariable(i)) {
                        Assert.AreEqual(
                            variable.Description.Name.ToLowerInvariant(),
                            field.Name.ToLowerInvariant(),
                            "field name mismatch");

                        Assert.AreEqual(
                            variable.Description.Size,
                            (int)Marshal.SizeOf(field.FieldType),
                            "field size mismatch: " + field.Name);

                        Assert.AreEqual(
                            variable.Description.StartOffset,
                            (int)Marshal.OffsetOf <ConstantsStruct>(field.Name),
                            "field offset mismatch: " + field.Name);
                    }
                }
            }
    }
예제 #2
0
        internal Dictionary <string, EConstantBuffer> ReflectConstantBuffers()
        {
            // MARK BUFFER IS DIRTY, SO ONLY CHANGED BUFFERS/VARIABLE GET UPDATED
            var numberOfConstantBuffers = shaderReflection.Description.ConstantBuffers;

            var eConstantBuffersList = new Dictionary <string, EConstantBuffer>();

            for (int i = 0; i < numberOfConstantBuffers; i++)
            {
                var constantBuffer = shaderReflection.GetConstantBuffer(i);

                EConstantBuffer c = new EConstantBuffer(constantBuffer.Description.Name, graphicsDevice);

                for (int x = 0; x < constantBuffer.Description.VariableCount; x++)
                {
                    var name   = constantBuffer.GetVariable(x).Description.Name;
                    var size   = constantBuffer.GetVariable(x).Description.Size;
                    var offset = constantBuffer.GetVariable(x).Description.StartOffset;

                    c.AddConstantBufferVariable(name, new ConstantBufferVariable(name, size, offset));
                }

                eConstantBuffersList.Add(constantBuffer.Description.Name, c);
            }

            foreach (var cbuffers in eConstantBuffersList)
            {
                cbuffers.Value.CreateBuffers();
            }

            return(eConstantBuffersList);
        }
예제 #3
0
        private void ShaderReflection(Shaders shaderType, int ShaderId, ShaderReflection shaderMetaData)
        {
            //Look with reflection, to find the Constant Buffers used with the shader;
            ConstantBuffer          constantBuffer;
            InputBindingDescription inputBindingdesc;

            for (int cptCB = 0; cptCB < shaderMetaData.Description.ConstantBuffers; cptCB++)
            {
                constantBuffer = shaderMetaData.GetConstantBuffer(cptCB);

                if (constantBuffer.Description.Type == ConstantBufferType.ConstantBuffer || constantBuffer.Description.Type == ConstantBufferType.TextureBuffer)
                {
                    for (int i = 0; i < _cBuffers.Length; i++)
                    {
                        if (_cBuffers[i].Name == constantBuffer.Description.Name)
                        {
                            inputBindingdesc              = shaderMetaData.GetResourceBindingDescription(constantBuffer.Description.Name);
                            _cBuffers[i].ShadersImpacted |= shaderType;
                            _cBuffers[i].Slot[ShaderId]   = inputBindingdesc.BindPoint;
                        }
                    }
                }
            }

            //Look with reflection, to find the Resources (Textures) used by the shader;
            for (int cptResources = 0; cptResources < shaderMetaData.Description.BoundResources; cptResources++)
            {
                inputBindingdesc = shaderMetaData.GetResourceBindingDescription(cptResources);

                if (inputBindingdesc.Type == ShaderInputType.Texture)
                {
                    for (int i = 0; i < _shaderResources.Length; i++)
                    {
                        if (_shaderResources[i].Name == inputBindingdesc.Name)
                        {
                            _shaderResources[i].ShadersImpacted |= shaderType;
                            _shaderResources[i].Slot[ShaderId]   = inputBindingdesc.BindPoint;
                        }
                    }
                }

                if (inputBindingdesc.Type == ShaderInputType.Sampler)
                {
                    for (int i = 0; i < _shaderSamplers.Length; i++)
                    {
                        if (_shaderSamplers[i].Name == inputBindingdesc.Name)
                        {
                            _shaderSamplers[i].ShadersImpacted |= shaderType;
                            _shaderSamplers[i].Slot[ShaderId]   = inputBindingdesc.BindPoint;
                        }
                    }
                }
            }
        }
예제 #4
0
        protected void Compile(string name, StreamReader shaderSource, Profile profile)
        {
            Logger.LogInfo(this, "Compiling " + name + " with profile " + profile + ".");

            _shaderByteCode = ShaderBytecode.Compile(shaderSource.ReadToEnd(), "main", profile.ToString(), ShaderFlags.None, EffectFlags.None, null, null, name);

            using (ShaderReflection sr = new ShaderReflection(_shaderByteCode))
            {
                for (int i = 0; i < sr.Description.BoundResources; i++)
                {
                    InputBindingDescription desc = sr.GetResourceBindingDescription(i);
                    switch (desc.Type)
                    {
                    case ShaderInputType.ConstantBuffer:
                    {
                        ConstantBufferInfo info = new ConstantBufferInfo();
                        info.BindingDescription = desc;
                        var buffer = sr.GetConstantBuffer(desc.Name);
                        for (int v = 0; v < buffer.Description.VariableCount; v++)
                        {
                            var variable = buffer.GetVariable(v);
                            info.VariableDescriptions.Add(variable.Description.Name, variable.Description);
                        }
                        _constantBuffersInfos.Add(desc.Name, info);
                    }
                    break;

                    case ShaderInputType.Texture:
                        _shaderResourceInfos.Add(desc.Name, desc);
                        break;

                    case ShaderInputType.Sampler:
                        _samplerStateInfos.Add(desc.Name, desc);
                        break;
                    }
                }
            }
        }
예제 #5
0
    void PrintConstantBuffers()
    {
        using var reflector = new ShaderReflection(mCompiledShader);

        var shaderDesc = reflector.Description;

        Logger.Info("Vertex Shader '{0}' has {1} constant buffers:", Name, shaderDesc.ConstantBuffers);

        for (var i = 0; i < shaderDesc.ConstantBuffers; i++)
        {
            var cbufferDesc = reflector.GetConstantBuffer(i);
            var bufferDesc  = cbufferDesc.Description;

            Logger.Info("  Constant Buffer #{0} '{1}'", i, bufferDesc.Name);

            for (var j = 0; j < bufferDesc.VariableCount; j++)
            {
                var variable     = cbufferDesc.GetVariable(j);
                var variableDesc = variable.Description;

                Logger.Info("    {0} @ {1}", variableDesc.Name, variableDesc.StartOffset);
            }
        }
    }
예제 #6
0
        public void Parse(byte[] byteCode, ShaderStage stage)
        {
            ConstantBufferMappings.Clear();
            TextureMappings.Clear();
            UAVMappings.Clear();
            SamplerMappings.Clear();
            using (var reflection = new ShaderReflection(byteCode))
            {
                FeatureLevel = reflection.MinFeatureLevel;
                for (int i = 0; i < reflection.Description.BoundResources; ++i)
                {
                    var res = reflection.GetResourceBindingDescription(i);
                    switch (res.Type)
                    {
                    case ShaderInputType.ConstantBuffer:
                        var cb     = reflection.GetConstantBuffer(res.Name);
                        var cbDesc = new ConstantBufferDescription(res.Name, cb.Description.Size)
                        {
                            Stage = stage, Slot = res.BindPoint
                        };
                        ConstantBufferMappings.Add(res.Name, cbDesc.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.Texture:
                        var tDescT = new TextureDescription(res.Name, stage, TextureType.Texture);
                        TextureMappings.Add(res.Name, tDescT.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.Structured:
                        var tDescStr = new TextureDescription(res.Name, stage, TextureType.Structured);
                        TextureMappings.Add(res.Name, tDescStr.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.TextureBuffer:
                        var tDescTB = new TextureDescription(res.Name, stage, TextureType.TextureBuffer);
                        TextureMappings.Add(res.Name, tDescTB.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewAppendStructured:
                        var uDescAppend = new UAVDescription(res.Name, stage, UnorderedAccessViewType.AppendStructured);
                        UAVMappings.Add(res.Name, uDescAppend.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewConsumeStructured:
                        var uDescConsume = new UAVDescription(res.Name, stage, UnorderedAccessViewType.ConsumeStructured);
                        UAVMappings.Add(res.Name, uDescConsume.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewRWByteAddress:
                        var uDescByte = new UAVDescription(res.Name, stage, UnorderedAccessViewType.RWByteAddress);
                        UAVMappings.Add(res.Name, uDescByte.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewRWStructuredWithCounter:
                        var uDescStr = new UAVDescription(res.Name, stage, UnorderedAccessViewType.RWStructuredWithCounter);
                        UAVMappings.Add(res.Name, uDescStr.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.UnorderedAccessViewRWTyped:
                        var uDescTyped = new UAVDescription(res.Name, stage, UnorderedAccessViewType.RWTyped);
                        UAVMappings.Add(res.Name, uDescTyped.CreateMapping(res.BindPoint));
                        break;

                    case ShaderInputType.Sampler:
                        SamplerMappings.Add(res.Name, new SamplerMapping(res.BindPoint, res.Name, stage));
                        break;
                    }
                }
            }
        }
예제 #7
0
        private System.Tuple <Shader, System.Exception> LoadShader(string shaderFile, params InputElement[] inputElements)
        {
            var result = new Shader()
            {
                vertexShader   = null,
                pixelShader    = null,
                geometryShader = null,
                layout         = null,
                validState     = false
            };

            ShaderBytecode  vertexShaderByteCode   = null;
            ShaderBytecode  pixelShaderByteCode    = null;
            ShaderBytecode  geometryShaderByteCode = null;
            ShaderSignature signature      = null;
            VertexShader    vertexShader   = null;
            PixelShader     pixelShader    = null;
            GeometryShader  geometryShader = null;
            InputLayout     layout         = null;

            System.Exception error = null;
            try
            {
                var shaderFileBytecode = File.ReadAllBytes(shaderFile);
                vertexShaderByteCode = ShaderBytecode.Compile(shaderFileBytecode, "VS", "vs_4_0", ShaderFlags.OptimizationLevel0);
                vertexShader         = new VertexShader(device, vertexShaderByteCode);
                var reflection = new ShaderReflection(vertexShaderByteCode);
                /* Iterate through constant buffers */
                for (int i = 0; i < reflection.Description.ConstantBuffers; ++i)
                {
                    var cb = reflection.GetConstantBuffer(i);
                    if (cb.Description.Name == "worldViewProj")
                    {
                        result.vertexShaderSlot.worldViewProj = i;
                    }
                }
                reflection.Dispose();

                pixelShaderByteCode = ShaderBytecode.Compile(shaderFileBytecode, "PS", "ps_4_0", ShaderFlags.OptimizationLevel0);
                pixelShader         = new PixelShader(device, pixelShaderByteCode);

                try
                {
                    geometryShaderByteCode = ShaderBytecode.Compile(shaderFileBytecode, "GS", "gs_4_0", ShaderFlags.OptimizationLevel0);
                    geometryShader         = new GeometryShader(device, geometryShaderByteCode);
                }
                catch (CompilationException e)
                {
                    if (!e.Message.Contains("'GS': entrypoint"))
                    {
                        throw e;
                    }
                }

                signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
                layout    = new InputLayout(device, signature, inputElements);
                signature.Dispose();

                result.vertexShader   = vertexShader;
                result.pixelShader    = pixelShader;
                result.geometryShader = geometryShader;
                result.layout         = layout;
            }
            catch (System.Exception e)
            {
                System.Console.WriteLine("Error while compiling shader {0}:\n{1}", shaderFile, e);
                error = e;
            }
            finally
            {
                if (geometryShaderByteCode != null)
                {
                    geometryShaderByteCode.Dispose();
                }
                if (vertexShaderByteCode != null)
                {
                    vertexShaderByteCode.Dispose();
                }
                if (pixelShaderByteCode != null)
                {
                    pixelShaderByteCode.Dispose();
                }
                if (geometryShaderByteCode != null)
                {
                    geometryShaderByteCode.Dispose();
                }
                if (signature != null)
                {
                    signature.Dispose();
                }

                if (error != null && vertexShader != null)
                {
                    vertexShader.Dispose();
                }
                if (error != null && pixelShader != null)
                {
                    pixelShader.Dispose();
                }
                if (error != null && geometryShader != null)
                {
                    geometryShader.Dispose();
                }
                if (error != null && layout != null)
                {
                    signature.Dispose();
                }
            }

            result.validState = error == null;

            return(System.Tuple.Create(result, error));
        }
예제 #8
0
        public static void CompileD3D12Shader(H1ShaderCompileInput input, H1ShaderCompileOutput output)
        {
            // process shared/single environments
            String includeContent = "";
            List <SharpDX.Direct3D.ShaderMacro> macros = new List <SharpDX.Direct3D.ShaderMacro>();

            // 1. shared environment
            ProcessShaderCompilerEnvironment(input.SharedEnvironment, ref includeContent, macros);

            // 2. single environment
            ProcessShaderCompilerEnvironment(input.Environment, ref includeContent, macros);

            // load shader file content
            String sourceContent = includeContent + "\n" + LoadShaderFile(input.SourceFileName);

            // preprocess the shader file
            sourceContent = ShaderBytecode.Preprocess(sourceContent, macros.ToArray(), new H1SharpDXCompileInclude());
#if DEBUG
            var shader = ShaderBytecode.Compile(sourceContent, input.EntryPointName, input.Target.ToFormat, SharpDX.D3DCompiler.ShaderFlags.Debug | SharpDX.D3DCompiler.ShaderFlags.SkipOptimization);
#else
            var shader = ShaderBytecode.Compile(sourceContent, input.EntryPointName, input.Target.ToFormat);
#endif
            if (shader.Message != null) // failed to compile the shader
            {
                // @TODO - should log the error for failing compiling shader
                output.IsSucceed = false;
                return;
            }

            // assign the resultant byte code
            output.Code = shader;
            // create shader parameter map
            output.ParameterMap = new H1ShaderParameterMap();

            // reflection for the compiled shader
            ShaderReflection  shaderReflect = new ShaderReflection(shader);
            ShaderDescription shaderDesc    = shaderReflect.Description;

            int bindResCounts = shaderDesc.BoundResources;
            for (int resIdx = 0; resIdx < bindResCounts; ++resIdx)
            {
                InputBindingDescription bindDesc = shaderReflect.GetResourceBindingDescription(resIdx);

                // for constant buffers
                if (bindDesc.Type == ShaderInputType.ConstantBuffer)
                {
                    int            cbIndex = bindDesc.BindPoint;
                    ConstantBuffer cb      = shaderReflect.GetConstantBuffer(cbIndex);

                    ConstantBufferDescription cbDesc;
                    cbDesc = cb.Description;

                    // track all variables in this constant buffer
                    for (int varIdx = 0; varIdx < cbDesc.VariableCount; varIdx++)
                    {
                        ShaderReflectionVariable  variable     = cb.GetVariable(varIdx);
                        ShaderVariableDescription variableDesc = variable.Description;

                        output.ParameterMap.ParameterMap.Add(variableDesc.Name,
                                                             new H1ParameterAllocation(H1ParameterType.Variable, cbIndex, variableDesc.StartOffset, variableDesc.Size));
                    }

                    // add constant buffer parameter
                    output.ParameterMap.ParameterMap.Add(cbDesc.Name,
                                                         new H1ParameterAllocation(H1ParameterType.ConstantBuffer, cbIndex, -1, cbDesc.Size));
                }

                // texture, samplers .... other various GDI data
            }

            // release shader reflection
            shaderReflect.Dispose();
            output.IsSucceed = true; // successfully compiled
        }
예제 #9
0
        public void ShaderReflectionMatchesDirect3DReflection(string relPath)
        {
            // Arrange.
            var file            = $"{ShaderDirectory}/{relPath}";
            var binaryFileBytes = File.ReadAllBytes(file + ".o");

            // Act.
            if (binaryFileBytes[0] == 0x01 &&
                binaryFileBytes[1] == 0x20 &&
                binaryFileBytes[2] == 0xFF &&
                binaryFileBytes[3] == 0xFE)
            {
                Effects11.CompareEffect(null, binaryFileBytes, Path.GetFileNameWithoutExtension(relPath));
                return;
            }
            var container = BytecodeContainer.Parse(binaryFileBytes);

            if (container.Chunks.OfType <LibHeaderChunk>().Any())
            {
                CompareLibrary(container, binaryFileBytes);
                return;
            }
            if (container.Chunks.OfType <EffectChunk>().Any())
            {
                Effects10.CompareEffect(container, binaryFileBytes, Path.GetFileNameWithoutExtension(relPath));
                return;
            }
            using (var shaderBytecode = ShaderBytecode.FromStream(new MemoryStream(binaryFileBytes)))
                using (var shaderReflection = new ShaderReflection(shaderBytecode))
                {
                    var desc = shaderReflection.Description;

                    // Assert.
                    Assert.AreEqual(shaderReflection.BitwiseInstructionCount, 0);             // TODO
                    Assert.AreEqual(shaderReflection.ConditionalMoveInstructionCount, container.Statistics.MovCInstructionCount);
                    Assert.AreEqual(shaderReflection.ConversionInstructionCount, container.Statistics.ConversionInstructionCount);
                    Assert.AreEqual((int)shaderReflection.GeometryShaderSInputPrimitive, (int)container.Statistics.InputPrimitive);
                    Assert.AreEqual(shaderReflection.InterfaceSlotCount, container.ResourceDefinition.InterfaceSlotCount);
                    Assert.AreEqual((bool)shaderReflection.IsSampleFrequencyShader, container.Statistics.IsSampleFrequencyShader);
                    Assert.AreEqual(shaderReflection.MoveInstructionCount, container.Statistics.MovInstructionCount);

                    var flags = ShaderRequiresFlags.None;
                    if (container.Version.MajorVersion >= 5)
                    {
                        if (container.Sfi0 != null)
                        {
                            flags = (ShaderRequiresFlags)container.Sfi0.Flags;
                        }
                        else
                        {
                            var dcl = container.Shader.DeclarationTokens
                                      .OfType <GlobalFlagsDeclarationToken>()
                                      .FirstOrDefault();
                            var globals = dcl?.Flags ?? 0;
                            flags = (ShaderRequiresFlags)Chunks.Sfi0.Sfi0Chunk.GlobalFlagsToRequireFlags(globals);
                        }
                    }
                    Assert.AreEqual(shaderReflection.RequiresFlags, flags);

                    int  expectedSizeX, expectedSizeY, expectedSizeZ;
                    uint actualSizeX, actualSizeY, actualSizeZ;
                    shaderReflection.GetThreadGroupSize(out expectedSizeX, out expectedSizeY, out expectedSizeZ);
                    container.Shader.GetThreadGroupSize(out actualSizeX, out actualSizeY, out actualSizeZ);
                    Assert.AreEqual(expectedSizeX, actualSizeX);
                    Assert.AreEqual(expectedSizeY, actualSizeY);
                    Assert.AreEqual(expectedSizeZ, actualSizeZ);


                    SharpDX.Direct3D.FeatureLevel featureLevel = 0;
                    if (container.Chunks.OfType <Chunks.Aon9.Level9ShaderChunk>().Any())
                    {
                        var level9Chunk = container.Chunks
                                          .OfType <Chunks.Aon9.Level9ShaderChunk>()
                                          .First();
                        featureLevel = level9Chunk.ShaderModel.MinorVersion == 1
                                                ? SharpDX.Direct3D.FeatureLevel.Level_9_3 :
                                       SharpDX.Direct3D.FeatureLevel.Level_9_1;
                    }
                    else if (container.Version.MajorVersion == 4 && container.Version.MinorVersion == 0)
                    {
                        featureLevel = SharpDX.Direct3D.FeatureLevel.Level_10_0;
                    }
                    else if (container.Version.MajorVersion == 4 && container.Version.MinorVersion == 1)
                    {
                        featureLevel = SharpDX.Direct3D.FeatureLevel.Level_10_1;
                    }
                    else if (container.Version.MajorVersion == 5)
                    {
                        featureLevel = SharpDX.Direct3D.FeatureLevel.Level_11_0;
                        if (flags.HasFlag(ShaderRequiresFlags.ShaderRequires64UnorderedAccessViews))
                        {
                            featureLevel = SharpDX.Direct3D.FeatureLevel.Level_11_1;
                        }
                    }

                    Assert.AreEqual(shaderReflection.MinFeatureLevel, featureLevel);             // TODO

                    Assert.AreEqual(desc.ArrayInstructionCount, container.Statistics.ArrayInstructionCount);
                    Assert.AreEqual(desc.BarrierInstructions, container.Statistics.BarrierInstructions);
                    Assert.AreEqual(desc.BoundResources, container.ResourceDefinition.ResourceBindings.Count);
                    Assert.AreEqual(desc.ConstantBuffers, container.ResourceDefinition.ConstantBuffers.Count);
                    Assert.AreEqual(desc.ControlPoints, container.Statistics.ControlPoints);
                    Assert.AreEqual(desc.Creator, container.ResourceDefinition.Creator);
                    Assert.AreEqual(desc.CutInstructionCount, container.Statistics.CutInstructionCount);
                    Assert.AreEqual(desc.DeclarationCount, container.Statistics.DeclarationCount);
                    Assert.AreEqual(desc.DefineCount, container.Statistics.DefineCount);
                    Assert.AreEqual(desc.DynamicFlowControlCount, container.Statistics.DynamicFlowControlCount);
                    Assert.AreEqual(desc.EmitInstructionCount, container.Statistics.EmitInstructionCount);
                    Assert.AreEqual((int)desc.Flags, (int)container.ResourceDefinition.Flags);
                    Assert.AreEqual(desc.FloatInstructionCount, container.Statistics.FloatInstructionCount);
                    Assert.AreEqual(desc.GeometryShaderInstanceCount, container.Statistics.GeometryShaderInstanceCount);
                    Assert.AreEqual(desc.GeometryShaderMaxOutputVertexCount, container.Statistics.GeometryShaderMaxOutputVertexCount);
                    Assert.AreEqual((int)desc.GeometryShaderOutputTopology, (int)container.Statistics.GeometryShaderOutputTopology);
                    Assert.AreEqual((int)desc.HullShaderOutputPrimitive, (int)container.Statistics.HullShaderOutputPrimitive);
                    Assert.AreEqual((int)desc.HullShaderPartitioning, (int)container.Statistics.HullShaderPartitioning);
                    Assert.AreEqual(desc.InputParameters, container.InputSignature.Parameters.Count);
                    Assert.AreEqual((int)desc.InputPrimitive, (int)container.Statistics.InputPrimitive);
                    Assert.AreEqual(desc.InstructionCount, container.Statistics.InstructionCount);
                    Assert.AreEqual(desc.InterlockedInstructions, container.Statistics.InterlockedInstructions);
                    Assert.AreEqual(desc.IntInstructionCount, container.Statistics.IntInstructionCount);
                    Assert.AreEqual(desc.MacroInstructionCount, container.Statistics.MacroInstructionCount);
                    Assert.AreEqual(desc.OutputParameters, container.OutputSignature.Parameters.Count);
                    Assert.AreEqual(desc.PatchConstantParameters, (container.PatchConstantSignature != null)
                                        ? container.PatchConstantSignature.Parameters.Count
                                        : 0);
                    Assert.AreEqual(desc.StaticFlowControlCount, container.Statistics.StaticFlowControlCount);
                    Assert.AreEqual(desc.TempArrayCount, container.Statistics.TempArrayCount);
                    Assert.AreEqual(desc.TempRegisterCount, container.Statistics.TempRegisterCount);
                    Assert.AreEqual((int)desc.TessellatorDomain, (int)container.Statistics.TessellatorDomain);
                    Assert.AreEqual(desc.TextureBiasInstructions, container.Statistics.TextureBiasInstructions);
                    Assert.AreEqual(desc.TextureCompInstructions, container.Statistics.TextureCompInstructions);
                    Assert.AreEqual(desc.TextureGradientInstructions, container.Statistics.TextureGradientInstructions);
                    Assert.AreEqual(desc.TextureLoadInstructions, container.Statistics.TextureLoadInstructions);
                    Assert.AreEqual(desc.TextureNormalInstructions, container.Statistics.TextureNormalInstructions);
                    Assert.AreEqual(desc.TextureStoreInstructions, container.Statistics.TextureStoreInstructions);
                    Assert.AreEqual(desc.UintInstructionCount, container.Statistics.UIntInstructionCount);

                    var version = Chunks.Common.ShaderVersion.FromShexToken((uint)desc.Version);
                    Assert.AreEqual(version.ToString(), container.ResourceDefinition.Target.ToString());

                    for (int i = 0; i < shaderReflection.Description.ConstantBuffers; i++)
                    {
                        CompareConstantBuffer(shaderReflection.GetConstantBuffer(i),
                                              container.ResourceDefinition.ConstantBuffers[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.BoundResources; i++)
                    {
                        CompareResourceBinding(shaderReflection.GetResourceBindingDescription(i),
                                               container.ResourceDefinition.ResourceBindings[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.InputParameters; i++)
                    {
                        CompareParameter(shaderReflection.GetInputParameterDescription(i),
                                         container.InputSignature.Parameters[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.OutputParameters; i++)
                    {
                        CompareParameter(shaderReflection.GetOutputParameterDescription(i),
                                         container.OutputSignature.Parameters[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.PatchConstantParameters; i++)
                    {
                        CompareParameter(shaderReflection.GetPatchConstantParameterDescription(i),
                                         container.PatchConstantSignature.Parameters[i]);
                    }
                }
        }
예제 #10
0
        private void PlatformConstruct(
            GraphicsDevice graphicsDevice,
            string functionName,
            byte[] deviceBytecode,
            out ShaderType shaderType,
            out ShaderResourceBinding[] resourceBindings)
        {
            DeviceBytecode = deviceBytecode;

            using (var shaderBytecode = new ShaderBytecode(DeviceBytecode))
            {
                switch (shaderBytecode.GetVersion().Version)
                {
                case ShaderVersion.VertexShader:
                    DeviceShader = AddDisposable(new VertexShader(graphicsDevice.Device, DeviceBytecode));
                    shaderType   = ShaderType.VertexShader;
                    break;

                case ShaderVersion.PixelShader:
                    DeviceShader = AddDisposable(new PixelShader(graphicsDevice.Device, DeviceBytecode));
                    shaderType   = ShaderType.PixelShader;
                    break;

                default:
                    throw new NotSupportedException();
                }
            }

            using (var reflection = new ShaderReflection(DeviceBytecode))
            {
                resourceBindings = new ShaderResourceBinding[reflection.Description.BoundResources];

                for (var i = 0; i < resourceBindings.Length; i++)
                {
                    var resourceDescription = reflection.GetResourceBindingDescription(i);

                    int constantBufferSizeInBytes;
                    ConstantBufferField[] constantBufferFields;
                    if (resourceDescription.Type == ShaderInputType.ConstantBuffer)
                    {
                        using (var constantBufferDesc = reflection.GetConstantBuffer(resourceDescription.Name))
                        {
                            constantBufferSizeInBytes = constantBufferDesc.Description.Size;
                            constantBufferFields      = new ConstantBufferField[constantBufferDesc.Description.VariableCount];
                            for (var j = 0; j < constantBufferFields.Length; j++)
                            {
                                var variable = constantBufferDesc.GetVariable(j);

                                constantBufferFields[j] = new ConstantBufferField(
                                    variable.Description.Name,
                                    variable.Description.StartOffset,
                                    variable.Description.Size);
                            }
                        }
                    }
                    else
                    {
                        constantBufferSizeInBytes = 0;
                        constantBufferFields      = null;
                    }

                    resourceBindings[i] = new ShaderResourceBinding(
                        resourceDescription.Name,
                        GetResourceType(resourceDescription.Type),
                        shaderType,
                        resourceDescription.BindPoint,
                        constantBufferSizeInBytes,
                        constantBufferFields);
                }
            }
        }
예제 #11
0
        private List <ConstantBuffer> ReflectConstantBuffers(ShaderReflection reflection)
        {
            var constantBuffers = new List <ConstantBuffer>();

            for (int cBufferIndex = 0; cBufferIndex < reflection.Description.ConstantBuffers; cBufferIndex++)
            {
                var cb             = reflection.GetConstantBuffer(cBufferIndex);
                var bindingDesc    = reflection.GetResourceBindingDescription(cb.Description.Name);
                var buf            = new Buffer(renderer.Device, cb.Description.Size, ResourceUsage.Dynamic, BindFlags.ConstantBuffer, CpuAccessFlags.Write, ResourceOptionFlags.None, sizeof(float));
                var constantBuffer = new ConstantBuffer(buf, bindingDesc.BindPoint);
                for (int i = 0; i < cb.Description.VariableCount; i++)
                {
                    var refVar = cb.GetVariable(i);
                    var type   = refVar.GetVariableType();
                    switch (type.Description.Type)
                    {
                    case ShaderVariableType.Float:
                        if (type.Description.RowCount == 4 && type.Description.ColumnCount == 4)
                        {
                            var matParam = new MatrixParameter(refVar.Description.StartOffset);
                            if (matParam.Size != refVar.Description.Size)
                            {
                                throw CargoEngineException.Create("Error ConstantBufferParamtersize");
                            }
                            constantBuffer.AddParameter(refVar.Description.Name, matParam);
                        }
                        if (type.Description.RowCount == 1)
                        {
                            switch (type.Description.ColumnCount)
                            {
                            case 2:
                                var vec2Param = new Vector2Parameter(refVar.Description.StartOffset);
                                if (vec2Param.Size != refVar.Description.Size)
                                {
                                    throw CargoEngineException.Create("Error ConstantBufferParamtersize");
                                }
                                constantBuffer.AddParameter(refVar.Description.Name, vec2Param);
                                break;

                            case 3:
                                var vec3Param = new Vector3Parameter(refVar.Description.StartOffset);
                                if (vec3Param.Size != refVar.Description.Size)
                                {
                                    throw CargoEngineException.Create("Error ConstantBufferParamtersize");
                                }
                                constantBuffer.AddParameter(refVar.Description.Name, vec3Param);
                                break;

                            case 4:
                                var vec4Param = new Vector4Parameter(refVar.Description.StartOffset);
                                if (vec4Param.Size != refVar.Description.Size)
                                {
                                    throw CargoEngineException.Create("Error ConstantBufferParamtersize");
                                }
                                constantBuffer.AddParameter(refVar.Description.Name, vec4Param);
                                break;
                            }
                        }
                        break;
                    }
                    constantBuffers.Add(constantBuffer);
                }
            }
            return(constantBuffers);
        }
예제 #12
0
        public void ShaderReflectionMatchesDirect3DReflection(string file)
        {
            // Arrange.
            var binaryFileBytes = File.ReadAllBytes(file + ".o");

            using (var shaderBytecode = ShaderBytecode.FromStream(new MemoryStream(binaryFileBytes)))
                using (var shaderReflection = new ShaderReflection(shaderBytecode))
                {
                    var desc = shaderReflection.Description;

                    // Act.
                    var container = BytecodeContainer.Parse(binaryFileBytes);

                    // Assert.
                    Assert.AreEqual(shaderReflection.BitwiseInstructionCount, 0);             // TODO
                    Assert.AreEqual(shaderReflection.ConditionalMoveInstructionCount, container.Statistics.MovCInstructionCount);
                    Assert.AreEqual(shaderReflection.ConversionInstructionCount, container.Statistics.ConversionInstructionCount);
                    Assert.AreEqual((int)shaderReflection.GeometryShaderSInputPrimitive, (int)container.Statistics.InputPrimitive);
                    Assert.AreEqual(shaderReflection.InterfaceSlotCount, container.ResourceDefinition.InterfaceSlotCount);
                    Assert.AreEqual((bool)shaderReflection.IsSampleFrequencyShader, container.Statistics.IsSampleFrequencyShader);
                    Assert.AreEqual(shaderReflection.MoveInstructionCount, container.Statistics.MovInstructionCount);
                    //Assert.AreEqual(shaderReflection.RequiresFlags, 0); // TODO

                    int  expectedSizeX, expectedSizeY, expectedSizeZ;
                    uint actualSizeX, actualSizeY, actualSizeZ;
                    shaderReflection.GetThreadGroupSize(out expectedSizeX, out expectedSizeY, out expectedSizeZ);
                    container.Shader.GetThreadGroupSize(out actualSizeX, out actualSizeY, out actualSizeZ);
                    Assert.AreEqual(expectedSizeX, actualSizeX);
                    Assert.AreEqual(expectedSizeY, actualSizeY);
                    Assert.AreEqual(expectedSizeZ, actualSizeZ);

                    //Assert.AreEqual((int) shaderReflection.MinFeatureLevel, 0); // TODO

                    Assert.AreEqual(desc.ArrayInstructionCount, container.Statistics.ArrayInstructionCount);
                    Assert.AreEqual(desc.BarrierInstructions, container.Statistics.BarrierInstructions);
                    Assert.AreEqual(desc.BoundResources, container.ResourceDefinition.ResourceBindings.Count);
                    Assert.AreEqual(desc.ConstantBuffers, container.ResourceDefinition.ConstantBuffers.Count);
                    Assert.AreEqual(desc.ControlPoints, container.Statistics.ControlPoints);
                    Assert.AreEqual(desc.Creator, container.ResourceDefinition.Creator);
                    Assert.AreEqual(desc.CutInstructionCount, container.Statistics.CutInstructionCount);
                    Assert.AreEqual(desc.DeclarationCount, container.Statistics.DeclarationCount);
                    Assert.AreEqual(desc.DefineCount, container.Statistics.DefineCount);
                    Assert.AreEqual(desc.DynamicFlowControlCount, container.Statistics.DynamicFlowControlCount);
                    Assert.AreEqual(desc.EmitInstructionCount, container.Statistics.EmitInstructionCount);
                    Assert.AreEqual((int)desc.Flags, (int)container.ResourceDefinition.Flags);
                    Assert.AreEqual(desc.FloatInstructionCount, container.Statistics.FloatInstructionCount);
                    Assert.AreEqual(desc.GeometryShaderInstanceCount, container.Statistics.GeometryShaderInstanceCount);
                    Assert.AreEqual(desc.GeometryShaderMaxOutputVertexCount, container.Statistics.GeometryShaderMaxOutputVertexCount);
                    Assert.AreEqual((int)desc.GeometryShaderOutputTopology, (int)container.Statistics.GeometryShaderOutputTopology);
                    Assert.AreEqual((int)desc.HullShaderOutputPrimitive, (int)container.Statistics.HullShaderOutputPrimitive);
                    Assert.AreEqual((int)desc.HullShaderPartitioning, (int)container.Statistics.HullShaderPartitioning);
                    Assert.AreEqual(desc.InputParameters, container.InputSignature.Parameters.Count);
                    Assert.AreEqual((int)desc.InputPrimitive, (int)container.Statistics.InputPrimitive);
                    Assert.AreEqual(desc.InstructionCount, container.Statistics.InstructionCount);
                    Assert.AreEqual(desc.InterlockedInstructions, container.Statistics.InterlockedInstructions);
                    Assert.AreEqual(desc.IntInstructionCount, container.Statistics.IntInstructionCount);
                    Assert.AreEqual(desc.MacroInstructionCount, container.Statistics.MacroInstructionCount);
                    Assert.AreEqual(desc.OutputParameters, container.OutputSignature.Parameters.Count);
                    Assert.AreEqual(desc.PatchConstantParameters, (container.PatchConstantSignature != null)
                                        ? container.PatchConstantSignature.Parameters.Count
                                        : 0);
                    Assert.AreEqual(desc.StaticFlowControlCount, container.Statistics.StaticFlowControlCount);
                    Assert.AreEqual(desc.TempArrayCount, container.Statistics.TempArrayCount);
                    Assert.AreEqual(desc.TempRegisterCount, container.Statistics.TempRegisterCount);
                    Assert.AreEqual((int)desc.TessellatorDomain, (int)container.Statistics.TessellatorDomain);
                    Assert.AreEqual(desc.TextureBiasInstructions, container.Statistics.TextureBiasInstructions);
                    Assert.AreEqual(desc.TextureCompInstructions, container.Statistics.TextureCompInstructions);
                    Assert.AreEqual(desc.TextureGradientInstructions, container.Statistics.TextureGradientInstructions);
                    Assert.AreEqual(desc.TextureLoadInstructions, container.Statistics.TextureLoadInstructions);
                    Assert.AreEqual(desc.TextureNormalInstructions, container.Statistics.TextureNormalInstructions);
                    Assert.AreEqual(desc.TextureStoreInstructions, container.Statistics.TextureStoreInstructions);
                    Assert.AreEqual(desc.UintInstructionCount, container.Statistics.UIntInstructionCount);
                    //Assert.AreEqual(desc.Version, container.ResourceDefinition.Target); // TODO

                    for (int i = 0; i < shaderReflection.Description.ConstantBuffers; i++)
                    {
                        CompareConstantBuffer(shaderReflection.GetConstantBuffer(i),
                                              container.ResourceDefinition.ConstantBuffers[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.BoundResources; i++)
                    {
                        CompareResourceBinding(shaderReflection.GetResourceBindingDescription(i),
                                               container.ResourceDefinition.ResourceBindings[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.InputParameters; i++)
                    {
                        CompareParameter(shaderReflection.GetInputParameterDescription(i),
                                         container.InputSignature.Parameters[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.OutputParameters; i++)
                    {
                        CompareParameter(shaderReflection.GetOutputParameterDescription(i),
                                         container.OutputSignature.Parameters[i]);
                    }

                    for (int i = 0; i < shaderReflection.Description.PatchConstantParameters; i++)
                    {
                        CompareParameter(shaderReflection.GetPatchConstantParameterDescription(i),
                                         container.PatchConstantSignature.Parameters[i]);
                    }
                }
        }
예제 #13
0
파일: Shader.cs 프로젝트: K0bin/DotGame
        public Shader(GraphicsDevice graphicsDevice, string name, ShaderBytecode vertex, ShaderBytecode pixel)
            : base(graphicsDevice, new StackTrace(1))
        {
            if (name == null)
            {
                throw new ArgumentNullException("name");
            }
            if (string.IsNullOrWhiteSpace(name))
            {
                throw new ArgumentException("Name is empty or whitespace.", "name");
            }
            if (vertex == null)
            {
                throw new ArgumentNullException("vertex");
            }
            if (pixel == null)
            {
                throw new ArgumentNullException("pixel");
            }

            this.Name       = name;
            this.VertexCode = vertex;
            this.PixelCode  = pixel;

            using (ShaderReflection reflection = new ShaderReflection(VertexCode))
            {
                for (int i = 0; i < reflection.Description.BoundResources; i++)
                {
                    var res = reflection.GetResourceBindingDescription(i);
                    resourcesVertex[res.Name] = res.BindPoint;

                    if (res.Type == ShaderInputType.ConstantBuffer)
                    {
                        constantBufferSizes[res.Name] = reflection.GetConstantBuffer(res.Name).Description.Size;
                    }
                }

                int inputCount     = reflection.Description.InputParameters;
                var vertexElements = new VertexElement[inputCount];
                for (int i = 0; i < inputCount; i++)
                {
                    var input = reflection.GetInputParameterDescription(i);
                    if (input.ComponentType != RegisterComponentType.Float32)
                    {
                        continue;
                    }

                    VertexElementType type;
                    if (input.UsageMask.HasFlag(RegisterComponentMaskFlags.All))
                    {
                        type = VertexElementType.Vector4;
                    }
                    else if (input.UsageMask.HasFlag(RegisterComponentMaskFlags.ComponentX | RegisterComponentMaskFlags.ComponentY | RegisterComponentMaskFlags.ComponentZ))
                    {
                        type = VertexElementType.Vector3;
                    }
                    else if (input.UsageMask.HasFlag(RegisterComponentMaskFlags.ComponentX | RegisterComponentMaskFlags.ComponentY))
                    {
                        type = VertexElementType.Vector2;
                    }
                    else if (input.UsageMask.HasFlag(RegisterComponentMaskFlags.ComponentX))
                    {
                        type = VertexElementType.Single;
                    }
                    else
                    {
                        continue;
                    }

                    VertexElementUsage usage = EnumConverter.ConvertToUsage(input.SemanticName);

                    vertexElements[i] = new VertexElement(usage, input.SemanticIndex, type);
                }
                VertexDescription = new VertexDescription(vertexElements);
            }

            using (ShaderReflection reflection = new ShaderReflection(PixelCode))
            {
                for (int i = 0; i < reflection.Description.BoundResources; i++)
                {
                    var res = reflection.GetResourceBindingDescription(i);
                    resourcesPixel[res.Name] = res.BindPoint;

                    if (res.Type == ShaderInputType.ConstantBuffer)
                    {
                        constantBufferSizes[res.Name] = reflection.GetConstantBuffer(res.Name).Description.Size;
                    }
                }
            }

            VertexShaderHandle = new VertexShader(graphicsDevice.Device, VertexCode);
            PixelShaderHandle  = new PixelShader(graphicsDevice.Device, PixelCode);

            using (MemoryStream stream = new MemoryStream())
                using (BinaryWriter writer = new BinaryWriter(stream))
                {
                    writer.Write("DIRECTX11");
                    writer.Write(VertexCode.Data.Length);
                    writer.Write(VertexCode.Data);
                    writer.Write(PixelCode.Data.Length);
                    writer.Write(PixelCode.Data);
                    binaryCode = stream.GetBuffer();
                }
        }