// Convert to int four tuple internal static void ConvertValueToMilColorI(object value, out MilColorI newVal) { Type t = value.GetType(); // Fill in four-tuples. Always fill in 1's for where there are // empty slots, to avoid division by zero on vector operations that // these values are subjected to. int iVal = 1; // // Note: conversions from long/ulong/uint can change the sign of the number // if (t == typeof(long)) { iVal = (int)(long)value; } else if (t == typeof(ulong)) { iVal = (int)(ulong)value; } else if (t == typeof(uint)) { iVal = (int)(uint)value; } else if (t == typeof(short)) { iVal = (int)(short)value; } else if (t == typeof(ushort)) { iVal = (int)(ushort)value; } else if (t == typeof(byte)) { iVal = (int)(byte)value; } else if (t == typeof(sbyte)) { iVal = (int)(sbyte)value; } else if (t == typeof(char)) { iVal = (int)(char)value; } else { iVal = (int)value; } // Scalars extend out to fill entire vector. newVal.r = newVal.g = newVal.b = newVal.a = iVal; }
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(); } } } }