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); } } } }
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); }
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; } } } } }
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; } } } }
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); } } }
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; } } } }
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)); }
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 }
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]); } } }
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); } } }
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); }
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]); } } }
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(); } }