| // 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 <spirv/unified1/spirv.hpp> | |
| 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 |