ATOMIC_OPERATION_OR,
ATOMIC_OPERATION_XOR,
ATOMIC_OPERATION_EXCHANGE,
+ ATOMIC_OPERATION_COMPARE_EXCHANGE,
ATOMIC_OPERATION_LAST
};
case ATOMIC_OPERATION_XOR:
return string("(" + x + "*" + x + " + " + y + "*" + y + " + " + z + "*" + z + ")");
case ATOMIC_OPERATION_EXCHANGE:
+ case ATOMIC_OPERATION_COMPARE_EXCHANGE:
return string("((" + z + "*" + toString(gridSize.x()) + " + " + x + ")*" + toString(gridSize.y()) + " + " + y + ")");
default:
DE_ASSERT(false);
{
switch (op)
{
- case ATOMIC_OPERATION_ADD: return string("add");
- case ATOMIC_OPERATION_MIN: return string("min");
- case ATOMIC_OPERATION_MAX: return string("max");
- case ATOMIC_OPERATION_AND: return string("and");
- case ATOMIC_OPERATION_OR: return string("or");
- case ATOMIC_OPERATION_XOR: return string("xor");
- case ATOMIC_OPERATION_EXCHANGE: return string("exchange");
+ case ATOMIC_OPERATION_ADD: return string("add");
+ case ATOMIC_OPERATION_MIN: return string("min");
+ case ATOMIC_OPERATION_MAX: return string("max");
+ case ATOMIC_OPERATION_AND: return string("and");
+ case ATOMIC_OPERATION_OR: return string("or");
+ case ATOMIC_OPERATION_XOR: return string("xor");
+ case ATOMIC_OPERATION_EXCHANGE: return string("exchange");
+ case ATOMIC_OPERATION_COMPARE_EXCHANGE: return string("compare_exchange");
default:
DE_ASSERT(false);
return DE_NULL;
{
switch (op)
{
- case ATOMIC_OPERATION_ADD: return string("imageAtomicAdd");
- case ATOMIC_OPERATION_MIN: return string("imageAtomicMin");
- case ATOMIC_OPERATION_MAX: return string("imageAtomicMax");
- case ATOMIC_OPERATION_AND: return string("imageAtomicAnd");
- case ATOMIC_OPERATION_OR: return string("imageAtomicOr");
- case ATOMIC_OPERATION_XOR: return string("imageAtomicXor");
- case ATOMIC_OPERATION_EXCHANGE: return string("imageAtomicExchange");
+ case ATOMIC_OPERATION_ADD: return string("imageAtomicAdd");
+ case ATOMIC_OPERATION_MIN: return string("imageAtomicMin");
+ case ATOMIC_OPERATION_MAX: return string("imageAtomicMax");
+ case ATOMIC_OPERATION_AND: return string("imageAtomicAnd");
+ case ATOMIC_OPERATION_OR: return string("imageAtomicOr");
+ case ATOMIC_OPERATION_XOR: return string("imageAtomicXor");
+ case ATOMIC_OPERATION_EXCHANGE: return string("imageAtomicExchange");
+ case ATOMIC_OPERATION_COMPARE_EXCHANGE: return string("imageAtomicCompSwap");
default:
DE_ASSERT(false);
return DE_NULL;
switch (op)
{
// \note 18 is just an arbitrary small nonzero value.
- case ATOMIC_OPERATION_ADD: return 18;
- case ATOMIC_OPERATION_MIN: return (1 << 15) - 1;
- case ATOMIC_OPERATION_MAX: return 18;
- case ATOMIC_OPERATION_AND: return (1 << 15) - 1;
- case ATOMIC_OPERATION_OR: return 18;
- case ATOMIC_OPERATION_XOR: return 18;
- case ATOMIC_OPERATION_EXCHANGE: return 18;
+ case ATOMIC_OPERATION_ADD: return 18;
+ case ATOMIC_OPERATION_MIN: return (1 << 15) - 1;
+ case ATOMIC_OPERATION_MAX: return 18;
+ case ATOMIC_OPERATION_AND: return (1 << 15) - 1;
+ case ATOMIC_OPERATION_OR: return 18;
+ case ATOMIC_OPERATION_XOR: return 18;
+ case ATOMIC_OPERATION_EXCHANGE: return 18;
+ case ATOMIC_OPERATION_COMPARE_EXCHANGE: return 18;
default:
DE_ASSERT(false);
return -1;
case ATOMIC_OPERATION_XOR:
return x*x + y*y + z*z;
case ATOMIC_OPERATION_EXCHANGE:
+ case ATOMIC_OPERATION_COMPARE_EXCHANGE:
return (z*gridSize.x() + x)*gridSize.y() + y;
default:
DE_ASSERT(false);
{
switch (op)
{
- case ATOMIC_OPERATION_ADD: return a + b;
- case ATOMIC_OPERATION_MIN: return de::min(a, b);
- case ATOMIC_OPERATION_MAX: return de::max(a, b);
- case ATOMIC_OPERATION_AND: return a & b;
- case ATOMIC_OPERATION_OR: return a | b;
- case ATOMIC_OPERATION_XOR: return a ^ b;
- case ATOMIC_OPERATION_EXCHANGE: return b;
+ case ATOMIC_OPERATION_ADD: return a + b;
+ case ATOMIC_OPERATION_MIN: return de::min(a, b);
+ case ATOMIC_OPERATION_MAX: return de::max(a, b);
+ case ATOMIC_OPERATION_AND: return a & b;
+ case ATOMIC_OPERATION_OR: return a | b;
+ case ATOMIC_OPERATION_XOR: return a ^ b;
+ case ATOMIC_OPERATION_EXCHANGE: return b;
+ case ATOMIC_OPERATION_COMPARE_EXCHANGE: return (a == 18) ? b : a;
default:
DE_ASSERT(false);
return -1;
const string atomicArgExpr = (uintFormat ? "uint" : intFormat ? "int" : "float")
+ getAtomicFuncArgumentShaderStr(m_operation, "gx", "gy", "gz", IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z()));
- const string atomicInvocation = getAtomicOperationShaderFuncName(m_operation) + "(u_resultImage, " + atomicCoord + ", " + atomicArgExpr + ")";
+ const string compareExchangeStr = (m_operation == ATOMIC_OPERATION_COMPARE_EXCHANGE) ? ", 18" + string(uintFormat ? "u" : "") : "";
+ const string atomicInvocation = getAtomicOperationShaderFuncName(m_operation) + "(u_resultImage, " + atomicCoord + compareExchangeStr + ", " + atomicArgExpr + ")";
const string shaderImageFormatStr = getShaderImageFormatQualifier(m_format);
const string shaderImageTypeStr = getShaderImageType(m_format, m_imageType);
const string atomicArgExpr = (uintFormat ? "uint" : intFormat ? "int" : "float")
+ getAtomicFuncArgumentShaderStr(m_operation, "gx", "gy", "gz", IVec3(NUM_INVOCATIONS_PER_PIXEL*gridSize.x(), gridSize.y(), gridSize.z()));
- const string atomicInvocation = getAtomicOperationShaderFuncName(m_operation) + "(u_resultImage, " + atomicCoord + ", " + atomicArgExpr + ")";
+ const string compareExchangeStr = (m_operation == ATOMIC_OPERATION_COMPARE_EXCHANGE) ? ", 18" + string(uintFormat ? "u" : "") : "";
+ const string atomicInvocation = getAtomicOperationShaderFuncName(m_operation) + "(u_resultImage, " + atomicCoord + compareExchangeStr + ", " + atomicArgExpr + ")";
const string shaderImageFormatStr = getShaderImageFormatQualifier(m_format);
const string shaderImageTypeStr = getShaderImageType(m_format, m_imageType);
const Unique<VkPipeline> pipeline(makeComputePipeline(deviceInterface, device, *pipelineLayout, *shaderModule));
// Create command buffer
- const Unique<VkCommandPool> cmdPool(makeCommandPool(deviceInterface, device, queueFamilyIndex));
- const Unique<VkCommandBuffer> cmdBuffer(makeCommandBuffer(deviceInterface, device, *cmdPool));
+ const Unique<VkCommandPool> cmdPool(createCommandPool(deviceInterface, device, VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, queueFamilyIndex));
+ const Unique<VkCommandBuffer> cmdBuffer(allocateCommandBuffer(deviceInterface, device, *cmdPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY));
beginCommandBuffer(deviceInterface, *cmdBuffer);
if (!matchFound)
return false;
}
+ else if (m_operation == ATOMIC_OPERATION_COMPARE_EXCHANGE)
+ {
+ // Check if the end result equals one of the atomic args.
+ bool matchFound = false;
+
+ for (deInt32 i = 0; i < static_cast<deInt32>(NUM_INVOCATIONS_PER_PIXEL) && !matchFound; i++)
+ {
+ const IVec3 gid(x + i*gridSize.x(), y, z);
+ matchFound = (resultValue == getAtomicFuncArgument(m_operation, gid, extendedGridSize));
+ }
+
+ if (!matchFound)
+ return false;
+ }
else
DE_ASSERT(false);
}
const ImageType imageType = imageParamsArray[imageTypeNdx].m_imageType;
const tcu::UVec3 imageSize = imageParamsArray[imageTypeNdx].m_imageSize;
+ de::MovePtr<tcu::TestCaseGroup> imageTypeGroup(new tcu::TestCaseGroup(testCtx, getImageTypeName(imageType).c_str(), ""));
+
for (deUint32 formatNdx = 0; formatNdx < DE_LENGTH_OF_ARRAY(formats); formatNdx++)
{
const TextureFormat& format = formats[formatNdx];
const std::string formatName = getShaderImageFormatQualifier(format);
//!< Atomic case checks the end result of the operations, and not the intermediate return values
- const string caseEndResult = getImageTypeName(imageType) + "_" + formatName + "_end_result";
- operationGroup->addChild(new BinaryAtomicEndResultCase(testCtx, caseEndResult, "", imageType, imageSize, format, operation, glu::GLSL_VERSION_440));
+ const string caseEndResult = formatName + "_end_result";
+ imageTypeGroup->addChild(new BinaryAtomicEndResultCase(testCtx, caseEndResult, "", imageType, imageSize, format, operation, glu::GLSL_VERSION_440));
//!< Atomic case checks the return values of the atomic function and not the end result.
- const string caseIntermValues = getImageTypeName(imageType) + "_" + formatName + "_intermediate_values";
- operationGroup->addChild(new BinaryAtomicIntermValuesCase(testCtx, caseIntermValues, "", imageType, imageSize, format, operation, glu::GLSL_VERSION_440));
+ const string caseIntermValues = formatName + "_intermediate_values";
+ imageTypeGroup->addChild(new BinaryAtomicIntermValuesCase(testCtx, caseIntermValues, "", imageType, imageSize, format, operation, glu::GLSL_VERSION_440));
}
+
+ operationGroup->addChild(imageTypeGroup.release());
}
imageAtomicOperationsTests->addChild(operationGroup.release());