// Check for image functions other than queries
if (node->isImage()) {
- std::vector<spv::Id> operands;
+ std::vector<spv::IdImmediate> operands;
auto opIt = arguments.begin();
- operands.push_back(*(opIt++));
+ spv::IdImmediate image = { true, *(opIt++) };
+ operands.push_back(image);
// Handle subpass operations
// TODO: GLSL should change to have the "MS" only on the type rather than the
std::vector<spv::Id> comps;
comps.push_back(zero);
comps.push_back(zero);
- operands.push_back(builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps));
+ spv::IdImmediate coord = { true,
+ builder.makeCompositeConstant(builder.makeVectorType(builder.makeIntType(32), 2), comps) };
+ operands.push_back(coord);
if (sampler.ms) {
- operands.push_back(spv::ImageOperandsSampleMask);
- operands.push_back(*(opIt++));
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *(opIt++) };
+ operands.push_back(imageOperand);
}
spv::Id result = builder.createOp(spv::OpImageRead, resultType(), operands);
builder.setPrecision(result, precision);
return result;
}
- operands.push_back(*(opIt++));
+ spv::IdImmediate coord = { true, *(opIt++) };
+ operands.push_back(coord);
#ifdef AMD_EXTENSIONS
if (node->getOp() == glslang::EOpImageLoad || node->getOp() == glslang::EOpImageLoadLod) {
#else
if (node->getOp() == glslang::EOpImageLoad) {
#endif
if (sampler.ms) {
- operands.push_back(spv::ImageOperandsSampleMask);
- operands.push_back(*opIt);
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *opIt };
+ operands.push_back(imageOperand);
#ifdef AMD_EXTENSIONS
} else if (cracked.lod) {
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
- operands.push_back(spv::ImageOperandsLodMask);
- operands.push_back(*opIt);
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *opIt };
+ operands.push_back(imageOperand);
#endif
}
- if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+ if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
- std::vector<spv::Id> result( 1, builder.createOp(spv::OpImageRead, resultType(), operands) );
+ std::vector<spv::Id> result(1, builder.createOp(spv::OpImageRead, resultType(), operands));
builder.setPrecision(result[0], precision);
// If needed, add a conversion constructor to the proper size.
} else if (node->getOp() == glslang::EOpImageStore) {
#endif
if (sampler.ms) {
- operands.push_back(*(opIt + 1));
- operands.push_back(spv::ImageOperandsSampleMask);
- operands.push_back(*opIt);
+ spv::IdImmediate texel = { true, *(opIt + 1) };
+ operands.push_back(texel);
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *opIt };
+ operands.push_back(imageOperand);
#ifdef AMD_EXTENSIONS
} else if (cracked.lod) {
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
- operands.push_back(*(opIt + 1));
- operands.push_back(spv::ImageOperandsLodMask);
- operands.push_back(*opIt);
+ spv::IdImmediate texel = { true, *(opIt + 1) };
+ operands.push_back(texel);
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *opIt };
+ operands.push_back(imageOperand);
#endif
- } else
- operands.push_back(*opIt);
+ } else {
+ spv::IdImmediate texel = { true, *opIt };
+ operands.push_back(texel);
+ }
builder.createNoResultOp(spv::OpImageWrite, operands);
- if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+ if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
builder.addCapability(spv::CapabilityStorageImageWriteWithoutFormat);
return spv::NoResult;
#ifdef AMD_EXTENSIONS
} else if (node->getOp() == glslang::EOpSparseImageLoad) {
#endif
builder.addCapability(spv::CapabilitySparseResidency);
- if (builder.getImageTypeFormat(builder.getImageType(operands.front())) == spv::ImageFormatUnknown)
+ if (builder.getImageTypeFormat(builder.getImageType(operands.front().word)) == spv::ImageFormatUnknown)
builder.addCapability(spv::CapabilityStorageImageReadWithoutFormat);
if (sampler.ms) {
- operands.push_back(spv::ImageOperandsSampleMask);
- operands.push_back(*opIt++);
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsSampleMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *opIt++ };
+ operands.push_back(imageOperand);
#ifdef AMD_EXTENSIONS
} else if (cracked.lod) {
builder.addExtension(spv::E_SPV_AMD_shader_image_load_store_lod);
builder.addCapability(spv::CapabilityImageReadWriteLodAMD);
- operands.push_back(spv::ImageOperandsLodMask);
- operands.push_back(*opIt++);
+ spv::IdImmediate imageOperands = { false, spv::ImageOperandsLodMask };
+ operands.push_back(imageOperands);
+ spv::IdImmediate imageOperand = { true, *opIt++ };
+ operands.push_back(imageOperand);
#endif
}
// GLSL "IMAGE_PARAMS" will involve in constructing an image texel pointer and this pointer,
// as the first source operand, is required by SPIR-V atomic operations.
- operands.push_back(sampler.ms ? *(opIt++) : builder.makeUintConstant(0)); // For non-MS, the value should be 0
+ // For non-MS, the sample value should be 0
+ spv::IdImmediate sample = { true, sampler.ms ? *(opIt++) : builder.makeUintConstant(0) };
+ operands.push_back(sample);
spv::Id resultTypeId = builder.makePointer(spv::StorageClassImage, resultType());
spv::Id pointer = builder.createOp(spv::OpImageTexelPointer, resultTypeId, operands);
#endif
spv::Op opCode = spv::OpNop;
- std::vector<spv::Id> spvGroupOperands;
+ std::vector<spv::IdImmediate> spvGroupOperands;
spv::GroupOperation groupOperation = spv::GroupOperationMax;
if (op == glslang::EOpBallot || op == glslang::EOpReadFirstInvocation ||
builder.addExtension(spv::E_SPV_AMD_shader_ballot);
#endif
- spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
#ifdef AMD_EXTENSIONS
switch (op) {
case glslang::EOpMinInvocations:
case glslang::EOpMaxInvocationsNonUniform:
case glslang::EOpAddInvocationsNonUniform:
groupOperation = spv::GroupOperationReduce;
- spvGroupOperands.push_back(groupOperation);
break;
case glslang::EOpMinInvocationsInclusiveScan:
case glslang::EOpMaxInvocationsInclusiveScan:
case glslang::EOpMaxInvocationsInclusiveScanNonUniform:
case glslang::EOpAddInvocationsInclusiveScanNonUniform:
groupOperation = spv::GroupOperationInclusiveScan;
- spvGroupOperands.push_back(groupOperation);
break;
case glslang::EOpMinInvocationsExclusiveScan:
case glslang::EOpMaxInvocationsExclusiveScan:
case glslang::EOpMaxInvocationsExclusiveScanNonUniform:
case glslang::EOpAddInvocationsExclusiveScanNonUniform:
groupOperation = spv::GroupOperationExclusiveScan;
- spvGroupOperands.push_back(groupOperation);
break;
default:
break;
}
+ spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+ spvGroupOperands.push_back(scope);
+ if (groupOperation != spv::GroupOperationMax) {
+ spv::IdImmediate groupOp = { false, groupOperation };
+ spvGroupOperands.push_back(groupOp);
+ }
#endif
}
- for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt)
- spvGroupOperands.push_back(*opIt);
+ for (auto opIt = operands.begin(); opIt != operands.end(); ++opIt) {
+ spv::IdImmediate op = { true, *opIt };
+ spvGroupOperands.push_back(op);
+ }
switch (op) {
case glslang::EOpAnyInvocation:
}
// Create group invocation operations on a vector
-spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation, spv::Id typeId, std::vector<spv::Id>& operands)
+spv::Id TGlslangToSpvTraverser::CreateInvocationsVectorOperation(spv::Op op, spv::GroupOperation groupOperation,
+ spv::Id typeId, std::vector<spv::Id>& operands)
{
#ifdef AMD_EXTENSIONS
assert(op == spv::OpGroupFMin || op == spv::OpGroupUMin || op == spv::OpGroupSMin ||
for (int comp = 0; comp < numComponents; ++comp) {
std::vector<unsigned int> indexes;
indexes.push_back(comp);
- spv::Id scalar = builder.createCompositeExtract(operands[0], scalarType, indexes);
- std::vector<spv::Id> spvGroupOperands;
+ spv::IdImmediate scalar = { true, builder.createCompositeExtract(operands[0], scalarType, indexes) };
+ std::vector<spv::IdImmediate> spvGroupOperands;
if (op == spv::OpSubgroupReadInvocationKHR) {
spvGroupOperands.push_back(scalar);
- spvGroupOperands.push_back(operands[1]);
+ spv::IdImmediate operand = { true, operands[1] };
+ spvGroupOperands.push_back(operand);
} else if (op == spv::OpGroupBroadcast) {
- spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
+ spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+ spvGroupOperands.push_back(scope);
spvGroupOperands.push_back(scalar);
- spvGroupOperands.push_back(operands[1]);
+ spv::IdImmediate operand = { true, operands[1] };
+ spvGroupOperands.push_back(operand);
} else {
- spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
- spvGroupOperands.push_back(groupOperation);
+ spv::IdImmediate scope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+ spvGroupOperands.push_back(scope);
+ spv::IdImmediate groupOp = { false, groupOperation };
+ spvGroupOperands.push_back(groupOp);
spvGroupOperands.push_back(scalar);
}
}
// Create subgroup invocation operations.
-spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId, std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
+spv::Id TGlslangToSpvTraverser::createSubgroupOperation(glslang::TOperator op, spv::Id typeId,
+ std::vector<spv::Id>& operands, glslang::TBasicType typeProxy)
{
// Add the required capabilities.
switch (op) {
default: assert(0 && "Unhandled subgroup operation!");
}
- std::vector<spv::Id> spvGroupOperands;
-
- // Every operation begins with the Execution Scope operand.
- spvGroupOperands.push_back(builder.makeUintConstant(spv::ScopeSubgroup));
-
- // Next, for all operations that use a Group Operation, push that as an operand.
+ // get the right Group Operation
+ spv::GroupOperation groupOperation = spv::GroupOperationMax;
switch (op) {
- default: break;
+ default:
+ break;
case glslang::EOpSubgroupBallotBitCount:
case glslang::EOpSubgroupAdd:
case glslang::EOpSubgroupMul:
case glslang::EOpSubgroupAnd:
case glslang::EOpSubgroupOr:
case glslang::EOpSubgroupXor:
- spvGroupOperands.push_back(spv::GroupOperationReduce);
+ groupOperation = spv::GroupOperationReduce;
break;
case glslang::EOpSubgroupBallotInclusiveBitCount:
case glslang::EOpSubgroupInclusiveAdd:
case glslang::EOpSubgroupInclusiveAnd:
case glslang::EOpSubgroupInclusiveOr:
case glslang::EOpSubgroupInclusiveXor:
- spvGroupOperands.push_back(spv::GroupOperationInclusiveScan);
+ groupOperation = spv::GroupOperationInclusiveScan;
break;
case glslang::EOpSubgroupBallotExclusiveBitCount:
case glslang::EOpSubgroupExclusiveAdd:
case glslang::EOpSubgroupExclusiveAnd:
case glslang::EOpSubgroupExclusiveOr:
case glslang::EOpSubgroupExclusiveXor:
- spvGroupOperands.push_back(spv::GroupOperationExclusiveScan);
+ groupOperation = spv::GroupOperationExclusiveScan;
break;
case glslang::EOpSubgroupClusteredAdd:
case glslang::EOpSubgroupClusteredMul:
case glslang::EOpSubgroupClusteredAnd:
case glslang::EOpSubgroupClusteredOr:
case glslang::EOpSubgroupClusteredXor:
- spvGroupOperands.push_back(spv::GroupOperationClusteredReduce);
+ groupOperation = spv::GroupOperationClusteredReduce;
break;
#ifdef NV_EXTENSIONS
case glslang::EOpSubgroupPartitionedAdd:
case glslang::EOpSubgroupPartitionedAnd:
case glslang::EOpSubgroupPartitionedOr:
case glslang::EOpSubgroupPartitionedXor:
- spvGroupOperands.push_back(spv::GroupOperationPartitionedReduceNV);
+ groupOperation = spv::GroupOperationPartitionedReduceNV;
break;
case glslang::EOpSubgroupPartitionedInclusiveAdd:
case glslang::EOpSubgroupPartitionedInclusiveMul:
case glslang::EOpSubgroupPartitionedInclusiveAnd:
case glslang::EOpSubgroupPartitionedInclusiveOr:
case glslang::EOpSubgroupPartitionedInclusiveXor:
- spvGroupOperands.push_back(spv::GroupOperationPartitionedInclusiveScanNV);
+ groupOperation = spv::GroupOperationPartitionedInclusiveScanNV;
break;
case glslang::EOpSubgroupPartitionedExclusiveAdd:
case glslang::EOpSubgroupPartitionedExclusiveMul:
case glslang::EOpSubgroupPartitionedExclusiveAnd:
case glslang::EOpSubgroupPartitionedExclusiveOr:
case glslang::EOpSubgroupPartitionedExclusiveXor:
- spvGroupOperands.push_back(spv::GroupOperationPartitionedExclusiveScanNV);
+ groupOperation = spv::GroupOperationPartitionedExclusiveScanNV;
break;
#endif
}
+ // build the instruction
+ std::vector<spv::IdImmediate> spvGroupOperands;
+
+ // Every operation begins with the Execution Scope operand.
+ spv::IdImmediate executionScope = { true, builder.makeUintConstant(spv::ScopeSubgroup) };
+ spvGroupOperands.push_back(executionScope);
+
+ // Next, for all operations that use a Group Operation, push that as an operand.
+ if (groupOperation != spv::GroupOperationMax) {
+ spv::IdImmediate groupOperand = { false, groupOperation };
+ spvGroupOperands.push_back(groupOperand);
+ }
+
// Push back the operands next.
- for (auto opIt : operands) {
- spvGroupOperands.push_back(opIt);
+ for (auto opIt = operands.cbegin(); opIt != operands.cend(); ++opIt) {
+ spv::IdImmediate operand = { true, *opIt };
+ spvGroupOperands.push_back(operand);
}
// Some opcodes have additional operands.
+ spv::Id directionId = spv::NoResult;
switch (op) {
default: break;
- case glslang::EOpSubgroupQuadSwapHorizontal: spvGroupOperands.push_back(builder.makeUintConstant(0)); break;
- case glslang::EOpSubgroupQuadSwapVertical: spvGroupOperands.push_back(builder.makeUintConstant(1)); break;
- case glslang::EOpSubgroupQuadSwapDiagonal: spvGroupOperands.push_back(builder.makeUintConstant(2)); break;
+ case glslang::EOpSubgroupQuadSwapHorizontal: directionId = builder.makeUintConstant(0); break;
+ case glslang::EOpSubgroupQuadSwapVertical: directionId = builder.makeUintConstant(1); break;
+ case glslang::EOpSubgroupQuadSwapDiagonal: directionId = builder.makeUintConstant(2); break;
+ }
+ if (directionId != spv::NoResult) {
+ spv::IdImmediate direction = { true, directionId };
+ spvGroupOperands.push_back(direction);
}
return builder.createOp(opCode, typeId, spvGroupOperands);