};
// Enum containing float behaviors that its possible to test.
-enum BehaviorId
+enum BehaviorFlagBits
{
- B_DENORM_PERSERVE = 0, // DenormPreserve
- B_DENORM_FLUSH, // DenormFlushToZero
- B_ZIN_PERSERVE, // SignedZeroInfNanPreserve
- B_RTE_ROUNDING, // RoundingModeRTE
- B_RTZ_ROUNDING, // RoundingModeRTZ
+ B_DENORM_PERSERVE = 0x00000001, // DenormPreserve
+ B_DENORM_FLUSH = 0x00000002, // DenormFlushToZero
+ B_ZIN_PERSERVE = 0x00000004, // SignedZeroInfNanPreserve
+ B_RTE_ROUNDING = 0x00000008, // RoundingModeRTE
+ B_RTZ_ROUNDING = 0x00000010 // RoundingModeRTZ
};
+typedef deUint32 BehaviorFlags;
+
// Codes for all float values used in tests as arguments and operation results
// This approach allows to replace values with different types reducing complexity of the tests implementation
enum ValueId
V_DOT_RTZ_RESULT,
V_DOT_RTE_RESULT,
- // non comon results of some operation
+ // non comon results of some operation - corner cases
V_MINUS_ONE_OR_CLOSE, // value used only fur fp16 subtraction result of preserved denorm and one
V_PI_DIV_2,
V_ZERO_OR_MINUS_ZERO, // both +0 and -0 are accepted
V_ZERO_OR_FP32_DENORM_TO_FP64,
V_DENORM_TIMES_TWO,
V_DEGREES_DENORM,
- V_TRIG_ONE, // 1.0 trigonometric operations, including precision margin
+ V_TRIG_ONE, // 1.0 trigonometric operations, including precision margin
//results of conversion operations
V_CONV_TO_FP16_RTZ_RESULT,
V_CONV_TO_FP16_RTE_RESULT,
V_CONV_TO_FP32_RTZ_RESULT,
V_CONV_TO_FP32_RTE_RESULT,
- V_CONV_DENORM_SMALLER, // used e.g. when converting fp16 denorm to fp32
+ V_CONV_DENORM_SMALLER, // used e.g. when converting fp16 denorm to fp32
V_CONV_DENORM_BIGGER,
};
OperationTestCase() {}
OperationTestCase(const char* _baseName,
- BehaviorId _behaviorId,
+ BehaviorFlags _behaviorFlags,
OperationId _operatinId,
ValueId _input1,
ValueId _input2,
ValueId _expectedOutput)
: baseName(_baseName)
- , behaviorId(_behaviorId)
+ , behaviorFlags(_behaviorFlags)
, operationId(_operatinId)
, expectedOutput(_expectedOutput)
{
public:
string baseName;
- BehaviorId behaviorId;
+ BehaviorFlags behaviorFlags;
OperationId operationId;
ValueId input[2];
ValueId expectedOutput;
{
const BinaryCase& binaryCase = typeTestResults->binaryOpFTZ[i];
OperationId operation = binaryCase.operationId;
- testCases.push_back(OTC("denorm_op_var_flush_to_zero", B_DENORM_FLUSH, operation, V_DENORM, V_ONE, binaryCase.opVarResult));
- testCases.push_back(OTC("denorm_op_denorm_flush_to_zero", B_DENORM_FLUSH, operation, V_DENORM, V_DENORM, binaryCase.opDenormResult));
- testCases.push_back(OTC("denorm_op_inf_flush_to_zero", B_DENORM_FLUSH, operation, V_DENORM, V_INF, binaryCase.opInfResult));
- testCases.push_back(OTC("denorm_op_nan_flush_to_zero", B_DENORM_FLUSH, operation, V_DENORM, V_NAN, binaryCase.opNanResult));
+ testCases.push_back(OTC("denorm_op_var_flush_to_zero", B_DENORM_FLUSH, operation, V_DENORM, V_ONE, binaryCase.opVarResult));
+ testCases.push_back(OTC("denorm_op_denorm_flush_to_zero", B_DENORM_FLUSH, operation, V_DENORM, V_DENORM, binaryCase.opDenormResult));
+ testCases.push_back(OTC("denorm_op_inf_flush_to_zero", B_DENORM_FLUSH | B_ZIN_PERSERVE, operation, V_DENORM, V_INF, binaryCase.opInfResult));
+ testCases.push_back(OTC("denorm_op_nan_flush_to_zero", B_DENORM_FLUSH | B_ZIN_PERSERVE, operation, V_DENORM, V_NAN, binaryCase.opNanResult));
}
// Denorm - FlushToZero - unary operations
{
const BinaryCase& binaryCase = typeTestResults->binaryOpDenormPreserve[i];
OperationId operation = binaryCase.operationId;
- testCases.push_back(OTC("denorm_op_var_preserve", B_DENORM_PERSERVE, operation, V_DENORM, V_ONE, binaryCase.opVarResult));
- testCases.push_back(OTC("denorm_op_denorm_preserve", B_DENORM_PERSERVE, operation, V_DENORM, V_DENORM, binaryCase.opDenormResult));
- testCases.push_back(OTC("denorm_op_inf_preserve", B_DENORM_PERSERVE, operation, V_DENORM, V_INF, binaryCase.opInfResult));
- testCases.push_back(OTC("denorm_op_nan_preserve", B_DENORM_PERSERVE, operation, V_DENORM, V_NAN, binaryCase.opNanResult));
+ testCases.push_back(OTC("denorm_op_var_preserve", B_DENORM_PERSERVE, operation, V_DENORM, V_ONE, binaryCase.opVarResult));
+ testCases.push_back(OTC("denorm_op_denorm_preserve", B_DENORM_PERSERVE, operation, V_DENORM, V_DENORM, binaryCase.opDenormResult));
+ testCases.push_back(OTC("denorm_op_inf_preserve", B_DENORM_PERSERVE | B_ZIN_PERSERVE, operation, V_DENORM, V_INF, binaryCase.opInfResult));
+ testCases.push_back(OTC("denorm_op_nan_preserve", B_DENORM_PERSERVE | B_ZIN_PERSERVE, operation, V_DENORM, V_NAN, binaryCase.opNanResult));
}
// Denom - Preserve - unary operations
void specializeOperation(const TestCaseInfo& testCaseInfo,
SpecializedOperation& specializedOperation) const;
- void getBehaviorCapabilityAndExecutionMode(BehaviorId behaviorId,
+ void getBehaviorCapabilityAndExecutionMode(BehaviorFlags behaviorFlags,
const string inBitWidth,
const string outBitWidth,
string& capability,
void setupVulkanFeatures(FloatType inFloatType,
FloatType outFloatType,
- BehaviorId behaviorId,
+ BehaviorFlags behaviorFlags,
bool float64FeatureRequired,
VulkanFeatures& features) const;
map<FloatType, TypeData> m_typeData;
// Map converting behaviuor id to OpCapability instruction
- map<BehaviorId, string> m_behaviorToName;
+ typedef map<BehaviorFlagBits, string> BehaviorNameMap;
+ BehaviorNameMap m_behaviorToName;
};
TestGroupBuilderBase::TestGroupBuilderBase()
}
-void TestGroupBuilderBase::getBehaviorCapabilityAndExecutionMode(BehaviorId behaviorId,
+void TestGroupBuilderBase::getBehaviorCapabilityAndExecutionMode(BehaviorFlags behaviorFlags,
const string inBitWidth,
const string outBitWidth,
string& capability,
string& executionMode) const
{
- const string behaviorName = m_behaviorToName.at(behaviorId);
- bool rounding = (behaviorId == B_RTE_ROUNDING) || (behaviorId == B_RTZ_ROUNDING);
+ // iterate over all behaviours and request those that are needed
+ BehaviorNameMap::const_iterator it = m_behaviorToName.begin();
+ while (it != m_behaviorToName.end())
+ {
+ BehaviorFlagBits behaviorId = it->first;
+ string behaviorName = it->second;
+
+ if (behaviorFlags & behaviorId)
+ {
+ capability += "OpCapability " + behaviorName + "\n";
- capability = "OpCapability " + behaviorName + "\n";
+ // rounding mode should be obeyed for destination type
+ bool rounding = (behaviorId == B_RTE_ROUNDING) || (behaviorId == B_RTZ_ROUNDING);
+ executionMode += "OpExecutionMode %main " + behaviorName + " " +
+ (rounding ? outBitWidth : inBitWidth) + "\n";
+ }
+
+ ++it;
+ }
- // rounding mode should be obeyed for destination type
- executionMode = "OpExecutionMode %main " + behaviorName + " " +
- (rounding ? outBitWidth : inBitWidth) + "\n";
+ DE_ASSERT(!capability.empty() && !executionMode.empty());
}
void TestGroupBuilderBase::setupVulkanFeatures(FloatType inFloatType,
FloatType outFloatType,
- BehaviorId behaviorId,
+ BehaviorFlags behaviorFlags,
bool float64FeatureRequired,
VulkanFeatures& features) const
{
ExtensionFloatControlsFeatures& floatControls = features.floatControlsProperties;
// rounding mode should obey the destination type
- bool rteRounding = (behaviorId == B_RTE_ROUNDING);
- bool rtzRounding = (behaviorId == B_RTZ_ROUNDING);
+ bool rteRounding = (behaviorFlags & B_RTE_ROUNDING) != 0;
+ bool rtzRounding = (behaviorFlags & B_RTZ_ROUNDING) != 0;
if (rteRounding || rtzRounding)
{
switch(outFloatType)
switch(inFloatType)
{
case FP16:
- floatControls.shaderDenormPreserveFloat16 = behaviorId == B_DENORM_PERSERVE;
- floatControls.shaderDenormFlushToZeroFloat16 = behaviorId == B_DENORM_FLUSH;
- floatControls.shaderSignedZeroInfNanPreserveFloat16 = behaviorId == B_ZIN_PERSERVE;
+ floatControls.shaderDenormPreserveFloat16 = behaviorFlags & B_DENORM_PERSERVE;
+ floatControls.shaderDenormFlushToZeroFloat16 = behaviorFlags & B_DENORM_FLUSH;
+ floatControls.shaderSignedZeroInfNanPreserveFloat16 = behaviorFlags & B_ZIN_PERSERVE;
return;
case FP32:
- floatControls.shaderDenormPreserveFloat32 = behaviorId == B_DENORM_PERSERVE;
- floatControls.shaderDenormFlushToZeroFloat32 = behaviorId == B_DENORM_FLUSH;
- floatControls.shaderSignedZeroInfNanPreserveFloat32 = behaviorId == B_ZIN_PERSERVE;
+ floatControls.shaderDenormPreserveFloat32 = behaviorFlags & B_DENORM_PERSERVE;
+ floatControls.shaderDenormFlushToZeroFloat32 = behaviorFlags & B_DENORM_FLUSH;
+ floatControls.shaderSignedZeroInfNanPreserveFloat32 = behaviorFlags & B_ZIN_PERSERVE;
return;
case FP64:
- floatControls.shaderDenormPreserveFloat64 = behaviorId == B_DENORM_PERSERVE;
- floatControls.shaderDenormFlushToZeroFloat64 = behaviorId == B_DENORM_FLUSH;
- floatControls.shaderSignedZeroInfNanPreserveFloat64 = behaviorId == B_ZIN_PERSERVE;
+ floatControls.shaderDenormPreserveFloat64 = behaviorFlags & B_DENORM_PERSERVE;
+ floatControls.shaderDenormFlushToZeroFloat64 = behaviorFlags & B_DENORM_FLUSH;
+ floatControls.shaderSignedZeroInfNanPreserveFloat64 = behaviorFlags & B_ZIN_PERSERVE;
return;
}
}
string behaviorCapability;
string behaviorExecutionMode;
- getBehaviorCapabilityAndExecutionMode(testCase.behaviorId,
+ getBehaviorCapabilityAndExecutionMode(testCase.behaviorFlags,
inFloatWidthForCaps,
outTypeSnippets->bitWidth,
behaviorCapability,
setupVulkanFeatures(inFloatTypeForCaps, // usualy same as inFloatType - different only for UnpackHalf2x16
outFloatType,
- testCase.behaviorId,
+ testCase.behaviorFlags,
float64FeatureRequired,
csSpec.requestedVulkanFeatures);
// be implemented as a method because of how addFunctionCaseWithPrograms
// was implemented
- SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
- const deUint32 vulkanVersion = dst.usedVulkanVersion;
+ SpirvVersion targetSpirvVersion = context.resources.spirvVersion;
+ const deUint32 vulkanVersion = dst.usedVulkanVersion;
static const string vertexTemplate =
"OpCapability Shader\n"
string behaviorCapability;
string behaviorExecutionMode;
- getBehaviorCapabilityAndExecutionMode(testCase.behaviorId,
+ getBehaviorCapabilityAndExecutionMode(testCase.behaviorFlags,
inFloatWidthForCaps,
outTypeSnippets->bitWidth,
behaviorCapability,
VulkanFeatures vulkanFeatures;
setupVulkanFeatures(inFloatTypeForCaps, // usualy same as inFloatType - different only for UnpackHalf2x16
outFloatType,
- testCase.behaviorId,
+ testCase.behaviorFlags,
float64FeatureRequired,
vulkanFeatures);
vulkanFeatures.coreFeatures.fragmentStoresAndAtomics = true;