glslangValidator: Add straightforward SPIR-V support (non-optimizing, ~3.x functionality).
git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@30032 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
1899e83369
commit
0df0cdeeeb
@ -1,59 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2014 LunarG, Inc.
|
|
||||||
//
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#include <assert.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
#include "BilBuilder.h"
|
|
||||||
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <cstdio>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
namespace glbil {
|
|
||||||
|
|
||||||
Builder::Builder()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
Builder::~Builder()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void MissingFunctionality(const char* fun)
|
|
||||||
{
|
|
||||||
printf("Missing functionality: %s\n", fun);
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // end glbil namespace
|
|
||||||
@ -1,56 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2014 LunarG, Inc.
|
|
||||||
//
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef BilBuilder_H
|
|
||||||
#define BilBuilder_H
|
|
||||||
|
|
||||||
#include "Bil.h"
|
|
||||||
#include "Bir.h"
|
|
||||||
|
|
||||||
#include <stack>
|
|
||||||
|
|
||||||
namespace glbil {
|
|
||||||
|
|
||||||
class Builder {
|
|
||||||
public:
|
|
||||||
Builder();
|
|
||||||
virtual ~Builder();
|
|
||||||
};
|
|
||||||
|
|
||||||
void MissingFunctionality(const char*);
|
|
||||||
|
|
||||||
}; // end glbil namespace
|
|
||||||
|
|
||||||
#endif // BilBuilder_H
|
|
||||||
49
BIL/Bir.h
49
BIL/Bir.h
@ -1,49 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2014 LunarG, Inc.
|
|
||||||
//
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef Bir_H
|
|
||||||
#define Bir_H
|
|
||||||
|
|
||||||
#include "Bil.h"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <iostream>
|
|
||||||
|
|
||||||
namespace glbil {
|
|
||||||
|
|
||||||
|
|
||||||
}; // end glbil namespace
|
|
||||||
|
|
||||||
#endif // Bir_H
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
namespace GLSL_STD_450 {
|
|
||||||
|
|
||||||
enum Entrypoints {
|
|
||||||
Round,
|
|
||||||
Count
|
|
||||||
};
|
|
||||||
|
|
||||||
extern const char* Names[Count];
|
|
||||||
|
|
||||||
inline void Initialize()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // end namespace GLSL_STD_450
|
|
||||||
@ -1,53 +0,0 @@
|
|||||||
//
|
|
||||||
//Copyright (C) 2014 LunarG, Inc.
|
|
||||||
//
|
|
||||||
//All rights reserved.
|
|
||||||
//
|
|
||||||
//Redistribution and use in source and binary forms, with or without
|
|
||||||
//modification, are permitted provided that the following conditions
|
|
||||||
//are met:
|
|
||||||
//
|
|
||||||
// Redistributions of source code must retain the above copyright
|
|
||||||
// notice, this list of conditions and the following disclaimer.
|
|
||||||
//
|
|
||||||
// Redistributions in binary form must reproduce the above
|
|
||||||
// copyright notice, this list of conditions and the following
|
|
||||||
// disclaimer in the documentation and/or other materials provided
|
|
||||||
// with the distribution.
|
|
||||||
//
|
|
||||||
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
|
||||||
// contributors may be used to endorse or promote products derived
|
|
||||||
// from this software without specific prior written permission.
|
|
||||||
//
|
|
||||||
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
||||||
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
||||||
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
|
||||||
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
|
||||||
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
|
||||||
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
|
||||||
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
||||||
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
||||||
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
|
||||||
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
|
||||||
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
||||||
//POSSIBILITY OF SUCH DAMAGE.
|
|
||||||
|
|
||||||
#include "Bil.h"
|
|
||||||
#include "GlslangToBil.h"
|
|
||||||
#include "BilBuilder.h"
|
|
||||||
|
|
||||||
// Glslang includes
|
|
||||||
#include "glslang/MachineIndependent/localintermediate.h"
|
|
||||||
#include "glslang/MachineIndependent/SymbolTable.h"
|
|
||||||
|
|
||||||
namespace glslang {
|
|
||||||
|
|
||||||
void GlslangToBil(const glslang::TIntermediate& intermediate, std::vector<unsigned int> bil)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void OutputBil(const std::vector<unsigned int>& bil, const char* baseName)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
}; // end namespace glslang
|
|
||||||
@ -16,4 +16,4 @@ endif(WIN32)
|
|||||||
add_subdirectory(glslang)
|
add_subdirectory(glslang)
|
||||||
add_subdirectory(OGLCompilersDLL)
|
add_subdirectory(OGLCompilersDLL)
|
||||||
add_subdirectory(StandAlone)
|
add_subdirectory(StandAlone)
|
||||||
add_subdirectory(BIL)
|
add_subdirectory(SPIRV)
|
||||||
|
|||||||
@ -3,20 +3,20 @@ cmake_minimum_required(VERSION 2.8)
|
|||||||
include_directories(.. ${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(.. ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
GlslangToBil.cpp
|
GlslangToSpv.cpp
|
||||||
BilBuilder.cpp)
|
SpvBuilder.cpp)
|
||||||
|
|
||||||
set(HEADERS
|
set(HEADERS
|
||||||
Bil.h
|
spirv.h
|
||||||
GlslangToBil.h
|
GlslangToSpv.h
|
||||||
BilBuilder.h
|
SpvBuilder.h
|
||||||
Bir.h)
|
SpvIR.h)
|
||||||
|
|
||||||
add_library(BIL STATIC ${SOURCES} ${HEADERS})
|
add_library(SPIRV STATIC ${SOURCES} ${HEADERS})
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
source_group("Source" FILES ${SOURCES} ${HEADERS})
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
install(TARGETS BIL
|
install(TARGETS SPIRV
|
||||||
ARCHIVE DESTINATION lib)
|
ARCHIVE DESTINATION lib)
|
||||||
212
SPIRV/GLSL450Lib.h
Normal file
212
SPIRV/GLSL450Lib.h
Normal file
@ -0,0 +1,212 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2015 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Author: John Kessenich, LunarG
|
||||||
|
//
|
||||||
|
|
||||||
|
namespace GLSL_STD_450 {
|
||||||
|
|
||||||
|
enum Entrypoints {
|
||||||
|
Round,
|
||||||
|
RoundEven,
|
||||||
|
Trunc,
|
||||||
|
Abs,
|
||||||
|
Sign,
|
||||||
|
Floor,
|
||||||
|
Ceil,
|
||||||
|
Fract,
|
||||||
|
|
||||||
|
Radians,
|
||||||
|
Degrees,
|
||||||
|
Sin,
|
||||||
|
Cos,
|
||||||
|
Tan,
|
||||||
|
Asin,
|
||||||
|
Acos,
|
||||||
|
Atan,
|
||||||
|
Sinh,
|
||||||
|
Cosh,
|
||||||
|
Tanh,
|
||||||
|
Asinh,
|
||||||
|
Acosh,
|
||||||
|
Atanh,
|
||||||
|
Atan2,
|
||||||
|
|
||||||
|
Pow,
|
||||||
|
Exp,
|
||||||
|
Log,
|
||||||
|
Exp2,
|
||||||
|
Log2,
|
||||||
|
Sqrt,
|
||||||
|
InverseSqrt,
|
||||||
|
|
||||||
|
Determinant,
|
||||||
|
MatrixInverse,
|
||||||
|
|
||||||
|
Modf, // second argument needs the OpVariable, not an OpLoad
|
||||||
|
Min,
|
||||||
|
Max,
|
||||||
|
Clamp,
|
||||||
|
Mix,
|
||||||
|
Step,
|
||||||
|
SmoothStep,
|
||||||
|
|
||||||
|
FloatBitsToInt,
|
||||||
|
FloatBitsToUint,
|
||||||
|
IntBitsToFloat,
|
||||||
|
UintBitsToFloat,
|
||||||
|
|
||||||
|
Fma,
|
||||||
|
Frexp,
|
||||||
|
Ldexp,
|
||||||
|
|
||||||
|
PackSnorm4x8,
|
||||||
|
PackUnorm4x8,
|
||||||
|
PackSnorm2x16,
|
||||||
|
PackUnorm2x16,
|
||||||
|
PackHalf2x16,
|
||||||
|
PackDouble2x32,
|
||||||
|
UnpackSnorm2x16,
|
||||||
|
UnpackUnorm2x16,
|
||||||
|
UnpackHalf2x16,
|
||||||
|
UnpackSnorm4x8,
|
||||||
|
UnpackUnorm4x8,
|
||||||
|
UnpackDouble2x32,
|
||||||
|
|
||||||
|
Length,
|
||||||
|
Distance,
|
||||||
|
Cross,
|
||||||
|
Normalize,
|
||||||
|
Ftransform,
|
||||||
|
FaceForward,
|
||||||
|
Reflect,
|
||||||
|
Refract,
|
||||||
|
|
||||||
|
UaddCarry,
|
||||||
|
UsubBorrow,
|
||||||
|
UmulExtended,
|
||||||
|
ImulExtended,
|
||||||
|
BitfieldExtract,
|
||||||
|
BitfieldInsert,
|
||||||
|
BitfieldReverse,
|
||||||
|
BitCount,
|
||||||
|
FindLSB,
|
||||||
|
FindMSB,
|
||||||
|
|
||||||
|
InterpolateAtCentroid,
|
||||||
|
InterpolateAtSample,
|
||||||
|
InterpolateAtOffset,
|
||||||
|
|
||||||
|
Count
|
||||||
|
};
|
||||||
|
|
||||||
|
inline void GetDebugNames(const char** names)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < Count; ++i)
|
||||||
|
names[i] = "unknown";
|
||||||
|
|
||||||
|
names[Round] = "round";
|
||||||
|
names[RoundEven] = "roundEven";
|
||||||
|
names[Trunc] = "trunc";
|
||||||
|
names[Abs] = "abs";
|
||||||
|
names[Sign] = "sign";
|
||||||
|
names[Floor] = "floor";
|
||||||
|
names[Ceil] = "ceil";
|
||||||
|
names[Fract] = "fract";
|
||||||
|
names[Radians] = "radians";
|
||||||
|
names[Degrees] = "degrees";
|
||||||
|
names[Sin] = "sin";
|
||||||
|
names[Cos] = "cos";
|
||||||
|
names[Tan] = "tan";
|
||||||
|
names[Asin] = "asin";
|
||||||
|
names[Acos] = "acos";
|
||||||
|
names[Atan] = "atan";
|
||||||
|
names[Sinh] = "sinh";
|
||||||
|
names[Cosh] = "cosh";
|
||||||
|
names[Tanh] = "tanh";
|
||||||
|
names[Asinh] = "asinh";
|
||||||
|
names[Acosh] = "acosh";
|
||||||
|
names[Atanh] = "atanh";
|
||||||
|
names[Atan2] = "atan2";
|
||||||
|
names[Pow] = "pow";
|
||||||
|
names[Exp] = "exp";
|
||||||
|
names[Log] = "log";
|
||||||
|
names[Exp2] = "exp2";
|
||||||
|
names[Log2] = "log2";
|
||||||
|
names[Sqrt] = "sqrt";
|
||||||
|
names[InverseSqrt] = "inverseSqrt";
|
||||||
|
names[Determinant] = "determinant";
|
||||||
|
names[MatrixInverse] = "matrixInverse";
|
||||||
|
names[Modf] = "modf";
|
||||||
|
names[Min] = "min";
|
||||||
|
names[Max] = "max";
|
||||||
|
names[Clamp] = "clamp";
|
||||||
|
names[Mix] = "mix";
|
||||||
|
names[Step] = "step";
|
||||||
|
names[SmoothStep] = "smoothStep";
|
||||||
|
names[FloatBitsToInt] = "floatBitsToInt";
|
||||||
|
names[FloatBitsToUint] = "floatBitsToUint";
|
||||||
|
names[IntBitsToFloat] = "intBitsToFloat";
|
||||||
|
names[UintBitsToFloat] = "uintBitsToFloat";
|
||||||
|
names[Fma] = "fma";
|
||||||
|
names[Frexp] = "frexp";
|
||||||
|
names[Ldexp] = "ldexp";
|
||||||
|
names[PackSnorm4x8] = "packSnorm4x8";
|
||||||
|
names[PackUnorm4x8] = "packUnorm4x8";
|
||||||
|
names[PackSnorm2x16] = "packSnorm2x16";
|
||||||
|
names[PackUnorm2x16] = "packUnorm2x16";
|
||||||
|
names[PackHalf2x16] = "packHalf2x16";
|
||||||
|
names[PackDouble2x32] = "packDouble2x32";
|
||||||
|
names[PackHalf2x16] = "packHalf2x16";
|
||||||
|
names[UnpackSnorm2x16] = "unpackSnorm2x16";
|
||||||
|
names[UnpackUnorm2x16] = "unpackUnorm2x16";
|
||||||
|
names[UnpackHalf2x16] = "unpackHalf2x16";
|
||||||
|
names[UnpackSnorm4x8] = "unpackSnorm4x8";
|
||||||
|
names[UnpackUnorm4x8] = "unpackUnorm4x8";
|
||||||
|
names[UnpackDouble2x32] = "unpackDouble2x32";
|
||||||
|
names[UnpackHalf2x16] = "unpackHalf2x16";
|
||||||
|
names[Length] = "length";
|
||||||
|
names[Distance] = "distance";
|
||||||
|
names[Cross] = "cross";
|
||||||
|
names[Normalize] = "normalize";
|
||||||
|
names[Ftransform] = "ftransform";
|
||||||
|
names[FaceForward] = "faceForward";
|
||||||
|
names[Reflect] = "reflect";
|
||||||
|
names[Refract] = "refract";
|
||||||
|
names[UaddCarry] = "uaddCarry";
|
||||||
|
names[UsubBorrow] = "usubBorrow";
|
||||||
|
names[UmulExtended] = "umulExtended";
|
||||||
|
names[ImulExtended] = "imulExtended";
|
||||||
|
names[BitfieldExtract] = "bitfieldExtract";
|
||||||
|
names[BitfieldInsert] = "bitfieldInsert";
|
||||||
|
names[BitfieldReverse] = "bitfieldReverse";
|
||||||
|
names[BitCount] = "bitCount";
|
||||||
|
names[FindLSB] = "findLSB";
|
||||||
|
names[FindMSB] = "findMSB";
|
||||||
|
names[InterpolateAtCentroid] = "interpolateAtCentroid";
|
||||||
|
names[InterpolateAtSample] = "interpolateAtSample";
|
||||||
|
names[InterpolateAtOffset] = "interpolateAtOffset";
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end namespace GLSL_STD_450
|
||||||
2589
SPIRV/GlslangToSpv.cpp
Normal file
2589
SPIRV/GlslangToSpv.cpp
Normal file
File diff suppressed because it is too large
Load Diff
@ -36,8 +36,7 @@
|
|||||||
|
|
||||||
namespace glslang {
|
namespace glslang {
|
||||||
|
|
||||||
void GlslangToBil(const glslang::TIntermediate& intermediate, std::vector<unsigned int> bil);
|
void GlslangToSpv(const glslang::TIntermediate& intermediate, std::vector<unsigned int>& spirv);
|
||||||
|
void OutputSpv(const std::vector<unsigned int>& spirv, const char* baseName);
|
||||||
void OutputBil(const std::vector<unsigned int>& bil, const char* baseName);
|
|
||||||
|
|
||||||
};
|
};
|
||||||
2011
SPIRV/SpvBuilder.cpp
Normal file
2011
SPIRV/SpvBuilder.cpp
Normal file
File diff suppressed because it is too large
Load Diff
519
SPIRV/SpvBuilder.h
Normal file
519
SPIRV/SpvBuilder.h
Normal file
@ -0,0 +1,519 @@
|
|||||||
|
//
|
||||||
|
//Copyright (C) 2014 LunarG, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Author: John Kessenich, LunarG
|
||||||
|
//
|
||||||
|
|
||||||
|
//
|
||||||
|
// "Builder" is an interface to fully build SPIR-V IR. Allocate one of
|
||||||
|
// these to build (a thread safe) internal SPIR-V representation (IR),
|
||||||
|
// and then dump it as a binary stream according to the SPIR-V specification.
|
||||||
|
//
|
||||||
|
// A Builder has a 1:1 relationship with a SPIR-V module.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef SpvBuilder_H
|
||||||
|
#define SpvBuilder_H
|
||||||
|
|
||||||
|
#include "spirv.h"
|
||||||
|
#include "spvIR.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <stack>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
class Builder {
|
||||||
|
public:
|
||||||
|
Builder(unsigned int userNumber);
|
||||||
|
virtual ~Builder();
|
||||||
|
|
||||||
|
static const int maxMatrixSize = 4;
|
||||||
|
|
||||||
|
void setSource(spv::SourceLanguage lang, int version)
|
||||||
|
{
|
||||||
|
source = lang;
|
||||||
|
sourceVersion = version;
|
||||||
|
}
|
||||||
|
void addSourceExtension(const char* ext) { extensions.push_back(ext); }
|
||||||
|
Id import(const char*);
|
||||||
|
void setMemoryModel(spv::AddressingModel addr, spv::MemoryModel mem)
|
||||||
|
{
|
||||||
|
addressModel = addr;
|
||||||
|
memoryModel = mem;
|
||||||
|
}
|
||||||
|
|
||||||
|
// To get a new <id> for anything needing a new one.
|
||||||
|
Id getUniqueId() { return ++uniqueId; }
|
||||||
|
|
||||||
|
// To get a set of new <id>s, e.g., for a set of function parameters
|
||||||
|
Id getUniqueIds(int numIds)
|
||||||
|
{
|
||||||
|
Id id = uniqueId + 1;
|
||||||
|
uniqueId += numIds;
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For creating new types (will return old type if the requested one was already made).
|
||||||
|
Id makeVoidType();
|
||||||
|
Id makeBoolType();
|
||||||
|
Id makePointer(StorageClass, Id type);
|
||||||
|
Id makeIntegerType(int width, bool hasSign); // generic
|
||||||
|
Id makeIntType(int width) { return makeIntegerType(width, true); }
|
||||||
|
Id makeUintType(int width) { return makeIntegerType(width, false); }
|
||||||
|
Id makeFloatType(int width);
|
||||||
|
Id makeStructType(std::vector<Id>& members, const char*);
|
||||||
|
Id makeVectorType(Id component, int size);
|
||||||
|
Id makeMatrixType(Id component, int cols, int rows);
|
||||||
|
Id makeArrayType(Id element, unsigned size);
|
||||||
|
Id makeFunctionType(Id returnType, std::vector<Id>& paramTypes);
|
||||||
|
enum samplerContent {
|
||||||
|
samplerContentTexture,
|
||||||
|
samplerContentImage,
|
||||||
|
samplerContentTextureFilter
|
||||||
|
};
|
||||||
|
Id makeSampler(Id sampledType, Dimensionality, samplerContent, bool arrayed, bool shadow, bool ms);
|
||||||
|
|
||||||
|
// For querying about types.
|
||||||
|
Id getTypeId(Id resultId) const { return module.getTypeId(resultId); }
|
||||||
|
Id getDerefTypeId(Id resultId) const;
|
||||||
|
OpCode getOpCode(Id id) const { return module.getInstruction(id)->getOpCode(); }
|
||||||
|
OpCode getTypeClass(Id typeId) const { return getOpCode(typeId); }
|
||||||
|
OpCode getMostBasicTypeClass(Id typeId) const;
|
||||||
|
int getNumComponents(Id resultId) const { return getNumTypeComponents(getTypeId(resultId)); }
|
||||||
|
int getNumTypeComponents(Id typeId) const;
|
||||||
|
Id getScalarTypeId(Id typeId) const;
|
||||||
|
Id getContainedTypeId(Id typeId) const;
|
||||||
|
Id getContainedTypeId(Id typeId, int) const;
|
||||||
|
|
||||||
|
bool isPointer(Id resultId) const { return isPointerType(getTypeId(resultId)); }
|
||||||
|
bool isScalar(Id resultId) const { return isScalarType(getTypeId(resultId)); }
|
||||||
|
bool isVector(Id resultId) const { return isVectorType(getTypeId(resultId)); }
|
||||||
|
bool isMatrix(Id resultId) const { return isMatrixType(getTypeId(resultId)); }
|
||||||
|
bool isAggregate(Id resultId) const { return isAggregateType(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
bool isPointerType(Id typeId) const { return getTypeClass(typeId) == OpTypePointer; }
|
||||||
|
bool isScalarType(Id typeId) const { return getTypeClass(typeId) == OpTypeFloat || getTypeClass(typeId) == OpTypeInt || getTypeClass(typeId) == OpTypeBool; }
|
||||||
|
bool isVectorType(Id typeId) const { return getTypeClass(typeId) == OpTypeVector; }
|
||||||
|
bool isMatrixType(Id typeId) const { return getTypeClass(typeId) == OpTypeMatrix; }
|
||||||
|
bool isStructType(Id typeId) const { return getTypeClass(typeId) == OpTypeStruct; }
|
||||||
|
bool isArrayType(Id typeId) const { return getTypeClass(typeId) == OpTypeArray; }
|
||||||
|
bool isAggregateType(Id typeId) const { return isArrayType(typeId) || isStructType(typeId); }
|
||||||
|
bool isSamplerType(Id typeId) const { return getTypeClass(typeId) == OpTypeSampler; }
|
||||||
|
|
||||||
|
bool isConstantScalar(Id resultId) const { return getOpCode(resultId) == OpConstant; }
|
||||||
|
unsigned int getConstantScalar(Id resultId) const { return module.getInstruction(resultId)->getImmediateOperand(0); }
|
||||||
|
|
||||||
|
int getTypeNumColumns(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(isMatrixType(typeId));
|
||||||
|
return getNumTypeComponents(typeId);
|
||||||
|
}
|
||||||
|
int getNumColumns(Id resultId) const { return getTypeNumColumns(getTypeId(resultId)); }
|
||||||
|
int getTypeNumRows(Id typeId) const
|
||||||
|
{
|
||||||
|
assert(isMatrixType(typeId));
|
||||||
|
return getNumTypeComponents(getContainedTypeId(typeId));
|
||||||
|
}
|
||||||
|
int getNumRows(Id resultId) const { return getTypeNumRows(getTypeId(resultId)); }
|
||||||
|
|
||||||
|
Dimensionality getDimensionality(Id resultId) const
|
||||||
|
{
|
||||||
|
assert(isSamplerType(getTypeId(resultId)));
|
||||||
|
return (Dimensionality)module.getInstruction(getTypeId(resultId))->getImmediateOperand(1);
|
||||||
|
}
|
||||||
|
bool isArrayedSampler(Id resultId) const
|
||||||
|
{
|
||||||
|
assert(isSamplerType(getTypeId(resultId)));
|
||||||
|
return module.getInstruction(getTypeId(resultId))->getImmediateOperand(3) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// For making new constants (will return old constant if the requested one was already made).
|
||||||
|
Id makeBoolConstant(bool b);
|
||||||
|
Id makeIntConstant(Id typeId, unsigned value);
|
||||||
|
Id makeIntConstant(int i) { return makeIntConstant(makeIntType(32), (unsigned)i); }
|
||||||
|
Id makeUintConstant(unsigned u) { return makeIntConstant(makeUintType(32), u); }
|
||||||
|
Id makeFloatConstant(float f);
|
||||||
|
Id makeDoubleConstant(double d);
|
||||||
|
|
||||||
|
// Turn the array of constants into a proper spv constant of the requested type.
|
||||||
|
Id makeCompositeConstant(Id type, std::vector<Id>& comps);
|
||||||
|
|
||||||
|
// Methods for adding information outside the CFG.
|
||||||
|
void addEntryPoint(ExecutionModel, Function*);
|
||||||
|
void addExecutionMode(Function*, ExecutionMode mode, int value = -1);
|
||||||
|
void addName(Id, const char* name);
|
||||||
|
void addMemberName(Id, int member, const char* name);
|
||||||
|
void addLine(Id target, Id fileName, int line, int column);
|
||||||
|
void addDecoration(Id, Decoration, int num = -1);
|
||||||
|
void addMemberDecoration(Id, unsigned int member, Decoration, int num = -1);
|
||||||
|
|
||||||
|
// At the end of what block do the next create*() instructions go?
|
||||||
|
void setBuildPoint(Block* bp) { buildPoint = bp; }
|
||||||
|
Block* getBuildPoint() const { return buildPoint; }
|
||||||
|
|
||||||
|
// Make the main function.
|
||||||
|
Function* makeMain();
|
||||||
|
|
||||||
|
// Return from main. Implicit denotes a return at the very end of main.
|
||||||
|
void makeMainReturn(bool implicit = false) { makeReturn(implicit, 0, true); }
|
||||||
|
|
||||||
|
// Close the main function.
|
||||||
|
void closeMain();
|
||||||
|
|
||||||
|
// Make a shader-style function, and create its entry block if entry is non-zero.
|
||||||
|
// Return the function, pass back the entry.
|
||||||
|
Function* makeFunctionEntry(Id returnType, const char* name, std::vector<Id>& paramTypes, Block **entry = 0);
|
||||||
|
|
||||||
|
// Create a return. Pass whether it is a return form main, and the return
|
||||||
|
// value (if applicable). In the case of an implicit return, no post-return
|
||||||
|
// block is inserted.
|
||||||
|
void makeReturn(bool implicit = false, Id retVal = 0, bool isMain = false);
|
||||||
|
|
||||||
|
// Generate all the code needed to finish up a function.
|
||||||
|
void leaveFunction(bool main);
|
||||||
|
|
||||||
|
// Create a discard.
|
||||||
|
void makeDiscard();
|
||||||
|
|
||||||
|
// Create a global or function local or IO variable.
|
||||||
|
Id createVariable(StorageClass, Id type, const char* name = 0);
|
||||||
|
|
||||||
|
// Store into an Id and return the l-value
|
||||||
|
void createStore(Id rValue, Id lValue);
|
||||||
|
|
||||||
|
// Load from an Id and return it
|
||||||
|
Id createLoad(Id lValue);
|
||||||
|
|
||||||
|
// Create an OpAccessChain instruction
|
||||||
|
Id createAccessChain(StorageClass, Id base, std::vector<Id>& offsets);
|
||||||
|
|
||||||
|
// Create an OpCompositeExtract instruction
|
||||||
|
Id createCompositeExtract(Id composite, Id typeId, unsigned index);
|
||||||
|
Id createCompositeExtract(Id composite, Id typeId, std::vector<unsigned>& indexes);
|
||||||
|
Id createCompositeInsert(Id object, Id composite, Id typeId, unsigned index);
|
||||||
|
Id createCompositeInsert(Id object, Id composite, Id typeId, std::vector<unsigned>& indexes);
|
||||||
|
|
||||||
|
Id createEmptyOp(OpCode);
|
||||||
|
void createControlBarrier(unsigned executionScope);
|
||||||
|
void createMemoryBarrier(unsigned executionScope, unsigned memorySemantics);
|
||||||
|
Id createUnaryOp(OpCode, Id typeId, Id operand);
|
||||||
|
Id createBinOp(OpCode, Id typeId, Id operand1, Id operand2);
|
||||||
|
Id createTriOp(OpCode, Id typeId, Id operand1, Id operand2, Id operand3);
|
||||||
|
Id createTernaryOp(OpCode, Id typeId, Id operand1, Id operand2, Id operand3);
|
||||||
|
Id createFunctionCall(spv::Function*, std::vector<spv::Id>&);
|
||||||
|
|
||||||
|
// Take an rvalue (source) and a set of channels to extract from it to
|
||||||
|
// make a new rvalue, which is returned.
|
||||||
|
Id createRvalueSwizzle(Id typeId, Id source, std::vector<unsigned>& channels);
|
||||||
|
|
||||||
|
// Take a copy of an lvalue (target) and a source of components, and set the
|
||||||
|
// source components into the lvalue where the 'channels' say to put them.
|
||||||
|
// An update version of the target is returned.
|
||||||
|
// (No true lvalue or stores are used.)
|
||||||
|
Id createLvalueSwizzle(Id typeId, Id target, Id source, std::vector<unsigned>& channels);
|
||||||
|
|
||||||
|
// If the value passed in is an instruction and the precision is not EMpNone,
|
||||||
|
// it gets tagged with the requested precision.
|
||||||
|
void setPrecision(Id value, Decoration precision)
|
||||||
|
{
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
// Can smear a scalar to a vector for the following forms:
|
||||||
|
// - promoteScalar(scalar, vector) // smear scalar to width of vector
|
||||||
|
// - promoteScalar(vector, scalar) // smear scalar to width of vector
|
||||||
|
// - promoteScalar(pointer, scalar) // smear scalar to width of what pointer points to
|
||||||
|
// - promoteScalar(scalar, scalar) // do nothing
|
||||||
|
// Other forms are not allowed.
|
||||||
|
//
|
||||||
|
// Note: One of the arguments will change, with the result coming back that way rather than
|
||||||
|
// through the return value.
|
||||||
|
void promoteScalar(Decoration precision, Id& left, Id& right);
|
||||||
|
|
||||||
|
// make a value by smearing the scalar to fill the type
|
||||||
|
Id smearScalar(Decoration precision, Id scalarVal, Id);
|
||||||
|
|
||||||
|
// Create a call to a built-in function.
|
||||||
|
Id createBuiltinCall(Decoration precision, Id resultType, Id builtins, int entryPoint, std::vector<Id>& args);
|
||||||
|
|
||||||
|
// List of parameters used to create a texture operation
|
||||||
|
struct TextureParameters {
|
||||||
|
Id sampler;
|
||||||
|
Id coords;
|
||||||
|
Id bias;
|
||||||
|
Id lod;
|
||||||
|
Id Dref;
|
||||||
|
Id offset;
|
||||||
|
Id gradX;
|
||||||
|
Id gradY;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Select the correct texture operation based on all inputs, and emit the correct instruction
|
||||||
|
Id createTextureCall(Decoration precision, Id resultType, bool proj, const TextureParameters&);
|
||||||
|
|
||||||
|
// Emit the OpTextureQuery* instruction that was passed in.
|
||||||
|
// Figure out the right return value and type, and return it.
|
||||||
|
Id createTextureQueryCall(OpCode, const TextureParameters&);
|
||||||
|
|
||||||
|
Id createSamplePositionCall(Decoration precision, Id, Id);
|
||||||
|
|
||||||
|
Id createBitFieldExtractCall(Decoration precision, Id, Id, Id, bool isSigned);
|
||||||
|
Id createBitFieldInsertCall(Decoration precision, Id, Id, Id, Id);
|
||||||
|
|
||||||
|
// Reduction comparision for composites: For equal and not-equal resulting in a scalar.
|
||||||
|
Id createCompare(Decoration precision, Id, Id, bool /* true if for equal, fales if for not-equal */);
|
||||||
|
|
||||||
|
// OpCompositeConstruct
|
||||||
|
Id createCompositeConstruct(Id typeId, std::vector<Id>& constituents);
|
||||||
|
|
||||||
|
// vector or scalar constructor
|
||||||
|
Id createConstructor(Decoration precision, const std::vector<Id>& sources, Id resultTypeId);
|
||||||
|
|
||||||
|
// matrix constructor
|
||||||
|
Id createMatrixConstructor(Decoration precision, const std::vector<Id>& sources, Id constructee);
|
||||||
|
|
||||||
|
// Helper to use for building nested control flow with if-then-else.
|
||||||
|
class If {
|
||||||
|
public:
|
||||||
|
If(Id condition, Builder& builder);
|
||||||
|
~If() {}
|
||||||
|
|
||||||
|
void makeBeginElse();
|
||||||
|
void makeEndIf();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Builder& builder;
|
||||||
|
Id condition;
|
||||||
|
Function* function;
|
||||||
|
Block* headerBlock;
|
||||||
|
Block* thenBlock;
|
||||||
|
Block* elseBlock;
|
||||||
|
Block* mergeBlock;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Make a switch statement. A switch has 'numSegments' of pieces of code, not containing
|
||||||
|
// any case/default labels, all separated by one or more case/default labels. Each possible
|
||||||
|
// case value v is a jump to the caseValues[v] segment. The defaultSegment is also in this
|
||||||
|
// number space. How to compute the value is given by 'condition', as in switch(condition).
|
||||||
|
//
|
||||||
|
// The SPIR-V Builder will maintain the stack of post-switch merge blocks for nested switches.
|
||||||
|
//
|
||||||
|
// Use a defaultSegment < 0 if there is no default segment (to branch to post switch).
|
||||||
|
//
|
||||||
|
// Returns the right set of basic blocks to start each code segment with, so that the caller's
|
||||||
|
// recursion stack can hold the memory for it.
|
||||||
|
//
|
||||||
|
void makeSwitch(Id condition, int numSegments, std::vector<int>& caseValues, std::vector<int>& valueToSegment, int defaultSegment,
|
||||||
|
std::vector<Block*>& segmentBB); // return argument
|
||||||
|
|
||||||
|
// Add a branch to the innermost switch's merge block.
|
||||||
|
void addSwitchBreak();
|
||||||
|
|
||||||
|
// Move to the next code segment, passing in the return argument in makeSwitch()
|
||||||
|
void nextSwitchSegment(std::vector<Block*>& segmentBB, int segment);
|
||||||
|
|
||||||
|
// Finish off the innermost switch.
|
||||||
|
void endSwitch(std::vector<Block*>& segmentBB);
|
||||||
|
|
||||||
|
// Start the beginning of a new loop.
|
||||||
|
void makeNewLoop();
|
||||||
|
|
||||||
|
// Add the branch at the end of the loop header, and leave the build position
|
||||||
|
// in the first block of the body.
|
||||||
|
// 'condition' is true if should exit the loop
|
||||||
|
void createLoopHeaderBranch(Id condition);
|
||||||
|
|
||||||
|
// Add a back-edge (e.g "continue") for the innermost loop that you're in
|
||||||
|
void createLoopBackEdge(bool implicit=false);
|
||||||
|
|
||||||
|
// Add an exit (e.g. "break") for the innermost loop that you're in
|
||||||
|
void createLoopExit();
|
||||||
|
|
||||||
|
// Close the innermost loop that you're in
|
||||||
|
void closeLoop();
|
||||||
|
|
||||||
|
//
|
||||||
|
// Access chain design for an R-Value vs. L-Value:
|
||||||
|
//
|
||||||
|
// There is a single access chain the builder is building at
|
||||||
|
// any particular time. Such a chain can be used to either to a load or
|
||||||
|
// a store, when desired.
|
||||||
|
//
|
||||||
|
// Expressions can be r-values, l-values, or both, or only r-values:
|
||||||
|
// a[b.c].d = .... // l-value
|
||||||
|
// ... = a[b.c].d; // r-value, that also looks like an l-value
|
||||||
|
// ++a[b.c].d; // r-value and l-value
|
||||||
|
// (x + y)[2]; // r-value only, can't possibly be l-value
|
||||||
|
//
|
||||||
|
// Computing an r-value means generating code. Hence,
|
||||||
|
// r-values should only be computed when they are needed, not speculatively.
|
||||||
|
//
|
||||||
|
// Computing an l-value means saving away information for later use in the compiler,
|
||||||
|
// no code is generated until the l-value is later dereferenced. It is okay
|
||||||
|
// to speculatively generate an l-value, just not okay to speculatively dereference it.
|
||||||
|
//
|
||||||
|
// The base of the access chain (the left-most variable or expression
|
||||||
|
// from which everything is based) can be set either as an l-value
|
||||||
|
// or as an r-value. Most efficient would be to set an l-value if one
|
||||||
|
// is available. If an expression was evaluated, the resulting r-value
|
||||||
|
// can be set as the chain base.
|
||||||
|
//
|
||||||
|
// The users of this single access chain can save and restore if they
|
||||||
|
// want to nest or manage multiple chains.
|
||||||
|
//
|
||||||
|
|
||||||
|
struct AccessChain {
|
||||||
|
Id base; // for l-values, pointer to the base object, for r-values, the base object
|
||||||
|
std::vector<Id> indexChain;
|
||||||
|
Id instr; // the instruction that generates this access chain
|
||||||
|
std::vector<unsigned> swizzle;
|
||||||
|
Id component; // a dynamic component index
|
||||||
|
int swizzleTargetWidth;
|
||||||
|
Id resultType; // dereferenced type, to be inclusive of swizzles, which can't have a pointer
|
||||||
|
bool isRValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// the SPIR-V builder maintains a single active chain that
|
||||||
|
// the following methods operated on
|
||||||
|
//
|
||||||
|
|
||||||
|
// for external save and restore
|
||||||
|
AccessChain getAccessChain() { return accessChain; }
|
||||||
|
void setAccessChain(AccessChain newChain) { accessChain = newChain; }
|
||||||
|
|
||||||
|
// clear accessChain
|
||||||
|
void clearAccessChain();
|
||||||
|
|
||||||
|
// set new base as an l-value base
|
||||||
|
void setAccessChainLValue(Id lValue)
|
||||||
|
{
|
||||||
|
assert(isPointer(lValue));
|
||||||
|
accessChain.base = lValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set new base value as an r-value
|
||||||
|
void setAccessChainRValue(Id rValue)
|
||||||
|
{
|
||||||
|
accessChain.isRValue = true;
|
||||||
|
accessChain.base = rValue;
|
||||||
|
accessChain.resultType = getTypeId(rValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// push offset onto the end of the chain
|
||||||
|
void accessChainPush(Id offset, Id newType)
|
||||||
|
{
|
||||||
|
accessChain.indexChain.push_back(offset);
|
||||||
|
accessChain.resultType = newType;
|
||||||
|
}
|
||||||
|
|
||||||
|
// push new swizzle onto the end of any existing swizzle, merging into a single swizzle
|
||||||
|
void accessChainPushSwizzle(std::vector<unsigned>& swizzle, int width, Id type);
|
||||||
|
|
||||||
|
// push a variable component selection onto the access chain; supporting only one, so unsided
|
||||||
|
void accessChainPushComponent(Id component) { accessChain.component = component; }
|
||||||
|
|
||||||
|
// use accessChain and swizzle to store value
|
||||||
|
void accessChainStore(Id rvalue);
|
||||||
|
|
||||||
|
// use accessChain and swizzle to load an r-value
|
||||||
|
Id accessChainLoad(Decoration precision);
|
||||||
|
|
||||||
|
// get the direct pointer for an l-value
|
||||||
|
Id accessChainGetLValue();
|
||||||
|
|
||||||
|
void dump(std::vector<unsigned int>&) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Id findScalarConstant(OpCode typeClass, Id typeId, unsigned value) const;
|
||||||
|
Id findCompositeConstant(OpCode typeClass, std::vector<Id>& comps) const;
|
||||||
|
Id collapseAccessChain();
|
||||||
|
void simplifyAccessChainSwizzle();
|
||||||
|
void createAndSetNoPredecessorBlock(const char*);
|
||||||
|
void createBranch(Block* block);
|
||||||
|
void createMerge(OpCode, Block*, unsigned int control);
|
||||||
|
void createConditionalBranch(Id condition, Block* thenBlock, Block* elseBlock);
|
||||||
|
void dumpInstructions(std::vector<unsigned int>&, const std::vector<Instruction*>&) const;
|
||||||
|
|
||||||
|
SourceLanguage source;
|
||||||
|
int sourceVersion;
|
||||||
|
std::vector<const char*> extensions;
|
||||||
|
AddressingModel addressModel;
|
||||||
|
MemoryModel memoryModel;
|
||||||
|
int builderNumber;
|
||||||
|
Module module;
|
||||||
|
Block* buildPoint;
|
||||||
|
Id uniqueId;
|
||||||
|
Function* mainFunction;
|
||||||
|
Block* stageExit;
|
||||||
|
AccessChain accessChain;
|
||||||
|
|
||||||
|
// special blocks of instructions for output
|
||||||
|
std::vector<Instruction*> imports;
|
||||||
|
std::vector<Instruction*> entryPoints;
|
||||||
|
std::vector<Instruction*> executionModes;
|
||||||
|
std::vector<Instruction*> names;
|
||||||
|
std::vector<Instruction*> lines;
|
||||||
|
std::vector<Instruction*> decorations;
|
||||||
|
std::vector<Instruction*> constantsTypesGlobals;
|
||||||
|
std::vector<Instruction*> externals;
|
||||||
|
|
||||||
|
// not output, internally used for quick & dirty canonical (unique) creation
|
||||||
|
std::vector<Instruction*> groupedConstants[OpConstant]; // all types appear before OpConstant
|
||||||
|
std::vector<Instruction*> groupedTypes[OpConstant];
|
||||||
|
|
||||||
|
// stack of switches
|
||||||
|
std::stack<Block*> switchMerges;
|
||||||
|
|
||||||
|
// Data that needs to be kept in order to properly handle loops.
|
||||||
|
struct Loop {
|
||||||
|
Block* header;
|
||||||
|
Block* merge;
|
||||||
|
Function* function;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Our loop stack.
|
||||||
|
std::stack<Loop> loops;
|
||||||
|
}; // end Builder class
|
||||||
|
|
||||||
|
void MissingFunctionality(const char*);
|
||||||
|
void ValidationError(const char* error);
|
||||||
|
|
||||||
|
}; // end spv namespace
|
||||||
|
|
||||||
|
#endif // SpvBuilder_H
|
||||||
762
SPIRV/spirv.h
Normal file
762
SPIRV/spirv.h
Normal file
@ -0,0 +1,762 @@
|
|||||||
|
/*
|
||||||
|
** Copyright (c) 2014-2015 The Khronos Group Inc.
|
||||||
|
**
|
||||||
|
** Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
** copy of this software and/or associated documentation files (the
|
||||||
|
** "Materials"), to deal in the Materials without restriction, including
|
||||||
|
** without limitation the rights to use, copy, modify, merge, publish,
|
||||||
|
** distribute, sublicense, and/or sell copies of the Materials, and to
|
||||||
|
** permit persons to whom the Materials are furnished to do so, subject to
|
||||||
|
** the following conditions:
|
||||||
|
**
|
||||||
|
** The above copyright notice and this permission notice shall be included
|
||||||
|
** in all copies or substantial portions of the Materials.
|
||||||
|
**
|
||||||
|
** THE MATERIALS ARE PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||||
|
** EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||||
|
** MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||||
|
** IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
||||||
|
** CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
||||||
|
** TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
||||||
|
** MATERIALS OR THE USE OR OTHER DEALINGS IN THE MATERIALS.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//
|
||||||
|
// Enumeration tokens for SPIR V.
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef spirv_H
|
||||||
|
#define spirv_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
namespace spv{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const int MagicNumber = 0x07230203;
|
||||||
|
const int Version = 99;
|
||||||
|
|
||||||
|
typedef unsigned int Id;
|
||||||
|
|
||||||
|
const Id NoResult = 0;
|
||||||
|
const Id NoType = 0;
|
||||||
|
|
||||||
|
const unsigned int OpCodeMask = 0xFFFF;
|
||||||
|
const unsigned int WordCountShift = 16;
|
||||||
|
|
||||||
|
// Set of capabilities. Generally, something is assumed to be in core,
|
||||||
|
// if nothing else is said. So, these are used to identify when something
|
||||||
|
// requires a specific capability to be declared.
|
||||||
|
enum Capability {
|
||||||
|
CapMatrix,
|
||||||
|
CapShader,
|
||||||
|
CapGeom,
|
||||||
|
CapTess,
|
||||||
|
CapAddr,
|
||||||
|
CapLink,
|
||||||
|
CapKernel
|
||||||
|
};
|
||||||
|
|
||||||
|
// What language is the source code in? Note the OpSource instruction has a separate
|
||||||
|
// operand for the version number, this is just the language name. The GLSL
|
||||||
|
// compatibility profile will be indicated by using an OpSourceExtension string.
|
||||||
|
enum SourceLanguage {
|
||||||
|
LangUnknown,
|
||||||
|
LangESSL,
|
||||||
|
LangGLSL,
|
||||||
|
LangOpenCL,
|
||||||
|
|
||||||
|
LangCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used per entry point to communicate the "stage" or other model of
|
||||||
|
// execution used by that entry point.
|
||||||
|
// See OpEntryPoint.
|
||||||
|
enum ExecutionModel {
|
||||||
|
ModelVertex,
|
||||||
|
ModelTessellationControl,
|
||||||
|
ModelTessellationEvaluation,
|
||||||
|
ModelGeometry,
|
||||||
|
ModelFragment,
|
||||||
|
ModelGLCompute,
|
||||||
|
ModelKernel,
|
||||||
|
|
||||||
|
ModelCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used as an argument to OpMemoryModel
|
||||||
|
enum AddressingModel {
|
||||||
|
AddressingLogical,
|
||||||
|
AddressingPhysical32,
|
||||||
|
AddressingPhysical64,
|
||||||
|
|
||||||
|
AddressingCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used as an argment to OpMemoryModel
|
||||||
|
enum MemoryModel {
|
||||||
|
MemorySimple,
|
||||||
|
MemoryGLSL450,
|
||||||
|
MemoryOCL12,
|
||||||
|
MemoryOCL20,
|
||||||
|
MemoryOCL21,
|
||||||
|
|
||||||
|
MemoryCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Used per entry point to communicate modes related to input, output, and execution.
|
||||||
|
// See OpExecutionMode.
|
||||||
|
enum ExecutionMode {
|
||||||
|
ExecutionInvocations,
|
||||||
|
ExecutionSpacingEqual,
|
||||||
|
ExecutionSpacingFractionalEven,
|
||||||
|
ExecutionSpacingFractionalOdd,
|
||||||
|
ExecutionVertexOrderCw,
|
||||||
|
ExecutionVertexOrderCcw,
|
||||||
|
ExecutionPixelCenterInteger,
|
||||||
|
ExecutionOriginUpperLeft,
|
||||||
|
ExecutionEarlyFragmentTests,
|
||||||
|
ExecutionPointMode,
|
||||||
|
ExecutionXfb,
|
||||||
|
ExecutionDepthReplacing,
|
||||||
|
ExecutionDepthAny,
|
||||||
|
ExecutionDepthGreater,
|
||||||
|
ExecutionDepthLess,
|
||||||
|
ExecutionDepthUnchanged,
|
||||||
|
ExecutionLocalSize,
|
||||||
|
ExecutionLocalSizeHint,
|
||||||
|
|
||||||
|
ExecutionInputPoints,
|
||||||
|
ExecutionInputLines,
|
||||||
|
ExecutionInputLinesAdjacency,
|
||||||
|
ExecutionInputTriangles,
|
||||||
|
ExecutionInputTrianglesAdjacency,
|
||||||
|
ExecutionInputQuads,
|
||||||
|
ExecutionInputIsolines,
|
||||||
|
|
||||||
|
ExecutionOutputVertices,
|
||||||
|
ExecutionOutputPoints,
|
||||||
|
ExecutionOutputLineStrip,
|
||||||
|
ExecutionOutputTriangleStrip,
|
||||||
|
|
||||||
|
ExecutionVecTypeHint,
|
||||||
|
ExecutionContractionOff,
|
||||||
|
ExecutionModeCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum StorageClass {
|
||||||
|
StorageConstantUniform,
|
||||||
|
StorageInput,
|
||||||
|
StorageUniform,
|
||||||
|
StorageOutput,
|
||||||
|
StorageWorkgroupLocal,
|
||||||
|
StorageWorkgroupGlobal,
|
||||||
|
StoragePrivateGlobal,
|
||||||
|
StorageFunction,
|
||||||
|
StorageGeneric,
|
||||||
|
StoragePrivate,
|
||||||
|
StorageAtomicCounter,
|
||||||
|
StorageCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Dimensionalities currently used for sampling.
|
||||||
|
// See TypeSampler in TypeClass.
|
||||||
|
enum Dimensionality {
|
||||||
|
Dim1D,
|
||||||
|
Dim2D,
|
||||||
|
Dim3D,
|
||||||
|
DimCube,
|
||||||
|
DimRect,
|
||||||
|
DimBuffer,
|
||||||
|
|
||||||
|
DimCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sampler addressing mode.
|
||||||
|
enum SamplerAddressingMode {
|
||||||
|
SamplerAddressingNone = 0,
|
||||||
|
SamplerAddressingClampToEdge = 2,
|
||||||
|
SamplerAddressingClamp = 4,
|
||||||
|
SamplerAddressingRepeat = 6,
|
||||||
|
SamplerAddressingRepeatMirrored = 8,
|
||||||
|
SamplerAddressingModeLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sampler filter mode.
|
||||||
|
enum SamplerFilterMode {
|
||||||
|
SamplerFilterNearest = 0x10,
|
||||||
|
SamplerFilterLinear = 0x20,
|
||||||
|
SamplerFilterModeLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
// FP Fast Math Mode.
|
||||||
|
enum FPFastMath {
|
||||||
|
FPFastMathNNan = 0, // assume parameters and result are not NaN.
|
||||||
|
FPFastMathNInf = 0x02, // assume parameters and result are not +/- Inf.
|
||||||
|
FPFastMathNSZ = 0x04, // treat the sign of a zero parameter or result as insignificant.
|
||||||
|
FPFastMathARcp = 0x08, // allow the usage of reciprocal rather than perform a division.
|
||||||
|
FPFastMathFast = 0x10, // allow Algebraic transformations according to real number associative and distibutive algebra. This flag implies all the others.
|
||||||
|
FPFastMathLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
// FP Fast Math Mode.
|
||||||
|
enum FPRoundingMode {
|
||||||
|
FPRoundRTE, // round to nearest even.
|
||||||
|
FPRoundRTZ, // round towards zero.
|
||||||
|
FPRoundRTP, // round towards positive infinity.
|
||||||
|
FPRoundRTN, // round towards negative infinity.
|
||||||
|
FPRoundLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Global identifier linkage types (by default the linkage type of global identifiers is private. This means that they are only accessible to objects inside the module.)
|
||||||
|
enum LinkageType {
|
||||||
|
LinkageExport, // accessible by objects in other modules as well.
|
||||||
|
LinkageImport, // a forward declaration to a global identifier that exists in another module.
|
||||||
|
LinkageLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Access Qualifiers for OpenCL pipes and images
|
||||||
|
enum AccessQualifier {
|
||||||
|
AccessQualReadOnly,
|
||||||
|
AccessQualWriteOnly,
|
||||||
|
AccessQualReadWrite,
|
||||||
|
AccessQualLast,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function argument attributes
|
||||||
|
enum FunctionParameterAttribute {
|
||||||
|
FuncParamAttrZext, // value should be zero extended if needed
|
||||||
|
FuncParamAttrSext, // value should be sign extended if needed
|
||||||
|
FuncParamAttrByval, // only valid for pointer parameters (not for ret value), this indicates that the pointer parameter should really be passed by value to the function.
|
||||||
|
FuncParamAttrSret, // indicates that the pointer parameter specifies the address of a structure that is the return value of the function in the source program. only applicable to the first parameter
|
||||||
|
FuncParamAttrNoAlias,
|
||||||
|
FuncParamAttrNoCapture,
|
||||||
|
FuncParamAttrSVM,
|
||||||
|
FuncParamAttrNoWrite,
|
||||||
|
FuncParamAttrNoReadWrite,
|
||||||
|
FuncParamAttrLast, // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Extra forms of "qualification" to add as needed. See OpDecorate.
|
||||||
|
enum Decoration {
|
||||||
|
// For legacy ES precision qualifiers; newer language
|
||||||
|
// designs can use the "num-bits" feature in TypeClass.
|
||||||
|
// The precision qualifiers may be decorated on type <id>s or instruction <id>s.
|
||||||
|
DecPrecisionLow,
|
||||||
|
DecPrecisionMedium,
|
||||||
|
DecPrecisionHigh,
|
||||||
|
|
||||||
|
DecBlock, // basic in/out/uniform block, applied only to types of TypeStruct
|
||||||
|
DecBufferBlock, // shader storage buffer block
|
||||||
|
DecRowMajor,
|
||||||
|
DecColMajor,
|
||||||
|
DecGLSLShared,
|
||||||
|
DecGLSLStd140,
|
||||||
|
DecGLSLStd430,
|
||||||
|
DecGLSLPacked,
|
||||||
|
DecSmooth,
|
||||||
|
DecNoperspective,
|
||||||
|
DecFlat,
|
||||||
|
DecPatch,
|
||||||
|
DecCentroid,
|
||||||
|
DecSample,
|
||||||
|
DecInvariant,
|
||||||
|
DecRestrict,
|
||||||
|
DecAliased,
|
||||||
|
DecVolatile,
|
||||||
|
DecConstant,
|
||||||
|
DecCoherent,
|
||||||
|
DecNonwritable,
|
||||||
|
DecNonreadable,
|
||||||
|
DecUniform,
|
||||||
|
DecNoStaticUse,
|
||||||
|
|
||||||
|
DecCPacked,
|
||||||
|
DecFPSaturatedConv,
|
||||||
|
|
||||||
|
// these all take one additional operand
|
||||||
|
DecStream,
|
||||||
|
DecLocation,
|
||||||
|
DecComponent,
|
||||||
|
DecIndex,
|
||||||
|
DecBinding,
|
||||||
|
DecDescriptorSet,
|
||||||
|
DecOffset,
|
||||||
|
DecAlignment,
|
||||||
|
DecXfbBuffer,
|
||||||
|
DecStride,
|
||||||
|
DecBuiltIn,
|
||||||
|
DecFuncParamAttr,
|
||||||
|
DecFPRoundingMode,
|
||||||
|
DecFPFastMathMode,
|
||||||
|
DecLinkageType,
|
||||||
|
DecSpecId,
|
||||||
|
|
||||||
|
DecCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum BuiltIn {
|
||||||
|
BuiltInPosition,
|
||||||
|
BuiltInPointSize,
|
||||||
|
BuiltInClipVertex,
|
||||||
|
BuiltInClipDistance,
|
||||||
|
BuiltInCullDistance,
|
||||||
|
BuiltInVertexId,
|
||||||
|
BuiltInInstanceId,
|
||||||
|
BuiltInPrimitiveId,
|
||||||
|
BuiltInInvocationId,
|
||||||
|
BuiltInLayer,
|
||||||
|
BuiltInViewportIndex,
|
||||||
|
BuiltInTessLevelOuter,
|
||||||
|
BuiltInTessLevelInner,
|
||||||
|
BuiltInTessCoord,
|
||||||
|
BuiltInPatchVertices,
|
||||||
|
BuiltInFragCoord,
|
||||||
|
BuiltInPointCoord,
|
||||||
|
BuiltInFrontFacing,
|
||||||
|
BuiltInSampleId,
|
||||||
|
BuiltInSamplePosition,
|
||||||
|
BuiltInSampleMask,
|
||||||
|
BuiltInFragColor,
|
||||||
|
BuiltInFragDepth,
|
||||||
|
BuiltInHelperInvocation,
|
||||||
|
|
||||||
|
// OpenGL compute stage, OpenCL work item built-ins
|
||||||
|
BuiltInNumWorkgroups, // number of work-groups that will execute a kernel
|
||||||
|
BuiltInWorkgroupSize, // OpenCL number of local work-items
|
||||||
|
BuiltInWorkgroupId, // OpenCL work group id
|
||||||
|
BuiltInLocalInvocationId, // OpenCL local work item id (decorates a vector3 i32/i64)
|
||||||
|
BuiltInGlobalInvocationId, // OpenCL global work item id (decorates a vector3 i32/i64)
|
||||||
|
BuiltInLocalInvocationIndex, // not in use in OpenCL
|
||||||
|
BuiltInWorkDim, // OpenCL number of dimensions in use (decorates a scalar i32/i64)
|
||||||
|
BuiltInGlobalSize, // OpenCL number of global work items, per dimension (decorates a vector3 i32/i64)
|
||||||
|
BuiltInEnqueuedWorkgroupSize, // OpenCL 2.0 only, get local size
|
||||||
|
BuiltInGlobalOffset, // OpenCL offset values specified global_work_offset
|
||||||
|
BuiltInGlobalLinearId, // OpenCL 2.0 only, work items 1-dimensional global ID.
|
||||||
|
BuiltInWorkgroupLinearId, // OpenCL 2.0 only work items 1-dimensional local ID.
|
||||||
|
|
||||||
|
// OpenCL 2.0 subgroups
|
||||||
|
BuiltInSubgroupSize, // Returns the number of work-items in the subgroup
|
||||||
|
BuiltInSubgroupMaxSize, // Returns the maximum size of a subgroup within the dispatch
|
||||||
|
BuiltInNumSubgroups, // Returns the maximum size of a subgroup within the dispatch
|
||||||
|
BuiltInNumEnqueuedSubgroups, // Returns the maximum size of a subgroup within the dispatch
|
||||||
|
BuiltInSubgroupId, //
|
||||||
|
BuiltInSubgroupLocalInvocationId, // Returns the unique work-item ID within the current subgroup
|
||||||
|
|
||||||
|
BuiltInCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum SelectControl {
|
||||||
|
SelectControlNone,
|
||||||
|
SelectControlFlatten,
|
||||||
|
SelectControlDontFlatten,
|
||||||
|
|
||||||
|
SelectControlCount, // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum LoopControl {
|
||||||
|
LoopControlNone,
|
||||||
|
LoopControlUnroll,
|
||||||
|
LoopControlDontUnroll,
|
||||||
|
|
||||||
|
LoopControlCount,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum FunctionControlMask {
|
||||||
|
FunctionControlNone = 0x0,
|
||||||
|
FunctionControlInline = 0x1,
|
||||||
|
FunctionControlDontInline = 0x2,
|
||||||
|
FunctionControlPure = 0x4,
|
||||||
|
FunctionControlConst = 0x8,
|
||||||
|
|
||||||
|
FunctionControlCount = 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemorySemanticsMask {
|
||||||
|
MemorySemanticsRelaxed = 0x0001,
|
||||||
|
MemorySemanticsSequentiallyConsistent = 0x0002,
|
||||||
|
MemorySemanticsAcquire = 0x0004,
|
||||||
|
MemorySemanticsRelease = 0x0008,
|
||||||
|
|
||||||
|
MemorySemanticsUniform = 0x0010,
|
||||||
|
MemorySemanticsSubgroup = 0x0020,
|
||||||
|
MemorySemanticsWorkgroupLocal = 0x0040,
|
||||||
|
MemorySemanticsWorkgroupGlobal = 0x0080,
|
||||||
|
MemorySemanticsAtomicCounter = 0x0100,
|
||||||
|
MemorySemanticsImage = 0x0200,
|
||||||
|
MemorySemanticsAllMemory = 0x03FF,
|
||||||
|
|
||||||
|
MemorySemanticsCount = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
enum MemoryAccessMask {
|
||||||
|
MemoryAccessVolatile = 0x0001,
|
||||||
|
MemoryAccessAligned = 0x0002,
|
||||||
|
|
||||||
|
MemoryAccessCount = 2
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ExecutionScope {
|
||||||
|
ExecutionScopeCrossDevice,
|
||||||
|
ExecutionScopeDevice,
|
||||||
|
ExecutionScopeWorkgroup,
|
||||||
|
ExecutionScopeSubgroup,
|
||||||
|
|
||||||
|
ExecutionScopeCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
enum GroupOperation {
|
||||||
|
GroupOpReduce,
|
||||||
|
GroupOpInclusiveScan,
|
||||||
|
GroupOpExclusiveScan,
|
||||||
|
|
||||||
|
GroupOpCount
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KernelEnqueueFlags {
|
||||||
|
EnqFlagNoWait,
|
||||||
|
EnqFlagWaitKernel,
|
||||||
|
EnqFlagWaitWaitWorgGroup,
|
||||||
|
|
||||||
|
EnqFlagCount
|
||||||
|
};
|
||||||
|
|
||||||
|
enum KernelProfilingInfo {
|
||||||
|
ProfInfoCmdExecTime = 0x01,
|
||||||
|
ProfilingInfoCount = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
enum OpCode {
|
||||||
|
OpNop = 0, // Not used.
|
||||||
|
|
||||||
|
OpSource,
|
||||||
|
OpSourceExtension,
|
||||||
|
OpExtension,
|
||||||
|
OpExtInstImport,
|
||||||
|
|
||||||
|
OpMemoryModel,
|
||||||
|
OpEntryPoint,
|
||||||
|
OpExecutionMode,
|
||||||
|
|
||||||
|
OpTypeVoid,
|
||||||
|
OpTypeBool,
|
||||||
|
OpTypeInt,
|
||||||
|
OpTypeFloat,
|
||||||
|
OpTypeVector,
|
||||||
|
OpTypeMatrix,
|
||||||
|
OpTypeSampler,
|
||||||
|
OpTypeFilter,
|
||||||
|
OpTypeArray,
|
||||||
|
OpTypeRuntimeArray,
|
||||||
|
OpTypeStruct,
|
||||||
|
OpTypeOpaque,
|
||||||
|
OpTypePointer,
|
||||||
|
OpTypeFunction,
|
||||||
|
OpTypeEvent,
|
||||||
|
OpTypeDeviceEvent,
|
||||||
|
OpTypeReserveId,
|
||||||
|
OpTypeQueue,
|
||||||
|
OpTypePipe,
|
||||||
|
|
||||||
|
OpConstantTrue,
|
||||||
|
OpConstantFalse,
|
||||||
|
OpConstant,
|
||||||
|
OpConstantComposite,
|
||||||
|
OpConstantSampler,
|
||||||
|
OpConstantNullPointer,
|
||||||
|
OpConstantNullObject,
|
||||||
|
|
||||||
|
OpSpecConstantTrue,
|
||||||
|
OpSpecConstantFalse,
|
||||||
|
OpSpecConstant,
|
||||||
|
OpSpecConstantComposite,
|
||||||
|
|
||||||
|
OpVariable,
|
||||||
|
OpVariableArray,
|
||||||
|
|
||||||
|
OpFunction,
|
||||||
|
OpFunctionParameter,
|
||||||
|
OpFunctionEnd,
|
||||||
|
OpFunctionCall,
|
||||||
|
|
||||||
|
OpExtInst,
|
||||||
|
|
||||||
|
OpUndef,
|
||||||
|
|
||||||
|
OpLoad,
|
||||||
|
OpStore,
|
||||||
|
|
||||||
|
OpPhi,
|
||||||
|
|
||||||
|
OpDecorationGroup,
|
||||||
|
OpDecorate,
|
||||||
|
OpMemberDecorate,
|
||||||
|
OpGroupDecorate,
|
||||||
|
OpGroupMemberDecorate,
|
||||||
|
|
||||||
|
OpName,
|
||||||
|
OpMemberName,
|
||||||
|
OpString,
|
||||||
|
OpLine,
|
||||||
|
|
||||||
|
OpVectorExtractDynamic,
|
||||||
|
OpVectorInsertDynamic,
|
||||||
|
OpVectorShuffle,
|
||||||
|
|
||||||
|
OpCompositeConstruct,
|
||||||
|
OpCompositeExtract,
|
||||||
|
OpCompositeInsert,
|
||||||
|
|
||||||
|
OpCopyObject,
|
||||||
|
OpCopyMemory,
|
||||||
|
OpCopyMemorySized,
|
||||||
|
|
||||||
|
OpSampler,
|
||||||
|
|
||||||
|
OpTextureSample,
|
||||||
|
OpTextureSampleDref,
|
||||||
|
OpTextureSampleLod,
|
||||||
|
OpTextureSampleProj,
|
||||||
|
OpTextureSampleGrad,
|
||||||
|
OpTextureSampleOffset,
|
||||||
|
OpTextureSampleProjLod,
|
||||||
|
OpTextureSampleProjGrad,
|
||||||
|
OpTextureSampleLodOffset,
|
||||||
|
OpTextureSampleProjOffset,
|
||||||
|
OpTextureSampleGradOffset,
|
||||||
|
OpTextureSampleProjLodOffset,
|
||||||
|
OpTextureSampleProjGradOffset,
|
||||||
|
|
||||||
|
OpTextureFetchTexel,
|
||||||
|
OpTextureFetchTexelOffset,
|
||||||
|
OpTextureFetchSample,
|
||||||
|
OpTextureFetchBuffer,
|
||||||
|
OpTextureGather,
|
||||||
|
OpTextureGatherOffset,
|
||||||
|
OpTextureGatherOffsets,
|
||||||
|
|
||||||
|
OpTextureQuerySizeLod,
|
||||||
|
OpTextureQuerySize,
|
||||||
|
OpTextureQueryLod,
|
||||||
|
OpTextureQueryLevels,
|
||||||
|
OpTextureQuerySamples,
|
||||||
|
|
||||||
|
OpAccessChain,
|
||||||
|
OpInBoundsAccessChain,
|
||||||
|
|
||||||
|
OpSNegate,
|
||||||
|
OpFNegate,
|
||||||
|
|
||||||
|
OpNot,
|
||||||
|
|
||||||
|
OpAny,
|
||||||
|
OpAll,
|
||||||
|
|
||||||
|
OpConvertFToU,
|
||||||
|
OpConvertFToS,
|
||||||
|
OpConvertSToF,
|
||||||
|
OpConvertUToF,
|
||||||
|
OpUConvert,
|
||||||
|
OpSConvert,
|
||||||
|
OpFConvert,
|
||||||
|
OpConvertPtrToU,
|
||||||
|
OpConvertUToPtr,
|
||||||
|
OpPtrCastToGeneric, // cast a pointer storage class to be in storage generic
|
||||||
|
OpGenericCastToPtr, // cast a pointer in the generic storage class generic to another storage class
|
||||||
|
OpBitcast,
|
||||||
|
|
||||||
|
OpTranspose,
|
||||||
|
|
||||||
|
OpIsNan,
|
||||||
|
OpIsInf,
|
||||||
|
OpIsFinite,
|
||||||
|
OpIsNormal,
|
||||||
|
OpSignBitSet,
|
||||||
|
OpLessOrGreater,
|
||||||
|
OpOrdered,
|
||||||
|
OpUnordered,
|
||||||
|
|
||||||
|
OpArrayLength,
|
||||||
|
|
||||||
|
OpIAdd,
|
||||||
|
OpFAdd,
|
||||||
|
OpISub,
|
||||||
|
OpFSub,
|
||||||
|
OpIMul,
|
||||||
|
OpFMul,
|
||||||
|
OpUDiv,
|
||||||
|
OpSDiv,
|
||||||
|
OpFDiv,
|
||||||
|
|
||||||
|
OpUMod,
|
||||||
|
OpSRem,
|
||||||
|
OpSMod,
|
||||||
|
OpFRem,
|
||||||
|
OpFMod,
|
||||||
|
|
||||||
|
OpVectorTimesScalar,
|
||||||
|
OpMatrixTimesScalar,
|
||||||
|
OpVectorTimesMatrix,
|
||||||
|
OpMatrixTimesVector,
|
||||||
|
OpMatrixTimesMatrix,
|
||||||
|
OpOuterProduct,
|
||||||
|
|
||||||
|
OpDot,
|
||||||
|
|
||||||
|
OpShiftRightLogical,
|
||||||
|
OpShiftRightArithmetic,
|
||||||
|
OpShiftLeftLogical,
|
||||||
|
OpLogicalOr,
|
||||||
|
OpLogicalXor,
|
||||||
|
OpLogicalAnd,
|
||||||
|
|
||||||
|
OpBitwiseOr,
|
||||||
|
OpBitwiseXor,
|
||||||
|
OpBitwiseAnd,
|
||||||
|
|
||||||
|
OpSelect,
|
||||||
|
|
||||||
|
OpIEqual,
|
||||||
|
OpFOrdEqual,
|
||||||
|
OpFUnordEqual,
|
||||||
|
|
||||||
|
OpINotEqual,
|
||||||
|
OpFOrdNotEqual,
|
||||||
|
OpFUnordNotEqual,
|
||||||
|
|
||||||
|
OpULessThan,
|
||||||
|
OpSLessThan,
|
||||||
|
OpFOrdLessThan,
|
||||||
|
OpFUnordLessThan,
|
||||||
|
|
||||||
|
OpUGreaterThan,
|
||||||
|
OpSGreaterThan,
|
||||||
|
OpFOrdGreaterThan,
|
||||||
|
OpFUnordGreaterThan,
|
||||||
|
|
||||||
|
OpULessThanEqual,
|
||||||
|
OpSLessThanEqual,
|
||||||
|
OpFOrdLessThanEqual,
|
||||||
|
OpFUnordLessThanEqual,
|
||||||
|
|
||||||
|
OpUGreaterThanEqual,
|
||||||
|
OpSGreaterThanEqual,
|
||||||
|
OpFOrdGreaterThanEqual,
|
||||||
|
OpFUnordGreaterThanEqual,
|
||||||
|
|
||||||
|
OpDPdx,
|
||||||
|
OpDPdy,
|
||||||
|
OpFwidth,
|
||||||
|
OpDPdxFine,
|
||||||
|
OpDPdyFine,
|
||||||
|
OpFwidthFine,
|
||||||
|
OpDPdxCoarse,
|
||||||
|
OpDPdyCoarse,
|
||||||
|
OpFwidthCoarse,
|
||||||
|
|
||||||
|
OpEmitVertex,
|
||||||
|
OpEndPrimitive,
|
||||||
|
OpEmitStreamVertex,
|
||||||
|
OpEndStreamPrimitive,
|
||||||
|
|
||||||
|
OpControlBarrier,
|
||||||
|
OpMemoryBarrier,
|
||||||
|
|
||||||
|
OpImagePointer,
|
||||||
|
|
||||||
|
OpAtomicInit,
|
||||||
|
OpAtomicLoad,
|
||||||
|
OpAtomicStore,
|
||||||
|
OpAtomicExchange,
|
||||||
|
OpAtomicCompareExchange,
|
||||||
|
OpAtomicCompareExchangeWeak,
|
||||||
|
OpAtomicIIncrement,
|
||||||
|
OpAtomicIDecrement,
|
||||||
|
OpAtomicIAdd,
|
||||||
|
OpAtomicISub,
|
||||||
|
OpAtomicUMin,
|
||||||
|
OpAtomicUMax,
|
||||||
|
OpAtomicAnd,
|
||||||
|
OpAtomicOr,
|
||||||
|
OpAtomicXor,
|
||||||
|
|
||||||
|
OpLoopMerge,
|
||||||
|
OpSelectionMerge,
|
||||||
|
OpLabel,
|
||||||
|
OpBranch,
|
||||||
|
OpBranchConditional,
|
||||||
|
OpSwitch,
|
||||||
|
OpKill,
|
||||||
|
OpReturn,
|
||||||
|
OpReturnValue,
|
||||||
|
|
||||||
|
OpUnreachable,
|
||||||
|
|
||||||
|
OpLifetimeStart,
|
||||||
|
OpLifetimeStop,
|
||||||
|
|
||||||
|
OpCompileFlag,
|
||||||
|
|
||||||
|
OpAsyncGroupCopy,
|
||||||
|
OpWaitGroupEvents,
|
||||||
|
|
||||||
|
OpGroupAll,
|
||||||
|
OpGroupAny,
|
||||||
|
OpGroupBroadcast,
|
||||||
|
|
||||||
|
OpGroupIAdd,
|
||||||
|
OpGroupFAdd,
|
||||||
|
OpGroupFMin,
|
||||||
|
OpGroupUMin,
|
||||||
|
OpGroupSMin,
|
||||||
|
OpGroupFMax,
|
||||||
|
OpGroupUMax,
|
||||||
|
OpGroupSMax,
|
||||||
|
|
||||||
|
OpGenericCastToPtrExplicit,
|
||||||
|
OpGenericPtrMemSemantics,
|
||||||
|
|
||||||
|
OpReadPipe,
|
||||||
|
OpWritePipe,
|
||||||
|
OpReservedReadPipe,
|
||||||
|
OpReservedWritePipe,
|
||||||
|
OpReserveReadPipePackets,
|
||||||
|
OpReserveWritePipePackets,
|
||||||
|
OpCommitReadPipe,
|
||||||
|
OpCommitWritePipe,
|
||||||
|
OpIsValidReserveId,
|
||||||
|
OpGetNumPipePackets,
|
||||||
|
OpGetMaxPipePackets,
|
||||||
|
OpGroupReserveReadPipePackets,
|
||||||
|
OpGroupReserveWritePipePackets,
|
||||||
|
OpGroupCommitReadPipe,
|
||||||
|
OpGroupCommitWritePipe,
|
||||||
|
|
||||||
|
OpEnqueueMarker,
|
||||||
|
OpEnqueueKernel,
|
||||||
|
OpGetKernelNDrangeSubGroupCount,
|
||||||
|
OpGetKernelNDrangeMaxSubGroupSize,
|
||||||
|
|
||||||
|
OpGetKernelWorkGroupSize,
|
||||||
|
OpGetKernelPreferredWorkGroupSizeMultiple,
|
||||||
|
|
||||||
|
OpRetainEvent,
|
||||||
|
OpReleaseEvent,
|
||||||
|
|
||||||
|
OpCreateUserEvent,
|
||||||
|
OpIsValidEvent,
|
||||||
|
OpSetUserEventStatus,
|
||||||
|
OpCaptureEventProfilingInfo,
|
||||||
|
OpGetDefaultQueue,
|
||||||
|
|
||||||
|
OpBuildNDRange,
|
||||||
|
|
||||||
|
OpCount // guard for validation, "default:" statements, etc.
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}; // end namespace spv
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // spirv_H
|
||||||
348
SPIRV/spvIR.h
Normal file
348
SPIRV/spvIR.h
Normal file
@ -0,0 +1,348 @@
|
|||||||
|
//
|
||||||
|
//Copyright (C) 2014 LunarG, Inc.
|
||||||
|
//
|
||||||
|
//All rights reserved.
|
||||||
|
//
|
||||||
|
//Redistribution and use in source and binary forms, with or without
|
||||||
|
//modification, are permitted provided that the following conditions
|
||||||
|
//are met:
|
||||||
|
//
|
||||||
|
// Redistributions of source code must retain the above copyright
|
||||||
|
// notice, this list of conditions and the following disclaimer.
|
||||||
|
//
|
||||||
|
// Redistributions in binary form must reproduce the above
|
||||||
|
// copyright notice, this list of conditions and the following
|
||||||
|
// disclaimer in the documentation and/or other materials provided
|
||||||
|
// with the distribution.
|
||||||
|
//
|
||||||
|
// Neither the name of 3Dlabs Inc. Ltd. nor the names of its
|
||||||
|
// contributors may be used to endorse or promote products derived
|
||||||
|
// from this software without specific prior written permission.
|
||||||
|
//
|
||||||
|
//THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
//"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
//LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||||
|
//FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||||
|
//COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||||
|
//INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
//BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||||
|
//LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
//CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
//LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||||
|
//ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
//POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
//
|
||||||
|
// Author: John Kessenich, LunarG
|
||||||
|
//
|
||||||
|
|
||||||
|
// SPIRV-IR
|
||||||
|
//
|
||||||
|
// Simple in-memory representation (IR) of SPIRV. Just for holding
|
||||||
|
// Each function's CFG of blocks. Has this hierarchy:
|
||||||
|
// - Module, which is a list of
|
||||||
|
// - Function, which is a list of
|
||||||
|
// - Block, which is a list of
|
||||||
|
// - Instruction
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef spvIR_H
|
||||||
|
#define spvIR_H
|
||||||
|
|
||||||
|
#include "spirv.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
namespace spv {
|
||||||
|
|
||||||
|
class Function;
|
||||||
|
class Module;
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR instruction.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Instruction {
|
||||||
|
public:
|
||||||
|
Instruction(Id resultId, Id typeId, OpCode opCode) : resultId(resultId), typeId(typeId), opCode(opCode), string(0) { }
|
||||||
|
explicit Instruction(OpCode opCode) : resultId(NoResult), typeId(NoType), opCode(opCode), string(0) { }
|
||||||
|
virtual ~Instruction()
|
||||||
|
{
|
||||||
|
delete string;
|
||||||
|
}
|
||||||
|
void addIdOperand(Id id) { operands.push_back(id); }
|
||||||
|
void addImmediateOperand(unsigned int immediate) { operands.push_back(immediate); }
|
||||||
|
void addStringOperand(const char* str)
|
||||||
|
{
|
||||||
|
string = new std::vector<unsigned int>;
|
||||||
|
unsigned int word;
|
||||||
|
char* wordString = (char*)&word;
|
||||||
|
char* wordPtr = wordString;
|
||||||
|
int charCount = 0;
|
||||||
|
char c;
|
||||||
|
do {
|
||||||
|
c = *(str++);
|
||||||
|
*(wordPtr++) = c;
|
||||||
|
++charCount;
|
||||||
|
if (charCount == 4) {
|
||||||
|
string->push_back(word);
|
||||||
|
wordPtr = wordString;
|
||||||
|
charCount = 0;
|
||||||
|
}
|
||||||
|
} while (c != 0);
|
||||||
|
|
||||||
|
// deal with partial last word
|
||||||
|
if (charCount > 0) {
|
||||||
|
// pad with 0s
|
||||||
|
for (; charCount < 4; ++charCount)
|
||||||
|
*(wordPtr++) = 0;
|
||||||
|
string->push_back(word);
|
||||||
|
}
|
||||||
|
|
||||||
|
originalString = str;
|
||||||
|
}
|
||||||
|
OpCode getOpCode() const { return opCode; }
|
||||||
|
int getNumOperands() const { return operands.size(); }
|
||||||
|
Id getResultId() const { return resultId; }
|
||||||
|
Id getTypeId() const { return typeId; }
|
||||||
|
Id getIdOperand(int op) const { return operands[op]; }
|
||||||
|
unsigned int getImmediateOperand(int op) const { return operands[op]; }
|
||||||
|
const char* getStringOperand() const { return originalString.c_str(); }
|
||||||
|
|
||||||
|
// Write out the binary form.
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
// Compute the wordCount
|
||||||
|
unsigned int wordCount = 1;
|
||||||
|
if (typeId)
|
||||||
|
++wordCount;
|
||||||
|
if (resultId)
|
||||||
|
++wordCount;
|
||||||
|
wordCount += operands.size();
|
||||||
|
if (string)
|
||||||
|
wordCount += string->size();
|
||||||
|
|
||||||
|
// Write out the beginning of the instruction
|
||||||
|
out.push_back(((wordCount) << WordCountShift) | opCode);
|
||||||
|
if (typeId)
|
||||||
|
out.push_back(typeId);
|
||||||
|
if (resultId)
|
||||||
|
out.push_back(resultId);
|
||||||
|
|
||||||
|
// Write out the operands
|
||||||
|
for (int op = 0; op < (int)operands.size(); ++op)
|
||||||
|
out.push_back(operands[op]);
|
||||||
|
if (string)
|
||||||
|
for (int op = 0; op < (int)string->size(); ++op)
|
||||||
|
out.push_back((*string)[op]);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Instruction(const Instruction&);
|
||||||
|
Id resultId;
|
||||||
|
Id typeId;
|
||||||
|
OpCode opCode;
|
||||||
|
std::vector<Id> operands;
|
||||||
|
std::vector<unsigned int>* string; // usually non-existent
|
||||||
|
std::string originalString; // could be optimized away; convenience for getting string operand
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR block.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Block {
|
||||||
|
public:
|
||||||
|
// Setting insert to true indicates to add this new block
|
||||||
|
// to the end of the parent function.
|
||||||
|
Block(Id id, Function& parent);
|
||||||
|
virtual ~Block()
|
||||||
|
{
|
||||||
|
// TODO: free instructions
|
||||||
|
}
|
||||||
|
|
||||||
|
Id getId() { return instructions.front()->getResultId(); }
|
||||||
|
|
||||||
|
Function& getParent() const { return parent; }
|
||||||
|
void addInstruction(Instruction* inst);
|
||||||
|
void addPredecessor(Block* pred) { predecessors.push_back(pred); }
|
||||||
|
void addLocalVariable(Instruction* inst) { localVariables.push_back(inst); }
|
||||||
|
int getNumPredecessors() const { return (int)predecessors.size(); }
|
||||||
|
|
||||||
|
bool isTerminated() const
|
||||||
|
{
|
||||||
|
switch (instructions.back()->getOpCode()) {
|
||||||
|
case OpBranch:
|
||||||
|
case OpBranchConditional:
|
||||||
|
case OpSwitch:
|
||||||
|
case OpKill:
|
||||||
|
case OpReturn:
|
||||||
|
case OpReturnValue:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
instructions[0]->dump(out);
|
||||||
|
for (int i = 0; i < (int)localVariables.size(); ++i)
|
||||||
|
localVariables[i]->dump(out);
|
||||||
|
for (int i = 1; i < (int)instructions.size(); ++i)
|
||||||
|
instructions[i]->dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Block(const Block&);
|
||||||
|
|
||||||
|
// To enforce keeping parent and ownership in sync:
|
||||||
|
friend Function;
|
||||||
|
|
||||||
|
std::vector<Instruction*> instructions;
|
||||||
|
std::vector<Block*> predecessors;
|
||||||
|
std::vector<Instruction*> localVariables;
|
||||||
|
Function& parent;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR Function.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Function {
|
||||||
|
public:
|
||||||
|
Function(Id id, Id resultType, Id functionType, Id firstParam, Module& parent);
|
||||||
|
virtual ~Function()
|
||||||
|
{
|
||||||
|
for (int i = 0; i < (int)parameterInstructions.size(); ++i)
|
||||||
|
delete parameterInstructions[i];
|
||||||
|
|
||||||
|
for (int i = 0; i < (int)blocks.size(); ++i)
|
||||||
|
delete blocks[i];
|
||||||
|
}
|
||||||
|
Id getId() const { return functionInstruction.getResultId(); }
|
||||||
|
Id getParamId(int p) { return parameterInstructions[p]->getResultId(); }
|
||||||
|
|
||||||
|
void addBlock(Block* block) { blocks.push_back(block); }
|
||||||
|
void popBlock(Block* block) { assert(blocks.back() == block); blocks.pop_back(); }
|
||||||
|
|
||||||
|
Module& getParent() const { return parent; }
|
||||||
|
Block* getEntryBlock() const { return blocks.front(); }
|
||||||
|
Block* getLastBlock() const { return blocks.back(); }
|
||||||
|
void addLocalVariable(Instruction* inst);
|
||||||
|
Id getReturnType() const { return functionInstruction.getTypeId(); }
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
// OpFunction
|
||||||
|
functionInstruction.dump(out);
|
||||||
|
|
||||||
|
// OpFunctionParameter
|
||||||
|
for (int p = 0; p < (int)parameterInstructions.size(); ++p)
|
||||||
|
parameterInstructions[p]->dump(out);
|
||||||
|
|
||||||
|
// Blocks
|
||||||
|
for (int b = 0; b < (int)blocks.size(); ++b)
|
||||||
|
blocks[b]->dump(out);
|
||||||
|
Instruction end(0, 0, OpFunctionEnd);
|
||||||
|
end.dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Function(const Function&);
|
||||||
|
Module& parent;
|
||||||
|
Instruction functionInstruction;
|
||||||
|
std::vector<Instruction*> parameterInstructions;
|
||||||
|
std::vector<Block*> blocks;
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// SPIR-V IR Module.
|
||||||
|
//
|
||||||
|
|
||||||
|
class Module {
|
||||||
|
public:
|
||||||
|
Module() {}
|
||||||
|
virtual ~Module()
|
||||||
|
{
|
||||||
|
// TODO delete things
|
||||||
|
}
|
||||||
|
|
||||||
|
void addFunction(Function *fun) { functions.push_back(fun); }
|
||||||
|
|
||||||
|
void mapInstruction(Instruction *instruction)
|
||||||
|
{
|
||||||
|
spv::Id resultId = instruction->getResultId();
|
||||||
|
// map the instruction's result id
|
||||||
|
if (resultId >= idToInstruction.size())
|
||||||
|
idToInstruction.resize(resultId + 16);
|
||||||
|
idToInstruction[resultId] = instruction;
|
||||||
|
}
|
||||||
|
|
||||||
|
Instruction* getInstruction(Id id) const { return idToInstruction[id]; }
|
||||||
|
spv::Id getTypeId(Id resultId) const { return idToInstruction[resultId]->getTypeId(); }
|
||||||
|
StorageClass getStorageClass(Id typeId) const { return (StorageClass)idToInstruction[typeId]->getImmediateOperand(0); }
|
||||||
|
void dump(std::vector<unsigned int>& out) const
|
||||||
|
{
|
||||||
|
for (int f = 0; f < (int)functions.size(); ++f)
|
||||||
|
functions[f]->dump(out);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Module(const Module&);
|
||||||
|
std::vector<Function*> functions;
|
||||||
|
|
||||||
|
// map from result id to instruction having that result id
|
||||||
|
std::vector<Instruction*> idToInstruction;
|
||||||
|
|
||||||
|
// map from a result id to its type id
|
||||||
|
};
|
||||||
|
|
||||||
|
//
|
||||||
|
// Implementation (it's here due to circular type definitions).
|
||||||
|
//
|
||||||
|
|
||||||
|
// Add both
|
||||||
|
// - the OpFunction instruction
|
||||||
|
// - all the OpFunctionParameter instructions
|
||||||
|
__inline Function::Function(Id id, Id resultType, Id functionType, Id firstParamId, Module& parent)
|
||||||
|
: parent(parent), functionInstruction(id, resultType, OpFunction)
|
||||||
|
{
|
||||||
|
// OpFunction
|
||||||
|
functionInstruction.addImmediateOperand(FunctionControlNone);
|
||||||
|
functionInstruction.addIdOperand(functionType);
|
||||||
|
parent.mapInstruction(&functionInstruction);
|
||||||
|
parent.addFunction(this);
|
||||||
|
|
||||||
|
// OpFunctionParameter
|
||||||
|
Instruction* typeInst = parent.getInstruction(functionType);
|
||||||
|
int numParams = typeInst->getNumOperands() - 1;
|
||||||
|
for (int p = 0; p < numParams; ++p) {
|
||||||
|
Instruction* param = new Instruction(firstParamId + p, typeInst->getIdOperand(p + 1), OpFunctionParameter);
|
||||||
|
parent.mapInstruction(param);
|
||||||
|
parameterInstructions.push_back(param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline void Function::addLocalVariable(Instruction* inst)
|
||||||
|
{
|
||||||
|
blocks[0]->addLocalVariable(inst);
|
||||||
|
parent.mapInstruction(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline Block::Block(Id id, Function& parent) : parent(parent)
|
||||||
|
{
|
||||||
|
instructions.push_back(new Instruction(id, NoType, OpLabel));
|
||||||
|
}
|
||||||
|
|
||||||
|
__inline void Block::addInstruction(Instruction* inst)
|
||||||
|
{
|
||||||
|
instructions.push_back(inst);
|
||||||
|
if (inst->getResultId())
|
||||||
|
parent.getParent().mapInstruction(inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
}; // end spv namespace
|
||||||
|
|
||||||
|
#endif // spvIR_H
|
||||||
@ -17,7 +17,7 @@ set(LIBRARIES
|
|||||||
glslang
|
glslang
|
||||||
OGLCompiler
|
OGLCompiler
|
||||||
OSDependent
|
OSDependent
|
||||||
BIL)
|
SPIRV)
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
set(LIBRARIES ${LIBRARIES} psapi)
|
set(LIBRARIES ${LIBRARIES} psapi)
|
||||||
|
|||||||
@ -40,8 +40,8 @@
|
|||||||
#include "Worklist.h"
|
#include "Worklist.h"
|
||||||
#include "./../glslang/Include/ShHandle.h"
|
#include "./../glslang/Include/ShHandle.h"
|
||||||
#include "./../glslang/Public/ShaderLang.h"
|
#include "./../glslang/Public/ShaderLang.h"
|
||||||
#include "../BIL/GlslangToBil.h"
|
#include "../SPIRV/GlslangToSpv.h"
|
||||||
#include "../BIL/GLSL450Lib.h"
|
#include "../SPIRV/GLSL450Lib.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@ -66,7 +66,7 @@ enum TOptions {
|
|||||||
EOptionDumpReflection = 0x100,
|
EOptionDumpReflection = 0x100,
|
||||||
EOptionSuppressWarnings = 0x200,
|
EOptionSuppressWarnings = 0x200,
|
||||||
EOptionDumpVersions = 0x400,
|
EOptionDumpVersions = 0x400,
|
||||||
EOptionBil = 0x800,
|
EOptionSpv = 0x800,
|
||||||
EOptionDefaultDesktop = 0x1000,
|
EOptionDefaultDesktop = 0x1000,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -479,8 +479,8 @@ bool ProcessArguments(int argc, char* argv[])
|
|||||||
Work[argc] = 0;
|
Work[argc] = 0;
|
||||||
if (argv[0][0] == '-') {
|
if (argv[0][0] == '-') {
|
||||||
switch (argv[0][1]) {
|
switch (argv[0][1]) {
|
||||||
case 'b':
|
case 'V':
|
||||||
Options |= EOptionBil;
|
Options |= EOptionSpv;
|
||||||
Options |= EOptionLinkProgram;
|
Options |= EOptionLinkProgram;
|
||||||
break;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
@ -634,14 +634,14 @@ void CompileAndLinkShaders()
|
|||||||
program.dumpReflection();
|
program.dumpReflection();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Options & EOptionBil) {
|
if (Options & EOptionSpv) {
|
||||||
if (CompileFailed || LinkFailed)
|
if (CompileFailed || LinkFailed)
|
||||||
printf("Bil is not generated for failed compile or link\n");
|
printf("SPIRV is not generated for failed compile or link\n");
|
||||||
else {
|
else {
|
||||||
for (int stage = 0; stage < EShLangCount; ++stage) {
|
for (int stage = 0; stage < EShLangCount; ++stage) {
|
||||||
if (program.getIntermediate((EShLanguage)stage)) {
|
if (program.getIntermediate((EShLanguage)stage)) {
|
||||||
std::vector<unsigned int> bil;
|
std::vector<unsigned int> spirv;
|
||||||
glslang::GlslangToBil(*program.getIntermediate((EShLanguage)stage), bil);
|
glslang::GlslangToSpv(*program.getIntermediate((EShLanguage)stage), spirv);
|
||||||
const char* name;
|
const char* name;
|
||||||
switch (stage) {
|
switch (stage) {
|
||||||
case EShLangVertex: name = "vert"; break;
|
case EShLangVertex: name = "vert"; break;
|
||||||
@ -652,7 +652,7 @@ void CompileAndLinkShaders()
|
|||||||
case EShLangCompute: name = "comp"; break;
|
case EShLangCompute: name = "comp"; break;
|
||||||
default: name = "unknown"; break;
|
default: name = "unknown"; break;
|
||||||
}
|
}
|
||||||
glslang::OutputBil(bil, name);
|
glslang::OutputSpv(spirv, name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -839,7 +839,7 @@ void usage()
|
|||||||
{
|
{
|
||||||
printf("Usage: glslangValidator [option]... [file]...\n"
|
printf("Usage: glslangValidator [option]... [file]...\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Where: each 'file' ends in\n"
|
"Where: each 'file' ends in .<stage>, where <stage> is one of\n"
|
||||||
" .conf to provide an optional config file that replaces the default configuration\n"
|
" .conf to provide an optional config file that replaces the default configuration\n"
|
||||||
" (see -c option below for generating a template)\n"
|
" (see -c option below for generating a template)\n"
|
||||||
" .vert for a vertex shader\n"
|
" .vert for a vertex shader\n"
|
||||||
@ -853,7 +853,7 @@ void usage()
|
|||||||
"\n"
|
"\n"
|
||||||
"To get other information, use one of the following options:\n"
|
"To get other information, use one of the following options:\n"
|
||||||
"(Each option must be specified separately, but can go anywhere in the command line.)\n"
|
"(Each option must be specified separately, but can go anywhere in the command line.)\n"
|
||||||
" -b create BIL in file <stage>.bil\n"
|
" -V create SPIR-V in file <stage>.spv\n"
|
||||||
" -c configuration dump; use to create default configuration file (redirect to a .conf file)\n"
|
" -c configuration dump; use to create default configuration file (redirect to a .conf file)\n"
|
||||||
" -d default to desktop (#version 110) when there is no version in the shader (default is ES version 100)\n"
|
" -d default to desktop (#version 110) when there is no version in the shader (default is ES version 100)\n"
|
||||||
" -i intermediate tree (glslang AST) is printed out\n"
|
" -i intermediate tree (glslang AST) is printed out\n"
|
||||||
|
|||||||
@ -482,6 +482,7 @@ public:
|
|||||||
|
|
||||||
layoutLocation = layoutLocationEnd;
|
layoutLocation = layoutLocationEnd;
|
||||||
layoutComponent = layoutComponentEnd;
|
layoutComponent = layoutComponentEnd;
|
||||||
|
layoutSet = layoutSetEnd;
|
||||||
layoutBinding = layoutBindingEnd;
|
layoutBinding = layoutBindingEnd;
|
||||||
layoutIndex = layoutIndexEnd;
|
layoutIndex = layoutIndexEnd;
|
||||||
|
|
||||||
@ -513,6 +514,9 @@ public:
|
|||||||
unsigned int layoutComponent : 3;
|
unsigned int layoutComponent : 3;
|
||||||
static const unsigned int layoutComponentEnd = 4;
|
static const unsigned int layoutComponentEnd = 4;
|
||||||
|
|
||||||
|
unsigned int layoutSet : 7;
|
||||||
|
static const unsigned int layoutSetEnd = 0x3F;
|
||||||
|
|
||||||
unsigned int layoutBinding : 8;
|
unsigned int layoutBinding : 8;
|
||||||
static const unsigned int layoutBindingEnd = 0xFF;
|
static const unsigned int layoutBindingEnd = 0xFF;
|
||||||
|
|
||||||
@ -575,6 +579,10 @@ public:
|
|||||||
{
|
{
|
||||||
return layoutIndex != layoutIndexEnd;
|
return layoutIndex != layoutIndexEnd;
|
||||||
}
|
}
|
||||||
|
bool hasSet() const
|
||||||
|
{
|
||||||
|
return layoutSet != layoutSetEnd;
|
||||||
|
}
|
||||||
bool hasBinding() const
|
bool hasBinding() const
|
||||||
{
|
{
|
||||||
return layoutBinding != layoutBindingEnd;
|
return layoutBinding != layoutBindingEnd;
|
||||||
@ -1201,6 +1209,8 @@ public:
|
|||||||
if (qualifier.hasIndex())
|
if (qualifier.hasIndex())
|
||||||
p += snprintf(p, end - p, "index=%d ", qualifier.layoutIndex);
|
p += snprintf(p, end - p, "index=%d ", qualifier.layoutIndex);
|
||||||
}
|
}
|
||||||
|
if (qualifier.hasSet())
|
||||||
|
p += snprintf(p, end - p, "set=%d ", qualifier.layoutSet);
|
||||||
if (qualifier.hasBinding())
|
if (qualifier.hasBinding())
|
||||||
p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
|
p += snprintf(p, end - p, "binding=%d ", qualifier.layoutBinding);
|
||||||
if (qualifier.hasStream())
|
if (qualifier.hasStream())
|
||||||
|
|||||||
@ -3312,6 +3312,12 @@ void TParseContext::setLayoutQualifier(TSourceLoc loc, TPublicType& publicType,
|
|||||||
else
|
else
|
||||||
publicType.qualifier.layoutLocation = value;
|
publicType.qualifier.layoutLocation = value;
|
||||||
return;
|
return;
|
||||||
|
} else if (id == "set") {
|
||||||
|
if ((unsigned int)value >= TQualifier::layoutSetEnd)
|
||||||
|
error(loc, "set is too large", id.c_str(), "");
|
||||||
|
else
|
||||||
|
publicType.qualifier.layoutSet = value;
|
||||||
|
return;
|
||||||
} else if (id == "binding") {
|
} else if (id == "binding") {
|
||||||
profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, "binding");
|
profileRequires(loc, ~EEsProfile, 420, GL_ARB_shading_language_420pack, "binding");
|
||||||
profileRequires(loc, EEsProfile, 310, 0, "binding");
|
profileRequires(loc, EEsProfile, 310, 0, "binding");
|
||||||
@ -3476,6 +3482,8 @@ void TParseContext::mergeObjectLayoutQualifiers(TSourceLoc loc, TQualifier& dst,
|
|||||||
if (src.hasOffset())
|
if (src.hasOffset())
|
||||||
dst.layoutOffset = src.layoutOffset;
|
dst.layoutOffset = src.layoutOffset;
|
||||||
|
|
||||||
|
if (src.hasSet())
|
||||||
|
dst.layoutSet = src.layoutSet;
|
||||||
if (src.layoutBinding != TQualifier::layoutBindingEnd)
|
if (src.layoutBinding != TQualifier::layoutBindingEnd)
|
||||||
dst.layoutBinding = src.layoutBinding;
|
dst.layoutBinding = src.layoutBinding;
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user