/// <summary> /// Creates merged parameter from given combination. /// </summary> /// <param name="combination"> The merge combination to try. </param> /// <param name="paramsTable"> The params table sorted by tpes in each row. </param> /// <param name="mergedParameter"> Will hold the merged parameter </param> /// <returns> </returns> internal static bool MergeParametersByCombination(MergeCombination combination, List <Parameter>[] paramsTable, out MergeParameter mergedParameter) { mergedParameter = new MergeParameter(); //Make sure we have enough parameters to combine. if (combination.srcParameterTypeCount[0] > paramsTable[0].Count || combination.srcParameterTypeCount[1] > paramsTable[1].Count || combination.srcParameterTypeCount[2] > paramsTable[2].Count || combination.srcParameterTypeCount[3] > paramsTable[3].Count) { return(false); } //Create the new output parameter. for (int i = 0; i < 4; ++i) { var curParamList = paramsTable[i]; int srcParameterTypeCount = combination.srcParameterTypeCount[i]; int srcParameterCount = 0; while (srcParameterCount > 0) { mergedParameter.AddSourceParameter(curParamList[curParamList.Count - 1], combination.srcParameterMask[srcParameterCount]); curParamList.RemoveAt(curParamList.Count - 1); srcParameterCount++; --srcParameterTypeCount; } } return(true); }
/// <summary> /// Merge reminders parameters that could not be merged into one slot using the predefined combinations. /// </summary> /// <param name="paramsTable"> The params table sorted by types in each row. </param> /// <param name="mergedParams"> The merged parameters list </param> /// <param name="splitParams"> The split parameters list </param> internal static void MergeParametersReminders(List <Parameter>[] paramsTable, List <MergeParameter> mergedParams, List <Parameter> splitParams) { //Handle reminders parameters - All of the parameters that could not be packed perfectly. int mergedParamsBaseIndex = mergedParams.Count; int remindersFloatCount = (1 * paramsTable[0].Count) + (2 * paramsTable[1].Count) + (3 * paramsTable[2].Count) + (4 * paramsTable[3].Count); int reminderFloatMod = remindersFloatCount % 4; int remindersFullSlotCount = remindersFloatCount / 4; int remindersPartialSlotCount = reminderFloatMod > 0 ? 1 : 0; int remindersTotalSlotCount = remindersFullSlotCount + remindersPartialSlotCount; //First pass -> fill the slots with the largest reminders paramters. for (int slot = 0; slot < remindersTotalSlotCount; ++slot) { MergeParameter curMergeParam; for (int row = 0; row < 4; ++row) { List <Parameter> curParamList = paramsTable[3 - row]; //Case this list contains parameters - remove it and add to merged params. if (curParamList.Count > 0) { curMergeParam = new MergeParameter(); curMergeParam.AddSourceParameter(curParamList[curParamList.Count - 1], (int)Operand.OpMask.All); curParamList.RemoveAt(curParamList.Count - 1); mergedParams.Add(curMergeParam); } } } //Second pass -> merge the reminders parameters. for (int row = 0; row < 4; ++row) { var curParamList = paramsTable[3 - row]; //Merge the all the paramters of the current list. while (curParamList.Count > 0) { Parameter srcParameter = curParamList[curParamList.Count - 1]; int splitCount = 0; // How many times the source paramter has been split. int srcParamterComponents; int srcParameterFloats; int curSrcParameterFloats; srcParameterFloats = GetParameterFloatCount(srcParameter.Type); curSrcParameterFloats = srcParameterFloats; srcParamterComponents = GetParameterMaskByType(srcParameter.Type); //while this parameter has remaining components -> split it. while (curSrcParameterFloats > 0) { for (int slot = 0; slot < remindersTotalSlotCount && curSrcParameterFloats > 0; ++slot) { MergeParameter curMergeParam = mergedParams[mergedParamsBaseIndex + slot]; int freeFloatCount = 4 - curMergeParam.UsedFloatCount; //Case this slot has free space. if (freeFloatCount > 0) { //Case current components of source paramter can go all into this slot without split. if (srcParameterFloats < freeFloatCount && splitCount == 0) { curMergeParam.AddSourceParameter(srcParameter, (int)Operand.OpMask.All); } //case we have to split the current source parameter } else { int srcComponentMask; //Create the mask that tell us which part of the source componetn is added to the merged paramter. srcComponentMask = GetParameterMaskByFloatCount(freeFloatCount) << splitCount; //Add the partial source paramter to merged paramter. curMergeParam.AddSourceParameter(srcParameter, srcComponentMask & srcParamterComponents); } splitCount++; //Update left floats count if (srcParameterFloats < freeFloatCount) { curSrcParameterFloats -= srcParameterFloats; } else { curSrcParameterFloats -= freeFloatCount; } } } //Add to split params list if (splitCount > 1) { splitParams.Add(srcParameter); } curParamList.RemoveAt(curParamList.Count - 1); } } }
/// <summary> /// Merge reminders parameters that could not be merged into one slot using the predefined combinations. /// </summary> /// <param name="paramsTable"> The params table sorted by types in each row. </param> /// <param name="mergedParams"> The merged parameters list </param> /// <param name="splitParams"> The split parameters list </param> internal static void MergeParametersReminders( List<Parameter>[] paramsTable, List<MergeParameter> mergedParams, List<Parameter> splitParams ) { //Handle reminders parameters - All of the parameters that could not be packed perfectly. int mergedParamsBaseIndex = mergedParams.Count; int remindersFloatCount = ( 1*paramsTable[ 0 ].Count ) + ( 2*paramsTable[ 1 ].Count ) + ( 3*paramsTable[ 2 ].Count ) + ( 4*paramsTable[ 3 ].Count ); int reminderFloatMod = remindersFloatCount%4; int remindersFullSlotCount = remindersFloatCount/4; int remindersPartialSlotCount = reminderFloatMod > 0 ? 1 : 0; int remindersTotalSlotCount = remindersFullSlotCount + remindersPartialSlotCount; //First pass -> fill the slots with the largest reminders paramters. for ( int slot = 0; slot < remindersTotalSlotCount; ++slot ) { MergeParameter curMergeParam; for ( int row = 0; row < 4; ++row ) { List<Parameter> curParamList = paramsTable[ 3 - row ]; //Case this list contains parameters - remove it and add to merged params. if ( curParamList.Count > 0 ) { curMergeParam = new MergeParameter(); curMergeParam.AddSourceParameter( curParamList[ curParamList.Count - 1 ], (int)Operand.OpMask.All ); curParamList.RemoveAt( curParamList.Count - 1 ); mergedParams.Add( curMergeParam ); } } } //Second pass -> merge the reminders parameters. for ( int row = 0; row < 4; ++row ) { var curParamList = paramsTable[ 3 - row ]; //Merge the all the paramters of the current list. while ( curParamList.Count > 0 ) { Parameter srcParameter = curParamList[ curParamList.Count - 1 ]; int splitCount = 0; // How many times the source paramter has been split. int srcParamterComponents; int srcParameterFloats; int curSrcParameterFloats; srcParameterFloats = GetParameterFloatCount( srcParameter.Type ); curSrcParameterFloats = srcParameterFloats; srcParamterComponents = GetParameterMaskByType( srcParameter.Type ); //while this parameter has remaining components -> split it. while ( curSrcParameterFloats > 0 ) { for ( int slot = 0; slot < remindersTotalSlotCount && curSrcParameterFloats > 0; ++slot ) { MergeParameter curMergeParam = mergedParams[ mergedParamsBaseIndex + slot ]; int freeFloatCount = 4 - curMergeParam.UsedFloatCount; //Case this slot has free space. if ( freeFloatCount > 0 ) { //Case current components of source paramter can go all into this slot without split. if ( srcParameterFloats < freeFloatCount && splitCount == 0 ) { curMergeParam.AddSourceParameter( srcParameter, (int)Operand.OpMask.All ); } //case we have to split the current source parameter } else { int srcComponentMask; //Create the mask that tell us which part of the source componetn is added to the merged paramter. srcComponentMask = GetParameterMaskByFloatCount( freeFloatCount ) << splitCount; //Add the partial source paramter to merged paramter. curMergeParam.AddSourceParameter( srcParameter, srcComponentMask & srcParamterComponents ); } splitCount++; //Update left floats count if ( srcParameterFloats < freeFloatCount ) { curSrcParameterFloats -= srcParameterFloats; } else { curSrcParameterFloats -= freeFloatCount; } } } //Add to split params list if ( splitCount > 1 ) { splitParams.Add( srcParameter ); } curParamList.RemoveAt( curParamList.Count - 1 ); } } }
/// <summary> /// Creates merged parameter from given combination. /// </summary> /// <param name="combination"> The merge combination to try. </param> /// <param name="paramsTable"> The params table sorted by tpes in each row. </param> /// <param name="mergedParameter"> Will hold the merged parameter </param> /// <returns> </returns> internal static bool MergeParametersByCombination( MergeCombination combination, List<Parameter>[] paramsTable, out MergeParameter mergedParameter ) { mergedParameter = new MergeParameter(); //Make sure we have enough parameters to combine. if ( combination.srcParameterTypeCount[ 0 ] > paramsTable[ 0 ].Count || combination.srcParameterTypeCount[ 1 ] > paramsTable[ 1 ].Count || combination.srcParameterTypeCount[ 2 ] > paramsTable[ 2 ].Count || combination.srcParameterTypeCount[ 3 ] > paramsTable[ 3 ].Count ) { return false; } //Create the new output parameter. for ( int i = 0; i < 4; ++i ) { var curParamList = paramsTable[ i ]; int srcParameterTypeCount = combination.srcParameterTypeCount[ i ]; int srcParameterCount = 0; while ( srcParameterCount > 0 ) { mergedParameter.AddSourceParameter( curParamList[ curParamList.Count - 1 ], combination.srcParameterMask[ srcParameterCount ] ); curParamList.RemoveAt( curParamList.Count - 1 ); srcParameterCount++; --srcParameterTypeCount; } } return true; }