public ShaderReflection GetShaderReflection() { ShaderReflection shaderReflection = new ShaderReflection(); int location; foreach (var p in _programs) { foreach (var item in p.Declarations) { if (item is GlobalVariableDeclaration) { GlobalVariableDeclaration vd = (GlobalVariableDeclaration)item; shaderReflection.Variables.Add(GetReflectionVariable(vd)); } else if (item is ConstantBufferDeclaration) { ConstantBufferDeclaration cb = (ConstantBufferDeclaration)item; BufferReflection buffer = new BufferReflection() { Type = cb.Type, Name = cb.Name }; foreach (var c in cb.Constants) { buffer.Constants.Add(GetReflectionVariable(c)); } shaderReflection.Buffers.Add(buffer); } } } return(shaderReflection); }
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); } } } }
public ShaderResource( String resource_name, ShaderReflection psReflection, ShaderReflection vsReflection ) { // try to find it in pixel shader try { // find the bind point of the resource Slot = psReflection.GetResourceBindingDescription( resource_name ).BindPoint; // set that the resource exist isPsExist = true; } catch ( Exception ex ) { // set the resource unusable isPsExist = false; } // try to find it in vertex shader try { // find the bind point of the resource Slot = vsReflection.GetResourceBindingDescription( resource_name ).BindPoint; // set that the resource exist isVsExist = true; } catch ( Exception ex ) { // set the resource unusable isVsExist = false; } }
private void Update(EvaluationContext context) { var resourceManager = ResourceManager.Instance(); if (Source.DirtyFlag.IsDirty || EntryPoint.DirtyFlag.IsDirty || DebugName.DirtyFlag.IsDirty) { string sourcePath = Source.GetValue(context); string entryPoint = EntryPoint.GetValue(context); string debugName = DebugName.GetValue(context); if (string.IsNullOrEmpty(debugName) && !string.IsNullOrEmpty(sourcePath)) { debugName = new FileInfo(sourcePath).Name; } _computeShaderResId = resourceManager.CreateComputeShaderFromFile(sourcePath, entryPoint, debugName, () => ComputerShader.DirtyFlag.Invalidate()); Log.Debug($"compute shader {sourcePath}:{entryPoint}", SymbolChildId); } else { resourceManager.UpdateComputeShaderFromFile(Source.Value, _computeShaderResId, ref ComputerShader.Value); } if (_computeShaderResId != ResourceManager.NullResource) { ComputerShader.Value = resourceManager.GetComputeShader(_computeShaderResId); var shaderReflection = new ShaderReflection(resourceManager.GetComputeShaderBytecode(_computeShaderResId)); shaderReflection.GetThreadGroupSize(out int x, out int y, out int z); ThreadCount.Value = new Int3(x, y, z); } }
private static bool DoesConstantBufferExist(ShaderReflection reflection, int slot, string name) { InputBindingDescription bindingDesc; try { bindingDesc = reflection.GetResourceBindingDescription(name); if (bindingDesc.BindPoint != slot) { throw new InvalidOperationException($"Mismatched binding slot for {name}. Expected: {slot}, Actual: {bindingDesc.BindPoint}"); } return(true); } catch (SharpDX.SharpDXException) { for (int i = 0; i < reflection.Description.BoundResources; i++) { var desc = reflection.GetResourceBindingDescription(i); if (desc.Type == ShaderInputType.ConstantBuffer && desc.BindPoint == slot) { Console.WriteLine("Buffer in slot " + slot + " has wrong name. Expected: " + name + ", Actual: " + desc.Name); bindingDesc = desc; return(true); } } } return(false); }
public static T CompileFromResource <T>(DxDevice device, Assembly assembly, string path, string entrypoint, out ShaderReflection reflectiondata) where T : class { ShaderBytecode sb = CompileFromResource(assembly, path, GetShaderProfile <T>(device), entrypoint); reflectiondata = new ShaderReflection(sb); return(GetShaderInstance <T>(device, sb)); }
private void InitDeadParticleIndices() { // init the buffer var resourceManager = ResourceManager.Instance(); resourceManager.SetupStructuredBuffer(ParticleIndexSizeInBytes * MaxCount, ParticleIndexSizeInBytes, ref DeadParticleIndices); resourceManager.CreateStructuredBufferUav(DeadParticleIndices, UnorderedAccessViewBufferFlags.Append, ref DeadParticleIndicesUav); // init counter of the dead list buffer (must be done due to uav binding) ComputeShader deadListInitShader = resourceManager.GetComputeShader(_initDeadListShaderResId); var device = resourceManager.Device; var deviceContext = device.ImmediateContext; var csStage = deviceContext.ComputeShader; var prevShader = csStage.Get(); var prevUavs = csStage.GetUnorderedAccessViews(0, 1); // set and call the init shader var reflectedShader = new ShaderReflection(resourceManager.GetComputeShaderBytecode(_initDeadListShaderResId)); reflectedShader.GetThreadGroupSize(out int x, out int y, out int z); csStage.Set(deadListInitShader); csStage.SetUnorderedAccessView(0, DeadParticleIndicesUav, 0); int dispatchCount = MaxCount / (x > 0 ? x : 1); Log.Info($"particle system: maxcount {MaxCount} dispatchCount: {dispatchCount} *64: {dispatchCount*64}"); deviceContext.Dispatch(dispatchCount, 1, 1); // restore prev setup csStage.SetUnorderedAccessView(0, prevUavs[0]); csStage.Set(prevShader); }
private static Script TranslateShaderViaReflection(byte[] vertexShader, byte[] fragmentShader) { var vertexInstructions = Shader.Parse(vertexShader); var vertexReflection = new ShaderReflection(vertexInstructions); var fragmentInstructions = Shader.Parse(fragmentShader); var fragmentReflection = new ShaderReflection(fragmentInstructions); return(ShaderScriptConverter.Convert(vertexReflection, fragmentReflection)); }
public void SetGLSL(string vertexSource, string fragmentSource, bool debug = true) { var vertexBytes = Veldrid.SPIRV.SpirvCompilation.CompileGlslToSpirv(vertexSource, "shader.spv", ShaderStages.Vertex, new GlslCompileOptions(debug)); var vertexReflection = new ShaderReflection(Shader.Parse(vertexBytes.SpirvBytes)); var fragmentBytes = Veldrid.SPIRV.SpirvCompilation.CompileGlslToSpirv(fragmentSource, "shader.spv", ShaderStages.Fragment, new GlslCompileOptions(debug)); var fragmentReflection = new ShaderReflection(Shader.Parse(fragmentBytes.SpirvBytes)); Script.Script = ShaderScriptConverter.Convert(vertexReflection, fragmentReflection); }
private static byte[] TranslateShaderViaReflection(byte[] vertexShader) { var instructions = Shader.Parse(vertexShader); var reflection = new ShaderReflection(instructions); var shader = reflection.BuildShader(); var generatedBytecode = shader.Build(); return(generatedBytecode); }
public void TestAlignment(TypeStructureField field) { var(shaderInstructions, shaders) = CompileShaderForFieldSet(new TypeStruct("ModelBuffer", marker, field)); var shaderReflection = new ShaderReflection(shaderInstructions); var structure = shaderReflection.Structures[0]; Assert.AreEqual(structure.Fields[1].ByteOffset, structure.Fields[1].Type.Alignment); }
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 virtual void WriteStructs() { var structs = new ShaderReflection(_shader).Structures .Where(_ => _.DebugName != "gl_PerVertex") .ToList(); for (var index = 0; index < structs.Count; index++) { var opTypeStruct = structs[index]; WriteStruct(opTypeStruct); } }
// load and compile the vertex shader private void LoadVertexShader() { try { if (_shaderEntryPoint.VertexShader_EntryPoint != null) { ShaderBytecode byteCode; //Check if existance of precompiled file FileInfo fi = new FileInfo(_filePathName); string precompiledFileName = string.Concat(fi.DirectoryName, @"\", Path.GetFileNameWithoutExtension(fi.Name), "_", _shaderEntryPoint.VertexShader_EntryPoint, ".chlsl"); if (File.Exists(precompiledFileName)) { //Load precompiled Blob byteCode = ShaderBytecode.FromFile(precompiledFileName); } else { //Live compiling CompilationResult result = ShaderBytecode.CompileFromFile(_filePathName, _shaderEntryPoint.VertexShader_EntryPoint, VSProfiles.DirectX10Profile, D3DEngine.ShaderFlags, EffectFlags.None, null, _includeHandler); //Log Compilation Warning if (result.Message != null) { logger.Warn("Vertex Shader [{0}] compilation message returned :\n{1}", _fileName, result.Message); } byteCode = result.Bytecode; } //Get the VS Input signature from the Vertex Shader _signature = ToDispose(ShaderSignature.GetInputSignature(byteCode)); //Create the inputLayout from the signature (Must Match the Vertex Format used with this effect !!!) if (_vertexDeclaration != null) { _inputLayout = ToDispose(new InputLayout(device, _signature, _vertexDeclaration.Elements)); } _vs = ToDispose(new VertexShader(device, byteCode)); #if DEBUG //Set resource Name, will only be done at debug time. _vs.DebugName = "VertexShader from " + _fileName; #endif using (ShaderReflection shaderMetaData = new ShaderReflection(byteCode)) { ShaderReflection(Shaders.VS, ShaderIDs.VS, shaderMetaData); } byteCode.Dispose(); } } catch (Exception e) { throw new Exception("Shader compilation error : " + e.Message); } }
private T ReflectBytecode <T, U>(ShaderBytecode bytecode) where T : ShaderBase <U> where U : DeviceChild { var inputSignature = ShaderSignature.GetInputSignature(bytecode); var shaderPtr = Activator.CreateInstance(typeof(U), new object[] { renderer.Device, bytecode.Data, null }) as U; using (var reflection = new ShaderReflection(bytecode)) { var(textures, samplers) = ReflectResources(reflection); var constantBuffers = ReflectConstantBuffers(reflection); var shader = Activator.CreateInstance(typeof(T), new object[] { inputSignature, shaderPtr, constantBuffers, textures, samplers }) as T; shaderPtr = null; return(shader); } }
public Script Convert(ShaderReflection vertexShader, ShaderReflection fragmentShader) { ValidateShader(vertexShader, nameof(vertexShader)); ValidateShader(fragmentShader, nameof(fragmentShader)); var vertex = VisitFunction(vertexShader.EntryPointInstructions[0].Value); var fragment = VisitFunction(fragmentShader.EntryPointInstructions[0].Value); var helper = new ScriptHelper(_script); EliminateLabels(helper); return(helper.BuildScript()); }
public void EmptyShaderReflectionTest() { byte[] vertexByteCode; byte[] framentByteCode; { var vertexShaderMain = new Function(Spv.FunctionControl.CreateNone(), new TypeFunction() { ReturnType = SpirvTypeBase.Void }, "main") .SetUp(_ => _ .ThenLabel() .ThenReturn() ); var shader = new ShaderReflection() .WithCapability(Capability.Shader()) .WithExtInstImport("GLSL.std.450") .WithMemoryModel(AddressingModel.Logical(), MemoryModel.GLSL450()) .WithEntryPoint(ExecutionModel.Vertex(), vertexShaderMain) .BuildShader(); vertexByteCode = shader.Build(); } { var fragmentShaderMain = new Function(Spv.FunctionControl.CreateNone(), new TypeFunction() { ReturnType = SpirvTypeBase.Void }, "main") .SetUp(_ => _ .ThenLabel() .ThenReturn() ); var shader = new ShaderReflection() .WithCapability(Capability.Shader()) .WithExtInstImport("GLSL.std.450") .WithMemoryModel(AddressingModel.Logical(), MemoryModel.GLSL450()) .WithEntryPoint(ExecutionModel.Fragment(), fragmentShaderMain) .BuildShader(); framentByteCode = shader .Build(); } var shaders = ResourceFactory.CreateFromSpirv( new ShaderDescription(ShaderStages.Vertex, vertexByteCode, "main"), new ShaderDescription(ShaderStages.Fragment, framentByteCode, "main")); var readRenderTargetPixel = RenderQuad(shaders); Assert.AreEqual(new RgbaByte(0, 0, 0, 255), readRenderTargetPixel); }
public void UnsizedArray() { var(vertexBytes, shaderInstructions) = CompileToBytecode(@"#version 450 layout(set = 0, binding = 0) uniform ModelBuffer { int unsizedArray[]; }; void main() { gl_Position = vec4(unsizedArray[0],0,0.5,1); }"); var shaderReflection = new ShaderReflection(shaderInstructions); var structure = shaderReflection.Structures[0]; }
public ComputeShader(GraphicsDevice device, string fileName, string kernel) { this.Device = device.Handle as Device; this.Context = this.Device.ImmediateContext; var byteCode = ShaderBytecode.CompileFromFile(fileName, kernel, "cs_5_0"); this.Shader = new SharpDX.Direct3D11.ComputeShader(this.Device, byteCode); this.Resources = new Dictionary <string, ResourceBinding>(); using (var reflector = new ShaderReflection(byteCode)) { this.ReflectInputs(reflector, fileName); } }
// Set a shader stage's resources and values private void SetShaderState(FetchTexture[] texs, FetchBuffer[] bufs, GLPipelineState.ShaderStage stage, Label shader, TreelistView.TreeListView resources, TreelistView.TreeListView samplers, TreelistView.TreeListView cbuffers, TreelistView.TreeListView classes) { ShaderReflection shaderDetails = stage.ShaderDetails; if (stage.Shader == ResourceId.Null) { shader.Text = "Unbound"; } else { shader.Text = "Shader " + stage.Shader.ToString(); } if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc != "" && shaderDetails.DebugInfo.files.Length > 0) { shader.Text = shaderDetails.DebugInfo.entryFunc + "()" + " - " + Path.GetFileName(shaderDetails.DebugInfo.files[0].filename); } cbuffers.BeginUpdate(); cbuffers.Nodes.Clear(); if (shaderDetails != null) { UInt32 i = 0; foreach (var shaderCBuf in shaderDetails.ConstantBlocks) { { string name = shaderCBuf.name; int numvars = shaderCBuf.variables.Length; string slotname = i.ToString(); var node = cbuffers.Nodes.Add(new object[] { slotname, name, "", "", numvars, "" }); node.Image = global::renderdocui.Properties.Resources.action; node.HoverImage = global::renderdocui.Properties.Resources.action_hover; node.Tag = i; } i++; } } cbuffers.EndUpdate(); cbuffers.NodesSelection.Clear(); }
public void TestArrayAlignment(TypeStructureField field) { if (field.Type.TypeCategory == SpirvTypeCategory.Array) { Assert.Ignore("Can't make array of arrays."); } var originalArrayType = new TypeArray(field.Type, 2); var(shaderInstructions, shaders) = CompileShaderForFieldSet(new TypeStruct("ModelBuffer", marker, new TypeStructureField(originalArrayType, "testArray"))); var shaderReflection = new ShaderReflection(shaderInstructions); var structure = shaderReflection.Structures[0]; var spirvStructureField = structure.Fields[1]; var arrayType = (TypeArray)spirvStructureField.Type; Assert.AreEqual(spirvStructureField.ByteOffset, spirvStructureField.Type.Alignment); Assert.AreEqual(arrayType.ArrayStride, originalArrayType.ArrayStride); }
// load and compile the pixel shader private void LoadPixelShader() { try { if (_shaderEntryPoint.PixelShader_EntryPoint != null) { ShaderBytecode byteCode; //Check if existance of precompiled file FileInfo fi = new FileInfo(_filePathName); string precompiledFileName = string.Concat(fi.DirectoryName, @"\", Path.GetFileNameWithoutExtension(fi.Name), "_", _shaderEntryPoint.PixelShader_EntryPoint, ".chlsl"); if (File.Exists(precompiledFileName)) { //Load precompiled Blob byteCode = ShaderBytecode.FromFile(precompiledFileName); } else { //Live compiling CompilationResult result = ShaderBytecode.CompileFromFile(_filePathName, _shaderEntryPoint.PixelShader_EntryPoint, PSProfiles.DirectX10Profile, D3DEngine.ShaderFlags, EffectFlags.None, null, _includeHandler); //Log Compilation Warning if (result.Message != null) { logger.Warn("Pixel Shader [{0}] compilation message returned :\n{1}", _fileName, result.Message); } byteCode = result.Bytecode; } _ps = ToDispose(new PixelShader(device, byteCode)); #if DEBUG //Set resource Name, will only be done at debug time. _ps.DebugName = "PixelShader from " + _fileName; #endif using (ShaderReflection shaderMetaData = new ShaderReflection(byteCode)) { ShaderReflection(Shaders.PS, ShaderIDs.PS, shaderMetaData); } byteCode.Dispose(); } } catch (Exception e) { throw new Exception("Shader compilation error : " + e.Message); } }
private void ReflectInputs(ShaderReflection reflector, string filename) { for (var i = 0; i < reflector.Description.BoundResources; i++) { var description = reflector.GetResourceBindingDescription(i); var register = description.BindPoint; var name = description.Name; var type = description.Type switch { ShaderInputType.ConstantBuffer => ShaderResourceType.ConstantBuffer, ShaderInputType.Structured => ShaderResourceType.StructuredBuffer, ShaderInputType.UnorderedAccessViewRWStructured => ShaderResourceType.RWStructuredBuffer, _ => throw new System.NotSupportedException($"Shader {filename} contains unsupported resource type {description.Type}") }; this.Resources.Add(name, new ResourceBinding(register, name, type)); } }
private void shader_Click(object sender, EventArgs e) { GLPipelineState.ShaderStage stage = GetStageForSender(sender); if (stage == null) { return; } ShaderReflection shaderDetails = stage.ShaderDetails; if (stage.Shader == ResourceId.Null) { return; } ShaderViewer s = new ShaderViewer(m_Core, shaderDetails, stage.stage, null, ""); s.Show(m_DockContent.DockPanel); }
private void debugToolStripMenuItem_Click(object sender, EventArgs e) { if (events.SelectedNode == null) { return; } var node = events.SelectedNode; if (node.Tag is EventTag) { EventTag tag = (EventTag)node.Tag; m_Core.SetEventID(this, m_Core.CurFrame, tag.EID); ShaderDebugTrace trace = null; ShaderReflection shaderDetails = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Pixel); m_Core.Renderer.Invoke((ReplayRenderer r) => { trace = r.DebugPixel((UInt32)pixel.X, (UInt32)pixel.Y, sample, tag.Primitive); }); if (trace == null || trace.states.Length == 0) { MessageBox.Show("Error debugging pixel.", "Debug Error", MessageBoxButtons.OK, MessageBoxIcon.Error); return; } this.BeginInvoke(new Action(() => { string debugContext = String.Format("Pixel {0},{1}", pixel.X, pixel.Y); ShaderViewer s = new ShaderViewer(m_Core, shaderDetails, ShaderStageType.Pixel, trace, debugContext); s.Show(this.DockPanel); })); } }
public void SetShader(string vs, string ps) { Dispose(); if (string.IsNullOrEmpty(vs) || string.IsNullOrEmpty(ps)) { return; } m_vsCompiled = ShaderBytecode.Compile(vs, "VS", "vs_4_0", ShaderFlags.None, EffectFlags.None); m_psCompiled = ShaderBytecode.Compile(ps, "PS", "ps_4_0", ShaderFlags.None, EffectFlags.None); using (var reflection = new ShaderReflection(m_vsCompiled.Bytecode)) { InputElements.Value = Enumerable.Range(0, reflection.Description.InputParameters) .Select(x => reflection.GetInputParameterDescription(x)) .Select(x => ToInputElement(x)) .ToArray() ; } m_updated.OnNext(Unit.Default); }
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; } } } }
private static void ValidateShader(ShaderReflection vertexShader, string vertexShaderName) { if (vertexShader == null) { throw new ArgumentNullException($"{vertexShaderName} should not be null"); } if (vertexShader.EntryPointInstructions.Count != 1) { throw new ArgumentException($"{vertexShaderName} expected to have exactly one entry point"); } if (vertexShader.EntryPointInstructions[0].Value.ResultType != SpirvTypeBase.Void) { throw new ArgumentException($"{vertexShaderName} entry point should have void result type"); } if (vertexShader.EntryPointInstructions[0].Value.Parameters.Count != 0) { throw new ArgumentException($"{vertexShaderName} entry point should not have arguments"); } if (((TypeFunction)vertexShader.EntryPointInstructions[0].Value.FunctionType).Arguments.Count != 0) { throw new ArgumentException($"{vertexShaderName} entry point should not have arguments"); } }
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)); }