public ConstantBufferDescription(ConstantBuffer buffer) { Name = buffer.Description.Name; StructSize = StrideSize = buffer.Description.Size; Variables = new List <ConstantBufferVariable>(); for (int i = 0; i < buffer.Description.VariableCount; ++i) { var variable = buffer.GetVariable(i); Variables.Add(new ConstantBufferVariable() { Name = variable.Description.Name, Size = variable.Description.Size, StartOffset = variable.Description.StartOffset }); } }
private void ValidateConstantBufferReflection(ConstantBuffer constantBufferRaw, ref ConstantBufferDescription constantBufferRawDesc, EffectConstantBufferDescription constantBuffer, LoggerResult log) { switch (constantBufferRawDesc.Type) { case SharpDX.D3DCompiler.ConstantBufferType.ConstantBuffer: if (constantBuffer.Type != ConstantBufferType.ConstantBuffer) { log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.ConstantBuffer}"); } break; case SharpDX.D3DCompiler.ConstantBufferType.TextureBuffer: if (constantBuffer.Type != ConstantBufferType.TextureBuffer) { log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.TextureBuffer}"); } break; default: if (constantBuffer.Type != ConstantBufferType.Unknown) { log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.Unknown}"); } break; } // ConstantBuffers variables for (int i = 0; i < constantBufferRawDesc.VariableCount; i++) { var variable = constantBufferRaw.GetVariable(i); var variableType = variable.GetVariableType(); var variableDescription = variable.Description; var variableTypeDescription = variableType.Description; if (variableTypeDescription.Offset != 0) { log.Error($"Unexpected offset [{variableTypeDescription.Offset}] for variable [{variableDescription.Name}] in constant buffer [{constantBuffer.Name}]"); } var binding = constantBuffer.Members[i]; // Retrieve Link Member if (binding.RawName != variableDescription.Name) { log.Error($"Variable [{variableDescription.Name}] in constant buffer [{constantBuffer.Name}] has no link"); } else { var parameter = new EffectValueDescription() { Type = { Class = (EffectParameterClass)variableTypeDescription.Class, Type = ConvertVariableValueType(variableTypeDescription.Type, log), Elements = variableTypeDescription.ElementCount, RowCount = (byte)variableTypeDescription.RowCount, ColumnCount = (byte)variableTypeDescription.ColumnCount, }, RawName = variableDescription.Name, Offset = variableDescription.StartOffset, Size = variableDescription.Size, }; if (parameter.Offset != binding.Offset || parameter.Size != binding.Size || parameter.Type.Elements != binding.Type.Elements || ((parameter.Type.Class != EffectParameterClass.Struct) && // Ignore columns/rows if it's a struct (sometimes it contains weird data) (parameter.Type.RowCount != binding.Type.RowCount || parameter.Type.ColumnCount != binding.Type.ColumnCount))) { log.Error($"Variable [{variableDescription.Name}] in constant buffer [{constantBuffer.Name}] binding doesn't match what was expected"); } } } if (constantBuffer.Size != constantBufferRawDesc.Size) { log.Error($"Error precomputing buffer size for {constantBuffer.Name}: {constantBuffer.Size} instead of {constantBufferRawDesc.Size}"); } }
private ShaderConstantBufferDescription GetConstantBufferReflection(ConstantBuffer constantBufferRaw, ref ConstantBufferDescription constantBufferRawDesc, ShaderConstantBufferDescription linkBuffer, LoggerResult log) { var constantBuffer = new ShaderConstantBufferDescription { Name = constantBufferRawDesc.Name, Size = constantBufferRawDesc.Size, }; switch (constantBufferRawDesc.Type) { case SharpDX.D3DCompiler.ConstantBufferType.ConstantBuffer: constantBuffer.Type = ConstantBufferType.ConstantBuffer; break; case SharpDX.D3DCompiler.ConstantBufferType.TextureBuffer: constantBuffer.Type = ConstantBufferType.TextureBuffer; break; default: constantBuffer.Type = ConstantBufferType.Unknown; break; } // ConstantBuffers variables var members = new List<EffectParameterValueData>(); for (int i = 0; i < constantBufferRawDesc.VariableCount; i++) { var variable = constantBufferRaw.GetVariable(i); var variableType = variable.GetVariableType(); var variableDescription = variable.Description; var variableTypeDescription = variableType.Description; var parameter = new EffectParameterValueData() { Param = { Class = (EffectParameterClass)variableTypeDescription.Class, Type = ConvertVariableValueType(variableTypeDescription.Type, log), RawName = variableDescription.Name, }, Offset = variableDescription.StartOffset, Size = variableDescription.Size, Count = variableTypeDescription.ElementCount == 0 ? 1 : variableTypeDescription.ElementCount, RowCount = (byte)variableTypeDescription.RowCount, ColumnCount = (byte)variableTypeDescription.ColumnCount, }; if (variableTypeDescription.Offset != 0) { log.Error("Unexpected offset [{0}] for variable [{1}] in constant buffer [{2}]", variableTypeDescription.Offset, variableDescription.Name, constantBuffer.Name); } bool bindingNotFound = true; // Retrieve Link Member foreach (var binding in linkBuffer.Members) { if (binding.Param.RawName == variableDescription.Name) { // TODO: should we replicate linkMember.Count/RowCount/ColumnCount? or use what is retrieved by D3DCompiler reflection parameter.Param.KeyName = binding.Param.KeyName; bindingNotFound = false; break; } } if (bindingNotFound) { log.Error("Variable [{0}] in constant buffer [{1}] has no link", variableDescription.Name, constantBuffer.Name); } members.Add(parameter); } constantBuffer.Members = members.ToArray(); return constantBuffer; }
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 }
/// <summary> /// コンスタントバッファインスタンスを返す /// </summary> /// <param name="name"></param> /// <returns></returns> public ConstantBufferInstance CreateConstantBufferInstance(string name) { // コンスタントバッファの実体をとってきて確実にある状況でGetResourceBindingDescriptionを呼ぶ int cb_num = reflector_.Description.ConstantBuffers; ConstantBuffer cb = null; for (int i = 0; i < cb_num; i++) { var tmp = reflector_.GetConstantBuffer(i); if (tmp.Description.Name == name) { cb = tmp; } } if (cb == null) { return(null); } //Util.Assert(cb != null); // インスタンスを作って返す Dictionary <string, ConstantBufferInstance.VariableData> cbuffer_desc = new Dictionary <string, ConstantBufferInstance.VariableData>(); for (int v = 0; v < cb.Description.Variables; v++) { var variable = cb.GetVariable(v); int offset = variable.Description.StartOffset; int size = variable.Description.Size; var var_type = variable.GetVariableType(); System.Type type = null; switch (var_type.Description.Class) { case ShaderVariableClass.MatrixColumns: type = typeof(SlimDX.Matrix); break; case ShaderVariableClass.Vector: switch (var_type.Description.Columns) { case 2: type = typeof(SlimDX.Vector2); break; case 3: type = typeof(SlimDX.Vector3); break; case 4: type = typeof(SlimDX.Vector4); break; } break; case ShaderVariableClass.Scalar: switch (var_type.Description.Type) { case ShaderVariableType.Float: type = typeof(float); break; case ShaderVariableType.UInt: type = typeof(uint); break; case ShaderVariableType.Int: type = typeof(int); break; } break; default: Util.Assert(false); break; } //Console.WriteLine("{0}", type.Description.Class); if (var_type.Description.Elements == 0) { cbuffer_desc[variable.Description.Name] = new ConstantBufferInstance.VariableData() { type = type, offset = offset, size = size }; } else { int cur_offset = offset; size = size / var_type.Description.Elements; for (int i = 0; i < var_type.Description.Elements; i++) { cbuffer_desc[variable.Description.Name + "_" + i] = new ConstantBufferInstance.VariableData() { type = type, offset = cur_offset, size = size }; cur_offset += size; } } } return(new ConstantBufferInstance(cbuffer_desc)); }
private void ValidateConstantBufferReflection(ConstantBuffer constantBufferRaw, ref ConstantBufferDescription constantBufferRawDesc, EffectConstantBufferDescription constantBuffer, LoggerResult log) { switch (constantBufferRawDesc.Type) { case SharpDX.D3DCompiler.ConstantBufferType.ConstantBuffer: if (constantBuffer.Type != ConstantBufferType.ConstantBuffer) log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.ConstantBuffer}"); break; case SharpDX.D3DCompiler.ConstantBufferType.TextureBuffer: if (constantBuffer.Type != ConstantBufferType.TextureBuffer) log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.TextureBuffer}"); break; default: if (constantBuffer.Type != ConstantBufferType.Unknown) log.Error($"Invalid buffer type for {constantBuffer.Name}: {constantBuffer.Type} instead of {ConstantBufferType.Unknown}"); break; } // ConstantBuffers variables for (int i = 0; i < constantBufferRawDesc.VariableCount; i++) { var variable = constantBufferRaw.GetVariable(i); var variableType = variable.GetVariableType(); var variableDescription = variable.Description; var variableTypeDescription = variableType.Description; if (variableTypeDescription.Offset != 0) { log.Error("Unexpected offset [{0}] for variable [{1}] in constant buffer [{2}]", variableTypeDescription.Offset, variableDescription.Name, constantBuffer.Name); } var binding = constantBuffer.Members[i]; // Retrieve Link Member if (binding.RawName != variableDescription.Name) { log.Error("Variable [{0}] in constant buffer [{1}] has no link", variableDescription.Name, constantBuffer.Name); } else { var parameter = new EffectValueDescription() { Type = { Class = (EffectParameterClass)variableTypeDescription.Class, Type = ConvertVariableValueType(variableTypeDescription.Type, log), Elements = variableTypeDescription.ElementCount, RowCount = (byte)variableTypeDescription.RowCount, ColumnCount = (byte)variableTypeDescription.ColumnCount, }, RawName = variableDescription.Name, Offset = variableDescription.StartOffset, Size = variableDescription.Size, }; if (parameter.Offset != binding.Offset || parameter.Size != binding.Size || parameter.Type.Elements != binding.Type.Elements || ((parameter.Type.Class != EffectParameterClass.Struct) && // Ignore columns/rows if it's a struct (sometimes it contains weird data) (parameter.Type.RowCount != binding.Type.RowCount || parameter.Type.ColumnCount != binding.Type.ColumnCount))) { log.Error("Variable [{0}] in constant buffer [{1}] binding doesn't match what was expected", variableDescription.Name, constantBuffer.Name); } } } if (constantBuffer.Size != constantBufferRawDesc.Size) { log.Error($"Error precomputing buffer size for {constantBuffer.Name}: {constantBuffer.Size} instead of {constantBufferRawDesc.Size}"); } }