public static DebugConstantBuffer Parse(
            DebugBytecodeReader reader, DebugBytecodeReader constantBufferReader,
            DebugShaderVersion target)
        {
            uint nameOffset     = constantBufferReader.ReadUInt32("nameOffset");
            var  nameReader     = reader.CopyAtOffset("nameReader", constantBufferReader, (int)nameOffset);
            var  name           = nameReader.ReadString("name");
            uint variableCount  = constantBufferReader.ReadUInt32("variableCount");
            uint variableOffset = constantBufferReader.ReadUInt32("variableOffset");

            var result = new DebugConstantBuffer
            {
                Name = name
            };

            var variableReader = reader.CopyAtOffset("variableReader", constantBufferReader, (int)variableOffset);

            for (int i = 0; i < variableCount; i++)
            {
                variableReader.AddIndent($"Variable {i}");
                result.Variables.Add(DebugShaderVariable.Parse(reader, variableReader, target, i == 0));
                variableReader.RemoveIndent();
            }
            result.Size       = constantBufferReader.ReadUInt32("size");
            result.Flags      = (ConstantBufferFlags)constantBufferReader.ReadUInt32("Flags");
            result.BufferType = (ConstantBufferType)constantBufferReader.ReadUInt32("BufferType");

            return(result);
        }
        public static DebugResourceDefinitionChunk Parse(DebugBytecodeReader reader)
        {
            var headerReader = reader.CopyAtCurrentPosition("RDefHeader", reader);

            uint constantBufferCount   = headerReader.ReadUInt32("constantBufferCount");
            uint constantBufferOffset  = headerReader.ReadUInt32("constantBufferOffset");
            uint resourceBindingCount  = headerReader.ReadUInt32("resourceBindingCount");
            uint resourceBindingOffset = headerReader.ReadUInt32("resourceBindingOffset");
            var  target = DebugShaderVersion.ParseRdef(headerReader);
            var  flags  = headerReader.ReadEnum32 <ShaderFlags>("flags");

            var creatorOffset = headerReader.ReadUInt32("creatorOffset");
            var creatorReader = reader.CopyAtOffset("CreatorString", headerReader, (int)creatorOffset);
            var creator       = creatorReader.ReadString("creator");

            var result = new DebugResourceDefinitionChunk
            {
                Target  = target,
                Flags   = flags,
                Creator = creator
            };

            if (target.MajorVersion == 5 || target.ProgramType == ProgramType.LibraryShader)
            {
                var isVersion5_1 = target.MajorVersion == 5 && target.MinorVersion == 1;
                if (isVersion5_1)
                {
                    var unknown0 = headerReader.ReadUInt32("unkRdefHeader");
                }
                else
                {
                    string rd11 = headerReader.ReadUInt32("rd11").ToFourCcString();
                    if (rd11 != "RD11")
                    {
                        throw new ParseException("Expected RD11.");
                    }
                }

                var unkStride1            = headerReader.ReadUInt32("unkStride1");      // TODO
                var constantBufferStride  = headerReader.ReadUInt32("constantBufferStride");
                var resourceBindingStride = headerReader.ReadUInt32("resourceBindingStride");
                //Shader Variable Stride?
                var unkStride2 = headerReader.ReadUInt32("unkStride2");
                var unkStride3 = headerReader.ReadUInt32("unkStride3");
                //Shader Type Member Stride?
                var unkStride4 = headerReader.ReadUInt32("unkStride4");

                Debug.Assert(unkStride1 == 60, $"unkStride1 is {unkStride1}");
                Debug.Assert(constantBufferStride == 24, $"constantBufferStride is {constantBufferStride}");
                Debug.Assert(resourceBindingStride == CalculateResourceBindingStride(target),
                             $"resourceBindingStride is {resourceBindingStride}");
                Debug.Assert(unkStride2 == 40, $"unkStride2 is {unkStride2}");
                Debug.Assert(unkStride3 == 36, $"unkStride3 is {unkStride3}");
                Debug.Assert(unkStride4 == 12, $"unkStride4 is {unkStride4}");

                result.InterfaceSlotCount = headerReader.ReadUInt32("InterfaceSlotCount");
            }

            var resourceBindingReader = reader.CopyAtOffset("ResourceBindings", headerReader, (int)resourceBindingOffset);

            for (int i = 0; i < resourceBindingCount; i++)
            {
                result.ResourceBindings.Add(DebugResourceBinding.Parse(reader, resourceBindingReader, target));
            }

            var constantBufferReader = reader.CopyAtOffset("ContantBuffers", headerReader, (int)constantBufferOffset);

            for (int i = 0; i < constantBufferCount; i++)
            {
                result.ConstantBuffers.Add(DebugConstantBuffer.Parse(reader, constantBufferReader, result.Target));
            }

            return(result);
        }