clang-format the src/Pipeline directory
Bug: b/144825072
Change-Id: I869aef91d6318bf6955581e5dad762800bd46296
Reviewed-on: https://swiftshader-review.googlesource.com/c/SwiftShader/+/39655
Tested-by: Ben Clayton <bclayton@google.com>
Reviewed-by: Nicolas Capens <nicolascapens@google.com>
diff --git a/src/Pipeline/SpirvShader.cpp b/src/Pipeline/SpirvShader.cpp
index 11b3770..2350195 100644
--- a/src/Pipeline/SpirvShader.cpp
+++ b/src/Pipeline/SpirvShader.cpp
@@ -23,17 +23,18 @@
namespace sw {
SpirvShader::SpirvShader(
- uint32_t codeSerialID,
- VkShaderStageFlagBits pipelineStage,
- const char *entryPointName,
- InsnStore const &insns,
- const vk::RenderPass *renderPass,
- uint32_t subpassIndex,
- bool robustBufferAccess)
- : insns{insns}, inputs{MAX_INTERFACE_COMPONENTS},
- outputs{MAX_INTERFACE_COMPONENTS},
- codeSerialID(codeSerialID),
- robustBufferAccess(robustBufferAccess)
+ uint32_t codeSerialID,
+ VkShaderStageFlagBits pipelineStage,
+ const char *entryPointName,
+ InsnStore const &insns,
+ const vk::RenderPass *renderPass,
+ uint32_t subpassIndex,
+ bool robustBufferAccess)
+ : insns{ insns }
+ , inputs{ MAX_INTERFACE_COMPONENTS }
+ , outputs{ MAX_INTERFACE_COMPONENTS }
+ , codeSerialID(codeSerialID)
+ , robustBufferAccess(robustBufferAccess)
{
ASSERT(insns.size() > 0);
@@ -46,7 +47,8 @@
{
auto attachmentIndex = subpass.pInputAttachments[i].attachment;
inputAttachmentFormats.push_back(attachmentIndex != VK_ATTACHMENT_UNUSED
- ? renderPass->getAttachment(attachmentIndex).format : VK_FORMAT_UNDEFINED);
+ ? renderPass->getAttachment(attachmentIndex).format
+ : VK_FORMAT_UNDEFINED);
}
}
@@ -63,403 +65,404 @@
switch(opcode)
{
- case spv::OpEntryPoint:
- {
- executionModel = spv::ExecutionModel(insn.word(1));
- auto id = Function::ID(insn.word(2));
- auto name = insn.string(3);
- auto stage = executionModelToStage(executionModel);
- if(stage == pipelineStage && strcmp(name, entryPointName) == 0)
+ case spv::OpEntryPoint:
{
- ASSERT_MSG(entryPoint == 0, "Duplicate entry point with name '%s' and stage %d", name, int(stage));
- entryPoint = id;
- }
- break;
- }
-
- case spv::OpExecutionMode:
- ProcessExecutionMode(insn);
- break;
-
- case spv::OpDecorate:
- {
- TypeOrObjectID targetId = insn.word(1);
- auto decoration = static_cast<spv::Decoration>(insn.word(2));
- uint32_t value = insn.wordCount() > 3 ? insn.word(3) : 0;
-
- decorations[targetId].Apply(decoration, value);
-
- switch(decoration)
- {
- case spv::DecorationDescriptorSet:
- descriptorDecorations[targetId].DescriptorSet = value;
- break;
- case spv::DecorationBinding:
- descriptorDecorations[targetId].Binding = value;
- break;
- case spv::DecorationInputAttachmentIndex:
- descriptorDecorations[targetId].InputAttachmentIndex = value;
- break;
- default:
- // Only handling descriptor decorations here.
+ executionModel = spv::ExecutionModel(insn.word(1));
+ auto id = Function::ID(insn.word(2));
+ auto name = insn.string(3);
+ auto stage = executionModelToStage(executionModel);
+ if(stage == pipelineStage && strcmp(name, entryPointName) == 0)
+ {
+ ASSERT_MSG(entryPoint == 0, "Duplicate entry point with name '%s' and stage %d", name, int(stage));
+ entryPoint = id;
+ }
break;
}
- if(decoration == spv::DecorationCentroid)
- modes.NeedsCentroid = true;
- break;
- }
+ case spv::OpExecutionMode:
+ ProcessExecutionMode(insn);
+ break;
- case spv::OpMemberDecorate:
- {
- Type::ID targetId = insn.word(1);
- auto memberIndex = insn.word(2);
- auto decoration = static_cast<spv::Decoration>(insn.word(3));
- uint32_t value = insn.wordCount() > 4 ? insn.word(4) : 0;
-
- auto &d = memberDecorations[targetId];
- if(memberIndex >= d.size())
- d.resize(memberIndex + 1); // on demand; exact size would require another pass...
-
- d[memberIndex].Apply(decoration, value);
-
- if(decoration == spv::DecorationCentroid)
- modes.NeedsCentroid = true;
- break;
- }
-
- case spv::OpDecorationGroup:
- // Nothing to do here. We don't need to record the definition of the group; we'll just have
- // the bundle of decorations float around. If we were to ever walk the decorations directly,
- // we might think about introducing this as a real Object.
- break;
-
- case spv::OpGroupDecorate:
- {
- uint32_t group = insn.word(1);
- auto const &groupDecorations = decorations[group];
- auto const &descriptorGroupDecorations = descriptorDecorations[group];
- for(auto i = 2u; i < insn.wordCount(); i++)
+ case spv::OpDecorate:
{
- // Remaining operands are targets to apply the group to.
- uint32_t target = insn.word(i);
- decorations[target].Apply(groupDecorations);
- descriptorDecorations[target].Apply(descriptorGroupDecorations);
+ TypeOrObjectID targetId = insn.word(1);
+ auto decoration = static_cast<spv::Decoration>(insn.word(2));
+ uint32_t value = insn.wordCount() > 3 ? insn.word(3) : 0;
+
+ decorations[targetId].Apply(decoration, value);
+
+ switch(decoration)
+ {
+ case spv::DecorationDescriptorSet:
+ descriptorDecorations[targetId].DescriptorSet = value;
+ break;
+ case spv::DecorationBinding:
+ descriptorDecorations[targetId].Binding = value;
+ break;
+ case spv::DecorationInputAttachmentIndex:
+ descriptorDecorations[targetId].InputAttachmentIndex = value;
+ break;
+ default:
+ // Only handling descriptor decorations here.
+ break;
+ }
+
+ if(decoration == spv::DecorationCentroid)
+ modes.NeedsCentroid = true;
+ break;
}
- break;
- }
-
- case spv::OpGroupMemberDecorate:
- {
- auto const &srcDecorations = decorations[insn.word(1)];
- for(auto i = 2u; i < insn.wordCount(); i += 2)
+ case spv::OpMemberDecorate:
{
- // remaining operands are pairs of <id>, literal for members to apply to.
- auto &d = memberDecorations[insn.word(i)];
- auto memberIndex = insn.word(i + 1);
+ Type::ID targetId = insn.word(1);
+ auto memberIndex = insn.word(2);
+ auto decoration = static_cast<spv::Decoration>(insn.word(3));
+ uint32_t value = insn.wordCount() > 4 ? insn.word(4) : 0;
+
+ auto &d = memberDecorations[targetId];
if(memberIndex >= d.size())
- d.resize(memberIndex + 1); // on demand resize, see above...
- d[memberIndex].Apply(srcDecorations);
+ d.resize(memberIndex + 1); // on demand; exact size would require another pass...
+
+ d[memberIndex].Apply(decoration, value);
+
+ if(decoration == spv::DecorationCentroid)
+ modes.NeedsCentroid = true;
+ break;
}
- break;
- }
- case spv::OpLabel:
- {
- ASSERT(currentBlock.value() == 0);
- currentBlock = Block::ID(insn.word(1));
- blockStart = insn;
- break;
- }
-
- // Branch Instructions (subset of Termination Instructions):
- case spv::OpBranch:
- case spv::OpBranchConditional:
- case spv::OpSwitch:
- case spv::OpReturn:
- // fallthrough
-
- // Termination instruction:
- case spv::OpKill:
- case spv::OpUnreachable:
- {
- ASSERT(currentBlock.value() != 0);
- ASSERT(currentFunction.value() != 0);
-
- auto blockEnd = insn; blockEnd++;
- functions[currentFunction].blocks[currentBlock] = Block(blockStart, blockEnd);
- currentBlock = Block::ID(0);
-
- if(opcode == spv::OpKill)
- {
- modes.ContainsKill = true;
- }
- break;
- }
-
- case spv::OpLoopMerge:
- case spv::OpSelectionMerge:
- break; // Nothing to do in analysis pass.
-
- case spv::OpTypeVoid:
- case spv::OpTypeBool:
- case spv::OpTypeInt:
- case spv::OpTypeFloat:
- case spv::OpTypeVector:
- case spv::OpTypeMatrix:
- case spv::OpTypeImage:
- case spv::OpTypeSampler:
- case spv::OpTypeSampledImage:
- case spv::OpTypeArray:
- case spv::OpTypeRuntimeArray:
- case spv::OpTypeStruct:
- case spv::OpTypePointer:
- case spv::OpTypeFunction:
- DeclareType(insn);
- break;
-
- case spv::OpVariable:
- {
- Type::ID typeId = insn.word(1);
- Object::ID resultId = insn.word(2);
- auto storageClass = static_cast<spv::StorageClass>(insn.word(3));
-
- auto &object = defs[resultId];
- object.kind = Object::Kind::Pointer;
- object.definition = insn;
- object.type = typeId;
-
- ASSERT(getType(typeId).definition.opcode() == spv::OpTypePointer);
- ASSERT(getType(typeId).storageClass == storageClass);
-
- switch(storageClass)
- {
- case spv::StorageClassInput:
- case spv::StorageClassOutput:
- ProcessInterfaceVariable(object);
+ case spv::OpDecorationGroup:
+ // Nothing to do here. We don't need to record the definition of the group; we'll just have
+ // the bundle of decorations float around. If we were to ever walk the decorations directly,
+ // we might think about introducing this as a real Object.
break;
- case spv::StorageClassUniform:
- case spv::StorageClassStorageBuffer:
- object.kind = Object::Kind::DescriptorSet;
+ case spv::OpGroupDecorate:
+ {
+ uint32_t group = insn.word(1);
+ auto const &groupDecorations = decorations[group];
+ auto const &descriptorGroupDecorations = descriptorDecorations[group];
+ for(auto i = 2u; i < insn.wordCount(); i++)
+ {
+ // Remaining operands are targets to apply the group to.
+ uint32_t target = insn.word(i);
+ decorations[target].Apply(groupDecorations);
+ descriptorDecorations[target].Apply(descriptorGroupDecorations);
+ }
+
+ break;
+ }
+
+ case spv::OpGroupMemberDecorate:
+ {
+ auto const &srcDecorations = decorations[insn.word(1)];
+ for(auto i = 2u; i < insn.wordCount(); i += 2)
+ {
+ // remaining operands are pairs of <id>, literal for members to apply to.
+ auto &d = memberDecorations[insn.word(i)];
+ auto memberIndex = insn.word(i + 1);
+ if(memberIndex >= d.size())
+ d.resize(memberIndex + 1); // on demand resize, see above...
+ d[memberIndex].Apply(srcDecorations);
+ }
+ break;
+ }
+
+ case spv::OpLabel:
+ {
+ ASSERT(currentBlock.value() == 0);
+ currentBlock = Block::ID(insn.word(1));
+ blockStart = insn;
+ break;
+ }
+
+ // Branch Instructions (subset of Termination Instructions):
+ case spv::OpBranch:
+ case spv::OpBranchConditional:
+ case spv::OpSwitch:
+ case spv::OpReturn:
+ // fallthrough
+
+ // Termination instruction:
+ case spv::OpKill:
+ case spv::OpUnreachable:
+ {
+ ASSERT(currentBlock.value() != 0);
+ ASSERT(currentFunction.value() != 0);
+
+ auto blockEnd = insn;
+ blockEnd++;
+ functions[currentFunction].blocks[currentBlock] = Block(blockStart, blockEnd);
+ currentBlock = Block::ID(0);
+
+ if(opcode == spv::OpKill)
+ {
+ modes.ContainsKill = true;
+ }
+ break;
+ }
+
+ case spv::OpLoopMerge:
+ case spv::OpSelectionMerge:
+ break; // Nothing to do in analysis pass.
+
+ case spv::OpTypeVoid:
+ case spv::OpTypeBool:
+ case spv::OpTypeInt:
+ case spv::OpTypeFloat:
+ case spv::OpTypeVector:
+ case spv::OpTypeMatrix:
+ case spv::OpTypeImage:
+ case spv::OpTypeSampler:
+ case spv::OpTypeSampledImage:
+ case spv::OpTypeArray:
+ case spv::OpTypeRuntimeArray:
+ case spv::OpTypeStruct:
+ case spv::OpTypePointer:
+ case spv::OpTypeFunction:
+ DeclareType(insn);
break;
- case spv::StorageClassPushConstant:
- case spv::StorageClassPrivate:
- case spv::StorageClassFunction:
- case spv::StorageClassUniformConstant:
- break; // Correctly handled.
-
- case spv::StorageClassWorkgroup:
+ case spv::OpVariable:
{
- auto &elTy = getType(getType(typeId).element);
- auto sizeInBytes = elTy.sizeInComponents * static_cast<uint32_t>(sizeof(float));
- workgroupMemory.allocate(resultId, sizeInBytes);
+ Type::ID typeId = insn.word(1);
+ Object::ID resultId = insn.word(2);
+ auto storageClass = static_cast<spv::StorageClass>(insn.word(3));
+
+ auto &object = defs[resultId];
object.kind = Object::Kind::Pointer;
- break;
- }
- case spv::StorageClassAtomicCounter:
- case spv::StorageClassImage:
- UNIMPLEMENTED("StorageClass %d not yet implemented", (int)storageClass);
- break;
+ object.definition = insn;
+ object.type = typeId;
- case spv::StorageClassCrossWorkgroup:
- UNSUPPORTED("SPIR-V OpenCL Execution Model (StorageClassCrossWorkgroup)");
- break;
+ ASSERT(getType(typeId).definition.opcode() == spv::OpTypePointer);
+ ASSERT(getType(typeId).storageClass == storageClass);
- case spv::StorageClassGeneric:
- UNSUPPORTED("SPIR-V GenericPointer Capability (StorageClassGeneric)");
- break;
-
- default:
- UNREACHABLE("Unexpected StorageClass %d", storageClass); // See Appendix A of the Vulkan spec.
- break;
- }
- break;
- }
-
- case spv::OpConstant:
- case spv::OpSpecConstant:
- CreateConstant(insn).constantValue[0] = insn.word(3);
- break;
- case spv::OpConstantFalse:
- case spv::OpSpecConstantFalse:
- CreateConstant(insn).constantValue[0] = 0; // Represent Boolean false as zero.
- break;
- case spv::OpConstantTrue:
- case spv::OpSpecConstantTrue:
- CreateConstant(insn).constantValue[0] = ~0u; // Represent Boolean true as all bits set.
- break;
- case spv::OpConstantNull:
- case spv::OpUndef:
- {
- // TODO: consider a real LLVM-level undef. For now, zero is a perfectly good value.
- // OpConstantNull forms a constant of arbitrary type, all zeros.
- auto &object = CreateConstant(insn);
- auto &objectTy = getType(object.type);
- for(auto i = 0u; i < objectTy.sizeInComponents; i++)
- {
- object.constantValue[i] = 0;
- }
- break;
- }
- case spv::OpConstantComposite:
- case spv::OpSpecConstantComposite:
- {
- auto &object = CreateConstant(insn);
- auto offset = 0u;
- for(auto i = 0u; i < insn.wordCount() - 3; i++)
- {
- auto &constituent = getObject(insn.word(i + 3));
- auto &constituentTy = getType(constituent.type);
- for(auto j = 0u; j < constituentTy.sizeInComponents; j++)
+ switch(storageClass)
{
- object.constantValue[offset++] = constituent.constantValue[j];
+ case spv::StorageClassInput:
+ case spv::StorageClassOutput:
+ ProcessInterfaceVariable(object);
+ break;
+
+ case spv::StorageClassUniform:
+ case spv::StorageClassStorageBuffer:
+ object.kind = Object::Kind::DescriptorSet;
+ break;
+
+ case spv::StorageClassPushConstant:
+ case spv::StorageClassPrivate:
+ case spv::StorageClassFunction:
+ case spv::StorageClassUniformConstant:
+ break; // Correctly handled.
+
+ case spv::StorageClassWorkgroup:
+ {
+ auto &elTy = getType(getType(typeId).element);
+ auto sizeInBytes = elTy.sizeInComponents * static_cast<uint32_t>(sizeof(float));
+ workgroupMemory.allocate(resultId, sizeInBytes);
+ object.kind = Object::Kind::Pointer;
+ break;
+ }
+ case spv::StorageClassAtomicCounter:
+ case spv::StorageClassImage:
+ UNIMPLEMENTED("StorageClass %d not yet implemented", (int)storageClass);
+ break;
+
+ case spv::StorageClassCrossWorkgroup:
+ UNSUPPORTED("SPIR-V OpenCL Execution Model (StorageClassCrossWorkgroup)");
+ break;
+
+ case spv::StorageClassGeneric:
+ UNSUPPORTED("SPIR-V GenericPointer Capability (StorageClassGeneric)");
+ break;
+
+ default:
+ UNREACHABLE("Unexpected StorageClass %d", storageClass); // See Appendix A of the Vulkan spec.
+ break;
}
+ break;
}
- auto objectId = Object::ID(insn.word(2));
- auto decorationsIt = decorations.find(objectId);
- if(decorationsIt != decorations.end() &&
- decorationsIt->second.BuiltIn == spv::BuiltInWorkgroupSize)
+ case spv::OpConstant:
+ case spv::OpSpecConstant:
+ CreateConstant(insn).constantValue[0] = insn.word(3);
+ break;
+ case spv::OpConstantFalse:
+ case spv::OpSpecConstantFalse:
+ CreateConstant(insn).constantValue[0] = 0; // Represent Boolean false as zero.
+ break;
+ case spv::OpConstantTrue:
+ case spv::OpSpecConstantTrue:
+ CreateConstant(insn).constantValue[0] = ~0u; // Represent Boolean true as all bits set.
+ break;
+ case spv::OpConstantNull:
+ case spv::OpUndef:
{
- // https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#interfaces-builtin-variables :
- // Decorating an object with the WorkgroupSize built-in
- // decoration will make that object contain the dimensions
- // of a local workgroup. If an object is decorated with the
- // WorkgroupSize decoration, this must take precedence over
- // any execution mode set for LocalSize.
- // The object decorated with WorkgroupSize must be declared
- // as a three-component vector of 32-bit integers.
- ASSERT(getType(object.type).sizeInComponents == 3);
- modes.WorkgroupSizeX = object.constantValue[0];
- modes.WorkgroupSizeY = object.constantValue[1];
- modes.WorkgroupSizeZ = object.constantValue[2];
- }
- break;
- }
- case spv::OpSpecConstantOp:
- EvalSpecConstantOp(insn);
- break;
-
- case spv::OpCapability:
- {
- auto capability = static_cast<spv::Capability>(insn.word(1));
- switch(capability)
- {
- case spv::CapabilityMatrix: capabilities.Matrix = true; break;
- case spv::CapabilityShader: capabilities.Shader = true; break;
- case spv::CapabilityClipDistance: capabilities.ClipDistance = true; break;
- case spv::CapabilityCullDistance: capabilities.CullDistance = true; break;
- case spv::CapabilityInputAttachment: capabilities.InputAttachment = true; break;
- case spv::CapabilitySampled1D: capabilities.Sampled1D = true; break;
- case spv::CapabilityImage1D: capabilities.Image1D = true; break;
- case spv::CapabilityImageCubeArray: capabilities.ImageCubeArray = true; break;
- case spv::CapabilitySampledBuffer: capabilities.SampledBuffer = true; break;
- case spv::CapabilitySampledCubeArray: capabilities.SampledCubeArray = true; break;
- case spv::CapabilityImageBuffer: capabilities.ImageBuffer = true; break;
- case spv::CapabilityStorageImageExtendedFormats: capabilities.StorageImageExtendedFormats = true; break;
- case spv::CapabilityImageQuery: capabilities.ImageQuery = true; break;
- case spv::CapabilityDerivativeControl: capabilities.DerivativeControl = true; break;
- case spv::CapabilityGroupNonUniform: capabilities.GroupNonUniform = true; break;
- case spv::CapabilityGroupNonUniformVote: capabilities.GroupNonUniformVote = true; break;
- case spv::CapabilityGroupNonUniformArithmetic: capabilities.GroupNonUniformArithmetic = true; break;
- case spv::CapabilityGroupNonUniformBallot: capabilities.GroupNonUniformBallot = true; break;
- case spv::CapabilityGroupNonUniformShuffle: capabilities.GroupNonUniformShuffle = true; break;
- case spv::CapabilityGroupNonUniformShuffleRelative: capabilities.GroupNonUniformShuffleRelative = true; break;
- case spv::CapabilityDeviceGroup: capabilities.DeviceGroup = true; break;
- case spv::CapabilityMultiView: capabilities.MultiView = true; break;
- default:
- UNSUPPORTED("Unsupported capability %u", insn.word(1));
- }
- break; // Various capabilities will be declared, but none affect our code generation at this point.
- }
-
- case spv::OpMemoryModel:
- break; // Memory model does not affect our code generation until we decide to do Vulkan Memory Model support.
-
- case spv::OpFunction:
- {
- auto functionId = Function::ID(insn.word(2));
- ASSERT_MSG(currentFunction == 0, "Functions %d and %d overlap", currentFunction.value(), functionId.value());
- currentFunction = functionId;
- auto &function = functions[functionId];
- function.result = Type::ID(insn.word(1));
- function.type = Type::ID(insn.word(4));
- // Scan forward to find the function's label.
- for(auto it = insn; it != end() && function.entry == 0; it++)
- {
- switch(it.opcode())
+ // TODO: consider a real LLVM-level undef. For now, zero is a perfectly good value.
+ // OpConstantNull forms a constant of arbitrary type, all zeros.
+ auto &object = CreateConstant(insn);
+ auto &objectTy = getType(object.type);
+ for(auto i = 0u; i < objectTy.sizeInComponents; i++)
{
- case spv::OpFunction:
- case spv::OpFunctionParameter:
- break;
- case spv::OpLabel:
- function.entry = Block::ID(it.word(1));
- break;
- default:
- WARN("Unexpected opcode '%s' following OpFunction", OpcodeName(it.opcode()).c_str());
+ object.constantValue[i] = 0;
}
+ break;
}
- ASSERT_MSG(function.entry != 0, "Function<%d> has no label", currentFunction.value());
- break;
- }
-
- case spv::OpFunctionEnd:
- currentFunction = 0;
- break;
-
- case spv::OpExtInstImport:
- {
- // We will only support the GLSL 450 extended instruction set, so no point in tracking the ID we assign it.
- // Valid shaders will not attempt to import any other instruction sets.
- auto ext = insn.string(2);
- if(0 != strcmp("GLSL.std.450", ext))
+ case spv::OpConstantComposite:
+ case spv::OpSpecConstantComposite:
{
- UNSUPPORTED("SPIR-V Extension: %s", ext);
+ auto &object = CreateConstant(insn);
+ auto offset = 0u;
+ for(auto i = 0u; i < insn.wordCount() - 3; i++)
+ {
+ auto &constituent = getObject(insn.word(i + 3));
+ auto &constituentTy = getType(constituent.type);
+ for(auto j = 0u; j < constituentTy.sizeInComponents; j++)
+ {
+ object.constantValue[offset++] = constituent.constantValue[j];
+ }
+ }
+
+ auto objectId = Object::ID(insn.word(2));
+ auto decorationsIt = decorations.find(objectId);
+ if(decorationsIt != decorations.end() &&
+ decorationsIt->second.BuiltIn == spv::BuiltInWorkgroupSize)
+ {
+ // https://www.khronos.org/registry/vulkan/specs/1.1/html/vkspec.html#interfaces-builtin-variables :
+ // Decorating an object with the WorkgroupSize built-in
+ // decoration will make that object contain the dimensions
+ // of a local workgroup. If an object is decorated with the
+ // WorkgroupSize decoration, this must take precedence over
+ // any execution mode set for LocalSize.
+ // The object decorated with WorkgroupSize must be declared
+ // as a three-component vector of 32-bit integers.
+ ASSERT(getType(object.type).sizeInComponents == 3);
+ modes.WorkgroupSizeX = object.constantValue[0];
+ modes.WorkgroupSizeY = object.constantValue[1];
+ modes.WorkgroupSizeZ = object.constantValue[2];
+ }
+ break;
}
- break;
- }
- case spv::OpName:
- case spv::OpMemberName:
- case spv::OpSource:
- case spv::OpSourceContinued:
- case spv::OpSourceExtension:
- case spv::OpLine:
- case spv::OpNoLine:
- case spv::OpModuleProcessed:
- case spv::OpString:
- // No semantic impact
- break;
+ case spv::OpSpecConstantOp:
+ EvalSpecConstantOp(insn);
+ break;
- case spv::OpFunctionParameter:
- // These should have all been removed by preprocessing passes. If we see them here,
- // our assumptions are wrong and we will probably generate wrong code.
- UNREACHABLE("%s should have already been lowered.", OpcodeName(opcode).c_str());
- break;
+ case spv::OpCapability:
+ {
+ auto capability = static_cast<spv::Capability>(insn.word(1));
+ switch(capability)
+ {
+ case spv::CapabilityMatrix: capabilities.Matrix = true; break;
+ case spv::CapabilityShader: capabilities.Shader = true; break;
+ case spv::CapabilityClipDistance: capabilities.ClipDistance = true; break;
+ case spv::CapabilityCullDistance: capabilities.CullDistance = true; break;
+ case spv::CapabilityInputAttachment: capabilities.InputAttachment = true; break;
+ case spv::CapabilitySampled1D: capabilities.Sampled1D = true; break;
+ case spv::CapabilityImage1D: capabilities.Image1D = true; break;
+ case spv::CapabilityImageCubeArray: capabilities.ImageCubeArray = true; break;
+ case spv::CapabilitySampledBuffer: capabilities.SampledBuffer = true; break;
+ case spv::CapabilitySampledCubeArray: capabilities.SampledCubeArray = true; break;
+ case spv::CapabilityImageBuffer: capabilities.ImageBuffer = true; break;
+ case spv::CapabilityStorageImageExtendedFormats: capabilities.StorageImageExtendedFormats = true; break;
+ case spv::CapabilityImageQuery: capabilities.ImageQuery = true; break;
+ case spv::CapabilityDerivativeControl: capabilities.DerivativeControl = true; break;
+ case spv::CapabilityGroupNonUniform: capabilities.GroupNonUniform = true; break;
+ case spv::CapabilityGroupNonUniformVote: capabilities.GroupNonUniformVote = true; break;
+ case spv::CapabilityGroupNonUniformArithmetic: capabilities.GroupNonUniformArithmetic = true; break;
+ case spv::CapabilityGroupNonUniformBallot: capabilities.GroupNonUniformBallot = true; break;
+ case spv::CapabilityGroupNonUniformShuffle: capabilities.GroupNonUniformShuffle = true; break;
+ case spv::CapabilityGroupNonUniformShuffleRelative: capabilities.GroupNonUniformShuffleRelative = true; break;
+ case spv::CapabilityDeviceGroup: capabilities.DeviceGroup = true; break;
+ case spv::CapabilityMultiView: capabilities.MultiView = true; break;
+ default:
+ UNSUPPORTED("Unsupported capability %u", insn.word(1));
+ }
+ break; // Various capabilities will be declared, but none affect our code generation at this point.
+ }
- case spv::OpFunctionCall:
- // TODO(b/141246700): Add full support for spv::OpFunctionCall
- break;
+ case spv::OpMemoryModel:
+ break; // Memory model does not affect our code generation until we decide to do Vulkan Memory Model support.
- case spv::OpFConvert:
- UNSUPPORTED("SPIR-V Float16 or Float64 Capability (OpFConvert)");
- break;
+ case spv::OpFunction:
+ {
+ auto functionId = Function::ID(insn.word(2));
+ ASSERT_MSG(currentFunction == 0, "Functions %d and %d overlap", currentFunction.value(), functionId.value());
+ currentFunction = functionId;
+ auto &function = functions[functionId];
+ function.result = Type::ID(insn.word(1));
+ function.type = Type::ID(insn.word(4));
+ // Scan forward to find the function's label.
+ for(auto it = insn; it != end() && function.entry == 0; it++)
+ {
+ switch(it.opcode())
+ {
+ case spv::OpFunction:
+ case spv::OpFunctionParameter:
+ break;
+ case spv::OpLabel:
+ function.entry = Block::ID(it.word(1));
+ break;
+ default:
+ WARN("Unexpected opcode '%s' following OpFunction", OpcodeName(it.opcode()).c_str());
+ }
+ }
+ ASSERT_MSG(function.entry != 0, "Function<%d> has no label", currentFunction.value());
+ break;
+ }
- case spv::OpSConvert:
- UNSUPPORTED("SPIR-V Int16 or Int64 Capability (OpSConvert)");
- break;
+ case spv::OpFunctionEnd:
+ currentFunction = 0;
+ break;
- case spv::OpUConvert:
- UNSUPPORTED("SPIR-V Int16 or Int64 Capability (OpUConvert)");
- break;
+ case spv::OpExtInstImport:
+ {
+ // We will only support the GLSL 450 extended instruction set, so no point in tracking the ID we assign it.
+ // Valid shaders will not attempt to import any other instruction sets.
+ auto ext = insn.string(2);
+ if(0 != strcmp("GLSL.std.450", ext))
+ {
+ UNSUPPORTED("SPIR-V Extension: %s", ext);
+ }
+ break;
+ }
+ case spv::OpName:
+ case spv::OpMemberName:
+ case spv::OpSource:
+ case spv::OpSourceContinued:
+ case spv::OpSourceExtension:
+ case spv::OpLine:
+ case spv::OpNoLine:
+ case spv::OpModuleProcessed:
+ case spv::OpString:
+ // No semantic impact
+ break;
- case spv::OpLoad:
- case spv::OpAccessChain:
- case spv::OpInBoundsAccessChain:
- case spv::OpSampledImage:
- case spv::OpImage:
+ case spv::OpFunctionParameter:
+ // These should have all been removed by preprocessing passes. If we see them here,
+ // our assumptions are wrong and we will probably generate wrong code.
+ UNREACHABLE("%s should have already been lowered.", OpcodeName(opcode).c_str());
+ break;
+
+ case spv::OpFunctionCall:
+ // TODO(b/141246700): Add full support for spv::OpFunctionCall
+ break;
+
+ case spv::OpFConvert:
+ UNSUPPORTED("SPIR-V Float16 or Float64 Capability (OpFConvert)");
+ break;
+
+ case spv::OpSConvert:
+ UNSUPPORTED("SPIR-V Int16 or Int64 Capability (OpSConvert)");
+ break;
+
+ case spv::OpUConvert:
+ UNSUPPORTED("SPIR-V Int16 or Int64 Capability (OpUConvert)");
+ break;
+
+ case spv::OpLoad:
+ case spv::OpAccessChain:
+ case spv::OpInBoundsAccessChain:
+ case spv::OpSampledImage:
+ case spv::OpImage:
{
// Propagate the descriptor decorations to the result.
Object::ID resultId = insn.word(2);
@@ -484,202 +487,202 @@
}
break;
- case spv::OpCompositeConstruct:
- case spv::OpCompositeInsert:
- case spv::OpCompositeExtract:
- case spv::OpVectorShuffle:
- case spv::OpVectorTimesScalar:
- case spv::OpMatrixTimesScalar:
- case spv::OpMatrixTimesVector:
- case spv::OpVectorTimesMatrix:
- case spv::OpMatrixTimesMatrix:
- case spv::OpOuterProduct:
- case spv::OpTranspose:
- case spv::OpVectorExtractDynamic:
- case spv::OpVectorInsertDynamic:
- // Unary ops
- case spv::OpNot:
- case spv::OpBitFieldInsert:
- case spv::OpBitFieldSExtract:
- case spv::OpBitFieldUExtract:
- case spv::OpBitReverse:
- case spv::OpBitCount:
- case spv::OpSNegate:
- case spv::OpFNegate:
- case spv::OpLogicalNot:
- case spv::OpQuantizeToF16:
- // Binary ops
- case spv::OpIAdd:
- case spv::OpISub:
- case spv::OpIMul:
- case spv::OpSDiv:
- case spv::OpUDiv:
- case spv::OpFAdd:
- case spv::OpFSub:
- case spv::OpFMul:
- case spv::OpFDiv:
- case spv::OpFMod:
- case spv::OpFRem:
- case spv::OpFOrdEqual:
- case spv::OpFUnordEqual:
- case spv::OpFOrdNotEqual:
- case spv::OpFUnordNotEqual:
- case spv::OpFOrdLessThan:
- case spv::OpFUnordLessThan:
- case spv::OpFOrdGreaterThan:
- case spv::OpFUnordGreaterThan:
- case spv::OpFOrdLessThanEqual:
- case spv::OpFUnordLessThanEqual:
- case spv::OpFOrdGreaterThanEqual:
- case spv::OpFUnordGreaterThanEqual:
- case spv::OpSMod:
- case spv::OpSRem:
- case spv::OpUMod:
- case spv::OpIEqual:
- case spv::OpINotEqual:
- case spv::OpUGreaterThan:
- case spv::OpSGreaterThan:
- case spv::OpUGreaterThanEqual:
- case spv::OpSGreaterThanEqual:
- case spv::OpULessThan:
- case spv::OpSLessThan:
- case spv::OpULessThanEqual:
- case spv::OpSLessThanEqual:
- case spv::OpShiftRightLogical:
- case spv::OpShiftRightArithmetic:
- case spv::OpShiftLeftLogical:
- case spv::OpBitwiseOr:
- case spv::OpBitwiseXor:
- case spv::OpBitwiseAnd:
- case spv::OpLogicalOr:
- case spv::OpLogicalAnd:
- case spv::OpLogicalEqual:
- case spv::OpLogicalNotEqual:
- case spv::OpUMulExtended:
- case spv::OpSMulExtended:
- case spv::OpIAddCarry:
- case spv::OpISubBorrow:
- case spv::OpDot:
- case spv::OpConvertFToU:
- case spv::OpConvertFToS:
- case spv::OpConvertSToF:
- case spv::OpConvertUToF:
- case spv::OpBitcast:
- case spv::OpSelect:
- case spv::OpExtInst:
- case spv::OpIsInf:
- case spv::OpIsNan:
- case spv::OpAny:
- case spv::OpAll:
- case spv::OpDPdx:
- case spv::OpDPdxCoarse:
- case spv::OpDPdy:
- case spv::OpDPdyCoarse:
- case spv::OpFwidth:
- case spv::OpFwidthCoarse:
- case spv::OpDPdxFine:
- case spv::OpDPdyFine:
- case spv::OpFwidthFine:
- case spv::OpAtomicLoad:
- case spv::OpAtomicIAdd:
- case spv::OpAtomicISub:
- case spv::OpAtomicSMin:
- case spv::OpAtomicSMax:
- case spv::OpAtomicUMin:
- case spv::OpAtomicUMax:
- case spv::OpAtomicAnd:
- case spv::OpAtomicOr:
- case spv::OpAtomicXor:
- case spv::OpAtomicIIncrement:
- case spv::OpAtomicIDecrement:
- case spv::OpAtomicExchange:
- case spv::OpAtomicCompareExchange:
- case spv::OpPhi:
- case spv::OpImageSampleImplicitLod:
- case spv::OpImageSampleExplicitLod:
- case spv::OpImageSampleDrefImplicitLod:
- case spv::OpImageSampleDrefExplicitLod:
- case spv::OpImageSampleProjImplicitLod:
- case spv::OpImageSampleProjExplicitLod:
- case spv::OpImageSampleProjDrefImplicitLod:
- case spv::OpImageSampleProjDrefExplicitLod:
- case spv::OpImageGather:
- case spv::OpImageDrefGather:
- case spv::OpImageFetch:
- case spv::OpImageQuerySizeLod:
- case spv::OpImageQuerySize:
- case spv::OpImageQueryLod:
- case spv::OpImageQueryLevels:
- case spv::OpImageQuerySamples:
- case spv::OpImageRead:
- case spv::OpImageTexelPointer:
- case spv::OpGroupNonUniformElect:
- case spv::OpGroupNonUniformAll:
- case spv::OpGroupNonUniformAny:
- case spv::OpGroupNonUniformAllEqual:
- case spv::OpGroupNonUniformBroadcast:
- case spv::OpGroupNonUniformBroadcastFirst:
- case spv::OpGroupNonUniformBallot:
- case spv::OpGroupNonUniformInverseBallot:
- case spv::OpGroupNonUniformBallotBitExtract:
- case spv::OpGroupNonUniformBallotBitCount:
- case spv::OpGroupNonUniformBallotFindLSB:
- case spv::OpGroupNonUniformBallotFindMSB:
- case spv::OpGroupNonUniformShuffle:
- case spv::OpGroupNonUniformShuffleXor:
- case spv::OpGroupNonUniformShuffleUp:
- case spv::OpGroupNonUniformShuffleDown:
- case spv::OpGroupNonUniformIAdd:
- case spv::OpGroupNonUniformFAdd:
- case spv::OpGroupNonUniformIMul:
- case spv::OpGroupNonUniformFMul:
- case spv::OpGroupNonUniformSMin:
- case spv::OpGroupNonUniformUMin:
- case spv::OpGroupNonUniformFMin:
- case spv::OpGroupNonUniformSMax:
- case spv::OpGroupNonUniformUMax:
- case spv::OpGroupNonUniformFMax:
- case spv::OpGroupNonUniformBitwiseAnd:
- case spv::OpGroupNonUniformBitwiseOr:
- case spv::OpGroupNonUniformBitwiseXor:
- case spv::OpGroupNonUniformLogicalAnd:
- case spv::OpGroupNonUniformLogicalOr:
- case spv::OpGroupNonUniformLogicalXor:
- case spv::OpCopyObject:
- case spv::OpArrayLength:
- // Instructions that yield an intermediate value or divergent pointer
- DefineResult(insn);
- break;
+ case spv::OpCompositeConstruct:
+ case spv::OpCompositeInsert:
+ case spv::OpCompositeExtract:
+ case spv::OpVectorShuffle:
+ case spv::OpVectorTimesScalar:
+ case spv::OpMatrixTimesScalar:
+ case spv::OpMatrixTimesVector:
+ case spv::OpVectorTimesMatrix:
+ case spv::OpMatrixTimesMatrix:
+ case spv::OpOuterProduct:
+ case spv::OpTranspose:
+ case spv::OpVectorExtractDynamic:
+ case spv::OpVectorInsertDynamic:
+ // Unary ops
+ case spv::OpNot:
+ case spv::OpBitFieldInsert:
+ case spv::OpBitFieldSExtract:
+ case spv::OpBitFieldUExtract:
+ case spv::OpBitReverse:
+ case spv::OpBitCount:
+ case spv::OpSNegate:
+ case spv::OpFNegate:
+ case spv::OpLogicalNot:
+ case spv::OpQuantizeToF16:
+ // Binary ops
+ case spv::OpIAdd:
+ case spv::OpISub:
+ case spv::OpIMul:
+ case spv::OpSDiv:
+ case spv::OpUDiv:
+ case spv::OpFAdd:
+ case spv::OpFSub:
+ case spv::OpFMul:
+ case spv::OpFDiv:
+ case spv::OpFMod:
+ case spv::OpFRem:
+ case spv::OpFOrdEqual:
+ case spv::OpFUnordEqual:
+ case spv::OpFOrdNotEqual:
+ case spv::OpFUnordNotEqual:
+ case spv::OpFOrdLessThan:
+ case spv::OpFUnordLessThan:
+ case spv::OpFOrdGreaterThan:
+ case spv::OpFUnordGreaterThan:
+ case spv::OpFOrdLessThanEqual:
+ case spv::OpFUnordLessThanEqual:
+ case spv::OpFOrdGreaterThanEqual:
+ case spv::OpFUnordGreaterThanEqual:
+ case spv::OpSMod:
+ case spv::OpSRem:
+ case spv::OpUMod:
+ case spv::OpIEqual:
+ case spv::OpINotEqual:
+ case spv::OpUGreaterThan:
+ case spv::OpSGreaterThan:
+ case spv::OpUGreaterThanEqual:
+ case spv::OpSGreaterThanEqual:
+ case spv::OpULessThan:
+ case spv::OpSLessThan:
+ case spv::OpULessThanEqual:
+ case spv::OpSLessThanEqual:
+ case spv::OpShiftRightLogical:
+ case spv::OpShiftRightArithmetic:
+ case spv::OpShiftLeftLogical:
+ case spv::OpBitwiseOr:
+ case spv::OpBitwiseXor:
+ case spv::OpBitwiseAnd:
+ case spv::OpLogicalOr:
+ case spv::OpLogicalAnd:
+ case spv::OpLogicalEqual:
+ case spv::OpLogicalNotEqual:
+ case spv::OpUMulExtended:
+ case spv::OpSMulExtended:
+ case spv::OpIAddCarry:
+ case spv::OpISubBorrow:
+ case spv::OpDot:
+ case spv::OpConvertFToU:
+ case spv::OpConvertFToS:
+ case spv::OpConvertSToF:
+ case spv::OpConvertUToF:
+ case spv::OpBitcast:
+ case spv::OpSelect:
+ case spv::OpExtInst:
+ case spv::OpIsInf:
+ case spv::OpIsNan:
+ case spv::OpAny:
+ case spv::OpAll:
+ case spv::OpDPdx:
+ case spv::OpDPdxCoarse:
+ case spv::OpDPdy:
+ case spv::OpDPdyCoarse:
+ case spv::OpFwidth:
+ case spv::OpFwidthCoarse:
+ case spv::OpDPdxFine:
+ case spv::OpDPdyFine:
+ case spv::OpFwidthFine:
+ case spv::OpAtomicLoad:
+ case spv::OpAtomicIAdd:
+ case spv::OpAtomicISub:
+ case spv::OpAtomicSMin:
+ case spv::OpAtomicSMax:
+ case spv::OpAtomicUMin:
+ case spv::OpAtomicUMax:
+ case spv::OpAtomicAnd:
+ case spv::OpAtomicOr:
+ case spv::OpAtomicXor:
+ case spv::OpAtomicIIncrement:
+ case spv::OpAtomicIDecrement:
+ case spv::OpAtomicExchange:
+ case spv::OpAtomicCompareExchange:
+ case spv::OpPhi:
+ case spv::OpImageSampleImplicitLod:
+ case spv::OpImageSampleExplicitLod:
+ case spv::OpImageSampleDrefImplicitLod:
+ case spv::OpImageSampleDrefExplicitLod:
+ case spv::OpImageSampleProjImplicitLod:
+ case spv::OpImageSampleProjExplicitLod:
+ case spv::OpImageSampleProjDrefImplicitLod:
+ case spv::OpImageSampleProjDrefExplicitLod:
+ case spv::OpImageGather:
+ case spv::OpImageDrefGather:
+ case spv::OpImageFetch:
+ case spv::OpImageQuerySizeLod:
+ case spv::OpImageQuerySize:
+ case spv::OpImageQueryLod:
+ case spv::OpImageQueryLevels:
+ case spv::OpImageQuerySamples:
+ case spv::OpImageRead:
+ case spv::OpImageTexelPointer:
+ case spv::OpGroupNonUniformElect:
+ case spv::OpGroupNonUniformAll:
+ case spv::OpGroupNonUniformAny:
+ case spv::OpGroupNonUniformAllEqual:
+ case spv::OpGroupNonUniformBroadcast:
+ case spv::OpGroupNonUniformBroadcastFirst:
+ case spv::OpGroupNonUniformBallot:
+ case spv::OpGroupNonUniformInverseBallot:
+ case spv::OpGroupNonUniformBallotBitExtract:
+ case spv::OpGroupNonUniformBallotBitCount:
+ case spv::OpGroupNonUniformBallotFindLSB:
+ case spv::OpGroupNonUniformBallotFindMSB:
+ case spv::OpGroupNonUniformShuffle:
+ case spv::OpGroupNonUniformShuffleXor:
+ case spv::OpGroupNonUniformShuffleUp:
+ case spv::OpGroupNonUniformShuffleDown:
+ case spv::OpGroupNonUniformIAdd:
+ case spv::OpGroupNonUniformFAdd:
+ case spv::OpGroupNonUniformIMul:
+ case spv::OpGroupNonUniformFMul:
+ case spv::OpGroupNonUniformSMin:
+ case spv::OpGroupNonUniformUMin:
+ case spv::OpGroupNonUniformFMin:
+ case spv::OpGroupNonUniformSMax:
+ case spv::OpGroupNonUniformUMax:
+ case spv::OpGroupNonUniformFMax:
+ case spv::OpGroupNonUniformBitwiseAnd:
+ case spv::OpGroupNonUniformBitwiseOr:
+ case spv::OpGroupNonUniformBitwiseXor:
+ case spv::OpGroupNonUniformLogicalAnd:
+ case spv::OpGroupNonUniformLogicalOr:
+ case spv::OpGroupNonUniformLogicalXor:
+ case spv::OpCopyObject:
+ case spv::OpArrayLength:
+ // Instructions that yield an intermediate value or divergent pointer
+ DefineResult(insn);
+ break;
- case spv::OpStore:
- case spv::OpAtomicStore:
- case spv::OpImageWrite:
- case spv::OpCopyMemory:
- case spv::OpMemoryBarrier:
- // Don't need to do anything during analysis pass
- break;
+ case spv::OpStore:
+ case spv::OpAtomicStore:
+ case spv::OpImageWrite:
+ case spv::OpCopyMemory:
+ case spv::OpMemoryBarrier:
+ // Don't need to do anything during analysis pass
+ break;
- case spv::OpControlBarrier:
- modes.ContainsControlBarriers = true;
- break;
+ case spv::OpControlBarrier:
+ modes.ContainsControlBarriers = true;
+ break;
- case spv::OpExtension:
- {
- auto ext = insn.string(1);
- // Part of core SPIR-V 1.3. Vulkan 1.1 implementations must also accept the pre-1.3
- // extension per Appendix A, `Vulkan Environment for SPIR-V`.
- if(!strcmp(ext, "SPV_KHR_storage_buffer_storage_class")) break;
- if(!strcmp(ext, "SPV_KHR_shader_draw_parameters")) break;
- if(!strcmp(ext, "SPV_KHR_16bit_storage")) break;
- if(!strcmp(ext, "SPV_KHR_variable_pointers")) break;
- if(!strcmp(ext, "SPV_KHR_device_group")) break;
- if(!strcmp(ext, "SPV_KHR_multiview")) break;
- UNSUPPORTED("SPIR-V Extension: %s", ext);
- break;
- }
+ case spv::OpExtension:
+ {
+ auto ext = insn.string(1);
+ // Part of core SPIR-V 1.3. Vulkan 1.1 implementations must also accept the pre-1.3
+ // extension per Appendix A, `Vulkan Environment for SPIR-V`.
+ if(!strcmp(ext, "SPV_KHR_storage_buffer_storage_class")) break;
+ if(!strcmp(ext, "SPV_KHR_shader_draw_parameters")) break;
+ if(!strcmp(ext, "SPV_KHR_16bit_storage")) break;
+ if(!strcmp(ext, "SPV_KHR_variable_pointers")) break;
+ if(!strcmp(ext, "SPV_KHR_device_group")) break;
+ if(!strcmp(ext, "SPV_KHR_multiview")) break;
+ UNSUPPORTED("SPIR-V Extension: %s", ext);
+ break;
+ }
- default:
- UNIMPLEMENTED("%s", OpcodeName(opcode).c_str());
+ default:
+ UNIMPLEMENTED("%s", OpcodeName(opcode).c_str());
}
}
@@ -702,45 +705,45 @@
// member. All members of such a structure are builtins.
switch(insn.opcode())
{
- case spv::OpTypeStruct:
- {
- auto d = memberDecorations.find(resultId);
- if(d != memberDecorations.end())
+ case spv::OpTypeStruct:
{
- for(auto &m : d->second)
+ auto d = memberDecorations.find(resultId);
+ if(d != memberDecorations.end())
{
- if(m.HasBuiltIn)
+ for(auto &m : d->second)
{
- type.isBuiltInBlock = true;
- break;
+ if(m.HasBuiltIn)
+ {
+ type.isBuiltInBlock = true;
+ break;
+ }
}
}
+ break;
}
- break;
- }
- case spv::OpTypePointer:
- {
- Type::ID elementTypeId = insn.word(3);
- type.element = elementTypeId;
- type.isBuiltInBlock = getType(elementTypeId).isBuiltInBlock;
- type.storageClass = static_cast<spv::StorageClass>(insn.word(2));
- break;
- }
- case spv::OpTypeVector:
- case spv::OpTypeMatrix:
- case spv::OpTypeArray:
- case spv::OpTypeRuntimeArray:
- {
- Type::ID elementTypeId = insn.word(2);
- type.element = elementTypeId;
- break;
- }
- default:
- break;
+ case spv::OpTypePointer:
+ {
+ Type::ID elementTypeId = insn.word(3);
+ type.element = elementTypeId;
+ type.isBuiltInBlock = getType(elementTypeId).isBuiltInBlock;
+ type.storageClass = static_cast<spv::StorageClass>(insn.word(2));
+ break;
+ }
+ case spv::OpTypeVector:
+ case spv::OpTypeMatrix:
+ case spv::OpTypeArray:
+ case spv::OpTypeRuntimeArray:
+ {
+ Type::ID elementTypeId = insn.word(2);
+ type.element = elementTypeId;
+ break;
+ }
+ default:
+ break;
}
}
-SpirvShader::Object& SpirvShader::CreateConstant(InsnIterator insn)
+SpirvShader::Object &SpirvShader::CreateConstant(InsnIterator insn)
{
Type::ID typeId = insn.word(1);
Object::ID resultId = insn.word(2);
@@ -771,7 +774,7 @@
{
// walk the builtin block, registering each of its members separately.
auto m = memberDecorations.find(objectTy.element);
- ASSERT(m != memberDecorations.end()); // otherwise we wouldn't have marked the type chain
+ ASSERT(m != memberDecorations.end()); // otherwise we wouldn't have marked the type chain
auto &structType = pointeeTy.definition;
auto offset = 0u;
auto word = 2u;
@@ -781,7 +784,7 @@
if(member.HasBuiltIn)
{
- builtinInterface[member.BuiltIn] = {resultId, offset, memberType.sizeInComponents};
+ builtinInterface[member.BuiltIn] = { resultId, offset, memberType.sizeInComponents };
}
offset += memberType.sizeInComponents;
@@ -793,24 +796,24 @@
auto d = decorations.find(resultId);
if(d != decorations.end() && d->second.HasBuiltIn)
{
- builtinInterface[d->second.BuiltIn] = {resultId, 0, pointeeTy.sizeInComponents};
+ builtinInterface[d->second.BuiltIn] = { resultId, 0, pointeeTy.sizeInComponents };
}
else
{
object.kind = Object::Kind::InterfaceVariable;
VisitInterface(resultId,
- [&userDefinedInterface](Decorations const &d, AttribType type) {
- // Populate a single scalar slot in the interface from a collection of decorations and the intended component type.
- auto scalarSlot = (d.Location << 2) | d.Component;
- ASSERT(scalarSlot >= 0 &&
- scalarSlot < static_cast<int32_t>(userDefinedInterface.size()));
+ [&userDefinedInterface](Decorations const &d, AttribType type) {
+ // Populate a single scalar slot in the interface from a collection of decorations and the intended component type.
+ auto scalarSlot = (d.Location << 2) | d.Component;
+ ASSERT(scalarSlot >= 0 &&
+ scalarSlot < static_cast<int32_t>(userDefinedInterface.size()));
- auto &slot = userDefinedInterface[scalarSlot];
- slot.Type = type;
- slot.Flat = d.Flat;
- slot.NoPerspective = d.NoPerspective;
- slot.Centroid = d.Centroid;
- });
+ auto &slot = userDefinedInterface[scalarSlot];
+ slot.Type = type;
+ slot.Flat = d.Flat;
+ slot.NoPerspective = d.NoPerspective;
+ slot.Centroid = d.Centroid;
+ });
}
}
@@ -819,31 +822,31 @@
auto mode = static_cast<spv::ExecutionMode>(insn.word(2));
switch(mode)
{
- case spv::ExecutionModeEarlyFragmentTests:
- modes.EarlyFragmentTests = true;
- break;
- case spv::ExecutionModeDepthReplacing:
- modes.DepthReplacing = true;
- break;
- case spv::ExecutionModeDepthGreater:
- modes.DepthGreater = true;
- break;
- case spv::ExecutionModeDepthLess:
- modes.DepthLess = true;
- break;
- case spv::ExecutionModeDepthUnchanged:
- modes.DepthUnchanged = true;
- break;
- case spv::ExecutionModeLocalSize:
- modes.WorkgroupSizeX = insn.word(3);
- modes.WorkgroupSizeY = insn.word(4);
- modes.WorkgroupSizeZ = insn.word(5);
- break;
- case spv::ExecutionModeOriginUpperLeft:
- // This is always the case for a Vulkan shader. Do nothing.
- break;
- default:
- UNREACHABLE("Execution mode: %d", int(mode));
+ case spv::ExecutionModeEarlyFragmentTests:
+ modes.EarlyFragmentTests = true;
+ break;
+ case spv::ExecutionModeDepthReplacing:
+ modes.DepthReplacing = true;
+ break;
+ case spv::ExecutionModeDepthGreater:
+ modes.DepthGreater = true;
+ break;
+ case spv::ExecutionModeDepthLess:
+ modes.DepthLess = true;
+ break;
+ case spv::ExecutionModeDepthUnchanged:
+ modes.DepthUnchanged = true;
+ break;
+ case spv::ExecutionModeLocalSize:
+ modes.WorkgroupSizeX = insn.word(3);
+ modes.WorkgroupSizeY = insn.word(4);
+ modes.WorkgroupSizeZ = insn.word(5);
+ break;
+ case spv::ExecutionModeOriginUpperLeft:
+ // This is always the case for a Vulkan shader. Do nothing.
+ break;
+ default:
+ UNREACHABLE("Execution mode: %d", int(mode));
}
}
@@ -854,54 +857,54 @@
// already been described (and so their sizes determined)
switch(insn.opcode())
{
- case spv::OpTypeVoid:
- case spv::OpTypeSampler:
- case spv::OpTypeImage:
- case spv::OpTypeSampledImage:
- case spv::OpTypeFunction:
- case spv::OpTypeRuntimeArray:
- // Objects that don't consume any space.
- // Descriptor-backed objects currently only need exist at compile-time.
- // Runtime arrays don't appear in places where their size would be interesting
- return 0;
+ case spv::OpTypeVoid:
+ case spv::OpTypeSampler:
+ case spv::OpTypeImage:
+ case spv::OpTypeSampledImage:
+ case spv::OpTypeFunction:
+ case spv::OpTypeRuntimeArray:
+ // Objects that don't consume any space.
+ // Descriptor-backed objects currently only need exist at compile-time.
+ // Runtime arrays don't appear in places where their size would be interesting
+ return 0;
- case spv::OpTypeBool:
- case spv::OpTypeFloat:
- case spv::OpTypeInt:
- // All the fundamental types are 1 component. If we ever add support for 8/16/64-bit components,
- // we might need to change this, but only 32 bit components are required for Vulkan 1.1.
- return 1;
+ case spv::OpTypeBool:
+ case spv::OpTypeFloat:
+ case spv::OpTypeInt:
+ // All the fundamental types are 1 component. If we ever add support for 8/16/64-bit components,
+ // we might need to change this, but only 32 bit components are required for Vulkan 1.1.
+ return 1;
- case spv::OpTypeVector:
- case spv::OpTypeMatrix:
- // Vectors and matrices both consume element count * element size.
- return getType(insn.word(2)).sizeInComponents * insn.word(3);
+ case spv::OpTypeVector:
+ case spv::OpTypeMatrix:
+ // Vectors and matrices both consume element count * element size.
+ return getType(insn.word(2)).sizeInComponents * insn.word(3);
- case spv::OpTypeArray:
- {
- // Element count * element size. Array sizes come from constant ids.
- auto arraySize = GetConstScalarInt(insn.word(3));
- return getType(insn.word(2)).sizeInComponents * arraySize;
- }
-
- case spv::OpTypeStruct:
- {
- uint32_t size = 0;
- for(uint32_t i = 2u; i < insn.wordCount(); i++)
+ case spv::OpTypeArray:
{
- size += getType(insn.word(i)).sizeInComponents;
+ // Element count * element size. Array sizes come from constant ids.
+ auto arraySize = GetConstScalarInt(insn.word(3));
+ return getType(insn.word(2)).sizeInComponents * arraySize;
}
- return size;
- }
- case spv::OpTypePointer:
- // Runtime representation of a pointer is a per-lane index.
- // Note: clients are expected to look through the pointer if they want the pointee size instead.
- return 1;
+ case spv::OpTypeStruct:
+ {
+ uint32_t size = 0;
+ for(uint32_t i = 2u; i < insn.wordCount(); i++)
+ {
+ size += getType(insn.word(i)).sizeInComponents;
+ }
+ return size;
+ }
- default:
- UNREACHABLE("%s", OpcodeName(insn.opcode()).c_str());
- return 0;
+ case spv::OpTypePointer:
+ // Runtime representation of a pointer is a per-lane index.
+ // Note: clients are expected to look through the pointer if they want the pointee size instead.
+ return 1;
+
+ default:
+ UNREACHABLE("%s", OpcodeName(insn.opcode()).c_str());
+ return 0;
}
}
@@ -924,54 +927,54 @@
auto const &obj = getType(id);
switch(obj.opcode())
{
- case spv::OpTypePointer:
- return VisitInterfaceInner(obj.definition.word(3), d, f);
- case spv::OpTypeMatrix:
- for(auto i = 0u; i < obj.definition.word(3); i++, d.Location++)
+ case spv::OpTypePointer:
+ return VisitInterfaceInner(obj.definition.word(3), d, f);
+ case spv::OpTypeMatrix:
+ for(auto i = 0u; i < obj.definition.word(3); i++, d.Location++)
+ {
+ // consumes same components of N consecutive locations
+ VisitInterfaceInner(obj.definition.word(2), d, f);
+ }
+ return d.Location;
+ case spv::OpTypeVector:
+ for(auto i = 0u; i < obj.definition.word(3); i++, d.Component++)
+ {
+ // consumes N consecutive components in the same location
+ VisitInterfaceInner(obj.definition.word(2), d, f);
+ }
+ return d.Location + 1;
+ case spv::OpTypeFloat:
+ f(d, ATTRIBTYPE_FLOAT);
+ return d.Location + 1;
+ case spv::OpTypeInt:
+ f(d, obj.definition.word(3) ? ATTRIBTYPE_INT : ATTRIBTYPE_UINT);
+ return d.Location + 1;
+ case spv::OpTypeBool:
+ f(d, ATTRIBTYPE_UINT);
+ return d.Location + 1;
+ case spv::OpTypeStruct:
{
- // consumes same components of N consecutive locations
- VisitInterfaceInner(obj.definition.word(2), d, f);
+ // iterate over members, which may themselves have Location/Component decorations
+ for(auto i = 0u; i < obj.definition.wordCount() - 2; i++)
+ {
+ ApplyDecorationsForIdMember(&d, id, i);
+ d.Location = VisitInterfaceInner(obj.definition.word(i + 2), d, f);
+ d.Component = 0; // Implicit locations always have component=0
+ }
+ return d.Location;
}
- return d.Location;
- case spv::OpTypeVector:
- for(auto i = 0u; i < obj.definition.word(3); i++, d.Component++)
+ case spv::OpTypeArray:
{
- // consumes N consecutive components in the same location
- VisitInterfaceInner(obj.definition.word(2), d, f);
+ auto arraySize = GetConstScalarInt(obj.definition.word(3));
+ for(auto i = 0u; i < arraySize; i++)
+ {
+ d.Location = VisitInterfaceInner(obj.definition.word(2), d, f);
+ }
+ return d.Location;
}
- return d.Location + 1;
- case spv::OpTypeFloat:
- f(d, ATTRIBTYPE_FLOAT);
- return d.Location + 1;
- case spv::OpTypeInt:
- f(d, obj.definition.word(3) ? ATTRIBTYPE_INT : ATTRIBTYPE_UINT);
- return d.Location + 1;
- case spv::OpTypeBool:
- f(d, ATTRIBTYPE_UINT);
- return d.Location + 1;
- case spv::OpTypeStruct:
- {
- // iterate over members, which may themselves have Location/Component decorations
- for(auto i = 0u; i < obj.definition.wordCount() - 2; i++)
- {
- ApplyDecorationsForIdMember(&d, id, i);
- d.Location = VisitInterfaceInner(obj.definition.word(i + 2), d, f);
- d.Component = 0; // Implicit locations always have component=0
- }
- return d.Location;
- }
- case spv::OpTypeArray:
- {
- auto arraySize = GetConstScalarInt(obj.definition.word(3));
- for(auto i = 0u; i < arraySize; i++)
- {
- d.Location = VisitInterfaceInner(obj.definition.word(2), d, f);
- }
- return d.Location;
- }
- default:
- // Intentionally partial; most opcodes do not participate in type hierarchies
- return 0;
+ default:
+ // Intentionally partial; most opcodes do not participate in type hierarchies
+ return 0;
}
}
@@ -996,33 +999,33 @@
for(auto i = 0u; i < numIndexes; i++)
{
ApplyDecorationsForId(d, typeId);
- auto & type = getType(typeId);
+ auto &type = getType(typeId);
switch(type.opcode())
{
- case spv::OpTypeStruct:
- {
- int memberIndex = GetConstScalarInt(indexIds[i]);
- ApplyDecorationsForIdMember(d, typeId, memberIndex);
- typeId = type.definition.word(2u + memberIndex);
- break;
- }
- case spv::OpTypeArray:
- case spv::OpTypeRuntimeArray:
- if(dd->InputAttachmentIndex >= 0)
+ case spv::OpTypeStruct:
{
- dd->InputAttachmentIndex += GetConstScalarInt(indexIds[i]);
+ int memberIndex = GetConstScalarInt(indexIds[i]);
+ ApplyDecorationsForIdMember(d, typeId, memberIndex);
+ typeId = type.definition.word(2u + memberIndex);
+ break;
}
- typeId = type.element;
- break;
- case spv::OpTypeVector:
- typeId = type.element;
- break;
- case spv::OpTypeMatrix:
- typeId = type.element;
- d->InsideMatrix = true;
- break;
- default:
- UNREACHABLE("%s", OpcodeName(type.definition.opcode()).c_str());
+ case spv::OpTypeArray:
+ case spv::OpTypeRuntimeArray:
+ if(dd->InputAttachmentIndex >= 0)
+ {
+ dd->InputAttachmentIndex += GetConstScalarInt(indexIds[i]);
+ }
+ typeId = type.element;
+ break;
+ case spv::OpTypeVector:
+ typeId = type.element;
+ break;
+ case spv::OpTypeMatrix:
+ typeId = type.element;
+ d->InsideMatrix = true;
+ break;
+ default:
+ UNREACHABLE("%s", OpcodeName(type.definition.opcode()).c_str());
}
}
}
@@ -1057,72 +1060,72 @@
for(auto i = 0u; i < numIndexes; i++)
{
- auto & type = getType(typeId);
+ auto &type = getType(typeId);
ApplyDecorationsForId(&d, typeId);
switch(type.definition.opcode())
{
- case spv::OpTypeStruct:
- {
- int memberIndex = GetConstScalarInt(indexIds[i]);
- ApplyDecorationsForIdMember(&d, typeId, memberIndex);
- ASSERT(d.HasOffset);
- constantOffset += d.Offset;
- typeId = type.definition.word(2u + memberIndex);
- break;
- }
- case spv::OpTypeArray:
- case spv::OpTypeRuntimeArray:
- {
- // TODO: b/127950082: Check bounds.
- ASSERT(d.HasArrayStride);
- auto & obj = getObject(indexIds[i]);
- if(obj.kind == Object::Kind::Constant)
+ case spv::OpTypeStruct:
{
- constantOffset += d.ArrayStride * GetConstScalarInt(indexIds[i]);
+ int memberIndex = GetConstScalarInt(indexIds[i]);
+ ApplyDecorationsForIdMember(&d, typeId, memberIndex);
+ ASSERT(d.HasOffset);
+ constantOffset += d.Offset;
+ typeId = type.definition.word(2u + memberIndex);
+ break;
}
- else
+ case spv::OpTypeArray:
+ case spv::OpTypeRuntimeArray:
{
- ptr += SIMD::Int(d.ArrayStride) * state->getIntermediate(indexIds[i]).Int(0);
+ // TODO: b/127950082: Check bounds.
+ ASSERT(d.HasArrayStride);
+ auto &obj = getObject(indexIds[i]);
+ if(obj.kind == Object::Kind::Constant)
+ {
+ constantOffset += d.ArrayStride * GetConstScalarInt(indexIds[i]);
+ }
+ else
+ {
+ ptr += SIMD::Int(d.ArrayStride) * state->getIntermediate(indexIds[i]).Int(0);
+ }
+ typeId = type.element;
+ break;
}
- typeId = type.element;
- break;
- }
- case spv::OpTypeMatrix:
- {
- // TODO: b/127950082: Check bounds.
- ASSERT(d.HasMatrixStride);
- d.InsideMatrix = true;
- auto columnStride = (d.HasRowMajor && d.RowMajor) ? static_cast<int32_t>(sizeof(float)) : d.MatrixStride;
- auto & obj = getObject(indexIds[i]);
- if(obj.kind == Object::Kind::Constant)
+ case spv::OpTypeMatrix:
{
- constantOffset += columnStride * GetConstScalarInt(indexIds[i]);
+ // TODO: b/127950082: Check bounds.
+ ASSERT(d.HasMatrixStride);
+ d.InsideMatrix = true;
+ auto columnStride = (d.HasRowMajor && d.RowMajor) ? static_cast<int32_t>(sizeof(float)) : d.MatrixStride;
+ auto &obj = getObject(indexIds[i]);
+ if(obj.kind == Object::Kind::Constant)
+ {
+ constantOffset += columnStride * GetConstScalarInt(indexIds[i]);
+ }
+ else
+ {
+ ptr += SIMD::Int(columnStride) * state->getIntermediate(indexIds[i]).Int(0);
+ }
+ typeId = type.element;
+ break;
}
- else
+ case spv::OpTypeVector:
{
- ptr += SIMD::Int(columnStride) * state->getIntermediate(indexIds[i]).Int(0);
+ auto elemStride = (d.InsideMatrix && d.HasRowMajor && d.RowMajor) ? d.MatrixStride : static_cast<int32_t>(sizeof(float));
+ auto &obj = getObject(indexIds[i]);
+ if(obj.kind == Object::Kind::Constant)
+ {
+ constantOffset += elemStride * GetConstScalarInt(indexIds[i]);
+ }
+ else
+ {
+ ptr += SIMD::Int(elemStride) * state->getIntermediate(indexIds[i]).Int(0);
+ }
+ typeId = type.element;
+ break;
}
- typeId = type.element;
- break;
- }
- case spv::OpTypeVector:
- {
- auto elemStride = (d.InsideMatrix && d.HasRowMajor && d.RowMajor) ? d.MatrixStride : static_cast<int32_t>(sizeof(float));
- auto & obj = getObject(indexIds[i]);
- if(obj.kind == Object::Kind::Constant)
- {
- constantOffset += elemStride * GetConstScalarInt(indexIds[i]);
- }
- else
- {
- ptr += SIMD::Int(elemStride) * state->getIntermediate(indexIds[i]).Int(0);
- }
- typeId = type.element;
- break;
- }
- default:
- UNREACHABLE("%s", OpcodeName(type.definition.opcode()).c_str());
+ default:
+ UNREACHABLE("%s", OpcodeName(type.definition.opcode()).c_str());
}
}
@@ -1143,63 +1146,64 @@
for(auto i = 0u; i < numIndexes; i++)
{
- auto & type = getType(typeId);
+ auto &type = getType(typeId);
switch(type.opcode())
{
- case spv::OpTypeStruct:
- {
- int memberIndex = GetConstScalarInt(indexIds[i]);
- int offsetIntoStruct = 0;
- for(auto j = 0; j < memberIndex; j++) {
- auto memberType = type.definition.word(2u + j);
- offsetIntoStruct += getType(memberType).sizeInComponents * sizeof(float);
- }
- constantOffset += offsetIntoStruct;
- typeId = type.definition.word(2u + memberIndex);
- break;
- }
-
- case spv::OpTypeVector:
- case spv::OpTypeMatrix:
- case spv::OpTypeArray:
- case spv::OpTypeRuntimeArray:
- {
- // TODO: b/127950082: Check bounds.
- if(getType(baseObject.type).storageClass == spv::StorageClassUniformConstant)
+ case spv::OpTypeStruct:
{
- // indexing into an array of descriptors.
- auto &obj = getObject(indexIds[i]);
- if(obj.kind != Object::Kind::Constant)
+ int memberIndex = GetConstScalarInt(indexIds[i]);
+ int offsetIntoStruct = 0;
+ for(auto j = 0; j < memberIndex; j++)
{
- UNSUPPORTED("SPIR-V SampledImageArrayDynamicIndexing Capability");
+ auto memberType = type.definition.word(2u + j);
+ offsetIntoStruct += getType(memberType).sizeInComponents * sizeof(float);
}
-
- auto d = descriptorDecorations.at(baseId);
- ASSERT(d.DescriptorSet >= 0);
- ASSERT(d.Binding >= 0);
- auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
- auto stride = static_cast<uint32_t>(setLayout->getBindingStride(d.Binding));
- ptr.base += stride * GetConstScalarInt(indexIds[i]);
+ constantOffset += offsetIntoStruct;
+ typeId = type.definition.word(2u + memberIndex);
+ break;
}
- else
+
+ case spv::OpTypeVector:
+ case spv::OpTypeMatrix:
+ case spv::OpTypeArray:
+ case spv::OpTypeRuntimeArray:
{
- auto stride = getType(type.element).sizeInComponents * static_cast<uint32_t>(sizeof(float));
- auto & obj = getObject(indexIds[i]);
- if(obj.kind == Object::Kind::Constant)
+ // TODO: b/127950082: Check bounds.
+ if(getType(baseObject.type).storageClass == spv::StorageClassUniformConstant)
{
- ptr += stride * GetConstScalarInt(indexIds[i]);
+ // indexing into an array of descriptors.
+ auto &obj = getObject(indexIds[i]);
+ if(obj.kind != Object::Kind::Constant)
+ {
+ UNSUPPORTED("SPIR-V SampledImageArrayDynamicIndexing Capability");
+ }
+
+ auto d = descriptorDecorations.at(baseId);
+ ASSERT(d.DescriptorSet >= 0);
+ ASSERT(d.Binding >= 0);
+ auto setLayout = routine->pipelineLayout->getDescriptorSetLayout(d.DescriptorSet);
+ auto stride = static_cast<uint32_t>(setLayout->getBindingStride(d.Binding));
+ ptr.base += stride * GetConstScalarInt(indexIds[i]);
}
else
{
- ptr += SIMD::Int(stride) * state->getIntermediate(indexIds[i]).Int(0);
+ auto stride = getType(type.element).sizeInComponents * static_cast<uint32_t>(sizeof(float));
+ auto &obj = getObject(indexIds[i]);
+ if(obj.kind == Object::Kind::Constant)
+ {
+ ptr += stride * GetConstScalarInt(indexIds[i]);
+ }
+ else
+ {
+ ptr += SIMD::Int(stride) * state->getIntermediate(indexIds[i]).Int(0);
+ }
}
+ typeId = type.element;
+ break;
}
- typeId = type.element;
- break;
- }
- default:
- UNREACHABLE("%s", OpcodeName(type.opcode()).c_str());
+ default:
+ UNREACHABLE("%s", OpcodeName(type.opcode()).c_str());
}
}
@@ -1216,35 +1220,36 @@
for(auto i = 0u; i < numIndexes; i++)
{
- auto & type = getType(typeId);
+ auto &type = getType(typeId);
switch(type.opcode())
{
- case spv::OpTypeStruct:
- {
- int memberIndex = indexes[i];
- int offsetIntoStruct = 0;
- for(auto j = 0; j < memberIndex; j++) {
- auto memberType = type.definition.word(2u + j);
- offsetIntoStruct += getType(memberType).sizeInComponents;
+ case spv::OpTypeStruct:
+ {
+ int memberIndex = indexes[i];
+ int offsetIntoStruct = 0;
+ for(auto j = 0; j < memberIndex; j++)
+ {
+ auto memberType = type.definition.word(2u + j);
+ offsetIntoStruct += getType(memberType).sizeInComponents;
+ }
+ componentOffset += offsetIntoStruct;
+ typeId = type.definition.word(2u + memberIndex);
+ break;
}
- componentOffset += offsetIntoStruct;
- typeId = type.definition.word(2u + memberIndex);
- break;
- }
- case spv::OpTypeVector:
- case spv::OpTypeMatrix:
- case spv::OpTypeArray:
- {
- auto elementType = type.definition.word(2);
- auto stride = getType(elementType).sizeInComponents;
- componentOffset += stride * indexes[i];
- typeId = elementType;
- break;
- }
+ case spv::OpTypeVector:
+ case spv::OpTypeMatrix:
+ case spv::OpTypeArray:
+ {
+ auto elementType = type.definition.word(2);
+ auto stride = getType(elementType).sizeInComponents;
+ componentOffset += stride * indexes[i];
+ typeId = elementType;
+ break;
+ }
- default:
- UNREACHABLE("%s", OpcodeName(type.opcode()).c_str());
+ default:
+ UNREACHABLE("%s", OpcodeName(type.opcode()).c_str());
}
}
@@ -1255,58 +1260,58 @@
{
switch(decoration)
{
- case spv::DecorationLocation:
- HasLocation = true;
- Location = static_cast<int32_t>(arg);
- break;
- case spv::DecorationComponent:
- HasComponent = true;
- Component = arg;
- break;
- case spv::DecorationBuiltIn:
- HasBuiltIn = true;
- BuiltIn = static_cast<spv::BuiltIn>(arg);
- break;
- case spv::DecorationFlat:
- Flat = true;
- break;
- case spv::DecorationNoPerspective:
- NoPerspective = true;
- break;
- case spv::DecorationCentroid:
- Centroid = true;
- break;
- case spv::DecorationBlock:
- Block = true;
- break;
- case spv::DecorationBufferBlock:
- BufferBlock = true;
- break;
- case spv::DecorationOffset:
- HasOffset = true;
- Offset = static_cast<int32_t>(arg);
- break;
- case spv::DecorationArrayStride:
- HasArrayStride = true;
- ArrayStride = static_cast<int32_t>(arg);
- break;
- case spv::DecorationMatrixStride:
- HasMatrixStride = true;
- MatrixStride = static_cast<int32_t>(arg);
- break;
- case spv::DecorationRelaxedPrecision:
- RelaxedPrecision = true;
- break;
- case spv::DecorationRowMajor:
- HasRowMajor = true;
- RowMajor = true;
- break;
- case spv::DecorationColMajor:
- HasRowMajor = true;
- RowMajor = false;
- default:
- // Intentionally partial, there are many decorations we just don't care about.
- break;
+ case spv::DecorationLocation:
+ HasLocation = true;
+ Location = static_cast<int32_t>(arg);
+ break;
+ case spv::DecorationComponent:
+ HasComponent = true;
+ Component = arg;
+ break;
+ case spv::DecorationBuiltIn:
+ HasBuiltIn = true;
+ BuiltIn = static_cast<spv::BuiltIn>(arg);
+ break;
+ case spv::DecorationFlat:
+ Flat = true;
+ break;
+ case spv::DecorationNoPerspective:
+ NoPerspective = true;
+ break;
+ case spv::DecorationCentroid:
+ Centroid = true;
+ break;
+ case spv::DecorationBlock:
+ Block = true;
+ break;
+ case spv::DecorationBufferBlock:
+ BufferBlock = true;
+ break;
+ case spv::DecorationOffset:
+ HasOffset = true;
+ Offset = static_cast<int32_t>(arg);
+ break;
+ case spv::DecorationArrayStride:
+ HasArrayStride = true;
+ ArrayStride = static_cast<int32_t>(arg);
+ break;
+ case spv::DecorationMatrixStride:
+ HasMatrixStride = true;
+ MatrixStride = static_cast<int32_t>(arg);
+ break;
+ case spv::DecorationRelaxedPrecision:
+ RelaxedPrecision = true;
+ break;
+ case spv::DecorationRowMajor:
+ HasRowMajor = true;
+ RowMajor = true;
+ break;
+ case spv::DecorationColMajor:
+ HasRowMajor = true;
+ RowMajor = false;
+ default:
+ // Intentionally partial, there are many decorations we just don't care about.
+ break;
}
}
@@ -1407,15 +1412,15 @@
switch(getType(typeId).opcode())
{
- case spv::OpTypePointer:
- case spv::OpTypeImage:
- case spv::OpTypeSampledImage:
- case spv::OpTypeSampler:
- object.kind = Object::Kind::Pointer;
- break;
+ case spv::OpTypePointer:
+ case spv::OpTypeImage:
+ case spv::OpTypeSampledImage:
+ case spv::OpTypeSampler:
+ object.kind = Object::Kind::Pointer;
+ break;
- default:
- object.kind = Object::Kind::Intermediate;
+ default:
+ object.kind = Object::Kind::Intermediate;
}
object.definition = insn;
@@ -1425,27 +1430,27 @@
{
switch(storageClass)
{
- case spv::StorageClassUniform:
- case spv::StorageClassStorageBuffer:
- // Buffer resource access. robustBufferAccess feature applies.
- return robustBufferAccess ? OutOfBoundsBehavior::RobustBufferAccess
- : OutOfBoundsBehavior::UndefinedBehavior;
-
- case spv::StorageClassImage:
- return OutOfBoundsBehavior::UndefinedValue; // "The value returned by a read of an invalid texel is undefined"
-
- case spv::StorageClassInput:
- if(executionModel == spv::ExecutionModelVertex)
- {
- // Vertex attributes follow robustBufferAccess rules.
+ case spv::StorageClassUniform:
+ case spv::StorageClassStorageBuffer:
+ // Buffer resource access. robustBufferAccess feature applies.
return robustBufferAccess ? OutOfBoundsBehavior::RobustBufferAccess
: OutOfBoundsBehavior::UndefinedBehavior;
- }
- // Fall through to default case.
- default:
- // TODO(b/137183137): Optimize if the pointer resulted from OpInBoundsAccessChain.
- // TODO(b/131224163): Optimize cases statically known to be within bounds.
- return OutOfBoundsBehavior::UndefinedValue;
+
+ case spv::StorageClassImage:
+ return OutOfBoundsBehavior::UndefinedValue; // "The value returned by a read of an invalid texel is undefined"
+
+ case spv::StorageClassInput:
+ if(executionModel == spv::ExecutionModelVertex)
+ {
+ // Vertex attributes follow robustBufferAccess rules.
+ return robustBufferAccess ? OutOfBoundsBehavior::RobustBufferAccess
+ : OutOfBoundsBehavior::UndefinedBehavior;
+ }
+ // Fall through to default case.
+ default:
+ // TODO(b/137183137): Optimize if the pointer resulted from OpInBoundsAccessChain.
+ // TODO(b/131224163): Optimize cases statically known to be within bounds.
+ return OutOfBoundsBehavior::UndefinedValue;
}
return OutOfBoundsBehavior::Nullify;
@@ -1459,48 +1464,48 @@
{
switch(insn.opcode())
{
- case spv::OpVariable:
- {
- Type::ID resultPointerTypeId = insn.word(1);
- auto resultPointerType = getType(resultPointerTypeId);
- auto pointeeType = getType(resultPointerType.element);
+ case spv::OpVariable:
+ {
+ Type::ID resultPointerTypeId = insn.word(1);
+ auto resultPointerType = getType(resultPointerTypeId);
+ auto pointeeType = getType(resultPointerType.element);
- if(pointeeType.sizeInComponents > 0) // TODO: what to do about zero-slot objects?
+ if(pointeeType.sizeInComponents > 0) // TODO: what to do about zero-slot objects?
+ {
+ Object::ID resultId = insn.word(2);
+ routine->createVariable(resultId, pointeeType.sizeInComponents);
+ }
+ break;
+ }
+ case spv::OpPhi:
+ {
+ auto type = getType(insn.word(1));
+ Object::ID resultId = insn.word(2);
+ routine->phis.emplace(resultId, SpirvRoutine::Variable(type.sizeInComponents));
+ break;
+ }
+
+ case spv::OpImageDrefGather:
+ case spv::OpImageFetch:
+ case spv::OpImageGather:
+ case spv::OpImageQueryLod:
+ case spv::OpImageSampleDrefExplicitLod:
+ case spv::OpImageSampleDrefImplicitLod:
+ case spv::OpImageSampleExplicitLod:
+ case spv::OpImageSampleImplicitLod:
+ case spv::OpImageSampleProjDrefExplicitLod:
+ case spv::OpImageSampleProjDrefImplicitLod:
+ case spv::OpImageSampleProjExplicitLod:
+ case spv::OpImageSampleProjImplicitLod:
{
Object::ID resultId = insn.word(2);
- routine->createVariable(resultId, pointeeType.sizeInComponents);
+ routine->samplerCache.emplace(resultId, SpirvRoutine::SamplerCache{});
+ break;
}
- break;
- }
- case spv::OpPhi:
- {
- auto type = getType(insn.word(1));
- Object::ID resultId = insn.word(2);
- routine->phis.emplace(resultId, SpirvRoutine::Variable(type.sizeInComponents));
- break;
- }
- case spv::OpImageDrefGather:
- case spv::OpImageFetch:
- case spv::OpImageGather:
- case spv::OpImageQueryLod:
- case spv::OpImageSampleDrefExplicitLod:
- case spv::OpImageSampleDrefImplicitLod:
- case spv::OpImageSampleExplicitLod:
- case spv::OpImageSampleImplicitLod:
- case spv::OpImageSampleProjDrefExplicitLod:
- case spv::OpImageSampleProjDrefImplicitLod:
- case spv::OpImageSampleProjExplicitLod:
- case spv::OpImageSampleProjImplicitLod:
- {
- Object::ID resultId = insn.word(2);
- routine->samplerCache.emplace(resultId, SpirvRoutine::SamplerCache{});
- break;
- }
-
- default:
- // Nothing else produces interface variables, so can all be safely ignored.
- break;
+ default:
+ // Nothing else produces interface variables, so can all be safely ignored.
+ break;
}
}
}
@@ -1531,13 +1536,13 @@
auto res = EmitInstruction(insn, state);
switch(res)
{
- case EmitResult::Continue:
- continue;
- case EmitResult::Terminator:
- break;
- default:
- UNREACHABLE("Unexpected EmitResult %d", int(res));
- break;
+ case EmitResult::Continue:
+ continue;
+ case EmitResult::Terminator:
+ break;
+ default:
+ UNREACHABLE("Unexpected EmitResult %d", int(res));
+ break;
}
}
}
@@ -1548,365 +1553,365 @@
switch(opcode)
{
- case spv::OpTypeVoid:
- case spv::OpTypeInt:
- case spv::OpTypeFloat:
- case spv::OpTypeBool:
- case spv::OpTypeVector:
- case spv::OpTypeArray:
- case spv::OpTypeRuntimeArray:
- case spv::OpTypeMatrix:
- case spv::OpTypeStruct:
- case spv::OpTypePointer:
- case spv::OpTypeFunction:
- case spv::OpTypeImage:
- case spv::OpTypeSampledImage:
- case spv::OpTypeSampler:
- case spv::OpExecutionMode:
- case spv::OpMemoryModel:
- case spv::OpFunction:
- case spv::OpFunctionEnd:
- case spv::OpConstant:
- case spv::OpConstantNull:
- case spv::OpConstantTrue:
- case spv::OpConstantFalse:
- case spv::OpConstantComposite:
- case spv::OpSpecConstant:
- case spv::OpSpecConstantTrue:
- case spv::OpSpecConstantFalse:
- case spv::OpSpecConstantComposite:
- case spv::OpSpecConstantOp:
- case spv::OpUndef:
- case spv::OpExtension:
- case spv::OpCapability:
- case spv::OpEntryPoint:
- case spv::OpExtInstImport:
- case spv::OpDecorate:
- case spv::OpMemberDecorate:
- case spv::OpGroupDecorate:
- case spv::OpGroupMemberDecorate:
- case spv::OpDecorationGroup:
- case spv::OpName:
- case spv::OpMemberName:
- case spv::OpSource:
- case spv::OpSourceContinued:
- case spv::OpSourceExtension:
- case spv::OpLine:
- case spv::OpNoLine:
- case spv::OpModuleProcessed:
- case spv::OpString:
- // Nothing to do at emit time. These are either fully handled at analysis time,
- // or don't require any work at all.
- return EmitResult::Continue;
+ case spv::OpTypeVoid:
+ case spv::OpTypeInt:
+ case spv::OpTypeFloat:
+ case spv::OpTypeBool:
+ case spv::OpTypeVector:
+ case spv::OpTypeArray:
+ case spv::OpTypeRuntimeArray:
+ case spv::OpTypeMatrix:
+ case spv::OpTypeStruct:
+ case spv::OpTypePointer:
+ case spv::OpTypeFunction:
+ case spv::OpTypeImage:
+ case spv::OpTypeSampledImage:
+ case spv::OpTypeSampler:
+ case spv::OpExecutionMode:
+ case spv::OpMemoryModel:
+ case spv::OpFunction:
+ case spv::OpFunctionEnd:
+ case spv::OpConstant:
+ case spv::OpConstantNull:
+ case spv::OpConstantTrue:
+ case spv::OpConstantFalse:
+ case spv::OpConstantComposite:
+ case spv::OpSpecConstant:
+ case spv::OpSpecConstantTrue:
+ case spv::OpSpecConstantFalse:
+ case spv::OpSpecConstantComposite:
+ case spv::OpSpecConstantOp:
+ case spv::OpUndef:
+ case spv::OpExtension:
+ case spv::OpCapability:
+ case spv::OpEntryPoint:
+ case spv::OpExtInstImport:
+ case spv::OpDecorate:
+ case spv::OpMemberDecorate:
+ case spv::OpGroupDecorate:
+ case spv::OpGroupMemberDecorate:
+ case spv::OpDecorationGroup:
+ case spv::OpName:
+ case spv::OpMemberName:
+ case spv::OpSource:
+ case spv::OpSourceContinued:
+ case spv::OpSourceExtension:
+ case spv::OpLine:
+ case spv::OpNoLine:
+ case spv::OpModuleProcessed:
+ case spv::OpString:
+ // Nothing to do at emit time. These are either fully handled at analysis time,
+ // or don't require any work at all.
+ return EmitResult::Continue;
- case spv::OpLabel:
- return EmitResult::Continue;
+ case spv::OpLabel:
+ return EmitResult::Continue;
- case spv::OpVariable:
- return EmitVariable(insn, state);
+ case spv::OpVariable:
+ return EmitVariable(insn, state);
- case spv::OpLoad:
- case spv::OpAtomicLoad:
- return EmitLoad(insn, state);
+ case spv::OpLoad:
+ case spv::OpAtomicLoad:
+ return EmitLoad(insn, state);
- case spv::OpStore:
- case spv::OpAtomicStore:
- return EmitStore(insn, state);
+ case spv::OpStore:
+ case spv::OpAtomicStore:
+ return EmitStore(insn, state);
- case spv::OpAtomicIAdd:
- case spv::OpAtomicISub:
- case spv::OpAtomicSMin:
- case spv::OpAtomicSMax:
- case spv::OpAtomicUMin:
- case spv::OpAtomicUMax:
- case spv::OpAtomicAnd:
- case spv::OpAtomicOr:
- case spv::OpAtomicXor:
- case spv::OpAtomicIIncrement:
- case spv::OpAtomicIDecrement:
- case spv::OpAtomicExchange:
- return EmitAtomicOp(insn, state);
+ case spv::OpAtomicIAdd:
+ case spv::OpAtomicISub:
+ case spv::OpAtomicSMin:
+ case spv::OpAtomicSMax:
+ case spv::OpAtomicUMin:
+ case spv::OpAtomicUMax:
+ case spv::OpAtomicAnd:
+ case spv::OpAtomicOr:
+ case spv::OpAtomicXor:
+ case spv::OpAtomicIIncrement:
+ case spv::OpAtomicIDecrement:
+ case spv::OpAtomicExchange:
+ return EmitAtomicOp(insn, state);
- case spv::OpAtomicCompareExchange:
- return EmitAtomicCompareExchange(insn, state);
+ case spv::OpAtomicCompareExchange:
+ return EmitAtomicCompareExchange(insn, state);
- case spv::OpAccessChain:
- case spv::OpInBoundsAccessChain:
- return EmitAccessChain(insn, state);
+ case spv::OpAccessChain:
+ case spv::OpInBoundsAccessChain:
+ return EmitAccessChain(insn, state);
- case spv::OpCompositeConstruct:
- return EmitCompositeConstruct(insn, state);
+ case spv::OpCompositeConstruct:
+ return EmitCompositeConstruct(insn, state);
- case spv::OpCompositeInsert:
- return EmitCompositeInsert(insn, state);
+ case spv::OpCompositeInsert:
+ return EmitCompositeInsert(insn, state);
- case spv::OpCompositeExtract:
- return EmitCompositeExtract(insn, state);
+ case spv::OpCompositeExtract:
+ return EmitCompositeExtract(insn, state);
- case spv::OpVectorShuffle:
- return EmitVectorShuffle(insn, state);
+ case spv::OpVectorShuffle:
+ return EmitVectorShuffle(insn, state);
- case spv::OpVectorExtractDynamic:
- return EmitVectorExtractDynamic(insn, state);
+ case spv::OpVectorExtractDynamic:
+ return EmitVectorExtractDynamic(insn, state);
- case spv::OpVectorInsertDynamic:
- return EmitVectorInsertDynamic(insn, state);
+ case spv::OpVectorInsertDynamic:
+ return EmitVectorInsertDynamic(insn, state);
- case spv::OpVectorTimesScalar:
- case spv::OpMatrixTimesScalar:
- return EmitVectorTimesScalar(insn, state);
+ case spv::OpVectorTimesScalar:
+ case spv::OpMatrixTimesScalar:
+ return EmitVectorTimesScalar(insn, state);
- case spv::OpMatrixTimesVector:
- return EmitMatrixTimesVector(insn, state);
+ case spv::OpMatrixTimesVector:
+ return EmitMatrixTimesVector(insn, state);
- case spv::OpVectorTimesMatrix:
- return EmitVectorTimesMatrix(insn, state);
+ case spv::OpVectorTimesMatrix:
+ return EmitVectorTimesMatrix(insn, state);
- case spv::OpMatrixTimesMatrix:
- return EmitMatrixTimesMatrix(insn, state);
+ case spv::OpMatrixTimesMatrix:
+ return EmitMatrixTimesMatrix(insn, state);
- case spv::OpOuterProduct:
- return EmitOuterProduct(insn, state);
+ case spv::OpOuterProduct:
+ return EmitOuterProduct(insn, state);
- case spv::OpTranspose:
- return EmitTranspose(insn, state);
+ case spv::OpTranspose:
+ return EmitTranspose(insn, state);
- case spv::OpNot:
- case spv::OpBitFieldInsert:
- case spv::OpBitFieldSExtract:
- case spv::OpBitFieldUExtract:
- case spv::OpBitReverse:
- case spv::OpBitCount:
- case spv::OpSNegate:
- case spv::OpFNegate:
- case spv::OpLogicalNot:
- case spv::OpConvertFToU:
- case spv::OpConvertFToS:
- case spv::OpConvertSToF:
- case spv::OpConvertUToF:
- case spv::OpBitcast:
- case spv::OpIsInf:
- case spv::OpIsNan:
- case spv::OpDPdx:
- case spv::OpDPdxCoarse:
- case spv::OpDPdy:
- case spv::OpDPdyCoarse:
- case spv::OpFwidth:
- case spv::OpFwidthCoarse:
- case spv::OpDPdxFine:
- case spv::OpDPdyFine:
- case spv::OpFwidthFine:
- case spv::OpQuantizeToF16:
- return EmitUnaryOp(insn, state);
+ case spv::OpNot:
+ case spv::OpBitFieldInsert:
+ case spv::OpBitFieldSExtract:
+ case spv::OpBitFieldUExtract:
+ case spv::OpBitReverse:
+ case spv::OpBitCount:
+ case spv::OpSNegate:
+ case spv::OpFNegate:
+ case spv::OpLogicalNot:
+ case spv::OpConvertFToU:
+ case spv::OpConvertFToS:
+ case spv::OpConvertSToF:
+ case spv::OpConvertUToF:
+ case spv::OpBitcast:
+ case spv::OpIsInf:
+ case spv::OpIsNan:
+ case spv::OpDPdx:
+ case spv::OpDPdxCoarse:
+ case spv::OpDPdy:
+ case spv::OpDPdyCoarse:
+ case spv::OpFwidth:
+ case spv::OpFwidthCoarse:
+ case spv::OpDPdxFine:
+ case spv::OpDPdyFine:
+ case spv::OpFwidthFine:
+ case spv::OpQuantizeToF16:
+ return EmitUnaryOp(insn, state);
- case spv::OpIAdd:
- case spv::OpISub:
- case spv::OpIMul:
- case spv::OpSDiv:
- case spv::OpUDiv:
- case spv::OpFAdd:
- case spv::OpFSub:
- case spv::OpFMul:
- case spv::OpFDiv:
- case spv::OpFMod:
- case spv::OpFRem:
- case spv::OpFOrdEqual:
- case spv::OpFUnordEqual:
- case spv::OpFOrdNotEqual:
- case spv::OpFUnordNotEqual:
- case spv::OpFOrdLessThan:
- case spv::OpFUnordLessThan:
- case spv::OpFOrdGreaterThan:
- case spv::OpFUnordGreaterThan:
- case spv::OpFOrdLessThanEqual:
- case spv::OpFUnordLessThanEqual:
- case spv::OpFOrdGreaterThanEqual:
- case spv::OpFUnordGreaterThanEqual:
- case spv::OpSMod:
- case spv::OpSRem:
- case spv::OpUMod:
- case spv::OpIEqual:
- case spv::OpINotEqual:
- case spv::OpUGreaterThan:
- case spv::OpSGreaterThan:
- case spv::OpUGreaterThanEqual:
- case spv::OpSGreaterThanEqual:
- case spv::OpULessThan:
- case spv::OpSLessThan:
- case spv::OpULessThanEqual:
- case spv::OpSLessThanEqual:
- case spv::OpShiftRightLogical:
- case spv::OpShiftRightArithmetic:
- case spv::OpShiftLeftLogical:
- case spv::OpBitwiseOr:
- case spv::OpBitwiseXor:
- case spv::OpBitwiseAnd:
- case spv::OpLogicalOr:
- case spv::OpLogicalAnd:
- case spv::OpLogicalEqual:
- case spv::OpLogicalNotEqual:
- case spv::OpUMulExtended:
- case spv::OpSMulExtended:
- case spv::OpIAddCarry:
- case spv::OpISubBorrow:
- return EmitBinaryOp(insn, state);
+ case spv::OpIAdd:
+ case spv::OpISub:
+ case spv::OpIMul:
+ case spv::OpSDiv:
+ case spv::OpUDiv:
+ case spv::OpFAdd:
+ case spv::OpFSub:
+ case spv::OpFMul:
+ case spv::OpFDiv:
+ case spv::OpFMod:
+ case spv::OpFRem:
+ case spv::OpFOrdEqual:
+ case spv::OpFUnordEqual:
+ case spv::OpFOrdNotEqual:
+ case spv::OpFUnordNotEqual:
+ case spv::OpFOrdLessThan:
+ case spv::OpFUnordLessThan:
+ case spv::OpFOrdGreaterThan:
+ case spv::OpFUnordGreaterThan:
+ case spv::OpFOrdLessThanEqual:
+ case spv::OpFUnordLessThanEqual:
+ case spv::OpFOrdGreaterThanEqual:
+ case spv::OpFUnordGreaterThanEqual:
+ case spv::OpSMod:
+ case spv::OpSRem:
+ case spv::OpUMod:
+ case spv::OpIEqual:
+ case spv::OpINotEqual:
+ case spv::OpUGreaterThan:
+ case spv::OpSGreaterThan:
+ case spv::OpUGreaterThanEqual:
+ case spv::OpSGreaterThanEqual:
+ case spv::OpULessThan:
+ case spv::OpSLessThan:
+ case spv::OpULessThanEqual:
+ case spv::OpSLessThanEqual:
+ case spv::OpShiftRightLogical:
+ case spv::OpShiftRightArithmetic:
+ case spv::OpShiftLeftLogical:
+ case spv::OpBitwiseOr:
+ case spv::OpBitwiseXor:
+ case spv::OpBitwiseAnd:
+ case spv::OpLogicalOr:
+ case spv::OpLogicalAnd:
+ case spv::OpLogicalEqual:
+ case spv::OpLogicalNotEqual:
+ case spv::OpUMulExtended:
+ case spv::OpSMulExtended:
+ case spv::OpIAddCarry:
+ case spv::OpISubBorrow:
+ return EmitBinaryOp(insn, state);
- case spv::OpDot:
- return EmitDot(insn, state);
+ case spv::OpDot:
+ return EmitDot(insn, state);
- case spv::OpSelect:
- return EmitSelect(insn, state);
+ case spv::OpSelect:
+ return EmitSelect(insn, state);
- case spv::OpExtInst:
- return EmitExtendedInstruction(insn, state);
+ case spv::OpExtInst:
+ return EmitExtendedInstruction(insn, state);
- case spv::OpAny:
- return EmitAny(insn, state);
+ case spv::OpAny:
+ return EmitAny(insn, state);
- case spv::OpAll:
- return EmitAll(insn, state);
+ case spv::OpAll:
+ return EmitAll(insn, state);
- case spv::OpBranch:
- return EmitBranch(insn, state);
+ case spv::OpBranch:
+ return EmitBranch(insn, state);
- case spv::OpPhi:
- return EmitPhi(insn, state);
+ case spv::OpPhi:
+ return EmitPhi(insn, state);
- case spv::OpSelectionMerge:
- case spv::OpLoopMerge:
- return EmitResult::Continue;
+ case spv::OpSelectionMerge:
+ case spv::OpLoopMerge:
+ return EmitResult::Continue;
- case spv::OpBranchConditional:
- return EmitBranchConditional(insn, state);
+ case spv::OpBranchConditional:
+ return EmitBranchConditional(insn, state);
- case spv::OpSwitch:
- return EmitSwitch(insn, state);
+ case spv::OpSwitch:
+ return EmitSwitch(insn, state);
- case spv::OpUnreachable:
- return EmitUnreachable(insn, state);
+ case spv::OpUnreachable:
+ return EmitUnreachable(insn, state);
- case spv::OpReturn:
- return EmitReturn(insn, state);
+ case spv::OpReturn:
+ return EmitReturn(insn, state);
- case spv::OpFunctionCall:
- return EmitFunctionCall(insn, state);
+ case spv::OpFunctionCall:
+ return EmitFunctionCall(insn, state);
- case spv::OpKill:
- return EmitKill(insn, state);
+ case spv::OpKill:
+ return EmitKill(insn, state);
- case spv::OpImageSampleImplicitLod:
- return EmitImageSampleImplicitLod(None, insn, state);
+ case spv::OpImageSampleImplicitLod:
+ return EmitImageSampleImplicitLod(None, insn, state);
- case spv::OpImageSampleExplicitLod:
- return EmitImageSampleExplicitLod(None, insn, state);
+ case spv::OpImageSampleExplicitLod:
+ return EmitImageSampleExplicitLod(None, insn, state);
- case spv::OpImageSampleDrefImplicitLod:
- return EmitImageSampleImplicitLod(Dref, insn, state);
+ case spv::OpImageSampleDrefImplicitLod:
+ return EmitImageSampleImplicitLod(Dref, insn, state);
- case spv::OpImageSampleDrefExplicitLod:
- return EmitImageSampleExplicitLod(Dref, insn, state);
+ case spv::OpImageSampleDrefExplicitLod:
+ return EmitImageSampleExplicitLod(Dref, insn, state);
- case spv::OpImageSampleProjImplicitLod:
- return EmitImageSampleImplicitLod(Proj, insn, state);
+ case spv::OpImageSampleProjImplicitLod:
+ return EmitImageSampleImplicitLod(Proj, insn, state);
- case spv::OpImageSampleProjExplicitLod:
- return EmitImageSampleExplicitLod(Proj, insn, state);
+ case spv::OpImageSampleProjExplicitLod:
+ return EmitImageSampleExplicitLod(Proj, insn, state);
- case spv::OpImageSampleProjDrefImplicitLod:
- return EmitImageSampleImplicitLod(ProjDref, insn, state);
+ case spv::OpImageSampleProjDrefImplicitLod:
+ return EmitImageSampleImplicitLod(ProjDref, insn, state);
- case spv::OpImageSampleProjDrefExplicitLod:
- return EmitImageSampleExplicitLod(ProjDref, insn, state);
+ case spv::OpImageSampleProjDrefExplicitLod:
+ return EmitImageSampleExplicitLod(ProjDref, insn, state);
- case spv::OpImageGather:
- return EmitImageGather(None, insn, state);
+ case spv::OpImageGather:
+ return EmitImageGather(None, insn, state);
- case spv::OpImageDrefGather:
- return EmitImageGather(Dref, insn, state);
+ case spv::OpImageDrefGather:
+ return EmitImageGather(Dref, insn, state);
- case spv::OpImageFetch:
- return EmitImageFetch(insn, state);
+ case spv::OpImageFetch:
+ return EmitImageFetch(insn, state);
- case spv::OpImageQuerySizeLod:
- return EmitImageQuerySizeLod(insn, state);
+ case spv::OpImageQuerySizeLod:
+ return EmitImageQuerySizeLod(insn, state);
- case spv::OpImageQuerySize:
- return EmitImageQuerySize(insn, state);
+ case spv::OpImageQuerySize:
+ return EmitImageQuerySize(insn, state);
- case spv::OpImageQueryLod:
- return EmitImageQueryLod(insn, state);
+ case spv::OpImageQueryLod:
+ return EmitImageQueryLod(insn, state);
- case spv::OpImageQueryLevels:
- return EmitImageQueryLevels(insn, state);
+ case spv::OpImageQueryLevels:
+ return EmitImageQueryLevels(insn, state);
- case spv::OpImageQuerySamples:
- return EmitImageQuerySamples(insn, state);
+ case spv::OpImageQuerySamples:
+ return EmitImageQuerySamples(insn, state);
- case spv::OpImageRead:
- return EmitImageRead(insn, state);
+ case spv::OpImageRead:
+ return EmitImageRead(insn, state);
- case spv::OpImageWrite:
- return EmitImageWrite(insn, state);
+ case spv::OpImageWrite:
+ return EmitImageWrite(insn, state);
- case spv::OpImageTexelPointer:
- return EmitImageTexelPointer(insn, state);
+ case spv::OpImageTexelPointer:
+ return EmitImageTexelPointer(insn, state);
- case spv::OpSampledImage:
- case spv::OpImage:
- return EmitSampledImageCombineOrSplit(insn, state);
+ case spv::OpSampledImage:
+ case spv::OpImage:
+ return EmitSampledImageCombineOrSplit(insn, state);
- case spv::OpCopyObject:
- return EmitCopyObject(insn, state);
+ case spv::OpCopyObject:
+ return EmitCopyObject(insn, state);
- case spv::OpCopyMemory:
- return EmitCopyMemory(insn, state);
+ case spv::OpCopyMemory:
+ return EmitCopyMemory(insn, state);
- case spv::OpControlBarrier:
- return EmitControlBarrier(insn, state);
+ case spv::OpControlBarrier:
+ return EmitControlBarrier(insn, state);
- case spv::OpMemoryBarrier:
- return EmitMemoryBarrier(insn, state);
+ case spv::OpMemoryBarrier:
+ return EmitMemoryBarrier(insn, state);
- case spv::OpGroupNonUniformElect:
- case spv::OpGroupNonUniformAll:
- case spv::OpGroupNonUniformAny:
- case spv::OpGroupNonUniformAllEqual:
- case spv::OpGroupNonUniformBroadcast:
- case spv::OpGroupNonUniformBroadcastFirst:
- case spv::OpGroupNonUniformBallot:
- case spv::OpGroupNonUniformInverseBallot:
- case spv::OpGroupNonUniformBallotBitExtract:
- case spv::OpGroupNonUniformBallotBitCount:
- case spv::OpGroupNonUniformBallotFindLSB:
- case spv::OpGroupNonUniformBallotFindMSB:
- case spv::OpGroupNonUniformShuffle:
- case spv::OpGroupNonUniformShuffleXor:
- case spv::OpGroupNonUniformShuffleUp:
- case spv::OpGroupNonUniformShuffleDown:
- case spv::OpGroupNonUniformIAdd:
- case spv::OpGroupNonUniformFAdd:
- case spv::OpGroupNonUniformIMul:
- case spv::OpGroupNonUniformFMul:
- case spv::OpGroupNonUniformSMin:
- case spv::OpGroupNonUniformUMin:
- case spv::OpGroupNonUniformFMin:
- case spv::OpGroupNonUniformSMax:
- case spv::OpGroupNonUniformUMax:
- case spv::OpGroupNonUniformFMax:
- case spv::OpGroupNonUniformBitwiseAnd:
- case spv::OpGroupNonUniformBitwiseOr:
- case spv::OpGroupNonUniformBitwiseXor:
- case spv::OpGroupNonUniformLogicalAnd:
- case spv::OpGroupNonUniformLogicalOr:
- case spv::OpGroupNonUniformLogicalXor:
- return EmitGroupNonUniform(insn, state);
+ case spv::OpGroupNonUniformElect:
+ case spv::OpGroupNonUniformAll:
+ case spv::OpGroupNonUniformAny:
+ case spv::OpGroupNonUniformAllEqual:
+ case spv::OpGroupNonUniformBroadcast:
+ case spv::OpGroupNonUniformBroadcastFirst:
+ case spv::OpGroupNonUniformBallot:
+ case spv::OpGroupNonUniformInverseBallot:
+ case spv::OpGroupNonUniformBallotBitExtract:
+ case spv::OpGroupNonUniformBallotBitCount:
+ case spv::OpGroupNonUniformBallotFindLSB:
+ case spv::OpGroupNonUniformBallotFindMSB:
+ case spv::OpGroupNonUniformShuffle:
+ case spv::OpGroupNonUniformShuffleXor:
+ case spv::OpGroupNonUniformShuffleUp:
+ case spv::OpGroupNonUniformShuffleDown:
+ case spv::OpGroupNonUniformIAdd:
+ case spv::OpGroupNonUniformFAdd:
+ case spv::OpGroupNonUniformIMul:
+ case spv::OpGroupNonUniformFMul:
+ case spv::OpGroupNonUniformSMin:
+ case spv::OpGroupNonUniformUMin:
+ case spv::OpGroupNonUniformFMin:
+ case spv::OpGroupNonUniformSMax:
+ case spv::OpGroupNonUniformUMax:
+ case spv::OpGroupNonUniformFMax:
+ case spv::OpGroupNonUniformBitwiseAnd:
+ case spv::OpGroupNonUniformBitwiseOr:
+ case spv::OpGroupNonUniformBitwiseXor:
+ case spv::OpGroupNonUniformLogicalAnd:
+ case spv::OpGroupNonUniformLogicalOr:
+ case spv::OpGroupNonUniformLogicalXor:
+ return EmitGroupNonUniform(insn, state);
- case spv::OpArrayLength:
- return EmitArrayLength(insn, state);
+ case spv::OpArrayLength:
+ return EmitArrayLength(insn, state);
- default:
- UNREACHABLE("%s", OpcodeName(opcode).c_str());
- break;
+ default:
+ UNREACHABLE("%s", OpcodeName(opcode).c_str());
+ break;
}
return EmitResult::Continue;
@@ -1948,8 +1953,8 @@
for(auto i = 0u; i < insn.wordCount() - 3; i++)
{
Object::ID srcObjectId = insn.word(3u + i);
- auto & srcObject = getObject(srcObjectId);
- auto & srcObjectTy = getType(srcObject.type);
+ auto &srcObject = getObject(srcObjectId);
+ auto &srcObjectTy = getType(srcObject.type);
GenericValue srcObjectAccess(this, state, srcObjectId);
for(auto j = 0u; j < srcObjectTy.sizeInComponents; j++)
@@ -2092,7 +2097,7 @@
for(auto i = 0u; i < type.sizeInComponents; i++)
{
auto sel = cond.Int(condIsScalar ? 0 : i);
- dst.move(i, (sel & lhs.Int(i)) | (~sel & rhs.Int(i))); // TODO: IfThenElse()
+ dst.move(i, (sel & lhs.Int(i)) | (~sel & rhs.Int(i))); // TODO: IfThenElse()
}
return EmitResult::Continue;
@@ -2160,41 +2165,41 @@
UInt v;
switch(insn.opcode())
{
- case spv::OpAtomicIAdd:
- case spv::OpAtomicIIncrement:
- v = AddAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicISub:
- case spv::OpAtomicIDecrement:
- v = SubAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicAnd:
- v = AndAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicOr:
- v = OrAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicXor:
- v = XorAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicSMin:
- v = As<UInt>(MinAtomic(Pointer<Int>(&ptr.base[offset]), As<Int>(laneValue), memoryOrder));
- break;
- case spv::OpAtomicSMax:
- v = As<UInt>(MaxAtomic(Pointer<Int>(&ptr.base[offset]), As<Int>(laneValue), memoryOrder));
- break;
- case spv::OpAtomicUMin:
- v = MinAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicUMax:
- v = MaxAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- case spv::OpAtomicExchange:
- v = ExchangeAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
- break;
- default:
- UNREACHABLE("%s", OpcodeName(insn.opcode()).c_str());
- break;
+ case spv::OpAtomicIAdd:
+ case spv::OpAtomicIIncrement:
+ v = AddAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicISub:
+ case spv::OpAtomicIDecrement:
+ v = SubAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicAnd:
+ v = AndAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicOr:
+ v = OrAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicXor:
+ v = XorAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicSMin:
+ v = As<UInt>(MinAtomic(Pointer<Int>(&ptr.base[offset]), As<Int>(laneValue), memoryOrder));
+ break;
+ case spv::OpAtomicSMax:
+ v = As<UInt>(MaxAtomic(Pointer<Int>(&ptr.base[offset]), As<Int>(laneValue), memoryOrder));
+ break;
+ case spv::OpAtomicUMin:
+ v = MinAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicUMax:
+ v = MaxAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ case spv::OpAtomicExchange:
+ v = ExchangeAtomic(Pointer<UInt>(&ptr.base[offset]), laneValue, memoryOrder);
+ break;
+ default:
+ UNREACHABLE("%s", OpcodeName(insn.opcode()).c_str());
+ break;
}
x = Insert(x, v, j);
}
@@ -2298,25 +2303,25 @@
{
switch(insn.opcode())
{
- case spv::OpVariable:
- {
- Object::ID resultId = insn.word(2);
- auto &object = getObject(resultId);
- auto &objectTy = getType(object.type);
- if(object.kind == Object::Kind::InterfaceVariable && objectTy.storageClass == spv::StorageClassOutput)
+ case spv::OpVariable:
{
- auto &dst = routine->getVariable(resultId);
- int offset = 0;
- VisitInterface(resultId,
- [&](Decorations const &d, AttribType type) {
- auto scalarSlot = d.Location << 2 | d.Component;
- routine->outputs[scalarSlot] = dst[offset++];
- });
+ Object::ID resultId = insn.word(2);
+ auto &object = getObject(resultId);
+ auto &objectTy = getType(object.type);
+ if(object.kind == Object::Kind::InterfaceVariable && objectTy.storageClass == spv::StorageClassOutput)
+ {
+ auto &dst = routine->getVariable(resultId);
+ int offset = 0;
+ VisitInterface(resultId,
+ [&](Decorations const &d, AttribType type) {
+ auto scalarSlot = d.Location << 2 | d.Component;
+ routine->outputs[scalarSlot] = dst[offset++];
+ });
+ }
+ break;
}
- break;
- }
- default:
- break;
+ default:
+ break;
}
}
@@ -2331,47 +2336,46 @@
{
switch(model)
{
- case spv::ExecutionModelVertex: return VK_SHADER_STAGE_VERTEX_BIT;
- // case spv::ExecutionModelTessellationControl: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
- // case spv::ExecutionModelTessellationEvaluation: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
- // case spv::ExecutionModelGeometry: return VK_SHADER_STAGE_GEOMETRY_BIT;
- case spv::ExecutionModelFragment: return VK_SHADER_STAGE_FRAGMENT_BIT;
- case spv::ExecutionModelGLCompute: return VK_SHADER_STAGE_COMPUTE_BIT;
- // case spv::ExecutionModelKernel: return VkShaderStageFlagBits(0); // Not supported by vulkan.
- // case spv::ExecutionModelTaskNV: return VK_SHADER_STAGE_TASK_BIT_NV;
- // case spv::ExecutionModelMeshNV: return VK_SHADER_STAGE_MESH_BIT_NV;
- // case spv::ExecutionModelRayGenerationNV: return VK_SHADER_STAGE_RAYGEN_BIT_NV;
- // case spv::ExecutionModelIntersectionNV: return VK_SHADER_STAGE_INTERSECTION_BIT_NV;
- // case spv::ExecutionModelAnyHitNV: return VK_SHADER_STAGE_ANY_HIT_BIT_NV;
- // case spv::ExecutionModelClosestHitNV: return VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV;
- // case spv::ExecutionModelMissNV: return VK_SHADER_STAGE_MISS_BIT_NV;
- // case spv::ExecutionModelCallableNV: return VK_SHADER_STAGE_CALLABLE_BIT_NV;
- default:
- UNSUPPORTED("ExecutionModel: %d", int(model));
- return VkShaderStageFlagBits(0);
+ case spv::ExecutionModelVertex: return VK_SHADER_STAGE_VERTEX_BIT;
+ // case spv::ExecutionModelTessellationControl: return VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT;
+ // case spv::ExecutionModelTessellationEvaluation: return VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT;
+ // case spv::ExecutionModelGeometry: return VK_SHADER_STAGE_GEOMETRY_BIT;
+ case spv::ExecutionModelFragment: return VK_SHADER_STAGE_FRAGMENT_BIT;
+ case spv::ExecutionModelGLCompute: return VK_SHADER_STAGE_COMPUTE_BIT;
+ // case spv::ExecutionModelKernel: return VkShaderStageFlagBits(0); // Not supported by vulkan.
+ // case spv::ExecutionModelTaskNV: return VK_SHADER_STAGE_TASK_BIT_NV;
+ // case spv::ExecutionModelMeshNV: return VK_SHADER_STAGE_MESH_BIT_NV;
+ // case spv::ExecutionModelRayGenerationNV: return VK_SHADER_STAGE_RAYGEN_BIT_NV;
+ // case spv::ExecutionModelIntersectionNV: return VK_SHADER_STAGE_INTERSECTION_BIT_NV;
+ // case spv::ExecutionModelAnyHitNV: return VK_SHADER_STAGE_ANY_HIT_BIT_NV;
+ // case spv::ExecutionModelClosestHitNV: return VK_SHADER_STAGE_CLOSEST_HIT_BIT_NV;
+ // case spv::ExecutionModelMissNV: return VK_SHADER_STAGE_MISS_BIT_NV;
+ // case spv::ExecutionModelCallableNV: return VK_SHADER_STAGE_CALLABLE_BIT_NV;
+ default:
+ UNSUPPORTED("ExecutionModel: %d", int(model));
+ return VkShaderStageFlagBits(0);
}
}
-SpirvShader::GenericValue::GenericValue(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId) :
- obj(shader->getObject(objId)),
- intermediate(obj.kind == SpirvShader::Object::Kind::Intermediate ? &state->getIntermediate(objId) : nullptr),
- type(obj.type) {}
+SpirvShader::GenericValue::GenericValue(SpirvShader const *shader, EmitState const *state, SpirvShader::Object::ID objId)
+ : obj(shader->getObject(objId))
+ , intermediate(obj.kind == SpirvShader::Object::Kind::Intermediate ? &state->getIntermediate(objId) : nullptr)
+ , type(obj.type)
+{}
-SpirvRoutine::SpirvRoutine(vk::PipelineLayout const *pipelineLayout) :
- pipelineLayout(pipelineLayout)
+SpirvRoutine::SpirvRoutine(vk::PipelineLayout const *pipelineLayout)
+ : pipelineLayout(pipelineLayout)
{
}
void SpirvRoutine::setImmutableInputBuiltins(SpirvShader const *shader)
{
- setInputBuiltin(shader, spv::BuiltInSubgroupLocalInvocationId, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInSubgroupLocalInvocationId, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 1);
value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 1, 2, 3));
});
- setInputBuiltin(shader, spv::BuiltInSubgroupEqMask, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInSubgroupEqMask, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 4);
value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(1, 2, 4, 8));
value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
@@ -2379,8 +2383,7 @@
value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
});
- setInputBuiltin(shader, spv::BuiltInSubgroupGeMask, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInSubgroupGeMask, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 4);
value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(15, 14, 12, 8));
value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
@@ -2388,8 +2391,7 @@
value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
});
- setInputBuiltin(shader, spv::BuiltInSubgroupGtMask, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInSubgroupGtMask, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 4);
value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(14, 12, 8, 0));
value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
@@ -2397,8 +2399,7 @@
value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
});
- setInputBuiltin(shader, spv::BuiltInSubgroupLeMask, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInSubgroupLeMask, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 4);
value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(1, 3, 7, 15));
value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
@@ -2406,8 +2407,7 @@
value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
});
- setInputBuiltin(shader, spv::BuiltInSubgroupLtMask, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInSubgroupLtMask, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 4);
value[builtin.FirstComponent + 0] = As<SIMD::Float>(SIMD::Int(0, 1, 3, 7));
value[builtin.FirstComponent + 1] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
@@ -2415,8 +2415,7 @@
value[builtin.FirstComponent + 3] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));
});
- setInputBuiltin(shader, spv::BuiltInDeviceIndex, [&](const SpirvShader::BuiltinMapping& builtin, Array<SIMD::Float>& value)
- {
+ setInputBuiltin(shader, spv::BuiltInDeviceIndex, [&](const SpirvShader::BuiltinMapping &builtin, Array<SIMD::Float> &value) {
ASSERT(builtin.SizeInComponents == 1);
// Only a single physical device is supported.
value[builtin.FirstComponent] = As<SIMD::Float>(SIMD::Int(0, 0, 0, 0));