Ejemplo n.º 1
0
        public PostVSMeshData GetPostVSData(MeshDataStage stage)
        {
            IntPtr mem = CustomMarshal.Alloc(typeof(PostVSMeshData));

            PostVSMeshData ret = null;

            bool success = ReplayRenderer_GetPostVSData(m_Real, stage, mem);

            if (success)
            {
                ret = (PostVSMeshData)CustomMarshal.PtrToStructure(mem, typeof(PostVSMeshData), true);
            }

            CustomMarshal.Free(mem);

            return(ret);
        }
Ejemplo n.º 2
0
        public MeshFormat GetPostVSData(UInt32 instID, MeshDataStage stage)
        {
            IntPtr mem = CustomMarshal.Alloc(typeof(MeshFormat));

            MeshFormat ret = new MeshFormat();

            ret.buf = ResourceId.Null;

            bool success = ReplayRenderer_GetPostVSData(m_Real, instID, stage, mem);

            if (success)
            {
                ret = (MeshFormat)CustomMarshal.PtrToStructure(mem, typeof(MeshFormat), true);
            }

            CustomMarshal.Free(mem);

            return(ret);
        }
Ejemplo n.º 3
0
        public void OnEventSelected(UInt32 frameID, UInt32 eventID)
        {
            ClearStoredData();

            var draw = m_Core.CurDrawcall;

            byteOffset.Enabled = false;

            instanceIdxToolitem.Enabled = (draw != null && draw.numInstances > 1);

            if (!instanceIdxToolitem.Enabled)
                instanceIdxToolitem.Text = "0";

            if (MeshView && draw == null)
            {
                m_VSIn.AbortThread();
                m_VSOut.AbortThread();
                m_GSOut.AbortThread();
                return;
            }

            int[] horizscroll = new int[] {
                m_VSIn.m_GridView.HorizontalScrollingOffset,
                m_VSOut.m_GridView.HorizontalScrollingOffset,
                m_GSOut.m_GridView.HorizontalScrollingOffset,
            };

            int curReq = m_ReqID;

            uint byteoffs = ByteOffset;

            m_Core.Renderer.BeginInvoke((ReplayRenderer r) =>
            {
                m_VSIn.AbortThread();
                m_VSOut.AbortThread();
                m_GSOut.AbortThread();

                if (curReq != m_ReqID)
                    return;

                if (MeshView)
                {
                    MeshDataStage[] stages = new MeshDataStage[] { MeshDataStage.VSIn, MeshDataStage.VSOut, MeshDataStage.GSOut };

                    FormatElement[] prevPos = new FormatElement[3];
                    FormatElement[] prevSecond = new FormatElement[3];

                    for (int i = 0; i < 3; i++)
                    {
                        prevPos[i] = GetPosHighlightFormatElement(stages[i]);
                        prevSecond[i] = GetSecondHighlightFormatElement(stages[i]);
                    }

                    m_VSIn.m_Input = GetCurrentMeshInput(draw, MeshDataStage.VSIn);
                    m_VSOut.m_Input = GetCurrentMeshInput(draw, MeshDataStage.VSOut);
                    m_GSOut.m_Input = GetCurrentMeshInput(draw, MeshDataStage.GSOut);

                    for(int i=0; i < 3; i++)
                    {
                        FormatElement curPos = GetPosHighlightFormatElement(stages[i]);
                        FormatElement curSecond = GetSecondHighlightFormatElement(stages[i]);
                        if (prevPos[i] == null || prevPos[i] != curPos) UI_AutoFetchRenderComponents(stages[i], true);
                        if (prevSecond[i] == null || prevSecond[i] != curSecond) UI_AutoFetchRenderComponents(stages[i], false);
                    }
                }

                var contentsVSIn = RT_FetchBufferContents(MeshDataStage.VSIn, r, m_VSIn.m_Input, byteoffs);
                var contentsVSOut = RT_FetchBufferContents(MeshDataStage.VSOut, r, m_VSOut.m_Input, byteoffs);
                var contentsGSOut = RT_FetchBufferContents(MeshDataStage.GSOut, r, m_GSOut.m_Input, byteoffs);

                if (curReq != m_ReqID)
                    return;

                this.BeginInvoke(new Action(() =>
                {
                    if (curReq != m_ReqID)
                        return;

                    m_VSIn.AbortThread();
                    m_VSOut.AbortThread();
                    m_GSOut.AbortThread();

                    if (m_VSIn.m_Input != null)
                        UI_SetRowsData(MeshDataStage.VSIn, contentsVSIn, horizscroll[0]);
                    if (m_VSOut.m_Input != null)
                        UI_SetRowsData(MeshDataStage.VSOut, contentsVSOut, horizscroll[1]);
                    if (m_GSOut.m_Input != null)
                        UI_SetRowsData(MeshDataStage.GSOut, contentsGSOut, horizscroll[2]);

                    if (MeshView)
                        UI_UpdateMeshRenderComponents();

                    UI_SetAllColumns();

                    camGuess_PropChanged();

                    render.Invalidate();
                }));
            });
        }
Ejemplo n.º 4
0
        private void UI_UpdateMeshColumns(MeshDataStage type, FormatElement[] el)
        {
            bool active = (type == m_MeshDisplay.type);
            bool input = (type == MeshDataStage.VSIn);
            var bufView = GetUIState(type).m_GridView;

            if (bufView.ColumnCount == 0)
                return;

            int colidx = 2; // skip VTX and IDX columns
            Color defaultCol = bufView.Columns[0].DefaultCellStyle.BackColor;

            for (int e = 0; e < el.Length; e++)
            {
                for (int i = 0; i < el[e].format.compCount; i++)
                {
                    if (colidx >= bufView.ColumnCount)
                        return;

                    DataGridViewColumn col = bufView.Columns[colidx];
                    colidx++;

                    if (e == m_PosElement[(int)type] && active)
                    {
                        if (i != 3 || !input)
                            col.DefaultCellStyle.BackColor = Color.SkyBlue;
                        else
                            col.DefaultCellStyle.BackColor = Color.LightCyan;
                    }
                    else if (e == m_SecondElement[(int)type] && active && m_MeshDisplay.solidShadeMode == SolidShadeMode.Secondary)
                    {
                        if ((m_MeshDisplay.secondary.showAlpha && i == 3) ||
                            (!m_MeshDisplay.secondary.showAlpha && i != 3))
                            col.DefaultCellStyle.BackColor = Color.LightGreen;
                        else
                            col.DefaultCellStyle.BackColor = Color.FromArgb(200, 238, 200);
                    }
                    else
                        col.DefaultCellStyle.BackColor = defaultCol;
                }
            }
        }
Ejemplo n.º 5
0
        private void UI_SetMeshColumns(MeshDataStage type, FormatElement[] el)
        {
            var bufView = GetUIState(type).m_GridView;

            bufView.Columns.Clear();

            DataGridViewTextBoxColumn Column = new DataGridViewTextBoxColumn();

            Column.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            Column.HeaderText = "VTX";
            Column.ReadOnly = true;
            Column.Frozen = true;
            Column.Width = 50;
            Column.DividerWidth = 0;
            Column.SortMode = DataGridViewColumnSortMode.Programmatic;
            Column.DefaultCellStyle.Padding = new Padding(0, 2, 0, 2);

            bufView.Columns.Add(Column);

            Column = new DataGridViewTextBoxColumn();

            Column.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
            Column.HeaderText = "IDX";
            Column.ReadOnly = true;
            Column.Frozen = true;
            Column.Width = 50;
            Column.DividerWidth = 10;
            Column.SortMode = DataGridViewColumnSortMode.Programmatic;
            Column.DefaultCellStyle.Padding = new Padding(0, 2, 0, 2);

            bufView.Columns.Add(Column);

            for(int e=0; e < el.Length; e++)
            {
                for (int i = 0; i < el[e].format.compCount; i++)
                {
                    DataGridViewTextBoxColumn col = new DataGridViewTextBoxColumn();

                    col.AutoSizeMode = DataGridViewAutoSizeColumnMode.AllCells;
                    col.MinimumWidth = 50;
                    col.HeaderText = el[e].name;
                    col.ReadOnly = true;
                    col.SortMode = DataGridViewColumnSortMode.Programmatic;
                    col.DefaultCellStyle.Padding = new Padding(0, 2, 0, 2);
                    bufView.Columns.Add(col);
                }

                if (e < el.Length-1)
                    bufView.Columns[bufView.Columns.Count - 1].DividerWidth = 10;
            }

            UI_UpdateMeshColumns(type, el);
        }
Ejemplo n.º 6
0
        private void UI_SetRowsData(MeshDataStage type, Dataset data, int horizScroll)
        {
            var state = GetUIState(type);

            Input input = state.m_Input;

            if(data.Buffers == null)
                return;

            var bufView = state.m_GridView;

            bufView.RowCount = 0;
            state.m_Data = data;

            {
                byte[][] d = data.Buffers;

                state.m_Stream = new Stream[d.Length];
                state.m_Reader = new BinaryReader[d.Length];

                state.m_MinBounds = null;
                state.m_MaxBounds = null;

                var bufferFormats = input.BufferFormats;

                foreach (var el in bufferFormats)
                {
                    if (state.m_Stream[el.buffer] == null)
                    {
                        if (d[el.buffer] == null)
                        {
                            state.m_Stream[el.buffer] = new MemoryStream(m_Zeroes);
                            state.m_Reader[el.buffer] = new BinaryReader(state.m_Stream[el.buffer]);
                        }
                        else
                        {
                            state.m_Stream[el.buffer] = new MemoryStream(d[el.buffer]);
                            state.m_Reader[el.buffer] = new BinaryReader(state.m_Stream[el.buffer]);
                        }
                    }
                }

                state.m_RawStride = 0;

                foreach (var el in bufferFormats)
                    state.m_RawStride += el.ByteSize;

                state.m_Rows = new object[data.IndexCount][];

                if (!MeshView)
                {
                    state.m_RawData = d[0];

                    this.BeginInvoke(new Action(() =>
                    {
                        UI_ShowRows(state, horizScroll);
                    }));
                }
                else
                {
                    state.m_RawData = new byte[state.m_RawStride * data.IndexCount];
                    UI_FillRawData(state, horizScroll);
                }
            }
        }
Ejemplo n.º 7
0
        private void UI_AutoFetchRenderComponents(MeshDataStage stage, bool pos)
        {
            var ui = GetUIState(stage);

            if (pos)
            {
                int posEl = -1;

                if (ui.m_Input != null && ui.m_Input.BufferFormats != null)
                {
                    // prioritise system value over general "POSITION" string matching
                    for (int i = 0; i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.systemValue == SystemAttribute.Position)
                        {
                            posEl = i;
                            break;
                        }
                    }
                    // look for an exact match
                    for (int i = 0; posEl == -1 && i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant() == "POSITION" ||
                            el.name.ToUpperInvariant() == "POSITION0" ||
                            el.name.ToUpperInvariant() == "POS" ||
                            el.name.ToUpperInvariant() == "POS0")
                        {
                            posEl = i;
                            break;
                        }
                    }
                    // try anything containing position
                    for (int i = 0; posEl == -1 && i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant().Contains("POSITION"))
                        {
                            posEl = i;
                            break;
                        }
                    }
                    // OK last resort, just look for 'pos'
                    for (int i = 0; posEl == -1 && i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant().Contains("POS"))
                        {
                            posEl = i;
                            break;
                        }
                    }
                    // if we still have absolutely nothing, just use the first available element
                    if (posEl == -1 && ui.m_Input.BufferFormats.Length > 0)
                    {
                        posEl = 0;
                    }
                }

                m_PosElement[(int)stage] = posEl;
            }
            else
            {
                int secondEl = -1;

                if (ui.m_Input != null && ui.m_Input.BufferFormats != null)
                {
                    // prioritise TEXCOORD over general COLOR
                    for (int i = 0; i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant() == "TEXCOORD" ||
                            el.name.ToUpperInvariant() == "TEXCOORD0" ||
                            el.name.ToUpperInvariant() == "TEX" ||
                            el.name.ToUpperInvariant() == "TEX0" ||
                            el.name.ToUpperInvariant() == "UV" ||
                            el.name.ToUpperInvariant() == "UV0")
                        {
                            secondEl = i;
                            break;
                        }
                    }
                    for (int i = 0; secondEl == -1 && i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant() == "COLOR" ||
                            el.name.ToUpperInvariant() == "COLOR0" ||
                            el.name.ToUpperInvariant() == "COL" ||
                            el.name.ToUpperInvariant() == "COL0")
                        {
                            secondEl = i;
                            break;
                        }
                    }
                }

                m_SecondElement[(int)stage] = secondEl;
            }
        }
Ejemplo n.º 8
0
 private void UI_SetColumns(MeshDataStage type, FormatElement[] el)
 {
     if (MeshView)
         UI_SetMeshColumns(type, el);
     else
         UI_SetRawColumns(el);
 }
Ejemplo n.º 9
0
 private static extern bool ReplayRenderer_GetPostVSData(IntPtr real, MeshDataStage stage, IntPtr outdata);
Ejemplo n.º 10
0
        public MeshFormat GetPostVSData(UInt32 instID, MeshDataStage stage)
        {
            IntPtr mem = CustomMarshal.Alloc(typeof(MeshFormat));

            MeshFormat ret = new MeshFormat();
            ret.buf = ResourceId.Null;

            bool success = ReplayRenderer_GetPostVSData(m_Real, instID, stage, mem);

            if (success)
                ret = (MeshFormat)CustomMarshal.PtrToStructure(mem, typeof(MeshFormat), true);

            CustomMarshal.Free(mem);

            return ret;
        }
Ejemplo n.º 11
0
        // used for the mesh view, to get the format of the mesh input from whichever stage that
        // we're looking at
        private Input GetCurrentMeshInput(FetchDrawcall draw, MeshDataStage type)
        {
            if (!MeshView)
                return null;

            Input ret = new Input();
            ret.Drawcall = draw;
            ret.Topology = draw.topology;

            ResourceId ibuffer = ResourceId.Null;
            ulong ioffset = 0;

            m_Core.CurPipelineState.GetIBuffer(out ibuffer, out ioffset);

            if (draw != null && (draw.flags & DrawcallFlags.UseIBuffer) == 0)
            {
                ibuffer = ResourceId.Null;
                ioffset = 0;
            }

            ret.IndexBuffer = ibuffer;
            ret.IndexOffset = ioffset;
            ret.IndexRestart = m_Core.CurPipelineState.IsStripRestartEnabled();
            ret.IndexRestartValue = m_Core.CurPipelineState.GetStripRestartIndex(draw != null ? draw.indexByteWidth : 0);

            if (type != MeshDataStage.VSIn)
            {
                ShaderReflection details = null;

                if (type == MeshDataStage.VSOut)
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Vertex);
                else if (type == MeshDataStage.GSOut)
                {
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Geometry);
                    if (details == null)
                        details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Domain);
                }

                if (details == null)
                    return null;

                List<FormatElement> f = new List<FormatElement>();

                int posidx = -1;
                for (int i = 0; i < details.OutputSig.Length; i++)
                {
                    var sig = details.OutputSig[i];

                    f.Add(new FormatElement());

                    f[i].buffer = 0;
                    f[i].name = details.OutputSig[i].varName.Length > 0 ? details.OutputSig[i].varName : details.OutputSig[i].semanticIdxName;
                    f[i].format.compByteWidth = sizeof(float);
                    f[i].format.compCount = sig.compCount;
                    f[i].format.compType = sig.compType;
                    f[i].format.special = false;
                    f[i].format.rawType = 0;
                    f[i].perinstance = false;
                    f[i].instancerate = 1;
                    f[i].rowmajor = false;
                    f[i].matrixdim = 1;
                    f[i].systemValue = sig.systemValue;

                    if(f[i].systemValue == SystemAttribute.Position)
                        posidx = i;
                }

                // shift position attribute up to first, keeping order otherwise
                // the same
                if (posidx > 0)
                {
                    FormatElement pos = f[posidx];
                    f.RemoveAt(posidx);
                    f.Insert(0, pos);
                }

                uint offset = 0;
                for (int i = 0; i < details.OutputSig.Length; i++)
                {
                    uint numComps = f[i].format.compCount;
                    uint elemSize = f[i].format.compType == FormatComponentType.Double ? 8U : 4U;

                    if (m_Core.CurPipelineState.HasAlignedPostVSData)
                    {
                        if (numComps == 2)
                            offset = offset.AlignUp(2U * elemSize);
                        else if (numComps > 2)
                            offset = offset.AlignUp(4U * elemSize);
                    }

                    f[i].offset = offset;

                    offset += numComps * elemSize;
                }

                ret.BufferFormats = f.ToArray();
                ret.Strides = new uint[] { offset };
                ret.Offsets = new ulong[] { 0 };
                ret.Buffers = null;

                return ret;
            }

            BoundVBuffer[] vbs = m_Core.CurPipelineState.GetVBuffers();

            ResourceId[] bs = new ResourceId[vbs.Length];
            uint[] s = new uint[vbs.Length];
            ulong[] o = new ulong[vbs.Length];

            for (int i = 0; i < vbs.Length; i++)
            {
                bs[i] = vbs[i].Buffer;
                s[i] = vbs[i].ByteStride;
                o[i] = vbs[i].ByteOffset;
            }

            {
                FormatElement[] f = null;

                var vinputs = m_Core.CurPipelineState.GetVertexInputs();
                f = new FormatElement[vinputs.Length];

                ret.GenericValues = new object[vinputs.Length][];

                int numinputs = vinputs.Length;

                int i = 0;
                foreach (var a in vinputs)
                {
                    if (!a.Used)
                    {
                        numinputs--;
                        Array.Resize(ref f, numinputs);
                        Array.Resize(ref ret.GenericValues, numinputs);
                        continue;
                    }

                    f[i] = new FormatElement(a.Name,
                                             a.VertexBuffer,
                                             a.RelativeByteOffset,
                                             a.PerInstance,
                                             a.InstanceRate,
                                             false, // row major matrix
                                             1, // matrix dimension
                                             a.Format,
                                             false);
                    ret.GenericValues[i] = a.GenericValue;
                    i++;
                }

                ret.BufferFormats = f;
                ret.Strides = s;
                ret.Offsets = o;
                ret.Buffers = bs;
            }

            return ret;
        }
Ejemplo n.º 12
0
        private FormatElement GetSecondHighlightFormatElement(MeshDataStage stage)
        {
            var ui = GetUIState(stage);

            int idx = m_SecondElement[(int)stage];

            if (ui.m_Input == null || ui.m_Input.BufferFormats == null ||
                idx == -1 || idx >= ui.m_Input.BufferFormats.Length)
                return null;

            return ui.m_Input.BufferFormats[idx];
        }
Ejemplo n.º 13
0
        private Dataset RT_FetchBufferContents(MeshDataStage type, ReplayRenderer r, Input input)
        {
            Dataset ret = new Dataset();

            ret.IndexCount = 0;

            if (input == null)
                return ret;

            if (!MeshView)
            {
                if (input != null && input.Buffers[0] != ResourceId.Null)
                {
                    ret.Buffers = new byte[1][];

                    ret.Buffers[0] = r.GetBufferData(input.Buffers[0], 0, 0);

                    ret.Indices = null;
                    ret.IndexCount = (uint)ret.Buffers[0].Length / input.Strides[0];
                }

                return ret;
            }

            if (input.Drawcall == null) return ret;

            ret.IndexCount = input.Drawcall.numIndices;
            ret.Topology = input.Topology;

            if (type != MeshDataStage.VSIn)
            {
                var postvs = r.GetPostVSData(type);

                ret.Buffers = new byte[1][];

                if (postvs == null)
                {
                    ret.IndexCount = 0;
                    ret.Topology = PrimitiveTopology.Unknown;
                }
                else
                {
                    ret.Buffers[0] = postvs.buf;

                    ret.Topology = postvs.topo;

                    ret.IndexCount = postvs.numVerts;

                    uint stride = 0;
                    foreach (var f in input.BufferFormats)
                        stride += f.ByteSize;

                    if (stride != 0)
                        ret.IndexCount = Math.Min(ret.IndexCount, (uint)ret.Buffers[0].Length / stride);
                }

                ret.Indices = null;

                return ret;
            }
            else if (input.Buffers != null && m_Output != null)
            {
                uint maxIndex = Math.Max(ret.IndexCount, 1) - 1;
                uint maxInstIndex = Math.Max(input.Drawcall.numInstances, 1) - 1;

                if ((input.Drawcall.flags & DrawcallFlags.UseIBuffer) != 0 &&
                    input.IndexBuffer != ResourceId.Null)
                {
                    byte[] rawidxs = r.GetBufferData(input.IndexBuffer,
                                                     input.IndexOffset + input.Drawcall.indexOffset * input.IndexFormat.format.compByteWidth,
                                                     ret.IndexCount * input.IndexFormat.format.compByteWidth);

                    ret.Indices = new uint[rawidxs.Length / input.IndexFormat.format.compByteWidth];

                    if (input.IndexFormat.format.compByteWidth == 2)
                    {
                        ushort[] tmp = new ushort[rawidxs.Length / 2];

                        Buffer.BlockCopy(rawidxs, 0, tmp, 0, rawidxs.Length);

                        for (int i = 0; i < tmp.Length; i++)
                        {
                            ret.Indices[i] = tmp[i];
                        }
                    }
                    else if (input.IndexFormat.format.compByteWidth == 4)
                    {
                        Buffer.BlockCopy(rawidxs, 0, ret.Indices, 0, rawidxs.Length);
                    }

                    maxIndex = 0;
                    foreach (var i in ret.Indices)
                    {
                        if(input.IndexFormat.format.compByteWidth == 2 && i == UInt16.MaxValue)
                            continue;
                        if (input.IndexFormat.format.compByteWidth == 4 && i == UInt32.MaxValue)
                            continue;

                        maxIndex = Math.Max(maxIndex, i);
                    }
                }

                ret.Buffers = new byte[input.Buffers.Length][];
                for (int i = 0; i < input.Buffers.Length; i++)
                {
                    bool used = false;
                    bool pi = false;
                    bool pv = false;

                    foreach (var f in input.BufferFormats)
                    {
                        if (f.buffer == i)
                        {
                            if (f.perinstance)
                                pi = true;
                            else
                                pv = true;

                            used = true;
                        }
                    }

                    uint maxIdx = 0;
                    uint offset = 0;

                    if(used)
                    {
                        if (pi)
                        {
                            maxIdx = maxInstIndex;
                            offset = input.Drawcall.instanceOffset;
                        }
                        if (pv)
                        {
                            maxIdx = Math.Max(maxIndex, maxIdx);
                            offset = input.Drawcall.vertexOffset;
                        }

                        System.Diagnostics.Debug.Assert(pi != pv || (pi == false && pv == false));
                    }

                    if (!used || input.Buffers[i] == ResourceId.Null)
                    {
                        ret.Buffers[i] = null;
                    }
                    else
                    {
                        ret.Buffers[i] = r.GetBufferData(input.Buffers[i],
                                                          input.Offsets[i] + offset * input.Strides[i],
                                                          (maxIdx + 1) * input.Strides[i]);

                        if (ret.Buffers[i].Length < (maxIdx + 1) * input.Strides[i])
                        {
                            // clamped
                        }
                    }
                }

                return ret;
            }

            return ret;
        }
Ejemplo n.º 14
0
        // used for the mesh view, to get the format of the mesh input from whichever stage that
        // we're looking at
        private Input GetCurrentMeshInput(FetchDrawcall draw, MeshDataStage type)
        {
            if (!MeshView)
                return null;

            FormatElement[] f = null;
            Input ret = new Input();
            ret.Drawcall = draw;
            ret.Topology = m_Core.CurPipelineState.DrawTopology;

            if (type != MeshDataStage.VSIn)
            {
                ShaderReflection details = null;

                if (type == MeshDataStage.VSOut)
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Vertex);
                else if (type == MeshDataStage.GSOut)
                {
                    details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Geometry);
                    if (details == null)
                        details = m_Core.CurPipelineState.GetShaderReflection(ShaderStageType.Domain);
                }

                if (details == null)
                    return null;

                f = new FormatElement[details.OutputSig.Length];

                uint offset = 0;
                for (int i = 0; i < details.OutputSig.Length; i++)
                {
                    var sig = details.OutputSig[i];

                    f[i] = new FormatElement();

                    f[i].buffer = 0;
                    f[i].name = details.OutputSig[i].varName != "" ? details.OutputSig[i].varName : details.OutputSig[i].semanticIdxName;
                    f[i].format.compByteWidth = sizeof(float);
                    f[i].format.compCount = sig.compCount;
                    f[i].format.compType = sig.compType;
                    f[i].format.special = false;
                    f[i].format.rawType = 0;
                    f[i].offset = offset;
                    f[i].perinstance = false;
                    f[i].rowmajor = false;
                    f[i].matrixdim = 1;

                    offset += details.OutputSig[i].compCount * sizeof(float);
                }

                ret.BufferFormats = f;
                ret.Strides = new uint[] { offset };
                ret.Offsets = new uint[] { 0 };
                ret.Buffers = null;
                ret.IndexBuffer = ResourceId.Null;

                return ret;
            }

            CommonPipelineState.VBuffer[] vbs = m_Core.CurPipelineState.GetVBuffers();

            ResourceId[] bs = new ResourceId[vbs.Length];
            uint[] s = new uint[vbs.Length];
            uint[] o = new uint[vbs.Length];

            for (int i = 0; i < vbs.Length; i++)
            {
                bs[i] = vbs[i].Buffer;
                s[i] = vbs[i].ByteStride;
                o[i] = vbs[i].ByteOffset;
            }

            {
                var vinputs = m_Core.CurPipelineState.GetVertexInputs();
                f = new FormatElement[vinputs.Length];

                int i = 0;
                foreach (var a in vinputs)
                {
                    f[i] = new FormatElement(a.Name,
                                             a.VertexBuffer,
                                             a.RelativeByteOffset,
                                             a.PerInstance,
                                             false, // row major matrix
                                             1, // matrix dimension
                                             a.Format);
                    i++;
                }
            }

            ResourceId ibuffer = ResourceId.Null;
            uint ioffset = 0;
            ResourceFormat ifmt = null;

            m_Core.CurPipelineState.GetIBuffer(out ibuffer, out ioffset, out ifmt);

            if (draw != null && (draw.flags & DrawcallFlags.UseIBuffer) == 0)
            {
                ibuffer = ResourceId.Null;
                ioffset = 0;
            }

            ret.BufferFormats = f;
            ret.Strides = s;
            ret.Offsets = o;
            ret.Buffers = bs;

            ret.IndexFormat = new FormatElement("", 0, 0, false, false, 1, ifmt);
            ret.IndexBuffer = ibuffer;
            ret.IndexOffset = ioffset;

            return ret;
        }
Ejemplo n.º 15
0
        private void UI_AutoFetchRenderComponents(MeshDataStage stage, bool pos)
        {
            var ui = GetUIState(stage);

            if (pos)
            {
                int posEl = -1;

                if (ui.m_Input != null && ui.m_Input.BufferFormats != null)
                {
                    // prioritise system value over general "POSITION" string matching
                    for (int i = 0; i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.systemValue == SystemAttribute.Position)
                        {
                            posEl = i;
                            break;
                        }
                    }
                    for (int i = 0; posEl == -1 && i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant() == "POSITION" ||
                            el.name.ToUpperInvariant() == "POSITION0" ||
                            el.name.ToUpperInvariant() == "POS" ||
                            el.name.ToUpperInvariant() == "POS0")
                        {
                            posEl = i;
                            break;
                        }
                    }
                }

                m_PosElement[(int)stage] = posEl;
            }
            else
            {
                int secondEl = -1;

                if (ui.m_Input != null && ui.m_Input.BufferFormats != null)
                {
                    // prioritise TEXCOORD over general COLOR
                    for (int i = 0; i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant() == "TEXCOORD" ||
                            el.name.ToUpperInvariant() == "TEXCOORD0" ||
                            el.name.ToUpperInvariant() == "TEX" ||
                            el.name.ToUpperInvariant() == "TEX0" ||
                            el.name.ToUpperInvariant() == "UV" ||
                            el.name.ToUpperInvariant() == "UV0")
                        {
                            secondEl = i;
                            break;
                        }
                    }
                    for (int i = 0; secondEl == -1 && i < ui.m_Input.BufferFormats.Length; i++)
                    {
                        FormatElement el = ui.m_Input.BufferFormats[i];

                        if (el.name.ToUpperInvariant() == "COLOR" ||
                            el.name.ToUpperInvariant() == "COLOR0" ||
                            el.name.ToUpperInvariant() == "COL" ||
                            el.name.ToUpperInvariant() == "COL0")
                        {
                            secondEl = i;
                            break;
                        }
                    }
                }

                m_SecondElement[(int)stage] = secondEl;
            }
        }
Ejemplo n.º 16
0
 public UIState(MeshDataStage stage)
 {
     m_Stage = stage;
 }
Ejemplo n.º 17
0
        public PostVSMeshData GetPostVSData(MeshDataStage stage)
        {
            IntPtr mem = CustomMarshal.Alloc(typeof(PostVSMeshData));

            PostVSMeshData ret = null;

            bool success = ReplayRenderer_GetPostVSData(m_Real, stage, mem);

            if (success)
                ret = (PostVSMeshData)CustomMarshal.PtrToStructure(mem, typeof(PostVSMeshData), true);

            CustomMarshal.Free(mem);

            return ret;
        }
Ejemplo n.º 18
0
        private UIState GetUIState(MeshDataStage type)
        {
            if (type == MeshDataStage.VSIn)
                return m_VSIn;
            if (type == MeshDataStage.VSOut)
                return m_VSOut;
            if (type == MeshDataStage.GSOut)
                return m_GSOut;

            return null;
        }
Ejemplo n.º 19
0
 private static extern bool ReplayRenderer_GetPostVSData(IntPtr real, UInt32 instID, MeshDataStage stage, IntPtr outdata);
Ejemplo n.º 20
0
        private Dataset RT_FetchBufferContents(MeshDataStage type, ReplayRenderer r, Input input, uint byteoffs)
        {
            Dataset ret = new Dataset();

            ret.IndexCount = 0;

            if (input == null)
                return ret;

            if (!MeshView)
            {
                if (input != null && (input.Buffers[0] != ResourceId.Null || input.Buffers[1] != ResourceId.Null))
                {
                    ret.Buffers = new byte[1][];

                    if(input.Buffers[0] != ResourceId.Null)
                        ret.Buffers[0] = r.GetBufferData(input.Buffers[0], byteoffs, 0);
                    else if (input.Buffers[1] != ResourceId.Null)
                        ret.Buffers[0] = r.GetTextureData(input.Buffers[1], byteoffs, 0);

                    ret.Indices = null;
                    ret.DataIndices = null;
                    ret.IndexCount = (uint)ret.Buffers[0].Length / input.Strides[0];
                }

                return ret;
            }

            if (input.Drawcall == null) return ret;

            ret.IndexCount = input.Drawcall.numIndices;
            ret.Topology = input.Topology;

            ret.PostVS.stride = 0;

            if (type != MeshDataStage.VSIn)
            {
                ret.PostVS = r.GetPostVSData(Math.Min(m_MeshDisplay.curInstance, Math.Max(1U, input.Drawcall.numInstances)), type);

                ret.Buffers = new byte[1][];

                if (ret.PostVS.buf == ResourceId.Null)
                {
                    ret.IndexCount = 0;
                    ret.Topology = PrimitiveTopology.Unknown;
                }
                else
                {
                    ret.Topology = ret.PostVS.topo;

                    ret.IndexCount = ret.PostVS.numVerts;
                }

                ret.Indices = null;
                ret.DataIndices = null;

                uint maxIndex = Math.Max(ret.IndexCount, 1) - 1;

                if (ret.PostVS.buf != ResourceId.Null && type == MeshDataStage.VSOut &&
                    (input.Drawcall.flags & DrawcallFlags.UseIBuffer) > 0 && input.IndexBuffer != ResourceId.Null)
                {
                    ret.IndexCount = input.Drawcall.numIndices;

                    byte[] rawidxs = r.GetBufferData(input.IndexBuffer,
                                                     input.IndexOffset + input.Drawcall.indexOffset * input.Drawcall.indexByteWidth,
                                                     ret.IndexCount * input.Drawcall.indexByteWidth);

                    if (input.Drawcall.indexByteWidth == 0 || rawidxs == null || rawidxs.Length == 0)
                    {
                        ret.Indices = new uint[0] { };
                    }
                    else
                    {
                        ret.Indices = new uint[rawidxs.Length / input.Drawcall.indexByteWidth];

                        if (input.Drawcall.indexByteWidth == 1)
                        {
                            for (int i = 0; i < rawidxs.Length; i++)
                                ret.Indices[i] = rawidxs[i];
                        }
                        else if (input.Drawcall.indexByteWidth == 2)
                        {
                            ushort[] tmp = new ushort[rawidxs.Length / 2];

                            Buffer.BlockCopy(rawidxs, 0, tmp, 0, tmp.Length * sizeof(ushort));

                            for (int i = 0; i < tmp.Length; i++)
                            {
                                ret.Indices[i] = tmp[i];
                            }
                        }
                        else if (input.Drawcall.indexByteWidth == 4)
                        {
                            Buffer.BlockCopy(rawidxs, 0, ret.Indices, 0, ret.Indices.Length * sizeof(uint));
                        }
                    }

                    rawidxs = r.GetBufferData(ret.PostVS.idxbuf, 0, 0);

                    if (input.Drawcall.indexByteWidth == 0 || rawidxs == null || rawidxs.Length == 0)
                    {
                        ret.DataIndices = new uint[0] { };
                    }
                    else
                    {
                        ret.DataIndices = new uint[rawidxs.Length / input.Drawcall.indexByteWidth];

                        if (input.Drawcall.indexByteWidth == 1)
                        {
                            for (int i = 0; i < rawidxs.Length; i++)
                                ret.DataIndices[i] = rawidxs[i];
                        }
                        else if (input.Drawcall.indexByteWidth == 2)
                        {
                            ushort[] tmp = new ushort[rawidxs.Length / 2];

                            Buffer.BlockCopy(rawidxs, 0, tmp, 0, tmp.Length * sizeof(ushort));

                            for (int i = 0; i < tmp.Length; i++)
                            {
                                ret.DataIndices[i] = tmp[i];
                            }
                        }
                        else if (input.Drawcall.indexByteWidth == 4)
                        {
                            Buffer.BlockCopy(rawidxs, 0, ret.DataIndices, 0, ret.DataIndices.Length * sizeof(uint));
                        }
                    }

                    maxIndex = 0;
                    foreach (var i in ret.DataIndices)
                    {
                        if (i == input.IndexRestartValue && input.IndexRestart)
                            continue;

                        maxIndex = Math.Max(maxIndex, i);
                    }
                }

                if (ret.PostVS.buf != ResourceId.Null)
                {
                    ret.Buffers[0] = r.GetBufferData(ret.PostVS.buf, ret.PostVS.offset, (maxIndex + 1) * ret.PostVS.stride);

                    uint stride = ret.PostVS.stride;

                    if (stride != 0 && (input.Drawcall.flags & DrawcallFlags.UseIBuffer) == 0)
                        ret.IndexCount = Math.Min(ret.IndexCount, (uint)ret.Buffers[0].Length / stride);
                }

                return ret;
            }
            else if (input.Buffers != null && m_Output != null)
            {
                uint maxIndex = Math.Max(ret.IndexCount, 1) - 1;
                uint maxInstIndex = Math.Max(input.Drawcall.numInstances, 1) - 1;

                if ((input.Drawcall.flags & DrawcallFlags.UseIBuffer) != 0 &&
                    input.IndexBuffer != ResourceId.Null)
                {
                    byte[] rawidxs = r.GetBufferData(input.IndexBuffer,
                                                     input.IndexOffset + input.Drawcall.indexOffset * input.Drawcall.indexByteWidth,
                                                     ret.IndexCount * input.Drawcall.indexByteWidth);

                    if (input.Drawcall.indexByteWidth == 0 || rawidxs == null || rawidxs.Length == 0)
                    {
                        ret.Indices = new uint[0];
                    }
                    else
                    {
                        ret.Indices = new uint[rawidxs.Length / input.Drawcall.indexByteWidth];

                        if (input.Drawcall.indexByteWidth == 1)
                        {
                            for (int i = 0; i < rawidxs.Length; i++)
                                ret.Indices[i] = rawidxs[i];
                        }
                        else if (input.Drawcall.indexByteWidth == 2)
                        {
                            ushort[] tmp = new ushort[rawidxs.Length / 2];

                            Buffer.BlockCopy(rawidxs, 0, tmp, 0, tmp.Length * sizeof(ushort));

                            for (int i = 0; i < tmp.Length; i++)
                            {
                                ret.Indices[i] = tmp[i];
                            }
                        }
                        else if (input.Drawcall.indexByteWidth == 4)
                        {
                            Buffer.BlockCopy(rawidxs, 0, ret.Indices, 0, ret.Indices.Length * sizeof(uint));
                        }
                    }

                    maxIndex = 0;
                    foreach (var i in ret.Indices)
                    {
                        if (i == input.IndexRestartValue && input.IndexRestart)
                            continue;

                        maxIndex = Math.Max(maxIndex, i);
                    }
                }

                ret.DataIndices = ret.Indices;

                ret.Buffers = new byte[input.Buffers.Length][];
                for (int i = 0; i < input.Buffers.Length; i++)
                {
                    bool used = false;
                    bool pi = false;
                    bool pv = false;

                    foreach (var f in input.BufferFormats)
                    {
                        if (f.buffer == i)
                        {
                            if (f.perinstance)
                                pi = true;
                            else
                                pv = true;

                            used = true;
                        }
                    }

                    uint maxIdx = 0;
                    uint offset = 0;

                    if(used)
                    {
                        if (pi)
                        {
                            maxIdx = maxInstIndex;
                            offset = input.Drawcall.instanceOffset;
                        }
                        if (pv)
                        {
                            maxIdx = Math.Max(maxIndex, maxIdx);
                            offset = input.Drawcall.vertexOffset;
                        }

                        System.Diagnostics.Debug.Assert(pi != pv || (pi == false && pv == false));
                    }

                    if (!used || input.Buffers[i] == ResourceId.Null)
                    {
                        ret.Buffers[i] = null;
                    }
                    else
                    {
                        ret.Buffers[i] = r.GetBufferData(input.Buffers[i],
                                                          input.Offsets[i] + offset * input.Strides[i],
                                                          (maxIdx + 1) * input.Strides[i]);

                        if (ret.Buffers[i].Length < (maxIdx + 1) * input.Strides[i])
                        {
                            // clamped
                        }
                    }
                }

                return ret;
            }

            return ret;
        }
Ejemplo n.º 21
0
        private void UI_SetRowsData(MeshDataStage type, Dataset data, int horizScroll)
        {
            var state = GetUIState(type);

            var bufView = state.m_GridView;

            if(bufView.IsDisposed)
                return;

            // only do this once, VSIn is guaranteed to be set (even if it's empty data)
            if(type == MeshDataStage.VSIn)
                CalcCellFloatWidth();

            Input input = state.m_Input;

            if(data.Buffers == null)
                return;

            bufView.RowCount = 0;
            state.m_Data = data;

            {
                byte[][] d = data.Buffers;

                state.m_Stream = new Stream[d.Length];
                state.m_Reader = new BinaryReader[d.Length];

                state.m_MinBounds = null;
                state.m_MaxBounds = null;

                var bufferFormats = input.BufferFormats;

                foreach (var el in bufferFormats)
                {
                    if (el.buffer < state.m_Stream.Length && state.m_Stream[el.buffer] == null)
                    {
                        if (d[el.buffer] == null)
                        {
                            state.m_Stream[el.buffer] = new MemoryStream(m_Zeroes);
                            state.m_Reader[el.buffer] = new BinaryReader(state.m_Stream[el.buffer]);
                        }
                        else
                        {
                            state.m_Stream[el.buffer] = new MemoryStream(d[el.buffer]);
                            state.m_Reader[el.buffer] = new BinaryReader(state.m_Stream[el.buffer]);
                        }
                    }
                }

                state.m_RawStride = 0;

                foreach (var el in bufferFormats)
                    state.m_RawStride += el.ByteSize;

                state.m_Rows = new object[data.IndexCount][];

                if (!MeshView)
                {
                    state.m_RawData = d[0];

                    this.BeginInvoke(new Action(() =>
                    {
                        UI_ShowRows(state, horizScroll);
                    }));
                }
                else
                {
                    state.m_RawData = new byte[state.m_RawStride * data.IndexCount];
                    UI_FillRawData(state, horizScroll);
                }
            }
        }