Put braces on new line after if/for/switch/case.
This commit is contained in:
parent
8a4e22ce27
commit
24c6bb308d
2 changed files with 231 additions and 116 deletions
|
|
@ -1,7 +1,7 @@
|
||||||
Language: Cpp
|
Language: Cpp
|
||||||
IndentWidth: 4
|
IndentWidth: 4
|
||||||
BreakBeforeBraces: Custom
|
BreakBeforeBraces: Custom
|
||||||
BraceWrapping: { AfterFunction: true }
|
BraceWrapping: { AfterFunction: true, AfterControlStatement: true }
|
||||||
IndentCaseLabels: false
|
IndentCaseLabels: false
|
||||||
ReflowComments: false
|
ReflowComments: false
|
||||||
ColumnLimit: 100
|
ColumnLimit: 100
|
||||||
|
|
|
||||||
|
|
@ -83,7 +83,8 @@ Id Builder::import(const char* name)
|
||||||
Id Builder::makeVoidType()
|
Id Builder::makeVoidType()
|
||||||
{
|
{
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
if (groupedTypes[OpTypeVoid].size() == 0) {
|
if (groupedTypes[OpTypeVoid].size() == 0)
|
||||||
|
{
|
||||||
type = new Instruction(getUniqueId(), NoType, OpTypeVoid);
|
type = new Instruction(getUniqueId(), NoType, OpTypeVoid);
|
||||||
groupedTypes[OpTypeVoid].push_back(type);
|
groupedTypes[OpTypeVoid].push_back(type);
|
||||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
|
@ -97,7 +98,8 @@ Id Builder::makeVoidType()
|
||||||
Id Builder::makeBoolType()
|
Id Builder::makeBoolType()
|
||||||
{
|
{
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
if (groupedTypes[OpTypeBool].size() == 0) {
|
if (groupedTypes[OpTypeBool].size() == 0)
|
||||||
|
{
|
||||||
type = new Instruction(getUniqueId(), NoType, OpTypeBool);
|
type = new Instruction(getUniqueId(), NoType, OpTypeBool);
|
||||||
groupedTypes[OpTypeBool].push_back(type);
|
groupedTypes[OpTypeBool].push_back(type);
|
||||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
|
@ -111,7 +113,8 @@ Id Builder::makeBoolType()
|
||||||
Id Builder::makeSamplerType()
|
Id Builder::makeSamplerType()
|
||||||
{
|
{
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
if (groupedTypes[OpTypeSampler].size() == 0) {
|
if (groupedTypes[OpTypeSampler].size() == 0)
|
||||||
|
{
|
||||||
type = new Instruction(getUniqueId(), NoType, OpTypeSampler);
|
type = new Instruction(getUniqueId(), NoType, OpTypeSampler);
|
||||||
groupedTypes[OpTypeSampler].push_back(type);
|
groupedTypes[OpTypeSampler].push_back(type);
|
||||||
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
constantsTypesGlobals.push_back(std::unique_ptr<Instruction>(type));
|
||||||
|
|
@ -126,7 +129,8 @@ Id Builder::makePointer(StorageClass storageClass, Id pointee)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypePointer].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypePointer][t];
|
type = groupedTypes[OpTypePointer][t];
|
||||||
if (type->getImmediateOperand(0) == (unsigned)storageClass &&
|
if (type->getImmediateOperand(0) == (unsigned)storageClass &&
|
||||||
type->getIdOperand(1) == pointee)
|
type->getIdOperand(1) == pointee)
|
||||||
|
|
@ -148,7 +152,8 @@ Id Builder::makeIntegerType(int width, bool hasSign)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeInt].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeInt][t];
|
type = groupedTypes[OpTypeInt][t];
|
||||||
if (type->getImmediateOperand(0) == (unsigned)width &&
|
if (type->getImmediateOperand(0) == (unsigned)width &&
|
||||||
type->getImmediateOperand(1) == (hasSign ? 1u : 0u))
|
type->getImmediateOperand(1) == (hasSign ? 1u : 0u))
|
||||||
|
|
@ -164,7 +169,8 @@ Id Builder::makeIntegerType(int width, bool hasSign)
|
||||||
module.mapInstruction(type);
|
module.mapInstruction(type);
|
||||||
|
|
||||||
// deal with capabilities
|
// deal with capabilities
|
||||||
switch (width) {
|
switch (width)
|
||||||
|
{
|
||||||
case 16:
|
case 16:
|
||||||
addCapability(CapabilityInt16);
|
addCapability(CapabilityInt16);
|
||||||
break;
|
break;
|
||||||
|
|
@ -182,7 +188,8 @@ Id Builder::makeFloatType(int width)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeFloat].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeFloat][t];
|
type = groupedTypes[OpTypeFloat][t];
|
||||||
if (type->getImmediateOperand(0) == (unsigned)width)
|
if (type->getImmediateOperand(0) == (unsigned)width)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
|
|
@ -196,7 +203,8 @@ Id Builder::makeFloatType(int width)
|
||||||
module.mapInstruction(type);
|
module.mapInstruction(type);
|
||||||
|
|
||||||
// deal with capabilities
|
// deal with capabilities
|
||||||
switch (width) {
|
switch (width)
|
||||||
|
{
|
||||||
case 16:
|
case 16:
|
||||||
addCapability(CapabilityFloat16);
|
addCapability(CapabilityFloat16);
|
||||||
break;
|
break;
|
||||||
|
|
@ -237,7 +245,8 @@ Id Builder::makeStructResultType(Id type0, Id type1)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeStruct].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeStruct][t];
|
type = groupedTypes[OpTypeStruct][t];
|
||||||
if (type->getNumOperands() != 2)
|
if (type->getNumOperands() != 2)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -258,7 +267,8 @@ Id Builder::makeVectorType(Id component, int size)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeVector].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeVector].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeVector][t];
|
type = groupedTypes[OpTypeVector][t];
|
||||||
if (type->getIdOperand(0) == component && type->getImmediateOperand(1) == (unsigned)size)
|
if (type->getIdOperand(0) == component && type->getImmediateOperand(1) == (unsigned)size)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
|
|
@ -283,7 +293,8 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
|
||||||
|
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeMatrix].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeMatrix].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeMatrix][t];
|
type = groupedTypes[OpTypeMatrix][t];
|
||||||
if (type->getIdOperand(0) == column && type->getImmediateOperand(1) == (unsigned)cols)
|
if (type->getIdOperand(0) == column && type->getImmediateOperand(1) == (unsigned)cols)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
|
|
@ -307,9 +318,11 @@ Id Builder::makeMatrixType(Id component, int cols, int rows)
|
||||||
Id Builder::makeArrayType(Id element, Id sizeId, int stride)
|
Id Builder::makeArrayType(Id element, Id sizeId, int stride)
|
||||||
{
|
{
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
if (stride == 0) {
|
if (stride == 0)
|
||||||
|
{
|
||||||
// try to find existing type
|
// try to find existing type
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeArray].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeArray].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeArray][t];
|
type = groupedTypes[OpTypeArray][t];
|
||||||
if (type->getIdOperand(0) == element && type->getIdOperand(1) == sizeId)
|
if (type->getIdOperand(0) == element && type->getIdOperand(1) == sizeId)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
|
|
@ -341,14 +354,17 @@ Id Builder::makeFunctionType(Id returnType, const std::vector<Id>& paramTypes)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeFunction].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeFunction].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeFunction][t];
|
type = groupedTypes[OpTypeFunction][t];
|
||||||
if (type->getIdOperand(0) != returnType ||
|
if (type->getIdOperand(0) != returnType ||
|
||||||
(int)paramTypes.size() != type->getNumOperands() - 1)
|
(int)paramTypes.size() != type->getNumOperands() - 1)
|
||||||
continue;
|
continue;
|
||||||
bool mismatch = false;
|
bool mismatch = false;
|
||||||
for (int p = 0; p < (int)paramTypes.size(); ++p) {
|
for (int p = 0; p < (int)paramTypes.size(); ++p)
|
||||||
if (paramTypes[p] != type->getIdOperand(p + 1)) {
|
{
|
||||||
|
if (paramTypes[p] != type->getIdOperand(p + 1))
|
||||||
|
{
|
||||||
mismatch = true;
|
mismatch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -374,7 +390,8 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeImage].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeImage].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeImage][t];
|
type = groupedTypes[OpTypeImage][t];
|
||||||
if (type->getIdOperand(0) == sampledType &&
|
if (type->getIdOperand(0) == sampledType &&
|
||||||
type->getImmediateOperand(1) == (unsigned int)dim &&
|
type->getImmediateOperand(1) == (unsigned int)dim &&
|
||||||
|
|
@ -401,7 +418,8 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
|
||||||
module.mapInstruction(type);
|
module.mapInstruction(type);
|
||||||
|
|
||||||
// deal with capabilities
|
// deal with capabilities
|
||||||
switch (dim) {
|
switch (dim)
|
||||||
|
{
|
||||||
case DimBuffer:
|
case DimBuffer:
|
||||||
if (sampled)
|
if (sampled)
|
||||||
addCapability(CapabilitySampledBuffer);
|
addCapability(CapabilitySampledBuffer);
|
||||||
|
|
@ -415,7 +433,8 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
|
||||||
addCapability(CapabilityImage1D);
|
addCapability(CapabilityImage1D);
|
||||||
break;
|
break;
|
||||||
case DimCube:
|
case DimCube:
|
||||||
if (arrayed) {
|
if (arrayed)
|
||||||
|
{
|
||||||
if (sampled)
|
if (sampled)
|
||||||
addCapability(CapabilitySampledCubeArray);
|
addCapability(CapabilitySampledCubeArray);
|
||||||
else
|
else
|
||||||
|
|
@ -435,7 +454,8 @@ Id Builder::makeImageType(Id sampledType, Dim dim, bool depth, bool arrayed, boo
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ms) {
|
if (ms)
|
||||||
|
{
|
||||||
if (arrayed)
|
if (arrayed)
|
||||||
addCapability(CapabilityImageMSArray);
|
addCapability(CapabilityImageMSArray);
|
||||||
if (!sampled)
|
if (!sampled)
|
||||||
|
|
@ -449,7 +469,8 @@ Id Builder::makeSampledImageType(Id imageType)
|
||||||
{
|
{
|
||||||
// try to find it
|
// try to find it
|
||||||
Instruction* type;
|
Instruction* type;
|
||||||
for (int t = 0; t < (int)groupedTypes[OpTypeSampledImage].size(); ++t) {
|
for (int t = 0; t < (int)groupedTypes[OpTypeSampledImage].size(); ++t)
|
||||||
|
{
|
||||||
type = groupedTypes[OpTypeSampledImage][t];
|
type = groupedTypes[OpTypeSampledImage][t];
|
||||||
if (type->getIdOperand(0) == imageType)
|
if (type->getIdOperand(0) == imageType)
|
||||||
return type->getResultId();
|
return type->getResultId();
|
||||||
|
|
@ -479,7 +500,8 @@ Op Builder::getMostBasicTypeClass(Id typeId) const
|
||||||
Instruction* instr = module.getInstruction(typeId);
|
Instruction* instr = module.getInstruction(typeId);
|
||||||
|
|
||||||
Op typeClass = instr->getOpCode();
|
Op typeClass = instr->getOpCode();
|
||||||
switch (typeClass) {
|
switch (typeClass)
|
||||||
|
{
|
||||||
case OpTypeVoid:
|
case OpTypeVoid:
|
||||||
case OpTypeBool:
|
case OpTypeBool:
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
|
|
@ -503,7 +525,8 @@ int Builder::getNumTypeConstituents(Id typeId) const
|
||||||
{
|
{
|
||||||
Instruction* instr = module.getInstruction(typeId);
|
Instruction* instr = module.getInstruction(typeId);
|
||||||
|
|
||||||
switch (instr->getOpCode()) {
|
switch (instr->getOpCode())
|
||||||
|
{
|
||||||
case OpTypeBool:
|
case OpTypeBool:
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
|
|
@ -511,7 +534,8 @@ int Builder::getNumTypeConstituents(Id typeId) const
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
return instr->getImmediateOperand(1);
|
return instr->getImmediateOperand(1);
|
||||||
case OpTypeArray: {
|
case OpTypeArray:
|
||||||
|
{
|
||||||
Id lengthId = instr->getImmediateOperand(1);
|
Id lengthId = instr->getImmediateOperand(1);
|
||||||
return module.getInstruction(lengthId)->getImmediateOperand(0);
|
return module.getInstruction(lengthId)->getImmediateOperand(0);
|
||||||
}
|
}
|
||||||
|
|
@ -531,7 +555,8 @@ Id Builder::getScalarTypeId(Id typeId) const
|
||||||
Instruction* instr = module.getInstruction(typeId);
|
Instruction* instr = module.getInstruction(typeId);
|
||||||
|
|
||||||
Op typeClass = instr->getOpCode();
|
Op typeClass = instr->getOpCode();
|
||||||
switch (typeClass) {
|
switch (typeClass)
|
||||||
|
{
|
||||||
case OpTypeVoid:
|
case OpTypeVoid:
|
||||||
case OpTypeBool:
|
case OpTypeBool:
|
||||||
case OpTypeInt:
|
case OpTypeInt:
|
||||||
|
|
@ -556,7 +581,8 @@ Id Builder::getContainedTypeId(Id typeId, int member) const
|
||||||
Instruction* instr = module.getInstruction(typeId);
|
Instruction* instr = module.getInstruction(typeId);
|
||||||
|
|
||||||
Op typeClass = instr->getOpCode();
|
Op typeClass = instr->getOpCode();
|
||||||
switch (typeClass) {
|
switch (typeClass)
|
||||||
|
{
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeMatrix:
|
case OpTypeMatrix:
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
|
|
@ -579,7 +605,8 @@ Id Builder::getContainedTypeId(Id typeId) const { return getContainedTypeId(type
|
||||||
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const
|
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned value) const
|
||||||
{
|
{
|
||||||
Instruction* constant;
|
Instruction* constant;
|
||||||
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
|
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i)
|
||||||
|
{
|
||||||
constant = groupedConstants[typeClass][i];
|
constant = groupedConstants[typeClass][i];
|
||||||
if (constant->getOpCode() == opcode && constant->getTypeId() == typeId &&
|
if (constant->getOpCode() == opcode && constant->getTypeId() == typeId &&
|
||||||
constant->getImmediateOperand(0) == value)
|
constant->getImmediateOperand(0) == value)
|
||||||
|
|
@ -593,7 +620,8 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned valu
|
||||||
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
|
Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1, unsigned v2) const
|
||||||
{
|
{
|
||||||
Instruction* constant;
|
Instruction* constant;
|
||||||
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
|
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i)
|
||||||
|
{
|
||||||
constant = groupedConstants[typeClass][i];
|
constant = groupedConstants[typeClass][i];
|
||||||
if (constant->getOpCode() == opcode && constant->getTypeId() == typeId &&
|
if (constant->getOpCode() == opcode && constant->getTypeId() == typeId &&
|
||||||
constant->getImmediateOperand(0) == v1 && constant->getImmediateOperand(1) == v2)
|
constant->getImmediateOperand(0) == v1 && constant->getImmediateOperand(1) == v2)
|
||||||
|
|
@ -608,7 +636,8 @@ Id Builder::findScalarConstant(Op typeClass, Op opcode, Id typeId, unsigned v1,
|
||||||
// the value consumed will be a constant, so includes specialization.
|
// the value consumed will be a constant, so includes specialization.
|
||||||
bool Builder::isConstantOpCode(Op opcode) const
|
bool Builder::isConstantOpCode(Op opcode) const
|
||||||
{
|
{
|
||||||
switch (opcode) {
|
switch (opcode)
|
||||||
|
{
|
||||||
case OpUndef:
|
case OpUndef:
|
||||||
case OpConstantTrue:
|
case OpConstantTrue:
|
||||||
case OpConstantFalse:
|
case OpConstantFalse:
|
||||||
|
|
@ -636,9 +665,11 @@ Id Builder::makeBoolConstant(bool b, bool specConstant)
|
||||||
|
|
||||||
// See if we already made it. Applies only to regular constants, because specialization constants
|
// See if we already made it. Applies only to regular constants, because specialization constants
|
||||||
// must remain distinct for the purpose of applying a SpecId decoration.
|
// must remain distinct for the purpose of applying a SpecId decoration.
|
||||||
if (!specConstant) {
|
if (!specConstant)
|
||||||
|
{
|
||||||
Id existing = 0;
|
Id existing = 0;
|
||||||
for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i) {
|
for (int i = 0; i < (int)groupedConstants[OpTypeBool].size(); ++i)
|
||||||
|
{
|
||||||
constant = groupedConstants[OpTypeBool][i];
|
constant = groupedConstants[OpTypeBool][i];
|
||||||
if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)
|
if (constant->getTypeId() == typeId && constant->getOpCode() == opcode)
|
||||||
existing = constant->getResultId();
|
existing = constant->getResultId();
|
||||||
|
|
@ -663,7 +694,8 @@ Id Builder::makeIntConstant(Id typeId, unsigned value, bool specConstant)
|
||||||
|
|
||||||
// See if we already made it. Applies only to regular constants, because specialization constants
|
// See if we already made it. Applies only to regular constants, because specialization constants
|
||||||
// must remain distinct for the purpose of applying a SpecId decoration.
|
// must remain distinct for the purpose of applying a SpecId decoration.
|
||||||
if (!specConstant) {
|
if (!specConstant)
|
||||||
|
{
|
||||||
Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value);
|
Id existing = findScalarConstant(OpTypeInt, opcode, typeId, value);
|
||||||
if (existing)
|
if (existing)
|
||||||
return existing;
|
return existing;
|
||||||
|
|
@ -691,7 +723,8 @@ Id Builder::makeFloatConstant(float f, bool specConstant)
|
||||||
|
|
||||||
// See if we already made it. Applies only to regular constants, because specialization constants
|
// See if we already made it. Applies only to regular constants, because specialization constants
|
||||||
// must remain distinct for the purpose of applying a SpecId decoration.
|
// must remain distinct for the purpose of applying a SpecId decoration.
|
||||||
if (!specConstant) {
|
if (!specConstant)
|
||||||
|
{
|
||||||
Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);
|
Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, value);
|
||||||
if (existing)
|
if (existing)
|
||||||
return existing;
|
return existing;
|
||||||
|
|
@ -721,7 +754,8 @@ Id Builder::makeDoubleConstant(double d, bool specConstant)
|
||||||
|
|
||||||
// See if we already made it. Applies only to regular constants, because specialization constants
|
// See if we already made it. Applies only to regular constants, because specialization constants
|
||||||
// must remain distinct for the purpose of applying a SpecId decoration.
|
// must remain distinct for the purpose of applying a SpecId decoration.
|
||||||
if (!specConstant) {
|
if (!specConstant)
|
||||||
|
{
|
||||||
Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2);
|
Id existing = findScalarConstant(OpTypeFloat, opcode, typeId, op1, op2);
|
||||||
if (existing)
|
if (existing)
|
||||||
return existing;
|
return existing;
|
||||||
|
|
@ -741,7 +775,8 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
|
||||||
{
|
{
|
||||||
Instruction* constant = 0;
|
Instruction* constant = 0;
|
||||||
bool found = false;
|
bool found = false;
|
||||||
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i) {
|
for (int i = 0; i < (int)groupedConstants[typeClass].size(); ++i)
|
||||||
|
{
|
||||||
constant = groupedConstants[typeClass][i];
|
constant = groupedConstants[typeClass][i];
|
||||||
|
|
||||||
// same shape?
|
// same shape?
|
||||||
|
|
@ -750,13 +785,16 @@ Id Builder::findCompositeConstant(Op typeClass, std::vector<Id>& comps) const
|
||||||
|
|
||||||
// same contents?
|
// same contents?
|
||||||
bool mismatch = false;
|
bool mismatch = false;
|
||||||
for (int op = 0; op < constant->getNumOperands(); ++op) {
|
for (int op = 0; op < constant->getNumOperands(); ++op)
|
||||||
if (constant->getIdOperand(op) != comps[op]) {
|
{
|
||||||
|
if (constant->getIdOperand(op) != comps[op])
|
||||||
|
{
|
||||||
mismatch = true;
|
mismatch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!mismatch) {
|
if (!mismatch)
|
||||||
|
{
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -772,7 +810,8 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
|
||||||
assert(typeId);
|
assert(typeId);
|
||||||
Op typeClass = getTypeClass(typeId);
|
Op typeClass = getTypeClass(typeId);
|
||||||
|
|
||||||
switch (typeClass) {
|
switch (typeClass)
|
||||||
|
{
|
||||||
case OpTypeVector:
|
case OpTypeVector:
|
||||||
case OpTypeArray:
|
case OpTypeArray:
|
||||||
case OpTypeStruct:
|
case OpTypeStruct:
|
||||||
|
|
@ -783,7 +822,8 @@ Id Builder::makeCompositeConstant(Id typeId, std::vector<Id>& members, bool spec
|
||||||
return makeFloatConstant(0.0);
|
return makeFloatConstant(0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!specConstant) {
|
if (!specConstant)
|
||||||
|
{
|
||||||
Id existing = findCompositeConstant(typeClass, members);
|
Id existing = findCompositeConstant(typeClass, members);
|
||||||
if (existing)
|
if (existing)
|
||||||
return existing;
|
return existing;
|
||||||
|
|
@ -914,7 +954,8 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
||||||
setPrecision(firstParamId + p, precisions[p]);
|
setPrecision(firstParamId + p, precisions[p]);
|
||||||
|
|
||||||
// CFG
|
// CFG
|
||||||
if (entry) {
|
if (entry)
|
||||||
|
{
|
||||||
*entry = new Block(getUniqueId(), *function);
|
*entry = new Block(getUniqueId(), *function);
|
||||||
function->addBlock(*entry);
|
function->addBlock(*entry);
|
||||||
setBuildPoint(*entry);
|
setBuildPoint(*entry);
|
||||||
|
|
@ -931,7 +972,8 @@ Function* Builder::makeFunctionEntry(Decoration precision, Id returnType, const
|
||||||
// Comments in header
|
// Comments in header
|
||||||
void Builder::makeReturn(bool implicit, Id retVal)
|
void Builder::makeReturn(bool implicit, Id retVal)
|
||||||
{
|
{
|
||||||
if (retVal) {
|
if (retVal)
|
||||||
|
{
|
||||||
Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
|
Instruction* inst = new Instruction(NoResult, NoType, OpReturnValue);
|
||||||
inst->addIdOperand(retVal);
|
inst->addIdOperand(retVal);
|
||||||
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
|
buildPoint->addInstruction(std::unique_ptr<Instruction>(inst));
|
||||||
|
|
@ -951,10 +993,12 @@ void Builder::leaveFunction()
|
||||||
assert(block);
|
assert(block);
|
||||||
|
|
||||||
// If our function did not contain a return, add a return void now.
|
// If our function did not contain a return, add a return void now.
|
||||||
if (!block->isTerminated()) {
|
if (!block->isTerminated())
|
||||||
|
{
|
||||||
if (function.getReturnType() == makeVoidType())
|
if (function.getReturnType() == makeVoidType())
|
||||||
makeReturn(true);
|
makeReturn(true);
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
makeReturn(true, createUndefined(function.getReturnType()));
|
makeReturn(true, createUndefined(function.getReturnType()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -974,7 +1018,8 @@ Id Builder::createVariable(StorageClass storageClass, Id type, const char* name)
|
||||||
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
Instruction* inst = new Instruction(getUniqueId(), pointerType, OpVariable);
|
||||||
inst->addImmediateOperand(storageClass);
|
inst->addImmediateOperand(storageClass);
|
||||||
|
|
||||||
switch (storageClass) {
|
switch (storageClass)
|
||||||
|
{
|
||||||
case StorageClassFunction:
|
case StorageClassFunction:
|
||||||
// Validation rules require the declaration in the entry block
|
// Validation rules require the declaration in the entry block
|
||||||
buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst));
|
buildPoint->getParent().addLocalVariable(std::unique_ptr<Instruction>(inst));
|
||||||
|
|
@ -1026,8 +1071,10 @@ Id Builder::createAccessChain(StorageClass storageClass, Id base, std::vector<Id
|
||||||
spv::Id typeId = getTypeId(base);
|
spv::Id typeId = getTypeId(base);
|
||||||
assert(isPointerType(typeId) && offsets.size() > 0);
|
assert(isPointerType(typeId) && offsets.size() > 0);
|
||||||
typeId = getContainedTypeId(typeId);
|
typeId = getContainedTypeId(typeId);
|
||||||
for (int i = 0; i < (int)offsets.size(); ++i) {
|
for (int i = 0; i < (int)offsets.size(); ++i)
|
||||||
if (isStructType(typeId)) {
|
{
|
||||||
|
if (isStructType(typeId))
|
||||||
|
{
|
||||||
assert(isConstantScalar(offsets[i]));
|
assert(isConstantScalar(offsets[i]));
|
||||||
typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
|
typeId = getContainedTypeId(typeId, getConstantScalar(offsets[i]));
|
||||||
} else
|
} else
|
||||||
|
|
@ -1338,42 +1385,50 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
numArgs; // track which operand, if it exists, is the mask of optional arguments
|
numArgs; // track which operand, if it exists, is the mask of optional arguments
|
||||||
++numArgs; // speculatively make room for the mask operand
|
++numArgs; // speculatively make room for the mask operand
|
||||||
ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
|
ImageOperandsMask mask = ImageOperandsMaskNone; // the mask operand
|
||||||
if (parameters.bias) {
|
if (parameters.bias)
|
||||||
|
{
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsBiasMask);
|
||||||
texArgs[numArgs++] = parameters.bias;
|
texArgs[numArgs++] = parameters.bias;
|
||||||
}
|
}
|
||||||
if (parameters.lod) {
|
if (parameters.lod)
|
||||||
|
{
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
|
||||||
texArgs[numArgs++] = parameters.lod;
|
texArgs[numArgs++] = parameters.lod;
|
||||||
explicitLod = true;
|
explicitLod = true;
|
||||||
} else if (parameters.gradX) {
|
} else if (parameters.gradX)
|
||||||
|
{
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsGradMask);
|
||||||
texArgs[numArgs++] = parameters.gradX;
|
texArgs[numArgs++] = parameters.gradX;
|
||||||
texArgs[numArgs++] = parameters.gradY;
|
texArgs[numArgs++] = parameters.gradY;
|
||||||
explicitLod = true;
|
explicitLod = true;
|
||||||
} else if (noImplicitLod && !fetch && !gather) {
|
} else if (noImplicitLod && !fetch && !gather)
|
||||||
|
{
|
||||||
// have to explicitly use lod of 0 if not allowed to have them be implicit, and
|
// have to explicitly use lod of 0 if not allowed to have them be implicit, and
|
||||||
// we would otherwise be about to issue an implicit instruction
|
// we would otherwise be about to issue an implicit instruction
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsLodMask);
|
||||||
texArgs[numArgs++] = makeFloatConstant(0.0);
|
texArgs[numArgs++] = makeFloatConstant(0.0);
|
||||||
explicitLod = true;
|
explicitLod = true;
|
||||||
}
|
}
|
||||||
if (parameters.offset) {
|
if (parameters.offset)
|
||||||
|
{
|
||||||
if (isConstant(parameters.offset))
|
if (isConstant(parameters.offset))
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetMask);
|
||||||
else
|
else
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsOffsetMask);
|
||||||
texArgs[numArgs++] = parameters.offset;
|
texArgs[numArgs++] = parameters.offset;
|
||||||
}
|
}
|
||||||
if (parameters.offsets) {
|
if (parameters.offsets)
|
||||||
|
{
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsConstOffsetsMask);
|
||||||
texArgs[numArgs++] = parameters.offsets;
|
texArgs[numArgs++] = parameters.offsets;
|
||||||
}
|
}
|
||||||
if (parameters.sample) {
|
if (parameters.sample)
|
||||||
|
{
|
||||||
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
|
mask = (ImageOperandsMask)(mask | ImageOperandsSampleMask);
|
||||||
texArgs[numArgs++] = parameters.sample;
|
texArgs[numArgs++] = parameters.sample;
|
||||||
}
|
}
|
||||||
if (parameters.lodClamp) {
|
if (parameters.lodClamp)
|
||||||
|
{
|
||||||
// capability if this bit is used
|
// capability if this bit is used
|
||||||
addCapability(CapabilityMinLod);
|
addCapability(CapabilityMinLod);
|
||||||
|
|
||||||
|
|
@ -1389,12 +1444,14 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
// Set up the instruction
|
// Set up the instruction
|
||||||
//
|
//
|
||||||
Op opCode = OpNop; // All paths below need to set this
|
Op opCode = OpNop; // All paths below need to set this
|
||||||
if (fetch) {
|
if (fetch)
|
||||||
|
{
|
||||||
if (sparse)
|
if (sparse)
|
||||||
opCode = OpImageSparseFetch;
|
opCode = OpImageSparseFetch;
|
||||||
else
|
else
|
||||||
opCode = OpImageFetch;
|
opCode = OpImageFetch;
|
||||||
} else if (gather) {
|
} else if (gather)
|
||||||
|
{
|
||||||
if (parameters.Dref)
|
if (parameters.Dref)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
opCode = OpImageSparseDrefGather;
|
opCode = OpImageSparseDrefGather;
|
||||||
|
|
@ -1404,8 +1461,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
opCode = OpImageSparseGather;
|
opCode = OpImageSparseGather;
|
||||||
else
|
else
|
||||||
opCode = OpImageGather;
|
opCode = OpImageGather;
|
||||||
} else if (explicitLod) {
|
} else if (explicitLod)
|
||||||
if (parameters.Dref) {
|
{
|
||||||
|
if (parameters.Dref)
|
||||||
|
{
|
||||||
if (proj)
|
if (proj)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
opCode = OpImageSparseSampleProjDrefExplicitLod;
|
opCode = OpImageSparseSampleProjDrefExplicitLod;
|
||||||
|
|
@ -1415,7 +1474,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
opCode = OpImageSparseSampleDrefExplicitLod;
|
opCode = OpImageSparseSampleDrefExplicitLod;
|
||||||
else
|
else
|
||||||
opCode = OpImageSampleDrefExplicitLod;
|
opCode = OpImageSampleDrefExplicitLod;
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
if (proj)
|
if (proj)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
opCode = OpImageSparseSampleProjExplicitLod;
|
opCode = OpImageSparseSampleProjExplicitLod;
|
||||||
|
|
@ -1426,8 +1486,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
else
|
else
|
||||||
opCode = OpImageSampleExplicitLod;
|
opCode = OpImageSampleExplicitLod;
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
if (parameters.Dref) {
|
{
|
||||||
|
if (parameters.Dref)
|
||||||
|
{
|
||||||
if (proj)
|
if (proj)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
opCode = OpImageSparseSampleProjDrefImplicitLod;
|
opCode = OpImageSparseSampleProjDrefImplicitLod;
|
||||||
|
|
@ -1437,7 +1499,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
opCode = OpImageSparseSampleDrefImplicitLod;
|
opCode = OpImageSparseSampleDrefImplicitLod;
|
||||||
else
|
else
|
||||||
opCode = OpImageSampleDrefImplicitLod;
|
opCode = OpImageSampleDrefImplicitLod;
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
if (proj)
|
if (proj)
|
||||||
if (sparse)
|
if (sparse)
|
||||||
opCode = OpImageSparseSampleProjImplicitLod;
|
opCode = OpImageSparseSampleProjImplicitLod;
|
||||||
|
|
@ -1454,8 +1517,10 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
// This happens when a legacy shadow*() call is made, which
|
// This happens when a legacy shadow*() call is made, which
|
||||||
// gets a vec4 back instead of a float.
|
// gets a vec4 back instead of a float.
|
||||||
Id smearedType = resultType;
|
Id smearedType = resultType;
|
||||||
if (!isScalarType(resultType)) {
|
if (!isScalarType(resultType))
|
||||||
switch (opCode) {
|
{
|
||||||
|
switch (opCode)
|
||||||
|
{
|
||||||
case OpImageSampleDrefImplicitLod:
|
case OpImageSampleDrefImplicitLod:
|
||||||
case OpImageSampleDrefExplicitLod:
|
case OpImageSampleDrefExplicitLod:
|
||||||
case OpImageSampleProjDrefImplicitLod:
|
case OpImageSampleProjDrefImplicitLod:
|
||||||
|
|
@ -1470,7 +1535,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
Id typeId0 = 0;
|
Id typeId0 = 0;
|
||||||
Id typeId1 = 0;
|
Id typeId1 = 0;
|
||||||
|
|
||||||
if (sparse) {
|
if (sparse)
|
||||||
|
{
|
||||||
typeId0 = resultType;
|
typeId0 = resultType;
|
||||||
typeId1 = getDerefTypeId(parameters.texelOut);
|
typeId1 = getDerefTypeId(parameters.texelOut);
|
||||||
resultType = makeStructResultType(typeId0, typeId1);
|
resultType = makeStructResultType(typeId0, typeId1);
|
||||||
|
|
@ -1489,7 +1555,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
|
|
||||||
Id resultId = textureInst->getResultId();
|
Id resultId = textureInst->getResultId();
|
||||||
|
|
||||||
if (sparse) {
|
if (sparse)
|
||||||
|
{
|
||||||
// set capability
|
// set capability
|
||||||
addCapability(CapabilitySparseResidency);
|
addCapability(CapabilitySparseResidency);
|
||||||
|
|
||||||
|
|
@ -1497,7 +1564,8 @@ Id Builder::createTextureCall(Decoration precision, Id resultType, bool sparse,
|
||||||
createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
|
createStore(createCompositeExtract(resultId, typeId1, 1), parameters.texelOut);
|
||||||
resultId = createCompositeExtract(resultId, typeId0, 0);
|
resultId = createCompositeExtract(resultId, typeId0, 0);
|
||||||
setPrecision(resultId, precision);
|
setPrecision(resultId, precision);
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
// When a smear is needed, do it, as per what was computed
|
// When a smear is needed, do it, as per what was computed
|
||||||
// above when resultType was changed to a scalar type.
|
// above when resultType was changed to a scalar type.
|
||||||
if (resultType != smearedType)
|
if (resultType != smearedType)
|
||||||
|
|
@ -1515,11 +1583,14 @@ Id Builder::createTextureQueryCall(Op opCode, const TextureParameters& parameter
|
||||||
|
|
||||||
// Figure out the result type
|
// Figure out the result type
|
||||||
Id resultType = 0;
|
Id resultType = 0;
|
||||||
switch (opCode) {
|
switch (opCode)
|
||||||
|
{
|
||||||
case OpImageQuerySize:
|
case OpImageQuerySize:
|
||||||
case OpImageQuerySizeLod: {
|
case OpImageQuerySizeLod:
|
||||||
|
{
|
||||||
int numComponents = 0;
|
int numComponents = 0;
|
||||||
switch (getTypeDimensionality(getImageType(parameters.sampler))) {
|
switch (getTypeDimensionality(getImageType(parameters.sampler)))
|
||||||
|
{
|
||||||
case Dim1D:
|
case Dim1D:
|
||||||
case DimBuffer:
|
case DimBuffer:
|
||||||
numComponents = 1;
|
numComponents = 1;
|
||||||
|
|
@ -1583,12 +1654,14 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
||||||
|
|
||||||
// Scalars and Vectors
|
// Scalars and Vectors
|
||||||
|
|
||||||
if (isScalarType(valueType) || isVectorType(valueType)) {
|
if (isScalarType(valueType) || isVectorType(valueType))
|
||||||
|
{
|
||||||
assert(valueType == getTypeId(value2));
|
assert(valueType == getTypeId(value2));
|
||||||
// These just need a single comparison, just have
|
// These just need a single comparison, just have
|
||||||
// to figure out what it is.
|
// to figure out what it is.
|
||||||
Op op;
|
Op op;
|
||||||
switch (getMostBasicTypeClass(valueType)) {
|
switch (getMostBasicTypeClass(valueType))
|
||||||
|
{
|
||||||
case OpTypeFloat:
|
case OpTypeFloat:
|
||||||
op = equal ? OpFOrdEqual : OpFOrdNotEqual;
|
op = equal ? OpFOrdEqual : OpFOrdNotEqual;
|
||||||
break;
|
break;
|
||||||
|
|
@ -1602,10 +1675,12 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isScalarType(valueType)) {
|
if (isScalarType(valueType))
|
||||||
|
{
|
||||||
// scalar
|
// scalar
|
||||||
resultId = createBinOp(op, boolType, value1, value2);
|
resultId = createBinOp(op, boolType, value1, value2);
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
// vector
|
// vector
|
||||||
resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2);
|
resultId = createBinOp(op, makeVectorType(boolType, numConstituents), value1, value2);
|
||||||
setPrecision(resultId, precision);
|
setPrecision(resultId, precision);
|
||||||
|
|
@ -1621,7 +1696,8 @@ Id Builder::createCompositeCompare(Decoration precision, Id value1, Id value2, b
|
||||||
assert(isAggregateType(valueType) || isMatrixType(valueType));
|
assert(isAggregateType(valueType) || isMatrixType(valueType));
|
||||||
|
|
||||||
// Compare each pair of constituents
|
// Compare each pair of constituents
|
||||||
for (int constituent = 0; constituent < numConstituents; ++constituent) {
|
for (int constituent = 0; constituent < numConstituents; ++constituent)
|
||||||
|
{
|
||||||
std::vector<unsigned> indexes(1, constituent);
|
std::vector<unsigned> indexes(1, constituent);
|
||||||
Id constituentType1 = getContainedTypeId(getTypeId(value1), constituent);
|
Id constituentType1 = getContainedTypeId(getTypeId(value1), constituent);
|
||||||
Id constituentType2 = getContainedTypeId(getTypeId(value2), constituent);
|
Id constituentType2 = getContainedTypeId(getTypeId(value2), constituent);
|
||||||
|
|
@ -1669,16 +1745,19 @@ Id Builder::createConstructor(Decoration precision, const std::vector<Id>& sourc
|
||||||
|
|
||||||
Id scalarTypeId = getScalarTypeId(resultTypeId);
|
Id scalarTypeId = getScalarTypeId(resultTypeId);
|
||||||
std::vector<Id> constituents; // accumulate the arguments for OpCompositeConstruct
|
std::vector<Id> constituents; // accumulate the arguments for OpCompositeConstruct
|
||||||
for (unsigned int i = 0; i < sources.size(); ++i) {
|
for (unsigned int i = 0; i < sources.size(); ++i)
|
||||||
|
{
|
||||||
assert(!isAggregate(sources[i]));
|
assert(!isAggregate(sources[i]));
|
||||||
unsigned int sourceSize = getNumComponents(sources[i]);
|
unsigned int sourceSize = getNumComponents(sources[i]);
|
||||||
unsigned int sourcesToUse = sourceSize;
|
unsigned int sourcesToUse = sourceSize;
|
||||||
if (sourcesToUse + targetComponent > numTargetComponents)
|
if (sourcesToUse + targetComponent > numTargetComponents)
|
||||||
sourcesToUse = numTargetComponents - targetComponent;
|
sourcesToUse = numTargetComponents - targetComponent;
|
||||||
|
|
||||||
for (unsigned int s = 0; s < sourcesToUse; ++s) {
|
for (unsigned int s = 0; s < sourcesToUse; ++s)
|
||||||
|
{
|
||||||
Id arg = sources[i];
|
Id arg = sources[i];
|
||||||
if (sourceSize > 1) {
|
if (sourceSize > 1)
|
||||||
|
{
|
||||||
std::vector<unsigned> swiz;
|
std::vector<unsigned> swiz;
|
||||||
swiz.push_back(s);
|
swiz.push_back(s);
|
||||||
arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz);
|
arg = createRvalueSwizzle(precision, scalarTypeId, arg, swiz);
|
||||||
|
|
@ -1719,8 +1798,10 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
Id ids[maxMatrixSize][maxMatrixSize];
|
Id ids[maxMatrixSize][maxMatrixSize];
|
||||||
Id one = makeFloatConstant(1.0);
|
Id one = makeFloatConstant(1.0);
|
||||||
Id zero = makeFloatConstant(0.0);
|
Id zero = makeFloatConstant(0.0);
|
||||||
for (int col = 0; col < 4; ++col) {
|
for (int col = 0; col < 4; ++col)
|
||||||
for (int row = 0; row < 4; ++row) {
|
{
|
||||||
|
for (int row = 0; row < 4; ++row)
|
||||||
|
{
|
||||||
if (col == row)
|
if (col == row)
|
||||||
ids[col][row] = one;
|
ids[col][row] = one;
|
||||||
else
|
else
|
||||||
|
|
@ -1729,40 +1810,49 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
}
|
}
|
||||||
|
|
||||||
// modify components as dictated by the arguments
|
// modify components as dictated by the arguments
|
||||||
if (sources.size() == 1 && isScalar(sources[0])) {
|
if (sources.size() == 1 && isScalar(sources[0]))
|
||||||
|
{
|
||||||
// a single scalar; resets the diagonals
|
// a single scalar; resets the diagonals
|
||||||
for (int col = 0; col < 4; ++col)
|
for (int col = 0; col < 4; ++col)
|
||||||
ids[col][col] = sources[0];
|
ids[col][col] = sources[0];
|
||||||
} else if (isMatrix(sources[0])) {
|
} else if (isMatrix(sources[0]))
|
||||||
|
{
|
||||||
// constructing from another matrix; copy over the parts that exist in both the argument and
|
// constructing from another matrix; copy over the parts that exist in both the argument and
|
||||||
// constructee
|
// constructee
|
||||||
Id matrix = sources[0];
|
Id matrix = sources[0];
|
||||||
int minCols = std::min(numCols, getNumColumns(matrix));
|
int minCols = std::min(numCols, getNumColumns(matrix));
|
||||||
int minRows = std::min(numRows, getNumRows(matrix));
|
int minRows = std::min(numRows, getNumRows(matrix));
|
||||||
for (int col = 0; col < minCols; ++col) {
|
for (int col = 0; col < minCols; ++col)
|
||||||
|
{
|
||||||
std::vector<unsigned> indexes;
|
std::vector<unsigned> indexes;
|
||||||
indexes.push_back(col);
|
indexes.push_back(col);
|
||||||
for (int row = 0; row < minRows; ++row) {
|
for (int row = 0; row < minRows; ++row)
|
||||||
|
{
|
||||||
indexes.push_back(row);
|
indexes.push_back(row);
|
||||||
ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes);
|
ids[col][row] = createCompositeExtract(matrix, componentTypeId, indexes);
|
||||||
indexes.pop_back();
|
indexes.pop_back();
|
||||||
setPrecision(ids[col][row], precision);
|
setPrecision(ids[col][row], precision);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
// fill in the matrix in column-major order with whatever argument components are available
|
// fill in the matrix in column-major order with whatever argument components are available
|
||||||
int row = 0;
|
int row = 0;
|
||||||
int col = 0;
|
int col = 0;
|
||||||
|
|
||||||
for (int arg = 0; arg < (int)sources.size(); ++arg) {
|
for (int arg = 0; arg < (int)sources.size(); ++arg)
|
||||||
|
{
|
||||||
Id argComp = sources[arg];
|
Id argComp = sources[arg];
|
||||||
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp) {
|
for (int comp = 0; comp < getNumComponents(sources[arg]); ++comp)
|
||||||
if (getNumComponents(sources[arg]) > 1) {
|
{
|
||||||
|
if (getNumComponents(sources[arg]) > 1)
|
||||||
|
{
|
||||||
argComp = createCompositeExtract(sources[arg], componentTypeId, comp);
|
argComp = createCompositeExtract(sources[arg], componentTypeId, comp);
|
||||||
setPrecision(argComp, precision);
|
setPrecision(argComp, precision);
|
||||||
}
|
}
|
||||||
ids[col][row++] = argComp;
|
ids[col][row++] = argComp;
|
||||||
if (row == numRows) {
|
if (row == numRows)
|
||||||
|
{
|
||||||
row = 0;
|
row = 0;
|
||||||
col++;
|
col++;
|
||||||
}
|
}
|
||||||
|
|
@ -1776,7 +1866,8 @@ Id Builder::createMatrixConstructor(Decoration precision, const std::vector<Id>&
|
||||||
// make the column vectors
|
// make the column vectors
|
||||||
Id columnTypeId = getContainedTypeId(resultTypeId);
|
Id columnTypeId = getContainedTypeId(resultTypeId);
|
||||||
std::vector<Id> matrixColumns;
|
std::vector<Id> matrixColumns;
|
||||||
for (int col = 0; col < numCols; ++col) {
|
for (int col = 0; col < numCols; ++col)
|
||||||
|
{
|
||||||
std::vector<Id> vectorComponents;
|
std::vector<Id> vectorComponents;
|
||||||
for (int row = 0; row < numRows; ++row)
|
for (int row = 0; row < numRows; ++row)
|
||||||
vectorComponents.push_back(ids[col][row]);
|
vectorComponents.push_back(ids[col][row]);
|
||||||
|
|
@ -1863,7 +1954,8 @@ void Builder::makeSwitch(Id selector, int numSegments, std::vector<int>& caseVal
|
||||||
auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock;
|
auto defaultOrMerge = (defaultSegment >= 0) ? segmentBlocks[defaultSegment] : mergeBlock;
|
||||||
switchInst->addIdOperand(defaultOrMerge->getId());
|
switchInst->addIdOperand(defaultOrMerge->getId());
|
||||||
defaultOrMerge->addPredecessor(buildPoint);
|
defaultOrMerge->addPredecessor(buildPoint);
|
||||||
for (int i = 0; i < (int)caseValues.size(); ++i) {
|
for (int i = 0; i < (int)caseValues.size(); ++i)
|
||||||
|
{
|
||||||
switchInst->addImmediateOperand(caseValues[i]);
|
switchInst->addImmediateOperand(caseValues[i]);
|
||||||
switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId());
|
switchInst->addIdOperand(segmentBlocks[valueIndexToSegment[i]]->getId());
|
||||||
segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint);
|
segmentBlocks[valueIndexToSegment[i]]->addPredecessor(buildPoint);
|
||||||
|
|
@ -1886,7 +1978,8 @@ void Builder::addSwitchBreak()
|
||||||
void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegment)
|
void Builder::nextSwitchSegment(std::vector<Block*>& segmentBlock, int nextSegment)
|
||||||
{
|
{
|
||||||
int lastSegment = nextSegment - 1;
|
int lastSegment = nextSegment - 1;
|
||||||
if (lastSegment >= 0) {
|
if (lastSegment >= 0)
|
||||||
|
{
|
||||||
// Close out previous segment by jumping, if necessary, to next segment
|
// Close out previous segment by jumping, if necessary, to next segment
|
||||||
if (!buildPoint->isTerminated())
|
if (!buildPoint->isTerminated())
|
||||||
createBranch(segmentBlock[nextSegment]);
|
createBranch(segmentBlock[nextSegment]);
|
||||||
|
|
@ -1960,10 +2053,12 @@ void Builder::accessChainPushSwizzle(std::vector<unsigned>& swizzle, Id preSwizz
|
||||||
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
accessChain.preSwizzleBaseType = preSwizzleBaseType;
|
||||||
|
|
||||||
// if needed, propagate the swizzle for the current access chain
|
// if needed, propagate the swizzle for the current access chain
|
||||||
if (accessChain.swizzle.size()) {
|
if (accessChain.swizzle.size())
|
||||||
|
{
|
||||||
std::vector<unsigned> oldSwizzle = accessChain.swizzle;
|
std::vector<unsigned> oldSwizzle = accessChain.swizzle;
|
||||||
accessChain.swizzle.resize(0);
|
accessChain.swizzle.resize(0);
|
||||||
for (unsigned int i = 0; i < swizzle.size(); ++i) {
|
for (unsigned int i = 0; i < swizzle.size(); ++i)
|
||||||
|
{
|
||||||
accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);
|
accessChain.swizzle.push_back(oldSwizzle[swizzle[i]]);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
|
|
@ -1987,14 +2082,16 @@ void Builder::accessChainStore(Id rvalue)
|
||||||
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
// If swizzle still exists, it is out-of-order or not full, we must load the target vector,
|
||||||
// extract and insert elements to perform writeMask and/or swizzle.
|
// extract and insert elements to perform writeMask and/or swizzle.
|
||||||
Id source = NoResult;
|
Id source = NoResult;
|
||||||
if (accessChain.swizzle.size()) {
|
if (accessChain.swizzle.size())
|
||||||
|
{
|
||||||
Id tempBaseId = createLoad(base);
|
Id tempBaseId = createLoad(base);
|
||||||
source =
|
source =
|
||||||
createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
|
createLvalueSwizzle(getTypeId(tempBaseId), tempBaseId, rvalue, accessChain.swizzle);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamic component selection
|
// dynamic component selection
|
||||||
if (accessChain.component != NoResult) {
|
if (accessChain.component != NoResult)
|
||||||
|
{
|
||||||
Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
|
Id tempBaseId = (source == NoResult) ? createLoad(base) : source;
|
||||||
source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue,
|
source = createVectorInsertDynamic(tempBaseId, getTypeId(tempBaseId), rvalue,
|
||||||
accessChain.component);
|
accessChain.component);
|
||||||
|
|
@ -2011,10 +2108,12 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
|
||||||
{
|
{
|
||||||
Id id;
|
Id id;
|
||||||
|
|
||||||
if (accessChain.isRValue) {
|
if (accessChain.isRValue)
|
||||||
|
{
|
||||||
// transfer access chain, but keep it static, so we can stay in registers
|
// transfer access chain, but keep it static, so we can stay in registers
|
||||||
transferAccessChainSwizzle(false);
|
transferAccessChainSwizzle(false);
|
||||||
if (accessChain.indexChain.size() > 0) {
|
if (accessChain.indexChain.size() > 0)
|
||||||
|
{
|
||||||
Id swizzleBase = accessChain.preSwizzleBaseType != NoType
|
Id swizzleBase = accessChain.preSwizzleBaseType != NoType
|
||||||
? accessChain.preSwizzleBaseType
|
? accessChain.preSwizzleBaseType
|
||||||
: resultType;
|
: resultType;
|
||||||
|
|
@ -2022,10 +2121,12 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
|
||||||
// if all the accesses are constants, we can use OpCompositeExtract
|
// if all the accesses are constants, we can use OpCompositeExtract
|
||||||
std::vector<unsigned> indexes;
|
std::vector<unsigned> indexes;
|
||||||
bool constant = true;
|
bool constant = true;
|
||||||
for (int i = 0; i < (int)accessChain.indexChain.size(); ++i) {
|
for (int i = 0; i < (int)accessChain.indexChain.size(); ++i)
|
||||||
|
{
|
||||||
if (isConstantScalar(accessChain.indexChain[i]))
|
if (isConstantScalar(accessChain.indexChain[i]))
|
||||||
indexes.push_back(getConstantScalar(accessChain.indexChain[i]));
|
indexes.push_back(getConstantScalar(accessChain.indexChain[i]));
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
constant = false;
|
constant = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -2033,7 +2134,8 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
|
||||||
|
|
||||||
if (constant)
|
if (constant)
|
||||||
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
id = createCompositeExtract(accessChain.base, swizzleBase, indexes);
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
// make a new function variable for this r-value
|
// make a new function variable for this r-value
|
||||||
Id lValue =
|
Id lValue =
|
||||||
createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
createVariable(StorageClassFunction, getTypeId(accessChain.base), "indexable");
|
||||||
|
|
@ -2051,7 +2153,8 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
|
||||||
setPrecision(id, precision);
|
setPrecision(id, precision);
|
||||||
} else
|
} else
|
||||||
id = accessChain.base; // no precision, it was set when this was defined
|
id = accessChain.base; // no precision, it was set when this was defined
|
||||||
} else {
|
} else
|
||||||
|
{
|
||||||
transferAccessChainSwizzle(true);
|
transferAccessChainSwizzle(true);
|
||||||
// load through the access chain
|
// load through the access chain
|
||||||
id = createLoad(collapseAccessChain());
|
id = createLoad(collapseAccessChain());
|
||||||
|
|
@ -2064,7 +2167,8 @@ Id Builder::accessChainLoad(Decoration precision, Id resultType)
|
||||||
|
|
||||||
// Do remaining swizzling
|
// Do remaining swizzling
|
||||||
// First, static swizzling
|
// First, static swizzling
|
||||||
if (accessChain.swizzle.size()) {
|
if (accessChain.swizzle.size())
|
||||||
|
{
|
||||||
// static swizzle
|
// static swizzle
|
||||||
Id swizzledType = getScalarTypeId(getTypeId(id));
|
Id swizzledType = getScalarTypeId(getTypeId(id));
|
||||||
if (accessChain.swizzle.size() > 1)
|
if (accessChain.swizzle.size() > 1)
|
||||||
|
|
@ -2109,7 +2213,8 @@ Id Builder::accessChainGetInferredType()
|
||||||
type = getContainedTypeId(type);
|
type = getContainedTypeId(type);
|
||||||
|
|
||||||
// dereference each index
|
// dereference each index
|
||||||
for (auto it = accessChain.indexChain.cbegin(); it != accessChain.indexChain.cend(); ++it) {
|
for (auto it = accessChain.indexChain.cbegin(); it != accessChain.indexChain.cend(); ++it)
|
||||||
|
{
|
||||||
if (isStructType(type))
|
if (isStructType(type))
|
||||||
type = getContainedTypeId(type, getConstantScalar(*it));
|
type = getContainedTypeId(type, getConstantScalar(*it));
|
||||||
else
|
else
|
||||||
|
|
@ -2139,7 +2244,8 @@ void Builder::dump(std::vector<unsigned int>& out) const
|
||||||
out.push_back(0);
|
out.push_back(0);
|
||||||
|
|
||||||
// Capabilities
|
// Capabilities
|
||||||
for (auto it = capabilities.cbegin(); it != capabilities.cend(); ++it) {
|
for (auto it = capabilities.cbegin(); it != capabilities.cend(); ++it)
|
||||||
|
{
|
||||||
Instruction capInst(0, 0, OpCapability);
|
Instruction capInst(0, 0, OpCapability);
|
||||||
capInst.addImmediateOperand(*it);
|
capInst.addImmediateOperand(*it);
|
||||||
capInst.dump(out);
|
capInst.dump(out);
|
||||||
|
|
@ -2158,13 +2264,15 @@ void Builder::dump(std::vector<unsigned int>& out) const
|
||||||
dumpInstructions(out, executionModes);
|
dumpInstructions(out, executionModes);
|
||||||
|
|
||||||
// Debug instructions
|
// Debug instructions
|
||||||
if (source != SourceLanguageUnknown) {
|
if (source != SourceLanguageUnknown)
|
||||||
|
{
|
||||||
Instruction sourceInst(0, 0, OpSource);
|
Instruction sourceInst(0, 0, OpSource);
|
||||||
sourceInst.addImmediateOperand(source);
|
sourceInst.addImmediateOperand(source);
|
||||||
sourceInst.addImmediateOperand(sourceVersion);
|
sourceInst.addImmediateOperand(sourceVersion);
|
||||||
sourceInst.dump(out);
|
sourceInst.dump(out);
|
||||||
}
|
}
|
||||||
for (int e = 0; e < (int)extensions.size(); ++e) {
|
for (int e = 0; e < (int)extensions.size(); ++e)
|
||||||
|
{
|
||||||
Instruction extInst(0, 0, OpSourceExtension);
|
Instruction extInst(0, 0, OpSourceExtension);
|
||||||
extInst.addStringOperand(extensions[e]);
|
extInst.addStringOperand(extensions[e]);
|
||||||
extInst.dump(out);
|
extInst.dump(out);
|
||||||
|
|
@ -2195,8 +2303,10 @@ Id Builder::collapseAccessChain()
|
||||||
{
|
{
|
||||||
assert(accessChain.isRValue == false);
|
assert(accessChain.isRValue == false);
|
||||||
|
|
||||||
if (accessChain.indexChain.size() > 0) {
|
if (accessChain.indexChain.size() > 0)
|
||||||
if (accessChain.instr == 0) {
|
{
|
||||||
|
if (accessChain.instr == 0)
|
||||||
|
{
|
||||||
StorageClass storageClass =
|
StorageClass storageClass =
|
||||||
(StorageClass)module.getStorageClass(getTypeId(accessChain.base));
|
(StorageClass)module.getStorageClass(getTypeId(accessChain.base));
|
||||||
accessChain.instr =
|
accessChain.instr =
|
||||||
|
|
@ -2220,7 +2330,8 @@ void Builder::simplifyAccessChainSwizzle()
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// if components are out of order, it is a swizzle
|
// if components are out of order, it is a swizzle
|
||||||
for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i) {
|
for (unsigned int i = 0; i < accessChain.swizzle.size(); ++i)
|
||||||
|
{
|
||||||
if (i != accessChain.swizzle[i])
|
if (i != accessChain.swizzle[i])
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
@ -2256,7 +2367,8 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
|
||||||
if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))
|
if (isBoolType(getContainedTypeId(accessChain.preSwizzleBaseType)))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (accessChain.swizzle.size() == 1) {
|
if (accessChain.swizzle.size() == 1)
|
||||||
|
{
|
||||||
// handle static component
|
// handle static component
|
||||||
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
|
accessChain.indexChain.push_back(makeUintConstant(accessChain.swizzle.front()));
|
||||||
accessChain.swizzle.clear();
|
accessChain.swizzle.clear();
|
||||||
|
|
@ -2264,7 +2376,8 @@ void Builder::transferAccessChainSwizzle(bool dynamic)
|
||||||
// component, so don't bother even looking at accessChain.component
|
// component, so don't bother even looking at accessChain.component
|
||||||
accessChain.preSwizzleBaseType = NoType;
|
accessChain.preSwizzleBaseType = NoType;
|
||||||
accessChain.component = NoResult;
|
accessChain.component = NoResult;
|
||||||
} else if (dynamic && accessChain.component != NoResult) {
|
} else if (dynamic && accessChain.component != NoResult)
|
||||||
|
{
|
||||||
// handle dynamic component
|
// handle dynamic component
|
||||||
accessChain.indexChain.push_back(accessChain.component);
|
accessChain.indexChain.push_back(accessChain.component);
|
||||||
accessChain.preSwizzleBaseType = NoType;
|
accessChain.preSwizzleBaseType = NoType;
|
||||||
|
|
@ -2326,7 +2439,8 @@ void Builder::createConditionalBranch(Id condition, Block* thenBlock, Block* els
|
||||||
void Builder::dumpInstructions(std::vector<unsigned int>& out,
|
void Builder::dumpInstructions(std::vector<unsigned int>& out,
|
||||||
const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
const std::vector<std::unique_ptr<Instruction> >& instructions) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < (int)instructions.size(); ++i) {
|
for (int i = 0; i < (int)instructions.size(); ++i)
|
||||||
|
{
|
||||||
instructions[i]->dump(out);
|
instructions[i]->dump(out);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2335,7 +2449,8 @@ void TbdFunctionality(const char* tbd)
|
||||||
{
|
{
|
||||||
static std::unordered_set<const char*> issued;
|
static std::unordered_set<const char*> issued;
|
||||||
|
|
||||||
if (issued.find(tbd) == issued.end()) {
|
if (issued.find(tbd) == issued.end())
|
||||||
|
{
|
||||||
printf("TBD functionality: %s\n", tbd);
|
printf("TBD functionality: %s\n", tbd);
|
||||||
issued.insert(tbd);
|
issued.insert(tbd);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue