summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/bgfx/src/shader_spirv.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/bgfx/src/shader_spirv.cpp')
-rw-r--r--3rdparty/bgfx/src/shader_spirv.cpp732
1 files changed, 732 insertions, 0 deletions
diff --git a/3rdparty/bgfx/src/shader_spirv.cpp b/3rdparty/bgfx/src/shader_spirv.cpp
new file mode 100644
index 00000000000..40bf7acbb6f
--- /dev/null
+++ b/3rdparty/bgfx/src/shader_spirv.cpp
@@ -0,0 +1,732 @@
+/*
+ * Copyright 2011-2015 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "bgfx_p.h"
+#include "shader_spirv.h"
+
+namespace bgfx
+{
+ struct SpirvOpcodeInfo
+ {
+ uint8_t numOperands;
+ uint8_t numValues;
+ bool hasVariable;
+ };
+
+ static const SpirvOpcodeInfo s_sprivOpcodeInfo[] =
+ {
+ { 0, 0, false }, // Nop,
+ { 0, 0, true }, // Source
+ { 0, 0, true }, // SourceExtension
+ { 0, 0, false }, // Extension
+ { 0, 1, true }, // ExtInstImport
+ { 0, 2, false }, // MemoryModel
+ { 0, 2, false }, // EntryPoint
+ { 0, 0, false }, // ExecutionMode
+ { 0, 1, false }, // TypeVoid
+ { 0, 1, false }, // TypeBool
+ { 0, 3, false }, // TypeInt
+ { 0, 2, false }, // TypeFloat
+ { 0, 3, false }, // TypeVector
+ { 0, 3, false }, // TypeMatrix
+ { 1, 7, false }, // TypeSampler
+ { 0, 0, false }, // TypeFilter
+ { 0, 0, false }, // TypeArray
+ { 0, 0, false }, // TypeRuntimeArray
+ { 0, 0, false }, // TypeStruct
+ { 0, 0, false }, // TypeOpaque
+ { 0, 3, false }, // TypePointer
+ { 0, 2, true }, // TypeFunction
+ { 0, 0, false }, // TypeEvent
+ { 0, 0, false }, // TypeDeviceEvent
+ { 0, 0, false }, // TypeReserveId
+ { 0, 0, false }, // TypeQueue
+ { 0, 0, false }, // TypePipe
+ { 0, 0, false }, // ConstantTrue
+ { 0, 0, false }, // ConstantFalse
+ { 0, 2, true }, // Constant
+ { 0, 2, true }, // ConstantComposite
+ { 0, 0, false }, // ConstantSampler
+ { 0, 0, false }, // ConstantNullPointer
+ { 0, 0, false }, // ConstantNullObject
+ { 0, 0, false }, // SpecConstantTrue
+ { 0, 0, false }, // SpecConstantFalse
+ { 0, 0, false }, // SpecConstant
+ { 0, 0, false }, // SpecConstantComposite
+ { 0, 3, true }, // Variable
+ { 0, 0, false }, // VariableArray
+ { 0, 4, false }, // Function
+ { 0, 0, false }, // FunctionParameter
+ { 0, 0, false }, // FunctionEnd
+ { 0, 0, false }, // FunctionCall
+ { 0, 0, false }, // ExtInst
+ { 0, 0, false }, // Undef
+ { 0, 0, false }, // Load
+ { 0, 2, true }, // Store
+ { 0, 0, false }, // Phi
+ { 0, 0, false }, // DecorationGroup
+ { 0, 2, true }, // Decorate
+ { 0, 0, false }, // MemberDecorate
+ { 0, 0, false }, // GroupDecorate
+ { 0, 0, false }, // GroupMemberDecorate
+ { 0, 1, true }, // Name
+ { 0, 1, true }, // MemberName
+ { 0, 0, false }, // String
+ { 0, 0, false }, // Line
+ { 0, 0, false }, // VectorExtractDynamic
+ { 0, 0, false }, // VectorInsertDynamic
+ { 0, 0, false }, // VectorShuffle
+ { 0, 0, false }, // CompositeConstruct
+ { 0, 0, false }, // CompositeExtract
+ { 0, 0, false }, // CompositeInsert
+ { 0, 0, false }, // CopyObject
+ { 0, 0, false }, // CopyMemory
+ { 0, 0, false }, // CopyMemorySized
+ { 0, 0, false }, // Sampler
+ { 0, 0, false }, // TextureSample
+ { 0, 0, false }, // TextureSampleDref
+ { 0, 0, false }, // TextureSampleLod
+ { 0, 0, false }, // TextureSampleProj
+ { 0, 0, false }, // TextureSampleGrad
+ { 0, 0, false }, // TextureSampleOffset
+ { 0, 0, false }, // TextureSampleProjLod
+ { 0, 0, false }, // TextureSampleProjGrad
+ { 0, 0, false }, // TextureSampleLodOffset
+ { 0, 0, false }, // TextureSampleProjOffset
+ { 0, 0, false }, // TextureSampleGradOffset
+ { 0, 0, false }, // TextureSampleProjLodOffset
+ { 0, 0, false }, // TextureSampleProjGradOffset
+ { 0, 0, false }, // TextureFetchTexelLod
+ { 0, 0, false }, // TextureFetchTexelOffset
+ { 0, 0, false }, // TextureFetchSample
+ { 0, 0, false }, // TextureFetchTexel
+ { 0, 0, false }, // TextureGather
+ { 0, 0, false }, // TextureGatherOffset
+ { 0, 0, false }, // TextureGatherOffsets
+ { 0, 0, false }, // TextureQuerySizeLod
+ { 0, 0, false }, // TextureQuerySize
+ { 0, 0, false }, // TextureQueryLod
+ { 0, 0, false }, // TextureQueryLevels
+ { 0, 0, false }, // TextureQuerySamples
+ { 0, 0, false }, // AccessChain
+ { 0, 0, false }, // InBoundsAccessChain
+ { 0, 0, false }, // SNegate
+ { 0, 0, false }, // FNegate
+ { 0, 0, false }, // Not
+ { 0, 0, false }, // Any
+ { 0, 0, false }, // All
+ { 0, 0, false }, // ConvertFToU
+ { 0, 0, false }, // ConvertFToS
+ { 0, 0, false }, // ConvertSToF
+ { 0, 0, false }, // ConvertUToF
+ { 0, 0, false }, // UConvert
+ { 0, 0, false }, // SConvert
+ { 0, 0, false }, // FConvert
+ { 0, 0, false }, // ConvertPtrToU
+ { 0, 0, false }, // ConvertUToPtr
+ { 0, 0, false }, // PtrCastToGeneric
+ { 0, 0, false }, // GenericCastToPtr
+ { 0, 0, false }, // Bitcast
+ { 0, 0, false }, // Transpose
+ { 0, 0, false }, // IsNan
+ { 0, 0, false }, // IsInf
+ { 0, 0, false }, // IsFinite
+ { 0, 0, false }, // IsNormal
+ { 0, 0, false }, // SignBitSet
+ { 0, 0, false }, // LessOrGreater
+ { 0, 0, false }, // Ordered
+ { 0, 0, false }, // Unordered
+ { 0, 0, false }, // ArrayLength
+ { 0, 0, false }, // IAdd
+ { 0, 0, false }, // FAdd
+ { 0, 0, false }, // ISub
+ { 0, 0, false }, // FSub
+ { 0, 0, false }, // IMul
+ { 0, 0, false }, // FMul
+ { 0, 0, false }, // UDiv
+ { 0, 0, false }, // SDiv
+ { 0, 0, false }, // FDiv
+ { 0, 0, false }, // UMod
+ { 0, 0, false }, // SRem
+ { 0, 0, false }, // SMod
+ { 0, 0, false }, // FRem
+ { 0, 0, false }, // FMod
+ { 0, 0, false }, // VectorTimesScalar
+ { 0, 0, false }, // MatrixTimesScalar
+ { 0, 0, false }, // VectorTimesMatrix
+ { 0, 0, false }, // MatrixTimesVector
+ { 0, 0, false }, // MatrixTimesMatrix
+ { 0, 0, false }, // OuterProduct
+ { 0, 0, false }, // Dot
+ { 0, 0, false }, // ShiftRightLogical
+ { 0, 0, false }, // ShiftRightArithmetic
+ { 0, 0, false }, // ShiftLeftLogical
+ { 0, 0, false }, // LogicalOr
+ { 0, 0, false }, // LogicalXor
+ { 0, 0, false }, // LogicalAnd
+ { 0, 0, false }, // BitwiseOr
+ { 0, 0, false }, // BitwiseXor
+ { 0, 0, false }, // BitwiseAnd
+ { 0, 0, false }, // Select
+ { 0, 0, false }, // IEqual
+ { 0, 0, false }, // FOrdEqual
+ { 0, 0, false }, // FUnordEqual
+ { 0, 0, false }, // INotEqual
+ { 0, 0, false }, // FOrdNotEqual
+ { 0, 0, false }, // FUnordNotEqual
+ { 0, 0, false }, // ULessThan
+ { 0, 0, false }, // SLessThan
+ { 0, 0, false }, // FOrdLessThan
+ { 0, 0, false }, // FUnordLessThan
+ { 0, 0, false }, // UGreaterThan
+ { 0, 0, false }, // SGreaterThan
+ { 0, 0, false }, // FOrdGreaterThan
+ { 0, 0, false }, // FUnordGreaterThan
+ { 0, 0, false }, // ULessThanEqual
+ { 0, 0, false }, // SLessThanEqual
+ { 0, 0, false }, // FOrdLessThanEqual
+ { 0, 0, false }, // FUnordLessThanEqual
+ { 0, 0, false }, // UGreaterThanEqual
+ { 0, 0, false }, // SGreaterThanEqual
+ { 0, 0, false }, // FOrdGreaterThanEqual
+ { 0, 0, false }, // FUnordGreaterThanEqual
+ { 0, 0, false }, // DPdx
+ { 0, 0, false }, // DPdy
+ { 0, 0, false }, // Fwidth
+ { 0, 0, false }, // DPdxFine
+ { 0, 0, false }, // DPdyFine
+ { 0, 0, false }, // FwidthFine
+ { 0, 0, false }, // DPdxCoarse
+ { 0, 0, false }, // DPdyCoarse
+ { 0, 0, false }, // FwidthCoarse
+ { 0, 0, false }, // EmitVertex
+ { 0, 0, false }, // EndPrimitive
+ { 0, 0, false }, // EmitStreamVertex
+ { 0, 0, false }, // EndStreamPrimitive
+ { 0, 0, false }, // ControlBarrier
+ { 0, 0, false }, // MemoryBarrier
+ { 0, 0, false }, // ImagePointer
+ { 0, 0, false }, // AtomicInit
+ { 0, 0, false }, // AtomicLoad
+ { 0, 0, false }, // AtomicStore
+ { 0, 0, false }, // AtomicExchange
+ { 0, 0, false }, // AtomicCompareExchange
+ { 0, 0, false }, // AtomicCompareExchangeWeak
+ { 0, 0, false }, // AtomicIIncrement
+ { 0, 0, false }, // AtomicIDecrement
+ { 0, 0, false }, // AtomicIAdd
+ { 0, 0, false }, // AtomicISub
+ { 0, 0, false }, // AtomicUMin
+ { 0, 0, false }, // AtomicUMax
+ { 0, 0, false }, // AtomicAnd
+ { 0, 0, false }, // AtomicOr
+ { 0, 0, false }, // AtomicXor
+ { 0, 0, false }, // LoopMerge
+ { 0, 0, false }, // SelectionMerge
+ { 0, 1, false }, // Label
+ { 0, 1, false }, // Branch
+ { 0, 0, false }, // BranchConditional
+ { 0, 0, false }, // Switch
+ { 0, 0, false }, // Kill
+ { 0, 0, false }, // Return
+ { 0, 0, false }, // ReturnValue
+ { 0, 0, false }, // Unreachable
+ { 0, 0, false }, // LifetimeStart
+ { 0, 0, false }, // LifetimeStop
+ { 0, 0, false }, // CompileFlag
+ { 0, 0, false }, // AsyncGroupCopy
+ { 0, 0, false }, // WaitGroupEvents
+ { 0, 0, false }, // GroupAll
+ { 0, 0, false }, // GroupAny
+ { 0, 0, false }, // GroupBroadcast
+ { 0, 0, false }, // GroupIAdd
+ { 0, 0, false }, // GroupFAdd
+ { 0, 0, false }, // GroupFMin
+ { 0, 0, false }, // GroupUMin
+ { 0, 0, false }, // GroupSMin
+ { 0, 0, false }, // GroupFMax
+ { 0, 0, false }, // GroupUMax
+ { 0, 0, false }, // GroupSMax
+ { 0, 0, false }, // GenericCastToPtrExplicit
+ { 0, 0, false }, // GenericPtrMemSemantics
+ { 0, 0, false }, // ReadPipe
+ { 0, 0, false }, // WritePipe
+ { 0, 0, false }, // ReservedReadPipe
+ { 0, 0, false }, // ReservedWritePipe
+ { 0, 0, false }, // ReserveReadPipePackets
+ { 0, 0, false }, // ReserveWritePipePackets
+ { 0, 0, false }, // CommitReadPipe
+ { 0, 0, false }, // CommitWritePipe
+ { 0, 0, false }, // IsValidReserveId
+ { 0, 0, false }, // GetNumPipePackets
+ { 0, 0, false }, // GetMaxPipePackets
+ { 0, 0, false }, // GroupReserveReadPipePackets
+ { 0, 0, false }, // GroupReserveWritePipePackets
+ { 0, 0, false }, // GroupCommitReadPipe
+ { 0, 0, false }, // GroupCommitWritePipe
+ { 0, 0, false }, // EnqueueMarker
+ { 0, 0, false }, // EnqueueKernel
+ { 0, 0, false }, // GetKernelNDrangeSubGroupCount
+ { 0, 0, false }, // GetKernelNDrangeMaxSubGroupSize
+ { 0, 0, false }, // GetKernelWorkGroupSize
+ { 0, 0, false }, // GetKernelPreferredWorkGroupSizeMultiple
+ { 0, 0, false }, // RetainEvent
+ { 0, 0, false }, // ReleaseEvent
+ { 0, 0, false }, // CreateUserEvent
+ { 0, 0, false }, // IsValidEvent
+ { 0, 0, false }, // SetUserEventStatus
+ { 0, 0, false }, // CaptureEventProfilingInfo
+ { 0, 0, false }, // GetDefaultQueue
+ { 0, 0, false }, // BuildNDRange
+ { 0, 0, false }, // SatConvertSToU
+ { 0, 0, false }, // SatConvertUToS
+ { 0, 0, false }, // AtomicIMin
+ { 0, 0, false }, // AtomicIMax
+ };
+ BX_STATIC_ASSERT(BX_COUNTOF(s_sprivOpcodeInfo) == SpirvOpcode::Count);
+
+ const char* s_spirvOpcode[] =
+ {
+ "Nop",
+ "Source",
+ "SourceExtension",
+ "Extension",
+ "ExtInstImport",
+ "MemoryModel",
+ "EntryPoint",
+ "ExecutionMode",
+ "TypeVoid",
+ "TypeBool",
+ "TypeInt",
+ "TypeFloat",
+ "TypeVector",
+ "TypeMatrix",
+ "TypeSampler",
+ "TypeFilter",
+ "TypeArray",
+ "TypeRuntimeArray",
+ "TypeStruct",
+ "TypeOpaque",
+ "TypePointer",
+ "TypeFunction",
+ "TypeEvent",
+ "TypeDeviceEvent",
+ "TypeReserveId",
+ "TypeQueue",
+ "TypePipe",
+ "ConstantTrue",
+ "ConstantFalse",
+ "Constant",
+ "ConstantComposite",
+ "ConstantSampler",
+ "ConstantNullPointer",
+ "ConstantNullObject",
+ "SpecConstantTrue",
+ "SpecConstantFalse",
+ "SpecConstant",
+ "SpecConstantComposite",
+ "Variable",
+ "VariableArray",
+ "Function",
+ "FunctionParameter",
+ "FunctionEnd",
+ "FunctionCall",
+ "ExtInst",
+ "Undef",
+ "Load",
+ "Store",
+ "Phi",
+ "DecorationGroup",
+ "Decorate",
+ "MemberDecorate",
+ "GroupDecorate",
+ "GroupMemberDecorate",
+ "Name",
+ "MemberName",
+ "String",
+ "Line",
+ "VectorExtractDynamic",
+ "VectorInsertDynamic",
+ "VectorShuffle",
+ "CompositeConstruct",
+ "CompositeExtract",
+ "CompositeInsert",
+ "CopyObject",
+ "CopyMemory",
+ "CopyMemorySized",
+ "Sampler",
+ "TextureSample",
+ "TextureSampleDref",
+ "TextureSampleLod",
+ "TextureSampleProj",
+ "TextureSampleGrad",
+ "TextureSampleOffset",
+ "TextureSampleProjLod",
+ "TextureSampleProjGrad",
+ "TextureSampleLodOffset",
+ "TextureSampleProjOffset",
+ "TextureSampleGradOffset",
+ "TextureSampleProjLodOffset",
+ "TextureSampleProjGradOffset",
+ "TextureFetchTexelLod",
+ "TextureFetchTexelOffset",
+ "TextureFetchSample",
+ "TextureFetchTexel",
+ "TextureGather",
+ "TextureGatherOffset",
+ "TextureGatherOffsets",
+ "TextureQuerySizeLod",
+ "TextureQuerySize",
+ "TextureQueryLod",
+ "TextureQueryLevels",
+ "TextureQuerySamples",
+ "AccessChain",
+ "InBoundsAccessChain",
+ "SNegate",
+ "FNegate",
+ "Not",
+ "Any",
+ "All",
+ "ConvertFToU",
+ "ConvertFToS",
+ "ConvertSToF",
+ "ConvertUToF",
+ "UConvert",
+ "SConvert",
+ "FConvert",
+ "ConvertPtrToU",
+ "ConvertUToPtr",
+ "PtrCastToGeneric",
+ "GenericCastToPtr",
+ "Bitcast",
+ "Transpose",
+ "IsNan",
+ "IsInf",
+ "IsFinite",
+ "IsNormal",
+ "SignBitSet",
+ "LessOrGreater",
+ "Ordered",
+ "Unordered",
+ "ArrayLength",
+ "IAdd",
+ "FAdd",
+ "ISub",
+ "FSub",
+ "IMul",
+ "FMul",
+ "UDiv",
+ "SDiv",
+ "FDiv",
+ "UMod",
+ "SRem",
+ "SMod",
+ "FRem",
+ "FMod",
+ "VectorTimesScalar",
+ "MatrixTimesScalar",
+ "VectorTimesMatrix",
+ "MatrixTimesVector",
+ "MatrixTimesMatrix",
+ "OuterProduct",
+ "Dot",
+ "ShiftRightLogical",
+ "ShiftRightArithmetic",
+ "ShiftLeftLogical",
+ "LogicalOr",
+ "LogicalXor",
+ "LogicalAnd",
+ "BitwiseOr",
+ "BitwiseXor",
+ "BitwiseAnd",
+ "Select",
+ "IEqual",
+ "FOrdEqual",
+ "FUnordEqual",
+ "INotEqual",
+ "FOrdNotEqual",
+ "FUnordNotEqual",
+ "ULessThan",
+ "SLessThan",
+ "FOrdLessThan",
+ "FUnordLessThan",
+ "UGreaterThan",
+ "SGreaterThan",
+ "FOrdGreaterThan",
+ "FUnordGreaterThan",
+ "ULessThanEqual",
+ "SLessThanEqual",
+ "FOrdLessThanEqual",
+ "FUnordLessThanEqual",
+ "UGreaterThanEqual",
+ "SGreaterThanEqual",
+ "FOrdGreaterThanEqual",
+ "FUnordGreaterThanEqual",
+ "DPdx",
+ "DPdy",
+ "Fwidth",
+ "DPdxFine",
+ "DPdyFine",
+ "FwidthFine",
+ "DPdxCoarse",
+ "DPdyCoarse",
+ "FwidthCoarse",
+ "EmitVertex",
+ "EndPrimitive",
+ "EmitStreamVertex",
+ "EndStreamPrimitive",
+ "ControlBarrier",
+ "MemoryBarrier",
+ "ImagePointer",
+ "AtomicInit",
+ "AtomicLoad",
+ "AtomicStore",
+ "AtomicExchange",
+ "AtomicCompareExchange",
+ "AtomicCompareExchangeWeak",
+ "AtomicIIncrement",
+ "AtomicIDecrement",
+ "AtomicIAdd",
+ "AtomicISub",
+ "AtomicUMin",
+ "AtomicUMax",
+ "AtomicAnd",
+ "AtomicOr",
+ "AtomicXor",
+ "LoopMerge",
+ "SelectionMerge",
+ "Label",
+ "Branch",
+ "BranchConditional",
+ "Switch",
+ "Kill",
+ "Return",
+ "ReturnValue",
+ "Unreachable",
+ "LifetimeStart",
+ "LifetimeStop",
+ "CompileFlag",
+ "AsyncGroupCopy",
+ "WaitGroupEvents",
+ "GroupAll",
+ "GroupAny",
+ "GroupBroadcast",
+ "GroupIAdd",
+ "GroupFAdd",
+ "GroupFMin",
+ "GroupUMin",
+ "GroupSMin",
+ "GroupFMax",
+ "GroupUMax",
+ "GroupSMax",
+ "GenericCastToPtrExplicit",
+ "GenericPtrMemSemantics",
+ "ReadPipe",
+ "WritePipe",
+ "ReservedReadPipe",
+ "ReservedWritePipe",
+ "ReserveReadPipePackets",
+ "ReserveWritePipePackets",
+ "CommitReadPipe",
+ "CommitWritePipe",
+ "IsValidReserveId",
+ "GetNumPipePackets",
+ "GetMaxPipePackets",
+ "GroupReserveReadPipePackets",
+ "GroupReserveWritePipePackets",
+ "GroupCommitReadPipe",
+ "GroupCommitWritePipe",
+ "EnqueueMarker",
+ "EnqueueKernel",
+ "GetKernelNDrangeSubGroupCount",
+ "GetKernelNDrangeMaxSubGroupSize",
+ "GetKernelWorkGroupSize",
+ "GetKernelPreferredWorkGroupSizeMultiple",
+ "RetainEvent",
+ "ReleaseEvent",
+ "CreateUserEvent",
+ "IsValidEvent",
+ "SetUserEventStatus",
+ "CaptureEventProfilingInfo",
+ "GetDefaultQueue",
+ "BuildNDRange",
+ "SatConvertSToU",
+ "SatConvertUToS",
+ "AtomicIMin",
+ "AtomicIMax",
+ };
+ BX_STATIC_ASSERT(BX_COUNTOF(s_spirvOpcode) == SpirvOpcode::Count);
+
+ const char* getName(SpirvOpcode::Enum _opcode)
+ {
+ BX_CHECK(_opcode < SpirvOpcode::Count, "Unknown opcode id %d.", _opcode);
+ return s_spirvOpcode[_opcode];
+ }
+
+ int32_t read(bx::ReaderI* _reader, SpirvOperand& _operand)
+ {
+ int32_t size = 0;
+
+ BX_UNUSED(_operand);
+ uint32_t token;
+ size += bx::read(_reader, token);
+
+ return size;
+ }
+
+ int32_t read(bx::ReaderI* _reader, SpirvInstruction& _instruction)
+ {
+ int32_t size = 0;
+
+ uint32_t token;
+ size += bx::read(_reader, token);
+
+ _instruction.opcode = SpirvOpcode::Enum( (token & UINT32_C(0x0000ffff) ) );
+ _instruction.length = uint16_t( (token & UINT32_C(0xffff0000) ) >> 16);
+
+ uint32_t currOp = 0;
+
+ const SpirvOpcodeInfo& info = s_sprivOpcodeInfo[_instruction.opcode];
+
+ if (0 < info.numValues)
+ {
+ size += read(_reader, _instruction.un.value, info.numValues*sizeof(uint32_t) );
+ }
+
+ if (info.hasVariable)
+ {
+ while (size/4 != _instruction.length)
+ {
+ uint32_t tmp;
+ size += bx::read(_reader, tmp);
+ }
+ }
+ else
+ {
+ _instruction.numOperands = info.numOperands;
+ switch (info.numOperands)
+ {
+ case 6: size += read(_reader, _instruction.operand[currOp++]);
+ case 5: size += read(_reader, _instruction.operand[currOp++]);
+ case 4: size += read(_reader, _instruction.operand[currOp++]);
+ case 3: size += read(_reader, _instruction.operand[currOp++]);
+ case 2: size += read(_reader, _instruction.operand[currOp++]);
+ case 1: size += read(_reader, _instruction.operand[currOp++]);
+ case 0:
+ break;
+
+ default:
+ BX_WARN(false, "Instruction %s with invalid number of operands %d (numValues %d)."
+ , getName(_instruction.opcode)
+ , info.numOperands
+ , info.numValues
+ );
+ break;
+ }
+
+ BX_WARN(size/4 == _instruction.length, "read %d, expected %d, %s"
+ , size/4
+ , _instruction.length
+ , getName(_instruction.opcode)
+ );
+ while (size/4 != _instruction.length)
+ {
+ uint32_t tmp;
+ size += bx::read(_reader, tmp);
+ }
+ }
+
+ return size;
+ }
+
+ int32_t write(bx::WriterI* _writer, const SpirvInstruction& _instruction)
+ {
+ int32_t size = 0;
+ BX_UNUSED(_writer, _instruction);
+ return size;
+ }
+
+ int32_t toString(char* _out, int32_t _size, const SpirvInstruction& _instruction)
+ {
+ int32_t size = 0;
+ size += bx::snprintf(&_out[size], bx::uint32_imax(0, _size-size)
+ , "%s %d (%d, %d)"
+ , getName(_instruction.opcode)
+ , _instruction.numOperands
+ , _instruction.un.value[0]
+ , _instruction.un.value[1]
+ );
+
+ return size;
+ }
+
+ int32_t read(bx::ReaderSeekerI* _reader, SpirvShader& _shader)
+ {
+ int32_t size = 0;
+
+ uint32_t len = uint32_t(bx::getSize(_reader) - bx::seek(_reader) );
+ _shader.byteCode.resize(len);
+ size += bx::read(_reader, _shader.byteCode.data(), len);
+
+ return size;
+ }
+
+ int32_t write(bx::WriterI* _writer, const SpirvShader& _shader)
+ {
+ int32_t size = 0;
+ BX_UNUSED(_writer, _shader);
+ return size;
+ }
+
+#define SPIRV_MAGIC 0x07230203
+
+ int32_t read(bx::ReaderSeekerI* _reader, Spirv& _spirv)
+ {
+ int32_t size = 0;
+
+ size += bx::read(_reader, _spirv.header);
+
+ if (size != sizeof(Spirv::Header)
+ || _spirv.header.magic != SPIRV_MAGIC
+ )
+ {
+ // error
+ return -size;
+ }
+
+ size += read(_reader, _spirv.shader);
+
+ return size;
+ }
+
+ int32_t write(bx::WriterSeekerI* _writer, const Spirv& _spirv)
+ {
+ int32_t size = 0;
+ BX_UNUSED(_writer, _spirv);
+ return size;
+ }
+
+ void parse(const SpirvShader& _src, SpirvParseFn _fn, void* _userData)
+ {
+ bx::MemoryReader reader(_src.byteCode.data(), uint32_t(_src.byteCode.size() ) );
+
+ for (uint32_t token = 0, numTokens = uint32_t(_src.byteCode.size() / sizeof(uint32_t) ); token < numTokens;)
+ {
+ SpirvInstruction instruction;
+ uint32_t size = read(&reader, instruction);
+ BX_CHECK(size/4 == instruction.length, "read %d, expected %d, %s"
+ , size/4
+ , instruction.length
+ , getName(instruction.opcode)
+ );
+ BX_UNUSED(size);
+
+ _fn(token * sizeof(uint32_t), instruction, _userData);
+
+ token += instruction.length;
+ }
+ }
+
+} // namespace bgfx