private static PixelShaderInputRegisterDeclarationToken FindInputRegisterDeclaration(
     IEnumerable<PixelShaderInputRegisterDeclarationToken> inputRegisterDeclarations, 
     SignatureParameterDescription inputParameter)
 {
     return inputRegisterDeclarations.FirstOrDefault(x => 
         x.Operand.Indices[0].Value == inputParameter.Register &&
             x.Operand.ComponentMask == inputParameter.ReadWriteMask);
 }
Beispiel #2
0
        public static InputOutputSignatureChunk Parse(BytecodeReader reader, ChunkType chunkType,
                                                      ProgramType programType)
        {
            InputOutputSignatureChunk result;

            switch (chunkType)
            {
            case ChunkType.Isgn:
                result = new InputSignatureChunk();
                break;

            case ChunkType.Osgn:
            case ChunkType.Osg5:
                result = new OutputSignatureChunk();
                break;

            case ChunkType.Pcsg:
                result = new PatchConstantSignatureChunk();
                break;

            default:
                throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType);
            }

            var chunkReader  = reader.CopyAtCurrentPosition();
            var elementCount = chunkReader.ReadUInt32();
            var uniqueKey    = chunkReader.ReadUInt32();

            SignatureElementSize elementSize;

            switch (chunkType)
            {
            case ChunkType.Osg5:
                elementSize = SignatureElementSize._7;
                break;

            case ChunkType.Isgn:
            case ChunkType.Osgn:
            case ChunkType.Pcsg:
                elementSize = SignatureElementSize._6;
                break;

            default:
                throw new ArgumentOutOfRangeException("chunkType", "Unrecognised chunk type: " + chunkType);
            }

            for (int i = 0; i < elementCount; i++)
            {
                result.Parameters.Add(SignatureParameterDescription.Parse(reader, chunkReader, chunkType, elementSize,
                                                                          programType));
            }

            return(result);
        }
        public static SignatureParameterDescription Parse(BytecodeReader reader, BytecodeReader parameterReader,
                                                          ChunkType chunkType, SignatureElementSize size, ProgramType programType)
        {
            uint stream = 0;

            if (size == SignatureElementSize._7 || size == SignatureElementSize._8)
            {
                stream = parameterReader.ReadUInt32();
            }
            uint nameOffset = parameterReader.ReadUInt32();
            var  nameReader = reader.CopyAtOffset((int)nameOffset);

            var result = new SignatureParameterDescription
            {
                SemanticName    = nameReader.ReadString(),
                SemanticIndex   = parameterReader.ReadUInt32(),
                SystemValueType = (Name)parameterReader.ReadUInt32(),
                ComponentType   = (RegisterComponentType)parameterReader.ReadUInt32(),
                Register        = parameterReader.ReadUInt32(),
                Stream          = stream,
            };

            uint mask = parameterReader.ReadUInt32();

            result.Mask          = mask.DecodeValue <ComponentMask>(0, 7);
            result.ReadWriteMask = mask.DecodeValue <ComponentMask>(8, 15);

            if (size == SignatureElementSize._8)
            {
                MinPrecision minPrecision = (MinPrecision)parameterReader.ReadUInt32();
                result.MinPrecision = minPrecision;
            }

            // This is my guesswork, but it works so far...
            if (chunkType == ChunkType.Osg5 ||
                chunkType == ChunkType.Osgn ||
                chunkType == ChunkType.Osg1 ||
                (chunkType == ChunkType.Pcsg && programType == ProgramType.HullShader))
            {
                result.ReadWriteMask = (ComponentMask)(ComponentMask.All - result.ReadWriteMask);
            }

            // Vertex and pixel shaders need special handling for SystemValueType in the output signature.
            if ((programType == ProgramType.PixelShader || programType == ProgramType.VertexShader) &&
                (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn || chunkType == ChunkType.Osg1))
            {
                if (result.Register == 0xffffffff)
                {
                    switch (result.SemanticName.ToUpper())
                    {
                    case "SV_DEPTH":
                        result.SystemValueType = Name.Depth;
                        break;

                    case "SV_COVERAGE":
                        result.SystemValueType = Name.Coverage;
                        break;

                    case "SV_DEPTHGREATEREQUAL":
                        result.SystemValueType = Name.DepthGreaterEqual;
                        break;

                    case "SV_DEPTHLESSEQUAL":
                        result.SystemValueType = Name.DepthLessEqual;
                        break;

                    case "SV_STENCILREF":
                        result.SystemValueType = Name.StencilRef;
                        break;
                    }
                }
                else if (programType == ProgramType.PixelShader)
                {
                    result.SystemValueType = Name.Target;
                }
            }

            return(result);
        }
		private static void CompareParameter(ShaderParameterDescription expected,
			SignatureParameterDescription actual)
		{
			Assert.AreEqual((int) expected.ComponentType, (int) actual.ComponentType);
			//Assert.AreEqual((int) expected.ReadWriteMask, (int) actual.ReadWriteMask); // TODO: Bug in SharpDX?
			if (expected.Register != -1 || actual.Register != uint.MaxValue)
				Assert.AreEqual(expected.Register, actual.Register);
			Assert.AreEqual(expected.SemanticIndex, actual.SemanticIndex);
			Assert.AreEqual(expected.SemanticName, actual.SemanticName);
			Assert.AreEqual(expected.Stream, actual.Stream);
			Assert.AreEqual((int) expected.SystemValueType, (int) actual.SystemValueType);
			//Assert.AreEqual((int) expected.UsageMask, (int) actual.Mask); // TODO: Bug in SharpDX?
		}
		public static SignatureParameterDescription Parse(BytecodeReader reader, BytecodeReader parameterReader,
			ChunkType chunkType, SignatureElementSize size, ProgramType programType)
		{
			uint stream = 0;
			if (size == SignatureElementSize._7)
				stream = parameterReader.ReadUInt32();

			uint nameOffset = parameterReader.ReadUInt32();
			var nameReader = reader.CopyAtOffset((int) nameOffset);

			var result = new SignatureParameterDescription
			{
				SemanticName = nameReader.ReadString(),
				SemanticIndex = parameterReader.ReadUInt32(),
				SystemValueType = (Name) parameterReader.ReadUInt32(),
				ComponentType = (RegisterComponentType) parameterReader.ReadUInt32(),
				Register = parameterReader.ReadUInt32(),
				Stream = stream,
				//MinPrecision = (MinPrecision) parameterReader.ReadByte() TODO
			};

			uint mask = parameterReader.ReadUInt32();
			result.Mask = mask.DecodeValue<ComponentMask>(0, 7);
			result.ReadWriteMask = mask.DecodeValue<ComponentMask>(8, 15);

			// This is my guesswork, but it works so far...
			if (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn
				|| (chunkType == ChunkType.Pcsg && programType == ProgramType.HullShader))
				result.ReadWriteMask = (ComponentMask) (ComponentMask.All - result.ReadWriteMask);

			// Vertex and pixel shaders need special handling for SystemValueType in the output signature.
			if ((programType == ProgramType.PixelShader || programType == ProgramType.VertexShader)
				&& (chunkType == ChunkType.Osg5 || chunkType == ChunkType.Osgn))
			{
				if (result.Register == 0xffffffff)
					switch (result.SemanticName.ToUpper())
					{
						case "SV_DEPTH":
							result.SystemValueType = Name.Depth;
							break;
						case "SV_COVERAGE":
							result.SystemValueType = Name.Coverage;
							break;
						case "SV_DEPTHGREATEREQUAL":
							result.SystemValueType = Name.DepthGreaterEqual;
							break;
						case "SV_DEPTHLESSEQUAL":
							result.SystemValueType = Name.DepthLessEqual;
							break;
					}
				else if (programType == ProgramType.PixelShader)
					result.SystemValueType = Name.Target;
			}

			return result;
		}