// Copyright 2020 The SwiftShader Authors. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. #include "SpirvShader.hpp" #include "spirv-tools/libspirv.h" #include namespace sw { const char *Spirv::OpcodeName(spv::Op opcode) { return spvOpcodeString(opcode); } // This function is used by the shader debugger to determine whether an instruction is steppable. bool Spirv::IsStatement(spv::Op opcode) { switch(opcode) { default: // Most statement-like instructions produce a result which has a type. // Note OpType* instructions have a result but it is a type itself. { bool hasResult = false; bool hasResultType = false; spv::HasResultAndType(opcode, &hasResult, &hasResultType); return hasResult && hasResultType; } break; // Instructions without a result but potential side-effects. case spv::OpNop: case spv::OpStore: case spv::OpCopyMemory: case spv::OpCopyMemorySized: case spv::OpImageWrite: case spv::OpEmitVertex: case spv::OpEndPrimitive: case spv::OpEmitStreamVertex: case spv::OpEndStreamPrimitive: case spv::OpControlBarrier: case spv::OpMemoryBarrier: case spv::OpAtomicStore: case spv::OpBranch: case spv::OpBranchConditional: case spv::OpSwitch: case spv::OpKill: case spv::OpReturn: case spv::OpReturnValue: case spv::OpLifetimeStart: case spv::OpLifetimeStop: case spv::OpGroupWaitEvents: case spv::OpCommitReadPipe: case spv::OpCommitWritePipe: case spv::OpGroupCommitReadPipe: case spv::OpGroupCommitWritePipe: case spv::OpRetainEvent: case spv::OpReleaseEvent: case spv::OpSetUserEventStatus: case spv::OpCaptureEventProfilingInfo: case spv::OpAtomicFlagClear: case spv::OpMemoryNamedBarrier: case spv::OpTerminateInvocation: case spv::OpTraceRayKHR: case spv::OpExecuteCallableKHR: case spv::OpIgnoreIntersectionKHR: case spv::OpTerminateRayKHR: case spv::OpRayQueryInitializeKHR: case spv::OpRayQueryTerminateKHR: case spv::OpRayQueryGenerateIntersectionKHR: case spv::OpRayQueryConfirmIntersectionKHR: case spv::OpBeginInvocationInterlockEXT: case spv::OpEndInvocationInterlockEXT: case spv::OpDemoteToHelperInvocationEXT: case spv::OpAssumeTrueKHR: return true; } } bool Spirv::IsTerminator(spv::Op opcode) { switch(opcode) { // Branch instructions case spv::OpBranch: case spv::OpBranchConditional: case spv::OpSwitch: // Function termination instructions case spv::OpReturn: case spv::OpReturnValue: case spv::OpKill: case spv::OpUnreachable: case spv::OpTerminateInvocation: return true; default: return false; } } } // namespace sw