#include #include "spirv_module.h" namespace dxvk { SpirvModule:: SpirvModule() { this->instImportGlsl450(); } SpirvModule::~SpirvModule() { } SpirvCodeBuffer SpirvModule::compile() const { SpirvCodeBuffer result; result.putHeader(m_id); result.append(m_capabilities); result.append(m_extensions); result.append(m_instExt); result.append(m_memoryModel); result.append(m_entryPoints); result.append(m_execModeInfo); result.append(m_debugNames); result.append(m_annotations); result.append(m_typeConstDefs); result.append(m_variables); result.append(m_code); return result; } uint32_t SpirvModule::allocateId() { return m_id++; } void SpirvModule::enableCapability( spv::Capability capability) { // Scan the generated instructions to check // whether we already enabled the capability. for (auto ins : m_capabilities) { if (ins.opCode() == spv::OpCapability && ins.arg(1) == capability) return; } m_capabilities.putIns (spv::OpCapability, 2); m_capabilities.putWord(capability); } void SpirvModule::enableExtension( const char* extensionName) { m_extensions.putIns (spv::OpExtension, 1 + m_extensions.strLen(extensionName)); m_extensions.putStr (extensionName); } void SpirvModule::addEntryPoint( uint32_t entryPointId, spv::ExecutionModel executionModel, const char* name, uint32_t interfaceCount, const uint32_t* interfaceIds) { m_entryPoints.putIns (spv::OpEntryPoint, 3 + m_entryPoints.strLen(name) + interfaceCount); m_entryPoints.putWord (executionModel); m_entryPoints.putWord (entryPointId); m_entryPoints.putStr (name); for (uint32_t i = 0; i < interfaceCount; i++) m_entryPoints.putWord(interfaceIds[i]); } void SpirvModule::setMemoryModel( spv::AddressingModel addressModel, spv::MemoryModel memoryModel) { m_memoryModel.putIns (spv::OpMemoryModel, 3); m_memoryModel.putWord (addressModel); m_memoryModel.putWord (memoryModel); } void SpirvModule::setExecutionMode( uint32_t entryPointId, spv::ExecutionMode executionMode) { m_execModeInfo.putIns (spv::OpExecutionMode, 3); m_execModeInfo.putWord(entryPointId); m_execModeInfo.putWord(executionMode); } void SpirvModule::setInvocations( uint32_t entryPointId, uint32_t invocations) { m_execModeInfo.putIns (spv::OpExecutionMode, 4); m_execModeInfo.putWord (entryPointId); m_execModeInfo.putWord (spv::ExecutionModeInvocations); m_execModeInfo.putInt32(invocations); } void SpirvModule::setLocalSize( uint32_t entryPointId, uint32_t x, uint32_t y, uint32_t z) { m_execModeInfo.putIns (spv::OpExecutionMode, 6); m_execModeInfo.putWord (entryPointId); m_execModeInfo.putWord (spv::ExecutionModeLocalSize); m_execModeInfo.putInt32(x); m_execModeInfo.putInt32(y); m_execModeInfo.putInt32(z); } void SpirvModule::setOutputVertices( uint32_t entryPointId, uint32_t vertexCount) { m_execModeInfo.putIns (spv::OpExecutionMode, 4); m_execModeInfo.putWord(entryPointId); m_execModeInfo.putWord(spv::ExecutionModeOutputVertices); m_execModeInfo.putWord(vertexCount); } uint32_t SpirvModule::addDebugString( const char* string) { uint32_t resultId = this->allocateId(); m_debugNames.putIns (spv::OpString, 2 + m_debugNames.strLen(string)); m_debugNames.putWord(resultId); m_debugNames.putStr (string); return resultId; } void SpirvModule::setDebugSource( spv::SourceLanguage language, uint32_t version, uint32_t file, const char* source) { uint32_t strLen = source != nullptr ? m_debugNames.strLen(source) : 0; m_debugNames.putIns (spv::OpSource, 4 + strLen); m_debugNames.putWord(language); m_debugNames.putWord(version); m_debugNames.putWord(file); if (source != nullptr) m_debugNames.putStr(source); } void SpirvModule::setDebugName( uint32_t expressionId, const char* debugName) { m_debugNames.putIns (spv::OpName, 2 + m_debugNames.strLen(debugName)); m_debugNames.putWord(expressionId); m_debugNames.putStr (debugName); } void SpirvModule::setDebugMemberName( uint32_t structId, uint32_t memberId, const char* debugName) { m_debugNames.putIns (spv::OpMemberName, 3 + m_debugNames.strLen(debugName)); m_debugNames.putWord(structId); m_debugNames.putWord(memberId); m_debugNames.putStr (debugName); } uint32_t SpirvModule::constBool( bool v) { return this->defConst(v ? spv::OpConstantTrue : spv::OpConstantFalse, this->defBoolType(), 0, nullptr); } uint32_t SpirvModule::consti32( int32_t v) { std::array data; std::memcpy(data.data(), &v, sizeof(v)); return this->defConst( spv::OpConstant, this->defIntType(32, 1), data.size(), data.data()); } uint32_t SpirvModule::consti64( int64_t v) { std::array data; std::memcpy(data.data(), &v, sizeof(v)); return this->defConst( spv::OpConstant, this->defIntType(64, 1), data.size(), data.data()); } uint32_t SpirvModule::constu32( uint32_t v) { std::array data; std::memcpy(data.data(), &v, sizeof(v)); return this->defConst( spv::OpConstant, this->defIntType(32, 0), data.size(), data.data()); } uint32_t SpirvModule::constu64( uint64_t v) { std::array data; std::memcpy(data.data(), &v, sizeof(v)); return this->defConst( spv::OpConstant, this->defIntType(64, 0), data.size(), data.data()); } uint32_t SpirvModule::constf32( float v) { std::array data; std::memcpy(data.data(), &v, sizeof(v)); return this->defConst( spv::OpConstant, this->defFloatType(32), data.size(), data.data()); } uint32_t SpirvModule::constf64( double v) { std::array data; std::memcpy(data.data(), &v, sizeof(v)); return this->defConst( spv::OpConstant, this->defFloatType(64), data.size(), data.data()); } uint32_t SpirvModule::constvec4i32( int32_t x, int32_t y, int32_t z, int32_t w) { std::array args = {{ this->consti32(x), this->consti32(y), this->consti32(z), this->consti32(w), }}; uint32_t scalarTypeId = this->defIntType(32, 1); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4); return this->constComposite(vectorTypeId, args.size(), args.data()); } uint32_t SpirvModule::constvec4u32( uint32_t x, uint32_t y, uint32_t z, uint32_t w) { std::array args = {{ this->constu32(x), this->constu32(y), this->constu32(z), this->constu32(w), }}; uint32_t scalarTypeId = this->defIntType(32, 0); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4); return this->constComposite(vectorTypeId, args.size(), args.data()); } uint32_t SpirvModule::constvec2f32( float x, float y) { std::array args = {{ this->constf32(x), this->constf32(y), }}; uint32_t scalarTypeId = this->defFloatType(32); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 2); return this->constComposite(vectorTypeId, args.size(), args.data()); } uint32_t SpirvModule::constvec3f32( float x, float y, float z) { std::array args = {{ this->constf32(x), this->constf32(y), this->constf32(z), }}; uint32_t scalarTypeId = this->defFloatType(32); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 3); return this->constComposite(vectorTypeId, args.size(), args.data()); } uint32_t SpirvModule::constvec4f32( float x, float y, float z, float w) { std::array args = {{ this->constf32(x), this->constf32(y), this->constf32(z), this->constf32(w), }}; uint32_t scalarTypeId = this->defFloatType(32); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, 4); return this->constComposite(vectorTypeId, args.size(), args.data()); } uint32_t SpirvModule::constfReplicant( float replicant, uint32_t count) { uint32_t value = this->constf32(replicant); std::array args = { value, value, value, value }; // Can't make a scalar composite. if (count == 1) return args[0]; uint32_t scalarTypeId = this->defFloatType(32); uint32_t vectorTypeId = this->defVectorType(scalarTypeId, count); return this->constComposite(vectorTypeId, count, args.data()); } uint32_t SpirvModule::constComposite( uint32_t typeId, uint32_t constCount, const uint32_t* constIds) { return this->defConst( spv::OpConstantComposite, typeId, constCount, constIds); } uint32_t SpirvModule::constUndef( uint32_t typeId) { return this->defConst(spv::OpUndef, typeId, 0, nullptr); } uint32_t SpirvModule::lateConst32( uint32_t typeId) { uint32_t resultId = this->allocateId(); m_lateConsts.insert(resultId); m_typeConstDefs.putIns (spv::OpConstant, 4); m_typeConstDefs.putWord(typeId); m_typeConstDefs.putWord(resultId); m_typeConstDefs.putWord(0); return resultId; } void SpirvModule::setLateConst( uint32_t constId, const uint32_t* argIds) { for (auto ins : m_typeConstDefs) { if (ins.opCode() != spv::OpConstant && ins.opCode() != spv::OpConstantComposite) continue; if (ins.arg(2) != constId) continue; for (uint32_t i = 3; i < ins.length(); i++) ins.setArg(i, argIds[i - 3]); return; } } uint32_t SpirvModule::specConstBool( bool v) { uint32_t typeId = this->defBoolType(); uint32_t resultId = this->allocateId(); const spv::Op op = v ? spv::OpSpecConstantTrue : spv::OpSpecConstantFalse; m_typeConstDefs.putIns (op, 3); m_typeConstDefs.putWord (typeId); m_typeConstDefs.putWord (resultId); return resultId; } uint32_t SpirvModule::specConst32( uint32_t typeId, uint32_t value) { uint32_t resultId = this->allocateId(); m_typeConstDefs.putIns (spv::OpSpecConstant, 4); m_typeConstDefs.putWord (typeId); m_typeConstDefs.putWord (resultId); m_typeConstDefs.putWord (value); return resultId; } void SpirvModule::decorate( uint32_t object, spv::Decoration decoration) { m_annotations.putIns (spv::OpDecorate, 3); m_annotations.putWord (object); m_annotations.putWord (decoration); } void SpirvModule::decorateArrayStride( uint32_t object, uint32_t stride) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationArrayStride); m_annotations.putInt32(stride); } void SpirvModule::decorateBinding( uint32_t object, uint32_t binding) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationBinding); m_annotations.putInt32(binding); } void SpirvModule::decorateBlock(uint32_t object) { m_annotations.putIns (spv::OpDecorate, 3); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationBlock); } void SpirvModule::decorateBuiltIn( uint32_t object, spv::BuiltIn builtIn) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationBuiltIn); m_annotations.putWord (builtIn); } void SpirvModule::decorateComponent( uint32_t object, uint32_t location) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationComponent); m_annotations.putInt32(location); } void SpirvModule::decorateDescriptorSet( uint32_t object, uint32_t set) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationDescriptorSet); m_annotations.putInt32(set); } void SpirvModule::decorateIndex( uint32_t object, uint32_t index) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationIndex); m_annotations.putInt32(index); } void SpirvModule::decorateLocation( uint32_t object, uint32_t location) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationLocation); m_annotations.putInt32(location); } void SpirvModule::decorateSpecId( uint32_t object, uint32_t specId) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationSpecId); m_annotations.putInt32(specId); } void SpirvModule::decorateXfb( uint32_t object, uint32_t streamId, uint32_t bufferId, uint32_t offset, uint32_t stride) { m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationStream); m_annotations.putInt32(streamId); m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationXfbBuffer); m_annotations.putInt32(bufferId); m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationXfbStride); m_annotations.putInt32(stride); m_annotations.putIns (spv::OpDecorate, 4); m_annotations.putWord (object); m_annotations.putWord (spv::DecorationOffset); m_annotations.putInt32(offset); } void SpirvModule::memberDecorateBuiltIn( uint32_t structId, uint32_t memberId, spv::BuiltIn builtIn) { m_annotations.putIns (spv::OpMemberDecorate, 5); m_annotations.putWord (structId); m_annotations.putWord (memberId); m_annotations.putWord (spv::DecorationBuiltIn); m_annotations.putWord (builtIn); } void SpirvModule::memberDecorate( uint32_t structId, uint32_t memberId, spv::Decoration decoration) { m_annotations.putIns (spv::OpMemberDecorate, 4); m_annotations.putWord (structId); m_annotations.putWord (memberId); m_annotations.putWord (decoration); } void SpirvModule::memberDecorateMatrixStride( uint32_t structId, uint32_t memberId, uint32_t stride) { m_annotations.putIns (spv::OpMemberDecorate, 5); m_annotations.putWord (structId); m_annotations.putWord (memberId); m_annotations.putWord (spv::DecorationMatrixStride); m_annotations.putWord (stride); } void SpirvModule::memberDecorateOffset( uint32_t structId, uint32_t memberId, uint32_t offset) { m_annotations.putIns (spv::OpMemberDecorate, 5); m_annotations.putWord (structId); m_annotations.putWord (memberId); m_annotations.putWord (spv::DecorationOffset); m_annotations.putWord (offset); } uint32_t SpirvModule::defVoidType() { return this->defType(spv::OpTypeVoid, 0, nullptr); } uint32_t SpirvModule::defBoolType() { return this->defType(spv::OpTypeBool, 0, nullptr); } uint32_t SpirvModule::defIntType( uint32_t width, uint32_t isSigned) { std::array args = {{ width, isSigned }}; return this->defType(spv::OpTypeInt, args.size(), args.data()); } uint32_t SpirvModule::defFloatType( uint32_t width) { std::array args = {{ width }}; return this->defType(spv::OpTypeFloat, args.size(), args.data()); } uint32_t SpirvModule::defVectorType( uint32_t elementType, uint32_t elementCount) { std::array args = {{ elementType, elementCount }}; return this->defType(spv::OpTypeVector, args.size(), args.data()); } uint32_t SpirvModule::defMatrixType( uint32_t columnType, uint32_t columnCount) { std::array args = {{ columnType, columnCount }}; return this->defType(spv::OpTypeMatrix, args.size(), args.data()); } uint32_t SpirvModule::defArrayType( uint32_t typeId, uint32_t length) { std::array args = {{ typeId, length }}; return this->defType(spv::OpTypeArray, args.size(), args.data()); } uint32_t SpirvModule::defArrayTypeUnique( uint32_t typeId, uint32_t length) { uint32_t resultId = this->allocateId(); m_typeConstDefs.putIns (spv::OpTypeArray, 4); m_typeConstDefs.putWord(resultId); m_typeConstDefs.putWord(typeId); m_typeConstDefs.putWord(length); return resultId; } uint32_t SpirvModule::defRuntimeArrayType( uint32_t typeId) { std::array args = { typeId }; return this->defType(spv::OpTypeRuntimeArray, args.size(), args.data()); } uint32_t SpirvModule::defRuntimeArrayTypeUnique( uint32_t typeId) { uint32_t resultId = this->allocateId(); m_typeConstDefs.putIns (spv::OpTypeRuntimeArray, 3); m_typeConstDefs.putWord(resultId); m_typeConstDefs.putWord(typeId); return resultId; } uint32_t SpirvModule::defFunctionType( uint32_t returnType, uint32_t argCount, const uint32_t* argTypes) { std::vector args; args.push_back(returnType); for (uint32_t i = 0; i < argCount; i++) args.push_back(argTypes[i]); return this->defType(spv::OpTypeFunction, args.size(), args.data()); } uint32_t SpirvModule::defStructType( uint32_t memberCount, const uint32_t* memberTypes) { return this->defType(spv::OpTypeStruct, memberCount, memberTypes); } uint32_t SpirvModule::defStructTypeUnique( uint32_t memberCount, const uint32_t* memberTypes) { uint32_t resultId = this->allocateId(); m_typeConstDefs.putIns (spv::OpTypeStruct, 2 + memberCount); m_typeConstDefs.putWord(resultId); for (uint32_t i = 0; i < memberCount; i++) m_typeConstDefs.putWord(memberTypes[i]); return resultId; } uint32_t SpirvModule::defPointerType( uint32_t variableType, spv::StorageClass storageClass) { std::array args = {{ static_cast(storageClass), variableType, }}; return this->defType(spv::OpTypePointer, args.size(), args.data()); } uint32_t SpirvModule::defSamplerType() { return this->defType(spv::OpTypeSampler, 0, nullptr); } uint32_t SpirvModule::defImageType( uint32_t sampledType, spv::Dim dimensionality, uint32_t depth, uint32_t arrayed, uint32_t multisample, uint32_t sampled, spv::ImageFormat format) { std::array args = {{ sampledType, static_cast(dimensionality), depth, arrayed, multisample, sampled, static_cast(format) }}; return this->defType(spv::OpTypeImage, args.size(), args.data()); } uint32_t SpirvModule::defSampledImageType( uint32_t imageType) { return this->defType(spv::OpTypeSampledImage, 1, &imageType); } uint32_t SpirvModule::newVar( uint32_t pointerType, spv::StorageClass storageClass) { uint32_t resultId = this->allocateId(); auto& code = storageClass != spv::StorageClassFunction ? m_variables : m_code; code.putIns (spv::OpVariable, 4); code.putWord (pointerType); code.putWord (resultId); code.putWord (storageClass); return resultId; } uint32_t SpirvModule::newVarInit( uint32_t pointerType, spv::StorageClass storageClass, uint32_t initialValue) { uint32_t resultId = this->allocateId(); auto& code = storageClass != spv::StorageClassFunction ? m_variables : m_code; code.putIns (spv::OpVariable, 5); code.putWord (pointerType); code.putWord (resultId); code.putWord (storageClass); code.putWord (initialValue); return resultId; } void SpirvModule::functionBegin( uint32_t returnType, uint32_t functionId, uint32_t functionType, spv::FunctionControlMask functionControl) { m_code.putIns (spv::OpFunction, 5); m_code.putWord(returnType); m_code.putWord(functionId); m_code.putWord(functionControl); m_code.putWord(functionType); } uint32_t SpirvModule::functionParameter( uint32_t parameterType) { uint32_t parameterId = this->allocateId(); m_code.putIns (spv::OpFunctionParameter, 3); m_code.putWord(parameterType); m_code.putWord(parameterId); return parameterId; } void SpirvModule::functionEnd() { m_code.putIns (spv::OpFunctionEnd, 1); } uint32_t SpirvModule::opAccessChain( uint32_t resultType, uint32_t composite, uint32_t indexCount, const uint32_t* indexArray) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAccessChain, 4 + indexCount); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(composite); for (uint32_t i = 0; i < indexCount; i++) m_code.putInt32(indexArray[i]); return resultId; } uint32_t SpirvModule::opArrayLength( uint32_t resultType, uint32_t structure, uint32_t memberId) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpArrayLength, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(structure); m_code.putWord(memberId); return resultId; } uint32_t SpirvModule::opAny( uint32_t resultType, uint32_t vector) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAny, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector); return resultId; } uint32_t SpirvModule::opAll( uint32_t resultType, uint32_t vector) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAll, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector); return resultId; } uint32_t SpirvModule::opAtomicLoad( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicLoad, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); return resultId; } void SpirvModule::opAtomicStore( uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { m_code.putIns (spv::OpAtomicStore, 5); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); } uint32_t SpirvModule::opAtomicExchange( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicExchange, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicCompareExchange( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t equal, uint32_t unequal, uint32_t value, uint32_t comparator) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicCompareExchange, 9); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(equal); m_code.putWord(unequal); m_code.putWord(value); m_code.putWord(comparator); return resultId; } uint32_t SpirvModule::opAtomicIIncrement( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicIIncrement, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); return resultId; } uint32_t SpirvModule::opAtomicIDecrement( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicIDecrement, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); return resultId; } uint32_t SpirvModule::opAtomicIAdd( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicIAdd, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicISub( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicISub, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicSMin( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicSMin, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicSMax( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicSMax, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicUMin( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicUMin, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicUMax( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicUMax, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicAnd( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicAnd, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicOr( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicOr, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opAtomicXor( uint32_t resultType, uint32_t pointer, uint32_t scope, uint32_t semantics, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpAtomicXor, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(pointer); m_code.putWord(scope); m_code.putWord(semantics); m_code.putWord(value); return resultId; } uint32_t SpirvModule::opBitcast( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitcast, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opBitCount( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitCount, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opBitReverse( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitReverse, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFindILsb( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FindILsb); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFindUMsb( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FindUMsb); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFindSMsb( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FindSMsb); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opBitFieldInsert( uint32_t resultType, uint32_t base, uint32_t insert, uint32_t offset, uint32_t count) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitFieldInsert, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(base); m_code.putWord(insert); m_code.putWord(offset); m_code.putWord(count); return resultId; } uint32_t SpirvModule::opBitFieldSExtract( uint32_t resultType, uint32_t base, uint32_t offset, uint32_t count) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitFieldSExtract, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(base); m_code.putWord(offset); m_code.putWord(count); return resultId; } uint32_t SpirvModule::opBitFieldUExtract( uint32_t resultType, uint32_t base, uint32_t offset, uint32_t count) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitFieldUExtract, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(base); m_code.putWord(offset); m_code.putWord(count); return resultId; } uint32_t SpirvModule::opBitwiseAnd( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitwiseAnd, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opBitwiseOr( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitwiseOr, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opBitwiseXor( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpBitwiseXor, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opNot( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpNot, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opShiftLeftLogical( uint32_t resultType, uint32_t base, uint32_t shift) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpShiftLeftLogical, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(base); m_code.putWord(shift); return resultId; } uint32_t SpirvModule::opShiftRightArithmetic( uint32_t resultType, uint32_t base, uint32_t shift) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpShiftRightArithmetic, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(base); m_code.putWord(shift); return resultId; } uint32_t SpirvModule::opShiftRightLogical( uint32_t resultType, uint32_t base, uint32_t shift) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpShiftRightLogical, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(base); m_code.putWord(shift); return resultId; } uint32_t SpirvModule::opConvertFtoS( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpConvertFToS, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opConvertFtoU( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpConvertFToU, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opConvertStoF( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpConvertSToF, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opConvertUtoF( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpConvertUToF, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opCompositeConstruct( uint32_t resultType, uint32_t valueCount, const uint32_t* valueArray) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpCompositeConstruct, 3 + valueCount); m_code.putWord(resultType); m_code.putWord(resultId); for (uint32_t i = 0; i < valueCount; i++) m_code.putWord(valueArray[i]); return resultId; } uint32_t SpirvModule::opCompositeExtract( uint32_t resultType, uint32_t composite, uint32_t indexCount, const uint32_t* indexArray) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpCompositeExtract, 4 + indexCount); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(composite); for (uint32_t i = 0; i < indexCount; i++) m_code.putInt32(indexArray[i]); return resultId; } uint32_t SpirvModule::opCompositeInsert( uint32_t resultType, uint32_t object, uint32_t composite, uint32_t indexCount, const uint32_t* indexArray) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpCompositeInsert, 5 + indexCount); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(object); m_code.putWord(composite); for (uint32_t i = 0; i < indexCount; i++) m_code.putInt32(indexArray[i]); return resultId; } uint32_t SpirvModule::opDpdx( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDPdx, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opDpdy( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDPdy, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opDpdxCoarse( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDPdxCoarse, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opDpdyCoarse( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDPdyCoarse, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opDpdxFine( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDPdxFine, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opDpdyFine( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDPdyFine, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opVectorExtractDynamic( uint32_t resultType, uint32_t vector, uint32_t index) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpVectorExtractDynamic, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector); m_code.putWord(index); return resultId; } uint32_t SpirvModule::opVectorShuffle( uint32_t resultType, uint32_t vectorLeft, uint32_t vectorRight, uint32_t indexCount, const uint32_t* indexArray) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpVectorShuffle, 5 + indexCount); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vectorLeft); m_code.putWord(vectorRight); for (uint32_t i = 0; i < indexCount; i++) m_code.putInt32(indexArray[i]); return resultId; } uint32_t SpirvModule::opSNegate( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSNegate, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFNegate( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFNegate, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opSAbs( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450SAbs); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFAbs( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FAbs); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFMix( uint32_t resultType, uint32_t x, uint32_t y, uint32_t a) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 8); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FMix); m_code.putWord(x); m_code.putWord(y); m_code.putWord(a); return resultId; } uint32_t SpirvModule::opCross( uint32_t resultType, uint32_t x, uint32_t y) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Cross); m_code.putWord(x); m_code.putWord(y); return resultId; } uint32_t SpirvModule::opIAdd( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpIAdd, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opISub( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpISub, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opFAdd( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFAdd, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opFSub( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFSub, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opSDiv( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSDiv, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opUDiv( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpUDiv, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opSRem( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSRem, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opUMod( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpUMod, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opFDiv( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFDiv, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opIMul( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpIMul, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opFMul( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFMul, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opVectorTimesScalar( uint32_t resultType, uint32_t vector, uint32_t scalar) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpVectorTimesScalar, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector); m_code.putWord(scalar); return resultId; } uint32_t SpirvModule::opMatrixTimesMatrix( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpMatrixTimesMatrix, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opMatrixTimesVector( uint32_t resultType, uint32_t matrix, uint32_t vector) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpMatrixTimesVector, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(matrix); m_code.putWord(vector); return resultId; } uint32_t SpirvModule::opVectorTimesMatrix( uint32_t resultType, uint32_t vector, uint32_t matrix) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpVectorTimesMatrix, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector); m_code.putWord(matrix); return resultId; } uint32_t SpirvModule::opTranspose( uint32_t resultType, uint32_t matrix) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpTranspose, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(matrix); return resultId; } uint32_t SpirvModule::opInverse( uint32_t resultType, uint32_t matrix) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450MatrixInverse); m_code.putWord(matrix); return resultId; } uint32_t SpirvModule::opFFma( uint32_t resultType, uint32_t a, uint32_t b, uint32_t c) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 8); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Fma); m_code.putWord(a); m_code.putWord(b); m_code.putWord(c); return resultId; } uint32_t SpirvModule::opFMax( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FMax); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opFMin( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FMin); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opNMax( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450NMax); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opNMin( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450NMin); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opSMax( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450SMax); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opSMin( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450SMin); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opUMax( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450UMax); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opUMin( uint32_t resultType, uint32_t a, uint32_t b) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450UMin); m_code.putWord(a); m_code.putWord(b); return resultId; } uint32_t SpirvModule::opFClamp( uint32_t resultType, uint32_t x, uint32_t minVal, uint32_t maxVal) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 8); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450FClamp); m_code.putWord(x); m_code.putWord(minVal); m_code.putWord(maxVal); return resultId; } uint32_t SpirvModule::opNClamp( uint32_t resultType, uint32_t x, uint32_t minVal, uint32_t maxVal) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 8); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450NClamp); m_code.putWord(x); m_code.putWord(minVal); m_code.putWord(maxVal); return resultId; } uint32_t SpirvModule::opIEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpIEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opINotEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpINotEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opSLessThan( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSLessThan, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opSLessThanEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSLessThanEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opSGreaterThan( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSGreaterThan, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opSGreaterThanEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSGreaterThanEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opULessThan( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpULessThan, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opULessThanEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpULessThanEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opUGreaterThan( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpUGreaterThan, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opUGreaterThanEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpUGreaterThanEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opFOrdEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFOrdEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opFOrdNotEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFOrdNotEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opFOrdLessThan( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFOrdLessThan, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opFOrdLessThanEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFOrdLessThanEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opFOrdGreaterThan( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFOrdGreaterThan, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opFOrdGreaterThanEqual( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFOrdGreaterThanEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opLogicalEqual( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpLogicalEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opLogicalNotEqual( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpLogicalNotEqual, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opLogicalAnd( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpLogicalAnd, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opLogicalOr( uint32_t resultType, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpLogicalOr, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opLogicalNot( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpLogicalNot, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opDot( uint32_t resultType, uint32_t vector1, uint32_t vector2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpDot, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(vector1); m_code.putWord(vector2); return resultId; } uint32_t SpirvModule::opSin( uint32_t resultType, uint32_t vector) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Sin); m_code.putWord(vector); return resultId; } uint32_t SpirvModule::opCos( uint32_t resultType, uint32_t vector) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Cos); m_code.putWord(vector); return resultId; } uint32_t SpirvModule::opSqrt( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Sqrt); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opInverseSqrt( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450InverseSqrt); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opNormalize( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Normalize); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opLength( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Length); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opExp2( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Exp2); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opExp( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Exp); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opLog2( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Log2); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opPow( uint32_t resultType, uint32_t base, uint32_t exponent) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Pow); m_code.putWord(base); m_code.putWord(exponent); return resultId; } uint32_t SpirvModule::opFract( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Fract); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opCeil( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Ceil); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFloor( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Floor); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opRound( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Round); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opRoundEven( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450RoundEven); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opTrunc( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450Trunc); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFConvert( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFConvert, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opPackHalf2x16( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450PackHalf2x16); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opUnpackHalf2x16( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450UnpackHalf2x16); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opSelect( uint32_t resultType, uint32_t condition, uint32_t operand1, uint32_t operand2) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSelect, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(condition); m_code.putWord(operand1); m_code.putWord(operand2); return resultId; } uint32_t SpirvModule::opIsNan( uint32_t resultType, uint32_t operand) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpIsNan, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(operand); return resultId; } uint32_t SpirvModule::opFunctionCall( uint32_t resultType, uint32_t functionId, uint32_t argCount, const uint32_t* argIds) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpFunctionCall, 4 + argCount); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(functionId); for (uint32_t i = 0; i < argCount; i++) m_code.putWord(argIds[i]); return resultId; } void SpirvModule::opLabel(uint32_t labelId) { m_code.putIns (spv::OpLabel, 2); m_code.putWord(labelId); } uint32_t SpirvModule::opLoad( uint32_t typeId, uint32_t pointerId) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpLoad, 4); m_code.putWord(typeId); m_code.putWord(resultId); m_code.putWord(pointerId); return resultId; } void SpirvModule::opStore( uint32_t pointerId, uint32_t valueId) { m_code.putIns (spv::OpStore, 3); m_code.putWord(pointerId); m_code.putWord(valueId); } uint32_t SpirvModule::opInterpolateAtCentroid( uint32_t resultType, uint32_t interpolant) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450InterpolateAtCentroid); m_code.putWord(interpolant); return resultId; } uint32_t SpirvModule::opInterpolateAtSample( uint32_t resultType, uint32_t interpolant, uint32_t sample) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450InterpolateAtSample); m_code.putWord(interpolant); m_code.putWord(sample); return resultId; } uint32_t SpirvModule::opInterpolateAtOffset( uint32_t resultType, uint32_t interpolant, uint32_t offset) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpExtInst, 7); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(m_instExtGlsl450); m_code.putWord(spv::GLSLstd450InterpolateAtOffset); m_code.putWord(interpolant); m_code.putWord(offset); return resultId; } uint32_t SpirvModule::opImageRead( uint32_t resultType, uint32_t image, uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageRead, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); m_code.putWord(coordinates); putImageOperands(operands); return resultId; } void SpirvModule::opImageWrite( uint32_t image, uint32_t coordinates, uint32_t texel, const SpirvImageOperands& operands) { m_code.putIns (spv::OpImageWrite, 4 + getImageOperandWordCount(operands)); m_code.putWord(image); m_code.putWord(coordinates); m_code.putWord(texel); putImageOperands(operands); } uint32_t SpirvModule::opSampledImage( uint32_t resultType, uint32_t image, uint32_t sampler) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpSampledImage, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); m_code.putWord(sampler); return resultId; } uint32_t SpirvModule::opImageTexelPointer( uint32_t resultType, uint32_t image, uint32_t coordinates, uint32_t sample) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageTexelPointer, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); m_code.putWord(coordinates); m_code.putWord(sample); return resultId; } uint32_t SpirvModule::opImageQuerySizeLod( uint32_t resultType, uint32_t image, uint32_t lod) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageQuerySizeLod, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); m_code.putWord(lod); return resultId; } uint32_t SpirvModule::opImageQuerySize( uint32_t resultType, uint32_t image) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageQuerySize, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); return resultId; } uint32_t SpirvModule::opImageQueryLevels( uint32_t resultType, uint32_t image) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageQueryLevels, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); return resultId; } uint32_t SpirvModule::opImageQueryLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageQueryLod, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); return resultId; } uint32_t SpirvModule::opImageQuerySamples( uint32_t resultType, uint32_t image) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpImageQuerySamples, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); return resultId; } uint32_t SpirvModule::opImageFetch( uint32_t resultType, uint32_t image, uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageFetch, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(image); m_code.putWord(coordinates); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageGather( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, uint32_t component, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageGather, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); m_code.putWord(component); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageDrefGather( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, uint32_t reference, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageDrefGather, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); m_code.putWord(reference); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleImplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleImplicitLod, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleExplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleExplicitLod, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleProjImplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleProjImplicitLod, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleProjExplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleProjExplicitLod, 5 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleDrefImplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, uint32_t reference, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleDrefImplicitLod, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); m_code.putWord(reference); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleDrefExplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, uint32_t reference, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleDrefExplicitLod, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); m_code.putWord(reference); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleProjDrefImplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, uint32_t reference, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleProjDrefImplicitLod, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); m_code.putWord(reference); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opImageSampleProjDrefExplicitLod( uint32_t resultType, uint32_t sampledImage, uint32_t coordinates, uint32_t reference, const SpirvImageOperands& operands) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpImageSampleProjDrefExplicitLod, 6 + getImageOperandWordCount(operands)); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(sampledImage); m_code.putWord(coordinates); m_code.putWord(reference); putImageOperands(operands); return resultId; } uint32_t SpirvModule::opGroupNonUniformBallot( uint32_t resultType, uint32_t execution, uint32_t predicate) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpGroupNonUniformBallot, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(execution); m_code.putWord(predicate); return resultId; } uint32_t SpirvModule::opGroupNonUniformBallotBitCount( uint32_t resultType, uint32_t execution, uint32_t operation, uint32_t ballot) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpGroupNonUniformBallotBitCount, 6); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(execution); m_code.putWord(operation); m_code.putWord(ballot); return resultId; } uint32_t SpirvModule::opGroupNonUniformElect( uint32_t resultType, uint32_t execution) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpGroupNonUniformElect, 4); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(execution); return resultId; } uint32_t SpirvModule::opGroupNonUniformBroadcastFirst( uint32_t resultType, uint32_t execution, uint32_t value) { uint32_t resultId = this->allocateId(); m_code.putIns(spv::OpGroupNonUniformBroadcastFirst, 5); m_code.putWord(resultType); m_code.putWord(resultId); m_code.putWord(execution); m_code.putWord(value); return resultId; } void SpirvModule::opControlBarrier( uint32_t execution, uint32_t memory, uint32_t semantics) { m_code.putIns (spv::OpControlBarrier, 4); m_code.putWord(execution); m_code.putWord(memory); m_code.putWord(semantics); } void SpirvModule::opMemoryBarrier( uint32_t memory, uint32_t semantics) { m_code.putIns (spv::OpMemoryBarrier, 3); m_code.putWord(memory); m_code.putWord(semantics); } void SpirvModule::opLoopMerge( uint32_t mergeBlock, uint32_t continueTarget, uint32_t loopControl) { m_code.putIns (spv::OpLoopMerge, 4); m_code.putWord(mergeBlock); m_code.putWord(continueTarget); m_code.putWord(loopControl); } void SpirvModule::opSelectionMerge( uint32_t mergeBlock, uint32_t selectionControl) { m_code.putIns (spv::OpSelectionMerge, 3); m_code.putWord(mergeBlock); m_code.putWord(selectionControl); } void SpirvModule::opBranch( uint32_t label) { m_code.putIns (spv::OpBranch, 2); m_code.putWord(label); } void SpirvModule::opBranchConditional( uint32_t condition, uint32_t trueLabel, uint32_t falseLabel) { m_code.putIns (spv::OpBranchConditional, 4); m_code.putWord(condition); m_code.putWord(trueLabel); m_code.putWord(falseLabel); } void SpirvModule::opSwitch( uint32_t selector, uint32_t jumpDefault, uint32_t caseCount, const SpirvSwitchCaseLabel* caseLabels) { m_code.putIns (spv::OpSwitch, 3 + 2 * caseCount); m_code.putWord(selector); m_code.putWord(jumpDefault); for (uint32_t i = 0; i < caseCount; i++) { m_code.putWord(caseLabels[i].literal); m_code.putWord(caseLabels[i].labelId); } } uint32_t SpirvModule::opPhi( uint32_t resultType, uint32_t sourceCount, const SpirvPhiLabel* sourceLabels) { uint32_t resultId = this->allocateId(); m_code.putIns (spv::OpPhi, 3 + 2 * sourceCount); m_code.putWord(resultType); m_code.putWord(resultId); for (uint32_t i = 0; i < sourceCount; i++) { m_code.putWord(sourceLabels[i].varId); m_code.putWord(sourceLabels[i].labelId); } return resultId; } void SpirvModule::opReturn() { m_code.putIns (spv::OpReturn, 1); } void SpirvModule::opKill() { m_code.putIns (spv::OpKill, 1); } void SpirvModule::opDemoteToHelperInvocation() { m_code.putIns (spv::OpDemoteToHelperInvocationEXT, 1); } void SpirvModule::opEmitVertex( uint32_t streamId) { if (streamId == 0) { m_code.putIns (spv::OpEmitVertex, 1); } else { m_code.putIns (spv::OpEmitStreamVertex, 2); m_code.putWord(streamId); } } void SpirvModule::opEndPrimitive( uint32_t streamId) { if (streamId == 0) { m_code.putIns (spv::OpEndPrimitive, 1); } else { m_code.putIns (spv::OpEndStreamPrimitive, 2); m_code.putWord(streamId); } } uint32_t SpirvModule::defType( spv::Op op, uint32_t argCount, const uint32_t* argIds) { // Since the type info is stored in the code buffer, // we can use the code buffer to look up type IDs as // well. Result IDs are always stored as argument 1. for (auto ins : m_typeConstDefs) { bool match = ins.opCode() == op && ins.length() == 2 + argCount; for (uint32_t i = 0; i < argCount && match; i++) match &= ins.arg(2 + i) == argIds[i]; if (match) return ins.arg(1); } // Type not yet declared, create a new one. uint32_t resultId = this->allocateId(); m_typeConstDefs.putIns (op, 2 + argCount); m_typeConstDefs.putWord(resultId); for (uint32_t i = 0; i < argCount; i++) m_typeConstDefs.putWord(argIds[i]); return resultId; } uint32_t SpirvModule::defConst( spv::Op op, uint32_t typeId, uint32_t argCount, const uint32_t* argIds) { // Avoid declaring constants multiple times for (auto ins : m_typeConstDefs) { bool match = ins.opCode() == op && ins.length() == 3 + argCount && ins.arg(1) == typeId; for (uint32_t i = 0; i < argCount && match; i++) match &= ins.arg(3 + i) == argIds[i]; if (!match) continue; uint32_t id = ins.arg(2); if (m_lateConsts.find(id) == m_lateConsts.end()) return id; } // Constant not yet declared, make a new one uint32_t resultId = this->allocateId(); m_typeConstDefs.putIns (op, 3 + argCount); m_typeConstDefs.putWord(typeId); m_typeConstDefs.putWord(resultId); for (uint32_t i = 0; i < argCount; i++) m_typeConstDefs.putWord(argIds[i]); return resultId; } void SpirvModule::instImportGlsl450() { m_instExtGlsl450 = this->allocateId(); const char* name = "GLSL.std.450"; m_instExt.putIns (spv::OpExtInstImport, 2 + m_instExt.strLen(name)); m_instExt.putWord(m_instExtGlsl450); m_instExt.putStr (name); } uint32_t SpirvModule::getImageOperandWordCount(const SpirvImageOperands& op) const { // Each flag may add one or more operands const uint32_t result = ((op.flags & spv::ImageOperandsBiasMask) ? 1 : 0) + ((op.flags & spv::ImageOperandsLodMask) ? 1 : 0) + ((op.flags & spv::ImageOperandsConstOffsetMask) ? 1 : 0) + ((op.flags & spv::ImageOperandsGradMask) ? 2 : 0) + ((op.flags & spv::ImageOperandsOffsetMask) ? 1 : 0) + ((op.flags & spv::ImageOperandsConstOffsetsMask)? 1 : 0) + ((op.flags & spv::ImageOperandsSampleMask) ? 1 : 0) + ((op.flags & spv::ImageOperandsMinLodMask) ? 1 : 0); // Add a DWORD for the operand mask if it is non-zero return result != 0 ? result + 1 : 0; } void SpirvModule::putImageOperands(const SpirvImageOperands& op) { if (op.flags != 0) { m_code.putWord(op.flags); if (op.flags & spv::ImageOperandsBiasMask) m_code.putWord(op.sLodBias); if (op.flags & spv::ImageOperandsLodMask) m_code.putWord(op.sLod); if (op.flags & spv::ImageOperandsConstOffsetMask) m_code.putWord(op.sConstOffset); if (op.flags & spv::ImageOperandsGradMask) { m_code.putWord(op.sGradX); m_code.putWord(op.sGradY); } if (op.flags & spv::ImageOperandsOffsetMask) m_code.putWord(op.gOffset); if (op.flags & spv::ImageOperandsConstOffsetsMask) m_code.putWord(op.gConstOffsets); if (op.flags & spv::ImageOperandsSampleMask) m_code.putWord(op.sSampleId); if (op.flags & spv::ImageOperandsMinLodMask) m_code.putWord(op.sMinLod); } } }