public override void Load(InstrumentData d)
    {
        SamplerData data = d as SamplerData;

        base.Load(data);
        speedDial.setPercent(data.speedDial);
        volumeDial.setPercent(data.ampDial);
        GetComponent <samplerLoad>().SetSample(data.label, data.file);

        volumeInput.ID  = data.jackInAmpID;
        speedInput.ID   = data.jackInSpeedID;
        controlInput.ID = data.jackInSeqID;
        output.ID       = data.jackOutID;

        playButton.startToggled = data.playToggle;
        dirSwitch.setSwitch(data.dirSwitch);
        loopSwitch.setSwitch(data.loopSwitch);
        headSlider.setPercent(data.headPos);
        tailSlider.setPercent(data.tailPos);

        turntableButton.startToggled = data.turntable;
        if (data.turntablePos != Vector3.zero)
        {
            turntableObject.transform.localPosition = data.turntablePos;
        }
        if (data.turntableRot != Quaternion.identity)
        {
            turntableObject.transform.localRotation = data.turntableRot;
        }
    }
Example #2
0
        // Written by hand to include management of input Brushes (which aren't DPs).
        internal override void ReleaseOnChannelCore(DUCE.Channel channel)
        {
            Debug.Assert(_duceResource.IsOnChannel(channel));

            if (_duceResource.ReleaseOnChannel(channel))
            {
                // Ensure that brushes are released.
                if (_samplerCount > 0)
                {
                    int numSamplers = _samplerData.Count;
                    for (int i = 0; i < numSamplers; i++)
                    {
                        SamplerData?ssn = _samplerData[i];
                        if (ssn.HasValue)
                        {
                            SamplerData ss = ssn.Value;

                            DUCE.IResource brush = ss._brush as DUCE.IResource;
                            if (brush != null)
                            {
                                brush.ReleaseOnChannel(channel);
                            }
                        }
                    }
                }

                PixelShader vPixelShader = PixelShader;
                if (vPixelShader != null)
                {
                    ((DUCE.IResource)vPixelShader).ReleaseOnChannel(channel);
                }

                ReleaseOnChannelAnimations(channel);
            }
        }
    public override InstrumentData GetData()
    {
        SamplerData data = new SamplerData();

        data.deviceType = menuItem.deviceType.Sampler;
        GetTransformData(data);
        data.speedDial = speedDial.percent;
        data.ampDial   = volumeDial.percent;

        data.file  = GetComponent <samplerLoad>().CurFile;
        data.label = GetComponent <samplerLoad>().CurTapeLabel;

        data.jackInAmpID   = volumeInput.transform.GetInstanceID();
        data.jackInSpeedID = speedInput.transform.GetInstanceID();
        data.jackInSeqID   = controlInput.transform.GetInstanceID();
        data.jackOutID     = output.transform.GetInstanceID();
        data.dirSwitch     = dirSwitch.switchVal;
        data.loopSwitch    = loopSwitch.switchVal;
        data.headPos       = headSlider.percent;
        data.tailPos       = tailSlider.percent;

        data.playToggle = playButton.isHit;

        data.turntable    = turntableOn;
        data.turntablePos = turntableObject.transform.localPosition;
        data.turntableRot = turntableObject.transform.localRotation;

        return(data);
    }
Example #4
0
        // Ensures that _samplerData is extended to 'position', and that
        // the specified value is inserted there.
        private void StashSamplerDataInPosition(int position, SamplerData newSampler, int maxIndex)
        {
            if (_samplerData == null)
            {
                _samplerData = new List <SamplerData?>(maxIndex);
            }

            if (_samplerData.Count <= position)
            {
                int numToAdd = position - _samplerData.Count + 1;
                for (int i = 0; i < numToAdd; i++)
                {
                    _samplerData.Add((SamplerData?)null);
                }
            }

            if (!_samplerData[position].HasValue)
            {
                // Going from null to having a value, so increment count
                _samplerCount++;
            }

            System.Windows.Threading.Dispatcher dispatcher = this.Dispatcher;

            // Release the old value if it is a resource on channel.  AddRef the
            // new value.
            if (dispatcher != null)
            {
                SamplerData?oldSampler = _samplerData[position];
                Brush       oldBrush   = null;
                if (oldSampler.HasValue)
                {
                    SamplerData ss = oldSampler.Value;

                    oldBrush = ss._brush;
                }

                Brush newBrush = newSampler._brush;

                DUCE.IResource targetResource = (DUCE.IResource) this;
                using (CompositionEngineLock.Acquire())
                {
                    int channelCount = targetResource.GetChannelCount();

                    for (int channelIndex = 0; channelIndex < channelCount; channelIndex++)
                    {
                        DUCE.Channel channel = targetResource.GetChannel(channelIndex);
                        Debug.Assert(!channel.IsOutOfBandChannel);
                        Debug.Assert(!targetResource.GetHandle(channel).IsNull);
                        ReleaseResource(oldBrush, channel);
                        AddRefResource(newBrush, channel);
                    }
                }
            }

            _samplerData[position] = newSampler;
        }
Example #5
0
        // Updates the shader sampler referred to by the DP.  Converts to the
        // form that the HLSL shaders want, and stores that value, since it will
        // be sent on every update.
        // We WritePreamble/Postscript here since this method is called by the user with the callback
        // created in PixelShaderSamplerCallback.
        private void UpdateShaderSampler(DependencyProperty dp, object newValue, int registerIndex, SamplingMode samplingMode)
        {
            WritePreamble();

            if (newValue != null)
            {
                if (!(typeof(VisualBrush).IsInstanceOfType(newValue) ||
                      typeof(BitmapCacheBrush).IsInstanceOfType(newValue) ||
                      typeof(ImplicitInputBrush).IsInstanceOfType(newValue) ||
                      typeof(ImageBrush).IsInstanceOfType(newValue))
                    )
                {
                    // Note that if the type of the brush is ImplicitInputBrush and the value is non null, the value is actually
                    // Effect.ImplicitInput. This is because ImplicitInputBrush is internal and the user can only get to the singleton
                    // Effect.ImplicitInput.
                    throw new ArgumentException(SR.Get(SRID.Effect_ShaderSamplerType), "dp");
                }
            }

            //
            // Treat as ps_2_0 by default
            //
            int    registerMax = PS_2_0_SAMPLER_LIMIT;
            string srid        = SRID.Effect_Shader20SamplerRegisterLimit;

            if (PixelShader != null && PixelShader.ShaderMajorVersion >= 3)
            {
                registerMax = PS_3_0_SAMPLER_LIMIT;
                srid        = SRID.Effect_Shader30SamplerRegisterLimit;
            }

            if (registerIndex >= registerMax || registerIndex < 0)
            {
                throw new ArgumentException(SR.Get(srid));
            }

            SamplerData sd = new SamplerData()
            {
                _brush        = (Brush)newValue,
                _samplingMode = samplingMode
            };

            StashSamplerDataInPosition(registerIndex, sd, registerMax);

            // Propagate dirty
            this.PropertyChanged(dp);
            WritePostscript();
        }
Example #6
0
        // Written by hand to include management of input Brushes (which aren't DPs).
        internal override DUCE.ResourceHandle AddRefOnChannelCore(DUCE.Channel channel)
        {
            if (_duceResource.CreateOrAddRefOnChannel(this, channel, System.Windows.Media.Composition.DUCE.ResourceType.TYPE_SHADEREFFECT))
            {
                // Ensures brushes are property instantiated into Duce resources.
                if (_samplerCount > 0)
                {
                    int numSamplers = _samplerData.Count;
                    for (int i = 0; i < numSamplers; i++)
                    {
                        SamplerData?ssn = _samplerData[i];
                        if (ssn.HasValue)
                        {
                            SamplerData ss = ssn.Value;

                            DUCE.IResource brush = ss._brush as DUCE.IResource;
                            if (brush != null)
                            {
                                brush.AddRefOnChannel(channel);
                            }
                        }
                    }
                }

                PixelShader vPixelShader = PixelShader;
                if (vPixelShader != null)
                {
                    ((DUCE.IResource)vPixelShader).AddRefOnChannel(channel);
                }

                AddRefOnChannelAnimations(channel);


                UpdateResource(channel, true /* skip "on channel" check - we already know that we're on channel */);
            }

            return(_duceResource.GetHandle(channel));
        }
Example #7
0
        private void ManualUpdateResource(DUCE.Channel channel, bool skipOnChannelCheck)
        {
            // If we're told we can skip the channel check, then we must be on channel
            Debug.Assert(!skipOnChannelCheck || _duceResource.IsOnChannel(channel));

            if (skipOnChannelCheck || _duceResource.IsOnChannel(channel))
            {
                if (PixelShader == null)
                {
                    throw new InvalidOperationException(SR.Get(SRID.Effect_ShaderPixelShaderSet));
                }

                checked
                {
                    DUCE.MILCMD_SHADEREFFECT data;
                    data.Type   = MILCMD.MilCmdShaderEffect;
                    data.Handle = _duceResource.GetHandle(channel);

                    data.TopPadding    = _topPadding;
                    data.BottomPadding = _bottomPadding;
                    data.LeftPadding   = _leftPadding;
                    data.RightPadding  = _rightPadding;

                    data.DdxUvDdyUvRegisterIndex = this.DdxUvDdyUvRegisterIndex;
                    data.hPixelShader            = ((DUCE.IResource)PixelShader).GetHandle(channel);

                    unsafe
                    {
                        data.ShaderConstantFloatRegistersSize  = (uint)(sizeof(Int16) * _floatCount);
                        data.DependencyPropertyFloatValuesSize = (uint)(4 * sizeof(Single) * _floatCount);
                        data.ShaderConstantIntRegistersSize    = (uint)(sizeof(Int16) * _intCount);
                        data.DependencyPropertyIntValuesSize   = (uint)(4 * sizeof(Int32) * _intCount);
                        data.ShaderConstantBoolRegistersSize   = (uint)(sizeof(Int16) * _boolCount);
                        //
                        // Note: the multiply by 4 is not because the boolean register holds 4
                        // values, but to compensate for the difference between sizeof(bool)
                        // in managed code (1) and sizeof(BOOL) in native code (4).
                        //
                        data.DependencyPropertyBoolValuesSize    = (uint)(4 * sizeof(bool) * _boolCount);
                        data.ShaderSamplerRegistrationInfoSize   = (uint)(2 * sizeof(uint) * _samplerCount); // 2 pieces of data per sampler.
                        data.DependencyPropertySamplerValuesSize = (uint)(1 * sizeof(DUCE.ResourceHandle) * _samplerCount);

                        channel.BeginCommand(
                            (byte *)&data,
                            sizeof(DUCE.MILCMD_SHADEREFFECT),
                            (int)(data.ShaderConstantFloatRegistersSize +
                                  data.DependencyPropertyFloatValuesSize +
                                  data.ShaderConstantIntRegistersSize +
                                  data.DependencyPropertyIntValuesSize +
                                  data.ShaderConstantBoolRegistersSize +
                                  data.DependencyPropertyBoolValuesSize +
                                  data.ShaderSamplerRegistrationInfoSize +
                                  data.DependencyPropertySamplerValuesSize)
                            );

                        // Arrays appear in this order:
                        // 1) float register indices
                        // 2) float dp values
                        // 3) int register indices
                        // 4) int dp values
                        // 5) bool register indices
                        // 6) bool dp values
                        // 7) sampler registration info
                        // 8) sampler dp values

                        // 1) float register indices
                        AppendRegisters(channel, _floatRegisters);

                        // 2) float dp values
                        if (_floatRegisters != null)
                        {
                            for (int i = 0; i < _floatRegisters.Count; i++)
                            {
                                MilColorF?v = _floatRegisters[i];
                                if (v.HasValue)
                                {
                                    MilColorF valueToPush = v.Value;
                                    channel.AppendCommandData((byte *)&valueToPush, sizeof(MilColorF));
                                }
                            }
                        }

                        // 3) int register indices
                        AppendRegisters(channel, _intRegisters);

                        // 4) int dp values
                        if (_intRegisters != null)
                        {
                            for (int i = 0; i < _intRegisters.Count; i++)
                            {
                                MilColorI?v = _intRegisters[i];
                                if (v.HasValue)
                                {
                                    MilColorI valueToPush = v.Value;
                                    channel.AppendCommandData((byte *)&valueToPush, sizeof(MilColorI));
                                }
                            }
                        }

                        // 5) bool register indices
                        AppendRegisters(channel, _boolRegisters);

                        // 6) bool dp values
                        if (_boolRegisters != null)
                        {
                            for (int i = 0; i < _boolRegisters.Count; i++)
                            {
                                bool?v = _boolRegisters[i];
                                if (v.HasValue)
                                {
                                    //
                                    // Note: need 4 bytes for the bool, because the render thread
                                    // unmarshals it into a 4-byte BOOL. See the comment above for
                                    // DependencyPropertyBoolValuesSize for more details.
                                    //

                                    Int32 valueToPush = v.Value ? 1 : 0;
                                    channel.AppendCommandData((byte *)&valueToPush, sizeof(Int32));
                                }
                            }
                        }

                        // 7) sampler registration info
                        if (_samplerCount > 0)
                        {
                            int count = _samplerData.Count;
                            for (int i = 0; i < count; i++)
                            {
                                SamplerData?ssn = _samplerData[i];
                                if (ssn.HasValue)
                                {
                                    SamplerData ss = ssn.Value;

                                    // add as a 2-tuple (SamplerRegisterIndex,
                                    // SamplingMode)

                                    channel.AppendCommandData((byte *)&i, sizeof(int));

                                    int value = (int)(ss._samplingMode);
                                    channel.AppendCommandData((byte *)&value, sizeof(int));
                                }
                            }
                        }


                        // 8) sampler dp values
                        if (_samplerCount > 0)
                        {
                            for (int i = 0; i < _samplerData.Count; i++)
                            {
                                SamplerData?ssn = _samplerData[i];
                                if (ssn.HasValue)
                                {
                                    SamplerData ss = ssn.Value;

                                    // Making this assumption by storing a collection of
                                    // handles as an Int32Collection
                                    Debug.Assert(sizeof(DUCE.ResourceHandle) == sizeof(Int32));

                                    DUCE.ResourceHandle hBrush = ss._brush != null
                                        ? ((DUCE.IResource)ss._brush).GetHandle(channel)
                                        : DUCE.ResourceHandle.Null;

                                    Debug.Assert(!hBrush.IsNull || ss._brush == null, "If brush isn't null, hBrush better not be");

                                    channel.AppendCommandData((byte *)&hBrush, sizeof(DUCE.ResourceHandle));
                                }
                            }
                        }

                        // That's it...
                        channel.EndCommand();
                    }
                }
            }
        }
        private void AddResourceRow(ShaderReflection shaderDetails, VulkanPipelineState.ShaderStage stage, int bindset, int bind, VulkanPipelineState.Pipeline pipe, TreelistView.TreeListView resources, FetchTexture[] texs, FetchBuffer[] bufs, ref Dictionary<ResourceId, SamplerData> samplers)
        {
            ShaderResource shaderRes = null;
            BindpointMap bindMap = null;

            bool isrw = false;
            uint bindPoint = 0;

            if (shaderDetails != null)
            {
                for (int i = 0; i < shaderDetails.ReadOnlyResources.Length; i++)
                {
                    var ro = shaderDetails.ReadOnlyResources[i];

                    if (stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bindset == bindset &&
                        stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bind == bind)
                    {
                        bindPoint = (uint)i;
                        shaderRes = ro;
                        bindMap = stage.BindpointMapping.ReadOnlyResources[ro.bindPoint];
                    }
                }

                for (int i = 0; i < shaderDetails.ReadWriteResources.Length; i++)
                {
                    var rw = shaderDetails.ReadWriteResources[i];

                    if (stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bindset == bindset &&
                        stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bind == bind)
                    {
                        bindPoint = (uint)i;
                        isrw = true;
                        shaderRes = rw;
                        bindMap = stage.BindpointMapping.ReadWriteResources[rw.bindPoint];
                    }
                }
            }

            VulkanPipelineState.Pipeline.DescriptorSet.DescriptorBinding.BindingElement[] slotBinds = null;
            ShaderBindType bindType = ShaderBindType.Unknown;
            ShaderStageBits stageBits = (ShaderStageBits)0;

            if (bindset < pipe.DescSets.Length && bind < pipe.DescSets[bindset].bindings.Length)
            {
                slotBinds = pipe.DescSets[bindset].bindings[bind].binds;
                bindType = pipe.DescSets[bindset].bindings[bind].type;
                stageBits = pipe.DescSets[bindset].bindings[bind].stageFlags;
            }
            else
            {
                if (shaderRes.IsSampler)
                    bindType = ShaderBindType.Sampler;
                else if (shaderRes.IsSampler && shaderRes.IsTexture)
                    bindType = ShaderBindType.ImageSampler;
                else if (shaderRes.resType == ShaderResourceType.Buffer)
                    bindType = ShaderBindType.ReadOnlyTBuffer;
                else
                    bindType = ShaderBindType.ReadOnlyImage;
            }

            bool usedSlot = bindMap != null && bindMap.used;
            bool stageBitsIncluded = stageBits.HasFlag((ShaderStageBits)(1 << (int)stage.stage));

            // skip descriptors that aren't for this shader stage
            if (!usedSlot && !stageBitsIncluded)
                return;

            if (bindType == ShaderBindType.ConstantBuffer)
                return;

            // TODO - check compatibility between bindType and shaderRes.resType ?

            // consider it filled if any array element is filled
            bool filledSlot = false;
            for (int idx = 0; slotBinds != null && idx < slotBinds.Length; idx++)
            {
                filledSlot |= slotBinds[idx].res != ResourceId.Null;
                if (bindType == ShaderBindType.Sampler || bindType == ShaderBindType.ImageSampler)
                    filledSlot |= slotBinds[idx].sampler != ResourceId.Null;
            }

            // if it's masked out by stage bits, act as if it's not filled, so it's marked in red
            if (!stageBitsIncluded)
                filledSlot = false;

            // show if
            if (usedSlot || // it's referenced by the shader - regardless of empty or not
                (showDisabled.Checked && !usedSlot && filledSlot) || // it's bound, but not referenced, and we have "show disabled"
                (showEmpty.Checked && !filledSlot) // it's empty, and we have "show empty"
                )
            {
                TreelistView.NodeCollection parentNodes = resources.Nodes;

                string setname = bindset.ToString();

                string slotname = bind.ToString();
                if (shaderRes != null && shaderRes.name.Length > 0)
                    slotname += ": " + shaderRes.name;

                int arrayLength = 0;
                if (slotBinds != null) arrayLength = slotBinds.Length;
                else arrayLength = (int)bindMap.arraySize;

                // for arrays, add a parent element that we add the real cbuffers below
                if (arrayLength > 1)
                {
                    var node = parentNodes.Add(new object[] { "", setname, slotname, String.Format("Array[{0}]", arrayLength), "", "", "", "" });

                    node.TreeColumn = 0;

                    if (!filledSlot)
                        EmptyRow(node);

                    if (!usedSlot)
                        InactiveRow(node);

                    parentNodes = node.Nodes;
                }

                for (int idx = 0; idx < arrayLength; idx++)
                {
                    VulkanPipelineState.Pipeline.DescriptorSet.DescriptorBinding.BindingElement descriptorBind = null;
                    if (slotBinds != null) descriptorBind = slotBinds[idx];

                    if (arrayLength > 1)
                    {
                        slotname = String.Format("{0}[{1}]", bind, idx);

                        if (shaderRes != null && shaderRes.name.Length > 0)
                            slotname += ": " + shaderRes.name;
                    }

                    bool isbuf = false;
                    UInt32 w = 1, h = 1, d = 1;
                    UInt32 a = 1;
                    UInt32 samples = 1;
                    UInt64 len = 0;
                    string format = "Unknown";
                    string name = "Empty";
                    ShaderResourceType restype = ShaderResourceType.None;
                    object tag = null;
                    bool viewDetails = false;

                    if (filledSlot && descriptorBind != null)
                    {
                        name = "Object " + descriptorBind.res.ToString();

                        format = descriptorBind.viewfmt.ToString();

                        // check to see if it's a texture
                        for (int t = 0; t < texs.Length; t++)
                        {
                            if (texs[t].ID == descriptorBind.res)
                            {
                                w = texs[t].width;
                                h = texs[t].height;
                                d = texs[t].depth;
                                a = texs[t].arraysize;
                                name = texs[t].name;
                                restype = texs[t].resType;
                                samples = texs[t].msSamp;

                                if (HasImportantViewParams(descriptorBind, texs[t]))
                                    viewDetails = true;

                                tag = new ViewTexTag(
                                        descriptorBind.viewfmt,
                                        descriptorBind.baseMip, descriptorBind.baseLayer,
                                        descriptorBind.numMip, descriptorBind.numLayer,
                                        texs[t]
                                    );
                            }
                        }

                        // if not a texture, it must be a buffer
                        for (int t = 0; t < bufs.Length; t++)
                        {
                            if (bufs[t].ID == descriptorBind.res)
                            {
                                len = bufs[t].length;
                                w = 0;
                                h = 0;
                                d = 0;
                                a = 0;
                                name = bufs[t].name;
                                restype = ShaderResourceType.Buffer;

                                ulong descriptorLen = descriptorBind.size;

                                if(descriptorLen == ulong.MaxValue)
                                    descriptorLen = len - descriptorBind.offset;

                                tag = new BufferResTag(isrw, bindPoint, bufs[t].ID, descriptorBind.offset, descriptorLen);

                                if (HasImportantViewParams(descriptorBind, bufs[t]))
                                    viewDetails = true;

                                isbuf = true;
                            }
                        }
                    }
                    else
                    {
                        name = "Empty";
                        format = "-";
                        w = h = d = a = 0;
                    }

                    TreelistView.Node node = null;

                    if (bindType == ShaderBindType.ReadWriteBuffer ||
                        bindType == ShaderBindType.ReadOnlyTBuffer ||
                        bindType == ShaderBindType.ReadWriteTBuffer
                        )
                    {
                        if (!isbuf)
                        {
                            node = parentNodes.Add(new object[] {
                                "", bindset, slotname, bindType,
                                "-",
                                "-",
                                "",
                            });

                            EmptyRow(node);
                        }
                        else
                        {
                            string range = "-";
                            if (descriptorBind != null)
                                range = String.Format("{0} - {1}", descriptorBind.offset, descriptorBind.size);
                            node = parentNodes.Add(new object[] {
                                "", bindset, slotname, bindType,
                                name,
                                String.Format("{0} bytes", len),
                                range,
                            });

                            node.Image = global::renderdocui.Properties.Resources.action;
                            node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                            node.Tag = tag;

                            if (!filledSlot)
                                EmptyRow(node);

                            if (!usedSlot)
                                InactiveRow(node);
                        }
                    }
                    else if (bindType == ShaderBindType.Sampler)
                    {
                        if (descriptorBind == null || descriptorBind.sampler == ResourceId.Null)
                        {
                            node = parentNodes.Add(new object[] {
                                "", bindset, slotname, bindType,
                                "-",
                                "-",
                                "",
                            });

                            EmptyRow(node);
                        }
                        else
                        {
                            node = parentNodes.Add(MakeSampler(bindset.ToString(), slotname, descriptorBind));

                            if (!filledSlot)
                                EmptyRow(node);

                            if (!usedSlot)
                                InactiveRow(node);

                            var data = new SamplerData(node);
                            node.Tag = data;

                            if (!samplers.ContainsKey(descriptorBind.sampler))
                                samplers.Add(descriptorBind.sampler, data);
                        }
                    }
                    else
                    {
                        if (descriptorBind == null || descriptorBind.res == ResourceId.Null)
                        {
                            node = parentNodes.Add(new object[] {
                                "", bindset, slotname, bindType,
                                "-",
                                "-",
                                "",
                            });

                            EmptyRow(node);
                        }
                        else
                        {
                            string typename = restype.Str() + " " + bindType.Str().Replace("&", "&&");

                            string dim;

                            if (restype == ShaderResourceType.Texture3D)
                                dim = String.Format("{0}x{1}x{2}", w, h, d);
                            else if (restype == ShaderResourceType.Texture1D || restype == ShaderResourceType.Texture1DArray)
                                dim = w.ToString();
                            else
                                dim = String.Format("{0}x{1}", w, h);

                            if (descriptorBind.swizzle[0] != TextureSwizzle.Red ||
                                descriptorBind.swizzle[1] != TextureSwizzle.Green ||
                                descriptorBind.swizzle[2] != TextureSwizzle.Blue ||
                                descriptorBind.swizzle[3] != TextureSwizzle.Alpha)
                            {
                                format += String.Format(" swizzle[{0}{1}{2}{3}]",
                                    descriptorBind.swizzle[0].Str(),
                                    descriptorBind.swizzle[1].Str(),
                                    descriptorBind.swizzle[2].Str(),
                                    descriptorBind.swizzle[3].Str());
                            }

                            if (restype == ShaderResourceType.Texture1DArray ||
                               restype == ShaderResourceType.Texture2DArray ||
                               restype == ShaderResourceType.Texture2DMSArray ||
                               restype == ShaderResourceType.TextureCubeArray)
                            {
                                dim += String.Format(" {0}[{1}]", restype.Str(), a);
                            }

                            if (restype == ShaderResourceType.Texture2DMS || restype == ShaderResourceType.Texture2DMSArray)
                                dim += String.Format(", {0}x MSAA", samples);

                            node = parentNodes.Add(new object[] {
                                "", bindset, slotname, typename,
                                name,
                                dim,
                                format,
                            });

                            node.Image = global::renderdocui.Properties.Resources.action;
                            node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                            node.Tag = tag;

                            if (!filledSlot)
                                EmptyRow(node);

                            if (!usedSlot)
                                InactiveRow(node);

                            ViewDetailsRow(node, viewDetails);
                        }

                        if (bindType == ShaderBindType.ImageSampler)
                        {
                            if (descriptorBind == null || descriptorBind.sampler == ResourceId.Null)
                            {
                                node = parentNodes.Add(new object[] {
                                    "", bindset, slotname, bindType,
                                    "-",
                                    "-",
                                    "",
                                });

                                EmptyRow(node);
                            }
                            else
                            {
                                var texnode = node;

                                if (!samplers.ContainsKey(descriptorBind.sampler))
                                {
                                    node = parentNodes.Add(MakeSampler("", "", descriptorBind));

                                    if (!filledSlot)
                                        EmptyRow(node);

                                    if (!usedSlot)
                                        InactiveRow(node);

                                    var data = new SamplerData(node);
                                    node.Tag = data;

                                    samplers.Add(descriptorBind.sampler, data);
                                }

                                if (texnode != null)
                                {
                                    m_CombinedImageSamplers[texnode] = samplers[descriptorBind.sampler].node;
                                    samplers[descriptorBind.sampler].images.Add(texnode);
                                }
                            }
                        }
                    }
                }
            }
        }
Example #9
0
 public Sampler(SamplerData data)
 {
     _data       = data;
     _samplerRes = this.CreateResource(ResourceType.RT_Sampler);
     RegisterUpdateResource();
 }
Example #10
0
 public void UpdateSampler(IResource res, ref SamplerData data)
 {
     _resourceManager.UpdateSampler(res, ref data);
 }
        // Set a shader stage's resources and values
        private void SetShaderState(FetchTexture[] texs, FetchBuffer[] bufs,
            VulkanPipelineState.ShaderStage stage, VulkanPipelineState.Pipeline pipe,
            Label shader, TreelistView.TreeListView resources,
            TreelistView.TreeListView cbuffers)
        {
            ShaderReflection shaderDetails = stage.ShaderDetails;

            if (stage.Shader == ResourceId.Null)
                shader.Text = "Unbound";
            else
                shader.Text = stage.ShaderName;

            if (shaderDetails != null && shaderDetails.DebugInfo.entryFunc.Length > 0)
            {
                if (shaderDetails.DebugInfo.files.Length > 0 || shaderDetails.DebugInfo.entryFunc != "main")
                    shader.Text = shaderDetails.DebugInfo.entryFunc + "()";

                if (shaderDetails.DebugInfo.files.Length > 0)
                {
                    string shaderfn = "";

                    int entryFile = shaderDetails.DebugInfo.entryFile;
                    if (entryFile < 0 || entryFile >= shaderDetails.DebugInfo.files.Length)
                        entryFile = 0;

                    shaderfn = shaderDetails.DebugInfo.files[entryFile].BaseFilename;

                    shader.Text += " - " + shaderfn;
                }
            }

            int vs = 0;

            vs = resources.VScrollValue();
            resources.BeginUpdate();
            resources.Nodes.Clear();

            var samplers = new Dictionary<ResourceId, SamplerData>();

            for(int bindset = 0; bindset < pipe.DescSets.Length; bindset++)
            {
                for(int bind = 0; bind < pipe.DescSets[bindset].bindings.Length; bind++)
                {
                    ShaderResource shaderRes = null;
                    BindpointMap bindMap = null;

                    bool isrw = false;
                    uint bindPoint = 0;

                    if (shaderDetails != null)
                    {
                        for(int i=0; i < shaderDetails.ReadOnlyResources.Length; i++)
                        {
                            var ro = shaderDetails.ReadOnlyResources[i];

                            if (stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bindset == bindset &&
                                stage.BindpointMapping.ReadOnlyResources[ro.bindPoint].bind == bind)
                            {
                                bindPoint = (uint)i;
                                shaderRes = ro;
                                bindMap = stage.BindpointMapping.ReadOnlyResources[ro.bindPoint];
                            }
                        }

                        for(int i=0; i < shaderDetails.ReadWriteResources.Length; i++)
                        {
                            var rw = shaderDetails.ReadWriteResources[i];

                            if (stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bindset == bindset &&
                                stage.BindpointMapping.ReadWriteResources[rw.bindPoint].bind == bind)
                            {
                                bindPoint = (uint)i;
                                isrw = true;
                                shaderRes = rw;
                                bindMap = stage.BindpointMapping.ReadWriteResources[rw.bindPoint];
                            }
                        }
                    }

                    VulkanPipelineState.Pipeline.DescriptorSet.DescriptorBinding.BindingElement[] slotBinds =
                        pipe.DescSets[bindset].bindings[bind].binds;
                    ShaderBindType bindType = pipe.DescSets[bindset].bindings[bind].type;
                    ShaderStageBits stageBits = pipe.DescSets[bindset].bindings[bind].stageFlags;

                    // skip descriptors that aren't for this shader stage
                    if (!stageBits.HasFlag((ShaderStageBits)(1 << (int)stage.stage)))
                        continue;

                    // these are treated as uniform buffers
                    if (bindType == ShaderBindType.ReadOnlyBuffer)
                        continue;

                    // consider it filled if any array element is filled
                    bool filledSlot = false;
                    for (int idx = 0; idx < slotBinds.Length; idx++)
                    {
                        filledSlot |= slotBinds[idx].res != ResourceId.Null;
                        if(bindType == ShaderBindType.Sampler || bindType == ShaderBindType.ImageSampler)
                            filledSlot |= slotBinds[idx].sampler != ResourceId.Null;
                    }
                    bool usedSlot = bindMap != null && bindMap.used;

                    // show if
                    if (usedSlot || // it's referenced by the shader - regardless of empty or not
                        (showDisabled.Checked && !usedSlot && filledSlot) || // it's bound, but not referenced, and we have "show disabled"
                        (showEmpty.Checked && !filledSlot) // it's empty, and we have "show empty"
                        )
                    {
                        TreelistView.NodeCollection parentNodes = resources.Nodes;

                        string setname = bindset.ToString();

                        string slotname = bind.ToString();
                        if(shaderRes != null)
                            slotname += ": " + shaderRes.name;

                        // for arrays, add a parent element that we add the real cbuffers below
                        if (slotBinds.Length > 1)
                        {
                            var node = parentNodes.Add(new object[] { "", setname, slotname, String.Format("Array[{0}]", slotBinds.Length), "", "", "", "" });

                            node.TreeColumn = 0;

                            if (!filledSlot)
                                EmptyRow(node);

                            if (!usedSlot)
                                InactiveRow(node);

                            parentNodes = node.Nodes;
                        }

                        for (int idx = 0; idx < slotBinds.Length; idx++)
                        {
                            var descriptorBind = slotBinds[idx];

                            if (slotBinds.Length > 1)
                            {
                                slotname = String.Format("{0}[{1}]", bind, idx);

                                if (shaderRes != null && shaderRes.name.Length > 0)
                                    slotname += ": " + shaderRes.name;
                            }

                            bool isbuf = false;
                            UInt32 w = 1, h = 1, d = 1;
                            UInt32 a = 1;
                            UInt32 samples = 1;
                            UInt64 len = 0;
                            string format = "Unknown";
                            string name = "Object " + descriptorBind.res.ToString();
                            ShaderResourceType restype = ShaderResourceType.None;
                            object tag = null;

                            if (!filledSlot)
                            {
                                name = "Empty";
                                format = "-";
                                w = h = d = a = 0;
                            }

                            // check to see if it's a texture
                            for (int t = 0; t < texs.Length; t++)
                            {
                                if (texs[t].ID == descriptorBind.res)
                                {
                                    w = texs[t].width;
                                    h = texs[t].height;
                                    d = texs[t].depth;
                                    a = texs[t].arraysize;
                                    format = texs[t].format.ToString();
                                    name = texs[t].name;
                                    restype = texs[t].resType;
                                    samples = texs[t].msSamp;

                                    tag = texs[t];
                                }
                            }

                            // if not a texture, it must be a buffer
                            for (int t = 0; t < bufs.Length; t++)
                            {
                                if (bufs[t].ID == descriptorBind.res)
                                {
                                    len = bufs[t].byteSize;
                                    w = bufs[t].length;
                                    h = 0;
                                    d = 0;
                                    a = 0;
                                    format = "";
                                    name = bufs[t].name;
                                    restype = ShaderResourceType.Buffer;

                                    tag = new BufferResTag(isrw, bindPoint, bufs[t].ID);

                                    isbuf = true;
                                }
                            }

                            TreelistView.Node node = null;

                            if (bindType == ShaderBindType.ReadWriteBuffer ||
                                bindType == ShaderBindType.ReadOnlyTBuffer ||
                                bindType == ShaderBindType.ReadWriteTBuffer
                                )
                            {
                                if (!isbuf)
                                {
                                    node = parentNodes.Add(new object[] {
                                        "", bindset, slotname, bindType, "-",
                                        "-",
                                        "",
                                        "",
                                    });

                                    EmptyRow(node);
                                }
                                else
                                {
                                    node = parentNodes.Add(new object[] {
                                        "", bindset, slotname, bindType, name,
                                        String.Format("{0} bytes", len),
                                        String.Format("{0} - {1}", descriptorBind.offset, descriptorBind.size),
                                        "",
                                    });

                                    node.Image = global::renderdocui.Properties.Resources.action;
                                    node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                                    node.Tag = tag;

                                    if (!filledSlot)
                                        EmptyRow(node);

                                    if (!usedSlot)
                                        InactiveRow(node);
                                }
                            }
                            else if (bindType == ShaderBindType.Sampler)
                            {
                                if (descriptorBind.sampler == ResourceId.Null)
                                {
                                    node = parentNodes.Add(new object[] {
                                        "", bindset, slotname, bindType, "-",
                                        "-",
                                        "",
                                        "",
                                    });

                                    EmptyRow(node);
                                }
                                else
                                {
                                    node = parentNodes.Add(MakeSampler(bindset.ToString(), slotname, descriptorBind));

                                    if (!filledSlot)
                                        EmptyRow(node);

                                    if (!usedSlot)
                                        InactiveRow(node);

                                    var data = new SamplerData(node);
                                    node.Tag = data;

                                    if (!samplers.ContainsKey(descriptorBind.sampler))
                                        samplers.Add(descriptorBind.sampler, data);
                                }
                            }
                            else
                            {
                                if (descriptorBind.res == ResourceId.Null)
                                {
                                    node = parentNodes.Add(new object[] {
                                        "", bindset, slotname, bindType, "-",
                                        "-",
                                        "",
                                        "",
                                    });

                                    EmptyRow(node);
                                }
                                else
                                {
                                    string typename = restype.Str() + " " + bindType.Str().Replace("&", "&&");

                                    string dim;

                                    if (restype == ShaderResourceType.Texture3D)
                                        dim = String.Format("{0}x{1}x{2}", w, h, d);
                                    else if (restype == ShaderResourceType.Texture1D || restype == ShaderResourceType.Texture1DArray)
                                        dim = w.ToString();
                                    else
                                        dim = String.Format("{0}x{1}", w, h);

                                    string arraydim = "-";

                                    if(restype == ShaderResourceType.Texture1DArray ||
                                       restype == ShaderResourceType.Texture2DArray ||
                                       restype == ShaderResourceType.Texture2DMSArray ||
                                       restype == ShaderResourceType.TextureCubeArray)
                                        arraydim = String.Format("{0}[{1}]", restype.Str(), a);

                                    if (restype == ShaderResourceType.Texture2DMS || restype == ShaderResourceType.Texture2DMSArray)
                                        dim += String.Format(", {0}x MSAA", samples);

                                    node = parentNodes.Add(new object[] {
                                        "", bindset, slotname, typename, name,
                                        dim,
                                        format,
                                        arraydim,
                                    });

                                    node.Image = global::renderdocui.Properties.Resources.action;
                                    node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                                    node.Tag = tag;

                                    if (!filledSlot)
                                        EmptyRow(node);

                                    if (!usedSlot)
                                        InactiveRow(node);
                                }

                                if (bindType == ShaderBindType.ImageSampler)
                                {
                                    if (descriptorBind.sampler == ResourceId.Null)
                                    {
                                        node = parentNodes.Add(new object[] {
                                            "", bindset, slotname, bindType, "-",
                                            "-",
                                            "",
                                            "",
                                        });

                                        EmptyRow(node);
                                    }
                                    else
                                    {
                                        var texnode = node;

                                        if (!samplers.ContainsKey(descriptorBind.sampler))
                                        {
                                            node = parentNodes.Add(MakeSampler("", "", descriptorBind));

                                            if (!filledSlot)
                                                EmptyRow(node);

                                            if (!usedSlot)
                                                InactiveRow(node);

                                            var data = new SamplerData(node);
                                            node.Tag = data;

                                            samplers.Add(descriptorBind.sampler, data);
                                        }

                                        if (texnode != null)
                                        {
                                            m_CombinedImageSamplers[texnode] = samplers[descriptorBind.sampler].node;
                                            samplers[descriptorBind.sampler].images.Add(texnode);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            resources.EndUpdate();
            resources.NodesSelection.Clear();
            resources.SetVScrollValue(vs);

            vs = cbuffers.VScrollValue();
            cbuffers.BeginUpdate();
            cbuffers.Nodes.Clear();
            for(int bindset = 0; bindset < pipe.DescSets.Length; bindset++)
            {
                for(int bind = 0; bind < pipe.DescSets[bindset].bindings.Length; bind++)
                {
                    ConstantBlock cblock = null;
                    BindpointMap bindMap = null;

                    uint slot = uint.MaxValue;
                    if (shaderDetails != null)
                    {
                        for (slot = 0; slot < (uint)shaderDetails.ConstantBlocks.Length; slot++)
                        {
                            ConstantBlock cb = shaderDetails.ConstantBlocks[slot];
                            if (stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bindset == bindset &&
                                stage.BindpointMapping.ConstantBlocks[cb.bindPoint].bind == bind)
                            {
                                cblock = cb;
                                bindMap = stage.BindpointMapping.ConstantBlocks[cb.bindPoint];
                                break;
                            }
                        }

                        if (slot >= (uint)shaderDetails.ConstantBlocks.Length)
                            slot = uint.MaxValue;
                    }

                    var slotBinds = pipe.DescSets[bindset].bindings[bind].binds;
                    ShaderBindType bindType = pipe.DescSets[bindset].bindings[bind].type;
                    ShaderStageBits stageBits = pipe.DescSets[bindset].bindings[bind].stageFlags;

                    // skip descriptors that aren't for this shader stage
                    if (!stageBits.HasFlag((ShaderStageBits)(1 << (int)stage.stage)))
                        continue;

                    // these are treated as uniform buffers
                    if (bindType != ShaderBindType.ReadOnlyBuffer)
                        continue;

                    bool usedSlot = bindMap != null && bindMap.used;

                    // consider it filled if any array element is filled (or it's push constants)
                    bool filledSlot = cblock != null && !cblock.bufferBacked;
                    for (int idx = 0; idx < slotBinds.Length; idx++)
                        filledSlot |= slotBinds[idx].res != ResourceId.Null;

                    // show if
                    if (usedSlot || // it's referenced by the shader - regardless of empty or not
                        (showDisabled.Checked && !usedSlot && filledSlot) || // it's bound, but not referenced, and we have "show disabled"
                        (showEmpty.Checked && !filledSlot) // it's empty, and we have "show empty"
                        )
                    {
                        TreelistView.NodeCollection parentNodes = cbuffers.Nodes;

                        string setname = bindset.ToString();

                        string slotname = bind.ToString();
                        if (cblock != null && cblock.name.Length > 0)
                            slotname += ": " + cblock.name;

                        // for arrays, add a parent element that we add the real cbuffers below
                        if (slotBinds.Length > 1)
                        {
                            var node = parentNodes.Add(new object[] { "", setname, slotname, String.Format("Array[{0}]", slotBinds.Length), "", "" });

                            node.TreeColumn = 0;

                            if (!filledSlot)
                                EmptyRow(node);

                            if (!usedSlot)
                                InactiveRow(node);

                            parentNodes = node.Nodes;
                        }

                        for (int idx = 0; idx < slotBinds.Length; idx++)
                        {
                            var descriptorBind = slotBinds[idx];

                            if (slotBinds.Length > 1)
                            {
                                slotname = String.Format("{0}[{1}]", bind, idx);

                                if (cblock != null && cblock.name.Length > 0)
                                    slotname += ": " + cblock.name;
                            }

                            string name = "UBO " + descriptorBind.res.ToString();
                            UInt64 length = descriptorBind.size;
                            int numvars = cblock != null ? cblock.variables.Length : 0;

                            if (!filledSlot)
                            {
                                name = "Empty";
                                length = 0;
                            }

                            for (int t = 0; t < bufs.Length; t++)
                                if (bufs[t].ID == descriptorBind.res)
                                    name = bufs[t].name;

                            if (name == "")
                                name = "UBO " + descriptorBind.res.ToString();

                            string sizestr = String.Format("{0} Variables, {1} bytes", numvars, length);
                            string vecrange = String.Format("{0} - {1}", descriptorBind.offset, descriptorBind.offset + descriptorBind.size);

                            // push constants
                            if (cblock != null && !cblock.bufferBacked)
                            {
                                setname = "";
                                slotname = cblock.name;
                                name = "Push constants";
                                vecrange = "";
                                sizestr = String.Format("{0} Variables", numvars);

                                // could maybe get range from ShaderVariable.reg if it's filled out
                                // from SPIR-V side.
                            }

                            var node = parentNodes.Add(new object[] { "", setname, slotname, name, vecrange, sizestr });

                            node.Image = global::renderdocui.Properties.Resources.action;
                            node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                            node.Tag = new CBufferTag(slot, (uint)idx);

                            if (!filledSlot)
                                EmptyRow(node);

                            if (!usedSlot)
                                InactiveRow(node);
                        }
                    }
                }
            }

            // search for push constants and add them last
            if (shaderDetails != null)
            {
                for (int cb = 0; cb < shaderDetails.ConstantBlocks.Length; cb++)
                {
                    var cblock = shaderDetails.ConstantBlocks[cb];
                    if (cblock.bufferBacked == false)
                    {
                        // could maybe get range from ShaderVariable.reg if it's filled out
                        // from SPIR-V side.

                        var node = cbuffers.Nodes.Add(new object[] { "", "",
                        cblock.name, "Push constants",
                        "", String.Format("{0} Variables", cblock.variables.Length) });

                        node.Image = global::renderdocui.Properties.Resources.action;
                        node.HoverImage = global::renderdocui.Properties.Resources.action_hover;
                        node.Tag = new CBufferTag((uint)cb, 0);
                    }
                }
            }
            cbuffers.EndUpdate();
            cbuffers.NodesSelection.Clear();
            cbuffers.SetVScrollValue(vs);
        }